def get_dbg_brk_linux32(): ''' Return the current brk value in the debugged process (only x86 Linux) ''' #TODO this method is so weird, find a unused address to inject code not the base address code = "" code += '\xb8-\x00\x00\x00' #mov eax, sys_brk ; 45 code += '1\xdb' #xor ebx, ebx code += '\xcd\x80' #int 0x80 eax = idc.get_reg_value("eax") ebx = idc.get_reg_value("ebx") eip = idc.get_reg_value("eip") efl = idc.get_reg_value("efl") base = idaapi.get_imagebase() #inj = idc.next_head(eip) #skip current instr inj = base save = idc.get_bytes(inj, len(code), use_dbg=True) for i in xrange(len(code)): idc.patch_dbg_byte(inj + i, ord(code[i])) #idc.MakeCode(inj) idc.set_reg_value(inj, "eip") idaapi.step_into() idc.GetDebuggerEvent(idc.WFNE_SUSP, -1) idaapi.step_into() idc.GetDebuggerEvent(idc.WFNE_SUSP, -1) idaapi.step_into() idc.GetDebuggerEvent(idc.WFNE_SUSP, -1) brk_res = idc.get_reg_value("eax") idc.set_reg_value(eax, "eax") idc.set_reg_value(ebx, "ebx") idc.set_reg_value(eip, "eip") idc.set_reg_value(efl, "efl") for i in xrange(len(save)): idc.patch_dbg_byte(inj + i, ord(save[i])) save = idc.get_bytes(inj, len(code), use_dbg=True) #idc.MakeCode(inj) return brk_res
def get_dbg_brk_linux64(): ''' Return the current brk value in the debugged process (only x86_64 Linux) ''' #TODO this method is so weird, find a unused address to inject code not the base address code = "" code += 'H\xc7\xc0\x0c\x00\x00\x00' #mov rax, sys_brk ; 12 code += 'H1\xff' #xor rdi, rdi code += '\x0f\x05' #syscall rax = idc.get_reg_value("rax") rdi = idc.get_reg_value("rdi") rip = idc.get_reg_value("rip") efl = idc.get_reg_value("efl") base = idaapi.get_imagebase() #inj = idc.next_head(rip) #skip current instr inj = base save = idc.get_bytes(inj, len(code), use_dbg=True) for i in xrange(len(code)): idc.patch_dbg_byte(inj + i, ord(code[i])) #idc.MakeCode(inj) idc.set_reg_value(inj, "rip") idaapi.step_into() idc.GetDebuggerEvent(idc.WFNE_SUSP, -1) idaapi.step_into() idc.GetDebuggerEvent(idc.WFNE_SUSP, -1) idaapi.step_into() idc.GetDebuggerEvent(idc.WFNE_SUSP, -1) brk_res = idc.get_reg_value("rax") idc.set_reg_value(rax, "rax") idc.set_reg_value(rdi, "rdi") idc.set_reg_value(rip, "rip") idc.set_reg_value(efl, "efl") for i in xrange(len(save)): idc.patch_dbg_byte(inj + i, ord(save[i])) save = idc.get_bytes(inj, len(code), use_dbg=True) #idc.MakeCode(inj) return brk_res
def colorize_register(self, reg): result = '' reduced = False try: reg_val = idc.get_reg_value(reg) except: return None, False label, changed = self.get_reg_label(reg, reg_val) chain = self.get_ptr_chain(reg_val) result += label + self.colorize_value(chain[0]) if reg == dbg.registers.flagsr: return result, changed elif reg != dbg.registers.pc: vals = chain[1:] if len(vals) > config.max_deref_levels: vals = vals[:config.max_deref_levels] reduced = True result += ''.join([self.as_ptr(value) for value in vals]) if reduced: result += self.as_arrow_string("[...]") result += self.get_value_info(chain[-1]) if chain.limit_exceeded: result += self.as_arrow_string("[...]") return result, changed
def __call__(self): try: idaapi.continue_process() idc.GetDebuggerEvent(self.mode, self.flag) l.debug("Debugger stopped at " + hex(idc.get_reg_value('eip'))) except Exception: self.exception = True
def get_jit_function(self): esp = idc.get_reg_value("ESP") method_name = self.get_method_name(esp) function = idc.get_wide_dword(esp + 8) method_id = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x20) abc_info_pos = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x1C) method_info = get_qword(abc_info_pos) + get_qword(abc_info_pos + 8) if (self.as3dump != []): method = next((x for x in self.as3dump if x["id"] == method_id), None) if (method is not None and method["info"] == method_info): method_name = method["name"] self.set_jit_info(method_id, function) print("Resolved jit function: 0x%x - %s" % (function, method_name)) self.rename_addr(function, method_name) if ((method_name not in self.ignore and not self.ignore_all) or (method_name in self.debug_if_equals) or (any(x for x in self.debug_if_contains if method_name is not None and x in method_name))): self.traced.append({"name": method_name, "ea": function, "type": "jit", "hit": 0}) idc.add_bpt(function)
def get_local_var_value_64(loc_var_name): frame = ida_frame.get_frame(idc.here()) loc_var = ida_struct.get_member_by_name(frame, loc_var_name) loc_var_start = loc_var.soff loc_var_ea = loc_var_start + idc.get_reg_value("RSP") loc_var_value = idc.read_dbg_qword(loc_var_ea) # in case the variable is 32bit, just use get_wide_dword() instead return loc_var_value
def get_native_function(self): ecx = idc.get_reg_value("ECX") esp = idc.get_reg_value("ESP") method_name = self.get_method_name(esp) if (idc.get_wide_byte(idc.get_wide_dword(ecx + 8) + 0x38) != 0): function = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x28) else: function = idc.get_wide_dword(idc.get_wide_dword(esp + 4) + 0x24) print("Resolved native function: 0x%x - %s" % (function, method_name)) if ((method_name not in self.ignore and not self.ignore_all) or (method_name in self.debug_if_equals) or (any(x for x in self.debug_if_contains if method_name is not None and x in method_name))): self.traced.append({"name": method_name, "ea": function, "type": "native", "hit": 0}) idc.add_bpt(function)
def get_interpreted_function(self, eip): if (eip == self.addr["setInterp"]): esp = idc.get_reg_value("ESP") self.method_name = self.get_method_name(esp) self.is_interpreted_state = True elif (eip == self.addr["setInterpRet"] and self.is_interpreted_state): function = idc.get_reg_value("EAX") print("Resolved interpreted function: 0x%x - %s" % (function, self.method_name)) if ((self.method_name not in self.ignore and not self.ignore_all) or (self.method_name in self.debug_if_equals) or (any(x for x in self.debug_if_contains if self.method_name is not None and x in self.method_name))): self.traced.append({"name": self.method_name, "ea": function, "type": "interp", "hit": 0}) idc.add_bpt(function) self.is_interpreted_state = False
def dbg_process_start(self, pid, tid, ea, name, base, size): self.mem_for_inline_hooks = 0 self.virtualalloc = 0 ntdll = DllHook('ntdll.dll') ntdll.add_func( FuncHook('ntdll_NtClose', NtClose_inline_hook_code_32, NtClose_bpt_cond_hook_code_32)) ntdll.add_func( FuncHook('ntdll_NtQueryInformationProcess', NtQueryInformationProcess_inline_hook_code_32, NtQueryInformationProcess_bpt_cond_hook_code_32)) self.dlls = [ntdll] # IDA creates a segment named "TIB[XXXXXXXX]", which points to # wow_peb64 antually. We can get peb from wow_peb64 with 0x1000 offset. # peb_addr = wow_peb64_addr + 0x1000 # Note: IDA has not created segment "TIB[XXXXXXXX]" at this point. # tid = get_current_thread() # tib_segm_name = "TIB[%08X]" % tid # print tib_segm_name # tib_segm = get_segm_by_name(tib_segm_name) # wow_peb64 = tib_segm.start_ea # peb = tib_segm.start_ea + 0x1000 # on debugging start, ebx points to peb # get addrs of peb and wow_peb64 ebx = idc.get_reg_value("ebx") peb = ebx wow_peb64 = peb - 0x1000 # patch peb->BeingDebugged # solving peb->NtGlobalFlag and "Heap Magic" anti-debug method # at the same time. idc.patch_byte(peb + 2, 0) idc.patch_byte(wow_peb64 + 2, 0) # patching peb process paramters peb_process_parameters = idaapi.get_dword(peb + 0x10) flag = idaapi.get_dword(peb_process_parameters + 0x8) idc.patch_dword(peb_process_parameters + 0x8, flag | 0x4000) # patching peb64 process paramters peb64_process_parameters = idaapi.get_qword(wow_peb64 + 0x20) flag = idaapi.get_dword(peb64_process_parameters + 0x8) idc.patch_dword(peb64_process_parameters + 0x8, flag | 0x4000)
def read_var(self, var): try: if isinstance(var, WatchVar): v = self.read_value(var.t, var.ea, var.np) else: ea = var.ea if isinstance(ea, str): ea = WordObj(idc.get_reg_value(var.ea)) else: sp = Arch.sp() ea = WordObj(sp + ea) v = self.read_value(var.t, ea, var.np) var.push_value(v) return v except Exception as e: return None
def modify_value(self): reg = self.get_selected_reg() if not reg: return reg_val = idc.get_reg_value(reg) b = idaapi.ask_str("0x%X" % reg_val, 0, "Modify register value") if b is not None: try: value = int(idaapi.str2ea(b)) idc.set_reg_value(value, reg) self.reload_info() if reg == dbg.registers.flags: self.reload_flags_view() except: idaapi.warning("Invalid expression")
def reload_info(self): if not dbg.is_process_suspended(): return False self.ClearLines() for flag in dbg.registers.flags: try: value = idc.get_reg_value(flag) result = None if self.flag_vals[flag] != value: result = self.as_changed(str(value)) self.flag_vals[flag] = value else: result = str(value) self.add_line('%-4s %s' % (flag, result)) except: pass return True
def reload_info(self): if not dbg.is_process_suspended(): return False base_addr = None if self.base_expr is None: base_addr = idc.get_reg_value(dbg.registers.stack) else: base_addr = idaapi.str2ea(self.base_expr) if base_addr == idc.BADADDR: idaapi.warning("Invalid base expr: %s" % self.base_expr) return False if not idaapi.is_loaded(base_addr): idaapi.warning("Memory address is not loaded: $#x" % base_addr) return False self.ClearLines() dbg.set_thread_info() try: segm_end = idc.get_segm_end(base_addr) n_entries = config.n_stack_entries or ((segm_end - base_addr) // dbg.ptr_size) for i in range(n_entries): offset = i * dbg.ptr_size ptr = base_addr + offset if not idaapi.is_loaded(ptr): break value = dbg.get_ptr(ptr) self.add_line("%02d:%04X %s" % (i, offset, self.parse_value(ptr))) except Exception as e: idaapi.warning(str(e)) return False return True
def getRegVarValue(reg): retval = None if idaapi.IDA_SDK_VERSION <= 699: try: retval = get_reg_value(reg) except: ''' reg is a symbol, get its value and read memory at that address ''' x = idc.get_name_ea_simple(reg) retval = idc.read_dbg_dword(x) else: ea = idaapi.get_screen_ea() regvar_map = {} fn = ida_funcs.get_func(ea) if fn: for rv in fn.regvars: regvar_map[rv.user] = rv.canon if reg in regvar_map: reg = regvar_map[reg] else: print('%s not in map' % (reg)) retval = idc.get_reg_value(reg) return retval
def log_operands(): dsm = idc.GetDisasm(cpu.eip) info(f"{dsm}") for i in range(2): op_type = idc.get_operand_type(cpu.eip, i) if op_type > 0: if op_type == 1: register = idc.print_operand(cpu.eip, i) value = idc.get_reg_value(register) info(f"register:{register} op{i}:0x{value:x}") elif op_type == 3: register = idc.print_operand(cpu.eip, i) register = re.match(r"\[(\w*)\]", register).group(1) address = getattr(cpu, register) value = get_32bit(address) info(f"address:0x{address:x} op{i}:0x{value:x}") elif op_type == 4: register = idc.print_operand(cpu.eip, i) register = re.match(r"\[(\w*)\+(.*)\]", register).group(1) value = ctypes.c_int32(idc.get_operand_value(cpu.eip, i)).value address = getattr(cpu, register) + value value = get_32bit(address) info(f"address:0x{address:x} op{i}:0x{value:x}")
def handler(self, break_on_next = False): if (not self.init()): return False timeout = time.time() + self.timeout_seconds while(self.wait_event()): eip = idc.get_reg_value("EIP") if (eip == self.addr["verifyNative"]): self.get_native_function() elif (eip == self.addr["setJit"]): self.get_jit_function() elif (eip == self.addr["setInterp"] or eip == self.addr["setInterpRet"]): self.get_interpreted_function(eip) elif (eip == self.addr["writePrologue"] or eip == self.addr["hasReachableExceptionsRet"]): self.force_save_eip_generation(eip) elif (self.stop_execution(eip, break_on_next)): break if (time.time() > timeout): ret = ask_yn(-1, 'Timeout %d seconds. Would you like to continue execution?' % self.timeout_seconds) if (ret == 1): timeout = time.time() + self.timeout_seconds else: return False return True
def reg(name): return idc.get_reg_value(name)
def GetRegValue(name): return idc.get_reg_value(name)
def __call__(self): try: self.result = idc.get_reg_value(self.register) except Exception as e: l.debug("read_register exception %s" % (e)) self.exception = True
def __getattr__(self, name): return idc.get_reg_value(name)
def get_reg_value(reg): if idaapi.IDA_SDK_VERSION <= 699: retval = idc.GetRegValue(reg) else: retval = idc.get_reg_value(reg) return retval
def get_reg(self, name): return idc.get_reg_value(name)
def __getattr__(self, name): #print "cpu.get(%s)" % name return idc.get_reg_value(name)
import ida_idd, idc, ida_dbg def go(): run_to(0x76794cf6) def gogo(): t = ida_idd.regval_t() t.set_int(0x76794cfa) ida_dbg.set_reg_val("PC", t) while get_reg_value("R7") < 9: go() GetDebuggerEvent(WFNE_SUSP, -1) print hex(idc.get_reg_value("R1")) + " " + hex( idc.get_reg_value("R4")) + "|" + hex(idc.get_reg_value("R1") + 10) + " " + hex( idc.get_reg_value("R2")) gogo() print "___"