1
0
Fork 0

BRIDGE: removed infoline stuff

DBG: fixed stack dumping (now you cannot dump outside of the stack range)
DBG: fixed a bug with x64 memory reading (values were written back incorrectly @ math.cpp)
GUI: fixed a bug with dumping on invalid memory addresses
GUI: fixed a bug with disassembling on invalid memory addresses
GUI: InfoBox draft
GUI: chop spaces at the end of disassembled instructions
GUI: follow in dump draw (currently you can only follow the current selection)
GUI: fixed bugs with slots executed when not debugging anything
GUI: added goto expression to the menu
GUI: very basic stack menu
GUI: GotoDialog now has a valid memory range specifier
This commit is contained in:
Mr. eXoDia 2014-03-30 22:12:09 +02:00
parent e9e5b26d14
commit 7fa39c08f2
17 changed files with 174 additions and 33 deletions

View File

@ -435,7 +435,6 @@ enum GUIMSG
GUI_UPDATE_DISASSEMBLY_VIEW, // param1=unused, param2=unused
GUI_UPDATE_BREAKPOINTS_VIEW, // param1=unused, param2=unused
GUI_UPDATE_WINDOW_TITLE, // param1=(const char*)file, param2=unused
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

View File

@ -2020,6 +2020,12 @@ CMDRESULT cbDebugStackDump(int argc, char* argv[])
dprintf("invalid address \"%s\"!\n", argv[1]);
return STATUS_ERROR;
}
GuiStackDumpAt(addr, GetContextData(UE_CSP));
duint csp=GetContextData(UE_CSP);
duint size=0;
duint base=memfindbaseaddr(fdProcessInfo->hProcess, csp, &size);
if(base && addr>=base && addr<(base+size))
GuiStackDumpAt(addr, csp);
else
dputs("invalid stack address!");
return STATUS_CONTINUE;
}

View File

@ -315,7 +315,7 @@ static bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool
if(!mathfromstring(temp, &value, silent, baseonly, 0, 0))
return false;
adjustpairs(exps, open, close, len+1, sprintf(exp+open, "%X", value));
adjustpairs(exps, open, close, len+1, sprintf(exp+open, "%"fext"X", value));
if(*backup)
strcat(exp, backup);

View File

@ -25,6 +25,8 @@ void HexDump::printDumpAt(int_t parVA)
{
int_t wBase = DbgMemFindBaseAddr(parVA, 0); //get memory base
int_t wSize = DbgMemGetPageSize(wBase); //get page size
if(!wBase || !wSize)
return;
int_t wRVA = parVA - wBase; //calculate rva
int wBytePerRowCount = getBytePerRowCount(); //get the number of bytes per row
int_t wRowCount;
@ -47,6 +49,8 @@ void HexDump::printDumpAt(int_t parVA)
setTableOffset((wRVA + mByteOffset) / wBytePerRowCount); //change the displayed offset
setSingleSelection(wRVA);
reloadData();
}

View File

@ -13,7 +13,6 @@ InfoBox::InfoBox(StdTable *parent) : StdTable(parent)
int height = getHeight();
setMaximumHeight(height);
setMinimumHeight(height);
connect(Bridge::getBridge(), SIGNAL(setInfoLine(int, QString)), this, SLOT(setInfoLineSlot(int, QString)));
}
int InfoBox::getHeight()
@ -21,10 +20,15 @@ int InfoBox::getHeight()
return (getRowHeight() + 1) * 3;
}
void InfoBox::setInfoLineSlot(int line, QString text)
void InfoBox::setInfoLine(int line, QString text)
{
if(line < 0 || line > 2)
return;
setCellContent(line, 0, text);
reloadData();
}
void InfoBox::disasmSelectionChanged(int_t parVA)
{
//setInfoLine(0, QString("%1").arg(parVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
}

View File

@ -4,6 +4,7 @@
#include <QtGui>
#include "StdTable.h"
#include "Bridge.h"
#include "CPUDisassembly.h"
class InfoBox : public StdTable
{
@ -13,7 +14,10 @@ public:
int getHeight();
public slots:
void setInfoLineSlot(int line, QString text);
void disasmSelectionChanged(int_t parVA);
private:
void setInfoLine(int line, QString text);
};
#endif // INFOBOX_H

View File

@ -77,18 +77,6 @@ void Bridge::emitUpdateWindowTitle(QString filename)
emit updateWindowTitle(filename);
}
void Bridge::emitSetInfoLine(int line, QString text)
{
emit setInfoLine(line, text);
}
void Bridge::emitClearInfoBox()
{
emit setInfoLine(0, "");
emit setInfoLine(1, "");
emit setInfoLine(2, "");
}
void Bridge::emitDumpAt(int_t va)
{
emit dumpAt(va);
@ -298,12 +286,6 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
}
break;
case GUI_SET_INFO_LINE:
{
Bridge::getBridge()->emitSetInfoLine((int)(int_t)param1, QString(reinterpret_cast<const char*>(param2)));
}
break;
case GUI_GET_WINDOW_HANDLE:
{
return Bridge::getBridge()->winId;

View File

@ -34,8 +34,6 @@ public:
void emitUpdateRegisters();
void emitUpdateBreakpoints();
void emitUpdateWindowTitle(QString filename);
void emitSetInfoLine(int line, QString text);
void emitClearInfoBox();
void emitDumpAt(int_t va);
void emitScriptAdd(int count, const char** lines);
void emitScriptClear();
@ -77,7 +75,6 @@ signals:
void updateRegisters();
void updateBreakpoints();
void updateWindowTitle(QString filename);
void setInfoLine(int line, QString text);
void dumpAt(int_t va);
void scriptAdd(int count, const char** lines);
void scriptClear();

View File

@ -171,7 +171,8 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, uint_t size, uint_t instIn
len = (len < 1) ? 1 : len ;
wInst.instStr = QString(mDisasmStruct.CompleteInstr);
if(wInst.instStr.at(wInst.instStr.length()-1)==' ')
int instrLen = wInst.instStr.length();
if(instrLen && wInst.instStr.at(instrLen-1)==' ')
wInst.instStr.chop(1);
wInst.dump = QByteArray((char*)mDisasmStruct.EIP, len);
wInst.rva = origInstRVA;

View File

@ -128,6 +128,17 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
mGotoMenu->addAction(mGotoOrigin);
mGotoMenu->addAction(mGotoExpression);
wMenu->addMenu(mGotoMenu);
wMenu->addMenu(mFollowMenu);
//remove previous actions
QList<QAction*> list = mFollowMenu->actions();
for(int i=0; i<list.length(); i++)
mFollowMenu->removeAction(list.at(i));
//add follow actions
mFollowMenu->addAction(new QAction("&Selection", this));
mFollowMenu->actions().last()->setObjectName(QString("DUMP|")+QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
connect(mFollowMenu->actions().last(), SIGNAL(triggered()), this, SLOT(followActionSlot()));
QAction* wAction = wMenu->exec(event->globalPos());
}
@ -192,6 +203,10 @@ void CPUDisassembly::setupRightClickContextMenu()
this->addAction(mGotoExpression);
connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpression()));
//-------------------- Follow in Dump ----------------------------
// Menu
mFollowMenu = new QMenu("&Follow in Dump", this);
//---------------------- Breakpoints -----------------------------
// Menu
mBPMenu = new QMenu("Breakpoint", this);
@ -234,12 +249,16 @@ void CPUDisassembly::setupRightClickContextMenu()
void CPUDisassembly::gotoOrigin()
{
DbgCmdExec("d cip");
if(!DbgIsDebugging())
return;
DbgCmdExec("disasm cip");
}
void CPUDisassembly::toggleInt3BPAction()
{
if(!DbgIsDebugging())
return;
uint_t wVA = rvaToVa(getInitialSelection());
BPXTYPE wBpType = DbgGetBpxTypeAt(wVA);
QString wCmd;
@ -344,6 +363,8 @@ void CPUDisassembly::setHwBpAt(uint_t va, int slot)
void CPUDisassembly::setNewOriginHereActionSlot()
{
if(!DbgIsDebugging())
return;
uint_t wVA = rvaToVa(getInitialSelection());
QString wCmd = "cip=" + QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
DbgCmdExec(wCmd.toUtf8().constData());
@ -351,6 +372,8 @@ void CPUDisassembly::setNewOriginHereActionSlot()
void CPUDisassembly::setLabel()
{
if(!DbgIsDebugging())
return;
uint_t wVA = rvaToVa(getInitialSelection());
LineEditDialog mLineEdit(this);
QString addr_text=QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
@ -372,6 +395,8 @@ void CPUDisassembly::setLabel()
void CPUDisassembly::setComment()
{
if(!DbgIsDebugging())
return;
uint_t wVA = rvaToVa(getInitialSelection());
LineEditDialog mLineEdit(this);
QString addr_text=QString("%1").arg(wVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
@ -393,6 +418,8 @@ void CPUDisassembly::setComment()
void CPUDisassembly::setBookmark()
{
if(!DbgIsDebugging())
return;
uint_t wVA = rvaToVa(getInitialSelection());
bool result;
if(DbgGetBookmarkAt(wVA))
@ -411,6 +438,8 @@ void CPUDisassembly::setBookmark()
void CPUDisassembly::toggleFunction()
{
if(!DbgIsDebugging())
return;
uint_t start = rvaToVa(getSelectionStart());
uint_t end = rvaToVa(getSelectionEnd());
uint_t function_start=0;
@ -456,6 +485,8 @@ void CPUDisassembly::toggleFunction()
void CPUDisassembly::assembleAt()
{
if(!DbgIsDebugging())
return;
int_t wRVA = getInitialSelection();
uint_t wVA = rvaToVa(wRVA);
LineEditDialog mLineEdit(this);
@ -497,10 +528,18 @@ void CPUDisassembly::assembleAt()
void CPUDisassembly::gotoExpression()
{
if(!DbgIsDebugging())
return;
GotoDialog mGoto(this);
if(mGoto.exec()==QDialog::Accepted)
{
QString cmd;
DbgCmdExec(cmd.sprintf("disasm \"%s\"", mGoto.expressionText.toUtf8().constData()).toUtf8().constData());
DbgCmdExec(QString().sprintf("disasm \"%s\"", mGoto.expressionText.toUtf8().constData()).toUtf8().constData());
}
}
void CPUDisassembly::followActionSlot()
{
QAction* action = qobject_cast<QAction*>(sender());
if(action && action->objectName().startsWith("DUMP|"))
DbgCmdExec(QString().sprintf("dump \"%s\"", action->objectName().mid(5).toUtf8().constData()).toUtf8().constData());
}

View File

@ -45,6 +45,7 @@ public slots:
void toggleFunction();
void assembleAt();
void gotoExpression();
void followActionSlot();
private:
@ -53,6 +54,7 @@ private:
// Menus
QMenu* mGotoMenu;
QMenu* mFollowMenu;
QMenu* mBPMenu;
QMenu* mHwSlotSelectMenu;

View File

@ -19,6 +19,7 @@ void CPUDump::setupContextMenu()
mGotoExpression->setShortcut(QKeySequence("ctrl+g"));
this->addAction(mGotoExpression);
connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpressionSlot()));
mGotoMenu->addAction(mGotoExpression);
//Hex menu
mHexMenu = new QMenu("&Hex", this);
@ -146,8 +147,10 @@ QString CPUDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, i
return wStr;
}
void CPUDump::contextMenuEvent(QContextMenuEvent *event)
void CPUDump::contextMenuEvent(QContextMenuEvent* event)
{
if(!DbgIsDebugging())
return;
QMenu* wMenu = new QMenu(this); //create context menu
wMenu->addMenu(mGotoMenu);
wMenu->addMenu(mHexMenu);
@ -161,6 +164,8 @@ void CPUDump::contextMenuEvent(QContextMenuEvent *event)
void CPUDump::gotoExpressionSlot()
{
if(!DbgIsDebugging())
return;
GotoDialog mGoto(this);
mGoto.setWindowTitle("Enter expression to follow in Dump...");
if(mGoto.exec()==QDialog::Accepted)

View File

@ -26,6 +26,30 @@ CPUStack::CPUStack(QWidget *parent) : HexDump(parent)
appendDescriptor(0, "Comments", false, wColDesc);
connect(Bridge::getBridge(), SIGNAL(stackDumpAt(uint_t,uint_t)), this, SLOT(stackDumpAt(uint_t,uint_t)));
setupContextMenu();
}
void CPUStack::setupContextMenu()
{
#ifdef _WIN64
mGotoSp = new QAction("Follow R&SP", this);
mGotoBp = new QAction("Follow R&BP", this);
#else
mGotoSp = new QAction("Follow E&SP", this);
mGotoBp = new QAction("Follow E&BP", this);
#endif //_WIN64
mGotoSp->setShortcutContext(Qt::WidgetShortcut);
mGotoSp->setShortcut(QKeySequence("*"));
this->addAction(mGotoSp);
connect(mGotoSp, SIGNAL(triggered()), this, SLOT(gotoSpSlot()));
connect(mGotoBp, SIGNAL(triggered()), this, SLOT(gotoBpSlot()));
mGotoExpression = new QAction("&Expression", this);
mGotoExpression->setShortcutContext(Qt::WidgetShortcut);
mGotoExpression->setShortcut(QKeySequence("ctrl+g"));
this->addAction(mGotoExpression);
connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpressionSlot()));
}
QString CPUStack::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
@ -94,8 +118,52 @@ QString CPUStack::paintContent(QPainter* painter, int_t rowBase, int rowOffset,
return wStr;
}
void CPUStack::contextMenuEvent(QContextMenuEvent* event)
{
if(!DbgIsDebugging())
return;
QMenu* wMenu = new QMenu(this); //create context menu
wMenu->addAction(mGotoSp);
wMenu->addAction(mGotoBp);
wMenu->addAction(mGotoExpression);
wMenu->exec(event->globalPos());
}
void CPUStack::stackDumpAt(uint_t addr, uint_t csp)
{
mCsp=csp;
printDumpAt(addr);
}
void CPUStack::gotoSpSlot()
{
if(!DbgIsDebugging())
return;
DbgCmdExec("sdump csp");
}
void CPUStack::gotoBpSlot()
{
#ifdef _WIN64
DbgCmdExec("sdump rbp");
#else
DbgCmdExec("sdump ebp");
#endif //_WIN64
}
void CPUStack::gotoExpressionSlot()
{
if(!DbgIsDebugging())
return;
uint_t size=0;
uint_t base=DbgMemFindBaseAddr(mCsp, &size);
GotoDialog mGoto(this);
mGoto.validRangeStart=base;
mGoto.validRangeEnd=base+size;
mGoto.setWindowTitle("Enter expression to follow in Stack...");
if(mGoto.exec()==QDialog::Accepted)
{
QString cmd;
DbgCmdExec(cmd.sprintf("sdump \"%s\"", mGoto.expressionText.toUtf8().constData()).toUtf8().constData());
}
}

View File

@ -4,9 +4,11 @@
#include <QtGui>
#include <QtDebug>
#include <QAction>
#include <QMenu>
#include "NewTypes.h"
#include "HexDump.h"
#include "Bridge.h"
#include "GotoDialog.h"
class CPUStack : public HexDump
{
@ -14,12 +16,22 @@ class CPUStack : public HexDump
public:
explicit CPUStack(QWidget *parent = 0);
QString paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h);
void contextMenuEvent(QContextMenuEvent* event);
void setupContextMenu();
public slots:
void stackDumpAt(uint_t addr, uint_t csp);
void gotoSpSlot();
void gotoBpSlot();
void gotoExpressionSlot();
private:
uint_t mCsp;
QAction* mGotoSp;
QAction* mGotoBp;
QAction* mGotoExpression;
};
#endif // CPUSTACK_H

View File

@ -15,6 +15,8 @@ CPUWidget::CPUWidget(QWidget *parent) :QWidget(parent), ui(new Ui::CPUWidget)
ui->mTopLeftLowerFrame->setMinimumHeight(height+2);
ui->mTopLeftLowerFrame->setMaximumHeight(height+2);
connect(mDisas, SIGNAL(selectionChanged(int_t)), mInfo, SLOT(disasmSelectionChanged(int_t)));
mGeneralRegs = new RegistersView(0);
//TODO: add more tabs

View File

@ -17,6 +17,8 @@ GotoDialog::GotoDialog(QWidget *parent) :
ui->labelError->setText("<font color='red'><b>Invalid expression...</b></color>");
ui->buttonOk->setEnabled(false);
ui->editExpression->setFocus();
validRangeStart=0;
validRangeEnd=0;
}
GotoDialog::~GotoDialog()
@ -40,13 +42,19 @@ void GotoDialog::on_editExpression_textChanged(const QString &arg1)
}
else
{
duint addr=DbgValFromString(arg1.toUtf8().constData());
uint_t addr=DbgValFromString(arg1.toUtf8().constData());
if(!DbgMemIsValidReadPtr(addr))
{
ui->labelError->setText("<font color='red'><b>Invalid memory address...</b></color>");
ui->buttonOk->setEnabled(false);
expressionText.clear();
}
else if(!IsValidMemoryRange(addr))
{
ui->labelError->setText("<font color='red'><b>Memory out of range...</b></color>");
ui->buttonOk->setEnabled(false);
expressionText.clear();
}
else
{
QString addrText;
@ -69,3 +77,8 @@ void GotoDialog::on_editExpression_textChanged(const QString &arg1)
}
}
}
bool GotoDialog::IsValidMemoryRange(uint_t addr)
{
return ((validRangeStart || validRangeEnd) && addr >= validRangeStart && addr < validRangeEnd);
}

View File

@ -17,12 +17,15 @@ public:
explicit GotoDialog(QWidget *parent = 0);
~GotoDialog();
QString expressionText;
uint_t validRangeStart;
uint_t validRangeEnd;
private slots:
void on_editExpression_textChanged(const QString &arg1);
private:
Ui::GotoDialog *ui;
bool IsValidMemoryRange(uint_t addr);
};
#endif // GOTODIALOG_H