Пример #1
0
def test_stream():
    dirpath = os.path.join(test_location, "i386")
    filepath = os.path.join(dirpath, "fauxware")
    lib1path = os.path.join(dirpath, "libc.so.6")
    lib2path = os.path.join(dirpath, "ld-linux.so.2")

    path_ld = cle.Loader(filepath)
    stream_ld = cle.Loader(open(filepath, 'rb'),
                           auto_load_libs=False,
                           preload_libs=(open(lib1path,
                                              'rb'), open(lib2path, 'rb')))

    nose.tools.assert_equal(path_ld.main_object.entry,
                            stream_ld.main_object.entry)
    nose.tools.assert_equal(
        [x for x in path_ld.shared_objects.keys() if x != 'fauxware'],
        list(stream_ld.shared_objects.keys()))
    nose.tools.assert_equal(
        path_ld.memory.unpack_word(path_ld.main_object.entry),
        stream_ld.memory.unpack_word(stream_ld.main_object.entry))
    strcmp_string = path_ld.describe_addr(
        path_ld.memory.unpack_word(0x804a000))
    nose.tools.assert_in('libc.so.6', strcmp_string)
    nose.tools.assert_in('strcmp', strcmp_string)
    nose.tools.assert_equal(
        strcmp_string,
        stream_ld.describe_addr(stream_ld.memory.unpack_word(0x804a000)))
Пример #2
0
def test_stream():
    dirpath = os.path.join(test_location, "i386")
    filepath = os.path.join(dirpath, "fauxware")
    lib1path = os.path.join(dirpath, "libc.so.6")
    lib2path = os.path.join(dirpath, "ld-linux.so.2")

    path_ld = cle.Loader(filepath)

    lib1 = cle.Loader.load_object(open(lib1path, 'rb'))
    lib2 = cle.Loader.load_object(open(lib2path, 'rb'))
    stream_ld = cle.Loader(open(filepath, 'rb'),
                           auto_load_libs=False,
                           force_load_libs=(lib1, lib2))

    nose.tools.assert_equal(path_ld.main_bin.entry, stream_ld.main_bin.entry)
    nose.tools.assert_equal(path_ld.shared_objects.keys(),
                            stream_ld.shared_objects.keys())
    nose.tools.assert_equal(
        path_ld.memory.read_addr_at(path_ld.main_bin.entry),
        stream_ld.memory.read_addr_at(stream_ld.main_bin.entry))
    strcmp_string = path_ld.whats_at(path_ld.memory.read_addr_at(0x804a000))
    nose.tools.assert_in('libc.so.6', strcmp_string)
    nose.tools.assert_in('strcmp', strcmp_string)
    nose.tools.assert_equal(
        strcmp_string,
        stream_ld.whats_at(stream_ld.memory.read_addr_at(0x804a000)))
Пример #3
0
    def fire(self, return_loader=False, **kwargs): #pylint:disable=arguments-differ
        if self.project is None:

            the_binary = self.target.resolve_local_path(self.target.target_path)

            # preload the binary to decide if it supports setting library options or base addresses
            preloader = cle.Loader(the_binary, **kwargs)
            if preloader.main_object.os == "cgc":
                # CGC binaries do not have libraries to load
                the_libs = { }
                lib_opts = { }
                # CGC binaries cannot be rebased
                bin_opts = { }
                self._mem_mapping = { }
            else:
                _,_,_,self._mem_mapping = self.scout_bow.fire()
                the_libs = [ self.target.resolve_local_path(lib) for lib in self._mem_mapping if lib.startswith("/") ]
                lib_opts = { os.path.basename(lib) : {'base_addr' : libaddr} for lib, libaddr in self._mem_mapping.items() }
                bin_opts = { "base_addr": 0x555555554000 }

            if return_loader:
                return cle.Loader(the_binary, preload_libs=the_libs, lib_opts=lib_opts, main_opts=bin_opts, **kwargs)
            self.project = angr.Project(the_binary, preload_libs=the_libs, lib_opts=lib_opts, main_opts=bin_opts, **kwargs)

            if self.static_simproc:
                self._apply_simprocedures()

        if return_loader:
            return self.project.loader
        return self.project
Пример #4
0
    def _run(self, inst):
        self._progress_callback(5)

        partial_ld = None
        try:
            # Try automatic loading
            partial_ld = cle.Loader(self.fname,
                                    perform_relocations=False,
                                    load_debug_info=False)
        except archinfo.arch.ArchNotFound as e:
            partial_ld = cle.Loader(self.fname,
                                    perform_relocations=False,
                                    load_debug_info=False,
                                    arch='x86')
            gui_thread_schedule(LoadBinary.binary_arch_detect_failed,
                                (self.fname, str(e)))
        except cle.CLECompatibilityError:
            # Continue loading as blob
            pass

        if partial_ld is None:
            try:
                # Try loading as blob; dummy architecture (x86) required, user will select proper arch
                partial_ld = cle.Loader(self.fname,
                                        main_opts={
                                            'backend': 'blob',
                                            'arch': 'x86'
                                        })
            except cle.CLECompatibilityError:
                # Failed to load executable, even as blob!
                gui_thread_schedule(LoadBinary.binary_loading_failed,
                                    (self.fname, ))
                return

        self._progress_callback(50)
        new_load_options, cfg_args, variable_recovery_args = gui_thread_schedule(
            LoadBinary.run, (partial_ld, ))
        if cfg_args is None:
            return

        engine = None
        if hasattr(new_load_options['arch'], 'pcode_arch'):
            engine = angr.engines.UberEnginePcode

        self.load_options.update(new_load_options)

        proj = angr.Project(self.fname,
                            load_options=self.load_options,
                            engine=engine)
        self._progress_callback(95)

        def callback():
            inst._reset_containers()
            inst.project.am_obj = proj
            inst.project.am_event(
                cfg_args=cfg_args,
                variable_recovery_args=variable_recovery_args)

        gui_thread_schedule(callback, ())
Пример #5
0
    def fire(self, return_loader=False, **kwargs):  #pylint:disable=arguments-differ
        if self.project is None:

            the_binary = self.target.resolve_local_path(
                self.target.target_path)

            # preload the binary to decide if it supports setting library options or base addresses
            cle_args = dict(kwargs)
            cle_args.update(cle_args.pop('load_options', {}))
            cle_args.pop('use_sim_procedures',
                         None)  # TODO do something less hacky than this
            preload_kwargs = dict(cle_args)
            preload_kwargs['auto_load_libs'] = False
            preloader = cle.Loader(the_binary, **preload_kwargs)

            if self.scout_bow is not None:
                _, _, _, self._mem_mapping = self.scout_bow.fire()
                the_libs = [
                    self.target.resolve_local_path(lib)
                    for lib in self._mem_mapping if lib.startswith("/")
                ]
                lib_opts = {
                    os.path.basename(lib): {
                        'base_addr': libaddr
                    }
                    for lib, libaddr in self._mem_mapping.items()
                }
                bin_opts = {
                    "base_addr": 0x555555554000
                } if preloader.main_object.pic else {}
            else:
                the_libs = {}
                lib_opts = {}
                bin_opts = {}
            self._mem_mapping = {}

            if return_loader:
                return cle.Loader(the_binary,
                                  preload_libs=the_libs,
                                  lib_opts=lib_opts,
                                  main_opts=bin_opts,
                                  **cle_args)
            self.project = angr.Project(the_binary,
                                        preload_libs=the_libs,
                                        lib_opts=lib_opts,
                                        main_opts=bin_opts,
                                        **kwargs)

            if self.static_simproc:
                self._apply_simprocedures()

        if return_loader:
            return self.project.loader
        return self.project
Пример #6
0
def main():
    r = socket.socket()
    r.connect(("172.17.0.1", 2323))
    recvline(r)
    recvline(r)
    recvline(r)
    recvline(r)

    for i in range(50):
        print("Iteration %d" % i)
        bine = recvline(r)
        obj = cle.Loader(StringIO.StringIO(bine.decode("base64")))
        proj = angr.Project(obj)
        cfg = proj.analyses.CFG()
        for j in proj.kb.functions:
            if proj.kb.functions[j].name == "success":
                success = proj.kb.functions[j].addr
            if proj.kb.functions[j].name == "failure":
                failure = proj.kb.functions[j].addr
        pg = proj.factory.path_group().explore(find=success, avoid=failure)
        if pg.found:
            solution = pg.found[0].state.posix.dumps(0)
            print("Found input to %d: %s" % (i, solution))
            r.sendall(solution)
        else:
            print("Failure to find a solution on iteration %d" % i)
            exit()

    flag = recvline(r)
    print flag
Пример #7
0
def test_minidump():
    exe = os.path.join(TEST_BASE, 'tests', 'x86', 'windows', 'jusched_x86.dmp')
    ld = cle.Loader(exe, auto_load_libs=False)
    nose.tools.assert_is_instance(ld.main_object, cle.Minidump)
    nose.tools.assert_is_instance(ld.main_object.arch, archinfo.ArchX86)
    nose.tools.assert_equal(ld.main_object.os, 'windows')
    nose.tools.assert_equal(len(ld.main_object.segments), 30)

    sections_map = ld.main_object.sections_map
    nose.tools.assert_in('jusched.exe', sections_map)
    nose.tools.assert_in('kernel32.dll', sections_map)

    nose.tools.assert_equal(len(ld.main_object.threads), 2)
    registers = ld.main_object.thread_registers(0x0548)
    nose.tools.assert_is_instance(registers, dict)
    nose.tools.assert_equal(
        registers, {
            'gs': 43,
            'fs': 83,
            'edi': 2001343136,
            'esi': 2001343136,
            'ebx': 0,
            'edx': 2001343136,
            'ecx': 2001343136,
            'eax': 2121117696,
            'ebp': 33357196,
            'eip': 2000776736,
            'eflags': 580,
            'esp': 33357152
        })
Пример #8
0
def test_gxx_exception_0():

    # Test if we can load exception handlings generated by g++ 7.4.0
    binary = os.path.join(TEST_BASE, "x86_64", "exceptions_0")
    ld = cle.Loader(binary, load_debug_info=True, auto_load_libs=False)

    nose.tools.assert_equal(len(ld.main_object.exception_handlings), 4)
    exception_handlings = dict(
        (exc.start_addr, exc) for exc in ld.main_object.exception_handlings)
    nose.tools.assert_equal(len(exception_handlings), 4)
    # 0x400a61
    nose.tools.assert_equal(exception_handlings[0x400a61].start_addr, 0x400a61)
    nose.tools.assert_equal(exception_handlings[0x400a61].size, 0x1a)
    nose.tools.assert_equal(exception_handlings[0x400a61].func_addr, 0x400a4a)
    nose.tools.assert_equal(exception_handlings[0x400a61].handler_addr,
                            0x400a82)
    # 0x400a98
    nose.tools.assert_equal(exception_handlings[0x400a98].start_addr, 0x400a98)
    nose.tools.assert_equal(exception_handlings[0x400a98].size, 0x1a)
    nose.tools.assert_equal(exception_handlings[0x400a98].func_addr, 0x400a4a)
    nose.tools.assert_equal(exception_handlings[0x400a98].handler_addr,
                            0x400ab9)
    # 0x400ab2
    nose.tools.assert_equal(exception_handlings[0x400ab2].start_addr, 0x400ab2)
    nose.tools.assert_equal(exception_handlings[0x400ab2].size, 0x5)
    nose.tools.assert_equal(exception_handlings[0x400ab2].func_addr, 0x400a4a)
    nose.tools.assert_equal(exception_handlings[0x400ab2].handler_addr, None)
    # 0x400ac7
    nose.tools.assert_equal(exception_handlings[0x400ac7].start_addr, 0x400ac7)
    nose.tools.assert_equal(exception_handlings[0x400ac7].size, 0x5)
    nose.tools.assert_equal(exception_handlings[0x400ac7].func_addr, 0x400a4a)
    nose.tools.assert_equal(exception_handlings[0x400ac7].handler_addr, None)
Пример #9
0
def test_mipsel():
    ping = os.path.join(test_location, 'mipsel', 'darpa_ping')
    skip = ['libgcc_s.so.1', 'libresolv.so.0']
    ld = cle.Loader(ping, skip_libs=skip)
    dep = set(ld._satisfied_deps)
    loadedlibs = set(ld.shared_objects)

    # 1) check dependencies and loaded binaries
    nose.tools.assert_true(
        dep.issuperset(
            {'libresolv.so.0', 'libgcc_s.so.1', 'libc.so.6', 'ld.so.1'}))
    nose.tools.assert_true(loadedlibs.issuperset({'libc.so.6', 'ld.so.1'}))

    # 2) Check GOT slot containts the right address
    # Cle: 4494036
    # got = ld.find_symbol_got_entry('__uClibc_main')
    # addr = ld.memory.read_addr_at(got)
    # nose.tools.assert_equal(addr, sproc_addr)
    # TODO: Get the right version of uClibc and devise a test that doesn't use angr

    ioctl = ld.find_relevant_relocations("ioctl").next()
    setsockopt = ld.find_relevant_relocations("setsockopt").next()

    nose.tools.assert_equal(ioctl.rebased_addr, 4494300)
    nose.tools.assert_equal(setsockopt.rebased_addr, 4494112)
Пример #10
0
def test_fauxware():
    machofile = os.path.join(TEST_BASE, 'tests', 'x86_64', 'fauxware.macho')
    ld = cle.Loader(machofile, auto_load_libs=False)
    nose.tools.assert_true(isinstance(ld.main_object,cle.MachO))
    nose.tools.assert_equal(ld.main_object.os, 'macos')
    nose.tools.assert_equal(ld.main_object.entry, 0x100000de0)
    nose.tools.assert_equal(sorted(list(ld.main_object.exports_by_name))[-1], '_sneaky')
Пример #11
0
def test_ppc():
    libc = os.path.join(test_location, 'ppc', 'libc.so.6')
    ld = cle.Loader(libc, auto_load_libs=True, main_opts={'custom_base_addr': 0})
    # This tests the relocation of _rtld_global_ro in ppc libc6.
    # This relocation is of type 20, and relocates a non-local symbol
    relocated = ld.memory.read_addr_at(0x18ace4)
    nose.tools.assert_equal(relocated % 0x1000, 0xf666e320 % 0x1000)
Пример #12
0
def hook_entry(binary, asm_code=None, bin_code=None):
    main_bin = io.BytesIO(binary)
    b = cle.Loader(main_bin,
                   auto_load_libs=False,
                   perform_relocations=False,
                   main_opts={'base_addr': 0})
    start_addr = b.main_object.addr_to_offset(b.main_object.entry)
    arch = b.main_object.arch
    if arch.name in ('ARMHF', 'ARMEL') and arch.is_thumb(
            start_addr):  # OMG, thumb mode is a disaster
        start_addr &= (~1)  # recover the real address
        main_bin.seek(start_addr)
        padding = (4 - (start_addr + 8) %
                   4) % 4  # we hardcode the shellcode so that its length is 8

        # we can' use arch.asm here because the shellcode THUMB, 8+padding-4 because the shellcode has length 8+padding,
        # we also need to take into account that in arm, pc points to two instructions ahead, which is 4 bytes in thumb mode
        main_bin.write(b'xF\x00\xf1' + struct.pack('<H', 8 + padding - 4) +
                       b'\x00G' + b'A' * padding)

        # now place our payload after this mini shellcode
        start_addr += 8 + padding
    main_bin.seek(start_addr)
    main_bin.write(b.main_object.arch.asm(asm_code) if asm_code else bin_code)
    main_bin.seek(0)
    return main_bin.read()
Пример #13
0
    def load(session):

        all_objects = {}  # path to object
        main_object = None

        db_objects = session.query(DbObject)  # type: List[DbObject]

        for db_o in db_objects:
            all_objects[db_o.path] = db_o
            if db_o.main_object:
                main_object = db_o

        if main_object is None:
            raise AngrCorruptDBError("Corrupt database: No main object.")

        # build params
        # FIXME: Load other objects

        loader = cle.Loader(BytesIO(main_object.content), )

        # fix the binary name of the main binary
        loader._main_binary_path = main_object.path
        loader.main_object.binary = main_object.path

        return loader
Пример #14
0
def test_blob_0():

    BASE_ADDR = 0x8000000
    ENTRYPOINT = 0x8001337

    blob_file = os.path.join(TEST_BASE, 'tests', 'i386', 'all')
    blob_file_size = os.stat(blob_file).st_size
    ld = cle.Loader(blob_file, main_opts={
        'backend': 'blob',
        'base_addr': BASE_ADDR,
        'entry_point': ENTRYPOINT,
        'arch': "ARM",
    })

    nose.tools.assert_equal(ld.main_object.linked_base, BASE_ADDR)
    nose.tools.assert_equal(ld.main_object.mapped_base, BASE_ADDR)
    nose.tools.assert_equal(ld.main_object.min_addr, BASE_ADDR)
    nose.tools.assert_equal(ld.main_object.max_addr, BASE_ADDR + blob_file_size - 1)
    nose.tools.assert_equal(ld.main_object.entry, ENTRYPOINT)
    nose.tools.assert_true(ld.main_object.contains_addr(BASE_ADDR))
    nose.tools.assert_false(ld.main_object.contains_addr(BASE_ADDR - 1))

    # ensure that pickling works
    ld_pickled = pickle.loads(pickle.dumps(ld))
    nose.tools.assert_equal(ld_pickled.main_object.mapped_base, BASE_ADDR)
Пример #15
0
def test_local_symbol_reloc():
    filename = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                            '../../binaries/tests/armel/btrfs.ko')
    ld = cle.Loader(filename)

    # readelf -r btrfs.ko
    # Relocation section '.rel.init.text' at offset 0xfe318 contains 94 entries
    # Offset     Info    Type            Sym.Value  Sym. Name
    # 000000b4  00003c2b R_ARM_MOVW_ABS_NC 00000000   .LANCHOR0
    # 000000b8  00003c2c R_ARM_MOVT_ABS    00000000   .LANCHOR0
    # there are multiple symbols with name .LANCHOR0, those relocations shall
    # point to the first byte of .data section

    init_text_vaddr = ld.main_object.sections_map['.init.text'].vaddr
    data_vaddr = ld.main_object.sections_map['.data'].vaddr

    reloc_abs_nc = None
    reloc_abs = None
    for r in ld.main_object.relocs:
        if r.rebased_addr == init_text_vaddr + 0xb4:
            reloc_abs_nc = r
        if r.rebased_addr == init_text_vaddr + 0xb8:
            reloc_abs = r

    nose.tools.assert_is_not_none(reloc_abs_nc)
    nose.tools.assert_equals(data_vaddr, reloc_abs_nc.resolvedby.rebased_addr)
    nose.tools.assert_is_not_none(reloc_abs)
    nose.tools.assert_equals(data_vaddr, reloc_abs.resolvedby.rebased_addr)
Пример #16
0
def check_plt_entries(filename):
    real_filename = os.path.join(TESTS_BASE, 'tests', filename)
    ld = cle.Loader(real_filename, auto_load_libs=False, main_opts={'base_addr': 0})

    if filename == os.path.join('ppc', 'libc.so.6'):
        # objdump can't find PLT stubs for this...
        nose.tools.assert_not_equal(ld.main_object._plt, {})
        sorted_keys = sorted(ld.main_object._plt.values())
        diffs = [y - x for x, y in zip(sorted_keys, sorted_keys[1:])]
        nose.tools.assert_equal(diffs, [4]*len(diffs))
        return

    # all our mips samples have no PLT, just resolver stubs
    if filename.startswith('mips'):
        nose.tools.assert_equal(ld.main_object.plt, {})
        return

    if filename == os.path.join('armel', 'helloworld'):
        nose.tools.assert_equal(ld.main_object.plt, {'printf': 0x102e0, '__libc_start_main': 0x102ec,
                                                   '__gmon_start__': 0x102f8, 'abort': 0x10304
                                                   }
                                )
        return

    if filename == os.path.join('x86_64', 'true'):
        nose.tools.assert_equal(ld.main_object.plt, {u'__uflow': 0x1440, u'getenv': 0x1448, u'free': 0x1450, u'abort': 0x1458, u'__errno_location': 0x1460, u'strncmp': 0x1468, u'_exit': 0x1470, u'__fpending': 0x1478, u'textdomain': 0x1480, u'fclose': 0x1488, u'bindtextdomain': 0x1490, u'dcgettext': 0x1498, u'__ctype_get_mb_cur_max': 0x14a0, u'strlen': 0x14a8, u'__stack_chk_fail': 0x14b0, u'mbrtowc': 0x14b8, u'strrchr': 0x14c0, u'lseek': 0x14c8, u'memset': 0x14d0, u'fscanf': 0x14d8, u'close': 0x14e0, u'memcmp': 0x14e8, u'fputs_unlocked': 0x14f0, u'calloc': 0x14f8, u'strcmp': 0x1500, u'memcpy': 0x1508, u'fileno': 0x1510, u'malloc': 0x1518, u'fflush': 0x1520, u'nl_langinfo': 0x1528, u'ungetc': 0x1530, u'__freading': 0x1538, u'realloc': 0x1540, u'fdopen': 0x1548, u'setlocale': 0x1550, u'__printf_chk': 0x1558, u'error': 0x1560, u'open': 0x1568, u'fseeko': 0x1570, u'__cxa_atexit': 0x1578, u'exit': 0x1580, u'fwrite': 0x1588, u'__fprintf_chk': 0x1590, u'mbsinit': 0x1598, u'iswprint': 0x15a0, u'__cxa_finalize': 0x15a8, u'__ctype_b_loc': 0x15b0})
        return

    ld.main_object._plt.pop('__gmon_start__', None)

    replaced_filename = filename.replace('\\', '/')
    if replaced_filename not in PLT_CACHE:
        p1 = subprocess.Popen(['objdump', '-d', real_filename], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['grep', '@plt>:'], stdin=p1.stdout, stdout=subprocess.PIPE)
        p1.stdout.close()
        dat, _ = p2.communicate()
        lines = dat.decode().strip().split('\n')

        ideal_plt = {}
        for line in lines:
           addr, ident = line.split()
           addr = int(addr, 16)
           name = ident.split('@')[0].strip('<')
           if '*' in name or name == '__gmon_start__':
               continue
           ideal_plt[name] = addr

        if filename == os.path.join('armhf', 'libc.so.6'):
           # objdump does these cases wrong as far as I can tell?
           # or maybe not wrong just... different
           # there's a prefix to this stub that jumps out of thumb mode
           # cle finds the arm stub, objdump finds the thumb prefix
           ideal_plt['free'] += 4
           ideal_plt['malloc'] += 4
        print("Regenerated ideal PLT for %s as %s", filename, ideal_plt)
        PLT_CACHE[filename.replace('\\', '/')] = ideal_plt

    ideal_plt = PLT_CACHE[replaced_filename]
    nose.tools.assert_equal(ideal_plt, ld.main_object.plt)
Пример #17
0
def run_sections(arch, filename, sections):

    binary_path = os.path.join(TESTS_BASE, arch, filename)

    ld = cle.Loader(binary_path, auto_load_libs=False)

    nose.tools.assert_equal(len(ld.main_object.sections), len(sections))
    for i, section in enumerate(ld.main_object.sections):
        nose.tools.assert_equal(section.name, sections[i].name)
        nose.tools.assert_equal(section.offset, sections[i].offset)
        nose.tools.assert_equal(
            AT.from_mva(section.vaddr, ld.main_object).to_lva(),
            sections[i].vaddr)
        nose.tools.assert_equal(section.memsize, sections[i].memsize)

    # address lookups
    nose.tools.assert_is_none(
        ld.main_object.sections.find_region_containing(-1))

    # skip all sections that are not mapped into memory
    mapped_sections = [section for section in sections if section.vaddr != 0]

    for section in mapped_sections:
        nose.tools.assert_equal(
            ld.main_object.find_section_containing(section.vaddr).name,
            section.name)
        nose.tools.assert_equal(
            ld.main_object.sections.find_region_containing(section.vaddr).name,
            section.name)
        if section.memsize > 0:
            nose.tools.assert_equal(
                ld.main_object.find_section_containing(section.vaddr + 1).name,
                section.name)
            nose.tools.assert_equal(
                ld.main_object.sections.find_region_containing(section.vaddr +
                                                               1).name,
                section.name)
            nose.tools.assert_equal(
                ld.main_object.find_section_containing(section.vaddr +
                                                       section.memsize -
                                                       1).name, section.name)
            nose.tools.assert_equal(
                ld.main_object.sections.find_region_containing(
                    section.vaddr + section.memsize - 1).name, section.name)

    for i in range(len(mapped_sections) - 1):
        sec_a, sec_b = mapped_sections[i], mapped_sections[i + 1]
        if sec_a.vaddr + sec_a.memsize < sec_b.vaddr:
            # there is a gap between sec_a and sec_b
            for j in range(min(sec_b.vaddr - (sec_a.vaddr + sec_a.memsize),
                               20)):
                a = sec_a.vaddr + sec_a.memsize + j
                nose.tools.assert_is_none(
                    ld.main_object.find_section_containing(a))
                nose.tools.assert_is_none(
                    ld.main_object.sections.find_region_containing(a))

    nose.tools.assert_is_none(
        ld.main_object.find_section_containing(0xffffffff), None)
Пример #18
0
def test_empty_segements():
    """
    Test for bizarre ELves #1: Energy Micro's compiler makes empty segments

    :return:
    """
    path = os.path.join(test_location, "armel", "efm32gg.elf")
    cle.Loader(path, rebase_granularity=0x1000)
Пример #19
0
def test_relocated():
    filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../binaries/tests/i386/fauxware')
    shared = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../binaries/tests/i386/prelinked')
    ld = cle.Loader(filename, ld_path=[shared], rebase_granularity=0x1000000)
    nose.tools.assert_equal(ld.main_object.mapped_base, 0x8048000)
    nose.tools.assert_sequence_equal(
        [x.mapped_base for x in ld.all_elf_objects],
        [0x8048000, 0x9000000, 0xA000000]
    )
Пример #20
0
def binary_loaded_info(app_bin):

    # First, get binary type: executable or shared object(PIE)
    bin_type = "executable"
    app_bin = os.path.realpath(app_bin)
    file_info = os.popen("file " + app_bin)
    if "shared object" in file_info.read():
        bin_type = "shared_object"
    print "binary type is ", bin_type

    # Now load binary, calculate program loaded base, entry, text_min and text_max
    ld = cle.Loader(app_bin)
    bin_code = ""

    base_addr = ld.main_object.sections[0].vaddr
    entry = ld.main_object.entry
    print "Program base by cle: ", hex(base_addr)
    print "Program entry by cle: ", hex(entry)
    for i in ld.main_object.sections:
        if i.name == ".text":
            text_min = i.vaddr
            text_max = i.vaddr + i.filesize
            raw_bytes = ld.memory.read_bytes(i.vaddr, i.filesize)
            for byte in raw_bytes:
                bin_code += byte
            break

    #Third, write raw binary code to file
    raw_bin = "." + os.path.basename(app_bin) + ".text"
    f = open(raw_bin, "wb")
    if not f:
        print "open file " + raw_bin + " for writing failed."
        sys.exit(-1)

    f.write(bin_code)
    f.close()

    # Now we have to recalcuate the loaded addresses for Position-independent executables
    if bin_type == "shared_object":
        text_min -= base_addr
        text_max -= base_addr
        entry -= base_addr
        base_addr = 0x0

        base_addr = 0x555555554000
        text_min += base_addr
        text_max += base_addr
        entry += base_addr

    bin_loaded_info = {
        'base': base_addr,
        'entry': entry,
        'text_min': text_min,
        'text_max': text_max,
        'raw_bin': raw_bin
    }
    return bin_loaded_info
Пример #21
0
def test_hex():
    machofile = os.path.join(TEST_BASE, 'tests', 'armel',
                             'i2c_master_read-arduino_mzero.hex')
    ld = cle.Loader(machofile,
                    auto_load_libs=False,
                    main_opts={'custom_arch': "ARMEL"})
    nose.tools.assert_true(isinstance(ld.main_object, cle.Hex))
    nose.tools.assert_equals(ld.main_object.os, 'unknown')
    nose.tools.assert_equals(ld.main_object.entry, 0x44cd)
Пример #22
0
def test_lifting(pth, startOverride = False, numBytes = 0x1000):	

	ld = cle.Loader(str(os.path.join(os.path.dirname(os.path.realpath(__file__)),pth)))
	start = startOverride if startOverride != False else ld.main_object.entry 
	bytes = ld.memory.read_bytes(start, numBytes)
	bytes=''.join(bytes)
	
	l = helpers_sh4.LifterSH4(arch_sh4.ArchSH4(), start, bytes, revBytes=False)
		
	l.irsb.pp()
Пример #23
0
def test_first_fit():
    filename = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                            '../../binaries/tests/x86_64/cfg_0')

    ld = cle.Loader(filename)
    nose.tools.assert_less(ld.main_object.mapped_base,
                           ld.shared_objects['libc.so.6'].mapped_base)
    nose.tools.assert_less(
        ld.shared_objects['libc.so.6'].mapped_base,
        ld.shared_objects['ld-linux-x86-64.so.2'].mapped_base)

    #[<ELF Object cfg_0, maps [0x400000:0x601047]>,
    # <ELF Object libc.so.6, maps [0x1000000:0x13c42bf]>,
    # <ELF Object ld-linux-x86-64.so.2, maps [0x2000000:0x22241c7]>,
    # <ELFTLSObj Object ##cle_tls##, maps [0x3000000:0x3030000]>]

    ld = cle.Loader(filename, lib_opts={'libc.so.6': {'base_addr': 0x1234000}})
    nose.tools.assert_less(
        ld.main_object.mapped_base,
        ld.shared_objects['ld-linux-x86-64.so.2'].mapped_base)
    nose.tools.assert_less(
        ld.shared_objects['ld-linux-x86-64.so.2'].mapped_base,
        ld.shared_objects['libc.so.6'].mapped_base)

    #[<ELF Object cfg_0, maps [0x400000:0x601047]>,
    # <ELF Object ld-linux-x86-64.so.2, maps [0x1000000:0x12241c7]>,
    # <ELF Object libc.so.6, maps [0x1234000:0x15f82bf]>,
    # <ELFTLSObj Object ##cle_tls##, maps [0x2000000:0x2030000]>]

    ld = cle.Loader(filename,
                    lib_opts={
                        'libc.so.6': {
                            'base_addr': 0x1234000
                        },
                        'ld-linux-x86-64.so.2': {
                            'base_addr': 0
                        }
                    })
    nose.tools.assert_less(
        ld.shared_objects['ld-linux-x86-64.so.2'].mapped_base,
        ld.main_object.mapped_base)
    nose.tools.assert_less(ld.main_object.mapped_base,
                           ld.shared_objects['libc.so.6'].mapped_base)
Пример #24
0
def test_progname():
    filename = os.path.join(test_location, 'x86_64', 'cat')
    ld = cle.Loader(filename, auto_load_libs=False)
    progname_ptr_symbol = ld.find_symbol('__progname')
    progname_ptr = ld.memory.unpack_word(progname_ptr_symbol.rebased_addr)

    nose.tools.assert_not_equal(progname_ptr, 0)

    progname = ld.memory.load(progname_ptr, 8)
    nose.tools.assert_equal(progname, b'program\0')
Пример #25
0
def test_remote_file_mapper():
    directory_for_binaries = get_binary_directory()
    remote_file_mapper = lambda x: x.replace("/tmp/foobar/does-not-exist",
                                             directory_for_binaries)
    ld = cle.Loader(get_coredump_file(),
                    main_opts={
                        "backend": "elfcore",
                        "remote_file_mapper": remote_file_mapper
                    })
    check_objects_loaded(ld)
Пример #26
0
    def run(self, inst):
        self._progress_callback(5)

        partial_ld = None
        try:
            # Try automatic loading
            partial_ld = cle.Loader(self.fname,
                                    perform_relocations=False,
                                    load_debug_info=False)
        except cle.CLECompatibilityError:
            pass

        if partial_ld is None:
            try:
                # Try loading as blob; dummy architecture (x86) required, user will select proper arch
                partial_ld = cle.Loader(self.fname,
                                        main_opts={
                                            'backend': 'blob',
                                            'arch': 'x86'
                                        })
            except cle.CLECompatibilityError:
                # Failed to load executable, even as blob!
                gui_thread_schedule(LoadBinary.binary_loading_failed,
                                    (self.fname, ))
                return

        self._progress_callback(50)
        load_options, cfg_args = gui_thread_schedule(LoadBinary.run,
                                                     (partial_ld, ))
        partial_ld.close()
        if cfg_args is None:
            return

        proj = angr.Project(self.fname, load_options=load_options)
        self._progress_callback(95)

        def callback():
            inst._reset_containers()
            inst.project.am_obj = proj
            inst.project.am_event(cfg_args=cfg_args)

        gui_thread_schedule(callback, ())
Пример #27
0
def hook_addr(binary, addr, asm_code=None, bin_code=b''):
    main_bin = io.BytesIO(binary)
    loader = cle.Loader(main_bin,
                        auto_load_libs=False,
                        perform_relocations=False)
    offset = loader.main_object.addr_to_offset(addr)
    main_bin.seek(offset)
    main_bin.write(
        loader.main_object.arch.asm(asm_code) if asm_code else bin_code)
    main_bin.seek(0)
    return main_bin.read()
Пример #28
0
def hook_entry(binary, asm_code=None, bin_code=None):
    main_bin = io.BytesIO(binary)
    b = cle.Loader(main_bin,
                   auto_load_libs=False,
                   perform_relocations=False,
                   main_opts={'base_addr': 0})
    start_addr = b.main_object.addr_to_offset(b.main_object.entry)
    main_bin.seek(start_addr)
    main_bin.write(b.main_object.arch.asm(asm_code) if asm_code else bin_code)
    main_bin.seek(0)
    return main_bin.read()
Пример #29
0
def check_plt_entries(filename):
    real_filename = os.path.join(TESTS_BASE, 'tests', filename)
    ld = cle.Loader(real_filename, auto_load_libs=False)

    if filename == os.path.join('ppc', 'libc.so.6'):
        # objdump can't find PLT stubs for this...
        nose.tools.assert_not_equal(ld.main_bin._plt, {})
        sorted_keys = sorted(ld.main_bin._plt.values())
        diffs = [y - x for x, y in zip(sorted_keys, sorted_keys[1:])]
        nose.tools.assert_equal(diffs, [4]*len(diffs))
        return

    if filename == os.path.join('mips', 'libc.so.6'):
        nose.tools.assert_in('__tls_get_addr', ld.main_bin._plt)
        nose.tools.assert_equal(ld.main_bin._plt['__tls_get_addr'], 1331168)
        return

    if filename == os.path.join('mips', 'fauxware'):
        nose.tools.assert_equal(ld.main_bin._plt, {'puts': 4197264, 'read': 4197232, '__libc_start_main': 4197312, 'printf': 4197248, 'exit': 4197280, 'open': 4197296, 'strcmp': 4197216})
        return

    if filename == os.path.join('mips64', 'libc.so.6'):
        nose.tools.assert_equal(ld.main_bin._plt, {'__tls_get_addr': 1458432, '_dl_find_dso_for_object': 1458448})
        return

    if filename == os.path.join('mips64', 'test_arrays'):
        nose.tools.assert_equal(ld.main_bin._plt, {'__libc_start_main': 4831841456, 'puts': 4831841440})
        return

    p1 = subprocess.Popen(['objdump', '-d', real_filename], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['grep', '@plt>:'], stdin=p1.stdout, stdout=subprocess.PIPE)
    p1.stdout.close()
    dat, _ = p2.communicate()
    lines = dat.strip().split('\n')

    ideal_plt = {}
    for line in lines:
        addr, ident = line.split()
        addr = int(addr, 16)
        name = ident.split('@')[0].strip('<')
        if '*' in name or name == '__gmon_start__':
            continue
        ideal_plt[name] = addr

    ld.main_bin._plt.pop('__gmon_start__', None)

    if filename == os.path.join('armhf', 'libc.so.6'):
        # objdump does these cases wrong as far as I can tell?
        # or maybe not wrong just... different
        # there's a prefix to this stub that jumps out of thumb mode
        # cle finds the arm stub, objdump finds the thumb prefix
        ideal_plt['free'] += 4
        ideal_plt['malloc'] += 4
    nose.tools.assert_equal(ideal_plt, ld.main_bin._plt)
Пример #30
0
    def run(self, inst):
        self._progress_callback(5)
        partial_ld = cle.Loader(self.fname, perform_relocations=False, load_debug_info=False)
        self._progress_callback(50)
        load_options, cfg_args = gui_thread_schedule(LoadBinary.run, (partial_ld, ))
        partial_ld.close()
        if cfg_args is None:
            return

        proj = angr.Project(self.fname, load_options=load_options)
        self._progress_callback(95)
        inst.set_project(proj, cfg_args)