def main(): for segstart, segend, segname in enum_segments(): if segname not in ('.rdata', 'UPX1'): continue print(segname) for src, dst, size in find_pointers(segstart, segend): if idc.get_segm_name(dst) not in (".text", "UPX0"): continue if is_code(dst): continue print("new function pointer: 0x%x -> 0x%x" % (src, dst)) ida_auto.auto_make_code(dst) ida_auto.auto_make_proc(dst) ida_bytes.del_items(src, size) ida_bytes.create_data(src, idc.FF_QWORD if size == 8 else idc.FF_DWORD, size, idc.BADADDR) # this doesn't seem to always work :-( idc.op_plain_offset(src, -1, 0) ida_name.set_name(src, "j_%s_%x" % (src, dst))
def restore_x(unique_name=None, start=None): ea = ida_kernwin.get_screen_ea() # signature if not unique_name: if not start: seg = ida_segment.getseg(ea) start = seg.start_ea sig_bytes = ida_bytes.get_bytes(start, SIGNATURE_SIZE) sig_hash = hashlib.md5(sig_bytes).hexdigest() unique_name = sig_hash if not start: seg = ida_segment.getseg(ea) start = seg.start_ea if MD5_hash_data_file and os.path.isfile(MD5_hash_data_file): with open(MD5_hash_data_file, "rb") as ifile: received_data = pickle.loads(ifile.read()) saved_data = received_data print("dumpDyn::restore\n\ Name: {}\n\ Restore address: {}\n".format(unique_name, hex(start))) # (start_addr, end_addr, names, comms, bpts, funcs) if unique_name in saved_data: current_data = saved_data[unique_name] # restore names names = current_data[2] for name in names: # names: (rel_addr, name, is_code) ida_name.set_name(start + name[0], name[1]) flags = ida_bytes.get_flags(start + name[0]) if name[2] and not ida_bytes.is_code(flags): ida_auto.auto_make_code(start + name[0]) # restore comments # comms: (rel_addr, TYPE, comment) comms = current_data[3] for comm in comms: # 0:MakeComm and 1:MakeRptCmt ida_bytes.set_cmt(start + comm[0], comm[2], comm[1]) # restore breakpoints # bpts: (rel_addr, size, type) bpts = current_data[4] for bpt in bpts: ida_dbg.add_bpt(start + bpt[0], bpt[1], bpt[2]) # restore functions funcs_addr = current_data[5] for addr in funcs_addr: ida_auto.auto_make_proc(start + addr) # make code & func
def nop_region(ea, size): """replace the given range with NOPs""" logger.debug("nopping region from 0x%x size 0x%x", ea, size) for i in range(ea, ea + size): ida_bytes.del_items(i) for i in range(ea, ea + size): ida_bytes.patch_byte(i, 0x90) ida_auto.auto_make_code(ea)
def set_function(address: int, name: str, is_func: bool, is_entry: bool) -> None: ida_auto.auto_make_code(address) if is_func: ida_auto.auto_make_proc(address) idaapi.set_name(address, name, idaapi.SN_NOCHECK | idaapi.SN_NOWARN) idaapi.auto_wait() if is_func: fn = idaapi.get_func(address) if fn: fn.flags |= idaapi.FUNC_LIB if is_entry: ida_entry.add_entry(address, address, name, True) if is_func and SigApplier.has_non_default_name(address, None): return idaapi.set_name(address, name, idaapi.SN_NOCHECK | idaapi.SN_NOWARN | idaapi.SN_LOCAL)
def assume_code_at(ea): ida_bytes.del_items(ea, ida_bytes.DELIT_EXPAND) ida_auto.auto_make_code(ea) run_autoanalysis(ea)
def apply_signatures(self, start_addr: int, end_addr: int) -> None: total_objs = len(self._signatures) idaapi.msg('Applying obj symbols...\n') objs_list = dict() for sig in self._signatures: bytes_data = sig.get_sig() low_entropy = (not bytes_data.is_bios_call()) and (sig.get_entropy() < self.min_entropy) labels = sig.get_labels() search_addr = start_addr while search_addr < end_addr: addr, _ = masked_search(search_addr, end_addr, bytes_data.get_bytes(), bytes_data.get_masks()) if addr == idaapi.BADADDR: break if not sig.is_applied(): objs_list[sig.get_name()] = (addr, sig.get_entropy()) for lb in labels: lb_name = lb[0] lb_offs = lb[1] if lb_name == '': # removed label continue lb_addr = addr + lb_offs if ida_bytes.is_unknown(ida_bytes.get_flags(lb_addr) and not low_entropy and not (sig.is_applied() and self.only_first)): ida_auto.auto_make_code(lb_addr) is_func = not lb_name.startswith('loc_') new_name = '%s_' % sig.get_name().replace('.', '_') new_lb_name = lb_name.replace('text_', new_name).replace('loc_', new_name) new_lb_name = ('_%s' % new_lb_name) if ('0' <= new_lb_name[0] <= '9') else new_lb_name if not low_entropy and not (sig.is_applied() and self.only_first) and not self.has_non_default_name(lb_addr, new_lb_name): SigApplier.set_function(lb_addr, new_lb_name, is_func, False) idaapi.msg('Symbol %s at 0x%08X\n' % (new_lb_name, lb_addr)) else: prev_comment = ida_bytes.get_cmt(lb_addr, False) prev_comment = ('%s\n' % prev_comment) if prev_comment else '' new_comment = 'Possible %s/%s' % (sig.get_name(), new_lb_name) if prev_comment.find(new_comment) == -1: ida_bytes.set_cmt(lb_addr, '%s%s' % (prev_comment, new_comment), False) idaapi.msg('Possible symbol %s at 0x%08X\n' % (new_lb_name, lb_addr)) sig.set_applied(True) search_addr = addr + 4 idaapi.msg('Applied OBJs for %s: %d/%d:\n' % (self.short_lib_name, len(objs_list), total_objs)) for k, v in objs_list.items(): idaapi.msg('\t0x%08X: %s, %.02f entropy\n' % (v[0], k, v[1]))