diff --git a/x64_dbg_dbg/_plugins.cpp b/x64_dbg_dbg/_plugins.cpp index 4b10f173..860f31a0 100644 --- a/x64_dbg_dbg/_plugins.cpp +++ b/x64_dbg_dbg/_plugins.cpp @@ -41,7 +41,7 @@ PLUG_IMPEXP void _plugin_logputs(const char* text) PLUG_IMPEXP void _plugin_debugpause() { - DebugUpdateGui(GetContextData(UE_CIP)); + DebugUpdateGui(GetContextData(UE_CIP), true); GuiSetDebugState(paused); lock(WAITID_RUN); dbgsetskipexceptions(false); diff --git a/x64_dbg_dbg/debugger.cpp b/x64_dbg_dbg/debugger.cpp index 4005596b..b45669f7 100644 --- a/x64_dbg_dbg/debugger.cpp +++ b/x64_dbg_dbg/debugger.cpp @@ -70,12 +70,16 @@ void dbgsetskipexceptions(bool skip) bSkipExceptions=skip; } -void DebugUpdateGui(uint disasm_addr) +void DebugUpdateGui(uint disasm_addr, bool stack) { GuiUpdateAllViews(); - GuiDisasmAt(disasm_addr, (duint)GetContextData(UE_CIP)); - uint csp=GetContextData(UE_CSP); - GuiStackDumpAt(csp, csp); + uint cip=GetContextData(UE_CIP); + GuiDisasmAt(disasm_addr, cip); + if(stack) + { + uint csp=GetContextData(UE_CSP); + GuiStackDumpAt(csp, csp); + } char modname[MAX_MODULE_SIZE]=""; if(!modnamefromaddr(disasm_addr, modname, true)) *modname=0; @@ -131,7 +135,7 @@ static void cbUserBreakpoint() bptobridge(&bp, &pluginBp); bpInfo.breakpoint=&pluginBp; } - DebugUpdateGui(GetContextData(UE_CIP)); + DebugUpdateGui(GetContextData(UE_CIP), true); GuiSetDebugState(paused); //lock lock(WAITID_RUN); @@ -164,7 +168,7 @@ static void cbHardwareBreakpoint(void* ExceptionAddress) bptobridge(&found, &pluginBp); bpInfo.breakpoint=&pluginBp; } - DebugUpdateGui(cip); + DebugUpdateGui(cip, true); GuiSetDebugState(paused); //lock lock(WAITID_RUN); @@ -201,7 +205,7 @@ static void cbMemoryBreakpoint(void* ExceptionAddress) } if(found.singleshoot) bpdel(found.addr, BPMEMORY); //delete from breakpoint list - DebugUpdateGui(cip); + DebugUpdateGui(cip, true); GuiSetDebugState(paused); //lock lock(WAITID_RUN); @@ -335,7 +339,7 @@ static bool cbRemoveModuleBreakpoints(const BREAKPOINT* bp) static void cbStep() { isStepping=false; - DebugUpdateGui(GetContextData(UE_CIP)); + DebugUpdateGui(GetContextData(UE_CIP), true); GuiSetDebugState(paused); PLUG_CB_STEPPED stepInfo; stepInfo.reserved=0; @@ -351,7 +355,7 @@ static void cbStep() static void cbRtrFinalStep() { - DebugUpdateGui(GetContextData(UE_CIP)); + DebugUpdateGui(GetContextData(UE_CIP), true); GuiSetDebugState(paused); //lock lock(WAITID_RUN); @@ -472,7 +476,7 @@ static void cbSystemBreakpoint(void* ExceptionData) //log message dputs("system breakpoint reached!"); //update GUI - DebugUpdateGui(GetContextData(UE_CIP)); + DebugUpdateGui(GetContextData(UE_CIP), true); GuiSetDebugState(paused); //lock lock(WAITID_RUN); @@ -558,7 +562,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData) { dputs("paused!"); SetNextDbgContinueStatus(DBG_CONTINUE); - DebugUpdateGui(GetContextData(UE_CIP)); + DebugUpdateGui(GetContextData(UE_CIP), true); GuiSetDebugState(paused); //lock lock(WAITID_RUN); @@ -586,7 +590,7 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData) SetNextDbgContinueStatus(DBG_CONTINUE); } - DebugUpdateGui(GetContextData(UE_CIP)); + DebugUpdateGui(GetContextData(UE_CIP), true); GuiSetDebugState(paused); //lock lock(WAITID_RUN); @@ -1121,7 +1125,7 @@ CMDRESULT cbDebugDisasm(int argc, char* argv[]) if(argget(*argv, arg1, 0, true)) if(!valfromstring(arg1, &addr)) addr=GetContextData(UE_CIP); - DebugUpdateGui(addr); + DebugUpdateGui(addr, false); return STATUS_CONTINUE; } diff --git a/x64_dbg_dbg/debugger.h b/x64_dbg_dbg/debugger.h index b57a6d97..fe070cf6 100644 --- a/x64_dbg_dbg/debugger.h +++ b/x64_dbg_dbg/debugger.h @@ -18,7 +18,7 @@ struct INIT_STRUCT void dbgdisablebpx(); void dbgenablebpx(); bool dbgisrunning(); -void DebugUpdateGui(uint disasm_addr); +void DebugUpdateGui(uint disasm_addr, bool stack); void dbgsetskipexceptions(bool skip); //callbacks CMDRESULT cbDebugInit(int argc, char* argv[]); diff --git a/x64_dbg_dbg/disasm_helper.cpp b/x64_dbg_dbg/disasm_helper.cpp index ece44605..b2be535e 100644 --- a/x64_dbg_dbg/disasm_helper.cpp +++ b/x64_dbg_dbg/disasm_helper.cpp @@ -7,6 +7,112 @@ #include #include +unsigned int disasmback(unsigned char* data, uint base, uint size, uint ip, int n) +{ + int i; + uint abuf[131], addr, back, cmdsize; + unsigned char* pdata; + int len; + + // Reset Disasm Structure + DISASM disasm; + memset(&disasm, 0, sizeof(DISASM)); +#ifdef _WIN64 + disasm.Archi = 64; +#endif + disasm.Options=NoformatNumeral; + + // Check if the pointer is not null + if (data == NULL) + return 0; + + // Round the number of back instructions to 127 + if(n < 0) + n = 0; + else if (n > 127) + n = 127; + + // Check if the instruction pointer ip is not outside the memory range + if(ip >= size) + ip = size - 1; + + // Obvious answer + if(n == 0) + return ip; + + if(ip < (uint)n) + return ip; + + back = 16 * (n + 3); // Instruction length limited to 16 + + if(ip < back) + back = ip; + + addr = ip - back; + + pdata = data + addr; + + for(i = 0; addr < ip; i++) + { + abuf[i % 128] = addr; + + disasm.EIP = (UIntPtr)pdata; + len = Disasm(&disasm); + cmdsize = (len < 1) ? 1 : len ; + + pdata += cmdsize; + addr += cmdsize; + back -= cmdsize; + } + + if(i < n) + return abuf[0]; + else + return abuf[(i - n + 128) % 128]; +} + +unsigned int disasmnext(unsigned char* data, uint base, uint size, uint ip, int n) +{ + int i; + uint cmdsize; + unsigned char* pdata; + int len; + + // Reset Disasm Structure + DISASM disasm; + memset(&disasm, 0, sizeof(DISASM)); +#ifdef _WIN64 + disasm.Archi = 64; +#endif + disasm.Options=NoformatNumeral; + + if(data == NULL) + return 0; + + if (ip >= size) + ip = size - 1; + + if(n <= 0) + return ip; + + pdata = data + ip; + size -= ip; + + for(i = 0; i < n && size > 0; i++) + { + disasm.EIP = (UIntPtr)pdata; + disasm.SecurityBlock = (UIntPtr)size; + len = Disasm(&disasm); + cmdsize = (len < 1) ? 1 : len; + + pdata += cmdsize; + ip += cmdsize; + size -= cmdsize; + } + + return ip; +} + const char* disasmtext(uint addr) { unsigned char buffer[16]=""; diff --git a/x64_dbg_dbg/disasm_helper.h b/x64_dbg_dbg/disasm_helper.h index f2902ae8..263ef869 100644 --- a/x64_dbg_dbg/disasm_helper.h +++ b/x64_dbg_dbg/disasm_helper.h @@ -4,6 +4,8 @@ #include "_global.h" //functions +unsigned int disasmback(unsigned char* data, uint base, uint size, uint ip, int n); +unsigned int disasmnext(unsigned char* data, uint base, uint size, uint ip, int n); const char* disasmtext(uint addr); void disasmprint(uint addr); void disasmget(unsigned char* buffer, uint addr, DISASM_INSTR* instr); diff --git a/x64_dbg_dbg/stackinfo.cpp b/x64_dbg_dbg/stackinfo.cpp index 240b5cef..054f5d25 100644 --- a/x64_dbg_dbg/stackinfo.cpp +++ b/x64_dbg_dbg/stackinfo.cpp @@ -1,6 +1,97 @@ #include "stackinfo.h" +#include "debugger.h" +#include "memory.h" +#include "disasm_helper.h" +#include "BeaEngine\BeaEngine.h" +#include "addrinfo.h" +#include "_exports.h" bool stackcommentget(uint addr, STACK_COMMENT* comment) { + uint data=0; + memset(comment, 0, sizeof(STACK_COMMENT)); + memread(fdProcessInfo->hProcess, (const void*)addr, &data, sizeof(uint), 0); + if(memisvalidreadptr(fdProcessInfo->hProcess, data)) //valid memory + { + uint size=0; + uint base=memfindbaseaddr(fdProcessInfo->hProcess, data, &size); + uint readStart=data-16*4; + if(readStarthProcess, (const void*)readStart, disasmData, sizeof(disasmData), 0); + unsigned int prev=disasmback(disasmData, 0, sizeof(disasmData), data-readStart, 1); + uint previousInstr=readStart+prev; + DISASM disasm; + disasm.Options=NoformatNumeral; +#ifdef _WIN64 + disasm.Archi=64; +#endif // _WIN64 + disasm.VirtualAddr=previousInstr; + disasm.EIP=(UIntPtr)(disasmData+prev); + int len=Disasm(&disasm); + static char instruction[INSTRUCT_LENGTH]=""; + if(len!=UNKNOWN_OPCODE && disasm.Instruction.BranchType==CallType) //call + { + DISASM_INSTR instr; + disasmget((unsigned char*)disasm.EIP, previousInstr, &instr); + + char label[MAX_LABEL_SIZE]=""; + ADDRINFO addrinfo; + addrinfo.flags=flaglabel; + if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) + strcpy(label, addrinfo.label); + char module[MAX_MODULE_SIZE]=""; + modnamefromaddr(data, module, false); + char returnToAddr[MAX_COMMENT_SIZE]=""; + if(*module) + sprintf(returnToAddr, "%s.", module); + if(!*label) + sprintf(label, fhex, data); + strcat(returnToAddr, label); + + data=instr.arg[0].value; + *label=0; + addrinfo.flags=flaglabel; + if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) + strcpy(label, addrinfo.label); + *module=0; + modnamefromaddr(data, module, false); + char returnFromAddr[MAX_COMMENT_SIZE]=""; + if(*module) + sprintf(returnFromAddr, "%s.", module); + if(!*label) + sprintf(label, fhex, data); + strcat(returnFromAddr, label); + + sprintf(comment->comment, "return to %s from %s", returnToAddr, returnFromAddr); + strcpy(comment->color, "#ff0000"); + return true; + } + else + { + char label[MAX_LABEL_SIZE]=""; + ADDRINFO addrinfo; + addrinfo.flags=flaglabel; + if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) + strcpy(label, addrinfo.label); + char module[MAX_MODULE_SIZE]=""; + modnamefromaddr(data, module, false); + char addrInfo[MAX_COMMENT_SIZE]=""; + if(*module) //module + { + if(*label) //+label + sprintf(comment->comment, "%s.%s", module, label); + else //module only + sprintf(comment->comment, "%s."fhex, module, data); + return true; + } + else if(*label) //label only + { + sprintf(comment->comment, "<%s>", label); + return true; + } + } + } return false; } \ No newline at end of file diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index 26cf601b..ec700cd8 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -1417,7 +1417,7 @@ bool valtostring(const char* string, uint* value, bool silent) } bool ok=setregister(string, *value); if(strstr(string, "ip")) - DebugUpdateGui(GetContextData(UE_CIP)); //update disassembly + register view + DebugUpdateGui(GetContextData(UE_CIP), false); //update disassembly + register view else if(strstr(string, "sp")) //update stack { uint csp=GetContextData(UE_CSP); diff --git a/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp b/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp index 7a938c0b..5419b400 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp @@ -80,7 +80,6 @@ QString CPUStack::paintContent(QPainter* painter, int_t rowBase, int rowOffset, painter->save(); if(wActiveStack) { - //TODO: custom colors if(*comment.color) painter->setPen(QPen(QColor(QString(comment.color)))); else