예제 #1
0
def test_function_leading_blocks_merging():

    # GitHub issue #1312

    path = os.path.join(test_location, 'armel',
                        'Nucleo_read_hyperterminal-stripped.elf')
    proj = angr.Project(path,
                        arch=archinfo.ArchARMCortexM(),
                        auto_load_libs=False)

    cfg = proj.analyses.CFGFast(resolve_indirect_jumps=True,
                                force_complete_scan=True,
                                normalize=True,
                                symbols=False,
                                detect_tail_calls=True)

    nose.tools.assert_in(0x8000799, cfg.kb.functions,
                         "Function 0x8000799 does not exist.")
    nose.tools.assert_not_in(0x800079b, cfg.kb.functions,
                             "Function 0x800079b does not exist.")
    nose.tools.assert_not_in(
        0x800079b, cfg.kb.functions[0x8000799].block_addrs_set,
        "Block 0x800079b is found, but it should not exist.")
    nose.tools.assert_in(
        0x8000799, cfg.kb.functions[0x8000799].block_addrs_set,
        "Block 0x8000799 is not found inside function 0x8000799.")
    nose.tools.assert_equal(
        next(
            iter(b for b in cfg.kb.functions[0x8000799].blocks
                 if b.addr == 0x8000799)).size, 6,
        "Block 0x800079b has an incorrect size.")
예제 #2
0
    def test_function_leading_blocks_merging(self):

        # GitHub issue #1312

        path = os.path.join(
            test_location, "armel", "Nucleo_read_hyperterminal-stripped.elf"
        )
        proj = angr.Project(path, arch=archinfo.ArchARMCortexM(), auto_load_libs=False)

        cfg = proj.analyses.CFGFast(
            resolve_indirect_jumps=True,
            force_complete_scan=True,
            normalize=True,
            symbols=False,
            detect_tail_calls=True,
        )

        assert 0x8000799 in cfg.kb.functions
        assert 0x800079B not in cfg.kb.functions
        assert 0x800079B not in cfg.kb.functions[0x8000799].block_addrs_set
        assert 0x8000799 in cfg.kb.functions[0x8000799].block_addrs_set
        assert (
                next(
                    iter(b for b in cfg.kb.functions[0x8000799].blocks if b.addr == 0x8000799)
                ).size
                == 6
        )
예제 #3
0
def add_sparkles(uc, args):
    global breakpoints
    uc.regs = SparklyRegs(uc)
    uc.mem = SparklyMem(uc)
    uc.stack = SparklyStack(uc)
    uc.step = types.MethodType(step, uc)
    if args.debug and args.breakpoint:
        add_block_hook(breakpoint_handler)
        breakpoints.append(args.breakpoint)
    uc.arch = archinfo.ArchARMCortexM()
    return uc
예제 #4
0
    def extract_arch(reader):
        arch_str = reader['e_machine']
        if 'ARM' in arch_str:
            # Check the ARM attributes, if they exist
            arm_attrs = ELF._extract_arm_attrs(reader)
            if arm_attrs and 'TAG_CPU_NAME' in arm_attrs:
                if arm_attrs['TAG_CPU_NAME'].endswith("-M") \
                    or 'Cortex-M' in arm_attrs['TAG_CPU_NAME']:
                    return archinfo.ArchARMCortexM('Iend_LE')
            if reader.header.e_flags & 0x200:
                return archinfo.ArchARMEL(
                    'Iend_LE' if reader.little_endian else 'Iend_BE')
            elif reader.header.e_flags & 0x400:
                return archinfo.ArchARMHF(
                    'Iend_LE' if reader.little_endian else 'Iend_BE')

        return archinfo.arch_from_id(arch_str,
                                     'le' if reader.little_endian else 'be',
                                     reader.elfclass)
예제 #5
0
def detect_arm_ivt(stream):
    """

    :param stream:
    :type stream: file
    :return:
    """
    min_arm_sp = 0x1FFF0000
    max_arm_sp = 0x20100000

    # TODO: We're just looking at the front for now
    try:
        maybe_sp = stream.read(4)
        maybe_le_sp = struct.unpack('<I', maybe_sp)[0]
        maybe_be_sp = struct.unpack(">I", maybe_sp)[0]
        if min_arm_sp < maybe_le_sp < max_arm_sp:
            maybe_arch = archinfo.ArchARMCortexM(endness=archinfo.Endness.LE)
            l.debug("Found possible Little-Endian ARM IVT with initial SP %#08x" % maybe_le_sp)
            maybe_entry = struct.unpack('<I', stream.read(4))[0]
            l.debug("Reset vector at %#08x" % maybe_entry)
            maybe_base = maybe_entry & 0xffff0000  # A complete guess
            l.debug("Guessing base address at %#08x" % maybe_base)
            return maybe_arch, maybe_base, maybe_entry
        elif min_arm_sp < maybe_be_sp < max_arm_sp:
            maybe_arch = archinfo.ArchARM(endness=archinfo.Endness.BE)
            l.debug("Found possible Big-Endian ARM IVT with initial SP %#08x" % maybe_be_sp)
            maybe_entry = struct.unpack('>I', stream.read(4))[0]
            l.debug("Reset vector at %#08x" % maybe_entry)
            maybe_base = maybe_entry & 0xffff0000  # A complete guess
            l.debug("Guessing base address at %#08x" % maybe_base)
            return maybe_arch, maybe_base, maybe_entry
        else:
            # Nope
            return (None, None, None)
    except:
        l.exception("Something died")
        return (None, None, None)
    finally:
        stream.seek(0)
예제 #6
0
def detect_marvell_fw(stream):
    """

    :param stream:
    :type stream: file
    :return:
    """
    min_arm_sp = 0x20000000
    max_arm_sp = 0x20100000

    try:
        stream.seek(0)
        header = stream.read(0xc0)
        if not b"MRVL" in header:
            return None, None, None
        maybe_entry = struct.unpack('<I', header[0x10:0x14])[0]
        maybe_fw_file_offs = struct.unpack('<I', header[0x18:0x1c])[0]
        if not (0 < maybe_fw_file_offs < 0x1000):
            return None, None, None
        # First dword of the firmware is the SP
        stream.seek(maybe_fw_file_offs)
        maybe_sp = struct.unpack("<I", stream.read(4))[0]
        if not (min_arm_sp < maybe_sp <= max_arm_sp):
            return None, None, None
        l.debug("Detected Marvell FW header")
        maybe_arch = archinfo.ArchARMCortexM(endness=archinfo.Endness.LE)
        l.debug("Found possible Little-Endian ARM IVT with initial SP %#08x" %
                maybe_sp)
        l.debug("Reset vector at %#08x" % maybe_entry)
        maybe_base = maybe_entry & 0xffff0000  # A complete guess
        l.debug("Guessing base address at %#08x" % maybe_base)
        return maybe_arch, maybe_base, maybe_entry
    except Exception:
        l.exception("")
        return None, None, None
    finally:
        stream.seek(0)