Improved attach dialog and messages bps (#1589)
* Some minor cpu info box enhancements * Switch to xrefs in InfoBox and some XrefBrowseDialog improvements * Added search boxes and saving symbols splitters and columns layout * Using .toULongLong for both platforms * casting added * Added option rva addresses in graph * Improved attach dialog and messages bps
This commit is contained in:
parent
5a19b434d4
commit
24972c0278
|
@ -169,7 +169,8 @@ bool _getprocesslist(DBGPROCESSINFO** entries, int* count)
|
|||
{
|
||||
std::vector<PROCESSENTRY32> infoList;
|
||||
std::vector<std::string> commandList;
|
||||
if(!dbglistprocesses(&infoList, &commandList))
|
||||
std::vector<std::string> winTextList;
|
||||
if(!dbglistprocesses(&infoList, &commandList, &winTextList))
|
||||
return false;
|
||||
*count = (int)infoList.size();
|
||||
if(!*count)
|
||||
|
@ -179,6 +180,7 @@ bool _getprocesslist(DBGPROCESSINFO** entries, int* count)
|
|||
{
|
||||
(*entries)[*count - i - 1].dwProcessId = infoList.at(i).th32ProcessID;
|
||||
strncpy_s((*entries)[*count - i - 1].szExeFile, infoList.at(i).szExeFile, _TRUNCATE);
|
||||
strncpy_s((*entries)[*count - i - 1].szExeMainWindowTitle, winTextList.at(i).c_str(), _TRUNCATE);
|
||||
strncpy_s((*entries)[*count - i - 1].szExeArgs, commandList.at(i).c_str(), _TRUNCATE);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct
|
|||
{
|
||||
DWORD dwProcessId;
|
||||
char szExeFile[MAX_PATH];
|
||||
char szExeMainWindowTitle[MAX_PATH];
|
||||
char szExeArgs[MAX_COMMAND_LINE_SIZE];
|
||||
} DBGPROCESSINFO;
|
||||
|
||||
|
|
|
@ -271,6 +271,7 @@ bool bVerboseExceptionLogging = true;
|
|||
bool bNoWow64SingleStepWorkaround = false;
|
||||
duint DbgEvents = 0;
|
||||
duint maxSkipExceptionCount = 10000;
|
||||
HANDLE mProcHandle;
|
||||
|
||||
static duint dbgcleartracestate()
|
||||
{
|
||||
|
@ -2147,7 +2148,46 @@ cmdline_qoutes_placement_t getqoutesplacement(const char* cmdline)
|
|||
return quotesPos;
|
||||
}
|
||||
|
||||
bool dbglistprocesses(std::vector<PROCESSENTRY32>* infoList, std::vector<std::string>* commandList)
|
||||
BOOL CALLBACK chkWindowPidCallback(HWND hWnd, LPARAM lParam)
|
||||
{
|
||||
DWORD procId = (DWORD)lParam;
|
||||
DWORD hwndPid = 0;
|
||||
GetWindowThreadProcessId(hWnd, &hwndPid);
|
||||
if(hwndPid == procId)
|
||||
{
|
||||
mProcHandle = hWnd;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool dbggetwintext(std::vector<std::string>* winTextList, const DWORD dwProcessId)
|
||||
{
|
||||
mProcHandle = NULL;
|
||||
EnumWindows(chkWindowPidCallback, dwProcessId);
|
||||
if(mProcHandle)
|
||||
{
|
||||
wchar_t limitedbuffer[256];
|
||||
limitedbuffer[255] = 0;
|
||||
GetWindowTextW((HWND)mProcHandle, limitedbuffer, 256);
|
||||
if(limitedbuffer[255] != 0) //Window title too long. Add "..." to the end of buffer.
|
||||
{
|
||||
if(limitedbuffer[252] < 0xDC00 || limitedbuffer[252] > 0xDFFF) //protect the last surrogate of UTF-16 surrogate pair
|
||||
limitedbuffer[252] = L'.';
|
||||
limitedbuffer[253] = L'.';
|
||||
limitedbuffer[254] = L'.';
|
||||
limitedbuffer[255] = 0;
|
||||
}
|
||||
auto UTF8WindowTitle = StringUtils::Utf16ToUtf8(limitedbuffer);
|
||||
winTextList->push_back(UTF8WindowTitle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dbglistprocesses(std::vector<PROCESSENTRY32>* infoList, std::vector<std::string>* commandList, std::vector<std::string>* winTextList)
|
||||
{
|
||||
infoList->clear();
|
||||
Handle hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
|
@ -2178,6 +2218,9 @@ bool dbglistprocesses(std::vector<PROCESSENTRY32>* infoList, std::vector<std::st
|
|||
//
|
||||
char* cmdline;
|
||||
|
||||
if(!dbggetwintext(winTextList, pe32.th32ProcessID))
|
||||
winTextList->push_back("");
|
||||
|
||||
if(!dbggetcmdline(&cmdline, NULL, hProcess))
|
||||
commandList->push_back("ARG_GET_ERROR");
|
||||
else
|
||||
|
|
|
@ -60,7 +60,7 @@ void dbgaddignoredexception(ExceptionRange range);
|
|||
bool dbgisignoredexception(unsigned int exception);
|
||||
bool dbgcmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly);
|
||||
bool dbgcmddel(const char* name);
|
||||
bool dbglistprocesses(std::vector<PROCESSENTRY32>* infoList, std::vector<std::string>* commandList);
|
||||
bool dbglistprocesses(std::vector<PROCESSENTRY32>* infoList, std::vector<std::string>* commandList, std::vector<std::string>* winTextList);
|
||||
bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error);
|
||||
bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error, HANDLE hProcess = NULL);
|
||||
cmdline_qoutes_placement_t getqoutesplacement(const char* cmdline);
|
||||
|
@ -76,6 +76,7 @@ bool dbgsettracelogfile(const char* fileName);
|
|||
void dbgsetdebuggeeinitscript(const char* fileName);
|
||||
const char* dbggetdebuggeeinitscript();
|
||||
void dbgsetforeground();
|
||||
bool dbggetwintext(std::vector<std::string>* winTextList, const DWORD dwProcessId);
|
||||
|
||||
void cbStep();
|
||||
void cbRtrStep();
|
||||
|
@ -101,6 +102,7 @@ EXCEPTION_DEBUG_INFO & getLastExceptionInfo();
|
|||
bool dbgrestartadmin();
|
||||
void StepIntoWow64(void* traceCallBack);
|
||||
bool dbgisdepenabled();
|
||||
BOOL CALLBACK chkWindowPidCallback(HWND hWnd, LPARAM lParam);
|
||||
|
||||
//variables
|
||||
extern PROCESS_INFORMATION* fdProcessInfo;
|
||||
|
@ -118,5 +120,6 @@ extern bool bNoForegroundWindow;
|
|||
extern bool bVerboseExceptionLogging;
|
||||
extern bool bNoWow64SingleStepWorkaround;
|
||||
extern duint maxSkipExceptionCount;
|
||||
extern HANDLE mProcHandle;
|
||||
|
||||
#endif // _DEBUGGER_H
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "SearchListView.h"
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
|
||||
AttachDialog::AttachDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AttachDialog)
|
||||
{
|
||||
|
@ -32,12 +33,16 @@ AttachDialog::AttachDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Attach
|
|||
//setup process list
|
||||
int charwidth = mSearchListView->mList->getCharWidth();
|
||||
mSearchListView->mList->addColumnAt(charwidth * sizeof(int) * 2 + 8, tr("PID"), true);
|
||||
mSearchListView->mList->addColumnAt(150, tr("Name"), true);
|
||||
mSearchListView->mList->addColumnAt(300, tr("Title"), true);
|
||||
mSearchListView->mList->addColumnAt(500, tr("Path"), true);
|
||||
mSearchListView->mList->addColumnAt(800, tr("Command Line Arguments"), true);
|
||||
mSearchListView->mList->setDrawDebugOnly(false);
|
||||
|
||||
charwidth = mSearchListView->mSearchList->getCharWidth();
|
||||
mSearchListView->mSearchList->addColumnAt(charwidth * sizeof(int) * 2 + 8, tr("PID"), true);
|
||||
mSearchListView->mSearchList->addColumnAt(150, tr("Name"), true);
|
||||
mSearchListView->mSearchList->addColumnAt(300, tr("Title"), true);
|
||||
mSearchListView->mSearchList->addColumnAt(500, tr("Path"), true);
|
||||
mSearchListView->mSearchList->addColumnAt(800, tr("Command Line Arguments"), true);
|
||||
mSearchListView->mSearchList->setDrawDebugOnly(false);
|
||||
|
@ -71,9 +76,12 @@ void AttachDialog::refresh()
|
|||
mSearchListView->mList->setRowCount(count);
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
QFileInfo fi(entries[i].szExeFile);
|
||||
mSearchListView->mList->setCellContent(i, 0, QString().sprintf(ConfigBool("Gui", "PidInHex") ? "%.8X" : "%u", entries[i].dwProcessId));
|
||||
mSearchListView->mList->setCellContent(i, 1, QString(entries[i].szExeFile));
|
||||
mSearchListView->mList->setCellContent(i, 2, QString(entries[i].szExeArgs));
|
||||
mSearchListView->mList->setCellContent(i, 1, fi.baseName());
|
||||
mSearchListView->mList->setCellContent(i, 2, QString(entries[i].szExeMainWindowTitle));
|
||||
mSearchListView->mList->setCellContent(i, 3, QString(entries[i].szExeFile));
|
||||
mSearchListView->mList->setCellContent(i, 4, QString(entries[i].szExeArgs));
|
||||
}
|
||||
mSearchListView->mList->setSingleSelection(0);
|
||||
mSearchListView->mList->reloadData();
|
||||
|
|
|
@ -128,7 +128,7 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
|
|||
connect(mActionFollowProc, SIGNAL(triggered()), this, SLOT(followInDisasmSlot()));
|
||||
mActionToggleProcBP = new QAction(DIcon("breakpoint_toggle.png"), tr("Toggle Breakpoint in Proc"), this);
|
||||
connect(mActionToggleProcBP, SIGNAL(triggered()), this, SLOT(toggleBPSlot()));
|
||||
mActionMessageProcBP = new QAction(DIcon("breakpoint_execute.png"), tr("Message Breakpoint in Proc"), this);
|
||||
mActionMessageProcBP = new QAction(DIcon("breakpoint_execute.png"), tr("Message Breakpoint"), this);
|
||||
connect(mActionMessageProcBP, SIGNAL(triggered()), this, SLOT(messagesBPSlot()));
|
||||
|
||||
connect(mHandlesTable, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(handlesTableContextMenuSlot(QMenu*)));
|
||||
|
|
|
@ -51,6 +51,8 @@ void MessagesBreakpoints::on_btnOk_clicked()
|
|||
{
|
||||
duint procVA;
|
||||
duint wndHandle;
|
||||
QString bpCondCmd;
|
||||
bool translMsg = ui->chkTranslateMessage->isChecked();
|
||||
|
||||
if(!DbgFunctions()->ValFromString(bpData.wndHandle.toUtf8().constData(), &wndHandle) ||
|
||||
!DbgFunctions()->ValFromString(bpData.procVA.toUtf8().constData(), &procVA))
|
||||
|
@ -59,11 +61,29 @@ void MessagesBreakpoints::on_btnOk_clicked()
|
|||
if(!DbgMemIsValidReadPtr(procVA) || !IsWindow((HWND)wndHandle))
|
||||
return;
|
||||
|
||||
BPXTYPE wBpType = DbgGetBpxTypeAt(procVA);
|
||||
if(wBpType == bp_none)
|
||||
DbgCmdExec(QString("bp 0x%1").arg(bpData.procVA).toUtf8().constData());
|
||||
if(!translMsg)
|
||||
{
|
||||
BPXTYPE wBpType = DbgGetBpxTypeAt(procVA);
|
||||
if(wBpType == bp_none)
|
||||
DbgCmdExec(QString("bp 0x%1").arg(bpData.procVA).toUtf8().constData());
|
||||
|
||||
bpCondCmd = QString("bpcnd 0x%1, \"arg.get(1) == 0x%2").arg(bpData.procVA).arg(messages.key(ui->cboxMessages->currentText()), 1, 16);
|
||||
bpCondCmd.append(ui->rbtnBreakCurrent->isChecked() ? QString(" && arg.get(0) == 0x%1\"").arg(bpData.wndHandle) : "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
BPXTYPE wBpType = DbgGetBpxTypeAt(DbgValFromString("TranslateMessage"));
|
||||
if(wBpType == bp_none)
|
||||
DbgCmdExec("bp TranslateMessage");
|
||||
|
||||
#ifdef _WIN64
|
||||
bpCondCmd = QString("bpcnd TranslateMessage, \"4:[arg.get(0)+8] == 0x%1").arg(messages.key(ui->cboxMessages->currentText()), 1, 16);
|
||||
bpCondCmd.append(ui->rbtnBreakCurrent->isChecked() ? QString(" && 4:[arg.get(0)] == 0x%1\"").arg(bpData.wndHandle) : "\"");
|
||||
#else //x86
|
||||
bpCondCmd = QString("bpcnd TranslateMessage, \"[arg.get(0)+4] == 0x%1").arg(messages.key(ui->cboxMessages->currentText()), 1, 16);
|
||||
bpCondCmd.append(ui->rbtnBreakCurrent->isChecked() ? QString(" && [arg.get(0)] == 0x%1\"").arg(bpData.wndHandle) : "\"");
|
||||
#endif //_WIN64
|
||||
}
|
||||
|
||||
QString bpCondCmd = QString("bpcnd 0x%1, \"arg.get(1) == 0x%2").arg(bpData.procVA).arg(messages.key(ui->cboxMessages->currentText()), 1, 16);
|
||||
bpCondCmd.append(ui->rbtnBreakCurrent->isChecked() ? QString(" && arg.get(0) == 0x%1\"").arg(bpData.wndHandle) : "\"");
|
||||
DbgCmdExec(bpCondCmd.toUtf8().constData());
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>301</width>
|
||||
<height>183</height>
|
||||
<width>289</width>
|
||||
<height>214</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Message Breakpoint on WinProc</string>
|
||||
<string>Message Breakpoint</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../../resource.qrc">
|
||||
|
@ -29,7 +29,7 @@
|
|||
<widget class="QLabel" name="lblMessages">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>22</x>
|
||||
<x>16</x>
|
||||
<y>16</y>
|
||||
<width>51</width>
|
||||
<height>16</height>
|
||||
|
@ -42,10 +42,10 @@
|
|||
<widget class="QGroupBox" name="gboxBreakpoints">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<x>14</x>
|
||||
<y>50</y>
|
||||
<width>261</width>
|
||||
<height>91</height>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
|
@ -54,7 +54,7 @@
|
|||
<widget class="QRadioButton" name="rbtnBreakAny">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<x>14</x>
|
||||
<y>20</y>
|
||||
<width>221</width>
|
||||
<height>17</height>
|
||||
|
@ -70,7 +70,7 @@
|
|||
<widget class="QRadioButton" name="rbtnBreakCurrent">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<x>14</x>
|
||||
<y>40</y>
|
||||
<width>221</width>
|
||||
<height>31</height>
|
||||
|
@ -81,12 +81,25 @@
|
|||
(Invalid for next session)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="chkTranslateMessage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>14</x>
|
||||
<y>90</y>
|
||||
<width>221</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use TranslateMessage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btnOk">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>150</y>
|
||||
<x>114</x>
|
||||
<y>180</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
@ -98,7 +111,7 @@
|
|||
<widget class="QComboBox" name="cboxMessages">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<x>74</x>
|
||||
<y>16</y>
|
||||
<width>201</width>
|
||||
<height>20</height>
|
||||
|
@ -111,8 +124,8 @@
|
|||
<widget class="QPushButton" name="btnCancel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>206</x>
|
||||
<y>150</y>
|
||||
<x>200</x>
|
||||
<y>180</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
|
|
@ -28,7 +28,7 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
|
|||
|
||||
// Create module list
|
||||
mModuleList = new SearchListView(true, this);
|
||||
mModuleList->mSearchStartCol = 1;
|
||||
mModuleList->mSearchStartCol = 0;
|
||||
int charwidth = mModuleList->mList->getCharWidth();
|
||||
mModuleList->mList->enableMultiSelection(true);
|
||||
mModuleList->mList->setCipBase(true);
|
||||
|
|
Loading…
Reference in New Issue