1
0
Fork 0

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:
ThunderCls 2017-05-15 17:35:15 -04:00 committed by Duncan Ogilvie
parent 5a19b434d4
commit 24972c0278
9 changed files with 115 additions and 25 deletions

View File

@ -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;

View File

@ -43,6 +43,7 @@ typedef struct
{
DWORD dwProcessId;
char szExeFile[MAX_PATH];
char szExeMainWindowTitle[MAX_PATH];
char szExeArgs[MAX_COMMAND_LINE_SIZE];
} DBGPROCESSINFO;

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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*)));

View File

@ -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());
}

View File

@ -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>

View File

@ -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);