def __init__(self, raw, address, arch): if len(raw) == 0: raise ValueError("Empty memory at {0:#x}".format(address)) arch = 'armv7' if arch == 'arm' else arch insns = list( bap.disasm(raw, addr=address, arch=arch, stop_conditions=[asm.Valid()])) if len(insns) == 0: raise ValueError( "Invalid instruction for {1} at {2:#x}[{3}]:\n{0}".format( hexlify(raw), arch, address, len(raw))) self.insn = insns[0] self.regs_read, self.regs_write = accesses(self.insn.bil) self.jumps = jumps(self.insn.bil) self.dtype = None if self.is_call(): self.dtype = DESTTYPE.call elif self.is_conditional(): self.dtype = DESTTYPE.cjump elif self.is_jump(): self.dtype = DESTTYPE.jump dests = [] if self.code_follows(): dests.append((self.insn.addr + self.insn.size, DESTTYPE.implicit)) if self.insn.bil is not None: for (jmp, dtype) in self.jumps: if isinstance(jmp.arg, bil.Int): if self.is_call(): dtype = DESTTYPE.call dests.append((jmp.arg.value, dtype)) elif self.is_jump() or self.is_call(): dst = self.insn.operands[0] #we want to check here if this is a relative or absolute jump #once we have BIL on x86 and x86-64 this won't matter if isinstance(dst, asm.Imm): dst_tmp = calc_offset(dst.arg, arch) if arch in [ "i386", "x86-64" ]: #jump after instruction on x86, bap should tell us this dst_tmp += self.insn.size dests.append((dst_tmp + address, self.dtype)) if self.is_ret(): self._dests = [] else: self._dests = dests
def __init__(self, raw, address, arch): if len(raw) == 0: raise ValueError("Empty memory at {0:#x}".format(address)) arch = 'armv7' if arch == 'arm' else arch insns = list(bap.disasm(raw, addr=address, arch=arch, stop_conditions=[asm.Valid()])) if len(insns) == 0: raise ValueError("Invalid instruction for {1} at {2:#x}[{3}]:\n{0}". format(hexlify(raw), arch, address, len(raw))) self.insn = insns[0] self.regs_read, self.regs_write = accesses(self.insn.bil) self.jumps = jumps(self.insn.bil) self.dtype = None if self.is_call(): self.dtype = DESTTYPE.call elif self.is_conditional(): self.dtype = DESTTYPE.cjump elif self.is_jump(): self.dtype = DESTTYPE.jump dests = [] if self.code_follows(): dests.append((self.insn.addr + self.insn.size, DESTTYPE.implicit)) if self.insn.bil is not None: for (jmp,dtype) in self.jumps: if isinstance(jmp.arg, bil.Int): if self.is_call(): dtype = DESTTYPE.call dests.append((jmp.arg.value, dtype)) elif self.is_jump() or self.is_call(): dst = self.insn.operands[0] #we want to check here if this is a relative or absolute jump #once we have BIL on x86 and x86-64 this won't matter if isinstance(dst, asm.Imm): dst_tmp = calc_offset(dst.arg, arch) if arch in ["i386","x86-64"]: #jump after instruction on x86, bap should tell us this dst_tmp += self.insn.size dests.append((dst_tmp + address, self.dtype)) if self.is_ret(): self._dests = [] else: self._dests = dests
# for sym in sect.symbols: # print sym.name #bap_dump(img) main = img.get_symbol("_main") bap_dump(main) nodes_by_addr = {} start = None # Go through each instruction and build the CFG # Each Sequence object has a dict of jump addresses # Tell each Sequence what it jumps to # Then, at the end, resolve the addresses back to actual Sequence nodes for ins in bap.disasm(main): node = cfg.Sequence() node.add_to_sequence(ins) if start is None: start = node node.start_addr = ins.addr nodes_by_addr[node.start_addr] = node #Go through BIL and find jumps (for now) for bil_instr in ins.bil: jump = bap.adt.visit(Get_Jump(), bil_instr).jump if jump is not None: # There is a jump in this expression #TODO: more complicated expressions than 'IF'? node.is_jump = True
def bap_dump(img): for instr in bap.disasm(img): # print instr print "%s %02x" % (instr.asm, instr.addr)
address = int(address, 16) relocations[address] = relocation functions = [] img = bap.image(path) segments = img.segments insns_all = {} value = 3 for s in segments: for sym in s.symbols: func = Function(sym.name, value) value += 1 for insn in bap.disasm(sym): func.instructions.append( Instruction(insn.name, insn.operands, insn.addr - 0xc0000040)) if DEBUG: print( hex(insn.addr - 0xc0000040) + " " + str(insn.name) + str(insn.operands)) functions.append(func) #functions.reverse() for func in functions: for insn in func.instructions: insn.format_insn() func.do_frame_allocation() func.do_relocations(relocations, functions)