1
0
Fork 0

Added SEH Viewer to GUI

This commit is contained in:
Avin 2016-03-26 02:24:55 +05:30
parent 121b884b7d
commit fe18bd2a68
17 changed files with 230 additions and 16 deletions

View File

@ -1200,6 +1200,11 @@ BRIDGE_IMPEXP void GuiUpdateCallStack()
_gui_sendmessage(GUI_UPDATE_CALLSTACK, 0, 0);
}
BRIDGE_IMPEXP void GuiUpdateSEHChain()
{
_gui_sendmessage(GUI_UPDATE_SEHCHAIN, 0, 0);
}
BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line)
{
_gui_sendmessage(GUI_LOAD_SOURCE_FILE, (void*)path, (void*)line);
@ -1289,4 +1294,4 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
hInst = hinstDLL;
return TRUE;
}
}

View File

@ -787,6 +787,7 @@ typedef enum
GUI_REPAINT_TABLE_VIEW, // param1=unused, param2=unused
GUI_UPDATE_PATCHES, // param1=unused, param2=unused
GUI_UPDATE_CALLSTACK, // param1=unused, param2=unused
GUI_UPDATE_SEHCHAIN, // param1=unused, param2=unused
GUI_SYMBOL_REFRESH_CURRENT, // param1=unused, param2=unused
GUI_UPDATE_MEMORY_VIEW, // param1=unused, param2=unused
GUI_REF_INITIALIZE, // param1=const char* name, param2=unused
@ -902,6 +903,7 @@ BRIDGE_IMPEXP void GuiUpdateSideBar();
BRIDGE_IMPEXP void GuiRepaintTableView();
BRIDGE_IMPEXP void GuiUpdatePatches();
BRIDGE_IMPEXP void GuiUpdateCallStack();
BRIDGE_IMPEXP void GuiUpdateSEHChain();
BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line);
BRIDGE_IMPEXP void GuiMenuSetIcon(int hMenu, const ICONDATA* icon);
BRIDGE_IMPEXP void GuiMenuSetEntryIcon(int hEntry, const ICONDATA* icon);

View File

@ -15,6 +15,7 @@
#include "stackinfo.h"
#include "symbolinfo.h"
#include "module.h"
#include "exhandlerinfo.h"
static DBGFUNCTIONS _dbgfunctions;
@ -90,6 +91,22 @@ static void _getcallstack(DBGCALLSTACK* callstack)
stackgetcallstack(GetContextDataEx(hActiveThread, UE_CSP), (CALLSTACK*)callstack);
}
static void _getsehchain(DBGSEHCHAIN* sehchain)
{
std::vector<duint> SEHList;
ExHandlerGetSEH(SEHList);
sehchain->total = SEHList.size();
if(sehchain->total > 0)
{
sehchain->records = (DBGSEHRECORD*)BridgeAlloc(sehchain->total * sizeof(DBGSEHRECORD));
for(size_t i = 0; i < sehchain->total; i++)
{
sehchain->records[i].addr = SEHList[i];
MemRead(SEHList[i] + 4, &sehchain->records[i].handler, sizeof(duint));
}
}
}
static bool _getjitauto(bool* jit_auto)
{
return dbggetjitauto(jit_auto, notfound, NULL, NULL);
@ -207,6 +224,7 @@ void dbgfunctionsinit()
_dbgfunctions.DisasmFast = disasmfast;
_dbgfunctions.MemUpdateMap = _memupdatemap;
_dbgfunctions.GetCallStack = _getcallstack;
_dbgfunctions.GetSEHChain = _getsehchain;
_dbgfunctions.SymbolDownloadAllSymbols = SymDownloadAllSymbols;
_dbgfunctions.GetJit = _getjit;
_dbgfunctions.GetJitAuto = _getjitauto;

View File

@ -27,6 +27,18 @@ typedef struct
DBGCALLSTACKENTRY* entries;
} DBGCALLSTACK;
typedef struct
{
duint addr;
duint handler;
} DBGSEHRECORD;
typedef struct
{
size_t total;
DBGSEHRECORD* records;
} DBGSEHCHAIN;
typedef struct
{
DWORD dwProcessId;
@ -52,6 +64,7 @@ typedef int (*MODPATHFROMNAME)(const char* modname, char* path, int size);
typedef bool (*DISASMFAST)(const unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo);
typedef void (*MEMUPDATEMAP)();
typedef void (*GETCALLSTACK)(DBGCALLSTACK* callstack);
typedef void (*GETSEHCHAIN)(DBGSEHCHAIN* sehchain);
typedef void (*SYMBOLDOWNLOADALLSYMBOLS)(const char* szSymbolStore);
typedef bool (*GETJIT)(char* jit, bool x64);
typedef bool (*GETJITAUTO)(bool* jitauto);
@ -91,6 +104,7 @@ typedef struct DBGFUNCTIONS_
DISASMFAST DisasmFast;
MEMUPDATEMAP MemUpdateMap;
GETCALLSTACK GetCallStack;
GETSEHCHAIN GetSEHChain;
SYMBOLDOWNLOADALLSYMBOLS SymbolDownloadAllSymbols;
GETJITAUTO GetJitAuto;
GETJIT GetJit;

View File

@ -213,6 +213,12 @@ DWORD WINAPI updateCallStackThread(void* ptr)
return 0;
}
DWORD WINAPI updateSEHChainThread(void* ptr)
{
GuiUpdateSEHChain();
return 0;
}
void DebugUpdateGui(duint disasm_addr, bool stack)
{
duint cip = GetContextDataEx(hActiveThread, UE_CIP);
@ -235,6 +241,7 @@ void DebugUpdateGui(duint disasm_addr, bool stack)
{
cacheCsp = csp;
CloseHandle(CreateThread(0, 0, updateCallStackThread, 0, 0, 0));
CloseHandle(CreateThread(0, 0, updateSEHChainThread, 0, 0, 0));
}
char modname[MAX_MODULE_SIZE] = "";
char modtext[MAX_MODULE_SIZE * 2] = "";
@ -1802,4 +1809,4 @@ DWORD WINAPI threadAttachLoop(void* lpParameter)
{
debugLoopFunction(lpParameter, true);
return 0;
}
}

View File

@ -54,18 +54,23 @@ bool ExHandlerGetInfo(EX_HANDLER_TYPE Type, EX_HANDLER_INFO* Info)
bool ExHandlerGetSEH(std::vector<duint> & Entries)
{
// TODO: 64-bit
#ifdef _WIN64
return false; // TODO: 64-bit
#endif
static duint nextSEH = 0;
NT_TIB tib;
if(ThreadGetTib((duint)GetTEBLocation(hActiveThread), &tib))
{
EXCEPTION_REGISTRATION_RECORD sehr;
duint addr_ExRegRecord = (duint)tib.ExceptionList;
while(addr_ExRegRecord != 0xFFFFFFFF)
int MAX_DEPTH = 1000;
while(addr_ExRegRecord != 0xFFFFFFFF && MAX_DEPTH)
{
Entries.push_back(addr_ExRegRecord);
MemRead(addr_ExRegRecord , &sehr, sizeof(EXCEPTION_REGISTRATION_RECORD));
if(!MemRead(addr_ExRegRecord , &sehr, sizeof(EXCEPTION_REGISTRATION_RECORD)))
break;
addr_ExRegRecord = (duint)sehr.Next;
MAX_DEPTH--;
}
}
return true;

View File

@ -16,16 +16,18 @@
bool stackcommentget(duint addr, STACK_COMMENT* comment)
{
std::vector<duint> SEHList;
ExHandlerGetSEH(SEHList);
std::vector<duint>::iterator iter = std::find(SEHList.begin(), SEHList.end(), addr);
if(iter != SEHList.end())
if(ExHandlerGetSEH(SEHList))
{
if(iter + 1 != SEHList.end())
sprintf_s(comment->comment, "Pointer to SEH_Record[%d]", iter - SEHList.begin() + 1);
else
sprintf_s(comment->comment, "End of SEH Chain");
strcpy_s(comment->color, "#AE81FF");
return true;
std::vector<duint>::iterator iter = std::find(SEHList.begin(), SEHList.end(), addr);
if(iter != SEHList.end())
{
if(iter + 1 != SEHList.end())
sprintf_s(comment->comment, "Pointer to SEH_Record[%d]", iter - SEHList.begin() + 1);
else
sprintf_s(comment->comment, "End of SEH Chain");
strcpy_s(comment->color, "#AE81FF");
return true;
}
}
duint data = 0;
memset(comment, 0, sizeof(STACK_COMMENT));

View File

@ -424,6 +424,10 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
emit updateCallStack();
break;
case GUI_UPDATE_SEHCHAIN:
emit updateSEHChain();
break;
case GUI_SYMBOL_REFRESH_CURRENT:
emit symbolRefreshCurrent();
break;

View File

@ -100,6 +100,7 @@ signals:
void repaintTableView();
void updatePatches();
void updateCallStack();
void updateSEHChain();
void symbolRefreshCurrent();
void loadSourceFile(const QString path, int line, int selection);
void setIconMenuEntry(int hEntry, QIcon icon);

View File

@ -110,6 +110,11 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
mCallStackView->setWindowIcon(QIcon(":/icons/images/callstack.png"));
connect(mCallStackView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
// SEH Chain view
mSEHChainView = new SEHChainView();
mSEHChainView->setWindowTitle("SEH Chain");
mSEHChainView->setWindowIcon(QIcon(":/icons/images/seh-chain.png"));
connect(mSEHChainView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
// Script view
mScriptView = new ScriptView();
mScriptView->setWindowTitle("Script");
@ -158,6 +163,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
mWidgetList.push_back(mBreakpointsView);
mWidgetList.push_back(mMemMapView);
mWidgetList.push_back(mCallStackView);
mWidgetList.push_back(mSEHChainView);
mWidgetList.push_back(mScriptView);
mWidgetList.push_back(mSymbolView);
mWidgetList.push_back(mSourceViewManager);
@ -227,6 +233,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(ui->actionFunctions, SIGNAL(triggered()), this, SLOT(displayFunctions()));
connect(ui->actionCheckUpdates, SIGNAL(triggered()), this, SLOT(checkUpdates()));
connect(ui->actionCallStack, SIGNAL(triggered()), this, SLOT(displayCallstack()));
connect(ui->actionSEHChain, SIGNAL(triggered()), this, SLOT(displaySEHChain()));
connect(ui->actionDonate, SIGNAL(triggered()), this, SLOT(donate()));
connect(ui->actionReportBug, SIGNAL(triggered()), this, SLOT(reportBug()));
connect(ui->actionAttach, SIGNAL(triggered()), this, SLOT(displayAttach()));
@ -1073,6 +1080,11 @@ void MainWindow::displayCallstack()
showQWidgetTab(mCallStackView);
}
void MainWindow::displaySEHChain()
{
showQWidgetTab(mSEHChainView);
}
void MainWindow::donate()
{
QMessageBox msg(QMessageBox::Information, "Donate", "All the money will go to x64dbg development.");

View File

@ -10,6 +10,7 @@
#include "CPUWidget.h"
#include "MemoryMapView.h"
#include "CallStackView.h"
#include "SEHChainView.h"
#include "LogView.h"
#include "SymbolView.h"
#include "BreakpointsView.h"
@ -102,6 +103,7 @@ public slots:
void displayFunctions();
void checkUpdates();
void displayCallstack();
void displaySEHChain();
void setGlobalShortcut(QAction* action, const QKeySequence & key);
void refreshShortcuts();
void openShortcuts();
@ -129,6 +131,7 @@ private:
CPUWidget* mCpuWidget;
MemoryMapView* mMemMapView;
CallStackView* mCallStackView;
SEHChainView* mSEHChainView;
LogView* mLogView;
SymbolView* mSymbolView;
SourceViewerManager* mSourceViewManager;

View File

@ -56,6 +56,7 @@
<addaction name="actionBreakpoints"/>
<addaction name="actionMemoryMap"/>
<addaction name="actionCallStack"/>
<addaction name="actionSEHChain"/>
<addaction name="actionScript"/>
<addaction name="actionSymbolInfo"/>
<addaction name="actionSource"/>
@ -157,6 +158,7 @@
<addaction name="actionBreakpoints"/>
<addaction name="actionMemoryMap"/>
<addaction name="actionCallStack"/>
<addaction name="actionSEHChain"/>
<addaction name="actionScript"/>
<addaction name="actionSymbolInfo"/>
<addaction name="actionSource"/>
@ -697,6 +699,15 @@
<string>FAQ</string>
</property>
</action>
<action name="actionSEHChain">
<property name="icon">
<iconset resource="../../resource.qrc">
<normaloff>:/icons/images/seh-chain.png</normaloff>:/icons/images/seh-chain.png</iconset>
</property>
<property name="text">
<string>SEH Chain</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>

View File

@ -0,0 +1,99 @@
#include "SEHChainView.h"
#include "Bridge.h"
SEHChainView::SEHChainView(StdTable* parent) : StdTable(parent)
{
int charWidth = getCharWidth();
addColumnAt(8 + charWidth * sizeof(dsint) * 2, "Address", true); //address in the stack
addColumnAt(8 + charWidth * 18, "Exception Handler", true); // Exception Handler
addColumnAt(8 + charWidth * 50, "Module/Label", false);
addColumnAt(charWidth * 10, "Comment", false);
connect(Bridge::getBridge(), SIGNAL(updateSEHChain()), this, SLOT(updateSEHChain()));
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot()));
setupContextMenu();
}
void SEHChainView::setupContextMenu()
{
mFollowAddress = new QAction("Follow &Address", this);
connect(mFollowAddress, SIGNAL(triggered()), this, SLOT(followAddress()));
mFollowHandler = new QAction("Follow Handler", this);
mFollowHandler->setShortcutContext(Qt::WidgetShortcut);
mFollowHandler->setShortcut(QKeySequence("enter"));
connect(mFollowHandler, SIGNAL(triggered()), this, SLOT(followHandler()));
connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followHandler()));
}
void SEHChainView::updateSEHChain()
{
DBGSEHCHAIN sehchain;
memset(&sehchain, 0, sizeof(DBGSEHCHAIN));
DbgFunctions()->GetSEHChain(&sehchain);
setRowCount(sehchain.total);
for(size_t i = 0; i < sehchain.total; i++)
{
QString cellText = QString("%1").arg(sehchain.records[i].addr, sizeof(duint) * 2, 16, QChar('0')).toUpper();
setCellContent(i, 0, cellText);
cellText = QString("%1").arg(sehchain.records[i].handler, sizeof(duint) * 2, 16, QChar('0')).toUpper();
setCellContent(i, 1, cellText);
char label[MAX_LABEL_SIZE] = "";
char module[MAX_MODULE_SIZE] = "";
DbgGetModuleAt(sehchain.records[i].handler, module);
QString label_text;
if(DbgGetLabelAt(sehchain.records[i].handler, SEG_DEFAULT, label))
label_text = "<" + QString(module) + "." + QString(label) + ">";
else
label_text = QString(module);
setCellContent(i, 2, label_text);
char comment[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(sehchain.records[i].handler, comment))
{
if(comment[0] == '\1') //automatic comment
setCellContent(i, 3, QString(comment + 1));
else
setCellContent(i, 3, comment);
}
}
if(sehchain.total)
BridgeFree(sehchain.records);
reloadData();
}
void SEHChainView::contextMenuSlot(const QPoint pos)
{
if(!DbgIsDebugging())
return;
QMenu* wMenu = new QMenu(this); //create context menu
wMenu->addAction(mFollowAddress);
wMenu->addAction(mFollowHandler);
QMenu wCopyMenu("&Copy", this);
setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu->addSeparator();
wMenu->addMenu(&wCopyMenu);
}
wMenu->exec(mapToGlobal(pos)); //execute context menu
}
void SEHChainView::doubleClickedSlot()
{
followHandler();
}
void SEHChainView::followAddress()
{
QString addrText = getCellContent(getInitialSelection(), 0);
DbgCmdExecDirect(QString("sdump " + addrText).toUtf8().constData());
emit showCpu();
}
void SEHChainView::followHandler()
{
QString addrText = getCellContent(getInitialSelection(), 1);
DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData());
emit showCpu();
}

View File

@ -0,0 +1,28 @@
#ifndef SEHCHAINVIEW_H
#define SEHCHAINVIEW_H
#include "StdTable.h"
class SEHChainView : public StdTable
{
Q_OBJECT
public:
explicit SEHChainView(StdTable* parent = 0);
void setupContextMenu();
signals:
void showCpu();
protected slots:
void updateSEHChain();
void contextMenuSlot(const QPoint pos);
void doubleClickedSlot();
void followAddress();
void followHandler();
private:
QAction* mFollowAddress;
QAction* mFollowHandler;
};
#endif // SEHCHAINVIEW_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

View File

@ -74,5 +74,6 @@
<file>images/processor32.png</file>
<file>images/processor64.png</file>
<file>images/processor-cpu.png</file>
<file>images/seh-chain.png</file>
</qresource>
</RCC>

View File

@ -142,7 +142,8 @@ SOURCES += \
Src/Gui/CPUMultiDump.cpp \
Src/Gui/AssembleDialog.cpp \
Src/ThirdPartyLibs/float128/float128.cpp \
Src/Utils/StringUtil.cpp
Src/Utils/StringUtil.cpp \
Src/Gui/SEHChainView.cpp
HEADERS += \
@ -225,7 +226,8 @@ HEADERS += \
Src/Utils/QActionLambda.h \
Src/Gui/CPUMultiDump.h \
Src/Gui/AssembleDialog.h \
Src/ThirdPartyLibs/float128/float128.h
Src/ThirdPartyLibs/float128/float128.h \
Src/Gui/SEHChainView.h
FORMS += \
Src/Gui/MainWindow.ui \