def handle_dll_calls(self): dll_call_count = ida_bytes.get_dword(self.E_info_entry_ea + self.dll_call_count_offset) dll_call_lib_names_ea = ida_bytes.get_dword( self.E_info_entry_ea + self.dll_call_lib_names_offset) dll_call_func_names_ea = ida_bytes.get_dword( self.E_info_entry_ea + self.dll_call_func_names_offset) self.dll_calls = Dll_calls(dll_call_lib_names_ea, dll_call_func_names_ea, dll_call_count) ida_auto.auto_wait() ea = ida_name.get_name_ea(idaapi.BADADDR, "j__krnl_MCallDllCmd") code_fref_eas = [] fref_ea = ida_xref.get_first_fcref_to(ea) while fref_ea != idaapi.BADADDR: code_fref_eas.append(fref_ea) fref_ea = ida_xref.get_next_cref_to(ea, fref_ea) for ref_ea in code_fref_eas: #get prev mov instruction prev_ins_ea = idaapi.get_item_head(ref_ea - 1) ins = ida_lines.generate_disasm_line(prev_ins_ea, ida_lines.GENDSM_REMOVE_TAGS) if (ins.startswith("mov eax,")): index = ida_bytes.get_dword(prev_ins_ea + 1) cmt = self.dll_calls[index] ida_bytes.set_cmt(ref_ea, cmt, False)
def extract_info_from_IDA(self): prots = ida_bytes.get_qword(self.ea + 0x10) if prots: count = ida_bytes.get_qword(prots) entrysize = 0x8 p_ea = prots + 8 for i in range(count): proto_ea = idc.get_qword(p_ea) self.prots.append(proto_ea) p_ea += entrysize type_info = ida_bytes.get_qword(self.ea + 0x48) for idx in range(0, 4): # 0: inst_meths # 1: class_meths # 2: opt_inst_meths # 3: opt_class_meths meth_list = ida_bytes.get_qword(self.ea + 0x18 + idx * 8) if meth_list: entrysize = ida_bytes.get_dword(meth_list) count = ida_bytes.get_dword(meth_list + 4) ea = meth_list + 8 for i in range(0, count): sel = idc.get_bytes(idc.Qword(ea), idc.get_item_size(idc.Qword(ea)) - 1) meth_type = idc.get_bytes(idc.Qword(type_info), idc.get_item_size(idc.Qword(type_info)) - 1) self.meths[sel] = meth_type ea += entrysize type_info += 8
def guid_at_addr(guid_addr): return GUID(bytes=struct.pack( "<LLLL", ida_bytes.get_dword(guid_addr), ida_bytes.get_dword(guid_addr + 0x4), ida_bytes.get_dword(guid_addr + 0x8), ida_bytes.get_dword(guid_addr + 0xC) ))
def analyze_block(block): """Analyze a basic bloc and return its successors, if it's correspond to a basic bloc treating the Driver case and the address for the DR/TL API table if one is loaded :param block: Basic block to analyze :type block: ida_gdl.BasicBlock :return: Successors Basic Blocks, if it deals with Secure Driver case, and the address of the table loaded if loaded :rtype: (Generator, bool, int) """ loaded_value = -1 is_dr_table = False insn = ida_ua.insn_t() insn_ea = block.start_ea insn_len = 0 while insn_ea < block.end_ea: insn_len = max(1, ida_ua.decode_insn(insn, insn_ea)) if insn.itype == ida_allins.ARM_sub and \ insn.ops[2].type == ida_ua.o_imm and \ insn.ops[2].value == 0x1000: is_dr_table = True if insn.itype == ida_allins.ARM_ldr and \ insn.ops[1].type == ida_ua.o_mem: pool_value = ida_bytes.get_dword(insn.ops[1].addr) value = ida_bytes.get_dword(pool_value) if value > 0x1000: loaded_value = pool_value insn_ea += insn_len return block.succs(), is_dr_table, loaded_value
def find_scatter_table(): scatter_load_bytes = { "__scatterload": [ "0A A0 90 E8 00 0C 82 44", "2C 00 8F E2 00 0C 90 E8 00 A0 8A E0 00 B0 8B E0", # For 5G ], } tables = {} for name, prefixes in scatter_load_bytes.items(): for prefix in prefixes: addrs = create_func_by_prefix(name, prefix, force=True) for addr in addrs: if addr == idc.BADADDR: continue offset_addr = idc.get_operand_value(addr, 1) if offset_addr == -1: old_flag = idc.get_sreg(addr, "T") idc.split_sreg_range(addr, "T", not old_flag, idc.SR_user) offset_addr = idc.get_operand_value(addr, 1) offset = ida_bytes.get_dword(offset_addr) offset2 = ida_bytes.get_dword(offset_addr + 4) start = (offset + offset_addr) & 0xFFFFFFFF end = (offset2 + offset_addr) & 0xFFFFFFFF if not idc.is_loaded(start): continue tables[start] = end print("__scatter_table: 0x%x -> 0x%x" % (start, end)) func_name = set_entry_name(start, "__scatter_table") return tables
def search_guid(guid): if isinstance(guid, basestring): target_guid = GUID(string = guid) else: print "UNSUPPORTED FORMAT" return for seg_addr in idautils.Segments(): seg = ida_segment.getseg(seg_addr) cur_addr = seg.start_ea seg_end = seg.end_ea while cur_addr < seg_end: d = [ida_bytes.get_dword(cur_addr), ida_bytes.get_dword(cur_addr+0x4), ida_bytes.get_dword(cur_addr+0x8), ida_bytes.get_dword(cur_addr+0xC)] if (d[0] == 0 and d[1] == 0 and d[2] == 0 and d[3] == 0) or \ ( d[0] == 0xFFFFFFFF and d[1] == 0xFFFFFFFF and d[2] == 0xFFFFFFFF and d[3] == 0xFFFFFFFF ): cur_addr += 0x10 else: cur_guid = GUID(bytes=struct.pack( "<LLLL", d[0], d[1], d[2], d[3] )) if str(target_guid) == str(cur_guid): print " - Found GUID {} at 0x{:08x}".format( str(target_guid), cur_addr ) return cur_addr += 1 print (" - GUID %s not found" % (str(target_guid)))
def find_pe(self, cursor=False): """Search IDB for possible MZ/PE headers""" info = idaapi.get_inf_structure() mz_headers = [] # Check current cursor for MZ/PE? if cursor: # Get IDA cursor address addr = idc.here() # Get segment and end address s = idaapi.getseg(addr) e = idc.get_segm_end(addr) # Check for MZ magic if ida_bytes.get_word(addr) == 0x5a4d: # Ensure the PE header is in the segment e_lfanew = ida_bytes.get_dword(addr + 0x3c) if addr + e_lfanew + 1 < e: # Check for PE magic if ida_bytes.get_word(addr + e_lfanew) == 0x4550: # Found possible MZ/PE header mz_headers.append([addr, idc.get_segm_name(addr), info.is_64bit()]) self.ret = mz_headers return self.ret # Search all segments for seg in idautils.Segments(): s = idc.get_segm_start(seg) e = idc.get_segm_end(seg) addr = s while True: # Find first byte of MZ header addr = ida_bytes.find_byte(addr, e-addr, 0x4d, 0) if addr == ida_idaapi.BADADDR or addr >= e: break # Check for MZ magic if ida_bytes.get_word(addr) == 0x5a4d: # Ensure the PE header is in the segment e_lfanew = ida_bytes.get_dword(addr + 0x3c) if addr + e_lfanew + 1 < e: # Check for PE magic if ida_bytes.get_word(addr + e_lfanew) == 0x4550: # Found possible MZ/PE header mz_headers.append([addr, idc.get_segm_name(s), info.is_64bit()]) # Resume search from next address addr += 1 self.ret = mz_headers return self.ret
def run_scatterload(debug=False): # Newly identified region may have additional scatter load procedure. Thus, # we continuously proceed until no changes left. is_changed = True while is_changed: is_changed = False tables = find_scatter_table() scatter_funcs = find_scatter_funcs() for start, end in tables.items(): print("Processing table: 0x%x to 0x%x" % (start, end)) while start < end: ida_bytes.create_dword(start, 16) ida_offset.op_offset(start, 0, idc.REF_OFF32) src = ida_bytes.get_dword(start) dst = ida_bytes.get_dword(start + 4) size = ida_bytes.get_dword(start + 8) how = ida_bytes.get_dword(start + 12) if how not in scatter_funcs: print("%x: no addr 0x%x in scatter_funcs" % (start, how)) start += 16 continue func_name = scatter_funcs[how] start += 16 print("%s: 0x%x -> 0x%x (0x%x bytes)" % (func_name, src, dst, size)) if func_name != "__scatterload_zeroinit": if not idc.is_loaded(src) or size == 0: print("0x%x is not loaded." % (src)) continue if debug: # only show information above continue if func_name == "__scatterload_copy": if add_segment(dst, size, "CODE"): memcpy(src, dst, size) is_changed = True elif func_name == "__scatterload_decompress": if add_segment(dst, size, "DATA"): decomp(src, dst, size) is_changed = True # some old firmware images have this. elif func_name == "__scatterload_decompress2": if add_segment(dst, size, "DATA"): decomp2(src, dst, size) is_changed = True elif func_name == "__scatterload_zeroinit": # No need to further proceed for zero init. if add_segment(dst, size, "DATA"): memclr(dst, size) ida_auto.auto_wait()
def main(): print("[*] loading crypto constants") for const in non_sparse_consts: const["byte_array"] = convert_to_byte_array(const) for start in idautils.Segments(): print("[*] searching for crypto constants in %s" % idc.get_segm_name(start)) ea = start while ea < idc.get_segm_end(start): bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4))) for const in non_sparse_consts: if bbbb != const["byte_array"][:4]: continue if map(lambda x:ord(x), idc.get_bytes(ea, len(const["byte_array"]))) == const["byte_array"]: print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"])) idc.set_name(ea, const["name"]) if const["size"] == "B": idc.create_byte(ea) elif const["size"] == "L": idc.create_dword(ea) elif const["size"] == "Q": idc.create_qword(ea) idc.make_array(ea, len(const["array"])) ea += len(const["byte_array"]) - 4 break ea += 4 ea = start if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2: while ea < idc.get_segm_end(start): d = ida_bytes.get_dword(ea) for const in sparse_consts: if d != const["array"][0]: continue tmp = ea + 4 for val in const["array"][1:]: for i in range(8): if ida_bytes.get_dword(tmp + i) == val: tmp = tmp + i + 4 break else: break else: print(("0x%0" + str(digits) + "X: found sparse constants for %s") % (ea, const["algorithm"])) cmt = idc.get_cmt(idc.prev_head(ea), 0) if cmt: idc.set_cmt(idc.prev_head(ea), cmt + ' ' + const["name"], 0) else: idc.set_cmt(idc.prev_head(ea), const["name"], 0) ea = tmp break ea += 1 print("[*] finished")
def main(): print("[*] loading crypto constants") for const in non_sparse_consts: const["byte_array"] = convert_to_byte_array(const) for start in Segments(): print("[*] searching for crypto constants in %s" % get_segm_name(start)) ea = start while ea < get_segm_end(start): bbbb = list(struct.unpack("BBBB", get_bytes(ea, 4))) for const in non_sparse_consts: if bbbb != const["byte_array"][:4]: continue if map(lambda x: ord(x), get_bytes(ea, len( const["byte_array"]))) == const["byte_array"]: print("0x%08X: found const array %s (used in %s)" % (ea, const["name"], const["algorithm"])) set_name(ea, const["name"]) if const["size"] == "B": idc.create_byte(ea) elif const["size"] == "L": idc.create_dword(ea) elif const["size"] == "Q": idc.create_qword(ea) make_array(ea, len(const["array"])) ea += len(const["byte_array"]) - 4 break ea += 4 ea = start if get_segm_attr(ea, SEGATTR_TYPE) == 2: while ea < get_segm_end(start): d = ida_bytes.get_dword(ea) for const in sparse_consts: if d != const["array"][0]: continue tmp = ea + 4 for val in const["array"][1:]: for i in range(8): if ida_bytes.get_dword(tmp + i) == val: tmp = tmp + i + 4 break else: break else: print("0x%08X: found sparse constants for %s" % (ea, const["algorithm"])) ea = tmp break ea += 1 print("[*] finished")
def is_method_a_getter(self, sel, f=None): base_props = ida_bytes.get_qword(self.info + 0x40) if not base_props: return False entrysize = ida_bytes.get_dword(base_props) count = ida_bytes.get_dword(base_props + 4) p_ea = base_props + 8 for i in range(count): p_name = idc.get_bytes(idc.Qword(p_ea), idc.get_item_size(idc.Qword(p_ea)) - 1) if p_name == sel: return True p_ea += entrysize return False
def callback2(ea): print("Found ref to cmd string at 0x%08X" % ea) ref=ida_bytes.get_dword(ea)&0xFFFF0000 for i in range(0,0x1000*4,0x10): value=ida_bytes.get_dword(ea+i) if value&0xFFFF0000 != ref: valbyte=ida_bytes.get_byte(ea+i) if valbyte==ord('$') or valbyte==ord('!') or valbyte==ord('+') or valbyte==ord('^') or valbyte==ord('*'): return ea+i break logger.debug("cmd_ref:%x" % (ea+i)) references.append(ea+i) return 0
def rename_guids(): labels = {} # Load GUIDs guids = dict( (str(GUID(array=v)), k) for k, v in efiguids.GUIDs.iteritems() ) guids.update(dict((v, k) for k, v in local_guids.iteritems())) # Find all the data segments in this binary for seg_addr in idautils.Segments(): seg = ida_segment.getseg(seg_addr) if seg.type == ida_segment.SEG_DATA or True: print "Processing data segment at 0x{:08x}".format(seg_addr) # Find any GUIDs we know about in the data segment cur_addr = seg.start_ea seg_end = seg.end_ea while cur_addr < seg_end: d = [ida_bytes.get_dword(cur_addr), ida_bytes.get_dword(cur_addr+0x4), ida_bytes.get_dword(cur_addr+0x8), ida_bytes.get_dword(cur_addr+0xC)] if (d[0] == 0 and d[1] == 0 and d[2] == 0 and d[3] == 0) or \ ( d[0] == 0xFFFFFFFF and d[1] == 0xFFFFFFFF and d[2] == 0xFFFFFFFF and d[3] == 0xFFFFFFFF ): cur_addr += 0x10 else: guid = GUID(bytes=struct.pack( "<LLLL", d[0], d[1], d[2], d[3] )) gstr = str(guid) if gstr in guids.keys(): print " - Found GUID {} ({}) at 0x{:08x}".format( gstr, guids[gstr], cur_addr ) struct_label = get_next_unused_label( underscore_to_global(guids[gstr]) ) ida_name.set_name(cur_addr, struct_label) labels[struct_label] = (cur_addr, guids[gstr]) cur_addr += 0xf cur_addr += 0x01 else: print "Skipping non-data segment at 0x{:08x}".format(seg_addr) return labels
def get_E_main(): # .text:00485090 55 push ebp # .text:00485091 8B EC mov ebp, esp # .text:00485093 51 push ecx # .text:00485094 53 push ebx # .text:00485095 56 push esi # .text:00485096 8B F1 mov esi, ecx # .text:00485098 57 push edi # .text:00485099 8B 4E 68 mov ecx, [esi+68h] # .text:0048509C 8D 86 D8 00 00 00 lea eax, [esi+0D8h] # .text:004850A2 50 push eax ; int # .text:004850A3 51 push ecx ; hModule # .text:004850A4 E8 C7 D3 00 00 call krnln_?GetInstancePath@@YAXPAUHINSTANCE__@@AAVCString@@@Z E_main_pat = "55 8B EC 51 53 56 8B F1 57 8B 4E 68 8D 86 D8 00 00 00 50 51 E8" E_main_call_ins_offset = 0x37 E_main_func_ea = 0 code_segs = get_code_segs() for seg in code_segs: start_ea = seg.start_ea end_ea = seg.end_ea E_main_pat_ea = ida_search.find_binary(start_ea, end_ea, E_main_pat, 16, ida_search.SEARCH_DOWN) if E_main_pat_ea != idaapi.BADADDR: call_ins_ea = E_main_pat_ea + E_main_call_ins_offset addr_off = ida_bytes.get_dword(call_ins_ea + 1) E_main_func_ea = call_ins_ea + 5 + idaapi.as_int32(addr_off) print("Find E_main addr 0x%X" % (E_main_func_ea)) break return E_main_func_ea
def method_list(ea): if not ea: return count = ida_bytes.get_dword(ea + 4) name = idc.get_segm_name(ea) first = ea + 8 def post14format(addr): for _ in range(3): data = ida_bytes.get_bytes(addr, 4) offset, = struct.unpack('<i', data) yield addr + offset addr += 4 is14 = name and (name.endswith(':__objc_const_ax') or name.endswith(':__objc_methlist')) for i in range(count): if is14: # iOS 14 yield Post14Method(*post14format(first + i * 12)) else: ea_method_t = first + i * Objc2Method.length data = ida_bytes.get_bytes(ea_method_t, Objc2Method.length) yield Objc2Method(data)
def search_idb(self): """Search IDB for possible MZ/PE headers""" # Search all segments for seg in idautils.Segments(): s = idc.get_segm_start(seg) e = idc.get_segm_end(seg) addr = s while True: # Find first byte of MZ header addr = ida_bytes.find_byte(addr, e-addr, 0x4d, 0) if addr == ida_idaapi.BADADDR or addr >= e: break # Check for MZ magic if ida_bytes.get_word(addr) == 0x5a4d: # Ensure the PE header is in the segment e_lfanew = ida_bytes.get_dword(addr + 0x3c) if addr + e_lfanew + 1 < e: # Check for PE magic if ida_bytes.get_word(addr + e_lfanew) == 0x4550: # Found possible MZ/PE file self.form.runtime.log("0x{:08x} - {}".format(addr, idc.get_segm_name(s))) self.form.map_pe(image_base=addr) # Resume search from next address addr += 1
def capstone_disas(ea): global cs insn = ida_bytes.get_dword(ea) insn_bytes = insn.to_bytes(4, byteorder='little') return cs.disasm(insn_bytes, ea)
def analyze_str_ptr(start_ea, end_ea): str_cnt = 0 start_time = time.time() # First, find string references. strings referenced by pointers are highly # likely string. ea = start_ea while ea != idc.BADADDR and ea < end_ea: status, ea = is_assigned(ea) if status: continue str_ptr = ida_bytes.get_dword(ea) if idc.get_str_type(str_ptr) is not None or check_string(str_ptr, 8): # even already assigned strings may not have reference. ida_offset.op_offset(ea, 0, idc.REF_OFF32) if idc.get_str_type(str_ptr) is None: create_string(str_ptr) str_cnt += 1 if str_cnt % 10000 == 0: print("%x: %d strings has been found. (%0.3f secs)" % (ea, str_cnt, time.time() - start_time)) ea = next_addr_aligned(ea, 4) print("Created %d strings. (%0.3f secs)" % (str_cnt, time.time() - start_time))
def find_parse_ip(li, ea, parsecode): # TODO check memory for SEGA SATURN string # segaSaturn = li.read(16) # warning(segaSaturn+' '+str(li.tell())) ida_bytes.create_strlit(ea, 16, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x10, 16, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x20, 10, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x2A, 6, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x30, 8, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x38, 8, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x40, 10, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x4A, 6, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x50, 16, ida_nalt.STRTYPE_C) ida_bytes.create_strlit(ea + 0x60, 0x70, ida_nalt.STRTYPE_C) ida_bytes.create_byte(ea + 0xD0, 16) ida_bytes.create_dword(ea + 0xE0, 4) ida_bytes.create_dword(ea + 0xE4, 4) ida_bytes.create_dword(ea + 0xE8, 4) ida_bytes.create_dword(ea + 0xEC, 4) ida_bytes.create_dword(ea + 0xF0, 4) ida_funcs.add_func(ida_bytes.get_dword(ea + 0xF0), ida_idaapi.BADADDR) ida_bytes.create_dword(ea + 0xF4, 4) ida_bytes.create_dword(ea + 0xF8, 4) ida_bytes.create_dword(ea + 0xFC, 4) if parsecode: ida_funcs.add_func(ea + 0x100, ida_idaapi.BADADDR) return 1
def find_pointers(start, end): for va in range(start, end - 0x8): ptr = ida_bytes.get_qword(va) if idc.get_segm_start(ptr) != idc.BADADDR: yield va, ptr, 8 ptr = ida_bytes.get_dword(va) if idc.get_segm_start(ptr) != idc.BADADDR: yield va, ptr, 4
def load_flirt_sigs(self): elib_count = ida_bytes.get_dword(self.E_info_entry_ea + self.elib_count_offset) elibs_start_ea = ida_bytes.get_dword(self.E_info_entry_ea + self.elib_infos_entry_offset) self.elibs = Elibs(elibs_start_ea, elib_count) for elib in self.elibs: if elib.sig_name: rc = ida_funcs.plan_to_apply_idasgn(elib.sig_name) if rc == 0: print( "Plan to apply %s ida signature error, may be there is no correspoing sig file in sig folder !!!" % elib.sig_name) else: print( "There is no known sigature file corresponding to the library %s, you can make it by yourself !!!" % elib.name)
def find_ptr(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) -> int: addr = find_pattern(pattern, expected, index) disp = ida_bytes.get_dword(addr + offset) # Real address is: pattern_addr + offset + displacement + size_of_displacement. return addr + offset + disp + 4
def find_funcname_ptr(ea, n): for i in range(4, n * 4, 4): name_ptr = ida_bytes.get_dword(ea + i) # this might be a function, so break and proceed next check if name_ptr & 1 == 1: return elif check_funcname(name_ptr): return ea + i return
def read_xword(self): if bitness == 32: res = ida_bytes.get_dword(self.addr) elif bitness == 64: res = ida_bytes.get_qword(self.addr) else: # bitness == 16 res = ida_bytes.get_word(self.addr) self.inc(self.bitness >> 3) return res
def method_list(ea): if not ea: return count = ida_bytes.get_dword(ea + 4) first = ea + 8 for i in range(count): ea_method_t = first + i * Objc2Method.length data = ida_bytes.get_bytes(ea_method_t, Objc2Method.length) yield Objc2Method(data)
def extract_info_from_IDA(self): for xref in idautils.XrefsTo(self.ea): frm = xref.frm if idc.SegName(frm) == '__objc_classrefs': self.classref = frm if idc.SegName(frm) == '__objc_superrefs': self.superref = frm base_ivars = ida_bytes.get_qword(self.info + 0x30) if base_ivars and idc.SegName(base_ivars) == '__objc_const': entrysize = ida_bytes.get_dword(base_ivars) count = ida_bytes.get_dword(base_ivars + 4) ea = base_ivars + 8 for i in range(count): offset = ida_bytes.get_dword(idc.get_qword(ea)) _type = idc.get_bytes(idc.Qword(ea + 0X10), idc.get_item_size(idc.Qword(ea + 0X10)) - 1) _name = idc.get_bytes(idc.Qword(ea + 0X08), idc.get_item_size(idc.Qword(ea + 0X08)) - 1) # self.ivars[offset] = _type self.ivars[_name] = _type ea += entrysize base_props = ida_bytes.get_qword(self.info + 0x40) if base_props and idc.SegName(base_props) == '__objc_const': entrysize = ida_bytes.get_dword(base_props) count = ida_bytes.get_dword(base_props + 4) ea = base_props + 8 for i in range(count): _type = idc.get_bytes(idc.Qword(ea + 0X08), idc.get_item_size(idc.Qword(ea + 0X08)) - 1) _name = idc.get_bytes(idc.Qword(ea), idc.get_item_size(idc.Qword(ea)) - 1) self.props[_name] = _type ea += entrysize base_prots = ida_bytes.get_qword(self.info + 0x28) if base_prots and idc.SegName(base_prots) == '__objc_const': count = ida_bytes.get_qword(base_prots) entrysize = 0x8 p_ea = base_prots + 8 for i in range(count): proto_ea = idc.get_qword(p_ea) self.prots.append(proto_ea) Protocol.add_implementing_class(proto_ea, self.ea) p_ea += entrysize
def find_mclib_jumper(): """Retrieves the address of the McLib jumper fills by the loader during the trustlet loading process :return: McLib jumper address :rtype: int """ segm = ida_segment.get_segm_by_name("rtm") mclib_jumper = ida_bytes.get_dword(segm.start_ea + 0x8C) return mclib_jumper
def set_name_prototype_tl_dr_function(api_number): """Set the name and the prototype of the TL/DR API function associated with the given function number :param api_number: API function number :type api_number: int """ global MAX_TL_API global MAX_DR_API tl_api_name, tl_api_type, dr_api_name, dr_api_type = get_apis_name_type(api_number) index = api_number * 4 if api_number < MAX_TL_API: if not tl_api_name: pass else: dword = ida_bytes.get_dword(tl_table + index) func = ida_funcs.get_func(dword) if func is None: MAX_TL_API = dword else: func_name = ida_name.get_name(func.start_ea) print("[*] Renaming function %s to %s" % (func_name, tl_api_name)) ida_name.set_name(func.start_ea, encode(tl_api_name), ida_name.SN_FORCE) if tl_api_type: set_function_prototype(func, encode(tl_api_type)) if api_number < MAX_DR_API: if not dr_api_name: pass else: dword = ida_bytes.get_dword(dr_table + index) func = ida_funcs.get_func(dword) if func is None: MAX_DR_API = dword else: func_name = ida_name.get_name(func.start_ea) print("[*] Renaming function %s to %s" % (func_name, tl_api_name)) ida_name.set_name(func.start_ea, encode(dr_api_name), ida_name.SN_FORCE) if dr_api_type: set_function_prototype(func, encode(dr_api_type))
def process_node(addr): global node_info if addr in node_info: node_info[addr]['first'] = False return node_info[addr] arg0 = ida_bytes.get_dword(addr) arg1 = ida_bytes.get_dword(addr + 0x4) func = ida_bytes.get_dword(addr + 0x8) n_out = ida_bytes.get_dword(addr + 0xC) out_ptr = ida_bytes.get_dword(addr + 0x10) out = [ida_bytes.get_dword(out_ptr + 4*i) for i in range(n_out)] info = { 'arg0' : arg0, 'arg1' : arg1, 'func' : func, 'n_out' : n_out, 'out' : out, } node_info[addr] = info return info
def followAddress(self, address): b = idaapi.get_byte(address) if (b == 0xE8): callOffset = ida_bytes.get_dword(address + 1) if (callOffset > 2147483647): callOffset -= 4294967296 address = address + 5 + callOffset return address, False elif (b == 0xE9): # Lazy and none of my signatures use this yet... return address, "JMP Instruction signatures not supported yet" else: return address, False
def _defineImportThunk(self, start, thunk_val): """If the binary has the Import Thunk filled, define it as a data chunk of appropriate size. """ info = idaapi.get_inf_structure() if info.is_64bit(): curr_val = idc.get_qword(start) if (curr_val == thunk_val): return ida_bytes.create_data(start, idaapi.FF_QWORD, 8, idaapi.BADADDR) elif info.is_32bit(): curr_val = ida_bytes.get_dword(start) if (curr_val == thunk_val): return ida_bytes.create_data(start, idaapi.FF_DWORD, 4, idaapi.BADADDR) return False