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])