BRIDGE+DBG: added callstack functions + speedup of stackcommentget
This commit is contained in:
parent
9e6d1e4311
commit
0f75da8315
|
@ -1012,6 +1012,11 @@ BRIDGE_IMPEXP void GuiUpdatePatches()
|
|||
_gui_sendmessage(GUI_UPDATE_PATCHES, 0, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateCallStack()
|
||||
{
|
||||
_gui_sendmessage(GUI_UPDATE_CALLSTACK, 0, 0);
|
||||
}
|
||||
|
||||
//Main
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
|
|
|
@ -629,7 +629,8 @@ typedef enum
|
|||
GUI_ADD_MSG_TO_STATUSBAR, // param1=const char* msg, param2=unused
|
||||
GUI_UPDATE_SIDEBAR, // param1=unused, param2=unused
|
||||
GUI_REPAINT_TABLE_VIEW, // param1=unused, param2=unused
|
||||
GUI_UPDATE_PATCHES // param1=unused, param2=unused
|
||||
GUI_UPDATE_PATCHES, // param1=unused, param2=unused
|
||||
GUI_UPDATE_CALLSTACK // param1=unused, param2=unused
|
||||
} GUIMSG;
|
||||
|
||||
//GUI structures
|
||||
|
@ -701,6 +702,7 @@ BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg);
|
|||
BRIDGE_IMPEXP void GuiUpdateSideBar();
|
||||
BRIDGE_IMPEXP void GuiRepaintTableView();
|
||||
BRIDGE_IMPEXP void GuiUpdatePatches();
|
||||
BRIDGE_IMPEXP void GuiUpdateCallStack();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "patches.h"
|
||||
#include "memory.h"
|
||||
#include "disasm_fast.h"
|
||||
#include "stackinfo.h"
|
||||
|
||||
static DBGFUNCTIONS _dbgfunctions;
|
||||
|
||||
|
@ -100,6 +101,11 @@ static int _modpathfromname(const char* modname, char* path, int size)
|
|||
return _modpathfromaddr(modbasefromname(modname), path, size);
|
||||
}
|
||||
|
||||
static void _getcallstack(DBGCALLSTACK* callstack)
|
||||
{
|
||||
stackgetcallstack(GetContextData(UE_CSP), (CALLSTACK*)callstack);
|
||||
}
|
||||
|
||||
void dbgfunctionsinit()
|
||||
{
|
||||
_dbgfunctions.AssembleAtEx=_assembleatex;
|
||||
|
@ -120,4 +126,5 @@ void dbgfunctionsinit()
|
|||
_dbgfunctions.ModPathFromName=_modpathfromname;
|
||||
_dbgfunctions.DisasmFast=disasmfast;
|
||||
_dbgfunctions.MemUpdateMap=memupdatemap;
|
||||
_dbgfunctions.GetCallStack=_getcallstack;
|
||||
}
|
|
@ -13,6 +13,20 @@ typedef struct
|
|||
unsigned char newbyte;
|
||||
} DBGPATCHINFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
duint addr;
|
||||
duint from;
|
||||
duint to;
|
||||
char comment[MAX_COMMENT_SIZE];
|
||||
} DBGCALLSTACKENTRY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int total;
|
||||
DBGCALLSTACKENTRY* entries;
|
||||
} DBGCALLSTACK;
|
||||
|
||||
typedef bool (*ASSEMBLEATEX)(duint addr, const char* instruction, char* error, bool fillnop);
|
||||
typedef bool (*SECTIONFROMADDR)(duint addr, char* section);
|
||||
typedef bool (*MODNAMEFROMADDR)(duint addr, char* modname, bool extension);
|
||||
|
@ -31,6 +45,7 @@ typedef int (*MODPATHFROMADDR)(duint addr, char* path, int size);
|
|||
typedef int (*MODPATHFROMNAME)(const char* modname, char* path, int size);
|
||||
typedef bool (*DISASMFAST)(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo);
|
||||
typedef void (*MEMUPDATEMAP)(HANDLE hProcess);
|
||||
typedef void (*GETCALLSTACK)(DBGCALLSTACK* callstack);
|
||||
|
||||
typedef struct DBGFUNCTIONS_
|
||||
{
|
||||
|
@ -52,6 +67,7 @@ typedef struct DBGFUNCTIONS_
|
|||
MODPATHFROMNAME ModPathFromName;
|
||||
DISASMFAST DisasmFast;
|
||||
MEMUPDATEMAP MemUpdateMap;
|
||||
GETCALLSTACK GetCallStack;
|
||||
} DBGFUNCTIONS;
|
||||
|
||||
#ifdef BUILD_DBG
|
||||
|
|
|
@ -181,15 +181,25 @@ bool dbgcmddel(const char* name)
|
|||
return true;
|
||||
}
|
||||
|
||||
DWORD WINAPI updateCallStackThread(void* ptr)
|
||||
{
|
||||
GuiUpdateCallStack();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DebugUpdateGui(uint disasm_addr, bool stack)
|
||||
{
|
||||
uint cip=GetContextData(UE_CIP);
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, disasm_addr))
|
||||
GuiDisasmAt(disasm_addr, cip);
|
||||
uint csp=GetContextData(UE_CSP);
|
||||
if(stack)
|
||||
{
|
||||
uint csp=GetContextData(UE_CSP);
|
||||
GuiStackDumpAt(csp, csp);
|
||||
static uint cacheCsp=0;
|
||||
if(csp!=cacheCsp)
|
||||
{
|
||||
cacheCsp=csp;
|
||||
CloseHandle(CreateThread(0, 0, updateCallStackThread, 0, 0, 0));
|
||||
}
|
||||
char modname[MAX_MODULE_SIZE]="";
|
||||
char modtext[MAX_MODULE_SIZE*2]="";
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
#include "disasm_helper.h"
|
||||
#include "disasm_fast.h"
|
||||
#include "BeaEngine\BeaEngine.h"
|
||||
#include "addrinfo.h"
|
||||
#include "_exports.h"
|
||||
|
@ -23,6 +24,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
memread(fdProcessInfo->hProcess, (const void*)readStart, disasmData, sizeof(disasmData), 0);
|
||||
uint prev=disasmback(disasmData, 0, sizeof(disasmData), data-readStart, 1);
|
||||
uint previousInstr=readStart+prev;
|
||||
|
||||
DISASM disasm;
|
||||
disasm.Options=NoformatNumeral;
|
||||
#ifdef _WIN64
|
||||
|
@ -31,13 +33,10 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
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
|
||||
BASIC_INSTRUCTION_INFO basicinfo;
|
||||
bool valid=disasmfast(disasmData+prev, previousInstr, &basicinfo);
|
||||
if(valid && basicinfo.call) //call
|
||||
{
|
||||
DISASM_INSTR instr;
|
||||
memset(&instr, 0, sizeof(instr));
|
||||
disasmget((unsigned char*)disasm.EIP, previousInstr, &instr);
|
||||
|
||||
char label[MAX_LABEL_SIZE]="";
|
||||
ADDRINFO addrinfo;
|
||||
addrinfo.flags=flaglabel;
|
||||
|
@ -52,21 +51,25 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
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);
|
||||
data=basicinfo.addr;
|
||||
if(data)
|
||||
{
|
||||
*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_s(returnFromAddr, label);
|
||||
sprintf_s(comment->comment, "return to %s from %s", returnToAddr, returnFromAddr);
|
||||
}
|
||||
else
|
||||
sprintf_s(comment->comment, "return to %s from ???", returnToAddr);
|
||||
strcpy(comment->color, "#ff0000");
|
||||
return true;
|
||||
}
|
||||
|
@ -107,4 +110,96 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#include "console.h"
|
||||
void stackgetcallstack(uint csp, CALLSTACK* callstack)
|
||||
{
|
||||
callstack->total=0;
|
||||
if(!DbgIsDebugging() or csp%sizeof(uint)) //alignment problem
|
||||
return;
|
||||
if(!memisvalidreadptr(fdProcessInfo->hProcess, csp))
|
||||
return;
|
||||
std::vector<CALLSTACKENTRY> callstackVector;
|
||||
DWORD ticks=GetTickCount();
|
||||
uint stacksize;
|
||||
uint stackbase=memfindbaseaddr(csp, &stacksize, false);
|
||||
//walk up the stack
|
||||
uint i=csp;
|
||||
while(i!=stackbase+stacksize)
|
||||
{
|
||||
uint data=0;
|
||||
memread(fdProcessInfo->hProcess, (const void*)i, &data, sizeof(uint), 0);
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, data)) //the stack value is a pointer
|
||||
{
|
||||
uint size=0;
|
||||
uint base=memfindbaseaddr(data, &size);
|
||||
uint readStart=data-16*4;
|
||||
if(readStart<base)
|
||||
readStart=base;
|
||||
unsigned char disasmData[256];
|
||||
memread(fdProcessInfo->hProcess, (const void*)readStart, disasmData, sizeof(disasmData), 0);
|
||||
uint prev=disasmback(disasmData, 0, sizeof(disasmData), data-readStart, 1);
|
||||
uint previousInstr=readStart+prev;
|
||||
BASIC_INSTRUCTION_INFO basicinfo;
|
||||
bool valid=disasmfast(disasmData+prev, previousInstr, &basicinfo);
|
||||
if(valid && basicinfo.call) //call
|
||||
{
|
||||
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);
|
||||
|
||||
CALLSTACKENTRY curEntry;
|
||||
memset(&curEntry, 0, sizeof(CALLSTACKENTRY));
|
||||
curEntry.addr=i;
|
||||
curEntry.to=data;
|
||||
curEntry.from=basicinfo.addr;
|
||||
|
||||
data=basicinfo.addr;
|
||||
|
||||
if(data)
|
||||
{
|
||||
*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_s(curEntry.comment, "return to %s from %s", returnToAddr, returnFromAddr);
|
||||
}
|
||||
else
|
||||
sprintf_s(curEntry.comment, "return to %s from ???", i, returnToAddr);
|
||||
callstackVector.push_back(curEntry);
|
||||
}
|
||||
}
|
||||
i+=sizeof(uint);
|
||||
}
|
||||
callstack->total=(int)callstackVector.size();
|
||||
if(callstack->total)
|
||||
{
|
||||
callstack->entries=(CALLSTACKENTRY*)BridgeAlloc(callstack->total*sizeof(CALLSTACKENTRY));
|
||||
for(int i=0; i<callstack->total; i++)
|
||||
{
|
||||
//CALLSTACKENTRY curEntry;
|
||||
//memcpy(&curEntry, &callstackVector.at(i), sizeof(CALLSTACKENTRY));
|
||||
//dprintf(fhex":"fhex":"fhex":%s\n", curEntry.addr, curEntry.to, curEntry.from, curEntry.comment);
|
||||
memcpy(&callstack->entries[i], &callstackVector.at(i), sizeof(CALLSTACKENTRY));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,21 @@
|
|||
|
||||
#include "_global.h"
|
||||
|
||||
struct CALLSTACKENTRY
|
||||
{
|
||||
uint addr;
|
||||
uint from;
|
||||
uint to;
|
||||
char comment[MAX_COMMENT_SIZE];
|
||||
};
|
||||
|
||||
struct CALLSTACK
|
||||
{
|
||||
int total;
|
||||
CALLSTACKENTRY* entries;
|
||||
};
|
||||
|
||||
bool stackcommentget(uint addr, STACK_COMMENT* comment);
|
||||
void stackgetcallstack(uint csp, CALLSTACK* callstack);
|
||||
|
||||
#endif //_STACKINFO_H
|
Loading…
Reference in New Issue