Merge branch 'development' of https://github.com/ThunderCls/x64dbg into ThunderCls-development
Also made various cleanup changes
This commit is contained in:
commit
1d00a61ba2
|
@ -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 };
|
||||
|
@ -150,6 +151,98 @@ bool cbDebugLoadLib(int argc, char* argv[])
|
|||
return ok;
|
||||
}
|
||||
|
||||
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 cbDebugFreeLib(int argc, char* argv[])
|
||||
{
|
||||
duint base = 0;
|
||||
if(IsArgumentsLessThan(argc, 2) || !valfromstring(argv[1], &base, false))
|
||||
return false;
|
||||
base = ModBaseFromAddr(base);
|
||||
if(!base)
|
||||
{
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Error: the specified address does not point inside a module"));
|
||||
return false;
|
||||
}
|
||||
|
||||
FreeLibThreadID = fdProcessInfo->dwThreadId;
|
||||
HANDLE UnLoadLibThread = ThreadGetHandle((DWORD)FreeLibThreadID);
|
||||
|
||||
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", base);
|
||||
#else
|
||||
sprintf_s(command, "push %p", base);
|
||||
#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[]);
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode
|
|||
|
||||
// Convert UTF-16 string to UTF-8
|
||||
std::string asciiData2 = StringUtils::Utf16ToUtf8((const wchar_t*)data());
|
||||
memcpy(asciiData, asciiData2.c_str(), min((maxlen + 1) * 2, asciiData2.size() + 1));
|
||||
memcpy(asciiData, asciiData2.c_str(), min((size_t(maxlen) + 1) * 2, asciiData2.size() + 1));
|
||||
|
||||
// Escape the string
|
||||
String escaped = StringUtils::Escape(asciiData);
|
||||
|
|
|
@ -138,7 +138,7 @@ String StringUtils::Escape(const String & s)
|
|||
break;
|
||||
default:
|
||||
int UTF8CharSize;
|
||||
if(ch >= 0x80 && (UTF8CharSize = IsValidUTF8Char(s.c_str() + i, s.length() - i)) != 0) //UTF-8 Character is emitted directly
|
||||
if(ch >= 0x80 && (UTF8CharSize = IsValidUTF8Char(s.c_str() + i, int(s.length() - i))) != 0) //UTF-8 Character is emitted directly
|
||||
{
|
||||
memcpy(buf, s.c_str() + i, UTF8CharSize);
|
||||
i += UTF8CharSize - 1;
|
||||
|
|
|
@ -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 TODO: undocumented
|
||||
dbgcmdnew("asm", cbInstrAssemble, true); //assemble instruction
|
||||
dbgcmdnew("gpa", cbInstrGpa, true); //get proc address
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
case GUI_ADD_MSG_TO_LOG:
|
||||
{
|
||||
auto msg = (const char*)param1;
|
||||
emit addMsgToLog(QByteArray(msg, strlen(msg) + 1)); //Speed up performance: don't convert to UCS-2 QString
|
||||
emit addMsgToLog(QByteArray(msg, int(strlen(msg)) + 1)); //Speed up performance: don't convert to UCS-2 QString
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ void FavouriteTools::on_btnAddFavouriteTool_clicked()
|
|||
char buffer[MAX_SETTING_SIZE];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
BridgeSettingGet("Favourite", "LastToolPath", buffer);
|
||||
BrowseDialog browse(this, QString("Browse tool"), QString("Enter the path of the tool."), QString("Executable Files (*.exe);;All Files (*.*)"), QString(buffer), false);
|
||||
BrowseDialog browse(this, tr("Browse tool"), tr("Enter the path of the tool."), tr("Executable Files (*.exe);;All Files (*.*)"), QString(buffer), false);
|
||||
if(browse.exec() != QDialog::Accepted && browse.path.length())
|
||||
return;
|
||||
filename = browse.path;
|
||||
|
@ -142,7 +142,7 @@ void FavouriteTools::on_btnEditFavouriteTool_clicked()
|
|||
if(!table->rowCount())
|
||||
return;
|
||||
QString filename = table->item(table->currentRow(), 0)->text();
|
||||
BrowseDialog browse(this, QString("Browse tool"), QString("Enter the path of the tool."), QString("Executable Files (*.exe);;All Files (*.*)"), filename, false);
|
||||
BrowseDialog browse(this, tr("Browse tool"), tr("Enter the path of the tool."), tr("Executable Files (*.exe);;All Files (*.*)"), filename, false);
|
||||
if(browse.exec() != QDialog::Accepted)
|
||||
return;
|
||||
filename = browse.path;
|
||||
|
|
|
@ -210,7 +210,7 @@ void LogView::addMsgToLogSlot(QByteArray msg)
|
|||
redirectError = true;
|
||||
}
|
||||
if(loggingEnabled)
|
||||
msgUtf16 = QString::fromUtf8(data, buffersize);
|
||||
msgUtf16 = QString::fromUtf8(data, int(buffersize));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
#include "YaraRuleSelectionDialog.h"
|
||||
#include "EntropyDialog.h"
|
||||
#include "LineEditDialog.h"
|
||||
#include "BrowseDialog.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QProcess>
|
||||
#include <QFileDialog>
|
||||
|
||||
SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView)
|
||||
{
|
||||
|
@ -170,6 +172,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 +397,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 +479,39 @@ void SymbolView::moduleDownloadAllSymbols()
|
|||
DbgCmdExec("symdownload");
|
||||
}
|
||||
|
||||
void SymbolView::moduleLoad()
|
||||
{
|
||||
QString cmd;
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
|
||||
BrowseDialog browse(this, tr("Select DLL"), tr("Enter the path of a DLL to load in the debuggee."), tr("DLL Files (*.dll);;All Files (*.*)"), QString(), false);
|
||||
if(browse.exec() != QDialog::Accepted && browse.path.length())
|
||||
return;
|
||||
auto fileName = browse.path;
|
||||
DbgCmdExec(QString("loadlib \"%1\"").arg(fileName.replace("\\", "\\\\")).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 = tr("Are you sure you want to free the module: %1?\n\nThis could introduce unexpected behaviour to your debugging session...").arg(moduleName);
|
||||
reply = QMessageBox::question(this,
|
||||
tr("Free Library").toUtf8().constData(),
|
||||
question.toUtf8().constData(),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if(reply == QMessageBox::Yes)
|
||||
DbgCmdExec(QString("freelib %1").arg(mModuleList->mCurList->getCellContent(mModuleList->mCurList->getInitialSelection(), 0)).toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
|
|
|
@ -70,7 +70,7 @@ void MHTabWidget::AttachTab(QWidget* parent)
|
|||
QWidget* tearOffWidget = detachedWidget->centralWidget();
|
||||
|
||||
// Reattach the tab
|
||||
int newIndex = addTabEx(tearOffWidget, detachedWidget->windowIcon(), detachedWidget->windowTitle(), detachedWidget->mNativeName);
|
||||
addTabEx(tearOffWidget, detachedWidget->windowIcon(), detachedWidget->windowTitle(), detachedWidget->mNativeName);
|
||||
|
||||
// Remove it from the windows list
|
||||
for(int i = 0; i < m_Windows.size(); i++)
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 507 B |
Binary file not shown.
After Width: | Height: | Size: 615 B |
|
@ -278,6 +278,8 @@
|
|||
<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>
|
||||
<file>images/christmas1.png</file>
|
||||
<file>images/christmas2.png</file>
|
||||
<file>images/christmas3.png</file>
|
||||
|
|
|
@ -255,7 +255,7 @@ struct RedirectWow
|
|||
|
||||
bool DisableRedirect()
|
||||
{
|
||||
return _Wow64DisableRedirection(&oldValue);
|
||||
return !!_Wow64DisableRedirection(&oldValue);
|
||||
}
|
||||
|
||||
~RedirectWow()
|
||||
|
|
Loading…
Reference in New Issue