Ejemplo n.º 1
0
def test_MACHO_prebind_64(assertion):
    global log_history
    macho_64 = open(__dir__ + 'macho_64.out', 'rb').read()
    e = MACHO(macho_64)
    d = e.virt[0x100000f50:0x100000f62]
    assertion('structure definie\0', d.decode('latin1'),
              'Extract chunk from mapped memory, in a section (64 bits)')
    e.virt[0x100000f50:0x100000f5c] = 'Hello World\0'.encode('latin1')
    d = e.pack()
    assertion('b29fe575093a6f68a54131e59138e1d8',
              hashlib.md5(d).hexdigest(),
              'Writing in memory (interval) (64 bits)')
    e.virt[0x100000f50] = 'Hello World\0'.encode('latin1')
    d = e.pack()
    assertion('b29fe575093a6f68a54131e59138e1d8',
              hashlib.md5(d).hexdigest(),
              'Writing in memory (address) (64 bits)')
    e.add(
        macho.Section(parent=macho.sectionHeader(parent=e.load),
                      content='arbitrary content'.encode('latin1')))
    d = e.pack()
    assertion('be836b2b8adcff60bcc7ca1d712a92a9',
              hashlib.md5(d).hexdigest(), 'Adding a section (64 bits)')
    e = MACHO(macho_64)
    e.add(type=macho.LC_SEGMENT_64,
          segname='__NEWTEXT',
          initprot=macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
          content='some binary data'.encode('latin1'))
    d = e.pack()
    assertion('b4ad381503c51b6dc9dc3d79fb8ca568',
              hashlib.md5(d).hexdigest(), 'Adding a segment (64 bits)')
Ejemplo n.º 2
0
def test_MACHO_unixthread_64(assertion):
    macho_64 = open(__dir__ + 'macho_64.out', 'rb').read()
    e = MACHO(macho_64)
    changeMainToUnixThread(e)
    d = e.pack()
    assertion('a77d64572857d5414ae414852b930370',
              hashlib.md5(d).hexdigest(),
              'Migrating from LC_MAIN to LC_UNIXTHREAD (64 bits)')
    insert_start_function(e)
    d = e.pack()
    assertion(
        '16b63a2d3cdb3549fe9870b805eb80f5',
        hashlib.md5(d).hexdigest(),
        'Migrating from LC_MAIN to LC_UNIXTHREAD with new segment (64 bits)')
Ejemplo n.º 3
0
def test_MACHO_lib_ATcommand(assertion):
    macho_lib = open(__dir__ + 'libATCommandStudioDynamic.dylib', 'rb').read()
    e = MACHO(macho_lib)
    macho_lib_hash = hashlib.md5(macho_lib).hexdigest()
    d = e.pack()
    assertion(macho_lib_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading libATCommandStudioDynamic')
    bind_s = [
        _ for _ in e.sect
        if getattr(_, 'type', None) in ('bind_', 'weak_bind_', 'lazy_bind_',
                                        'rebase_', 'export_')
    ]
    d = ('\n'.join([str(_) for s in bind_s for _ in s.info])).encode('latin1')
    assertion('8b29446352613fdb6c4a6142c7c476c3',
              hashlib.md5(d).hexdigest(),
              'dyldinfo-like output for all binding types (libATCommand...)')
    bind_s = [
        _ for _ in e.sect
        if getattr(_, 'type', None) in ('bind_', 'weak_bind_', 'lazy_bind_',
                                        'rebase_')
    ]
    d = ('\n'.join([str(_) for s in bind_s for _ in s])).encode('latin1')
    assertion('66bb196759c094c0c08d8159cf61d67f',
              hashlib.md5(d).hexdigest(),
              'dyldinfo-like output for dyld opcodes (libATCommand...)')
Ejemplo n.º 4
0
def test_MACHO_bin_sh(assertion):
    macho_bin = open(__dir__ + 'sh', 'rb').read()
    e = MACHO(macho_bin)
    macho_bin_hash = hashlib.md5(macho_bin).hexdigest()
    d = e.pack()
    assertion(macho_bin_hash,
              hashlib.md5(d).hexdigest(), 'Packing after reading /bin/sh')
Ejemplo n.º 5
0
def test_MACHO_one_loader(assertion):
    global log_history
    f = struct.pack("<IIIIIIIIII", macho.MH_MAGIC, macho.CPU_TYPE_I386, 0, 0,
                    1, 12, 0, macho.LC_PREBIND_CKSUM, 12, 0)
    e = MACHO(f)
    d = e.pack()
    assertion(f, d, 'Parsing data, with one LC_PREBIND_CKSU loader')
Ejemplo n.º 6
0
def test_MACHO_ios_decibels(assertion):
    global log_history
    macho_ios = open(__dir__ + 'Decibels', 'rb').read()
    e = MACHO(macho_ios)
    assertion([
        ('warn',
         ('Some encrypted text is not parsed with the section headers of LC_SEGMENT(__TEXT)',
          ), {}),
        ('warn',
         ('parse_dynamic_symbols() can only be used with x86 architectures, not %s',
          12), {}),
        ('warn', ('Part of the file was not parsed: %d bytes', 2499), {}),
        ('warn',
         ('Some encrypted text is not parsed with the section headers of LC_SEGMENT(__TEXT)',
          ), {}),
        ('warn',
         ('parse_dynamic_symbols() can only be used with x86 architectures, not %s',
          12), {}),
        ('warn', ('Part of the file was not parsed: %d bytes', 2495), {})
    ], log_history, 'Parsing Decibels iOS app (logs)')
    log_history = []
    macho_ios_hash = hashlib.md5(macho_ios).hexdigest()
    d = e.pack()
    assertion(macho_ios_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading iOS application Decibels')
    d = ('\n'.join([_ for a in e.arch for l in a.load
                    for _ in l.otool()])).encode('latin1')
    assertion('0d3281e546fd6e41306dbf38e5fbd0b6',
              hashlib.md5(d).hexdigest(),
              'Otool-like output for LC in iOS application')
Ejemplo n.º 7
0
def test_MACHO_unixthread_32(assertion):
    # The function changeMainToUnixThread migrates a Mach-O binary for
    # recent MacOSX (using a LC_MAIN loader) to a Mac-O binary for older
    # versions of MacOSX (10.7 and older, using a LC_UNIXTHREAD loader).
    macho_32 = open(__dir__ + 'macho_32.out', 'rb').read()
    e = MACHO(macho_32)
    changeMainToUnixThread(e)
    d = e.pack()
    assertion('1aa73a50d1b941c560f08c20926f9a05',
              hashlib.md5(d).hexdigest(),
              'Migrating from LC_MAIN to LC_UNIXTHREAD (32 bits)')
    insert_start_function(e)
    d = e.pack()
    assertion(
        '14e8007a3b5b5070c56ea2a43b6b888e',
        hashlib.md5(d).hexdigest(),
        'Migrating from LC_MAIN to LC_UNIXTHREAD with new segment (32 bits)')
Ejemplo n.º 8
0
def test_MACHO_macho64_exe(assertion):
    macho_64 = open(__dir__ + 'macho_64.out', 'rb').read()
    macho_64_hash = hashlib.md5(macho_64).hexdigest()
    e = MACHO(macho_64)
    d = e.pack()
    assertion(macho_64_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading 64-bit Mach-O executable')
Ejemplo n.º 9
0
def test_MACHO_empty_loader(assertion):
    f = struct.pack("<IIIIIIIII", macho.MH_MAGIC, macho.CPU_TYPE_I386, 0, 0, 1,
                    8, 0, 0, 8)
    e = MACHO(f)
    assertion(1, len(e.load),
              'Parsing data, with one empty loader (lhlist length)')
    d = e.pack()
    assertion(f, d, 'Parsing data, with one empty loader (pack)')
Ejemplo n.º 10
0
def test_MACHO_changeUUID(assertion):
    macho_64 = open(__dir__ + 'macho_64.out', 'rb').read()
    e = MACHO(macho_64)
    e.changeUUID("2A0405CF8B1F3502A605695A54C407BB")
    uuid_pos, = e.load.getpos(macho.LC_UUID)
    lh = e.load[uuid_pos]
    assertion((0x2A0405CF, 0x8B1F, 0x3502, 0xA605, 0x695A, 0x54C407BB),
              lh.uuid, 'UUID change')
    assertion('<LC_UUID 2A0405CF-8B1F-3502-A605-695A54C407BB>', repr(lh),
              'UUID change (repr)')
    d = e.pack()
    assertion('f86802506fb24de2ac2bebd9101326e9',
              hashlib.md5(d).hexdigest(), 'UUID change (pack)')
    lh.uuid = (0, 0xAAAA, 0, 0, 0, 0x11111111)
    assertion((0, 0xAAAA, 0, 0, 0, 0x11111111), lh.uuid, 'set UUID')
    d = e.pack()
    assertion('c8457df239deb4c51c316bd6670a445e',
              hashlib.md5(d).hexdigest(), 'set UUID (pack)')
Ejemplo n.º 11
0
def test_MACHO_extend_segment(assertion):
    macho_64 = open(__dir__ + 'macho_64.out', 'rb').read()
    e = MACHO(macho_64)
    for l in e.load:
        if getattr(l, 'segname', None) == "__LINKEDIT": break
    e.load.extendSegment(l, 0x1000)
    d = e.pack()
    assertion('405962fd8a4fe751c0ea4fe1a9d02c1e',
              hashlib.md5(d).hexdigest(), 'Extend segment')
    assertion([], log_history,
              'No non-regression test created unwanted log messages')
Ejemplo n.º 12
0
def test_MACHO_prebind_32(assertion):
    global log_history
    macho_32 = open(__dir__ + 'macho_32.out', 'rb').read()
    e = MACHO(macho_32)
    e.add(macho.LoadCommand(sex='<', wsize=32, cmd=0))
    d = e.pack()
    assertion('6fefeaf7b4de67f8270d3425942d7a97',
              hashlib.md5(d).hexdigest(), 'Adding an empty command (32 bits)')
    f = struct.pack("<III", macho.LC_ROUTINES_64, 12, 0)
    l = macho.prebind_cksum_command(parent=None, sex='<', wsize=32, content=f)
    assertion(
        [('warn', ('Incoherent input cmd=%#x for %s', 26,
                   'prebind_cksum_command'), {})], log_history,
        'Parsing incoherent load command prebind_cksum_command with LC_ROUTINES_64 tag (logs)'
    )
    log_history = []
    assertion(
        f, l.pack(),
        'Creating a LC_PREBIND_CKSUM (with content and incoherent subclass)')
    f = struct.pack("<III", macho.LC_PREBIND_CKSUM, 12, 0)
    l = macho.prebind_cksum_command(parent=None, sex='<', wsize=32, content=f)
    assertion(f, l.pack(),
              'Creating a LC_PREBIND_CKSUM (with content and subclass)')
    l = macho.LoadCommand(parent=None, sex='<', wsize=32, content=f)
    assertion(f, l.pack(), 'Creating a LC_PREBIND_CKSUM (from "content")')
    l = macho.LoadCommand(sex='<', wsize=32, cmd=macho.LC_PREBIND_CKSUM)
    assertion(f, l.pack(), 'Creating a LC_PREBIND_CKSUM (from "cmd")')
    e = MACHO(macho_32)
    e.add(l)
    d = e.pack()
    assertion('d7a33133a04126527eb6d270990092fa',
              hashlib.md5(d).hexdigest(), 'Adding a LC_PREBIND_CKSUM command')
    e = MACHO(macho_32)
    e.add(type=macho.LC_SEGMENT,
          segname='__NEWTEXT',
          initprot=macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
          content='some binary data'.encode('latin1'))
    d = e.pack()
    assertion('c4ad6da5422642cb15b91ccd3a09f592',
              hashlib.md5(d).hexdigest(), 'Adding a segment (32 bits)')
Ejemplo n.º 13
0
def test_MACHO_virt(assertion):
    macho_32 = open(__dir__ + 'macho_32.out', 'rb').read()
    e = MACHO(macho_32)
    d = e.virt[0x1f9c:0x1fae]
    assertion('structure definie\0', d.decode('latin1'),
              'Extract chunk from mapped memory, in a section (32 bits)')
    e.virt[0x1f9c] = 'Hello World\0'.encode('latin1')
    d = e.pack()
    assertion('16db05dfe60b5ac86c45d8324ef5cfc6',
              hashlib.md5(d).hexdigest(),
              'Writing in memory (address) (32 bits)')
    e.virt[0x1f9c:0x1fa8] = 'Hello World\0'.encode('latin1')
    d = e.pack()
    assertion('16db05dfe60b5ac86c45d8324ef5cfc6',
              hashlib.md5(d).hexdigest(),
              'Writing in memory (interval) (32 bits)')
    e.add(
        macho.Section(parent=macho.sectionHeader(parent=e.load),
                      content='arbitrary content'.encode('latin1')))
    d = e.pack()
    assertion('b61b686819bd3c94e765b220ef708353',
              hashlib.md5(d).hexdigest(), 'Adding a section (32 bits)')
Ejemplo n.º 14
0
def _get_code_sig(b: MACHO):
    # Get the offset of the signature from the header
    # It is under the LC_CODE_SIGNATURE command
    sigmeta = [cmd for cmd in b.load.lhlist if cmd.cmd == LC_CODE_SIGNATURE]
    if len(sigmeta) == 0:
        raise Exception("No embedded code signature sections")
    elif len(sigmeta) > 1:
        raise Exception("Multiple embedded code signature sections")
    sig_lc = sigmeta[0]
    sig_end = sig_lc.dataoff + sig_lc.datasize

    sig_data = b.pack()[sig_lc.dataoff:sig_end]
    return BytesIO(sig_data)
Ejemplo n.º 15
0
def test_MACHO_loader_lc_build_version(assertion):
    global log_history
    macho_lcbuild = open(__dir__ + 'macho_lcbuild.out', 'rb').read()
    macho_lcbuild_hash = hashlib.md5(macho_lcbuild).hexdigest()
    e = MACHO(macho_lcbuild)
    d = e.pack()
    assertion(macho_lcbuild_hash,
              hashlib.md5(d).hexdigest(),
              "Packing after reading executable with LC_BUILD_VERSION")
    d = ('\n'.join([_ for l in e.load for _ in l.otool()])).encode('latin1')
    assertion('6dd985753ccf51b0d5c7470126d43a6c',
              hashlib.md5(d).hexdigest(),
              'Otool-like output for LC in executable with LC_BUILD_VERSION')
Ejemplo n.º 16
0
def test_MACHO_macho32_obj(assertion):
    global log_history
    # Parsing and modifying files
    macho_32 = open(__dir__ + 'macho_32.o', 'rb').read()
    macho_32_hash = hashlib.md5(macho_32).hexdigest()
    e = MACHO(macho_32)
    d = e.pack()
    assertion(macho_32_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading 32-bit Mach-O object')
    assertion(e.entrypoint, -1, 'No entrypoint in a Mach-O object')
    assertion([('error', ('Not a unique loader with entrypoint: []', ), {})],
              log_history, 'No entrypoint in a Mach-O object (logs)')
    assertion(len(e.symbols), 3, 'Number of symbols in a Mach-O object')
    d = ("\n".join([_.otool() for _ in e.symbols])).encode('latin1')
    assertion('9543b68138927d012139e526f159846c',
              hashlib.md5(d).hexdigest(), 'Display symbols')
    assertion(
        e.symbols['_printf'].otool(),
        '_printf                             NO_SECT         UX   0x00000000 0000',
        'Find symbol by name')
    assertion('SymbolNotFound', e.symbols[10].__class__.__name__,
              'Find symbol by invalid index')
    e.symbols[0].sectionindex = 5
    assertion(
        e.symbols[0].otool(),
        '_a                                  INVALID(5)      SX   0x00000000 0000',
        'Display symbol with invalid section')
    e.symbols[0].sectionindex = 0xff
    assertion(
        e.symbols[0].otool(),
        '_a                                  INVALID(255)    SX   0x00000000 0000',
        'Display symbol with too big section index')
    log_history = []
    e.entrypoint = 0
    assertion([('error', ('Not a unique loader with entrypoint: []', ), {})],
              log_history, 'Cannot set entrypoint in a Mach-O object (logs)')
    log_history = []
    for s in e.sect.sect:
        if not hasattr(s, 'reloclist'): continue
        d = s.reloclist[0].pack()
        assertion('a8f95e95126c45ff26d5c838300443bc',
                  hashlib.md5(d).hexdigest(),
                  'Not scattered relocation in a 32-bit Mach-O object')
        d = s.reloclist[2].pack()
        assertion('4f66fe3447267f2bf90da8108ef10ba6',
                  hashlib.md5(d).hexdigest(),
                  'Scattered relocation in a 32-bit Mach-O object')
        break
Ejemplo n.º 17
0
def test_MACHO_lib_tls(assertion):
    macho_lib = open(__dir__ + 'libcoretls.dylib', 'rb').read()
    e = MACHO(macho_lib)
    macho_lib_hash = hashlib.md5(macho_lib).hexdigest()
    d = e.pack()
    assertion(macho_lib_hash,
              hashlib.md5(d).hexdigest(), 'Packing after reading libcoretls')
    bind_s = [
        _ for a in e.arch for _ in a.sect
        if getattr(_, 'type', None) in ('rebase_', 'export_')
    ]
    d = ('\n'.join([str(_) for s in bind_s for _ in s.info])).encode('latin1')
    assertion('d7983c780f70e8c81d277ee0f7f8a27d',
              hashlib.md5(d).hexdigest(),
              'dyldinfo-like output for rebase and export (libcoretls)')
Ejemplo n.º 18
0
def test_MACHO_lib_dns(assertion):
    global log_history
    macho_lib = open(__dir__ + 'libdns_services.dylib', 'rb').read()
    e = MACHO(macho_lib)
    assertion(e.entrypoint, -1, 'No entrypoint in a Mach-O library')
    assertion([('error', ('Not a unique loader with entrypoint: []', ), {})],
              log_history, 'No entrypoint in a Mach-O library (logs)')
    log_history = []
    macho_lib_hash = hashlib.md5(macho_lib).hexdigest()
    d = e.pack()
    assertion(macho_lib_hash,
              hashlib.md5(d).hexdigest(), 'Packing after reading DNS library')
    d = ('\n'.join([_ for l in e.load for _ in l.otool()])).encode('latin1')
    assertion('2d6194feedf82da26124d3128473a949',
              hashlib.md5(d).hexdigest(),
              'Otool-like output including LC_SOURCE_VERSION')
Ejemplo n.º 19
0
def test_MACHO_minimal(assertion):
    global log_history
    # Simple tests of object creation
    e = MACHO(struct.pack("<I", macho.MH_MAGIC))
    assertion([('warn', (
        'parse_dynamic_symbols() can only be used with x86 architectures, not %s',
        0), {})], log_history,
              'Parsing a minimal data, with Mach-O magic number only (logs)')
    log_history = []
    assertion(e.entrypoint, -1, 'No entrypoint in a truncated Mach-O header')
    assertion([('error', ('Not a unique loader with entrypoint: []', ), {})],
              log_history, 'No entrypoint in a truncated Mach-O header (logs)')
    log_history = []
    d = e.pack()
    assertion('37b830a1776346543c72ff53fbbe2b4a',
              hashlib.md5(d).hexdigest(),
              'Parsing a minimal data, with Mach-O magic number only')
Ejemplo n.º 20
0
def test_MACHO_app_OSXII(assertion):
    global log_history
    macho_app = open(__dir__ + 'OSXII', 'rb').read()
    e = MACHO(macho_app)
    assertion([('warn', (
        'parse_dynamic_symbols() can only be used with x86 architectures, not %s',
        18), {})], log_history, 'Parsing OSXII app (logs)')
    log_history = []
    macho_app_hash = hashlib.md5(macho_app).hexdigest()
    d = e.pack()
    assertion(macho_app_hash,
              hashlib.md5(d).hexdigest(), 'Packing after reading OSXII app')
    d = ('\n'.join(
        [_ for a in e.arch for l in a.load
         for _ in l.otool(llvm=7)])).encode('latin1')
    assertion('8b926db115b4cae5146774ef589674be',
              hashlib.md5(d).hexdigest(),
              'Otool-like output including ppc & i386 register state')
Ejemplo n.º 21
0
def test_MACHO_obj_telephony(assertion):
    global log_history
    macho_linkopt = open(__dir__ + 'TelephonyUtil.o', 'rb').read()
    macho_linkopt_hash = hashlib.md5(macho_linkopt).hexdigest()
    e = MACHO(macho_linkopt)
    assertion([('warn', ('Part of the file was not parsed: %d bytes', 6), {})],
              log_history, 'Parsing TelephonyUtil.o (logs)')
    log_history = []
    d = e.pack()
    assertion(
        macho_linkopt_hash,
        hashlib.md5(d).hexdigest(),
        "Packing after reading object file with LC_LINKER_OPTION, 'interval' option is needed because there is some nop padding at the end of __TEXT,__text"
    )
    d = ('\n'.join([_ for l in e.load for _ in l.otool()])).encode('latin1')
    assertion('984bf38084c14e435f30eebe36944b47',
              hashlib.md5(d).hexdigest(),
              'Otool-like output for LC in object file with LC_LINKER_OPTION')
Ejemplo n.º 22
0
def test_MACHO_lib_print(assertion):
    global log_history
    macho_32be = open(__dir__ + 'libPrintServiceQuota.1.dylib', 'rb').read()
    e = MACHO(macho_32be)
    assertion([('warn', (
        'parse_dynamic_symbols() can only be used with x86 architectures, not %s',
        18), {})], log_history, 'Parsing libPrintServiceQuota (logs)')
    log_history = []
    macho_32be_hash = hashlib.md5(macho_32be).hexdigest()
    d = e.pack()
    assertion(macho_32be_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading 32-bit big-endian Mach-O shared library')
    d = ('\n'.join([_ for l in e.load for _ in l.otool()])).encode('latin1')
    assertion(
        'cabaf4f4368c094bbb0c09f278510006',
        hashlib.md5(d).hexdigest(),
        'Otool-like output for LC in 32-bit big-endian Mach-O shared library')
Ejemplo n.º 23
0
def test_MACHO_exe_SH3D(assertion):
    global log_history
    macho_app = open(__dir__ + 'SweetHome3D', 'rb').read()
    e = MACHO(macho_app)
    assertion([('warn', (
        'parse_dynamic_symbols() can only be used with x86 architectures, not %s',
        18), {})], log_history, 'Parsing SweetHome3D app (logs)')
    log_history = []
    macho_app_hash = hashlib.md5(macho_app).hexdigest()
    d = e.pack()
    assertion(macho_app_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading SweetHome3D app')
    d = ('\n'.join([_ for a in e.arch for l in a.load
                    for _ in l.otool()])).encode('latin1')
    assertion('4bf0088471bd2161baf4a42dbb09dc5b',
              hashlib.md5(d).hexdigest(),
              'Otool-like output including ppc, i386 & x86_64register state')
Ejemplo n.º 24
0
def test_MACHO_app_MTR(assertion):
    global log_history
    macho_app = open(__dir__ + 'MacTheRipper', 'rb').read()
    e = MACHO(macho_app)
    assertion([('warn', (
        'parse_dynamic_symbols() can only be used with x86 architectures, not %s',
        18), {})], log_history, 'Parsing MacTheRipper app (logs)')
    log_history = []
    macho_app_hash = hashlib.md5(macho_app).hexdigest()
    d = e.pack()
    assertion(macho_app_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading MacTheRipper app')
    assertion(e.entrypoint, 0xa760, 'Entrypoint in MacTheRipper app')
    d = ('\n'.join([_ for l in e.load for _ in l.otool()])).encode('latin1')
    assertion('b10cd006c10906db3329e0dccd0babbe',
              hashlib.md5(d).hexdigest(),
              'Otool-like output including LC_PREBOUND_DYLIB')
Ejemplo n.º 25
0
def _dump_single(filename: str, b: MACHO):
    # Get the offset of the signature from the header
    # It is under the LC_CODE_SIGNATURE command
    sigmeta = [cmd for cmd in b.load.lhlist if cmd.cmd == LC_CODE_SIGNATURE]
    if len(sigmeta) == 0:
        raise Exception("No embedded code signature sections")
    elif len(sigmeta) > 1:
        raise Exception("Multiple embedded code signature sections")
    sig_lc = sigmeta[0]
    sig_end = sig_lc.dataoff + sig_lc.datasize

    sig_data = b.pack()[sig_lc.dataoff : sig_end]
    v = BytesIO(sig_data)

    sig_superblob = EmbeddedSignatureBlob()
    sig_superblob.deserialize(v)

    assert sig_superblob.code_dir_blob
    assert sig_superblob.sig_blob

    print(sig_superblob)
Ejemplo n.º 26
0
def test_MACHO_macho32_exe(assertion):
    global log_history
    macho_32 = open(__dir__ + 'macho_32.out', 'rb').read()
    macho_32_hash = hashlib.md5(macho_32).hexdigest()
    e = MACHO(macho_32)
    d = e.pack()
    assertion(macho_32_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading 32-bit Mach-O executable')
    assertion(e.entrypoint, 8000, 'entrypoint in a 32-bit Mach-O executable')
    assertion(e.virt.max_addr(), 16384,
              'Maximum address in a 32-bit Mach-O executable')
    e.entrypoint = 8010
    assertion(e.entrypoint, 8010,
              'Changing entrypoint in a 32-bit Mach-O executable')
    e.entrypoint = 9000
    assertion(e.entrypoint, 8010,
              'Changing entrypoint with an invalid address')
    assertion([('error', ('Address %#x not mapped in memory', 9000), {})],
              log_history,
              'Changing entrypoint with an invalid address (logs)')
    log_history = []
Ejemplo n.º 27
0
def test_MACHO_fat(assertion):
    global log_history
    macho_fat = open(__dir__ + 'macho_fat.out', 'rb').read()
    macho_fat_hash = hashlib.md5(macho_fat).hexdigest()
    e = MACHO(macho_fat)
    d = e.pack()
    assertion(macho_fat_hash,
              hashlib.md5(d).hexdigest(), 'Packing after reading fat Mach-O')
    assertion(e.virt.max_addr(), -1,
              'No unique maximum address in a Mach-O fat')
    assertion([('error', ('Not a unique memory mapping in Mach-O fat', ), {})],
              log_history, 'No unique maximum address in a Mach-O fat (logs)')
    log_history = []
    assertion(e.entrypoint, -1, 'Many entrypoints in a fat Mach-O')
    assertion([('error', ('Not a unique entrypoint in Mach-O fat', ), {})],
              log_history, 'Many entrypoints in a fat Mach-O (logs)')
    log_history = []
    e.entrypoint = 0
    assertion([('error', ('Not a unique entrypoint in Mach-O fat', ), {})],
              log_history,
              'Cannot set entrypoint directly in a fat Mach-O (logs)')
    log_history = []
Ejemplo n.º 28
0
def test_MACHO_lib_ecpg(assertion):
    macho_lib = open(__dir__ + 'libecpg.6.5.dylib', 'rb').read()
    e = MACHO(macho_lib)
    macho_lib_hash = hashlib.md5(macho_lib).hexdigest()
    d = e.pack()
    assertion(macho_lib_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading postgresql library')
    d = ('\n'.join([_ for l in e.load for _ in l.otool()])).encode('latin1')
    assertion('df729c8806748bba93ef960787036d37',
              hashlib.md5(d).hexdigest(),
              'Otool-like output including section size "past end of file"')
    d = ('\n'.join([_ for l in e.load
                    for _ in l.otool(llvm=7)])).encode('latin1')
    assertion(
        '7038d70ea2d7caf8b4a2adc3c9c01ef9',
        hashlib.md5(d).hexdigest(),
        'Otool-like output including section size "past end of file", llvm version 7'
    )
    assertion(
        e.symbols[1].otool(),
        'execute.c                           NO_SECT         0x4  D 0x00000000 0000',
        'Display symbol with N_STAB type')
Ejemplo n.º 29
0
def test_MACHO_lib_system(assertion):
    macho_lib = open(__dir__ + 'libSystem.B.dylib', 'rb').read()
    e = MACHO(macho_lib)
    macho_lib_hash = hashlib.md5(macho_lib).hexdigest()
    d = e.pack()
    assertion(macho_lib_hash,
              hashlib.md5(d).hexdigest(), 'Packing after reading libSystem')
    bind_s = [
        _ for a in e.arch for _ in a.sect
        if getattr(_, 'type', None) in ('rebase_', 'export_')
    ]
    d = ('\n'.join([str(_) for s in bind_s for _ in s.info])).encode('latin1')
    assertion('81bc735570cb8f78099579fcf6a29f65',
              hashlib.md5(d).hexdigest(),
              'dyldinfo-like output for rebase and export (libSystem)')
    bind_s = [
        _ for a in e.arch for _ in a.sect
        if getattr(_, 'type', None) == 'rebase_'
    ]
    d = ('\n'.join([str(_) for s in bind_s for _ in s])).encode('latin1')
    assertion('c71cebc604ba70bfd348a3e08f7ea20c',
              hashlib.md5(d).hexdigest(),
              'dyldinfo-like output for rebase opcodes (libSystem)')
Ejemplo n.º 30
0
def test_MACHO_ios_lyonmetro(assertion):
    global log_history
    macho_ios = open(__dir__ + 'LyonMetro', 'rb').read()
    e = MACHO(macho_ios)
    assertion([
        ('warn',
         ('Some encrypted text is not parsed with the section headers of LC_SEGMENT(__TEXT)',
          ), {}),
        ('warn',
         ('parse_dynamic_symbols() can only be used with x86 architectures, not %s',
          12), {}),
        ('warn', ('Part of the file was not parsed: %d bytes', 3908), {})
    ], log_history, 'Parsing LyonMetro iOS app (logs)')
    log_history = []
    macho_ios_hash = hashlib.md5(macho_ios).hexdigest()
    d = e.pack()
    assertion(macho_ios_hash,
              hashlib.md5(d).hexdigest(),
              'Packing after reading iOS application LyonMetro')
    assertion(e.entrypoint, 0x2f50, 'Entrypoint in iOS application LyonMetro')
    d = ('\n'.join([_ for l in e.load for _ in l.otool()])).encode('latin1')
    assertion('7bac82cc00b5cce2cb96344d678508e5',
              hashlib.md5(d).hexdigest(),
              'Otool-like output including LC_VERSION_MIN_IPHONEOS')