1
0
Fork 0

BRIDGE+DBG: added callstack functions + speedup of stackcommentget

This commit is contained in:
Mr. eXoDia 2014-07-24 21:04:46 +02:00
parent 9e6d1e4311
commit 0f75da8315
7 changed files with 174 additions and 24 deletions

View File

@ -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)
{

View File

@ -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
}

View File

@ -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;
}

View File

@ -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

View File

@ -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]="";

View File

@ -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));
}
}
}

View File

@ -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