1
0
Fork 0

GUI: 'Previous (-)' and 'Next (+)' commands have been added to the context menu

This commit is contained in:
mr.exodia 2014-04-08 00:04:21 +02:00
parent cbd8a0fc6f
commit b4ffffdbe9
4 changed files with 185 additions and 23 deletions

View File

@ -7,6 +7,8 @@ Disassembly::Disassembly(QWidget *parent) : AbstractTableView(parent)
mInstBuffer.clear();
historyClear();
SelectionData_t data;
memset(&data, 0, sizeof(SelectionData_t));
mSelection = data;
@ -30,7 +32,7 @@ Disassembly::Disassembly(QWidget *parent) : AbstractTableView(parent)
setShowHeader(false); //hide header
connect(Bridge::getBridge(), SIGNAL(disassembleAt(int_t, int_t)), this, SLOT(disassambleAt(int_t, int_t)));
connect(Bridge::getBridge(), SIGNAL(disassembleAt(int_t, int_t)), this, SLOT(disassembleAt(int_t, int_t)));
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE)));
connect(Bridge::getBridge(), SIGNAL(repaintGui()), this, SLOT(reloadData()));
}
@ -1019,7 +1021,7 @@ uint_t Disassembly::rvaToVa(int_t rva)
return mBase + rva;
}
void Disassembly::disassambleAt(int_t parVA, int_t parCIP)
void Disassembly::disassembleAt(int_t parVA, int_t parCIP, bool history, int_t newTableOffset)
{
int_t wBase = DbgMemFindBaseAddr(parVA, 0);
int_t wSize = DbgMemGetPageSize(wBase);
@ -1028,6 +1030,34 @@ void Disassembly::disassambleAt(int_t parVA, int_t parCIP)
int_t wRVA = parVA - wBase;
int_t wCipRva = parCIP - wBase;
HistoryData_t newHistory;
//VA history
if(history)
{
//truncate everything right from the current VA
if(mVaHistory.size() && mCurrentVa<mVaHistory.size()-1) //mCurrentVa is not the last
mVaHistory.erase(mVaHistory.begin()+mCurrentVa+1, mVaHistory.end());
//NOTE: mCurrentVa always points to the last entry of the list
//add the currently selected address to the history
int_t selectionVA=rvaToVa(getInitialSelection()); //currently selected VA
int_t selectionTableOffset=getTableOffset();
if(selectionVA && mVaHistory.size() && mVaHistory.last().va!=selectionVA) //do not have 2x the same va in a row
{
if(mVaHistory.size() >= 1024) //max 1024 in the history
{
mCurrentVa--;
mVaHistory.erase(mVaHistory.begin()); //remove the oldest element
}
mCurrentVa++;
newHistory.va=selectionVA;
newHistory.tableOffset=selectionTableOffset;
mVaHistory.push_back(newHistory);
}
}
// Set base and size (Useful when memory page changed)
mBase = wBase;
mSize = wSize;
@ -1036,49 +1066,93 @@ void Disassembly::disassambleAt(int_t parVA, int_t parCIP)
setSingleSelection(wRVA); // Selects disassembled instruction
//set CIP rva
mCipRva = wCipRva;
// Update table offset depending on the location of the instruction to disassamble
if(mInstBuffer.size() > 0 && wRVA >= (int_t)mInstBuffer.first().rva && wRVA < (int_t)mInstBuffer.last().rva)
if(newTableOffset==-1) //nothing specified
{
int wI;
bool wIsAligned = false;
// Check if the new RVA is aligned on an instruction from the cache (buffer)
for(wI = 0; wI < mInstBuffer.size(); wI++)
// Update table offset depending on the location of the instruction to disassemble
if(mInstBuffer.size() > 0 && wRVA >= (int_t)mInstBuffer.first().rva && wRVA < (int_t)mInstBuffer.last().rva)
{
if(mInstBuffer.at(wI).rva == wRVA)
int wI;
bool wIsAligned = false;
// Check if the new RVA is aligned on an instruction from the cache (buffer)
for(wI = 0; wI < mInstBuffer.size(); wI++)
{
wIsAligned = true;
break;
if(mInstBuffer.at(wI).rva == wRVA)
{
wIsAligned = true;
break;
}
}
if(wIsAligned == true)
{
repaint();
}
else
{
setTableOffset(wRVA);
}
}
if(wIsAligned == true)
else if(mInstBuffer.size() > 0 && wRVA == (int_t)mInstBuffer.last().rva)
{
repaint();
setTableOffset(mInstBuffer.first().rva + mInstBuffer.first().lentgh);
}
else
{
setTableOffset(wRVA);
}
if(history)
{
//new disassembled address
newHistory.va=parVA;
newHistory.tableOffset=getTableOffset();
if(mVaHistory.size())
{
if(mVaHistory.last().va!=parVA) //not 2x the same va in history
{
if(mVaHistory.size() >= 1024) //max 1024 in the history
{
mCurrentVa--;
mVaHistory.erase(mVaHistory.begin()); //remove the oldest element
}
mCurrentVa++;
mVaHistory.push_back(newHistory); //add a va to the history
}
}
else //the list is empty
mVaHistory.push_back(newHistory);
}
}
else if(mInstBuffer.size() > 0 && wRVA == (int_t)mInstBuffer.last().rva)
else //specified new table offset
setTableOffset(newTableOffset);
/*
//print history
if(history)
{
setTableOffset(mInstBuffer.first().rva + mInstBuffer.first().lentgh);
}
else
{
setTableOffset(wRVA);
QString strList = "";
for(int i=0; i<mVaHistory.size(); i++)
strList += QString().sprintf("[%d]:%p,%p\n", i, mVaHistory.at(i).va, mVaHistory.at(i).tableOffset);
MessageBoxA(GuiGetWindowHandle(), strList.toUtf8().constData(), QString().sprintf("mCurrentVa=%d", mCurrentVa).toUtf8().constData(), MB_ICONINFORMATION);
}
*/
reloadData();
}
void Disassembly::disassembleAt(int_t parVA, int_t parCIP)
{
disassembleAt(parVA, parCIP, true, -1);
}
void Disassembly::disassembleClear()
{
//TODO: fix this (also try restarting)
historyClear();
mBase = 0;
mSize = 0;
setRowCount(0);
@ -1104,3 +1178,40 @@ int_t Disassembly::getSize()
return mSize;
}
void Disassembly::historyClear()
{
mVaHistory.clear(); //clear history for new targets
mCurrentVa = 0;
}
void Disassembly::historyPrevious()
{
if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry
return;
mCurrentVa--;
disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
}
void Disassembly::historyNext()
{
int size = mVaHistory.size();
if(!size || mCurrentVa >= mVaHistory.size()-1) //we are at the newest history entry
return;
mCurrentVa++;
disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
}
bool Disassembly::historyHasPrevious()
{
if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry
return false;
return true;
}
bool Disassembly::historyHasNext()
{
int size = mVaHistory.size();
if(!size || mCurrentVa >= mVaHistory.size()-1) //we are at the newest history entry
return false;
return true;
}

View File

@ -77,11 +77,21 @@ public:
int_t getBase();
int_t getSize();
// history management
void historyClear();
void historyPrevious();
void historyNext();
bool historyHasPrevious();
bool historyHasNext();
//disassemble
void disassembleAt(int_t parVA, int_t parCIP, bool history, int_t newTableOffset);
signals:
void selectionChanged(int_t parVA);
public slots:
void disassambleAt(int_t parVA, int_t parCIP);
void disassembleAt(int_t parVA, int_t parCIP);
void debugStateChangedSlot(DBGSTATE state);
private:
@ -109,6 +119,15 @@ private:
int_t mCipRva;
QList<Instruction_t> mInstBuffer;
typedef struct _HistoryData_t
{
int_t va;
int_t tableOffset;
} HistoryData_t;
QList<HistoryData_t> mVaHistory;
int mCurrentVa;
};
#endif // DISASSEMBLY_H

View File

@ -126,6 +126,10 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
// Goto Menu
mGotoMenu->addAction(mGotoOrigin);
if(historyHasPrevious())
mGotoMenu->addAction(mGotoPrevious);
if(historyHasNext())
mGotoMenu->addAction(mGotoNext);
mGotoMenu->addAction(mGotoExpression);
wMenu->addMenu(mGotoMenu);
wMenu->addMenu(mFollowMenu);
@ -196,6 +200,20 @@ void CPUDisassembly::setupRightClickContextMenu()
this->addAction(mGotoOrigin);
connect(mGotoOrigin, SIGNAL(triggered()), this, SLOT(gotoOrigin()));
// Previous action
mGotoPrevious = new QAction("Previous", this);
mGotoPrevious->setShortcutContext(Qt::WidgetShortcut);
mGotoPrevious->setShortcut(QKeySequence("-"));
this->addAction(mGotoPrevious);
connect(mGotoPrevious, SIGNAL(triggered()), this, SLOT(gotoPrevious()));
// Next action
mGotoNext = new QAction("Next", this);
mGotoNext->setShortcutContext(Qt::WidgetShortcut);
mGotoNext->setShortcut(QKeySequence("+"));
this->addAction(mGotoNext);
connect(mGotoNext, SIGNAL(triggered()), this, SLOT(gotoNext()));
// Address action
mGotoExpression = new QAction("Expression", this);
mGotoExpression->setShortcutContext(Qt::WidgetShortcut);
@ -543,3 +561,13 @@ void CPUDisassembly::followActionSlot()
if(action && action->objectName().startsWith("DUMP|"))
DbgCmdExec(QString().sprintf("dump \"%s\"", action->objectName().mid(5).toUtf8().constData()).toUtf8().constData());
}
void CPUDisassembly::gotoPrevious()
{
historyPrevious();
}
void CPUDisassembly::gotoNext()
{
historyNext();
}

View File

@ -46,6 +46,8 @@ public slots:
void assembleAt();
void gotoExpression();
void followActionSlot();
void gotoPrevious();
void gotoNext();
private:
@ -73,6 +75,8 @@ private:
QAction* msetHwBPOnSlot2Action;
QAction* msetHwBPOnSlot3Action;
QAction* mGotoExpression;
QAction* mGotoPrevious;
QAction* mGotoNext;
};
#endif // CPUDISASSEMBLY_H