mirror of
https://github.com/x64dbg/x64dbg.git
synced 2024-11-27 06:40:24 +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();
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP duint DbgGetTimeWastedCounter()
|
||||
{
|
||||
return _dbg_sendmessage(DBG_GET_TIME_WASTED_COUNTER, nullptr, nullptr);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint 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);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter()
|
||||
{
|
||||
_gui_sendmessage(GUI_UPDATE_TIME_WASTED_COUNTER, nullptr, nullptr);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
hInst = hinstDLL;
|
||||
|
@ -174,7 +174,8 @@ typedef enum
|
||||
DBG_WIN_EVENT, // param1=MSG* message, param2=long* result
|
||||
DBG_WIN_EVENT_GLOBAL, // param1=MSG* message, 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;
|
||||
|
||||
typedef enum
|
||||
@ -691,6 +692,7 @@ BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions();
|
||||
BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result);
|
||||
BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message);
|
||||
BRIDGE_IMPEXP bool DbgIsRunning();
|
||||
BRIDGE_IMPEXP duint DbgGetTimeWastedCounter();
|
||||
|
||||
//Gui defines
|
||||
#define GUI_PLUGIN_MENU 0
|
||||
@ -772,7 +774,8 @@ typedef enum
|
||||
GUI_ADD_QWIDGET_TAB, // param1=QWidget*, param2=unused
|
||||
GUI_SHOW_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;
|
||||
|
||||
//GUI Typedefs
|
||||
@ -866,6 +869,7 @@ BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget);
|
||||
BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget);
|
||||
BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget);
|
||||
BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread);
|
||||
BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1006,6 +1006,9 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
||||
SectionLockerGlobal::Deinitialize();
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_GET_TIME_WASTED_COUNTER:
|
||||
return dbggettimewastedcounter();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -39,7 +39,10 @@ static HANDLE hEvent = 0;
|
||||
static HANDLE hProcess = 0;
|
||||
static HANDLE hMemMapThread = 0;
|
||||
static bool bStopMemMapThread = false;
|
||||
static HANDLE hTimeWastedCounterThread = 0;
|
||||
static bool bStopTimeWastedCounterThread = false;
|
||||
static String lastDebugText;
|
||||
static uint timeWastedDebugging = 0;
|
||||
char szFileName[MAX_PATH] = "";
|
||||
char szSymbolCachePath[MAX_PATH] = "";
|
||||
char sqlitedb[deflen] = "";
|
||||
@ -72,17 +75,43 @@ static DWORD WINAPI memMapThread(void* ptr)
|
||||
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()
|
||||
{
|
||||
ExceptionCodeInit();
|
||||
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()
|
||||
{
|
||||
bStopMemMapThread = true;
|
||||
bStopTimeWastedCounterThread = true;
|
||||
WaitForThreadTermination(hMemMapThread);
|
||||
WaitForThreadTermination(hTimeWastedCounterThread);
|
||||
}
|
||||
|
||||
SIZE_T dbggetprivateusage(HANDLE hProcess, bool update)
|
||||
@ -101,6 +130,11 @@ uint dbgdebuggedbase()
|
||||
return pDebuggedBase;
|
||||
}
|
||||
|
||||
uint dbggettimewastedcounter()
|
||||
{
|
||||
return timeWastedDebugging;
|
||||
}
|
||||
|
||||
bool dbgisrunning()
|
||||
{
|
||||
return !waitislocked(WAITID_RUN);
|
||||
@ -675,11 +709,20 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
||||
else
|
||||
{
|
||||
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE);
|
||||
int invalidCount = 0;
|
||||
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
||||
{
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + pDebuggedBase, i + 1);
|
||||
cmddirectexec(dbggetcommandlist(), command);
|
||||
uint callbackVA = TLSCallBacks()[i] - ImageBase + pDebuggedBase;
|
||||
if (MemIsValidReadPtr(callbackVA))
|
||||
{
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
|
||||
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
|
||||
{
|
||||
uint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE);
|
||||
int invalidCount = 0;
|
||||
for(unsigned int i = 0; i < NumberOfCallBacks; i++)
|
||||
{
|
||||
if(bIsDebuggingThis)
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1);
|
||||
uint callbackVA = TLSCallBacks()[i] - ImageBase + (uint)base;
|
||||
if (MemIsValidReadPtr(callbackVA))
|
||||
{
|
||||
if (bIsDebuggingThis)
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d\",ss", callbackVA, i + 1);
|
||||
else
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", callbackVA, i + 1, modname);
|
||||
cmddirectexec(dbggetcommandlist(), command);
|
||||
}
|
||||
else
|
||||
sprintf(command, "bp "fhex",\"TLS Callback %d (%s)\",ss", TLSCallBacks()[i] - ImageBase + (uint)base, i + 1, modname);
|
||||
cmddirectexec(dbggetcommandlist(), command);
|
||||
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 dbgstop();
|
||||
uint dbgdebuggedbase();
|
||||
uint dbggettimewastedcounter();
|
||||
bool dbgisrunning();
|
||||
bool dbgisdll();
|
||||
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());
|
||||
emit executeOnGuiThread(param1);
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_TIME_WASTED_COUNTER:
|
||||
emit updateTimeWastedCounter();
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ signals:
|
||||
void showQWidgetTab(QWidget* qWidget);
|
||||
void closeQWidgetTab(QWidget* qWidget);
|
||||
void executeOnGuiThread(void* cbGuiThread);
|
||||
void updateTimeWastedCounter();
|
||||
|
||||
private:
|
||||
QMutex* mBridgeMutex;
|
||||
|
@ -12,11 +12,23 @@
|
||||
#include "ShortcutsDialog.h"
|
||||
#include "AttachDialog.h"
|
||||
#include "LineEditDialog.h"
|
||||
#include "TimeWastedCounter.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
{
|
||||
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
|
||||
connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(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/SourceView.cpp \
|
||||
Src/Utils/ValidateExpressionThread.cpp \
|
||||
Src/Utils/MainWindowCloseThread.cpp
|
||||
Src/Utils/MainWindowCloseThread.cpp \
|
||||
Src/Gui/TimeWastedCounter.cpp
|
||||
|
||||
|
||||
HEADERS += \
|
||||
@ -164,7 +165,8 @@ HEADERS += \
|
||||
Src/Gui/SourceView.h \
|
||||
Src/Utils/StringUtil.h \
|
||||
Src/Utils/ValidateExpressionThread.h \
|
||||
Src/Utils/MainWindowCloseThread.h
|
||||
Src/Utils/MainWindowCloseThread.h \
|
||||
Src/Gui/TimeWastedCounter.h
|
||||
|
||||
|
||||
INCLUDEPATH += \
|
||||
|
Loading…
Reference in New Issue
Block a user