mirror of
https://github.com/x64dbg/x64dbg.git
synced 2024-11-27 14:50:24 +00:00
Merge branch 'x64dbg:development' into 3051_Switch__to_thread_handles
This commit is contained in:
commit
0853cafadc
@ -28,20 +28,188 @@ class BridgeArchitecture : public Architecture
|
||||
/************************************************************************************
|
||||
Class Members
|
||||
************************************************************************************/
|
||||
static const char* msg2str(GUIMSG msg)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case GUI_UPDATE_REGISTER_VIEW:
|
||||
return "GUI_UPDATE_REGISTER_VIEW";
|
||||
case GUI_UPDATE_DISASSEMBLY_VIEW:
|
||||
return "GUI_UPDATE_DISASSEMBLY_VIEW";
|
||||
case GUI_UPDATE_BREAKPOINTS_VIEW:
|
||||
return "GUI_UPDATE_BREAKPOINTS_VIEW";
|
||||
case GUI_UPDATE_DUMP_VIEW:
|
||||
return "GUI_UPDATE_DUMP_VIEW";
|
||||
case GUI_UPDATE_THREAD_VIEW:
|
||||
return "GUI_UPDATE_THREAD_VIEW";
|
||||
case GUI_UPDATE_MEMORY_VIEW:
|
||||
return "GUI_UPDATE_MEMORY_VIEW";
|
||||
case GUI_UPDATE_SIDEBAR:
|
||||
return "GUI_UPDATE_SIDEBAR";
|
||||
case GUI_REPAINT_TABLE_VIEW:
|
||||
return "GUI_REPAINT_TABLE_VIEW";
|
||||
case GUI_UPDATE_PATCHES:
|
||||
return "GUI_UPDATE_PATCHES";
|
||||
case GUI_UPDATE_CALLSTACK:
|
||||
return "GUI_UPDATE_CALLSTACK";
|
||||
case GUI_UPDATE_SEHCHAIN:
|
||||
return "GUI_UPDATE_SEHCHAIN";
|
||||
case GUI_UPDATE_TIME_WASTED_COUNTER:
|
||||
return "GUI_UPDATE_TIME_WASTED_COUNTER";
|
||||
case GUI_UPDATE_ARGUMENT_VIEW:
|
||||
return "GUI_UPDATE_ARGUMENT_VIEW";
|
||||
case GUI_UPDATE_WATCH_VIEW:
|
||||
return "GUI_UPDATE_WATCH_VIEW";
|
||||
case GUI_UPDATE_GRAPH_VIEW:
|
||||
return "GUI_UPDATE_GRAPH_VIEW";
|
||||
case GUI_UPDATE_TYPE_WIDGET:
|
||||
return "GUI_UPDATE_TYPE_WIDGET";
|
||||
case GUI_UPDATE_TRACE_BROWSER:
|
||||
return "GUI_UPDATE_TRACE_BROWSER";
|
||||
default:
|
||||
return "<unknown message>";
|
||||
}
|
||||
}
|
||||
|
||||
void Bridge::throttleUpdateSlot(GUIMSG msg)
|
||||
{
|
||||
// NOTE: This is running synchronously on the UI thread
|
||||
|
||||
auto lastUpdate = mLastUpdates[msg];
|
||||
auto now = GetTickCount();
|
||||
auto elapsed = now - lastUpdate;
|
||||
const auto interval = 100;
|
||||
if(lastUpdate > 0 && elapsed < interval)
|
||||
{
|
||||
//qDebug() << "Delay update:" << msg2str(msg);
|
||||
QTimer* timer = mUpdateTimers[msg];
|
||||
if(timer == nullptr)
|
||||
{
|
||||
timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
connect(timer, &QTimer::timeout, this, [this, msg]
|
||||
{
|
||||
doUpdate(msg);
|
||||
});
|
||||
mUpdateTimers[msg] = timer;
|
||||
}
|
||||
|
||||
if(!timer->isActive())
|
||||
{
|
||||
timer->setInterval(interval - elapsed);
|
||||
timer->start();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//qDebug() << "No delay: " << msg2str(msg);
|
||||
doUpdate(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void Bridge::doUpdate(GUIMSG msg)
|
||||
{
|
||||
auto start = GetTickCount();
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case GUI_UPDATE_REGISTER_VIEW:
|
||||
updateRegisters();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_DISASSEMBLY_VIEW:
|
||||
updateDisassembly();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_BREAKPOINTS_VIEW:
|
||||
updateBreakpoints();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_DUMP_VIEW:
|
||||
updateDump();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_THREAD_VIEW:
|
||||
updateThreads();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_MEMORY_VIEW:
|
||||
updateMemory();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_SIDEBAR:
|
||||
updateSideBar();
|
||||
break;
|
||||
|
||||
case GUI_REPAINT_TABLE_VIEW:
|
||||
repaintTableView();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_PATCHES:
|
||||
updatePatches();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_CALLSTACK:
|
||||
updateCallStack();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_SEHCHAIN:
|
||||
updateSEHChain();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_TIME_WASTED_COUNTER:
|
||||
updateTimeWastedCounter();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_ARGUMENT_VIEW:
|
||||
updateArgumentView();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_WATCH_VIEW:
|
||||
updateWatch();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_GRAPH_VIEW:
|
||||
updateGraph();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_TYPE_WIDGET:
|
||||
typeUpdateWidget();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_TRACE_BROWSER:
|
||||
updateTraceBrowser();
|
||||
break;
|
||||
|
||||
default:
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
// Log potentially bottlenecked updates
|
||||
auto now = GetTickCount();
|
||||
auto elapsed = now - start;
|
||||
if(elapsed > 5)
|
||||
qDebug() << msg2str(msg) << elapsed << "ms";
|
||||
|
||||
mLastUpdates[msg] = now;
|
||||
}
|
||||
|
||||
Bridge::Bridge(QObject* parent) : QObject(parent)
|
||||
{
|
||||
InitializeCriticalSection(&csBridge);
|
||||
InitializeCriticalSection(&mCsBridge);
|
||||
for(size_t i = 0; i < BridgeResult::Last; i++)
|
||||
resultEvents[i] = CreateEventW(nullptr, true, true, nullptr);
|
||||
dwMainThreadId = GetCurrentThreadId();
|
||||
mResultEvents[i] = CreateEventW(nullptr, true, true, nullptr);
|
||||
mMainThreadId = GetCurrentThreadId();
|
||||
|
||||
connect(this, &Bridge::throttleUpdate, this, &Bridge::throttleUpdateSlot);
|
||||
}
|
||||
|
||||
Bridge::~Bridge()
|
||||
{
|
||||
EnterCriticalSection(&csBridge);
|
||||
EnterCriticalSection(&mCsBridge);
|
||||
for(size_t i = 0; i < BridgeResult::Last; i++)
|
||||
CloseHandle(resultEvents[i]);
|
||||
DeleteCriticalSection(&csBridge);
|
||||
CloseHandle(mResultEvents[i]);
|
||||
DeleteCriticalSection(&mCsBridge);
|
||||
}
|
||||
|
||||
void Bridge::CopyToClipboard(const QString & text)
|
||||
@ -68,8 +236,8 @@ void Bridge::setResult(BridgeResult::Type type, dsint result)
|
||||
#ifdef DEBUG
|
||||
OutputDebugStringA(QString().sprintf("[x64dbg] [%u] Bridge::setResult(%d, %p)\n", GetCurrentThreadId(), type, result).toUtf8().constData());
|
||||
#endif //DEBUG
|
||||
bridgeResults[type] = result;
|
||||
SetEvent(resultEvents[type]);
|
||||
mBridgeResults[type] = result;
|
||||
SetEvent(mResultEvents[type]);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
@ -103,7 +271,7 @@ void Bridge::emitMenuAddToList(QWidget* parent, QMenu* menu, GUIMENUTYPE hMenu,
|
||||
|
||||
void Bridge::setDbgStopped()
|
||||
{
|
||||
dbgStopped = true;
|
||||
mDbgStopped = true;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
@ -112,7 +280,7 @@ void Bridge::setDbgStopped()
|
||||
|
||||
void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
{
|
||||
if(dbgStopped) //there can be no more messages if the debugger stopped = IGNORE
|
||||
if(mDbgStopped) //there can be no more messages if the debugger stopped = IGNORE
|
||||
return nullptr;
|
||||
switch(type)
|
||||
{
|
||||
@ -160,24 +328,12 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
emit redirectLogStop();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_REGISTER_VIEW:
|
||||
emit updateRegisters();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_DISASSEMBLY_VIEW:
|
||||
emit updateDisassembly();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_BREAKPOINTS_VIEW:
|
||||
emit updateBreakpoints();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_WINDOW_TITLE:
|
||||
emit updateWindowTitle(QString((const char*)param1));
|
||||
break;
|
||||
|
||||
case GUI_GET_WINDOW_HANDLE:
|
||||
return winId;
|
||||
return mWinId;
|
||||
|
||||
case GUI_DUMP_AT:
|
||||
emit dumpAt((dsint)param1);
|
||||
@ -252,25 +408,25 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
break;
|
||||
|
||||
case GUI_REF_ADDCOLUMN:
|
||||
if(referenceManager->currentReferenceView())
|
||||
referenceManager->currentReferenceView()->addColumnAtRef((int)param1, QString((const char*)param2));
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
mReferenceManager->currentReferenceView()->addColumnAtRef((int)param1, QString((const char*)param2));
|
||||
break;
|
||||
|
||||
case GUI_REF_SETROWCOUNT:
|
||||
{
|
||||
if(referenceManager->currentReferenceView())
|
||||
referenceManager->currentReferenceView()->setRowCount((dsint)param1);
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
mReferenceManager->currentReferenceView()->setRowCount((dsint)param1);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_REF_GETROWCOUNT:
|
||||
if(referenceManager->currentReferenceView())
|
||||
return (void*)referenceManager->currentReferenceView()->stdList()->getRowCount();
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
return (void*)mReferenceManager->currentReferenceView()->stdList()->getRowCount();
|
||||
return 0;
|
||||
|
||||
case GUI_REF_SEARCH_GETROWCOUNT:
|
||||
if(referenceManager->currentReferenceView())
|
||||
return (void*)referenceManager->currentReferenceView()->mCurList->getRowCount();
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
return (void*)mReferenceManager->currentReferenceView()->mCurList->getRowCount();
|
||||
return 0;
|
||||
|
||||
case GUI_REF_DELETEALLCOLUMNS:
|
||||
@ -280,16 +436,16 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
case GUI_REF_SETCELLCONTENT:
|
||||
{
|
||||
CELLINFO* info = (CELLINFO*)param1;
|
||||
if(referenceManager->currentReferenceView())
|
||||
referenceManager->currentReferenceView()->setCellContent(info->row, info->col, QString(info->str));
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
mReferenceManager->currentReferenceView()->setCellContent(info->row, info->col, QString(info->str));
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_REF_GETCELLCONTENT:
|
||||
{
|
||||
QString content;
|
||||
if(referenceManager->currentReferenceView())
|
||||
content = referenceManager->currentReferenceView()->stdList()->getCellContent((int)param1, (int)param2);
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
content = mReferenceManager->currentReferenceView()->stdList()->getCellContent((int)param1, (int)param2);
|
||||
auto bytes = content.toUtf8();
|
||||
auto data = BridgeAlloc(bytes.size() + 1);
|
||||
memcpy(data, bytes.constData(), bytes.size());
|
||||
@ -299,8 +455,8 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
case GUI_REF_SEARCH_GETCELLCONTENT:
|
||||
{
|
||||
QString content;
|
||||
if(referenceManager->currentReferenceView())
|
||||
content = referenceManager->currentReferenceView()->mCurList->getCellContent((int)param1, (int)param2);
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
content = mReferenceManager->currentReferenceView()->mCurList->getCellContent((int)param1, (int)param2);
|
||||
auto bytes = content.toUtf8();
|
||||
auto data = BridgeAlloc(bytes.size() + 1);
|
||||
memcpy(data, bytes.constData(), bytes.size());
|
||||
@ -316,26 +472,26 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
break;
|
||||
|
||||
case GUI_REF_SETPROGRESS:
|
||||
if(referenceManager->currentReferenceView())
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
{
|
||||
auto newProgress = (int)param1;
|
||||
if(referenceManager->currentReferenceView()->progress() != newProgress)
|
||||
if(mReferenceManager->currentReferenceView()->progress() != newProgress)
|
||||
emit referenceSetProgress(newProgress);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_REF_SETCURRENTTASKPROGRESS:
|
||||
if(referenceManager->currentReferenceView())
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
{
|
||||
auto newProgress = (int)param1;
|
||||
if(referenceManager->currentReferenceView()->currentTaskProgress() != newProgress)
|
||||
if(mReferenceManager->currentReferenceView()->currentTaskProgress() != newProgress)
|
||||
emit referenceSetCurrentTaskProgress((int)param1, QString((const char*)param2));
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_REF_SETSEARCHSTARTCOL:
|
||||
if(referenceManager->currentReferenceView())
|
||||
referenceManager->currentReferenceView()->setSearchStartCol((duint)param1);
|
||||
if(mReferenceManager->currentReferenceView())
|
||||
mReferenceManager->currentReferenceView()->setSearchStartCol((duint)param1);
|
||||
break;
|
||||
|
||||
case GUI_REF_INITIALIZE:
|
||||
@ -350,18 +506,6 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
emit stackDumpAt((duint)param1, (duint)param2);
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_DUMP_VIEW:
|
||||
emit updateDump();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_THREAD_VIEW:
|
||||
emit updateThreads();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_MEMORY_VIEW:
|
||||
emit updateMemory();
|
||||
break;
|
||||
|
||||
case GUI_ADD_RECENT_FILE:
|
||||
emit addRecentFile(QString((const char*)param1));
|
||||
break;
|
||||
@ -619,26 +763,6 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
emit addMsgToStatusBar(QString((const char*)param1));
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_SIDEBAR:
|
||||
emit updateSideBar();
|
||||
break;
|
||||
|
||||
case GUI_REPAINT_TABLE_VIEW:
|
||||
emit repaintTableView();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_PATCHES:
|
||||
emit updatePatches();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_CALLSTACK:
|
||||
emit updateCallStack();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_SEHCHAIN:
|
||||
emit updateSEHChain();
|
||||
break;
|
||||
|
||||
case GUI_SYMBOL_REFRESH_CURRENT:
|
||||
emit symbolRefreshCurrent();
|
||||
break;
|
||||
@ -669,17 +793,13 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
|
||||
case GUI_EXECUTE_ON_GUI_THREAD:
|
||||
{
|
||||
if(GetCurrentThreadId() == dwMainThreadId)
|
||||
if(GetCurrentThreadId() == mMainThreadId)
|
||||
((GUICALLBACKEX)param1)(param2);
|
||||
else
|
||||
emit executeOnGuiThread(param1, param2);
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_TIME_WASTED_COUNTER:
|
||||
emit updateTimeWastedCounter();
|
||||
break;
|
||||
|
||||
case GUI_SET_GLOBAL_NOTES:
|
||||
{
|
||||
QString text = QString((const char*)param1);
|
||||
@ -734,10 +854,6 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
emit unregisterScriptLang((int)param1);
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_ARGUMENT_VIEW:
|
||||
emit updateArgumentView();
|
||||
break;
|
||||
|
||||
case GUI_FOCUS_VIEW:
|
||||
{
|
||||
int hWindow = int(param1);
|
||||
@ -764,10 +880,6 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_WATCH_VIEW:
|
||||
emit updateWatch();
|
||||
break;
|
||||
|
||||
case GUI_LOAD_GRAPH:
|
||||
{
|
||||
BridgeResult result(BridgeResult::LoadGraph);
|
||||
@ -784,17 +896,13 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_GRAPH_VIEW:
|
||||
emit updateGraph();
|
||||
break;
|
||||
|
||||
case GUI_SET_LOG_ENABLED:
|
||||
loggingEnabled = param1 != 0;
|
||||
emit setLogEnabled(loggingEnabled);
|
||||
mLoggingEnabled = param1 != 0;
|
||||
emit setLogEnabled(mLoggingEnabled);
|
||||
break;
|
||||
|
||||
case GUI_IS_LOG_ENABLED:
|
||||
return (void*)loggingEnabled;
|
||||
return (void*)mLoggingEnabled;
|
||||
|
||||
case GUI_ADD_FAVOURITE_TOOL:
|
||||
{
|
||||
@ -883,10 +991,6 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_TYPE_WIDGET:
|
||||
emit typeUpdateWidget();
|
||||
break;
|
||||
|
||||
case GUI_CLOSE_APPLICATION:
|
||||
emit closeApplication();
|
||||
break;
|
||||
@ -914,12 +1018,8 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
}
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_TRACE_BROWSER:
|
||||
emit updateTraceBrowser();
|
||||
break;
|
||||
|
||||
case GUI_INVALIDATE_SYMBOL_SOURCE:
|
||||
symbolView->invalidateSymbolSource(duint(param1));
|
||||
mSymbolView->invalidateSymbolSource(duint(param1));
|
||||
break;
|
||||
|
||||
case GUI_GET_CURRENT_GRAPH:
|
||||
@ -947,7 +1047,28 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||
break;
|
||||
|
||||
case GUI_GET_MAIN_THREAD_ID:
|
||||
return (void*)dwMainThreadId;
|
||||
return (void*)mMainThreadId;
|
||||
|
||||
case GUI_UPDATE_REGISTER_VIEW:
|
||||
case GUI_UPDATE_DISASSEMBLY_VIEW:
|
||||
case GUI_UPDATE_BREAKPOINTS_VIEW:
|
||||
case GUI_UPDATE_DUMP_VIEW:
|
||||
case GUI_UPDATE_THREAD_VIEW:
|
||||
case GUI_UPDATE_MEMORY_VIEW:
|
||||
case GUI_UPDATE_SIDEBAR:
|
||||
case GUI_REPAINT_TABLE_VIEW:
|
||||
case GUI_UPDATE_PATCHES:
|
||||
case GUI_UPDATE_CALLSTACK:
|
||||
case GUI_UPDATE_SEHCHAIN:
|
||||
case GUI_UPDATE_TIME_WASTED_COUNTER:
|
||||
case GUI_UPDATE_ARGUMENT_VIEW:
|
||||
case GUI_UPDATE_WATCH_VIEW:
|
||||
case GUI_UPDATE_GRAPH_VIEW:
|
||||
case GUI_UPDATE_TYPE_WIDGET:
|
||||
case GUI_UPDATE_TRACE_BROWSER:
|
||||
// NOTE: this can run on any thread.
|
||||
emit throttleUpdate(type);
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -26,6 +26,11 @@ class Bridge : public QObject
|
||||
|
||||
friend class BridgeResult;
|
||||
|
||||
void doUpdate(GUIMSG msg);
|
||||
|
||||
private slots:
|
||||
void throttleUpdateSlot(GUIMSG msg);
|
||||
|
||||
public:
|
||||
explicit Bridge(QObject* parent = nullptr);
|
||||
~Bridge();
|
||||
@ -49,12 +54,12 @@ public:
|
||||
void setDbgStopped();
|
||||
|
||||
//Public variables
|
||||
void* winId = nullptr;
|
||||
ReferenceManager* referenceManager = nullptr;
|
||||
void* mWinId = nullptr;
|
||||
ReferenceManager* mReferenceManager = nullptr;
|
||||
bool mIsRunning = false;
|
||||
duint mLastCip = 0;
|
||||
SymbolView* symbolView = nullptr;
|
||||
bool loggingEnabled = true;
|
||||
SymbolView* mSymbolView = nullptr;
|
||||
bool mLoggingEnabled = true;
|
||||
|
||||
signals:
|
||||
void disassembleAt(duint va, duint eip);
|
||||
@ -183,11 +188,14 @@ signals:
|
||||
void showReferences();
|
||||
void gotoTraceIndex(duint index);
|
||||
void showTraceBrowser();
|
||||
void throttleUpdate(GUIMSG msg);
|
||||
|
||||
private:
|
||||
CRITICAL_SECTION csBridge;
|
||||
HANDLE resultEvents[BridgeResult::Last];
|
||||
duint bridgeResults[BridgeResult::Last];
|
||||
DWORD dwMainThreadId = 0;
|
||||
volatile bool dbgStopped = false;
|
||||
CRITICAL_SECTION mCsBridge;
|
||||
HANDLE mResultEvents[BridgeResult::Last];
|
||||
duint mBridgeResults[BridgeResult::Last];
|
||||
DWORD mMainThreadId = 0;
|
||||
volatile bool mDbgStopped = false;
|
||||
QMap<GUIMSG, DWORD> mLastUpdates;
|
||||
QMap<GUIMSG, QTimer*> mUpdateTimers;
|
||||
};
|
||||
|
@ -6,11 +6,11 @@ BridgeResult::BridgeResult(Type type)
|
||||
: mType(type)
|
||||
{
|
||||
Bridge* bridge = Bridge::getBridge();
|
||||
EnterCriticalSection(&bridge->csBridge);
|
||||
EnterCriticalSection(&bridge->mCsBridge);
|
||||
#ifdef DEBUG
|
||||
OutputDebugStringA(QString().sprintf("[x64dbg] [%u] BridgeResult(%d)\n", GetCurrentThreadId(), type).toUtf8().constData());
|
||||
#endif //DEBUG
|
||||
ResetEvent(bridge->resultEvents[type]);
|
||||
ResetEvent(bridge->mResultEvents[type]);
|
||||
}
|
||||
|
||||
BridgeResult::~BridgeResult()
|
||||
@ -18,7 +18,7 @@ BridgeResult::~BridgeResult()
|
||||
#ifdef DEBUG
|
||||
OutputDebugStringA(QString().sprintf("[x64dbg] [%u] ~BridgeResult(%d)\n", GetCurrentThreadId(), mType).toUtf8().constData());
|
||||
#endif //DEBUG
|
||||
LeaveCriticalSection(&Bridge::getBridge()->csBridge);
|
||||
LeaveCriticalSection(&Bridge::getBridge()->mCsBridge);
|
||||
}
|
||||
|
||||
dsint BridgeResult::Wait()
|
||||
@ -27,9 +27,9 @@ dsint BridgeResult::Wait()
|
||||
OutputDebugStringA(QString().sprintf("[x64dbg] [%u] BridgeResult::Wait(%d)\n", GetCurrentThreadId(), mType).toUtf8().constData());
|
||||
#endif //DEBUG
|
||||
Bridge* bridge = Bridge::getBridge();
|
||||
HANDLE hResultEvent = bridge->resultEvents[mType];
|
||||
HANDLE hResultEvent = bridge->mResultEvents[mType];
|
||||
//Don't freeze when waiting on the main thread (https://github.com/x64dbg/x64dbg/issues/1716)
|
||||
if(GetCurrentThreadId() == bridge->dwMainThreadId)
|
||||
if(GetCurrentThreadId() == bridge->mMainThreadId)
|
||||
while(WaitForSingleObject(hResultEvent, 10) == WAIT_TIMEOUT)
|
||||
QCoreApplication::processEvents();
|
||||
else
|
||||
@ -37,5 +37,5 @@ dsint BridgeResult::Wait()
|
||||
#ifdef DEBUG
|
||||
OutputDebugStringA(QString().sprintf("[x64dbg] [%u] BridgeResult::~Wait(%d)\n", GetCurrentThreadId(), mType).toUtf8().constData());
|
||||
#endif //DEBUG
|
||||
return bridge->bridgeResults[mType];
|
||||
return bridge->mBridgeResults[mType];
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ void DisassemblerGraphView::resizeEvent(QResizeEvent* event)
|
||||
adjustSize(event->size().width(), event->size().height());
|
||||
}
|
||||
|
||||
duint DisassemblerGraphView::get_cursor_pos()
|
||||
duint DisassemblerGraphView::get_cursor_pos() const
|
||||
{
|
||||
if(this->cur_instr == 0)
|
||||
return this->function;
|
||||
@ -934,7 +934,7 @@ void DisassemblerGraphView::wheelEvent(QWheelEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
bool DisassemblerGraphView::isMouseEventInBlock(QMouseEvent* event)
|
||||
bool DisassemblerGraphView::isMouseEventInBlock(QMouseEvent* event) const
|
||||
{
|
||||
//Convert coordinates to system used in blocks
|
||||
int xofs = this->horizontalScrollBar()->value();
|
||||
@ -945,7 +945,7 @@ bool DisassemblerGraphView::isMouseEventInBlock(QMouseEvent* event)
|
||||
// Check each block for hits
|
||||
for(auto & blockIt : this->blocks)
|
||||
{
|
||||
DisassemblerBlock & block = blockIt.second;
|
||||
auto & block = blockIt.second;
|
||||
//Compute coordinate relative to text area in block
|
||||
int blockx = x - (block.x + (2 * this->charWidth));
|
||||
int blocky = y - (block.y + (2 * this->charWidth));
|
||||
@ -959,7 +959,7 @@ bool DisassemblerGraphView::isMouseEventInBlock(QMouseEvent* event)
|
||||
return false;
|
||||
}
|
||||
|
||||
duint DisassemblerGraphView::getInstrForMouseEvent(QMouseEvent* event)
|
||||
duint DisassemblerGraphView::getInstrForMouseEvent(QMouseEvent* event) const
|
||||
{
|
||||
//Convert coordinates to system used in blocks
|
||||
int xofs = this->horizontalScrollBar()->value();
|
||||
@ -970,7 +970,7 @@ duint DisassemblerGraphView::getInstrForMouseEvent(QMouseEvent* event)
|
||||
//Check each block for hits
|
||||
for(auto & blockIt : this->blocks)
|
||||
{
|
||||
DisassemblerBlock & block = blockIt.second;
|
||||
auto & block = blockIt.second;
|
||||
//Compute coordinate relative to text area in block
|
||||
int blockx = x - (block.x + (2 * this->charWidth));
|
||||
int blocky = y - (block.y + (2 * this->charWidth));
|
||||
@ -985,7 +985,7 @@ duint DisassemblerGraphView::getInstrForMouseEvent(QMouseEvent* event)
|
||||
int cur_row = int(block.block.header_text.lines.size());
|
||||
if(row < cur_row)
|
||||
return block.block.entry;
|
||||
for(Instr & instr : block.block.instrs)
|
||||
for(auto & instr : block.block.instrs)
|
||||
{
|
||||
if(row < cur_row + int(instr.text.lines.size()))
|
||||
return instr.addr;
|
||||
@ -995,7 +995,7 @@ duint DisassemblerGraphView::getInstrForMouseEvent(QMouseEvent* event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DisassemblerGraphView::getTokenForMouseEvent(QMouseEvent* event, ZydisTokenizer::SingleToken & tokenOut)
|
||||
bool DisassemblerGraphView::getTokenForMouseEvent(QMouseEvent* event, ZydisTokenizer::SingleToken & tokenOut) const
|
||||
{
|
||||
//Convert coordinates to system used in blocks
|
||||
int xofs = this->horizontalScrollBar()->value();
|
||||
@ -1006,7 +1006,7 @@ bool DisassemblerGraphView::getTokenForMouseEvent(QMouseEvent* event, ZydisToken
|
||||
//Check each block for hits
|
||||
for(auto & blockIt : this->blocks)
|
||||
{
|
||||
DisassemblerBlock & block = blockIt.second;
|
||||
auto & block = blockIt.second;
|
||||
//Compute coordinate relative to text area in block
|
||||
int blockx = x - (block.x + (2 * this->charWidth));
|
||||
int blocky = y - (block.y + (2 * this->charWidth));
|
||||
@ -1064,12 +1064,16 @@ bool DisassemblerGraphView::getTokenForMouseEvent(QMouseEvent* event, ZydisToken
|
||||
bool DisassemblerGraphView::find_instr(duint addr, Instr & instrOut)
|
||||
{
|
||||
for(auto & blockIt : this->blocks)
|
||||
{
|
||||
for(Instr & instr : blockIt.second.block.instrs)
|
||||
{
|
||||
if(instr.addr == addr)
|
||||
{
|
||||
instrOut = instr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1358,7 +1362,7 @@ void DisassemblerGraphView::computeGraphLayout(DisassemblerBlock & block)
|
||||
block.row_count = row_count;
|
||||
}
|
||||
|
||||
bool DisassemblerGraphView::isEdgeMarked(EdgesVector & edges, int row, int col, int index)
|
||||
bool DisassemblerGraphView::isEdgeMarked(EdgesVector & edges, int row, int col, int index) const
|
||||
{
|
||||
if(index >= int(edges[row][col].size()))
|
||||
return false;
|
||||
@ -2692,7 +2696,7 @@ void DisassemblerGraphView::copyHighlightedTokenValueSlot()
|
||||
Bridge::CopyToClipboard(text);
|
||||
}
|
||||
|
||||
bool DisassemblerGraphView::getHighlightedTokenValueText(QString & text)
|
||||
bool DisassemblerGraphView::getHighlightedTokenValueText(QString & text) const
|
||||
{
|
||||
if(mHighlightToken.type <= ZydisTokenizer::TokenType::MnemonicUnusual)
|
||||
return false;
|
||||
|
@ -212,7 +212,7 @@ public:
|
||||
void initFont();
|
||||
void adjustSize(int viewportWidth, int viewportHeight, QPoint mousePosition = QPoint(0, 0), bool fitToWindow = false);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
duint get_cursor_pos();
|
||||
duint get_cursor_pos() const;
|
||||
void set_cursor_pos(duint addr);
|
||||
std::tuple<duint, duint> get_selection_range();
|
||||
void set_selection_range(std::tuple<duint, duint> range);
|
||||
@ -220,9 +220,9 @@ public:
|
||||
void paintNormal(QPainter & p, QRect & viewportRect, int xofs, int yofs);
|
||||
void paintOverview(QPainter & p, QRect & viewportRect, int xofs, int yofs);
|
||||
void paintEvent(QPaintEvent* event);
|
||||
bool isMouseEventInBlock(QMouseEvent* event);
|
||||
duint getInstrForMouseEvent(QMouseEvent* event);
|
||||
bool getTokenForMouseEvent(QMouseEvent* event, ZydisTokenizer::SingleToken & token);
|
||||
bool isMouseEventInBlock(QMouseEvent* event) const;
|
||||
duint getInstrForMouseEvent(QMouseEvent* event) const;
|
||||
bool getTokenForMouseEvent(QMouseEvent* event, ZydisTokenizer::SingleToken & token) const;
|
||||
bool find_instr(duint addr, Instr & instr);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
@ -236,7 +236,7 @@ public:
|
||||
template<typename T>
|
||||
using Matrix = std::vector<std::vector<T>>;
|
||||
using EdgesVector = Matrix<std::vector<bool>>;
|
||||
bool isEdgeMarked(EdgesVector & edges, int row, int col, int index);
|
||||
bool isEdgeMarked(EdgesVector & edges, int row, int col, int index) const;
|
||||
void markEdge(EdgesVector & edges, int row, int col, int index, bool used = true);
|
||||
int findHorizEdgeIndex(EdgesVector & edges, int row, int min_col, int max_col);
|
||||
int findVertEdgeIndex(EdgesVector & edges, int col, int min_row, int max_row);
|
||||
@ -257,7 +257,7 @@ public:
|
||||
VaHistory mHistory;
|
||||
|
||||
signals:
|
||||
void selectionChanged(dsint parVA);
|
||||
void selectionChanged(duint parVA);
|
||||
void displayLogWidget();
|
||||
void detachGraph();
|
||||
|
||||
@ -392,5 +392,5 @@ private:
|
||||
XrefBrowseDialog* mXrefDlg = nullptr;
|
||||
|
||||
void addReferenceAction(QMenu* menu, duint addr, const QString & description);
|
||||
bool getHighlightedTokenValueText(QString & text);
|
||||
bool getHighlightedTokenValueText(QString & text) const;
|
||||
};
|
||||
|
@ -129,12 +129,15 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
|
||||
|
||||
connect(mHandlesTable, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(handlesTableContextMenuSlot(QMenu*)));
|
||||
connect(mWindowsTable, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(windowsTableContextMenuSlot(QMenu*)));
|
||||
connect(mWindowsTable, SIGNAL(enterPressedSignal()), this, SLOT(followInDisasmSlot()));
|
||||
connect(mTcpConnectionsTable, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(tcpConnectionsTableContextMenuSlot(QMenu*)));
|
||||
connect(mPrivilegesTable, SIGNAL(contextMenuSignal(const QPoint &)), this, SLOT(privilegesTableContextMenuSlot(const QPoint &)));
|
||||
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts()));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChanged(DBGSTATE)));
|
||||
|
||||
#ifdef _WIN32 // This is only supported on Windows Vista or greater
|
||||
if(!IsWindowsVistaOrGreater())
|
||||
#endif //_WIN32
|
||||
{
|
||||
mTcpConnectionsTable->setRowCount(1);
|
||||
mTcpConnectionsTable->setCellContent(0, 0, tr("TCP Connection enumeration is only available on Windows Vista or greater."));
|
||||
@ -404,6 +407,8 @@ void HandlesView::enumHandles()
|
||||
|
||||
static QIcon getWindowIcon(HWND hWnd)
|
||||
{
|
||||
QIcon result;
|
||||
#ifdef _WIN32
|
||||
HICON winIcon;
|
||||
if(IsWindowUnicode(hWnd))
|
||||
{
|
||||
@ -416,12 +421,12 @@ static QIcon getWindowIcon(HWND hWnd)
|
||||
//if(SendMessageTimeoutA(hWnd, WM_GETICON, 0, 0, SMTO_ABORTIFHUNG | SMTO_BLOCK | SMTO_ERRORONEXIT, 500, (PDWORD)&winIcon) == 0)
|
||||
winIcon = (HICON)GetClassLongPtrA(hWnd, -14); //GCL_HICON
|
||||
}
|
||||
QIcon result;
|
||||
if(winIcon != 0)
|
||||
{
|
||||
result = QIcon(QtWin::fromHICON(winIcon));
|
||||
DestroyIcon(winIcon);
|
||||
}
|
||||
#endif //_WIN32
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ MainWindow::MainWindow(QWidget* parent)
|
||||
|
||||
// Symbol view
|
||||
mSymbolView = new SymbolView();
|
||||
Bridge::getBridge()->symbolView = mSymbolView;
|
||||
Bridge::getBridge()->mSymbolView = mSymbolView;
|
||||
mSymbolView->setWindowTitle(tr("Symbols"));
|
||||
mSymbolView->setWindowIcon(DIcon("pdb"));
|
||||
mSymbolView->hide();
|
||||
@ -207,7 +207,7 @@ MainWindow::MainWindow(QWidget* parent)
|
||||
|
||||
// Reference manager
|
||||
mReferenceManager = new ReferenceManager(this);
|
||||
Bridge::getBridge()->referenceManager = mReferenceManager;
|
||||
Bridge::getBridge()->mReferenceManager = mReferenceManager;
|
||||
mReferenceManager->setWindowTitle(tr("References"));
|
||||
mReferenceManager->setWindowIcon(DIcon("search"));
|
||||
|
||||
@ -1248,7 +1248,7 @@ void MainWindow::openFileSlot()
|
||||
|
||||
void MainWindow::openRecentFileSlot(QString filename)
|
||||
{
|
||||
DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()));
|
||||
DbgCmdExec(QString().sprintf("init \"%s\"", DbgCmdEscape(filename).toUtf8().constData()));
|
||||
}
|
||||
|
||||
void MainWindow::runSlot()
|
||||
@ -1263,7 +1263,7 @@ void MainWindow::restartDebugging()
|
||||
{
|
||||
auto last = mMRUList->getEntry(0);
|
||||
if(!last.isEmpty())
|
||||
DbgCmdExec(QString("init \"%1\"").arg(last));
|
||||
DbgCmdExec(QString("init \"%1\"").arg(DbgCmdEscape(last)));
|
||||
}
|
||||
|
||||
void MainWindow::displayBreakpointWidget()
|
||||
@ -1281,10 +1281,11 @@ void MainWindow::dragEnterEvent(QDragEnterEvent* pEvent)
|
||||
|
||||
void MainWindow::dropEvent(QDropEvent* pEvent)
|
||||
{
|
||||
|
||||
if(pEvent->mimeData()->hasUrls())
|
||||
{
|
||||
QString filename = QDir::toNativeSeparators(pEvent->mimeData()->urls()[0].toLocalFile());
|
||||
DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()));
|
||||
DbgCmdExec(QString().sprintf("init \"%s\"", DbgCmdEscape(filename).toUtf8().constData()));
|
||||
pEvent->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ MemoryMapView::MemoryMapView(StdTable* parent)
|
||||
loadColumnFromConfig("MemoryMap");
|
||||
setIconColumn(ColParty);
|
||||
|
||||
connect(Bridge::getBridge(), SIGNAL(updateMemory()), this, SLOT(refreshMap()));
|
||||
connect(Bridge::getBridge(), SIGNAL(updateMemory()), this, SLOT(refreshMapSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(stateChangedSlot(DBGSTATE)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectInMemoryMap(duint)), this, SLOT(selectAddress(duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectInMemoryMap(duint)), this, SLOT(selectAddressSlot(duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionMemmapGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionMemmapSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
|
||||
@ -63,12 +63,12 @@ void MemoryMapView::setupContextMenu()
|
||||
|
||||
//Set PageMemory Rights
|
||||
mPageMemoryRights = new QAction(DIcon("memmap_set_page_memory_rights"), tr("Set Page Memory Rights"), this);
|
||||
connect(mPageMemoryRights, SIGNAL(triggered()), this, SLOT(pageMemoryRights()));
|
||||
connect(mPageMemoryRights, SIGNAL(triggered()), this, SLOT(pageMemoryRightsSlot()));
|
||||
|
||||
//Switch View
|
||||
mSwitchView = new QAction(DIcon("change-view"), "", this);
|
||||
setSwitchViewName();
|
||||
connect(mSwitchView, SIGNAL(triggered()), this, SLOT(switchView()));
|
||||
connect(mSwitchView, SIGNAL(triggered()), this, SLOT(switchViewSlot()));
|
||||
|
||||
//Breakpoint menu
|
||||
mBreakpointMenu = new QMenu(tr("Memory &Breakpoint"), this);
|
||||
@ -169,11 +169,11 @@ void MemoryMapView::setupContextMenu()
|
||||
//Dump
|
||||
//TODO: These two actions should also appear in CPUDump
|
||||
mDumpMemory = new QAction(DIcon("binary_save"), tr("&Dump Memory to File"), this);
|
||||
connect(mDumpMemory, SIGNAL(triggered()), this, SLOT(dumpMemory()));
|
||||
connect(mDumpMemory, SIGNAL(triggered()), this, SLOT(dumpMemorySlot()));
|
||||
|
||||
//Load
|
||||
mLoadMemory = new QAction(DIcon(""), tr("&Overwrite with Data from File"), this);
|
||||
connect(mLoadMemory, SIGNAL(triggered()), this, SLOT(loadMemory()));
|
||||
connect(mLoadMemory, SIGNAL(triggered()), this, SLOT(loadMemorySlot()));
|
||||
|
||||
//Add virtual module
|
||||
mAddVirtualMod = new QAction(DIcon("virtual"), tr("Add virtual module"), this);
|
||||
@ -272,17 +272,6 @@ void MemoryMapView::contextMenuSlot(const QPoint & pos)
|
||||
menu.exec(mapToGlobal(pos)); //execute context menu
|
||||
}
|
||||
|
||||
static QString getProtectionString(DWORD Protect)
|
||||
{
|
||||
#define RIGHTS_STRING (sizeof("ERWCG"))
|
||||
char rights[RIGHTS_STRING];
|
||||
|
||||
if(!DbgFunctions()->PageRightsToString(Protect, rights))
|
||||
return "bad";
|
||||
|
||||
return QString(rights);
|
||||
}
|
||||
|
||||
QString MemoryMapView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
if(col == 0) //address
|
||||
@ -377,14 +366,14 @@ void MemoryMapView::setSwitchViewName()
|
||||
QAction* MemoryMapView::makeCommandAction(QAction* action, const QString & command)
|
||||
{
|
||||
action->setData(QVariant(command));
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(ExecCommand()));
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(execCommandSlot()));
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MemoryMapView::ExecCommand execute command slot for menus.
|
||||
* @brief MemoryMapView::execCommandSlot execute command slot for menus.
|
||||
*/
|
||||
void MemoryMapView::ExecCommand()
|
||||
void MemoryMapView::execCommandSlot()
|
||||
{
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if(action)
|
||||
@ -404,16 +393,52 @@ void MemoryMapView::ExecCommand()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::refreshMap()
|
||||
static QString getProtectionString(DWORD protect)
|
||||
{
|
||||
//reserved pages don't have a protection (https://goo.gl/Izkk0c)
|
||||
if(protect == 0)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
#define meme(prot, str) (prot & PAGE_GUARD) ? QStringLiteral(str QT_UNICODE_LITERAL("G")) : QStringLiteral(str QT_UNICODE_LITERAL("-"))
|
||||
|
||||
switch(protect & 0xFF)
|
||||
{
|
||||
case PAGE_NOACCESS:
|
||||
return meme(protect, "----");
|
||||
case PAGE_READONLY:
|
||||
return meme(protect, "-R--");
|
||||
case PAGE_READWRITE:
|
||||
return meme(protect, "-RW-");
|
||||
case PAGE_WRITECOPY:
|
||||
return meme(protect, "-RWC");
|
||||
case PAGE_EXECUTE:
|
||||
return meme(protect, "E---");
|
||||
case PAGE_EXECUTE_READ:
|
||||
return meme(protect, "ER--");
|
||||
case PAGE_EXECUTE_READWRITE:
|
||||
return meme(protect, "ERW-");
|
||||
case PAGE_EXECUTE_WRITECOPY:
|
||||
return meme(protect, "ERWC");
|
||||
default:
|
||||
return meme(protect, "????");
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::refreshMapSlot()
|
||||
{
|
||||
MEMMAP memoryMap = {};
|
||||
DbgMemMap(&memoryMap);
|
||||
|
||||
setRowCount(memoryMap.count);
|
||||
|
||||
auto strUser = tr("User");
|
||||
auto strSystem = tr("System");
|
||||
|
||||
for(int i = 0; i < memoryMap.count; i++)
|
||||
{
|
||||
const auto & mbi = (memoryMap.page)[i].mbi;
|
||||
const auto & mbi = memoryMap.page[i].mbi;
|
||||
|
||||
// Base address
|
||||
setCellContent(i, ColAddress, ToPtrString((duint)mbi.BaseAddress));
|
||||
@ -428,11 +453,11 @@ void MemoryMapView::refreshMap()
|
||||
switch(party)
|
||||
{
|
||||
case mod_user:
|
||||
setCellContent(i, ColParty, tr("User"));
|
||||
setCellContent(i, ColParty, strUser);
|
||||
setRowIcon(i, DIcon("markasuser"));
|
||||
break;
|
||||
case mod_system:
|
||||
setCellContent(i, ColParty, tr("System"));
|
||||
setCellContent(i, ColParty, strSystem);
|
||||
setRowIcon(i, DIcon("markassystem"));
|
||||
break;
|
||||
default:
|
||||
@ -442,64 +467,62 @@ void MemoryMapView::refreshMap()
|
||||
}
|
||||
|
||||
// Information
|
||||
auto content = QString((memoryMap.page)[i].info);
|
||||
setCellContent(i, ColPageInfo, content);
|
||||
auto info = memoryMap.page[i].info;
|
||||
setCellContent(i, ColPageInfo, info);
|
||||
|
||||
// Content, TODO: proper section content analysis in dbg/memory.cpp:MemUpdateMap
|
||||
QString content;
|
||||
char comment_text[MAX_COMMENT_SIZE];
|
||||
if(DbgFunctions()->GetUserComment((duint)mbi.BaseAddress, comment_text)) // user comment present
|
||||
content = comment_text;
|
||||
else if(content.contains(".bss"))
|
||||
else if(strncmp(info, ".bss", 4) == 0)
|
||||
content = tr("Uninitialized data");
|
||||
else if(content.contains(".data"))
|
||||
else if(strncmp(info, ".data", 5) == 0)
|
||||
content = tr("Initialized data");
|
||||
else if(content.contains(".edata"))
|
||||
else if(strncmp(info, ".edata", 6) == 0)
|
||||
content = tr("Export tables");
|
||||
else if(content.contains(".idata"))
|
||||
else if(strncmp(info, ".idata", 6) == 0)
|
||||
content = tr("Import tables");
|
||||
else if(content.contains(".pdata"))
|
||||
else if(strncmp(info, ".pdata", 6) == 0)
|
||||
content = tr("Exception information");
|
||||
else if(content.contains(".rdata"))
|
||||
else if(strncmp(info, ".rdata", 6) == 0)
|
||||
content = tr("Read-only initialized data");
|
||||
else if(content.contains(".reloc"))
|
||||
else if(strncmp(info, ".reloc", 6) == 0)
|
||||
content = tr("Base relocations");
|
||||
else if(content.contains(".rsrc"))
|
||||
else if(strncmp(info, ".rsrc", 5) == 0)
|
||||
content = tr("Resources");
|
||||
else if(content.contains(".text"))
|
||||
else if(strncmp(info, ".text", 5) == 0)
|
||||
content = tr("Executable code");
|
||||
else if(content.contains(".tls"))
|
||||
else if(strncmp(info, ".tls", 4) == 0)
|
||||
content = tr("Thread-local storage");
|
||||
else if(content.contains(".xdata"))
|
||||
else if(strncmp(info, ".xdata", 6) == 0)
|
||||
content = tr("Exception information");
|
||||
else
|
||||
content = QString("");
|
||||
setCellContent(i, ColContent, std::move(content));
|
||||
|
||||
// Type
|
||||
const char* type = "";
|
||||
QString type;
|
||||
switch(mbi.Type)
|
||||
{
|
||||
case MEM_IMAGE:
|
||||
type = "IMG";
|
||||
type = QStringLiteral("IMG");
|
||||
break;
|
||||
case MEM_MAPPED:
|
||||
type = "MAP";
|
||||
type = QStringLiteral("MAP");
|
||||
break;
|
||||
case MEM_PRIVATE:
|
||||
type = "PRV";
|
||||
type = QStringLiteral("PRV");
|
||||
break;
|
||||
default:
|
||||
type = "N/A";
|
||||
type = QStringLiteral("N/A");
|
||||
break;
|
||||
}
|
||||
setCellContent(i, ColAllocation, type);
|
||||
setCellContent(i, ColAllocation, std::move(type));
|
||||
|
||||
// current access protection
|
||||
setCellContent(i, ColCurProtect, getProtectionString(mbi.Protect));
|
||||
|
||||
// allocation protection
|
||||
setCellContent(i, ColAllocProtect, getProtectionString(mbi.AllocationProtect));
|
||||
|
||||
}
|
||||
if(memoryMap.page != 0)
|
||||
BridgeFree(memoryMap.page);
|
||||
@ -509,7 +532,7 @@ void MemoryMapView::refreshMap()
|
||||
void MemoryMapView::stateChangedSlot(DBGSTATE state)
|
||||
{
|
||||
if(state == paused)
|
||||
refreshMap();
|
||||
refreshMapSlot();
|
||||
}
|
||||
|
||||
void MemoryMapView::followDumpSlot()
|
||||
@ -554,16 +577,16 @@ void MemoryMapView::memoryExecuteSingleshootToggleSlot()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::pageMemoryRights()
|
||||
void MemoryMapView::pageMemoryRightsSlot()
|
||||
{
|
||||
PageMemoryRights PageMemoryRightsDialog(this);
|
||||
connect(&PageMemoryRightsDialog, SIGNAL(refreshMemoryMap()), this, SLOT(refreshMap()));
|
||||
connect(&PageMemoryRightsDialog, SIGNAL(refreshMemoryMap()), this, SLOT(refreshMapSlot()));
|
||||
duint addr = getSelectionAddr();
|
||||
duint size = getCellUserdata(getInitialSelection(), ColSize);
|
||||
PageMemoryRightsDialog.RunAddrSize(addr, size, getCellContent(getInitialSelection(), ColCurProtect));
|
||||
}
|
||||
|
||||
void MemoryMapView::switchView()
|
||||
void MemoryMapView::switchViewSlot()
|
||||
{
|
||||
Config()->setBool("Engine", "ListAllPages", !ConfigBool("Engine", "ListAllPages"));
|
||||
Config()->writeBools();
|
||||
@ -632,7 +655,7 @@ void MemoryMapView::findPatternSlot()
|
||||
emit showReferences();
|
||||
}
|
||||
|
||||
void MemoryMapView::dumpMemory()
|
||||
void MemoryMapView::dumpMemorySlot()
|
||||
{
|
||||
duint start = 0;
|
||||
duint end = 0;
|
||||
@ -665,7 +688,7 @@ void MemoryMapView::dumpMemory()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::loadMemory()
|
||||
void MemoryMapView::loadMemorySlot()
|
||||
{
|
||||
auto modname = mainModuleName();
|
||||
if(!modname.isEmpty())
|
||||
@ -682,7 +705,7 @@ void MemoryMapView::loadMemory()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMapView::selectAddress(duint va)
|
||||
void MemoryMapView::selectAddressSlot(duint va)
|
||||
{
|
||||
auto base = DbgMemFindBaseAddr(va, nullptr);
|
||||
if(base)
|
||||
@ -703,7 +726,7 @@ void MemoryMapView::selectAddress(duint va)
|
||||
|
||||
void MemoryMapView::gotoOriginSlot()
|
||||
{
|
||||
selectAddress(mCipBase);
|
||||
selectAddressSlot(mCipBase);
|
||||
}
|
||||
|
||||
void MemoryMapView::gotoExpressionSlot()
|
||||
@ -714,7 +737,7 @@ void MemoryMapView::gotoExpressionSlot()
|
||||
mGoto->setInitialExpression(ToPtrString(getSelectionAddr()));
|
||||
if(mGoto->exec() == QDialog::Accepted)
|
||||
{
|
||||
selectAddress(DbgValFromString(mGoto->expressionText.toUtf8().constData()));
|
||||
selectAddressSlot(DbgValFromString(mGoto->expressionText.toUtf8().constData()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,16 +24,16 @@ public slots:
|
||||
void doubleClickedSlot();
|
||||
void memoryExecuteSingleshootToggleSlot();
|
||||
void memoryAllocateSlot();
|
||||
void ExecCommand();
|
||||
void execCommandSlot();
|
||||
void contextMenuSlot(const QPoint & pos);
|
||||
void switchView();
|
||||
void pageMemoryRights();
|
||||
void refreshMap();
|
||||
void switchViewSlot();
|
||||
void pageMemoryRightsSlot();
|
||||
void refreshMapSlot();
|
||||
void findPatternSlot();
|
||||
void dumpMemory();
|
||||
void loadMemory();
|
||||
void dumpMemorySlot();
|
||||
void loadMemorySlot();
|
||||
void commentSlot();
|
||||
void selectAddress(duint va);
|
||||
void selectAddressSlot(duint va);
|
||||
void gotoOriginSlot();
|
||||
void gotoExpressionSlot();
|
||||
void addVirtualModSlot();
|
||||
|
@ -55,24 +55,27 @@ void PageMemoryRights::RunAddrSize(duint addrin, duint sizein, QString pagetypei
|
||||
|
||||
void PageMemoryRights::on_btnSelectall_clicked()
|
||||
{
|
||||
for(int i = 0; i < ui->pagetableWidget->rowCount(); i++)
|
||||
{
|
||||
for(int j = 0; j < ui->pagetableWidget->columnCount(); j++)
|
||||
{
|
||||
QModelIndex idx = (ui->pagetableWidget->model()->index(i, j));
|
||||
ui->pagetableWidget->selectionModel()->select(idx, QItemSelectionModel::Select);
|
||||
}
|
||||
}
|
||||
const auto rowCount = ui->pagetableWidget->rowCount();
|
||||
const auto columnCount = ui->pagetableWidget->columnCount();
|
||||
|
||||
QModelIndex topLeft = ui->pagetableWidget->model()->index(0, 0);
|
||||
QModelIndex bottomRight = ui->pagetableWidget->model()->index(rowCount - 1, columnCount - 1);
|
||||
|
||||
QItemSelection selection(topLeft, bottomRight);
|
||||
ui->pagetableWidget->selectionModel()->select(selection, QItemSelectionModel::Select);
|
||||
}
|
||||
|
||||
void PageMemoryRights::on_btnDeselectall_clicked()
|
||||
{
|
||||
QModelIndexList indexList = ui->pagetableWidget->selectionModel()->selectedIndexes();
|
||||
foreach(QModelIndex index, indexList)
|
||||
{
|
||||
ui->pagetableWidget->selectionModel()->select(index, QItemSelectionModel::Deselect);
|
||||
QModelIndexList selectedIndexes = ui->pagetableWidget->selectionModel()->selectedIndexes();
|
||||
if(selectedIndexes.isEmpty())
|
||||
return;
|
||||
|
||||
}
|
||||
QModelIndex topLeft = selectedIndexes.first();
|
||||
QModelIndex bottomRight = selectedIndexes.last();
|
||||
|
||||
QItemSelection selection(topLeft, bottomRight);
|
||||
ui->pagetableWidget->selectionModel()->select(selection, QItemSelectionModel::Deselect);
|
||||
}
|
||||
|
||||
void PageMemoryRights::on_btnSetrights_clicked()
|
||||
|
@ -123,7 +123,7 @@ QAction* ThreadView::makeCommandAction(QAction* action, const QString & command)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ThreadView::ExecCommand execute command slot for menus. Only used by command that reference thread id.
|
||||
* @brief ThreadView::execCommandSlot execute command slot for menus. Only used by command that reference thread id.
|
||||
*/
|
||||
void ThreadView::execCommandSlot()
|
||||
{
|
||||
|
@ -295,6 +295,7 @@ QString DbgCmdEscape(QString argument)
|
||||
{
|
||||
// TODO: implement this properly
|
||||
argument.replace("\"", "\\\"");
|
||||
argument.replace("{", "\\{");
|
||||
|
||||
return argument;
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ inline QString ToPtrString(duint Address)
|
||||
|
||||
char temp[32];
|
||||
#ifdef _WIN64
|
||||
sprintf_s(temp, "%016llX", Address);
|
||||
auto size = sprintf_s(temp, "%016llX", Address);
|
||||
#else
|
||||
sprintf_s(temp, "%08X", Address);
|
||||
auto size = sprintf_s(temp, "%08X", Address);
|
||||
#endif // _WIN64
|
||||
return QString(temp);
|
||||
return QString::fromLatin1(temp, size);
|
||||
}
|
||||
|
||||
inline QString ToLongLongHexString(unsigned long long Value)
|
||||
|
@ -190,6 +190,7 @@ int main(int argc, char* argv[])
|
||||
qRegisterMetaType<duint>("duint");
|
||||
qRegisterMetaType<byte_t>("byte_t");
|
||||
qRegisterMetaType<DBGSTATE>("DBGSTATE");
|
||||
qRegisterMetaType<GUIMSG>("GUIMSG");
|
||||
|
||||
// Set QString codec to UTF-8
|
||||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||
@ -207,7 +208,7 @@ int main(int argc, char* argv[])
|
||||
mainWindow->show();
|
||||
|
||||
// Set some data
|
||||
Bridge::getBridge()->winId = (void*)mainWindow->winId();
|
||||
Bridge::getBridge()->mWinId = (void*)mainWindow->winId();
|
||||
|
||||
// Init debugger
|
||||
const char* errormsg = DbgInit();
|
||||
|
Loading…
Reference in New Issue
Block a user