Module refinery.units.formats.archive.xtmacho
Expand source code Browse git
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from enum import IntFlag
from refinery.units.formats.archive import ArchiveUnit
from refinery.lib.structures import Struct, StructReader, StreamDetour
class CPUType(IntFlag):
any = 0xFFFFFFFF # noqa
vax = 0x00000001 # noqa
mc680x0 = 0x00000006 # noqa
x32 = 0x00000007 # noqa
x64 = 0x01000007 # noqa
mips = 0x00000008 # noqa
mc98000 = 0x0000000A # noqa
hppa = 0x0000000B # noqa
arm32 = 0x0000000C # noqa
arm64 = 0x0100000C # noqa
mc880000 = 0x0000000D # noqa
sparc = 0x0000000E # noqa
i860 = 0x0000000F # noqa
alpha = 0x00000010 # noqa
ppc32 = 0x00000012 # noqa
ppc64 = 0x01000012 # noqa
class FatArch(Struct):
def __init__(self, reader: StructReader):
self.cputype = CPUType(reader.u32())
self.machine = reader.u32()
offset = reader.u32()
size = reader.u32()
self.is64bit = (self.cputype >> 24) & 1
with StreamDetour(reader, offset):
self.data = reader.read(size)
self.align = reader.u32()
class xtmacho(ArchiveUnit):
"""
Extract the individual executables from a MachO universal binary (sometimes called a MachO fat file)."
"""
_SIGNATURE_BE = B'\xCA\xFE\xBA\xBE'
_SIGNATURE_LE = B'\xBE\xBA\xFE\xCA'
def unpack(self, data: bytearray):
view = memoryview(data)
signature = bytes(view[:4])
try:
reader = StructReader(view, bigendian={
self._SIGNATURE_BE: True,
self._SIGNATURE_LE: False,
}[signature])
except KeyError as KE:
raise ValueError('Not a MachO universal binary; invalid magic header bytes.') from KE
else:
reader.seekset(4)
count = reader.u32()
self.log_info(F'reading {count} embedded executables')
while count > 0:
fa = FatArch(reader)
self.log_info(F'reading item of size 0x{len(fa.data):08X}, arch {fa.cputype.name}')
yield self._pack(fa.cputype.name, None, fa.data)
count -= 1
@classmethod
def handles(cls, data: bytearray):
return data[:4] in (
cls._SIGNATURE_BE,
cls._SIGNATURE_LE,
)
Classes
class CPUType (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
An enumeration.
Expand source code Browse git
class CPUType(IntFlag): any = 0xFFFFFFFF # noqa vax = 0x00000001 # noqa mc680x0 = 0x00000006 # noqa x32 = 0x00000007 # noqa x64 = 0x01000007 # noqa mips = 0x00000008 # noqa mc98000 = 0x0000000A # noqa hppa = 0x0000000B # noqa arm32 = 0x0000000C # noqa arm64 = 0x0100000C # noqa mc880000 = 0x0000000D # noqa sparc = 0x0000000E # noqa i860 = 0x0000000F # noqa alpha = 0x00000010 # noqa ppc32 = 0x00000012 # noqa ppc64 = 0x01000012 # noqa
Ancestors
- enum.IntFlag
- builtins.int
- enum.Flag
- enum.Enum
Class variables
var any
var vax
var mc680x0
var x32
var x64
var mips
var mc98000
var hppa
var arm32
var arm64
var mc880000
var sparc
var i860
var alpha
var ppc32
var ppc64
class FatArch (reader)
-
A class to parse structured data. A
Struct
class can be instantiated as follows:foo = Struct(data, bar=29)
The initialization routine of the structure will be called with a single argument
reader
. If the objectdata
is already aStructReader
, then it will be passed asreader
. Otherwise, the argument will be wrapped in aStructReader
. Additional arguments to the struct are passed through.Expand source code Browse git
class FatArch(Struct): def __init__(self, reader: StructReader): self.cputype = CPUType(reader.u32()) self.machine = reader.u32() offset = reader.u32() size = reader.u32() self.is64bit = (self.cputype >> 24) & 1 with StreamDetour(reader, offset): self.data = reader.read(size) self.align = reader.u32()
Ancestors
class xtmacho (*paths, list=False, join_path=False, drop_path=False, fuzzy=0, exact=False, regex=False, path=b'path', date=b'date', pwd=b'')
-
Extract the individual executables from a MachO universal binary (sometimes called a MachO fat file)."
Expand source code Browse git
class xtmacho(ArchiveUnit): """ Extract the individual executables from a MachO universal binary (sometimes called a MachO fat file)." """ _SIGNATURE_BE = B'\xCA\xFE\xBA\xBE' _SIGNATURE_LE = B'\xBE\xBA\xFE\xCA' def unpack(self, data: bytearray): view = memoryview(data) signature = bytes(view[:4]) try: reader = StructReader(view, bigendian={ self._SIGNATURE_BE: True, self._SIGNATURE_LE: False, }[signature]) except KeyError as KE: raise ValueError('Not a MachO universal binary; invalid magic header bytes.') from KE else: reader.seekset(4) count = reader.u32() self.log_info(F'reading {count} embedded executables') while count > 0: fa = FatArch(reader) self.log_info(F'reading item of size 0x{len(fa.data):08X}, arch {fa.cputype.name}') yield self._pack(fa.cputype.name, None, fa.data) count -= 1 @classmethod def handles(cls, data: bytearray): return data[:4] in ( cls._SIGNATURE_BE, cls._SIGNATURE_LE, )
Ancestors
Class variables
var required_dependencies
var optional_dependencies
Methods
def unpack(self, data)
-
Expand source code Browse git
def unpack(self, data: bytearray): view = memoryview(data) signature = bytes(view[:4]) try: reader = StructReader(view, bigendian={ self._SIGNATURE_BE: True, self._SIGNATURE_LE: False, }[signature]) except KeyError as KE: raise ValueError('Not a MachO universal binary; invalid magic header bytes.') from KE else: reader.seekset(4) count = reader.u32() self.log_info(F'reading {count} embedded executables') while count > 0: fa = FatArch(reader) self.log_info(F'reading item of size 0x{len(fa.data):08X}, arch {fa.cputype.name}') yield self._pack(fa.cputype.name, None, fa.data) count -= 1
Inherited members