def setBreakPoint(self, addr, funcName): self.addr = addr self.funcName = funcName #内部で保持しておかないと、消される。 self.bp_obj = pykd.setBp(int(addr), self.callBack) return
def _debug_server(self): ''' debugger thread ''' self._system_pid = None self.logger.info('Init pykd environment') pykd.initialize() try: # Start a new process for debugging argv = [self._process_path] + self._process_args + self.process_data argv = ' '.join(argv) self.logger.debug('Debugger starting server: %s' % argv) try: self.logger.info('Start running program with cmd:"%s"' % argv) self.report.add('cmd', argv) self._pid = pykd.startProcess(argv) self._get_correct_process_id() self.logger.debug('Process started. pykd_pid=%d' % self._pid) self._process = pykd.getCurrentProcess() self.logger.debug('Process is %s' % hex(self._process)) except WindowsError: self.logger.error('debug_server received exception', traceback.fmt_exc()) # Get Process System ID self._wait_break() while self._system_pid is None: try: self._system_pid = pykd.getProcessSystemID(self._pid) self.logger.info('process system_id=%d' % self._system_pid) except Exception as err: self.logger.debug("Get system id fail because of: %s" % err) continue # Set break points if self._wait_break(): self.logger.info("Server is in break status setting break points") for bp in self._break_points: pykd.setBp(bp) self.logger.info("Start register event handle") # This will register our handle handler = self._handler(self) self.logger.debug('Handler object is : %s' % handler) self.logger.info('Go !!!!!') pykd.go() except: self.logger.error('Got an exception in _debug_server') self.logger.error(traceback.format_exc())
def __init__(self): addr = get_address("jscript9!StrToDbl") if addr == None: return self.start = timeit.default_timer() handle_allocate_heap() handle_free_heap() handle_realloc_heap() self.bp_init = pykd.setBp(int(addr, 16), self.enter_call_back)
def enter_call_back(self,bp): print "RtlAllocateHeap called." if self.bp_end == None: disas = pykd.dbgCommand("uf ntdll!RtlAllocateHeap").split('\n') for i in disas: if 'ret' in i: self.ret_addr = i.split()[0] break self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def enter_call_back(self, bp): self.out = "RtlAllocateHeap(" esp = pykd.reg("esp") self.out += hex(pykd.ptrPtr(esp + 4)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x8)) + " , " self.out += hex(pykd.ptrMWord(esp + 0xC)) + ") = " if self.bp_end == None: self.ret_addr = pykd.dbgCommand("dd esp L1").split()[1] self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def enter_call_back(self,bp): self.out = "RtlAllocateHeap(" esp = pykd.reg("esp") self.out += hex(pykd.ptrPtr(esp + 4)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x8)) + " , " self.out += hex(pykd.ptrMWord(esp + 0xC)) + ") = " if self.bp_end == None: disas = pykd.dbgCommand("uf ntdll!RtlAllocateHeap").split('\n') for i in disas: if 'ret' in i: self.ret_addr = i.split()[0] break self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def enter_call_back(self,bp): self.out = "RtlFreeHeap(" if arch_bits == 32: esp = pykd.reg(stack_pointer) self.out += hex(pykd.ptrPtr(esp + 4)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x8)) + " , " self.out += hex(pykd.ptrPtr(esp + 0xC)) + ") = " else: self.out += hex(pykd.reg("rcx")) + " , " self.out += hex(pykd.reg("rdx")) + " , " self.out += hex(pykd.reg("r8")) + ") = " if self.bp_end == None: self.ret_addr = pykd.dbgCommand("dd esp L1").split()[1] self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def enter_call_back(self, bp): self.out = "RtlAllocateHeap(" if arch_bits == 32: esp = pykd.reg(stack_pointer) self.out += hex(pykd.ptrPtr(esp + 4)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x8)) + " , " self.out += hex(pykd.ptrMWord(esp + 0xC)) + ") = " else: self.out += hex(pykd.reg("rcx")) + " , " self.out += hex(pykd.reg("rdx")) + " , " self.out += hex(pykd.reg("r8")) + ") = " if self.bp_end == None: self.ret_addr = pykd.dbgCommand("dd esp L1").split()[1] self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def main(): pykd.initialize() pykd.handler = ExceptionHandler() pykd.startProcess("hello.exe") targetModule = pykd.module("hello") targetModule.reload() breakCount = callCounter() b1 = pykd.setBp(targetModule.offset('add'), breakCount) # The b1 cannot be commented print "There is %d breakpoint" % pykd.getNumberBreakpoints() pykd.go() print breakCount.count targetModule = None pykd.killAllProcesses()
def bpHandlerInterp(): """...""" global NPS, GBP if not NPS['HOOK_INTERP']: # Allocate memory for our hook getMethodNameHook = int((pykd.dbgCommand(".dvalloc 1000").\ split()[-1]),16) # Write the Interp hook print "[+] Interp Hook setup at address 0x%x" % getMethodNameHook writeHookInterp(getMethodNameHook) NPS['HOOK_INTERP'] = getMethodNameHook print "[+] Start hooking Interp Flash functions..." # Set the breakpoit right after getMethodName returns so that # we can read the resolved function name and address GBP['HOOK_INTERP'] = pykd.setBp(NPS['HOOK_INTERP']+0xe, hookHandlerInterp) # Redirect to our Interp hook pykd.dbgCommand("r eip=0x%x" % NPS['HOOK_INTERP']) return pykd.executionStatus.NoChange
def enter_call_back(self, bp): self.out = "RtlFreeHeap(" if arch_bits == 32: esp = pykd.reg(stack_pointer) self.out += hex(pykd.ptrPtr(esp + 4)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x8)) + " , " self.out += hex(pykd.ptrPtr(esp + 0xC)) + ") = " else: self.out += hex(pykd.reg("rcx")) + " , " self.out += hex(pykd.reg("rdx")) + " , " self.out += hex(pykd.reg("r8")) + ") = " if self.bp_end == None: disas = pykd.dbgCommand("uf ntdll!RtlFreeHeap").split("\n") for i in disas: if "ret" in i: self.ret_addr = i.split()[0] break self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def hookHandlerInterpRet(methodName): """...""" global GBP interpfunc = pykd.reg("eax") if pykd.isValid(interpfunc): print "[#] INTERP STUB: at 0x%x \t offset: 0x%x \t\tName: %s" %\ (interpfunc,0,methodName.decode("utf-8","replace")) if NPS["TraceInterp"] and methodName not in GBP['BP_FUNCS'] and\ methodName not in GBP['BP_RFUNCS']: if NPS["Debug"]: print "[Debug] Setting bp for tracing on 0x%x" % interpfunc GBP[interpfunc] = pykd.setBp(interpfunc, lambda: functionHandler(methodName)) func_breakpoints(methodName.decode("utf-8","replace"), interpfunc) else: print "[!] No interp stub found. Something is likely wrong!!!" try: del GBP['INTERP_RET'] except KeyError: pass return pykd.executionStatus.NoChange
def bpHandlerNative(): """Create and Install getMethodName hook void BaseExecMgr::setNative(MethodInfo* m, GprMethodProc p) Stringp MethodInfo::getMethodName(bool includeAllNamesplaces) const""" global NPS, GBP if not NPS['HOOK_NATIVE']: # Allocate memory for our hook getMethodNameHook = int((pykd.dbgCommand(".dvalloc 1000").\ split()[-1]),16) # Write the Native hook print "[+] Native Hook setup at address 0x%x" % getMethodNameHook writeHookNative(getMethodNameHook) NPS['HOOK_NATIVE'] = getMethodNameHook print "[+] Start hooking Native Flash functions..." # Set the breakpoit right after getMethodName returns so that # we can read the resolved function name and address GBP['HOOK_NATIVE'] = pykd.setBp(NPS['HOOK_NATIVE']+0xc, hookHandlerNative) # Redirect to our Native hook pykd.dbgCommand("r eip=0x%x" % NPS['HOOK_NATIVE']) return pykd.executionStatus.NoChange
def allocHandlerFixedMalloc(ret_addr): """Callback invoked when a FixedMalloc allcoation is requested.The function sets a breakpoint on the addresses within the function where the allocation address is returned.""" global GBP try: ret = ret_addr[pykd.reg("eip")] f_sig = pykd.dbgCommand("u 0x%x L1" % pykd.reg("eip")) # "0fdf1b82 81fef0070000 cmp esi,7F0h" reg32 = f_sig.split()[-1].split(",")[0].strip() #print "[Debug] Signature: %s reg32: %s" % (signature, reg32) req_size = pykd.reg(reg32) GBP["FixedMallocBPs"][ret] = pykd.setBp(ret, lambda: allocServedFixedMalloc(ret, req_size)) return pykd.executionStatus.NoChange except IndexError: print "[!] Could not extract the register for the follwing"\ "instruction: %s" % f_sig return pykd.executionStatus.Break
def enter_call_back(self): self.out = 'RtlFreeHeap(' if arch_bits == 32: esp = pykd.reg(stack_pointer) self.out += hex(pykd.ptrPtr(esp + 4)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x8)) + " , " self.out += hex(pykd.ptrPtr(esp + 0xC)) + ") = " else: self.out += hex(pykd.reg("rcx")) + " , " self.out += hex(pykd.reg("rdx")) + " , " self.out += hex(pykd.reg("r8")) + ") = " if self.bp_end == None: disas = pykd.dbgCommand("uf ntdll!RtlFreeHeap").split('\n') for i in disas: if 'ret' in i: self.ret_addr = i.split()[0] break self.bp_end = pykd.setBp(pykd.expr(self.ret_addr), self.return_call_back) return False
def monitorFixedMalloc(): """General monitor for FixedMalloc allocations""" global GBP start = time.time() ret_addr = {} for f_sig in fixedmalloc_funcs_sigs.keys(): try: f_start = func_addr[f_sig] except: continue # the function start (f_start) identified by the signature can either # be an address or a list of addresses in case findFunc found more # entries with that specific signature. if isinstance(f_start, (long,)): f_start = [f_start,] # For each f_start we try to find the place in the function where the # allocation is pulled from the free allocations linked list for # a specific memory page at page_start+4. According to our tests, # we can have 3 specific cases/signatures in which the pointer to the # head of the free list at poi(page_start+4) is copied to either ebx, # ebp or eax. # RetIns (Return Instruction) # 8B 5E 04 mov ebx, [esi+4] # OptRetIns (Optional Return Instructions): # 8B 6E 04 mov ebp, [esi+4] # 8B 46 04 mov eax, [esi+4] for i in f_start: rets = findAllocRets(i, None, ["\x8B", "\x5E", "\x04"], True, "FixedMalloc", (["\x8B", "\x6E", "\x04"], ["\x8B", "\x46", "\x04"])) if len(rets) > 1: if NPS["Debug"]: print "[Debug] More than one mov reg32, [esi+4] found!" ret_addr[i] = rets[0] GBP[i] = pykd.setBp(i, lambda: allocHandlerFixedMalloc(ret_addr)) if NPS["Debug"]: print "[*] %d seconds to complete the search and bps" %\ (time.time()-start)
def func_breakpoints(methodName, methodAddr): """Set the appropriate breakpoints when instructed by the user through the script options. Also set the appropriate breakpoints in the GC and FixedMalloc allocator functions to monitor heap allocations when instructed by the user through the script options.""" global GBP # Normal breakpoints on complete function name # like flash.display::LoaderInfo for func_name in GBP["BP_FUNCS"]: if func_name.lower() == methodName.lower(): print "[*] Setting break point on %s at address: 0x%x" %\ (methodName,methodAddr) #GBP[methodName] = pykd.setBp(methodAddr, #lambda: functionHandler(methodName)) pykd.dbgCommand("bp 0x%x" % methodAddr) # Breakpoints on any function matching a string like breakpoint on any # function containing the string LoaderInfo for func_name in GBP["BP_RFUNCS"]: if (methodName.lower().find(func_name.lower()))!=-1: print "[*] Setting break point on %s at address: 0x%x" %\ (methodName,methodAddr) #GBP[methodName] = pykd.setBp(methodAddr, #lambda: functionHandler(methodName)) pykd.dbgCommand("bp 0x%x" % methodAddr) # Heap monitor breakpoints if GBP["StartMonitorOnFunc"]: if (GBP["StartMonitorOnFunc"].lower().strip() ==\ methodName.lower().strip()): if NPS['list_gcallocs']: monitorGCAlloc() if NPS['list_fmallocs']: monitorFixedMallocOutOfLineAlloc() monitorFixedMallocLargeAlloc() monitorFixedMalloc() if NPS['list_HeapAlloc']: monitorHeapAlloc() print "[+] Starting to monitoring allocations after method %s" %\ methodName GBP["monitor_alloc_method"] = pykd.setBp(methodAddr, monitorHandler)
def hookHandlerJit(): """Unlike setNative, setJit is a fairly simple in that the GprMethodProc parameted contains the resolved address of the jitted function. We simply need to read that register value.""" global GBP # address of the func name as returned by getMethodName address = pykd.ptrPtr(pykd.reg("eax")+0x8) # address of the jitted function jitfunc = pykd.ptrPtr(pykd.reg("esp")+0x28) if pykd.isValid(address): methodName = pykd.loadCStr(address) if pykd.isValid(jitfunc): print "[&] JITTED METHOD: at 0x%x \t offset: 0x%x \t\tName: %s" %\ (jitfunc,0,methodName.decode("utf-8","replace")) if NPS["TraceJit"] and methodName not in GBP['BP_FUNCS'] and\ methodName not in GBP['BP_RFUNCS']: if NPS["Debug"]: print "[Debug] Setting bp for tracing on 0x%x" % jitfunc GBP[jitfunc] = pykd.setBp(jitfunc, lambda: functionHandler(methodName)) func_breakpoints(methodName.decode("utf-8","replace"), jitfunc) else: print "[!] No jitted function found. Something is likely wrong!!!" return pykd.executionStatus.NoChange
def enter_call_back(self): time = datetime.datetime.now() self.out = str(time) self.out += ", VirtualAlloc(" if arch_bits == 32: esp = pykd.reg(stack_pointer) self.out += hex(pykd.ptrPtr(esp + 4)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x8)) + " , " self.out += hex(pykd.ptrMWord(esp + 0xC)) + " , " self.out += hex(pykd.ptrMWord(esp + 0x10)) + ") = " else: self.out += hex(pykd.reg("rcx")) + " , " self.out += hex(pykd.reg("rdx")) + " , " self.out += hex(pykd.reg("r8")) + " , " self.out += hex(pykd.reg("r9")) + ") = " if self.bp_end == None: disas = pykd.dbgCommand("uf kernelbase!VirtualAlloc").split('\n') for i in disas: if 'ret' in i: self.ret_addr = format64(i.split()[0]) break self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def allocHandlerGCAlloc(rets): """Callback invoked when a GC allocation is requested. The function sets a breakpoint on the addresses within the function where the allocation address is returned.""" global GBP req_size = pykd.ptrPtr(pykd.reg("esi")+0x20) GCAlloc = pykd.reg("ecx") #MMgc::GCAlloc::GCAlloc #mov esi, ecx #... #mov ecx, [esp+10h+SmallGCAllocHeapPartition] #mov [esi+38h], edx #mov [esi+3Ch], ecx ; 0x3c is the partition index #mov [esi+30h], eax if IsheapIsolVersion(): Partition = pykd.ptrPtr(pykd.reg("esi")+0x3c) else: Partition = "NotImplemented" for ret in findAllocRets('GCAlloc::Alloc', func_sigs_ends['GCAllocEnd'], ["\xC2", "\x04", "\x00"]): GBP["GCAllocBPs"][ret] = pykd.setBp(ret, lambda: allocServedGCAlloc(req_size, ret, GCAlloc, Partition)) return pykd.executionStatus.NoChange
def handler_onCall(self): cmdr = pykd.dbgCommand("dd esp+8 L1") if cmdr == None: self.br.dbiprintf("[E] Before %s : Cannot dump stack" % self.symAllocateVirtualMemory) return pykd.eventResult.Break strPAllocAddr = cmdr[cmdr.find(" "):] iPAllocAddr = int(strPAllocAddr, 16) cmdr = pykd.dbgCommand("dd esp+10 L1") if cmdr == None: self.br.dbiprintf("[E] Before %s : Cannot dump stack" % self.symAllocateVirtualMemory) return pykd.eventResult.Break strPAllocSize = cmdr[cmdr.find(" "):] iPAllocSize = int(strPAllocSize, 16) cmdr = pykd.dbgCommand("dd esp+18 L1") if cmdr == None: self.br.dbiprintf("[E] Before %s : Cannot dump stack" % self.symAllocateVirtualMemory) return pykd.eventResult.Break strProtection = cmdr[cmdr.find(" "):] iProtection = int(strProtection, 16) if iProtection == 0x40: #self.br.dbiprintf("[*] Allocating memory for obfuscation has detected") #self.br.dbiprintf(" -> pAlloc : 0x%08x" % iPAllocAddr) self.iVmPAllocAddr = iPAllocAddr self.iVmPAllocSize = iPAllocSize self.iVmProtection = iProtection cmdr = pykd.dbgCommand("dd esp L1") strRet = cmdr[cmdr.find(" "):] self.pRet = int(strRet, 16) #self.br.dbiprintf(" -> Set break on RET : 0x%08x" % self.pRet) self.bp_end = pykd.setBp(self.pRet, self.handler_onRet) return pykd.eventResult.Proceed
def __init__(self): addr = get_address("ntdll!RtlAllocateHeap") if addr == None: return self.bp_init = pykd.setBp(int(addr, 16), self.enter_call_back) self.bp_end = None
def setBreakPoint(self, addr): #内部で保持しておかないと、消される。 self.bp_obj = pykd.setBp(int(addr), self.callBack) return
def testSetBp(self): bp = pykd.setBp(self.targetModule.CdeclFunc) self.assertEqual(pykd.executionStatus.Break, pykd.go())
def setBpOnNextInst(self, handler): eip = self.br.getRegVal("eip") instBytes = self.br.parseInstructionBytes() return pykd.setBp(eip + len(instBytes), handler)
# # We need to wait for the second instance of the target DLL if NPS['count'] == 2: # A custom exception handler can be handy to automate the analysis # at the moment we don't need it though. # pykd.dbgCommand("sxd av") # exc = ExceptionHandler() # Calculate module bounds that we will use for function searches getModuleSize('NPS') # Find the addresses of our functions findFuncs('NPS') # check for any options #parse_options() if NPS['list_jit'] or NPS["TraceJit"]: # Start resolving Jitted functions GBP["bpHandlerJit"] = pykd.setBp(func_addr["setJit"], bpHandlerJit) if NPS['list_native'] or NPS["TraceNative"]: # Start resolving Native functions GBP["bpHandlerNative"] = pykd.setBp(func_addr["setNative"], bpHandlerNative) if NPS['list_interp'] or NPS["TraceInterp"]: # Start resolving Interp functions GBP["bpHandlerInterp"] = pykd.setBp(func_addr["setInterp"], bpHandlerInterp) for offset in GBP['BP_OFFSETS']: print "[*] Setting break point at address: 0x%x" %\ (NPS['base_addr']+offset) #GBP[offset] = pykd.setBp(NPS['base_addr']+offset, None) cmd = "bp 0x%x" % (NPS['base_addr']+offset) pykd.dbgCommand(cmd) break
def testDeleteBp(self): bp = pykd.setBp(self.targetModule.CdeclFunc) del bp self.assertEqual(pykd.executionStatus.NoDebuggee, pykd.go())
def __add_breakpoint(self, address): if not address in self.breakpoints_map: self.breakpoints_map[address] = {} self.breakpoints_map[address]['bp'] = pykd.setBp( address, self.handle_breakpoint)
def testRemoveByIndex(self): bp1 = pykd.setBp(self.targetModule.CdeclFunc) bp2 = pykd.getBp(0) bp2.remove() self.assertEqual(pykd.executionStatus.NoDebuggee, pykd.go())
def __init__(self): addr = format64(get_address("ntdll!RtlAllocateHeap")) if addr == None: return self.bp_init = pykd.setBp(int(addr, 16), self.enter_call_back)
def __init__(self): addr = format64(get_address("kernel32!VirtualAlloc")) if addr == None: return self.bp_init = pykd.setBp(int(addr, 16), self.enter_call_back) self.bp_end = None
def bypass_evasion(self, esp, event_name, eip): try: if "FindWindow" in event_name: a = '' a = pykd.dbgCommand("dd esp") addr = a.split(" ")[4] esp_addr = a.split(" ")[0] a = pykd.dbgCommand("db " + addr).split(" ")[2] if "windbg" in a.replace(".", ''): pykd.dbgCommand("ed " + hex(int(esp_addr, 16) + 8) + " " + esp_addr) elif "QueryInformationProcess" in event_name: a = '' a = pykd.dbgCommand("dd esp") #print a addr = a.split(" ")[4] esp_addr = a.split(" ")[0] if int(addr, 16) == 7 or int(addr, 16) == 30 or int(addr, 16) == 31: pykd.dbgCommand("ed " + hex(int(esp_addr, 16) + 4) + " " + "0") a = pykd.dbgCommand("dd esp") addr = a.split(" ")[4] esp_addr = a.split(" ")[0] a = pykd.dbgCommand("dd esp+8").split(" ")[1][:8] if int(addr, 16) == 17: pykd.dbgCommand("ed " + hex(int(esp_addr, 16) + 4) + " " + "0") if "call_completed" in event_name: if self.mainClass.previous_tick_count == 0: self.mainClass.previous_tick_count = int( "9378c867", 16) pykd.dbgCommand("r @eax=9378c867" ) #+ hex(int("9378c867",16))[2:-1]) else: pykd.dbgCommand( "r @eax=" + hex(self.mainClass.previous_tick_count + 2)[2:-1]) self.mainClass.previous_tick_count = int( pykd.dbgCommand("r eax").split("=")[1].strip("\n"), 16) bl = pykd.dbgCommand("bl") index_of_breakpoint = bl.find(eip) tmp = bl[index_of_breakpoint - 8:index_of_breakpoint - 3].split("\n")[1] pykd.dbgCommand("bc " + tmp) else: if esp in self.mainClass.breakpoints_info.keys(): pass else: self.mainClass.GetTickCount_call_count += 1 self.mainClass.bp_init.append( pykd.setBp(int(esp, 16), self.mainClass.break_hit)) self.mainClass.breakpoints_info.update( {esp: "GetTickCount_call_completed"}) elif "DebugString" in event_name: if "DebugString_call_completed" in event_name: pykd.dbgCommand("r @eax=1") teb = pykd.dbgCommand("r $teb").split("=")[1].strip("\n") pykd.dbgCommand("ed " + hex(int(teb, 16) + 52)[2:] + " 6") else: self.mainClass.bp_init.append( pykd.setBp(int(esp, 16), self.mainClass.break_hit)) self.mainClass.breakpoints_info.update( {esp: "OutputDebugString_call_completed"}) elif "QueryObject" in event_name: if "QueryObject_call_completed" in event_name: pykd.dbgCommand("ed " + hex(self.mainClass.pObjectAllInfo) + " 0") else: a = pykd.dbgCommand("dd esp") addr = a.split("\n")[0].split(" ")[5] self.mainClass.pObjectAllInfo = int(addr, 16) self.mainClass.bp_init.append( pykd.setBp(int(esp, 16), self.mainClass.break_hit)) self.mainClass.breakpoints_info.update( {esp: "NtQueryObject_call_completed"}) elif "DebugActiveProcess" in event_name: if "bugActiveProcess_call_completed" in event_name: pykd.dbgCommand("r @eax=1") else: self.mainClass.bp_init.append( pykd.setBp(int(esp, 16), self.mainClass.break_hit)) self.mainClass.breakpoints_info.update( {esp: "DebugActiveProcess_call_completed"}) elif "ZwContinue" in event_name: pass if "_call_completed" in event_name: pass else: a = pykd.dbgCommand("dd esp") addr = a.split("\n")[0].split(" ")[3] next_eip = pykd.dbgCommand( "dd " + hex(int(addr, 16) + int("b8", 16))[2:]).split("\n")[0].split(" ")[2] elif "PerformanceCounter" in event_name: if "PerformanceCounter_call_completed" in event_name: pykd.dbgCommand("eq " + hex(self.mainClass.pLarge_integer) + " 0") else: self.mainClass.QueryPerformanceCounter_call_count += 1 a = pykd.dbgCommand("dd esp") addr = a.split("\n")[0].split(" ")[3] self.mainClass.pLarge_integer = int(addr, 16) self.mainClass.bp_init.append( pykd.setBp(int(esp, 16), self.mainClass.break_hit)) self.mainClass.breakpoints_info.update( {esp: "QueryPerformanceCounter_call_completed"} ) # +=esp+" "+ "QueryPerformanceCounter_call_completed" +"\n" elif "ConsoleCtrlEvent" in event_name: esp_addr = pykd.dbgCommand("r esp").split("=")[1].strip("\n") event = int( pykd.dbgCommand("dd " + esp_addr).split("\n")[0].split(" ")[3], 16) if event == 0: pykd.dbgCommand("ed " + hex(int(esp_addr, 16) + 4)[2:] + " 10") elif "entry_address" in event_name: teb = pykd.dbgCommand("r $teb").split("=")[1].strip("\n") a = pykd.dbgCommand("dd " + hex(int(teb, 16) + int("1000", 16) + 24)[2:]).split("\n")[0].split(" ")[2] pykd.dbgCommand("ba r4 " + hex(int(a, 16) + 16) + '"' + "r @eax=0;gc" + '"') pykd.dbgCommand("ba r4 " + hex(int(a, 16) + 12) + '"' + "r @eax=2;gc" + '"') elif "BlockInput" in event_name: esp_addr = pykd.dbgCommand("r esp").split("=")[1].strip("\n") event = int( pykd.dbgCommand("dd " + hex(int(esp_addr, 16) + 4)[2:]).split("\n")[0].split(" ")[2], 16) if event == 1: pykd.dbgCommand("ed " + hex(int(esp_addr, 16) + 4)[2:] + " 0") else: print "skipping" except Exception as e: print "exception in bypass: " + str(e) return True
def enter_call_back(self,bp): print "RtlAllocateHeap called." if self.bp_end == None: self.ret_addr = pykd.dbgCommand("dd esp L1").split()[1] self.bp_end = pykd.setBp(int(self.ret_addr, 16), self.return_call_back) return False
def testBreakCallback(self): breakCount = callCounter(stopOnBreak) bp = pykd.setBp(self.targetModule.CdeclFunc, breakCount) self.assertEqual(pykd.executionStatus.Break, pykd.go()) self.assertEqual(1, breakCount.count)
def testLambdaBpBreak(self): bp2 = pykd.setBp(self.targetModule.CdeclFunc, lambda: True) self.assertEqual(pykd.executionStatus.Break, pykd.go())
def onLoadModule(self, base, name): for offset, cb in self._pending_breakpoints.get(name.lower(), []): if name not in self._breakpoints: self._breakpoints[name] = [] self._breakpoints[name].append(pykd.setBp(base + offset, cb)) return pykd.eventResult.NoChange
def __init__(self): addr = get_address("ntdll!RtlFreeHeap") if addr == None: return self.bp_init = pykd.setBp(int(addr, 16), self.enter_call_back) self.bp_end = None
def testNoBreakCallback(self): breakCount = callCounter(continueOnBreak) bp = pykd.setBp(self.targetModule.CdeclFunc, breakCount) self.assertEqual(pykd.executionStatus.NoDebuggee, pykd.go()) self.assertEqual(1, breakCount.count)
def __init__(self): addr = pykd.getOffset("ntdll!RtlReAllocateHeap") if addr is None: return self.bp_init = pykd.setBp(addr, self.enter_call_back) self.bp_end = None
def __init__(self): addr = get_address("jscript9!StrToDbl") if addr == None: return self.start = timeit.default_timer() self.bp_init = pykd.setBp(int(addr, 16), self.enter_call_back)