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.")
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 )
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
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)
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)
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)