def activate(self, ctx): f = search_strlit_form_t() f, args = f.Compile() ok = f.Execute() if ok: current_ea = ida_kernwin.get_screen_ea() patterns = ida_bytes.compiled_binpat_vec_t() encoding = ida_nalt.get_default_encoding_idx( ida_nalt.BPU_2B if f.Encoding.value else ida_nalt.BPU_1B) # string literals must be quoted. That's how parse_binpat_str # recognizes them (we want to be careful though: the user # might type in something like 'L"hello"', which should # decode to the IDB-specific wide-char set of bytes) text = f.Text.value if text.find('"') < 0: text = '"%s"' % text err = ida_bytes.parse_binpat_str( patterns, current_ea, text, 10, # radix (not that it matters though, since we're all about string literals) encoding) if not err: ea = ida_bytes.bin_search( current_ea, ida_ida.inf_get_max_ea(), patterns, ida_bytes.BIN_SEARCH_FORWARD | ida_bytes.BIN_SEARCH_NOBREAK | ida_bytes.BIN_SEARCH_NOSHOW) ok = ea != ida_idaapi.BADADDR if ok: ida_kernwin.jumpto(ea) else: print("Failed parsing binary pattern: \"%s\"" % err) return ok
def init_nearest_names(): debugNamesList = ida_name.get_debug_names(ida_ida.inf_get_min_ea(), ida_ida.inf_get_max_ea()) #NearestName definition: <ida_dir>\python\3\ida_name.py, line: 1351 #if your idapython NearestName is unavailable, comment this code return idaapi.NearestName(debugNamesList)
def get_new_func_name(log_func_addr, new_nm_index): frn_log("try get log args {:#x}".format(log_func_addr)) args_list = idaapi.get_arg_addrs(log_func_addr) if args_list == None: frn_log("func argument is none , try set argument number") return False if len(args_list) < (new_nm_index + 1): frn_log("func argument number is too small") return False if args_list[new_nm_index] > ida_ida.inf_get_max_ea(): frn_log("func argument addr is not accessible") return False name_addr = [ ref for ref in idautils.DataRefsFrom(args_list[new_nm_index]) ] if len(name_addr) < 2: frn_log("can't get name addr") return False name = idc.get_strlit_contents(name_addr[1]) if name == None: frn_log("new name is not string") return False name = 'func_' + ''.join(x for x in name.decode() if x.isalpha()) # Keep only the letters frn_log("new_func_name {}".format(name)) return name
def get_all_byte_chunks() -> Iterable[Tuple[int, int]]: """ Iterates all chunks of defined bytes in the sample. """ start = ida_ida.inf_get_min_ea() end = ida_ida.inf_get_max_ea() yield from get_byte_chunks(start, end - start)
def main(): if not ida_dbg.is_debugger_on(): print("Please run the process first!") return if ida_dbg.get_process_state() != -1: print("Please suspend the debugger first!") return dn = ida_name.get_debug_names(ida_ida.inf_get_min_ea(), ida_ida.inf_get_max_ea()) for i in dn: print("%08x: %s" % (i, dn[i]))
def dbg_trace(self, tid, ea): # Log all traced addresses if ea < ida_ida.inf_get_min_ea() or ea > ida_ida.inf_get_max_ea(): raise Exception( "Received a trace callback for an address outside this database!" ) self._log("trace %08X" % ea) self.traces += 1 insn = ida_ua.insn_t() insnlen = ida_ua.decode_insn(insn, ea) # log disassembly and ESP for call instructions if insnlen > 0 and insn.itype in [NN_callni, NN_call, NN_callfi]: self._log("call insn: %s" % generate_disasm_line( ea, GENDSM_FORCE_CODE | GENDSM_REMOVE_TAGS)) self._log("ESP=%08X" % ida_dbg.get_reg_val("ESP")) return 1
def apply_iat(self, iat): min_ea = ida_ida.inf_get_min_ea() max_ea = ida_ida.inf_get_max_ea() image_base = ida_nalt.get_imagebase() idaapi.msg(f"{hex(min_ea)} - {hex(max_ea)} - {hex(image_base)} \n") for i in range(min_ea, max_ea): mnemonic = idc.print_insn_mnem(i) if mnemonic == "call" and str(idc.print_operand( i, 0)).startswith("dword"): try: idc.set_name( idc.get_operand_value(i, 0), iat[hex(idc.get_operand_value(i, 0))] + str(random.randint(0, 1000)) ) # I added random.randint() because some functions already in the IAT are dynamically resolved again, so renaming them causes a conflict, if you want remove it. (Sample causing the problem: https://bazaar.abuse.ch/sample/49fd52a3f3d1d46dc065217e588d1d29fba4d978cd8fdb2887fd603320540f71/) open("resolved_iat.txt", "a").write(f"{hex(idc.get_operand_value(i, 0))}\n") except: open("unresolved_iat.txt", "a").write(f"{hex(idc.get_operand_value(i, 0))}\n")
def add_rodata_segment(self): last_seg_end = idc.get_first_seg() # print(hex(last_seg_end)) for s in idautils.Segments(): start = idc.get_segm_start(s) end = idc.get_segm_end(s) if int(start) != int(last_seg_end): # found idaapi.add_segm(0, last_seg_end, start, "roooodata", "CONST") print("Adding segment from 0x%x to 0x%x" % (last_seg_end, start)) print("OK") break else: last_seg_end = end idc.plan_and_wait(ida_ida.inf_get_min_ea(), ida_ida.inf_get_max_ea()) # idc.plan_and_wait(idc.MinEA(), idc.MaxEA()) self.start = last_seg_end self.end = start return last_seg_end, start
Run like so: ida -A "-S...path/to/produce_lst_file.py" <binary-file> where: -A instructs IDA to run in non-interactive mode -S holds a path to the script to run (note this is a single token; there is no space between '-S' and its path.) """ import ida_auto import ida_fpro import ida_ida import ida_loader import ida_pro # derive output file name idb_path = ida_loader.get_path(ida_loader.PATH_TYPE_IDB) lst_path = "%s.lst" % idb_path ida_auto.auto_wait() # wait for end of auto-analysis fptr = ida_fpro.qfile_t() # FILE * wrapper if fptr.open(lst_path, "wt"): try: ida_loader.gen_file( # generate .lst file ida_loader.OFILE_LST, fptr.get_fp(), ida_ida.inf_get_min_ea(), ida_ida.inf_get_max_ea(), 0) finally: fptr.close() ida_pro.qexit(0)
def make_udefind_func(self): ea = ida_ida.inf_get_min_ea() max_addr = ida_ida.inf_get_max_ea() while ea < max_addr: ea = idaapi.find_not_func(ea, idc.SEARCH_DOWN) ida_funcs.add_func(ea)
import idc import idaapi import ida_ida import ida_funcs max_addr = ida_ida.inf_get_max_ea() def find_a(): ea = ida_ida.inf_get_min_ea() while ea < max_addr: ea = idc.FindUnexplored(ea, idc.SEARCH_DOWN) ida_funcs.add_func(ea) def find_b(): ea = ida_ida.inf_get_min_ea() while ea < max_addr: ea = idaapi.find_not_func(ea, idc.SEARCH_DOWN) ida_funcs.add_func(ea) if __name__ == '__main__': find_b()