def find_function_epilogue_bxlr(self, makecode=False): ''' Find opcode bytes corresponding to BX LR. This is a common way to return from a function call. Using the IDA API, convert these opcodes to code. This kicks off IDA analysis. ''' EAstart = idc.MinEA() EAend = idc.MaxEA() ea = EAstart length = 2 # this code isn't tolerant to values other than 2 right now fmt_string = "Possible BX LR 0x%08x == " for i in range(length): fmt_string += "%02x " while ea < EAend: instructions = [] for i in range(length): instructions.append(idc.Byte(ea + i)) if not ida_bytes.isCode(ida_bytes.getFlags(ea)) and instructions[ 0] == 0x70 and instructions[1] == 0x47: if self.printflag: print fmt_string % (ea, instructions[0], instructions[1]) if makecode: idc.MakeCode(ea) ea = ea + length
def find_pushpop_registers_arm(self, makecode=False): ''' Find opcodes for PUSH/POP registers in ARM mode Using the IDA API, convert these opcodes to code. This kicks off IDA analysis. bigup jmitch ** ** 2d e9 and ** ** bd e8 ''' EAstart = idc.MinEA() EAend = idc.MaxEA() ea = EAstart length = 2 # this code isn't tolerant to values other than 2 right now fmt_string = "Possible %s {REGS} 0x%08x == " for i in range(length): fmt_string += "%02x " while ea < EAend: instructions = [] for i in range(length): instructions.append(idc.Byte(ea + i)) # print BX LR bytes if not ida_bytes.isCode(ida_bytes.getFlags(ea)) and \ (instructions[0] == 0xbd and instructions[1] == 0xe8): if self.printflag: print fmt_string % ("POP ", ea, instructions[0], instructions[1]) if makecode: idc.MakeCode(ea) if not ida_bytes.isCode(ida_bytes.getFlags(ea)) and \ (instructions[0] == 0x2d and instructions[1] == 0xe9) \ : if self.printflag: print fmt_string % ("PUSH", ea, instructions[0], instructions[1]) if makecode: idc.MakeCode(ea) ea = ea + length
def nonfunction_first_instruction_heuristic(self, makefunction=False): EAstart = idc.MinEA() EAend = idc.MaxEA() ea = EAstart flag_code_outside_function = False self.printflag = False while ea < EAend: # skip functions, next instruction will be the target to inspect function_name = idc.GetFunctionName(ea) if function_name != "": flag_code_outside_function = False # skip to end of function and keep going # ea = idc.FindFuncEnd(ea) #if self.printflag: # print "Skipping function %s" % (function_name) ea = ida_search.find_not_func(ea, 1) continue elif ida_bytes.isCode(ida_bytes.getFlags(ea)): # code that is not a function # get mnemonic to see if this is a push mnem = idc.GetMnem(ea) if makefunction and (mnem == "PUSH" or mnem == "PUSH.W" or mnem == "STM" or mnem == "MOV"): if self.printflag: print "nonfunction_first_instruction_heuristic() making function %08x" % ea idc.MakeFunction(ea) flag_code_outside_function = False ea = ida_search.find_not_func(ea, 1) continue else: if self.printflag: print "nonfunction_first_instruction_heuristic() other instruction %08x\t'%s'" % ( ea, mnem) ea = idc.NextFunction(ea) continue ea += 1
def make_new_functions_heuristic_push_regs(self, makefunction=False): ''' After converting bytes to instructions, Look for PUSH instructions that are likely the beginning of functions. Convert these code areas to functions. ''' EAstart = idc.MinEA() EAend = idc.MaxEA() ea = EAstart while ea < EAend: if self.printflag: print "EA %08x" % ea ea_function_start = idc.GetFunctionAttr(ea, idc.FUNCATTR_START) # If ea is inside a defined function, skip to end of function if ea_function_start != idc.BADADDR: ea = idc.FindFuncEnd(ea) continue # If current ea is code if ida_bytes.isCode(ida_bytes.getFlags(ea)): # Looking for prologues that do PUSH {register/s} mnem = idc.GetMnem(ea) # if (mnem == "PUSH"): if makefunction: if self.printflag: print "Converting code to function @ %08x" % ea idc.MakeFunction(ea) eanewfunction = idc.FindFuncEnd(ea) if eanewfunction != idc.BADADDR: ea = eanewfunction continue nextcode = ida_search.find_code(ea, idc.SEARCH_DOWN) if nextcode != idc.BADADDR: ea = nextcode else: ea += 1
def find_pushpop_registers_thumb(self, makecode=False): ''' Look for opcodes that push registers onto the stack, which are indicators of function prologues. Using the IDA API, convert these opcodes to code. This kicks off IDA analysis. ''' ''' thumb register list from [email protected] ''' thumb_reg_list = [ 0x00, 0x02, 0x08, 0x0b, 0x0e, 0x10, 0x1c, 0x1f, 0x30, 0x30, 0x38, 0x3e, 0x4e, 0x55, 0x70, 0x72, 0x73, 0x7c, 0x7f, 0x80, 0x90, 0xb0, 0xf0, 0xf3, 0xf7, 0xf8, 0xfe, 0xff ] EAstart = idc.MinEA() EAend = idc.MaxEA() ea = EAstart length = 2 # this code isn't tolerant to values other than 2 right now fmt_string = "Possible Function 0x%08x == " for i in range(length): fmt_string += "%02x " while ea < EAend: instructions = [] for i in range(length): instructions.append(idc.Byte(ea + i)) if not ida_bytes.isCode(ida_bytes.getFlags( ea)) and instructions[0] in thumb_reg_list and ( instructions[1] == 0xb5 or instructions[1] == 0xbd): if self.printflag: print fmt_string % (ea, instructions[0], instructions[1]) if makecode: idc.MakeCode(ea) ea = ea + length