1
0
Fork 0

GUI: added stack

BRIDGE: added stack functions (GuiStackDumpAt & DbgStackCommentGet)
DBG: added stackinfo skeleton
GUI: fixed some stuff in the HexDump class
This commit is contained in:
mr.exodia 2014-03-02 20:59:58 +01:00
parent 10fc4ee86e
commit 68a7a66336
18 changed files with 174 additions and 45 deletions

View File

@ -549,6 +549,11 @@ BRIDGE_IMPEXP void DbgDisasmAt(duint addr, DISASM_INSTR* instr)
_dbg_sendmessage(DBG_DISASM_AT, (void*)addr, instr);
}
BRIDGE_IMPEXP bool DbgStackCommentGet(duint addr, STACK_COMMENT* comment)
{
return (bool)(duint)_dbg_sendmessage(DBG_STACK_COMMENT_GET, (void*)addr, comment);
}
//GUI
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
{
@ -721,6 +726,11 @@ BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress)
_gui_sendmessage(GUI_REF_SETPROGRESS, (void*)(duint)progress, 0);
}
BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp)
{
_gui_sendmessage(GUI_STACK_DUMP_AT, (void*)addr, (void*)csp);
}
//Main
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{

View File

@ -114,7 +114,8 @@ enum DBGMSG
DBG_SYMBOL_ENUM, // param1=SYMBOLCBINFO* cbInfo, param2=unused
DBG_ASSEMBLE_AT, // param1=duint addr, param2=const char* instruction
DBG_MODBASE_FROM_NAME, // param1=const char* modname, param2=unused
DBG_DISASM_AT // param1=duint addr, param2=DISASM_INSTR* instr
DBG_DISASM_AT, // param1=duint addr, param2=DISASM_INSTR* instr
DBG_STACK_COMMENT_GET // param1=duint addr, param2=STACK_COMMENT* comment
};
enum SCRIPTLINETYPE
@ -288,6 +289,12 @@ struct DISASM_INSTR
DISASM_ARG arg[3];
};
struct STACK_COMMENT
{
char color[8]; //hex color-code
char comment[MAX_COMMENT_SIZE];
};
//Debugger functions
BRIDGE_IMPEXP const char* DbgInit();
BRIDGE_IMPEXP void DbgMemRead(duint va, unsigned char* dest, duint size);
@ -331,6 +338,7 @@ BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* us
BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction);
BRIDGE_IMPEXP duint DbgModBaseFromName(const char* name);
BRIDGE_IMPEXP void DbgDisasmAt(duint addr, DISASM_INSTR* instr);
BRIDGE_IMPEXP bool DbgStackCommentGet(duint addr, STACK_COMMENT* comment);
//Gui enums
enum GUIMSG
@ -347,7 +355,6 @@ enum GUIMSG
GUI_SET_INFO_LINE, // param1=(int)line, param2=(const char*)text
GUI_GET_WINDOW_HANDLE, // param1=unused, param2=unused
GUI_DUMP_AT, // param1=(duint)va param2=unused
GUI_SCRIPT_ADD, // param1=int count, param2=const char** lines
GUI_SCRIPT_CLEAR, // param1=unused, param2=unused
GUI_SCRIPT_SETIP, // param1=int line, param2=unused
@ -356,12 +363,10 @@ enum GUIMSG
GUI_SCRIPT_SETINFOLINE, // param1=int line, param2=const char* info
GUI_SCRIPT_MESSAGE, // param1=const char* message, param2=unused
GUI_SCRIPT_MSGYN, // param1=const char* message, param2=unused
GUI_SYMBOL_LOG_ADD, // param1(const char*)msg, param2=unused
GUI_SYMBOL_LOG_CLEAR, // param1=unused, param2=unused
GUI_SYMBOL_SET_PROGRESS, // param1=int percent param2=unused
GUI_SYMBOL_UPDATE_MODULE_LIST, // param1=int count, param2=SYMBOLMODULEINFO* modules
GUI_REF_ADDCOLUMN, // param1=int width, param2=(const char*)title
GUI_REF_SETROWCOUNT, // param1=int rows, param2=unused
GUI_REF_GETROWCOUNT, // param1=unused, param2=unused
@ -370,7 +375,8 @@ enum GUIMSG
GUI_REF_GETCELLCONTENT, // param1=int row, param2=int col
GUI_REF_RELOADDATA, // param1=unused, param2=unused
GUI_REF_SETSINGLESELECTION, // param1=int index, param2=bool scroll
GUI_REF_SETPROGRESS // param1=int progress, param2=unused
GUI_REF_SETPROGRESS, // param1=int progress, param2=unused
GUI_STACK_DUMP_AT // param1=duint addr, param2=duint csp
};
//GUI structures
@ -415,6 +421,7 @@ BRIDGE_IMPEXP const char* GuiReferenceGetCellContent(int row, int col);
BRIDGE_IMPEXP void GuiReferenceReloadData();
BRIDGE_IMPEXP void GuiReferenceSetSingleSelection(int index, bool scroll);
BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress);
BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp);
#ifdef __cplusplus
}

View File

@ -10,6 +10,7 @@
#include "simplescript.h"
#include "symbolinfo.h"
#include "assemble.h"
#include "stackinfo.h"
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size)
{
@ -611,6 +612,12 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
disasmget((uint)param1, (DISASM_INSTR*)param2);
}
break;
case DBG_STACK_COMMENT_GET:
{
return stackcommentget((uint)param1, (STACK_COMMENT*)param2);
}
break;
}
return 0;
}

View File

@ -74,6 +74,8 @@ void DebugUpdateGui(uint disasm_addr)
{
GuiUpdateAllViews();
GuiDisasmAt(disasm_addr, (duint)GetContextData(UE_CIP));
uint csp=GetContextData(UE_CSP);
GuiStackDumpAt(csp, csp);
char modname[MAX_MODULE_SIZE]="";
if(!modnamefromaddr(disasm_addr, modname, true))
*modname=0;

View File

@ -0,0 +1,6 @@
#include "stackinfo.h"
bool stackcommentget(uint addr, STACK_COMMENT* comment)
{
return false;
}

8
x64_dbg_dbg/stackinfo.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _STACKINFO_H
#define _STACKINFO_H
#include "_global.h"
bool stackcommentget(uint addr, STACK_COMMENT* comment);
#endif //_STACKINFO_H

View File

@ -1418,6 +1418,11 @@ 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
else if(strstr(string, "sp")) //update stack
{
uint csp=GetContextData(UE_CSP);
GuiStackDumpAt(csp, csp);
}
else
GuiUpdateAllViews(); //repaint gui
return ok;

View File

@ -113,6 +113,8 @@
<Unit filename="sqlhelper.cpp" />
<Unit filename="sqlhelper.h" />
<Unit filename="sqlite/sqlite3.h" />
<Unit filename="stackinfo.cpp" />
<Unit filename="stackinfo.h" />
<Unit filename="symbolinfo.cpp" />
<Unit filename="symbolinfo.h" />
<Unit filename="threading.cpp" />

View File

@ -27,6 +27,7 @@
<ClCompile Include="plugin_loader.cpp" />
<ClCompile Include="simplescript.cpp" />
<ClCompile Include="sqlhelper.cpp" />
<ClCompile Include="stackinfo.cpp" />
<ClCompile Include="symbolinfo.cpp" />
<ClCompile Include="threading.cpp" />
<ClCompile Include="value.cpp" />
@ -54,6 +55,7 @@
<ClInclude Include="plugin_loader.h" />
<ClInclude Include="simplescript.h" />
<ClInclude Include="sqlhelper.h" />
<ClInclude Include="stackinfo.h" />
<ClInclude Include="symbolinfo.h" />
<ClInclude Include="threading.h" />
<ClInclude Include="value.h" />

View File

@ -87,6 +87,9 @@
<ClCompile Include="symbolinfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stackinfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="_exports.h">
@ -167,5 +170,8 @@
<ClInclude Include="symbolinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stackinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -150,23 +150,17 @@ void HexDump::mouseReleaseEvent(QMouseEvent* event)
QString HexDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
{
//return QString("HexDump: Col:") + QString::number(col) + "Row:" + QString::number(rowBase + rowOffset);
QString wStr = "";
int wBytePerRowCount;
int_t wRva;
// Reset byte offset when base address is reached
if(rowBase == 0 && mByteOffset != 0)
printDumpAt(mBase);
// Compute RVA
wBytePerRowCount = getBytePerRowCount();
wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
int wBytePerRowCount = getBytePerRowCount();
int_t wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
QString wStr = "";
if(col == 0) // Addresses
{
//wStr += QString::number(wRva);
wStr += QString("%1").arg(mBase + wRva, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
}
else if(mDescriptor.at(col - 1).isData == true) //paint data
@ -174,14 +168,11 @@ QString HexDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, i
printSelected(painter, rowBase, rowOffset, col, x, y, w, h);
wStr += getString(col - 1, wRva);
}
else //paint comments
wStr += printNonData(col, wRva, mDescriptor.at(col-1), mMemPage);
return wStr;
}
else //paint non-data
{
QString HexDump::printNonData(int col, int_t wRva, ColumnDescriptor_t descriptor, MemoryPage* memPage)
{
return "";
}
return wStr;
}
void HexDump::printSelected(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)

View File

@ -126,9 +126,6 @@ public:
//descriptor management
void appendDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor);
void clearDescriptors();
//virtual
virtual QString printNonData(int col, int_t wRva, ColumnDescriptor_t descriptor, MemoryPage* memPage);
public slots:
void printDumpAt(int_t parVA);
@ -144,17 +141,15 @@ private:
} SelectionData_t;
SelectionData_t mSelection;
QList<ColumnDescriptor_t> mDescriptor;
GuiState_t mGuiState;
protected:
MemoryPage* mMemPage;
int_t mBase;
int_t mSize;
MemoryPage* mMemPage;
int mByteOffset;
QList<ColumnDescriptor_t> mDescriptor;
};
#endif // DUMP_H

View File

@ -205,6 +205,11 @@ void Bridge::emitReferenceSetProgress(int progress)
emit referenceSetProgress(progress);
}
void Bridge::emitStackDumpAt(uint_t va, uint_t csp)
{
emit stackDumpAt(va, csp);
}
/************************************************************************************
Static Functions
************************************************************************************/
@ -218,7 +223,6 @@ void Bridge::initBridge()
mBridge = new Bridge();
}
/************************************************************************************
Exported Functions
************************************************************************************/
@ -430,6 +434,12 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
}
break;
case GUI_STACK_DUMP_AT:
{
Bridge::getBridge()->emitStackDumpAt((uint_t)param1, (uint_t)param2);
}
break;
default:
{
}

View File

@ -50,7 +50,6 @@ public:
void emitAddMsgToSymbolLog(QString msg);
void emitClearSymbolLog();
void emitSetSymbolProgress(int progress);
void emitReferenceAddColumnAt(int width, QString title);
void emitReferenceSetRowCount(int_t count);
void emitReferenceDeleteAllColumns();
@ -58,6 +57,7 @@ public:
void emitReferenceReloadData();
void emitReferenceSetSingleSelection(int index, bool scroll);
void emitReferenceSetProgress(int progress);
void emitStackDumpAt(uint_t va, uint_t csp);
//Public variables
void* winId;
@ -77,7 +77,6 @@ signals:
void updateCPUTitle(QString modname);
void setInfoLine(int line, QString text);
void dumpAt(int_t va);
void scriptAdd(int count, const char** lines);
void scriptClear();
void scriptSetIp(int line);
@ -86,12 +85,10 @@ signals:
void scriptSetInfoLine(int line, QString info);
void scriptMessage(QString message);
void scriptQuestion(QString message);
void updateSymbolList(int module_count, SYMBOLMODULEINFO* modules);
void addMsgToSymbolLog(QString msg);
void clearSymbolLog();
void setSymbolProgress(int progress);
void referenceAddColumnAt(int width, QString title);
void referenceSetRowCount(int_t count);
void referenceDeleteAllColumns();
@ -99,6 +96,7 @@ signals:
void referenceReloadData();
void referenceSetSingleSelection(int index, bool scroll);
void referenceSetProgress(int progress);
void stackDumpAt(uint_t va, uint_t csp);
private:
QMutex mBridgeMutex;

View File

@ -47,13 +47,19 @@ CPUDump::CPUDump(QWidget *parent) : HexDump(parent)
connect(Bridge::getBridge(), SIGNAL(dumpAt(int_t)), this, SLOT(printDumpAt(int_t)));
}
QString CPUDump::printNonData(int col, int_t wRva, ColumnDescriptor_t descriptor, MemoryPage* memPage)
QString CPUDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
{
QString wStr = "";
uint_t data=0;
memPage->readOriginalMemory((byte_t*)&data, wRva, sizeof(uint_t));
char label_text[MAX_LABEL_SIZE]="";
if(DbgGetLabelAt(data, SEG_DEFAULT, label_text))
wStr+=QString(label_text);// + QString("%1").arg(data, sizeof(uint_t)*2, 16, QChar('0')).toUpper();
if(col && mDescriptor.at(col - 1).isData == false) //print comments
{
uint_t data=0;
int_t wRva = (rowBase + rowOffset) * getBytePerRowCount() - mByteOffset;
mMemPage->readOriginalMemory((byte_t*)&data, wRva, sizeof(uint_t));
char label_text[MAX_LABEL_SIZE]="";
if(DbgGetLabelAt(data, SEG_DEFAULT, label_text))
wStr=QString(label_text);
}
else
wStr = HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
return wStr;
}

View File

@ -12,7 +12,7 @@ class CPUDump : public HexDump
Q_OBJECT
public:
explicit CPUDump(QWidget *parent = 0);
QString printNonData(int col, int_t wRva, ColumnDescriptor_t descriptor, MemoryPage* memPage);
QString paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h);
};
#endif // CPUDUMP_H

View File

@ -25,10 +25,78 @@ CPUStack::CPUStack(QWidget *parent) : HexDump(parent)
wColDesc.data = dDesc;
appendDescriptor(0, "Comments", false, wColDesc);
connect(Bridge::getBridge(), SIGNAL(dumpAt(int_t)), this, SLOT(printDumpAt(int_t)));
connect(Bridge::getBridge(), SIGNAL(stackDumpAt(uint_t,uint_t)), this, SLOT(stackDumpAt(uint_t,uint_t)));
}
QString CPUStack::printNonData(int col, int_t wRva, ColumnDescriptor_t descriptor, MemoryPage* memPage)
QString CPUStack::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
{
return "Stack comment";
QString wStr=HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
// Compute RVA
int wBytePerRowCount = getBytePerRowCount();
int_t wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
uint_t wVa = wRva + mMemPage->getBase();
bool wIsSelected=isSelected(wRva);
if(wIsSelected) //highlight if selected
painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#C0C0C0")));
bool wActiveStack=true;
if(wVa<mCsp) //inactive stack
wActiveStack=false;
STACK_COMMENT comment;
if(col == 0) // paint stack address
{
painter->save();
if(wVa==mCsp) //CSP
{
painter->fillRect(QRect(x, y, w, h), QBrush(QColor("#000000")));
painter->setPen(QPen(QColor("#fffbf0")));
}
else if(wIsSelected)
painter->setPen(QPen(QColor("#000000"))); //black address
else
painter->setPen(QPen(QColor("#808080")));
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, wStr);
painter->restore();
wStr = "";
}
else if(mDescriptor.at(col - 1).isData == true) //paint stack data
{
painter->save();
if(wActiveStack)
painter->setPen(QPen(QColor("#000000")));
else
painter->setPen(QPen(QColor("#808080")));
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, wStr);
painter->restore();
wStr = "";
}
else if(DbgStackCommentGet(mMemPage->getBase()+wRva, &comment)) //paint stack comments
{
wStr = QString(comment.comment);
painter->save();
if(wActiveStack)
{
//TODO: custom colors
if(*comment.color)
painter->setPen(QPen(QColor(QString(comment.color))));
else
painter->setPen(QPen(QColor("#000000")));
}
else
painter->setPen(QPen(QColor("#808080")));
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, wStr);
painter->restore();
wStr = "";
}
return wStr;
}
void CPUStack::stackDumpAt(uint_t addr, uint_t csp)
{
mCsp=csp;
printDumpAt(addr);
}

View File

@ -12,7 +12,13 @@ class CPUStack : public HexDump
Q_OBJECT
public:
explicit CPUStack(QWidget *parent = 0);
QString printNonData(int col, int_t wRva, ColumnDescriptor_t descriptor, MemoryPage* memPage);
QString paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h);
public slots:
void stackDumpAt(uint_t addr, uint_t csp);
private:
uint_t mCsp;
};
#endif // CPUSTACK_H