1
0
Fork 0

Load/Free Modules in Symbols window

- Added command "freelib" to free a module previously loaded
- Added menu entries for load/free modules in the symbols view
This commit is contained in:
ThunderCls 2016-12-14 00:23:00 -05:00
parent 9b4d140eb4
commit 22108bd046
8 changed files with 187 additions and 0 deletions

View File

@ -49,6 +49,7 @@ bool cbDebugHide(int argc, char* argv[])
}
static duint LoadLibThreadID;
static duint FreeLibThreadID;
static duint DLLNameMem;
static duint ASMAddr;
static TITAN_ENGINE_CONTEXT_t backupctx = { 0 };
@ -77,6 +78,29 @@ static void cbDebugLoadLibBPX()
wait(WAITID_RUN);
}
static void cbDebugFreeLibBPX()
{
HANDLE FreeLibThread = ThreadGetHandle((DWORD)FreeLibThreadID);
#ifdef _WIN64
duint LibAddr = GetContextDataEx(FreeLibThread, UE_RAX);
#else
duint LibAddr = GetContextDataEx(FreeLibThread, UE_EAX);
#endif //_WIN64
varset("$result", LibAddr, false);
backupctx.eflags &= ~0x100;
SetFullContextDataEx(FreeLibThread, &backupctx);
MemFreeRemote(ASMAddr);
ThreadResumeAll();
//update GUI
DebugUpdateGuiSetStateAsync(GetContextDataEx(hActiveThread, UE_CIP), true);
//lock
lock(WAITID_RUN);
dbgsetforeground();
PLUG_CB_PAUSEDEBUG pauseInfo = { nullptr };
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
wait(WAITID_RUN);
}
bool cbDebugLoadLib(int argc, char* argv[])
{
if(argc < 2)
@ -150,6 +174,106 @@ bool cbDebugLoadLib(int argc, char* argv[])
return ok;
}
bool GetModuleEntry(MODULEENTRY32* me32, DWORD pID, char* module_name)
{
HANDLE hModuleSnap;
bool found = false;
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pID);
if(hModuleSnap == INVALID_HANDLE_VALUE)
return false;
if(Module32First(hModuleSnap, me32))
{
do
{
if(_strcmpi(module_name, me32->szModule) == 0)
found = true;
}
while(!found && Module32Next(hModuleSnap, me32));
}
CloseHandle(hModuleSnap);
return found;
}
bool cbDebugFreeLib(int argc, char* argv[])
{
MODULEENTRY32 unloadModule;
ZeroMemory(&unloadModule, sizeof(MODULEENTRY32));
unloadModule.dwSize = sizeof(MODULEENTRY32);
if(argc < 2)
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error: you must specify the name of the DLL to unload\n"));
return false;
}
FreeLibThreadID = fdProcessInfo->dwThreadId;
HANDLE UnLoadLibThread = ThreadGetHandle((duint)FreeLibThreadID);
if(!GetModuleEntry(&unloadModule, DbgGetProcessId(), argv[1]))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't get library handle"));
return false;
}
ASMAddr = MemAllocRemote(0, 0x1000);
if(!ASMAddr)
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't allocate memory in debuggee"));
return false;
}
int size = 0;
int counter = 0;
duint FreeLibrary = 0;
char command[50] = "";
char error[MAX_ERROR_SIZE] = "";
GetFullContextDataEx(UnLoadLibThread, &backupctx);
if(!valfromstring("kernel32:FreeLibrary", &FreeLibrary, false))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't get kernel32:FreeLibrary"));
return false;
}
// Arch specific asm code
#ifdef _WIN64
sprintf_s(command, "mov rcx, %p", unloadModule.hModule);
#else
sprintf_s(command, "push %p", unloadModule.hModule);
#endif // _WIN64
assembleat(ASMAddr, command, &size, error, true);
counter += size;
#ifdef _WIN64
sprintf_s(command, "mov rax, %p", FreeLibrary);
assembleat(ASMAddr + counter, command, &size, error, true);
counter += size;
sprintf_s(command, "call rax");
#else
sprintf_s(command, "call %p", FreeLibrary);
#endif // _WIN64
assembleat(ASMAddr + counter, command, &size, error, true);
counter += size;
SetContextDataEx(UnLoadLibThread, UE_CIP, ASMAddr);
auto ok = SetBPX(ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugFreeLibBPX);
ThreadSuspendAll();
ResumeThread(UnLoadLibThread);
unlock(WAITID_RUN);
return ok;
}
bool cbInstrAssemble(int argc, char* argv[])
{
if(IsArgumentsLessThan(argc, 3))

View File

@ -7,6 +7,7 @@ bool cbInstrZzz(int argc, char* argv[]);
bool cbDebugHide(int argc, char* argv[]);
bool cbDebugLoadLib(int argc, char* argv[]);
bool cbDebugFreeLib(int argc, char* argv[]);
bool cbInstrAssemble(int argc, char* argv[]);
bool cbInstrGpa(int argc, char* argv[]);

View File

@ -398,6 +398,7 @@ static void registercommands()
dbgcmdnew("HideDebugger\1dbh\1hide", cbDebugHide, true); //HideDebugger
dbgcmdnew("loadlib", cbDebugLoadLib, true); //Load DLL
dbgcmdnew("freelib", cbDebugFreeLib, true); //Unload DLL
dbgcmdnew("asm", cbInstrAssemble, true); //assemble instruction
dbgcmdnew("gpa", cbInstrGpa, true); //get proc address

View File

@ -8,6 +8,7 @@
#include "LineEditDialog.h"
#include <QVBoxLayout>
#include <QProcess>
#include <QFileDialog>
SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView)
{
@ -170,6 +171,20 @@ void SymbolView::setupContextMenu()
mModuleList->mSearchList->addAction(mBrowseInExplorer);
connect(mBrowseInExplorer, SIGNAL(triggered()), this, SLOT(moduleBrowse()));
mLoadLib = new QAction(DIcon("lib_load.png"), tr("Load library..."), this);
mLoadLib->setShortcutContext(Qt::WidgetWithChildrenShortcut);
this->addAction(mLoadLib);
mModuleList->mList->addAction(mLoadLib);
mModuleList->mSearchList->addAction(mLoadLib);
connect(mLoadLib, SIGNAL(triggered()), this, SLOT(moduleLoad()));
mFreeLib = new QAction(DIcon("lib_free.png"), tr("Free library"), this);
mFreeLib->setShortcutContext(Qt::WidgetWithChildrenShortcut);
this->addAction(mFreeLib);
mModuleList->mList->addAction(mFreeLib);
mModuleList->mSearchList->addAction(mFreeLib);
connect(mFreeLib, SIGNAL(triggered()), this, SLOT(moduleFree()));
mYaraAction = new QAction(DIcon("yara.png"), tr("&Yara Memory..."), this);
connect(mYaraAction, SIGNAL(triggered()), this, SLOT(moduleYara()));
@ -381,6 +396,8 @@ void SymbolView::moduleContextMenu(QMenu* wMenu)
wMenu->addAction(mCopyPathAction);
wMenu->addAction(mBrowseInExplorer);
}
wMenu->addAction(mLoadLib);
wMenu->addAction(mFreeLib);
wMenu->addAction(mYaraAction);
wMenu->addAction(mYaraFileAction);
wMenu->addAction(mEntropyAction);
@ -461,6 +478,44 @@ void SymbolView::moduleDownloadAllSymbols()
DbgCmdExec("symdownload");
}
void SymbolView::moduleLoad()
{
QString cmd;
if(!DbgIsDebugging())
return;
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("Dll Files (*.dll)"));
if(fileName.size() != 0)
{
cmd = "loadlib " + fileName;
DbgCmdExec(cmd.toUtf8().constData());
}
}
void SymbolView::moduleFree()
{
QString cmd;
if(!DbgIsDebugging())
return;
QString moduleName = mModuleList->mCurList->getCellContent(mModuleList->mCurList->getInitialSelection(), 1);
if(moduleName.length() != 0)
{
QMessageBox::StandardButton reply;
QString question = "Are you sure you want to free the module: " + moduleName + "\r\nThis could bring an unexpected behaviour to your debugging sesion";
reply = QMessageBox::question(this,
tr("Free Library").toUtf8().constData(),
question.toUtf8().constData(),
QMessageBox::Yes | QMessageBox::No);
if(reply == QMessageBox::Yes)
{
cmd = "freelib " + moduleName;
DbgCmdExec(cmd.toUtf8().constData());
mSearchListView->mCurList->setRowCount(0);
}
}
}
void SymbolView::toggleBreakpoint()
{
if(!DbgIsDebugging())

View File

@ -52,6 +52,8 @@ private slots:
void moduleEntropy();
void emptySearchResultSlot();
void selectionGetSlot(SELECTIONDATA* selection);
void moduleLoad();
void moduleFree();
signals:
void showReferences();
@ -81,6 +83,8 @@ private:
QAction* mModSetPartyAction;
QAction* mBrowseInExplorer;
QAction* mFollowInMemMap;
QAction* mLoadLib;
QAction* mFreeLib;
static void cbSymbolEnum(SYMBOLINFO* symbol, void* user);
};

BIN
src/gui/images/lib_free.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

BIN
src/gui/images/lib_load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

View File

@ -278,5 +278,7 @@
<file>images/uac.png</file>
<file>images/hidetab.png</file>
<file>images/variables.png</file>
<file>images/lib_load.png</file>
<file>images/lib_free.png</file>
</qresource>
</RCC>