1
0
Fork 0

GUI: implement initial version of ZehSymbolTable

beware of race conditions, but it appears to kinda work
This commit is contained in:
Duncan Ogilvie 2017-12-19 22:14:56 +01:00
parent f68b830069
commit b07611387f
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
12 changed files with 174 additions and 9 deletions

View File

@ -1075,6 +1075,11 @@ BRIDGE_IMPEXP void DbgMenuPrepare(int hMenu)
_dbg_sendmessage(DBG_MENU_PREPARE, (void*)hMenu, nullptr);
}
BRIDGE_IMPEXP void DbgGetSymbolInfo(void* symbol, SYMBOLINFO* info)
{
_dbg_sendmessage(DBG_GET_SYMBOL_INFO, symbol, info);
}
BRIDGE_IMPEXP const char* GuiTranslateText(const char* Source)
{
EnterCriticalSection(&csTranslate);
@ -1690,6 +1695,11 @@ BRIDGE_IMPEXP void GuiOpenTraceFile(const char* fileName)
_gui_sendmessage(GUI_OPEN_TRACE_FILE, (void*)fileName, nullptr);
}
BRIDGE_IMPEXP void GuiSetModuleSymbols(duint base, ListOf(void*) symbols)
{
_gui_sendmessage(GUI_SET_MODULE_SYMBOLS, (void*)base, symbols);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
hInst = hinstDLL;

View File

@ -308,7 +308,8 @@ typedef enum
DBG_GET_PEB_ADDRESS, // param1=DWORD ProcessId, param2=unused
DBG_GET_TEB_ADDRESS, // param1=DWORD ThreadId, param2=unused
DBG_ANALYZE_FUNCTION, // param1=BridgeCFGraphList* graph, param2=duint entry
DBG_MENU_PREPARE // param1=int hMenu, param2=unused
DBG_MENU_PREPARE, // param1=int hMenu, param2=unused
DBG_GET_SYMBOL_INFO, // param1=void* symbol, param2=SYMBOLINFO* info
} DBGMSG;
typedef enum
@ -1012,6 +1013,7 @@ BRIDGE_IMPEXP duint DbgGetTebAddress(DWORD ThreadId);
BRIDGE_IMPEXP bool DbgAnalyzeFunction(duint entry, BridgeCFGraphList* graph);
BRIDGE_IMPEXP duint DbgEval(const char* expression, bool* success = 0);
BRIDGE_IMPEXP void DbgMenuPrepare(int hMenu);
BRIDGE_IMPEXP void DbgGetSymbolInfo(void* symbol, SYMBOLINFO* info);
//Gui defines
#define GUI_PLUGIN_MENU 0
@ -1139,7 +1141,8 @@ typedef enum
GUI_MENU_REMOVE, // param1=int hEntryMenu, param2=unused
GUI_REF_ADDCOMMAND, // param1=const char* title, param2=const char* command
GUI_OPEN_TRACE_FILE, // param1=const char* file name,param2=unused
GUI_UPDATE_TRACE_BROWSER // param1=unused, param2=unused
GUI_UPDATE_TRACE_BROWSER, // param1=unused, param2=unused
GUI_SET_MODULE_SYMBOLS, // param1=duint base, param2=ListOf(void*) symbols
} GUIMSG;
//GUI Typedefs
@ -1316,6 +1319,7 @@ BRIDGE_IMPEXP void GuiFlushLog();
BRIDGE_IMPEXP void GuiReferenceAddCommand(const char* title, const char* command);
BRIDGE_IMPEXP void GuiUpdateTraceBrowser();
BRIDGE_IMPEXP void GuiOpenTraceFile(const char* fileName);
BRIDGE_IMPEXP void GuiSetModuleSymbols(duint base, ListOf(void*) symbols);
#ifdef __cplusplus
}

View File

@ -1472,6 +1472,18 @@ extern "C" DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* pa
plugincbcall(CB_MENUPREPARE, &info);
}
break;
case DBG_GET_SYMBOL_INFO:
{
//hack^2
auto real = (SymbolInfo*)param1;
auto fake = (SYMBOLINFO*)param2;
fake->addr = real->addr;
fake->decoratedSymbol = (char*)real->decoratedName.c_str();
fake->undecoratedSymbol = (char*)real->undecoratedName.c_str();
fake->isImported = strncmp(fake->decoratedSymbol, "__imp_", 6) == 0;
}
break;
}
return 0;
}

View File

@ -166,6 +166,17 @@ bool SymbolSourcePDB::loadSymbolsAsync(String path)
dprintf("Loaded %d symbols in %.03f\n", _sym.size(), secs);
ListInfo blub;
blub.count = _sym.size();
blub.size = blub.count * sizeof(void*);
std::vector<SymbolInfo*> fuck;
fuck.resize(_sym.size());
size_t i = 0;
for(auto it = _sym.begin(); it != _sym.end(); ++it)
fuck[i++] = &it->second;
blub.data = fuck.data();
GuiSetModuleSymbols(_imageBase, &blub);
GuiUpdateAllViews();
return true;

View File

@ -707,6 +707,7 @@ void AbstractStdTable::headerButtonPressedSlot(int col)
void AbstractStdTable::reloadData()
{
//TODO: do this on request, not every time reloadData is called...
if(mSort.column != -1) //re-sort if the user wants to sort
{
sortRows(mSort.column, mSort.ascending);

View File

@ -840,6 +840,11 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
emit updateTraceBrowser();
break;
case GUI_SET_MODULE_SYMBOLS:
std::vector<void*> moduleSymbols;
BridgeList<void*>::ToVector((const ListInfo*)param2, moduleSymbols, false);
symbolView->setModuleSymbols(duint(param1), moduleSymbols);
break;
}
return nullptr;

View File

@ -22,9 +22,13 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
mMainLayout->addWidget(ui->mainSplitter);
setLayout(mMainLayout);
// Create symbol table
mSymbolTable = new ZehSymbolTable(this);
// Create reference view
mSearchListView = new SearchListView(true, this, true);
mSearchListView->mSearchStartCol = 1;
mSearchListView->setVisible(false);
// Create module list
mModuleList = new SearchListView(true, this);
@ -62,7 +66,7 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
// Setup list splitter
ui->listSplitter->addWidget(mModuleList);
ui->listSplitter->addWidget(mSearchListView);
ui->listSplitter->addWidget(mSymbolTable);
#ifdef _WIN64
// mModuleList : mSymbolList = 40 : 100
ui->listSplitter->setStretchFactor(0, 40);
@ -140,6 +144,13 @@ void SymbolView::loadWindowSettings()
loadSymbolsSplitter(ui->mainSplitter, "mHSymbolsLogSplitter");
}
void SymbolView::setModuleSymbols(duint base, const std::vector<void*> & symbols)
{
//TODO: reload actual symbol list, race conditions
GuiAddLogMessage(QString("base: %1, count: %2\n").arg(ToPtrString(base)).arg(symbols.size()).toUtf8().constData());
mModuleSymbolMap[base] = symbols;
}
void SymbolView::setupContextMenu()
{
QIcon disassembler = DIcon(ArchValue("processor32.png", "processor64.png"));
@ -334,7 +345,7 @@ void SymbolView::moduleSelectionChanged(int index)
Q_UNUSED(index);
setUpdatesEnabled(false);
mSearchListView->mList->setRowCount(0);
/*mSearchListView->mList->setRowCount(0);
for(auto index : mModuleList->mCurList->getSelection())
{
QString mod = mModuleList->mCurList->getCellContent(index, 1);
@ -348,7 +359,15 @@ void SymbolView::moduleSelectionChanged(int index)
if(!mSearchListView->isSearchBoxLocked())
mSearchListView->mSearchBox->setText("");
else
mSearchListView->refreshSearchList();
mSearchListView->refreshSearchList();*/
QString modBase = mModuleList->mCurList->getCellContent(mModuleList->mCurList->getInitialSelection(), 0);
duint wVA;
if(!DbgFunctions()->ValFromString(modBase.toUtf8().constData(), &wVA))
return;
mSymbolTable->mData = mModuleSymbolMap[wVA];
mSymbolTable->setRowCount(mSymbolTable->mData.size());
mSymbolTable->reloadData();
setUpdatesEnabled(true);
}

View File

@ -3,6 +3,7 @@
#include <QWidget>
#include "Bridge.h"
#include "ZehSymbolTable.h"
class QMenu;
class SearchListView;
@ -24,6 +25,8 @@ public:
void saveWindowSettings();
void loadWindowSettings();
void setModuleSymbols(duint base, const std::vector<void*> & symbols);
private slots:
void updateStyle();
void addMsgToSymbolLogSlot(QString msg);
@ -69,6 +72,7 @@ private:
QWidget* mSymbolPlaceHolder;
SearchListView* mSearchListView;
SearchListView* mModuleList;
ZehSymbolTable* mSymbolTable;
QMap<QString, duint> mModuleBaseList;
QAction* mFollowSymbolAction;
QAction* mFollowSymbolDumpAction;
@ -91,6 +95,8 @@ private:
QAction* mLoadLib;
QAction* mFreeLib;
std::map<duint, std::vector<void*>> mModuleSymbolMap;
static void cbSymbolEnum(SYMBOLINFO* symbol, void* user);
};

View File

@ -0,0 +1,66 @@
#include "ZehSymbolTable.h"
ZehSymbolTable::ZehSymbolTable(QWidget* parent)
: AbstractStdTable(parent)
{
auto charwidth = getCharWidth();
//enableMultiSelection(true); //TODO
addColumnAt(charwidth * 2 * sizeof(dsint) + 8, tr("Address"), true);
addColumnAt(charwidth * 6 + 8, tr("Type"), true);
addColumnAt(charwidth * 80, tr("Symbol"), true);
addColumnAt(2000, tr("Symbol (undecorated)"), true);
//loadColumnFromConfig("Symbol"); //TODO
}
QString ZehSymbolTable::getCellContent(int r, int c)
{
if(!isValidIndex(r, c))
return QString();
SYMBOLINFO info = {0};
DbgGetSymbolInfo(mData.at(r), &info);
switch(c)
{
case ColAddr:
return ToPtrString(info.addr);
case ColType:
return info.isImported ? tr("Import") : tr("Export");
case ColDecorated:
return info.decoratedSymbol;
case ColUndecorated:
return info.undecoratedSymbol;
default:
return QString();
}
}
bool ZehSymbolTable::isValidIndex(int r, int c)
{
return r >= 0 && r < mData.size() && c >= 0 && c <= ColUndecorated;
}
void ZehSymbolTable::sortRows(int column, bool ascending)
{
std::stable_sort(mData.begin(), mData.end(), [column, ascending](void* a, void* b)
{
SYMBOLINFO ainfo, binfo;
DbgGetSymbolInfo(a, &ainfo);
DbgGetSymbolInfo(b, &binfo);
bool less;
switch(column)
{
case ColAddr:
less = ainfo.addr < binfo.addr;
break;
case ColType:
less = ainfo.isImported < binfo.isImported;
break;
case ColDecorated:
less = strcmp(ainfo.decoratedSymbol, binfo.decoratedSymbol) < 0;
break;
case ColUndecorated:
less = strcmp(ainfo.undecoratedSymbol, binfo.undecoratedSymbol) < 0;
break;
}
return ascending ? less : !less;
});
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "AbstractStdTable.h"
class ZehSymbolTable : public AbstractStdTable
{
Q_OBJECT
public:
ZehSymbolTable(QWidget* parent);
QString getCellContent(int r, int c) override;
bool isValidIndex(int r, int c) override;
void sortRows(int column, bool ascending) override;
friend class SymbolView;
private:
std::vector<void*> mData;
enum
{
ColAddr,
ColType,
ColDecorated,
ColUndecorated
};
};

View File

@ -186,7 +186,8 @@ SOURCES += \
Src/Tracer/TraceFileReader.cpp \
Src/Tracer/TraceFileSearch.cpp \
Src/Gui/MultiItemsSelectWindow.cpp \
Src/BasicView/AbstractStdTable.cpp
Src/BasicView/AbstractStdTable.cpp \
Src/Gui/ZehSymbolTable.cpp
HEADERS += \
@ -308,7 +309,8 @@ HEADERS += \
Src/Tracer/TraceFileReaderInternal.h \
Src/Tracer/TraceFileSearch.h \
Src/Gui/MultiItemsSelectWindow.h \
Src/BasicView/AbstractStdTable.h
Src/BasicView/AbstractStdTable.h \
Src/Gui/ZehSymbolTable.h
FORMS += \

View File

@ -225,7 +225,8 @@ SOURCES += \
gui/Src/Tracer/TraceFileReader.cpp \
gui/Src/Tracer/TraceFileSearch.cpp \
gui/Src/Gui/MultiItemsSelectWindow.cpp \
gui/Src/BasicView/AbstractStdTable.cpp
gui/Src/BasicView/AbstractStdTable.cpp \
gui/Src/Gui/ZehSymbolTable.cpp
HEADERS += \
gui/Src/Exports.h \
@ -462,7 +463,8 @@ HEADERS += \
gui/Src/Tracer/TraceFileReaderInternal.h \
gui/Src/Tracer/TraceFileSearch.h \
gui/Src/Gui/MultiItemsSelectWindow.h \
gui/Src/BasicView/AbstractStdTable.h
gui/Src/BasicView/AbstractStdTable.h \
gui/Src/Gui/ZehSymbolTable.h
FORMS += \
gui/Src/Gui/AppearanceDialog.ui \