mirror of
https://github.com/x64dbg/x64dbg.git
synced 2024-11-23 13:00:14 +00:00
DBG + GUI: don't try to set breakpoints on invalid TLS callbacks + added time wasted counter + added version number in menu bar
This commit is contained in:
parent
f0565fb57b
commit
61fa77d3ac
@ -805,6 +805,11 @@ BRIDGE_IMPEXP bool DbgIsRunning()
|
|||||||
return !DbgIsRunLocked();
|
return !DbgIsRunLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BRIDGE_IMPEXP duint DbgGetTimeWastedCounter()
|
||||||
|
{
|
||||||
|
return _dbg_sendmessage(DBG_GET_TIME_WASTED_COUNTER, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
|
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip)
|
||||||
{
|
{
|
||||||
_gui_sendmessage(GUI_DISASSEMBLE_AT, (void*)addr, (void*)cip);
|
_gui_sendmessage(GUI_DISASSEMBLE_AT, (void*)addr, (void*)cip);
|
||||||
@ -1195,6 +1200,11 @@ BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread)
|
|||||||
_gui_sendmessage(GUI_EXECUTE_ON_GUI_THREAD, cbGuiThread, nullptr);
|
_gui_sendmessage(GUI_EXECUTE_ON_GUI_THREAD, cbGuiThread, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter()
|
||||||
|
{
|
||||||
|
_gui_sendmessage(GUI_UPDATE_TIME_WASTED_COUNTER, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
{
|
{
|
||||||
hInst = hinstDLL;
|
hInst = hinstDLL;
|
||||||
|
@ -174,7 +174,8 @@ typedef enum
|
|||||||
DBG_WIN_EVENT, // param1=MSG* message, param2=long* result
|
DBG_WIN_EVENT, // param1=MSG* message, param2=long* result
|
||||||
DBG_WIN_EVENT_GLOBAL, // param1=MSG* message, param2=unused
|
DBG_WIN_EVENT_GLOBAL, // param1=MSG* message, param2=unused
|
||||||
DBG_INITIALIZE_LOCKS, // param1=unused, param2=unused
|
DBG_INITIALIZE_LOCKS, // param1=unused, param2=unused
|
||||||
DBG_DEINITIALIZE_LOCKS // param1=unused, param2=unused
|
DBG_DEINITIALIZE_LOCKS, // param1=unused, param2=unused
|
||||||
|
DBG_GET_TIME_WASTED_COUNTER // param1=unused, param2=unused
|
||||||
} DBGMSG;
|
} DBGMSG;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -691,6 +692,7 @@ BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions();
|
|||||||
BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result);
|
BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result);
|
||||||
BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message);
|
BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message);
|
||||||
BRIDGE_IMPEXP bool DbgIsRunning();
|
BRIDGE_IMPEXP bool DbgIsRunning();
|
||||||
|
BRIDGE_IMPEXP duint DbgGetTimeWastedCounter();
|
||||||
|
|
||||||
//Gui defines
|
//Gui defines
|
||||||
#define GUI_PLUGIN_MENU 0
|
#define GUI_PLUGIN_MENU 0
|
||||||
@ -772,7 +774,8 @@ typedef enum
|
|||||||
GUI_ADD_QWIDGET_TAB, // param1=QWidget*, param2=unused
|
GUI_ADD_QWIDGET_TAB, // param1=QWidget*, param2=unused
|
||||||
GUI_SHOW_QWIDGET_TAB, // param1=QWidget*, param2=unused
|
GUI_SHOW_QWIDGET_TAB, // param1=QWidget*, param2=unused
|
||||||
GUI_CLOSE_QWIDGET_TAB, // param1=QWidget*, param2=unused
|
GUI_CLOSE_QWIDGET_TAB, // param1=QWidget*, param2=unused
|
||||||
GUI_EXECUTE_ON_GUI_THREAD // param1=GUICALLBACK, param2=unused
|
GUI_EXECUTE_ON_GUI_THREAD, // param1=GUICALLBACK, param2=unused
|
||||||
|
GUI_UPDATE_TIME_WASTED_COUNTER // param1=unused, param2=unused
|
||||||
} GUIMSG;
|
} GUIMSG;
|
||||||
|
|
||||||
//GUI Typedefs
|
//GUI Typedefs
|
||||||
@ -866,6 +869,7 @@ BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget);
|
|||||||
BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget);
|
BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget);
|
||||||
BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget);
|
BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget);
|
||||||
BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread);
|
BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread);
|
||||||
|
BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1006,6 +1006,9 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||||||
SectionLockerGlobal::Deinitialize();
|
SectionLockerGlobal::Deinitialize();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DBG_GET_TIME_WASTED_COUNTER:
|
||||||
|
return dbggettimewastedcounter();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,10 @@ static HANDLE hEvent = 0;
|
|||||||
static HANDLE hProcess = 0;
|
static HANDLE hProcess = 0;
|
||||||
static HANDLE hMemMapThread = 0;
|
static HANDLE hMemMapThread = 0;
|
||||||
static bool bStopMemMapThread = false;
|
static bool bStopMemMapThread = false;
|
||||||
|
static HANDLE hTimeWastedCounterThread = 0;
|
||||||
|
static bool bStopTimeWastedCounterThread = false;
|
||||||
static String lastDebugText;
|
static String lastDebugText;
|
||||||
|
static uint timeWastedDebugging = 0;
|
||||||
char szFileName[MAX_PATH] = "";
|
char szFileName[MAX_PATH] = "";
|
||||||
char szSymbolCachePath[MAX_PATH] = "";
|
char szSymbolCachePath[MAX_PATH] = "";
|
||||||
char sqlitedb[deflen] = "";
|
char sqlitedb[deflen] = "";
|
||||||
@ -72,17 +75,43 @@ static DWORD WINAPI memMapThread(void* ptr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI timeWastedCounterThread(void* ptr)
|
||||||
|
{
|
||||||
|
if (!BridgeSettingGetUint("Engine", "TimeWastedDebugging", &timeWastedDebugging))
|
||||||
|
timeWastedDebugging = 0;
|
||||||
|
GuiUpdateTimeWastedCounter();
|
||||||
|
while (!bStopTimeWastedCounterThread)
|
||||||
|
{
|
||||||
|
while (!DbgIsDebugging())
|
||||||
|
{
|
||||||
|
if (bStopTimeWastedCounterThread)
|
||||||
|
break;
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
if (bStopTimeWastedCounterThread)
|
||||||
|
break;
|
||||||
|
timeWastedDebugging++;
|
||||||
|
GuiUpdateTimeWastedCounter();
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
BridgeSettingSetUint("Engine", "TimeWastedDebugging", timeWastedDebugging);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void dbginit()
|
void dbginit()
|
||||||
{
|
{
|
||||||
ExceptionCodeInit();
|
ExceptionCodeInit();
|
||||||
ErrorCodeInit();
|
ErrorCodeInit();
|
||||||
hMemMapThread = CreateThread(0, 0, memMapThread, 0, 0, 0);
|
hMemMapThread = CreateThread(nullptr, 0, memMapThread, nullptr, 0, nullptr);
|
||||||
|
hTimeWastedCounterThread = CreateThread(nullptr, 0, timeWastedCounterThread, nullptr, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbgstop()
|
void dbgstop()
|
||||||
{
|
{
|
||||||
bStopMemMapThread = true;
|
bStopMemMapThread = true;
|
||||||
|
bStopTimeWastedCounterThread = true;
|
||||||
WaitForThreadTermination(hMemMapThread);
|
WaitForThreadTermination(hMemMapThread);
|
||||||
|
WaitForThreadTermination(hTimeWastedCounterThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
SIZE_T dbggetprivateusage(HANDLE hProcess, bool update)
|
SIZE_T dbggetprivateusage(HANDLE hProcess, bool update)
|
||||||
@ -101,6 +130,11 @@ uint dbgdebuggedbase()
|
|||||||
return pDebuggedBase;
|
return pDebuggedBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint dbggettimewastedcounter()
|
||||||
|
{
|
||||||
|
return timeWastedDebugging;
|
||||||
|
}
|
||||||
|
|
||||||
bool dbgisrunning()
|
bool dbgisrunning()
|
||||||
{
|
{
|
||||||
return !waitislocked(WAITID_RUN);
|
return !waitislocked(WAITID_RUN);
|
||||||
@ -675,11 +709,20 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE);
|
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE);
|
||||||
|
int invalidCount = 0;
|
||||||
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
||||||
{
|
{
|
||||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + pDebuggedBase, i + 1);
|
uint callbackVA = TLSCallBacks()[i] - ImageBase + pDebuggedBase;
|
||||||
|
if (MemIsValidReadPtr(callbackVA))
|
||||||
|
{
|
||||||
|
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
|
||||||
cmddirectexec(dbggetcommandlist(), command);
|
cmddirectexec(dbggetcommandlist(), command);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
invalidCount++;
|
||||||
|
}
|
||||||
|
if (invalidCount)
|
||||||
|
dprintf("%d invalid TLS callback addresses...\n", invalidCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -871,14 +914,23 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE);
|
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE);
|
||||||
|
int invalidCount = 0;
|
||||||
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
||||||
{
|
{
|
||||||
if(bIsDebuggingThis)
|
uint callbackVA = TLSCallBacks()[i] - ImageBase + (uint)base;
|
||||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1);
|
if (MemIsValidReadPtr(callbackVA))
|
||||||
|
{
|
||||||
|
if (bIsDebuggingThis)
|
||||||
|
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
|
||||||
else
|
else
|
||||||
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1, modname);
|
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", callbackVA, i + 1, modname);
|
||||||
cmddirectexec(dbggetcommandlist(), command);
|
cmddirectexec(dbggetcommandlist(), command);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
invalidCount++;
|
||||||
|
}
|
||||||
|
if (invalidCount)
|
||||||
|
dprintf("%s invalid TLS callback addresses...\n", invalidCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,7 @@ SIZE_T dbggetprivateusage(HANDLE hProcess, bool update = false);
|
|||||||
void dbginit();
|
void dbginit();
|
||||||
void dbgstop();
|
void dbgstop();
|
||||||
uint dbgdebuggedbase();
|
uint dbgdebuggedbase();
|
||||||
|
uint dbggettimewastedcounter();
|
||||||
bool dbgisrunning();
|
bool dbgisrunning();
|
||||||
bool dbgisdll();
|
bool dbgisdll();
|
||||||
void dbgsetattachevent(HANDLE handle);
|
void dbgsetattachevent(HANDLE handle);
|
||||||
|
@ -485,6 +485,10 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||||||
GuiAddLogMessage(QString().sprintf("thread id (bridge) %X\n", GetCurrentThreadId()).toUtf8().constData());
|
GuiAddLogMessage(QString().sprintf("thread id (bridge) %X\n", GetCurrentThreadId()).toUtf8().constData());
|
||||||
emit executeOnGuiThread(param1);
|
emit executeOnGuiThread(param1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GUI_UPDATE_TIME_WASTED_COUNTER:
|
||||||
|
emit updateTimeWastedCounter();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,7 @@ signals:
|
|||||||
void showQWidgetTab(QWidget* qWidget);
|
void showQWidgetTab(QWidget* qWidget);
|
||||||
void closeQWidgetTab(QWidget* qWidget);
|
void closeQWidgetTab(QWidget* qWidget);
|
||||||
void executeOnGuiThread(void* cbGuiThread);
|
void executeOnGuiThread(void* cbGuiThread);
|
||||||
|
void updateTimeWastedCounter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMutex* mBridgeMutex;
|
QMutex* mBridgeMutex;
|
||||||
|
@ -12,11 +12,23 @@
|
|||||||
#include "ShortcutsDialog.h"
|
#include "ShortcutsDialog.h"
|
||||||
#include "AttachDialog.h"
|
#include "AttachDialog.h"
|
||||||
#include "LineEditDialog.h"
|
#include "LineEditDialog.h"
|
||||||
|
#include "TimeWastedCounter.h"
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
//build information
|
||||||
|
QString buildText = QString().sprintf("v%d, "__DATE__, BridgeGetDbgVersion());
|
||||||
|
QAction* buildInfo = new QAction(buildText, this);
|
||||||
|
buildInfo->setEnabled(false);
|
||||||
|
ui->menuBar->addAction(buildInfo);
|
||||||
|
|
||||||
|
//time wasted counter
|
||||||
|
QAction* timeWastedLabel = new QAction(this);
|
||||||
|
ui->menuBar->addAction(timeWastedLabel);
|
||||||
|
TimeWastedCounter* timeWastedCounter = new TimeWastedCounter(this, timeWastedLabel);
|
||||||
|
|
||||||
//setup bridge signals
|
//setup bridge signals
|
||||||
connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString)));
|
connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString)));
|
connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString)));
|
||||||
|
19
x64_dbg_gui/Project/Src/Gui/TimeWastedCounter.cpp
Normal file
19
x64_dbg_gui/Project/Src/Gui/TimeWastedCounter.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "TimeWastedCounter.h"
|
||||||
|
#include "Bridge.h"
|
||||||
|
|
||||||
|
TimeWastedCounter::TimeWastedCounter(QObject* parent, QAction* label)
|
||||||
|
: QObject(parent), mLabel(label)
|
||||||
|
{
|
||||||
|
mLabel->setEnabled(false);
|
||||||
|
connect(Bridge::getBridge(), SIGNAL(updateTimeWastedCounter()), this, SLOT(updateTimeWastedCounter()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeWastedCounter::updateTimeWastedCounter()
|
||||||
|
{
|
||||||
|
duint timeWasted = DbgGetTimeWastedCounter();
|
||||||
|
int days = timeWasted / (60 * 60 * 24);
|
||||||
|
int hours = (timeWasted / (60 * 60)) % 24;
|
||||||
|
int minutes = (timeWasted / 60) % 60;
|
||||||
|
int seconds = timeWasted % 60;
|
||||||
|
mLabel->setText(QString().sprintf("Time Wasted Debugging: %d:%02d:%02d:%02d", days, hours, minutes, seconds));
|
||||||
|
}
|
20
x64_dbg_gui/Project/Src/Gui/TimeWastedCounter.h
Normal file
20
x64_dbg_gui/Project/Src/Gui/TimeWastedCounter.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef TIMEWASTEDCOUNTER_H
|
||||||
|
#define TIMEWASTEDCOUNTER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
class TimeWastedCounter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TimeWastedCounter(QObject* parent, QAction* label);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateTimeWastedCounter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QAction* mLabel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMEWASTEDCOUNTER_H
|
@ -92,7 +92,8 @@ SOURCES += \
|
|||||||
Src/Gui/SourceViewerManager.cpp \
|
Src/Gui/SourceViewerManager.cpp \
|
||||||
Src/Gui/SourceView.cpp \
|
Src/Gui/SourceView.cpp \
|
||||||
Src/Utils/ValidateExpressionThread.cpp \
|
Src/Utils/ValidateExpressionThread.cpp \
|
||||||
Src/Utils/MainWindowCloseThread.cpp
|
Src/Utils/MainWindowCloseThread.cpp \
|
||||||
|
Src/Gui/TimeWastedCounter.cpp
|
||||||
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
@ -164,7 +165,8 @@ HEADERS += \
|
|||||||
Src/Gui/SourceView.h \
|
Src/Gui/SourceView.h \
|
||||||
Src/Utils/StringUtil.h \
|
Src/Utils/StringUtil.h \
|
||||||
Src/Utils/ValidateExpressionThread.h \
|
Src/Utils/ValidateExpressionThread.h \
|
||||||
Src/Utils/MainWindowCloseThread.h
|
Src/Utils/MainWindowCloseThread.h \
|
||||||
|
Src/Gui/TimeWastedCounter.h
|
||||||
|
|
||||||
|
|
||||||
INCLUDEPATH += \
|
INCLUDEPATH += \
|
||||||
|
Loading…
Reference in New Issue
Block a user