extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr) { static uint cacheFlags; static uint cacheAddr; static bool cacheResult; if(cacheAddr != addr || cacheFlags != GetContextDataEx(hActiveThread, UE_EFLAGS)) { cacheFlags = GetContextDataEx(hActiveThread, UE_EFLAGS); cacheAddr = addr; cacheResult = IsJumpGoingToExecuteEx(fdProcessInfo->hProcess, fdProcessInfo->hThread, (ULONG_PTR)cacheAddr, cacheFlags); } return cacheResult; }
PLUG_IMPEXP void _plugin_debugpause() { GuiSetDebugState(paused); DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); lock(WAITID_RUN); SetForegroundWindow(GuiGetWindowHandle()); dbgsetskipexceptions(false); wait(WAITID_RUN); }
bool cbInstrPrintStack(int argc, char* argv[]) { duint csp = GetContextDataEx(hActiveThread, UE_CSP); std::vector<CALLSTACKENTRY> callstackVector; stackgetcallstack(csp, callstackVector, false); if(callstackVector.size() == 0) dputs(QT_TRANSLATE_NOOP("DBG", "No call stack.")); else { duint cip = GetContextDataEx(hActiveThread, UE_CIP); #ifdef _WIN64 duint cbp = GetContextDataEx(hActiveThread, UE_RBP); dprintf(QT_TRANSLATE_NOOP("DBG", "%llu call stack frames (RIP = %p , RSP = %p , RBP = %p ):\n"), callstackVector.size(), cip, csp, cbp); #else //x86 duint cbp = GetContextDataEx(hActiveThread, UE_EBP); dprintf(QT_TRANSLATE_NOOP("DBG", "%u call stack frames (EIP = %p , ESP = %p , EBP = %p ):\n"), callstackVector.size(), cip, csp, cbp); #endif //_WIN64 for(auto & i : callstackVector) dprintf_untranslated("%p %s\n", i.addr, i.comment); } return true; }
static void cbDebugLoadLibBPX() { HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID); #ifdef _WIN64 duint LibAddr = GetContextDataEx(LoadLibThread, UE_RAX); #else duint LibAddr = GetContextDataEx(LoadLibThread, UE_EAX); #endif //_WIN64 varset("$result", LibAddr, false); backupctx.eflags &= ~0x100; SetFullContextDataEx(LoadLibThread, &backupctx); MemFreeRemote(DLLNameMem); MemFreeRemote(ASMAddr); ThreadResumeAll(); //update GUI DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true); //lock lock(WAITID_RUN); dbgsetforeground(); PLUG_CB_PAUSEDEBUG pauseInfo = { nullptr }; plugincbcall(CB_PAUSEDEBUG, &pauseInfo); wait(WAITID_RUN); }
void ThreadGetList(THREADLIST* List) { ASSERT_NONNULL(List); SHARED_ACQUIRE(LockThreads); // // This function converts a C++ std::unordered_map to a C-style THREADLIST[]. // Also assume BridgeAlloc zeros the returned buffer. // List->count = (int)threadList.size(); List->list = nullptr; if(List->count <= 0) return; // Allocate C-style array List->list = (THREADALLINFO*)BridgeAlloc(List->count * sizeof(THREADALLINFO)); // Fill out the list data int index = 0; for(auto & itr : threadList) { HANDLE threadHandle = itr.second.Handle; // Get the debugger's active thread index if(threadHandle == hActiveThread) List->CurrentThread = index; memcpy(&List->list[index].BasicInfo, &itr.second, sizeof(THREADINFO)); List->list[index].ThreadCip = GetContextDataEx(threadHandle, UE_CIP); List->list[index].SuspendCount = ThreadGetSuspendCount(threadHandle); List->list[index].Priority = ThreadGetPriority(threadHandle); List->list[index].WaitReason = ThreadGetWaitReason(threadHandle); List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase); index++; } }
extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo) { if(!DbgIsDebugging()) return false; bool retval = false; if(addrinfo->flags & flagmodule) //get module { if(ModNameFromAddr(addr, addrinfo->module, false)) //get module name retval = true; } if(addrinfo->flags & flaglabel) { if(LabelGet(addr, addrinfo->label)) retval = true; else //no user labels { DWORD64 displacement = 0; char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_LABEL_SIZE; if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) && !displacement) { pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) strcpy_s(addrinfo->label, pSymbol->Name); retval = true; } if(!retval) //search for CALL <jmp.&user32.MessageBoxA> { BASIC_INSTRUCTION_INFO basicinfo; memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); if(disasmfast(addr, &basicinfo) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP { uint val = 0; if(MemRead(basicinfo.memory.value, &val, sizeof(val))) { if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) && !displacement) { pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name); retval = true; } } } } if(!retval) //search for module entry { uint entry = ModEntryFromAddr(addr); if(entry && entry == addr) { strcpy_s(addrinfo->label, "EntryPoint"); retval = true; } } } } if(addrinfo->flags & flagbookmark) { addrinfo->isbookmark = BookmarkGet(addr); retval = true; } if(addrinfo->flags & flagfunction) { if(FunctionGet(addr, &addrinfo->function.start, &addrinfo->function.end)) retval = true; } if(addrinfo->flags & flagloop) { if(LoopGet(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end)) retval = true; } if(addrinfo->flags & flagcomment) { *addrinfo->comment = 0; if(CommentGet(addr, addrinfo->comment)) retval = true; else { DWORD dwDisplacement; IMAGEHLP_LINE64 line; line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); if(SafeSymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) && !dwDisplacement) { char filename[deflen] = ""; strcpy_s(filename, line.FileName); int len = (int)strlen(filename); while(filename[len] != '\\' && len != 0) len--; if(len) len++; sprintf_s(addrinfo->comment, "\1%s:%u", filename + len, line.LineNumber); retval = true; } else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number { DISASM_INSTR instr; String temp_string; String comment; ADDRINFO newinfo; char ascii[256 * 2] = ""; char unicode[256 * 2] = ""; memset(&instr, 0, sizeof(DISASM_INSTR)); disasmget(addr, &instr); int len_left = MAX_COMMENT_SIZE; for(int i = 0; i < instr.argcount; i++) { memset(&newinfo, 0, sizeof(ADDRINFO)); newinfo.flags = flaglabel; STRING_TYPE strtype = str_none; if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label { if(instr.type == instr_branch || !disasmgetstringat(instr.arg[i].constant, &strtype, ascii, unicode, len_left) || strtype == str_none) continue; switch(strtype) { case str_none: break; case str_ascii: temp_string = instr.arg[i].mnemonic; temp_string.append(":\""); temp_string.append(ascii); temp_string.append("\""); break; case str_unicode: temp_string = instr.arg[i].mnemonic; temp_string.append(":L\""); temp_string.append(unicode); temp_string.append("\""); break; } } else if(instr.arg[i].memvalue && (disasmgetstringat(instr.arg[i].memvalue, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo))) { switch(strtype) { case str_none: if(*newinfo.label) { temp_string = "["; temp_string.append(instr.arg[i].mnemonic); temp_string.append("]:"); temp_string.append(newinfo.label); } break; case str_ascii: temp_string = "["; temp_string.append(instr.arg[i].mnemonic); temp_string.append("]:"); temp_string.append(ascii); break; case str_unicode: temp_string = "["; temp_string.append(instr.arg[i].mnemonic); temp_string.append("]:"); temp_string.append(unicode); break; } } else if(instr.arg[i].value && (disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo))) { if(instr.type != instr_normal) //stack/jumps (eg add esp,4 or jmp 401110) cannot directly point to strings strtype = str_none; switch(strtype) { case str_none: if(*newinfo.label) { temp_string = instr.arg[i].mnemonic; temp_string.append(":"); temp_string.append(newinfo.label); } break; case str_ascii: temp_string = instr.arg[i].mnemonic; temp_string.append(":\""); temp_string.append(ascii); temp_string.append("\""); break; case str_unicode: temp_string = instr.arg[i].mnemonic; temp_string.append(":L\""); temp_string.append(unicode); temp_string.append("\""); break; } } else continue; if(!strstr(comment.c_str(), temp_string.c_str())) { if(comment.length()) comment.append(", "); comment.append(temp_string); retval = true; } } comment.resize(MAX_COMMENT_SIZE - 2); String fullComment = "\1"; fullComment += comment; strcpy_s(addrinfo->comment, fullComment.c_str()); } } } return retval; }