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:
parent
9b4d140eb4
commit
22108bd046
|
@ -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))
|
||||
|
|
|
@ -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[]);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 507 B |
Binary file not shown.
After Width: | Height: | Size: 615 B |
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue