diff --git a/help/resumeallthreads_threadresumeall.htm b/help/resumeallthreads_threadresumeall.htm new file mode 100644 index 00000000..b098b6cb --- /dev/null +++ b/help/resumeallthreads_threadresumeall.htm @@ -0,0 +1,36 @@ + + + +resumeallthreads/threadresumeall + + + + + + + +

resumeallthreads[,threadresumeall]
Resume all threads in the debuggee.

+

+ + +arguments + +  +
+
+ +This command has no arguments.

+

+ + +result
This command does not set any result +variables.

+

 

+ \ No newline at end of file diff --git a/help/suspendallthreads_threadsuspendall.htm b/help/suspendallthreads_threadsuspendall.htm new file mode 100644 index 00000000..6ace5501 --- /dev/null +++ b/help/suspendallthreads_threadsuspendall.htm @@ -0,0 +1,24 @@ + + + +suspendallthreads/threadsuspendall + + + + + + + +

suspendallthreads[,threadsuspendall]
Suspend all threads in the debuggee.

+

arguments 
This command has no arguments.

+

result
This command does not set any result +variables.

+ \ No newline at end of file diff --git a/help/x64_dbg.wcp b/help/x64_dbg.wcp index 3292d1c3..d38b1f35 100644 Binary files a/help/x64_dbg.wcp and b/help/x64_dbg.wcp differ diff --git a/x64_dbg_dbg/_global.cpp b/x64_dbg_dbg/_global.cpp index fc47cee8..eb935d7a 100644 --- a/x64_dbg_dbg/_global.cpp +++ b/x64_dbg_dbg/_global.cpp @@ -1,4 +1,6 @@ #include "_global.h" +#include +#include #include HINSTANCE hInst; @@ -194,4 +196,57 @@ bool IsWow64() //x64_dbg supports WinXP SP3 and later only, so ignore the GetProcAddress crap :D IsWow64Process(GetCurrentProcess(), &bIsWow64Process); return !!bIsWow64Process; +} + +//Taken from: http://www.cplusplus.com/forum/windows/64088/ +bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize) +{ + if(szResolvedPath == NULL) + return SUCCEEDED(E_INVALIDARG); + + //Initialize COM stuff + CoInitialize(NULL); + + //Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); + if(SUCCEEDED(hres)) + { + //Get a pointer to the IPersistFile interface. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); + if(SUCCEEDED(hres)) + { + //Load the shortcut. + hres = ppf->Load(szShortcutPath, STGM_READ); + + if(SUCCEEDED(hres)) + { + //Resolve the link. + hres = psl->Resolve(hwnd, 0); + + if(SUCCEEDED(hres)) + { + //Get the path to the link target. + char szGotPath[MAX_PATH] = {0}; + hres = psl->GetPath(szGotPath, _countof(szGotPath), NULL, SLGP_SHORTPATH); + + if(SUCCEEDED(hres)) + { + strcpy_s(szResolvedPath, nSize, szGotPath); + } + } + } + + //Release the pointer to the IPersistFile interface. + ppf->Release(); + } + + //Release the pointer to the IShellLink interface. + psl->Release(); + } + + //Uninitialize COM stuff + CoUninitialize(); + return SUCCEEDED(hres); } \ No newline at end of file diff --git a/x64_dbg_dbg/_global.h b/x64_dbg_dbg/_global.h index 1f8beea5..92f7feed 100644 --- a/x64_dbg_dbg/_global.h +++ b/x64_dbg_dbg/_global.h @@ -122,6 +122,7 @@ bool GetFileNameFromHandle(HANDLE hFile, char* szFileName); bool settingboolget(const char* section, const char* name); arch GetFileArchitecture(const char* szFileName); bool IsWow64(); +bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize); #include "dynamicmem.h" diff --git a/x64_dbg_dbg/console.cpp b/x64_dbg_dbg/console.cpp index de10e662..8a82b91a 100644 --- a/x64_dbg_dbg/console.cpp +++ b/x64_dbg_dbg/console.cpp @@ -1,7 +1,5 @@ #include "console.h" -static char msg[66000]; - void dputs(const char* text) { dprintf("%s\n", text); @@ -11,7 +9,7 @@ void dprintf(const char* format, ...) { va_list args; va_start(args, format); - *msg = 0; - vsnprintf(msg, sizeof(msg), format, args); + Memory msg(66000); + vsnprintf(msg, msg.size(), format, args); GuiAddLogMessage(msg); } diff --git a/x64_dbg_dbg/debugger_commands.cpp b/x64_dbg_dbg/debugger_commands.cpp index f3e71686..faf1a6af 100644 --- a/x64_dbg_dbg/debugger_commands.cpp +++ b/x64_dbg_dbg/debugger_commands.cpp @@ -25,6 +25,12 @@ CMDRESULT cbDebugInit(int argc, char* argv[]) static char arg1[deflen] = ""; if(!argget(*argv, arg1, 0, false)) return STATUS_ERROR; + char szResolvedPath[MAX_PATH] = ""; + if(ResolveShortcut(GuiGetWindowHandle(), StringUtils::Utf8ToUtf16(arg1).c_str(), szResolvedPath, _countof(szResolvedPath))) + { + dprintf("resolved shortcut \"%s\"->\"%s\"\n", arg1, szResolvedPath); + strcpy_s(arg1, szResolvedPath); + } if(!FileExists(arg1)) { dputs("file does not exist!"); @@ -1095,6 +1101,24 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[]) return STATUS_ERROR; } +CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]) +{ + int threadCount = threadgetcount(); + int suspendedCount = threadsuspendall(); + dprintf("%d/%d thread(s) suspended\n", suspendedCount, threadCount); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]) +{ + int threadCount = threadgetcount(); + int resumeCount = threadresumeall(); + dprintf("%d/%d thread(s) resumed\n", resumeCount, threadCount); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + CMDRESULT cbDebugSetPriority(int argc, char* argv[]) { if(argc < 3) diff --git a/x64_dbg_dbg/debugger_commands.h b/x64_dbg_dbg/debugger_commands.h index 8537f55a..7e9b7eb1 100644 --- a/x64_dbg_dbg/debugger_commands.h +++ b/x64_dbg_dbg/debugger_commands.h @@ -50,6 +50,8 @@ CMDRESULT cbDebugGetJITAuto(int argc, char* argv[]); CMDRESULT cbDebugSetJITAuto(int argc, char* argv[]); CMDRESULT cbDebugSuspendthread(int argc, char* argv[]); CMDRESULT cbDebugKillthread(int argc, char* argv[]); +CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]); +CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]); CMDRESULT cbDebugSetPriority(int argc, char* argv[]); CMDRESULT cbDebugGetCmdline(int argc, char* argv[]); CMDRESULT cbDebugSetCmdline(int argc, char* argv[]); diff --git a/x64_dbg_dbg/stringutils.cpp b/x64_dbg_dbg/stringutils.cpp index 6d101370..b9ea5da6 100644 --- a/x64_dbg_dbg/stringutils.cpp +++ b/x64_dbg_dbg/stringutils.cpp @@ -3,7 +3,7 @@ #include #include -std::vector StringUtils::Split(const String & s, char delim, std::vector & elems) +StringList StringUtils::Split(const String & s, char delim, std::vector & elems) { std::stringstream ss(s); String item; @@ -16,7 +16,7 @@ std::vector StringUtils::Split(const String & s, char delim, std::vector return elems; } -std::vector StringUtils::Split(const String & s, char delim) +StringList StringUtils::Split(const String & s, char delim) { std::vector elems; Split(s, delim, elems); diff --git a/x64_dbg_dbg/stringutils.h b/x64_dbg_dbg/stringutils.h index 48a41bae..302566a2 100644 --- a/x64_dbg_dbg/stringutils.h +++ b/x64_dbg_dbg/stringutils.h @@ -6,12 +6,14 @@ typedef std::string String; typedef std::wstring WString; +typedef std::vector StringList; +typedef std::vector WStringList; class StringUtils { public: - static std::vector Split(const String & s, char delim, std::vector & elems); - static std::vector Split(const String & s, char delim); + static StringList Split(const String & s, char delim, std::vector & elems); + static StringList Split(const String & s, char delim); static String Trim(const String & s); static String TrimLeft(const String & s); static String TrimRight(const String & s); diff --git a/x64_dbg_dbg/thread.cpp b/x64_dbg_dbg/thread.cpp index fa183b22..b1310657 100644 --- a/x64_dbg_dbg/thread.cpp +++ b/x64_dbg_dbg/thread.cpp @@ -50,6 +50,7 @@ void threadclear() static THREADWAITREASON GetThreadWaitReason(DWORD dwThreadId) { + //TODO: implement this return _Executive; } @@ -126,4 +127,29 @@ DWORD threadgetid(HANDLE hThread) if(threadList.at(i).hThread == hThread) return threadList.at(i).dwThreadId; return 0; +} + +int threadgetcount() +{ + return (int)threadList.size(); +} + +int threadsuspendall() +{ + CriticalSectionLocker locker(LockThreads); + int count = 0; + for(unsigned int i = 0; i < threadList.size(); i++) + if(SuspendThread(threadList.at(i).hThread) != -1) + count++; + return count; +} + +int threadresumeall() +{ + CriticalSectionLocker locker(LockThreads); + int count = 0; + for(unsigned int i = 0; i < threadList.size(); i++) + if(ResumeThread(threadList.at(i).hThread) != -1) + count++; + return count; } \ No newline at end of file diff --git a/x64_dbg_dbg/thread.h b/x64_dbg_dbg/thread.h index defdfabe..eaacbaef 100644 --- a/x64_dbg_dbg/thread.h +++ b/x64_dbg_dbg/thread.h @@ -13,5 +13,8 @@ bool threadisvalid(DWORD dwThreadId); bool threadsetname(DWORD dwTHreadId, const char* name); HANDLE threadgethandle(DWORD dwThreadId); DWORD threadgetid(HANDLE hThread); +int threadgetcount(); +int threadsuspendall(); +int threadresumeall(); #endif //_THREAD_H diff --git a/x64_dbg_dbg/x64_dbg.cpp b/x64_dbg_dbg/x64_dbg.cpp index 556182f5..37423135 100644 --- a/x64_dbg_dbg/x64_dbg.cpp +++ b/x64_dbg_dbg/x64_dbg.cpp @@ -74,6 +74,8 @@ static void registercommands() dbgcmdnew("suspendthread\1threadsuspend", cbDebugSuspendthread, true); //suspend thread dbgcmdnew("resumethread\1threadresume", cbDebugResumethread, true); //resume thread dbgcmdnew("killthread\1threadkill", cbDebugKillthread, true); //kill thread + dbgcmdnew("suspendallthreads\1threadsuspendall", cbDebugSuspendAllThreads, true); //suspend all threads + dbgcmdnew("resumeallthreads\1threadresumeall", cbDebugResumeAllThreads, true); //resume all threads dbgcmdnew("setthreadpriority\1setprioritythread\1threadsetpriority", cbDebugSetPriority, true); //set thread priority dbgcmdnew("symdownload\1downloadsym", cbDebugDownloadSymbol, true); //download symbols dbgcmdnew("setjit\1jitset", cbDebugSetJIT, false); //set JIT diff --git a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp index 9fd64d46..688d8b68 100644 --- a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp +++ b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp @@ -586,13 +586,10 @@ void MainWindow::dropEvent(QDropEvent* pEvent) if(pEvent->mimeData()->hasUrls()) { QString filename = QDir::toNativeSeparators(pEvent->mimeData()->urls()[0].toLocalFile()); - if(filename.contains(".exe", Qt::CaseInsensitive) || filename.contains(".dll", Qt::CaseInsensitive)) - { - if(DbgIsDebugging()) - DbgCmdExecDirect("stop"); - QString cmd; - DbgCmdExec(cmd.sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); - } + if(DbgIsDebugging()) + DbgCmdExecDirect("stop"); + QString cmd; + DbgCmdExec(cmd.sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); pEvent->acceptProposedAction(); } } diff --git a/x64_dbg_gui/Project/Src/Gui/StatusLabel.cpp b/x64_dbg_gui/Project/Src/Gui/StatusLabel.cpp index ce27c241..24dde11e 100644 --- a/x64_dbg_gui/Project/Src/Gui/StatusLabel.cpp +++ b/x64_dbg_gui/Project/Src/Gui/StatusLabel.cpp @@ -44,6 +44,7 @@ void StatusLabel::debugStateChangedSlot(DBGSTATE state) default: break; } + this->repaint(); } void StatusLabel::logUpdate(QString message) @@ -52,4 +53,5 @@ void StatusLabel::logUpdate(QString message) labelText = ""; labelText += message; setText(labelText); + this->repaint(); } diff --git a/x64_dbg_launcher/x64_dbg_launcher.cpp b/x64_dbg_launcher/x64_dbg_launcher.cpp index 2239e07d..f4f2ec64 100644 --- a/x64_dbg_launcher/x64_dbg_launcher.cpp +++ b/x64_dbg_launcher/x64_dbg_launcher.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include enum arch { @@ -98,6 +100,59 @@ static void CreateUnicodeFile(const wchar_t* file) CloseHandle(hFile); } +//Taken from: http://www.cplusplus.com/forum/windows/64088/ +static bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize) +{ + if(szResolvedPath == NULL) + return SUCCEEDED(E_INVALIDARG); + + //Initialize COM stuff + CoInitialize(NULL); + + //Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); + if(SUCCEEDED(hres)) + { + //Get a pointer to the IPersistFile interface. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); + if(SUCCEEDED(hres)) + { + //Load the shortcut. + hres = ppf->Load(szShortcutPath, STGM_READ); + + if(SUCCEEDED(hres)) + { + //Resolve the link. + hres = psl->Resolve(hwnd, 0); + + if(SUCCEEDED(hres)) + { + //Get the path to the link target. + char szGotPath[MAX_PATH] = {0}; + hres = psl->GetPath(szGotPath, _countof(szGotPath), NULL, SLGP_SHORTPATH); + + if(SUCCEEDED(hres)) + { + strcpy_s(szResolvedPath, nSize, szGotPath); + } + } + } + + //Release the pointer to the IPersistFile interface. + ppf->Release(); + } + + //Release the pointer to the IShellLink interface. + psl->Release(); + } + + //Uninitialize COM stuff + CoUninitialize(); + return SUCCEEDED(hres); +} + int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { CoInitialize(NULL); //fixed some crash @@ -192,10 +247,15 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi } if(argc == 2) //one argument -> execute debugger { + wchar_t szPath[MAX_PATH] = L""; + wcscpy_s(szPath, argv[1]); + char szResolvedPath[MAX_PATH] = ""; + if(ResolveShortcut(0, szPath, szResolvedPath, _countof(szResolvedPath))) + MultiByteToWideChar(CP_ACP, 0, szResolvedPath, -1, szPath, _countof(szPath)); std::wstring cmdLine = L"\""; - cmdLine += argv[1]; + cmdLine += szPath; cmdLine += L"\""; - switch(GetFileArchitecture(argv[1])) + switch(GetFileArchitecture(szPath)) { case x32: if(sz32Path[0])