From 87fc0de91cbd8eb72606f90f639cb20396deb9b5 Mon Sep 17 00:00:00 2001 From: Herzeh Date: Mon, 7 Dec 2015 17:13:43 +0100 Subject: [PATCH] Added searching for references for Command/Constant/Strings/Calls either in Current Region/Current Module/All Modules --- src/bridge/bridgemain.cpp | 4 + src/bridge/bridgemain.h | 2 + src/dbg/instruction.cpp | 37 +++- src/dbg/reference.cpp | 210 ++++++++++++++++++----- src/dbg/reference.h | 12 +- src/gui/Src/BasicView/ReferenceView.cpp | 65 +++++-- src/gui/Src/BasicView/ReferenceView.h | 8 +- src/gui/Src/BasicView/SearchListView.cpp | 2 + src/gui/Src/Bridge/Bridge.cpp | 4 + src/gui/Src/Bridge/Bridge.h | 1 + src/gui/Src/Gui/CPUDisassembly.cpp | 98 +++++++++-- src/gui/Src/Gui/CPUDisassembly.h | 16 ++ 12 files changed, 376 insertions(+), 83 deletions(-) diff --git a/src/bridge/bridgemain.cpp b/src/bridge/bridgemain.cpp index b1d07523..93696359 100644 --- a/src/bridge/bridgemain.cpp +++ b/src/bridge/bridgemain.cpp @@ -1038,6 +1038,10 @@ BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress) _gui_sendmessage(GUI_REF_SETPROGRESS, (void*)(duint)progress, 0); } +BRIDGE_IMPEXP void GuiReferenceSetCurrentTaskProgress(int progress, const char* taskTitle) +{ + _gui_sendmessage(GUI_REF_SETCURRENTTASKPROGRESS, (void*)(duint)progress, (void*)taskTitle); +} BRIDGE_IMPEXP void GuiReferenceSetSearchStartCol(int col) { diff --git a/src/bridge/bridgemain.h b/src/bridge/bridgemain.h index 1d2bba78..c97345ce 100644 --- a/src/bridge/bridgemain.h +++ b/src/bridge/bridgemain.h @@ -746,6 +746,7 @@ typedef enum 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_SETCURRENTTASKPROGRESS, // param1=int progress, param2=const char* taskTitle GUI_REF_SETSEARCHSTARTCOL, // param1=int col param2=unused GUI_STACK_DUMP_AT, // param1=duint addr, param2=duint csp GUI_UPDATE_DUMP_VIEW, // param1=unused, param2=unused @@ -847,6 +848,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 GuiReferenceSetCurrentTaskProgress(int progress, const char* taskTitle); BRIDGE_IMPEXP void GuiReferenceSetSearchStartCol(int col); BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp); BRIDGE_IMPEXP void GuiUpdateDumpView(); diff --git a/src/dbg/instruction.cpp b/src/dbg/instruction.cpp index a1899e80..cf145ec9 100644 --- a/src/dbg/instruction.cpp +++ b/src/dbg/instruction.cpp @@ -885,6 +885,8 @@ CMDRESULT cbInstrRefFind(int argc, char* argv[]) newCommand += std::string(",") + argv[2]; if (argc > 3) newCommand += std::string(",") + argv[3]; + if (argc > 4) + newCommand += std::string(",") + argv[4]; return cmddirectexec(newCommand.c_str()); } @@ -913,7 +915,13 @@ CMDRESULT cbInstrRefFindRange(int argc, char* argv[]) sprintf_s(title, "Constant: %" fext "X", range.start); else sprintf_s(title, "Range: %" fext "X-%" fext "X", range.start, range.end); - int found = RefFind(addr, size, cbRefFind, &range, false, title); + + duint refFindType = CURRENT_REGION; + if (argc >= 6 && valfromstring(argv[5], &refFindType, true)) + if (refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES) + refFindType = CURRENT_REGION; + + int found = RefFind(addr, size, cbRefFind, &range, false, title, (REFFINDTYPE)refFindType); dprintf("%u reference(s) in %ums\n", found, GetTickCount() - ticks); varset("$result", found, false); return STATUS_CONTINUE; @@ -970,14 +978,22 @@ bool cbRefStr(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refi CMDRESULT cbInstrRefStr(int argc, char* argv[]) { duint addr; + duint size = 0; + + // If not specified, assume CURRENT_REGION by default if (argc < 2 || !valfromstring(argv[1], &addr, true)) addr = GetContextDataEx(hActiveThread, UE_CIP); - duint size = 0; if (argc >= 3) if (!valfromstring(argv[2], &size, true)) size = 0; + + duint refFindType = CURRENT_REGION; + if (argc >= 4 && valfromstring(argv[3], &refFindType, true)) + if (refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES) + refFindType = CURRENT_REGION; + duint ticks = GetTickCount(); - int found = RefFind(addr, size, cbRefStr, 0, false, "Strings"); + int found = RefFind(addr, size, cbRefStr, 0, false, "Strings", (REFFINDTYPE)refFindType); dprintf("%u string(s) in %ums\n", found, GetTickCount() - ticks); varset("$result", found, false); return STATUS_CONTINUE; @@ -1399,8 +1415,14 @@ CMDRESULT cbInstrModCallFind(int argc, char* argv[]) if (argc >= 3) if (!valfromstring(argv[2], &size, true)) size = 0; + + duint refFindType = CURRENT_REGION; + if (argc >= 4 && valfromstring(argv[3], &refFindType, true)) + if (refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES) + refFindType = CURRENT_REGION; + duint ticks = GetTickCount(); - int found = RefFind(addr, size, cbModCallFind, 0, false, "Calls"); + int found = RefFind(addr, size, cbModCallFind, 0, false, "Calls", (REFFINDTYPE)refFindType); dprintf("%u call(s) in %ums\n", found, GetTickCount() - ticks); varset("$result", found, false); return STATUS_CONTINUE; @@ -1656,6 +1678,11 @@ CMDRESULT cbInstrFindAsm(int argc, char* argv[]) if (!valfromstring(argv[3], &size)) size = 0; + duint refFindType = CURRENT_REGION; + if (argc >= 5 && valfromstring(argv[4], &refFindType, true)) + if (refFindType != CURRENT_REGION && refFindType != CURRENT_MODULE && refFindType != ALL_MODULES) + refFindType = CURRENT_REGION; + unsigned char dest[16]; int asmsize = 0; char error[MAX_ERROR_SIZE] = ""; @@ -1671,7 +1698,7 @@ CMDRESULT cbInstrFindAsm(int argc, char* argv[]) duint ticks = GetTickCount(); char title[256] = ""; sprintf_s(title, "Command: \"%s\"", basicinfo.instruction); - int found = RefFind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, title); + int found = RefFind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, title, (REFFINDTYPE)refFindType); dprintf("%u result(s) in %ums\n", found, GetTickCount() - ticks); varset("$result", found, false); return STATUS_CONTINUE; diff --git a/src/dbg/reference.cpp b/src/dbg/reference.cpp index f586ca6b..671ca632 100644 --- a/src/dbg/reference.cpp +++ b/src/dbg/reference.cpp @@ -9,34 +9,182 @@ #include "console.h" #include "module.h" -int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name) +int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name, REFFINDTYPE type) { - duint regionSize = 0; - duint regionBase = MemFindBaseAddr(Address, ®ionSize, true); + char fullName[deflen]; + char moduleName[MAX_MODULE_SIZE]; + int refFindInRangeRet; + duint scanStart, scanSize; + REFINFO refInfo; - // If the memory page wasn't found, fail - if(!regionBase || !regionSize) + // Search in current Region + if (type == CURRENT_REGION) { - if(!Silent) - dprintf("Invalid memory page 0x%p\n", Address); + duint regionSize = 0; + duint regionBase = MemFindBaseAddr(Address, ®ionSize, true); - return 0; + // If the memory page wasn't found, fail + if (!regionBase || !regionSize) + { + if (!Silent) + dprintf("Invalid memory page 0x%p\n", Address); + + return 0; + } + + // Assume the entire range is used + scanStart = regionBase; + scanSize = regionSize; + + // Otherwise use custom boundaries if size was supplied + if(Size) + { + duint maxsize = Size - (Address - regionBase); + + // Make sure the size fits in one page + scanStart = Address; + scanSize = min(Size, maxsize); + } + + // Determine the full module name + if (ModNameFromAddr(scanStart, moduleName, true)) + sprintf_s(fullName, "%s (Region %s)", Name, moduleName); + else + sprintf_s(fullName, "%s (Region %p)", Name, scanStart); + + // Initialize disassembler + Capstone cp; + + // Allow an "initialization" notice + refInfo.refcount = 0; + refInfo.userinfo = UserData; + refInfo.name = fullName; + + + refFindInRangeRet = RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, true, [](int percent) + { + GuiReferenceSetCurrentTaskProgress(percent, "Region Search"); + GuiReferenceSetProgress(percent); + }); + + GuiReferenceReloadData(); + + if (!refFindInRangeRet) + return refFindInRangeRet; + + refInfo.refcount += refFindInRangeRet; } - // Assume the entire range is used - duint scanStart = regionBase; - duint scanSize = regionSize; - - // Otherwise use custom boundaries if size was supplied - if(Size) + // Search in current Module + else if (type == CURRENT_MODULE) { - duint maxsize = Size - (Address - regionBase); + MODINFO *modInfo = ModInfoFromAddr(Address); - // Make sure the size fits in one page - scanStart = Address; - scanSize = min(Size, maxsize); + if (!modInfo) + { + if (!Silent) + dprintf("Couldn't locate module for 0x%p\n", Address); + + return 0; + } + + duint modBase = modInfo->base; + duint modSize = modInfo->size; + + scanStart = modBase; + scanSize = modSize; + + // Determine the full module name + if (ModNameFromAddr(scanStart, moduleName, true)) + sprintf_s(fullName, "%s (%s)", Name, moduleName); + else + sprintf_s(fullName, "%s (%p)", Name, scanStart); + + // Initialize disassembler + Capstone cp; + + // Allow an "initialization" notice + refInfo.refcount = 0; + refInfo.userinfo = UserData; + refInfo.name = fullName; + + refFindInRangeRet = RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, true, [](int percent) + { + GuiReferenceSetCurrentTaskProgress(percent, "Module Search"); + GuiReferenceSetProgress(percent); + }); + + + if (!refFindInRangeRet) + return refFindInRangeRet; + + GuiReferenceReloadData(); } + // Search in all Modules + else if (type == ALL_MODULES) + { + bool initCallBack = true; + std::vector modList; + ModGetList(modList); + + if (!modList.size()) + { + if (!Silent) + dprintf("Couldn't get module list"); + + return 0; + } + + // Initialize disassembler + Capstone cp; + + // Determine the full module + sprintf_s(fullName, "All Modules (%s)", Name); + + // Allow an "initialization" notice + refInfo.refcount = 0; + refInfo.userinfo = UserData; + refInfo.name = fullName; + + for (duint i = 0; i < modList.size(); i++) + { + scanStart = modList[i].base; + scanSize = modList[i].size; + + if (i != 0) + initCallBack = false; + + refFindInRangeRet = RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, initCallBack, [&i, &modList](int percent) + { + float fPercent = (float)percent / 100.f; + float fTotalPercent = ((float)i + fPercent) / (float)modList.size(); + + int totalPercent = (int)floor(fTotalPercent * 100.f); + + char tst[256]; + strcpy_s(tst, modList[i].name); + + GuiReferenceSetCurrentTaskProgress(percent, modList[i].name); + GuiReferenceSetProgress(totalPercent); + }); + + + if (!refFindInRangeRet) + return refFindInRangeRet; + + GuiReferenceReloadData(); + } + } + + GuiReferenceSetProgress(100); + GuiReferenceReloadData(); + return refInfo.refcount; +} + + +int RefFindInRange(duint scanStart, duint scanSize, CBREF Callback, void* UserData, bool Silent, REFINFO &refInfo, Capstone &cp, bool initCallBack, CBPROGRESS cbUpdateProgress) +{ // Allocate and read a buffer from the remote process Memory data(scanSize, "reffind:data"); @@ -48,25 +196,8 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile return 0; } - // Determine the full module name - char fullName[deflen]; - char moduleName[MAX_MODULE_SIZE]; - - if(ModNameFromAddr(scanStart, moduleName, true)) - sprintf_s(fullName, "%s (%s)", Name, moduleName); - else - sprintf_s(fullName, "%s (%p)", Name, scanStart); - - // Initialize disassembler - Capstone cp; - - // Allow an "initialization" notice - REFINFO refInfo; - refInfo.refcount = 0; - refInfo.userinfo = UserData; - refInfo.name = fullName; - - Callback(0, 0, &refInfo); + if(initCallBack) + Callback(0, 0, &refInfo); //concurrency::parallel_for(duint (0), scanSize, [&](duint i) for(duint i = 0; i < scanSize;) @@ -78,7 +209,7 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile // Integer = floor(percent) int percent = (int)floor(((float)i / (float)scanSize) * 100.0f); - GuiReferenceSetProgress(percent); + cbUpdateProgress(percent); } // Disassemble the instruction @@ -104,7 +235,6 @@ int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Sile i += disasmLen; } - GuiReferenceSetProgress(100); - GuiReferenceReloadData(); + cbUpdateProgress(100); return refInfo.refcount; } diff --git a/src/dbg/reference.h b/src/dbg/reference.h index 58a3bd2a..12187415 100644 --- a/src/dbg/reference.h +++ b/src/dbg/reference.h @@ -2,6 +2,7 @@ #include "_global.h" #include "disasm_fast.h" +#include struct REFINFO { @@ -10,7 +11,16 @@ struct REFINFO const char* name; }; +typedef enum +{ + CURRENT_REGION, + CURRENT_MODULE, + ALL_MODULES +} REFFINDTYPE; + // Reference callback typedef typedef bool (*CBREF)(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo); +typedef std::function CBPROGRESS; -int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name); \ No newline at end of file +int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name, REFFINDTYPE type); +int RefFindInRange(duint scanStart, duint scanSize, CBREF Callback, void* UserData, bool Silent, REFINFO &refInfo, Capstone &cp, bool initCallBack, CBPROGRESS cbUpdateProgress); diff --git a/src/gui/Src/BasicView/ReferenceView.cpp b/src/gui/Src/BasicView/ReferenceView.cpp index 44ea53f7..e88cd494 100644 --- a/src/gui/Src/BasicView/ReferenceView.cpp +++ b/src/gui/Src/BasicView/ReferenceView.cpp @@ -10,25 +10,41 @@ ReferenceView::ReferenceView() mSearchStartCol = 1; mFollowDumpDefault = false; - QHBoxLayout* layout = new QHBoxLayout(); + QHBoxLayout* layoutTotalProgress = new QHBoxLayout(); + QHBoxLayout* layoutCurrentTaskProgress = new QHBoxLayout(); - // Create search progress bar - mSearchProgress = new QProgressBar(); - mSearchProgress->setRange(0, 100); - mSearchProgress->setTextVisible(false); - mSearchProgress->setMaximumHeight(15); - layout->addWidget(mSearchProgress); + // Create current task search progress bar + mSearchCurrentTaskProgress = new QProgressBar(); + mSearchCurrentTaskProgress->setRange(0, 100); + mSearchCurrentTaskProgress->setTextVisible(true); + mSearchCurrentTaskProgress->setMaximumHeight(15); + layoutCurrentTaskProgress->addWidget(mSearchCurrentTaskProgress); + + // Create total search progress bar + mSearchTotalProgress = new QProgressBar(); + mSearchTotalProgress->setRange(0, 100); + mSearchTotalProgress->setTextVisible(true); + mSearchTotalProgress->setMaximumHeight(15); + layoutTotalProgress->addWidget(mSearchTotalProgress); // Label for the number of references - mCountLabel = new QLabel("tst"); - mCountLabel->setAlignment(Qt::AlignCenter); - mCountLabel->setMaximumHeight(16); - mCountLabel->setMinimumWidth(40); - mCountLabel->setContentsMargins(2, 0, 5, 0); - layout->addWidget(mCountLabel); + mCountTotalLabel = new QLabel("tst"); + mCountTotalLabel->setAlignment(Qt::AlignCenter); + mCountTotalLabel->setMaximumHeight(16); + mCountTotalLabel->setMinimumWidth(40); + mCountTotalLabel->setContentsMargins(2, 0, 5, 0); + layoutTotalProgress->addWidget(mCountTotalLabel); + + mCountCurrentTaskLabel = new QLabel(""); + mCountCurrentTaskLabel->setAlignment(Qt::AlignCenter); + mCountCurrentTaskLabel->setMaximumHeight(16); + mCountCurrentTaskLabel->setMinimumWidth(40); + mCountCurrentTaskLabel->setContentsMargins(2, 0, 5, 0); + layoutCurrentTaskProgress->addWidget(mCountCurrentTaskLabel); // Add the progress bar and label to the main layout - mMainLayout->addLayout(layout); + mMainLayout->addLayout(layoutCurrentTaskProgress); + mMainLayout->addLayout(layoutTotalProgress); // Setup signals connect(Bridge::getBridge(), SIGNAL(referenceAddColumnAt(int, QString)), this, SLOT(addColumnAt(int, QString))); @@ -36,7 +52,8 @@ ReferenceView::ReferenceView() connect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString))); connect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData())); connect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool))); - connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int))); + connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int))); + connect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int,QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int,QString))); connect(Bridge::getBridge(), SIGNAL(referenceSetSearchStartCol(int)), this, SLOT(setSearchStartCol(int))); connect(this, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(referenceContextMenu(QMenu*))); connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followGenericAddress())); @@ -80,7 +97,7 @@ void ReferenceView::disconnectBridge() disconnect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString))); disconnect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData())); disconnect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool))); - disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int))); + disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchTotalProgress, SLOT(setValue(int))); disconnect(Bridge::getBridge(), SIGNAL(referenceSetSearchStartCol(int)), this, SLOT(setSearchStartCol(int))); } @@ -90,6 +107,20 @@ void ReferenceView::refreshShortcutsSlot() mToggleBookmark->setShortcut(ConfigShortcut("ActionToggleBookmark")); } +void ReferenceView::referenceSetProgressSlot(int progress) +{ + mSearchTotalProgress->setValue(progress); + mSearchTotalProgress->setAlignment(Qt::AlignCenter); + mSearchTotalProgress->setFormat("Total Progress " + QString::number(progress) + "%"); +} + +void ReferenceView::referenceSetCurrentTaskProgressSlot(int progress, QString taskTitle) +{ + mSearchCurrentTaskProgress->setValue(progress); + mSearchCurrentTaskProgress->setAlignment(Qt::AlignCenter); + mSearchCurrentTaskProgress->setFormat(taskTitle + " " + QString::number(progress) + "%"); +} + void ReferenceView::addColumnAt(int width, QString title) { int charwidth = mList->getCharWidth(); @@ -109,7 +140,7 @@ void ReferenceView::addColumnAt(int width, QString title) void ReferenceView::setRowCount(dsint count) { - emit mCountLabel->setText(QString("%1").arg(count)); + emit mCountTotalLabel->setText(QString("%1").arg(count)); mSearchBox->setText(""); mList->setRowCount(count); } diff --git a/src/gui/Src/BasicView/ReferenceView.h b/src/gui/Src/BasicView/ReferenceView.h index 07633283..7d83e065 100644 --- a/src/gui/Src/BasicView/ReferenceView.h +++ b/src/gui/Src/BasicView/ReferenceView.h @@ -29,19 +29,23 @@ private slots: void toggleBreakpoint(); void toggleBookmark(); void refreshShortcutsSlot(); + void referenceSetProgressSlot(int progress); + void referenceSetCurrentTaskProgressSlot(int progress, QString taskTitle); signals: void showCpu(); private: - QProgressBar* mSearchProgress; + QProgressBar* mSearchTotalProgress; + QProgressBar* mSearchCurrentTaskProgress; QAction* mFollowAddress; QAction* mFollowDumpAddress; QAction* mFollowApiAddress; QAction* mToggleBreakpoint; QAction* mToggleBookmark; bool mFollowDumpDefault; - QLabel* mCountLabel; + QLabel* mCountTotalLabel; + QLabel* mCountCurrentTaskLabel; dsint apiAddressFromString(const QString & s); }; diff --git a/src/gui/Src/BasicView/SearchListView.cpp b/src/gui/Src/BasicView/SearchListView.cpp index 1da4730f..f6b4c7d7 100644 --- a/src/gui/Src/BasicView/SearchListView.cpp +++ b/src/gui/Src/BasicView/SearchListView.cpp @@ -194,8 +194,10 @@ bool SearchListView::eventFilter(QObject *obj, QEvent *event) { QMouseEvent *mouseEvent = static_cast(event); QLineEdit *lineEdit = static_cast(obj); + mCursorPosition = lineEdit->cursorPositionAt(mouseEvent->pos()); lineEdit->setFocusPolicy(Qt::NoFocus); + return QObject::eventFilter(obj, event); } // KeyPress in List diff --git a/src/gui/Src/Bridge/Bridge.cpp b/src/gui/Src/Bridge/Bridge.cpp index 533e5a5f..c44417bb 100644 --- a/src/gui/Src/Bridge/Bridge.cpp +++ b/src/gui/Src/Bridge/Bridge.cpp @@ -228,6 +228,10 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2) emit referenceSetProgress((int)param1); break; + case GUI_REF_SETCURRENTTASKPROGRESS: + emit referenceSetCurrentTaskProgress((int)param1, QString((const char*)param2)); + break; + case GUI_REF_SETSEARCHSTARTCOL: emit referenceSetSearchStartCol((int)param1); break; diff --git a/src/gui/Src/Bridge/Bridge.h b/src/gui/Src/Bridge/Bridge.h index 38b369d6..8d8dc371 100644 --- a/src/gui/Src/Bridge/Bridge.h +++ b/src/gui/Src/Bridge/Bridge.h @@ -70,6 +70,7 @@ signals: void referenceReloadData(); void referenceSetSingleSelection(int index, bool scroll); void referenceSetProgress(int progress); + void referenceSetCurrentTaskProgress(int progress, QString taskTitle); void referenceSetSearchStartCol(int col); void referenceInitialize(QString name); void stackDumpAt(duint va, duint csp); diff --git a/src/gui/Src/Gui/CPUDisassembly.cpp b/src/gui/Src/Gui/CPUDisassembly.cpp index 25d83249..19b0cee1 100644 --- a/src/gui/Src/Gui/CPUDisassembly.cpp +++ b/src/gui/Src/Gui/CPUDisassembly.cpp @@ -358,11 +358,45 @@ void CPUDisassembly::setupRightClickContextMenu() mMenuBuilder->addSeparator(); MenuBuilder* searchMenu = new MenuBuilder(this); - searchMenu->addAction(makeShortcutAction("C&ommand", SLOT(findCommandSlot()), "ActionFind")); - searchMenu->addAction(makeAction("&Constant", SLOT(findConstantSlot()))); - searchMenu->addAction(makeAction("&String references", SLOT(findStringsSlot()))); - searchMenu->addAction(makeAction("&Intermodular calls", SLOT(findCallsSlot()))); - searchMenu->addAction(makeShortcutAction("&Pattern", SLOT(findPatternSlot()), "ActionFindPattern")); + MenuBuilder* mSearchRegionMenu = new MenuBuilder(this); + MenuBuilder* mSearchModuleMenu = new MenuBuilder(this); + MenuBuilder* mSearchAllMenu = new MenuBuilder(this); + + // Search in Current Region menu + mFindCommandRegion = makeShortcutAction("C&ommand", SLOT(findCommandSlot()), "ActionFind"); + mFindConstantRegion = makeAction("&Constant", SLOT(findConstantSlot())); + mFindStringsRegion = makeAction("&String references", SLOT(findStringsSlot())); + mFindCallsRegion = makeAction("&Intermodular calls", SLOT(findCallsSlot())); + mSearchRegionMenu->addAction(mFindCommandRegion); + mSearchRegionMenu->addAction(mFindConstantRegion); + mSearchRegionMenu->addAction(mFindStringsRegion); + mSearchRegionMenu->addAction(mFindCallsRegion); + mSearchRegionMenu->addAction(makeShortcutAction("&Pattern", SLOT(findPatternSlot()), "ActionFindPattern")); + + // Search in Current Module menu + mFindCommandModule = makeShortcutAction("C&ommand", SLOT(findCommandSlot()), "ActionFind"); + mFindConstantModule = makeAction("&Constant", SLOT(findConstantSlot())); + mFindStringsModule = makeAction("&String references", SLOT(findStringsSlot())); + mFindCallsModule = makeAction("&Intermodular calls", SLOT(findCallsSlot())); + mSearchModuleMenu->addAction(mFindCommandModule); + mSearchModuleMenu->addAction(mFindConstantModule); + mSearchModuleMenu->addAction(mFindStringsModule); + mSearchModuleMenu->addAction(mFindCallsModule); + + + // Search in All Modules menu + mFindCommandAll = makeShortcutAction("C&ommand", SLOT(findCommandSlot()), "ActionFind"); + mFindConstantAll = makeAction("&Constant", SLOT(findConstantSlot())); + mFindStringsAll = makeAction("&String references", SLOT(findStringsSlot())); + mFindCallsAll = makeAction("&Intermodular calls", SLOT(findCallsSlot())); + mSearchAllMenu->addAction(mFindCommandAll); + mSearchAllMenu->addAction(mFindConstantAll); + mSearchAllMenu->addAction(mFindStringsAll); + mSearchAllMenu->addAction(mFindCallsAll); + + searchMenu->addMenu(makeMenu("Current Region"), mSearchRegionMenu); + searchMenu->addMenu(makeMenu("Current Module"), mSearchModuleMenu); + searchMenu->addMenu(makeMenu("All Modules"), mSearchAllMenu); mMenuBuilder->addMenu(makeMenu(QIcon(":/icons/images/search-for.png"), "&Search for"), searchMenu); mReferenceSelectedAddressAction = makeShortcutAction("&Selected Address(es)", SLOT(findReferencesSlot()), "ActionFindReferencesToSelectedAddress"); @@ -831,27 +865,52 @@ void CPUDisassembly::findReferencesSlot() void CPUDisassembly::findConstantSlot() { + int refFindType = 0; + if(sender() == mFindConstantRegion) + refFindType = 0; + else if(sender() == mFindConstantModule) + refFindType = 1; + else if(sender() == mFindConstantAll) + refFindType = 2; + WordEditDialog wordEdit(this); wordEdit.setup("Enter Constant", 0, sizeof(dsint)); if(wordEdit.exec() != QDialog::Accepted) //cancel pressed return; QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); QString constText = QString("%1").arg(wordEdit.getVal(), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - DbgCmdExec(QString("findref " + constText + ", " + addrText).toUtf8().constData()); + DbgCmdExec(QString("findref " + constText + ", " + addrText + ", 0, %1").arg(refFindType).toUtf8().constData()); emit displayReferencesWidget(); } void CPUDisassembly::findStringsSlot() { + int refFindType = 0; + if(sender() == mFindStringsRegion) + refFindType = 0; + else if(sender() == mFindStringsModule) + refFindType = 1; + else if(sender() == mFindStringsAll) + refFindType = 2; + QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - DbgCmdExec(QString("strref " + addrText).toUtf8().constData()); + DbgCmdExec(QString("strref " + addrText + ", 0, %1").arg(refFindType).toUtf8().constData()); emit displayReferencesWidget(); } + void CPUDisassembly::findCallsSlot() { + int refFindType = 0; + if(sender() == mFindCallsRegion) + refFindType = 0; + else if(sender() == mFindCallsModule) + refFindType = 1; + else if(sender() == mFindCallsAll) + refFindType = 2; + QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - DbgCmdExec(QString("modcallfind " + addrText).toUtf8().constData()); + DbgCmdExec(QString("modcallfind " + addrText + ", 0, 0").toUtf8().constData()); emit displayReferencesWidget(); } @@ -1121,10 +1180,18 @@ void CPUDisassembly::findCommandSlot() if(!DbgIsDebugging()) return; + int refFindType = 0; + if(sender() == mFindCommandRegion) + refFindType = 0; + else if(sender() == mFindCommandModule) + refFindType = 1; + else if(sender() == mFindCommandAll) + refFindType = 2; + LineEditDialog mLineEdit(this); - mLineEdit.enableCheckBox(true); - mLineEdit.setCheckBoxText("Entire &Block"); - mLineEdit.setCheckBox(ConfigBool("Disassembler", "FindCommandEntireBlock")); + mLineEdit.enableCheckBox(false); +// mLineEdit.setCheckBoxText("Entire &Block"); +// mLineEdit.setCheckBox(ConfigBool("Disassembler", "FindCommandEntireBlock")); mLineEdit.setWindowTitle("Find Command"); if(mLineEdit.exec() != QDialog::Accepted) return; @@ -1147,13 +1214,8 @@ void CPUDisassembly::findCommandSlot() QString addr_text = QString("%1").arg(va, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - if(!mLineEdit.bChecked) - { - dsint size = mMemPage->getSize(); - DbgCmdExec(QString("findasm \"%1\", %2, .%3").arg(mLineEdit.editText).arg(addr_text).arg(size).toUtf8().constData()); - } - else - DbgCmdExec(QString("findasm \"%1\", %2").arg(mLineEdit.editText).arg(addr_text).toUtf8().constData()); + dsint size = mMemPage->getSize(); + DbgCmdExec(QString("findasm \"%1\", %2, .%3, %4").arg(mLineEdit.editText).arg(addr_text).arg(size).arg(refFindType).toUtf8().constData()); emit displayReferencesWidget(); } diff --git a/src/gui/Src/Gui/CPUDisassembly.h b/src/gui/Src/Gui/CPUDisassembly.h index d758b5c4..02da9752 100644 --- a/src/gui/Src/Gui/CPUDisassembly.h +++ b/src/gui/Src/Gui/CPUDisassembly.h @@ -94,6 +94,21 @@ private: // Actions QAction* mReferenceSelectedAddressAction; + QAction* mFindCommandRegion; + QAction* mFindConstantRegion; + QAction* mFindStringsRegion; + QAction* mFindCallsRegion; + + QAction* mFindCommandModule; + QAction* mFindConstantModule; + QAction* mFindStringsModule; + QAction* mFindCallsModule; + + QAction* mFindCommandAll; + QAction* mFindConstantAll; + QAction* mFindStringsAll; + QAction* mFindCallsAll; + // Goto dialog specific GotoDialog* mGoto; @@ -102,6 +117,7 @@ private: CPUWidget *mParentCPUWindow; MenuBuilder* mMenuBuilder; + }; #endif // CPUDISASSEMBLY_H