LAUNCHER+DBG: add support for PID attaching + PLMDebug in the command line
closes #1698
This commit is contained in:
parent
948c40eb1a
commit
80210eb9b0
|
|
@ -167,13 +167,6 @@ bool cbDebugAttach(int argc, char* argv[])
|
|||
duint pid = 0;
|
||||
if(!valfromstring(argv[1], &pid, false))
|
||||
return false;
|
||||
if(argc > 2)
|
||||
{
|
||||
duint eventHandle = 0;
|
||||
if(!valfromstring(argv[2], &eventHandle, false))
|
||||
return false;
|
||||
dbgsetattachevent((HANDLE)eventHandle);
|
||||
}
|
||||
if(DbgIsDebugging())
|
||||
DbgCmdExecDirect("stop");
|
||||
Handle hProcess = TitanOpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);
|
||||
|
|
@ -202,6 +195,22 @@ bool cbDebugAttach(int argc, char* argv[])
|
|||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not get module filename %X!\n"), DWORD(pid));
|
||||
return false;
|
||||
}
|
||||
if(argc > 2) //event handle (JIT)
|
||||
{
|
||||
duint eventHandle = 0;
|
||||
if(!valfromstring(argv[2], &eventHandle, false))
|
||||
return false;
|
||||
if(eventHandle)
|
||||
dbgsetattachevent((HANDLE)eventHandle);
|
||||
}
|
||||
if(argc > 3) //thread id to resume (PLMDebug)
|
||||
{
|
||||
duint tid = 0;
|
||||
if(!valfromstring(argv[3], &tid, false))
|
||||
return false;
|
||||
if(tid)
|
||||
dbgsetresumetid(tid);
|
||||
}
|
||||
CloseHandle(CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ static bool bBreakOnNextDll = false;
|
|||
static bool bFreezeStack = false;
|
||||
static std::vector<ExceptionRange> ignoredExceptionRange;
|
||||
static HANDLE hEvent = 0;
|
||||
static duint tidToResume = 0;
|
||||
static HANDLE hProcess = 0;
|
||||
static HANDLE hMemMapThread = 0;
|
||||
static bool bStopMemMapThread = false;
|
||||
|
|
@ -289,6 +290,11 @@ void dbgsetattachevent(HANDLE handle)
|
|||
hEvent = handle;
|
||||
}
|
||||
|
||||
void dbgsetresumetid(duint tid)
|
||||
{
|
||||
tidToResume = tid;
|
||||
}
|
||||
|
||||
void dbgsetskipexceptions(bool skip)
|
||||
{
|
||||
bSkipExceptions = skip;
|
||||
|
|
@ -1923,6 +1929,11 @@ static void cbAttachDebugger()
|
|||
SetEvent(hEvent);
|
||||
hEvent = 0;
|
||||
}
|
||||
if(tidToResume) //Resume a thread
|
||||
{
|
||||
cmddirectexec(StringUtils::sprintf("resumethread %p", tidToResume).c_str());
|
||||
tidToResume = 0;
|
||||
}
|
||||
hProcess = fdProcessInfo->hProcess;
|
||||
varset("$hp", (duint)fdProcessInfo->hProcess, true);
|
||||
varset("$pid", fdProcessInfo->dwProcessId, true);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ duint dbggettimewastedcounter();
|
|||
bool dbgisrunning();
|
||||
bool dbgisdll();
|
||||
void dbgsetattachevent(HANDLE handle);
|
||||
void dbgsetresumetid(duint tid);
|
||||
void DebugUpdateGui(duint disasm_addr, bool stack);
|
||||
void DebugUpdateGuiAsync(duint disasm_addr, bool stack);
|
||||
void DebugUpdateGuiSetStateAsync(duint disasm_addr, bool stack, DBGSTATE state = paused);
|
||||
|
|
|
|||
|
|
@ -732,18 +732,23 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
dputs(QT_TRANSLATE_NOOP("DBG", "Loading plugins..."));
|
||||
pluginloadall(plugindir);
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Handling command line..."));
|
||||
dprintf(" %s\n", StringUtils::Utf16ToUtf8(GetCommandLineW()).c_str());
|
||||
//handle command line
|
||||
int argc = 0;
|
||||
wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
//MessageBoxW(0, GetCommandLineW(), StringUtils::sprintf(L"%d", argc).c_str(), MB_SYSTEMMODAL);
|
||||
if(argc == 2) //1 argument (init filename)
|
||||
DbgCmdExec(StringUtils::Utf16ToUtf8(StringUtils::sprintf(L"init \"%s\"", escape(argv[1]).c_str())).c_str());
|
||||
else if(argc == 3 && !_wcsicmp(argv[1], L"-p")) //2 arguments (-p PID)
|
||||
DbgCmdExec(StringUtils::Utf16ToUtf8(StringUtils::sprintf(L"attach .%s", argv[2])).c_str()); //attach pid
|
||||
else if(argc == 3) //2 arguments (init filename, cmdline)
|
||||
DbgCmdExec(StringUtils::Utf16ToUtf8(StringUtils::sprintf(L"init \"%s\", \"%s\"", escape(argv[1]).c_str(), escape(argv[2]).c_str())).c_str());
|
||||
else if(argc == 4) //3 arguments (init filename, cmdline, currentdir)
|
||||
DbgCmdExec(StringUtils::Utf16ToUtf8(StringUtils::sprintf(L"init \"%s\", \"%s\", \"%s\"", escape(argv[1]).c_str(), escape(argv[2]).c_str(), escape(argv[3]).c_str())).c_str());
|
||||
else if(argc == 5 && !_wcsicmp(argv[1], L"-a") && !_wcsicmp(argv[3], L"-e")) //4 arguments (JIT)
|
||||
DbgCmdExec(StringUtils::Utf16ToUtf8(StringUtils::sprintf(L"attach .%s, .%s", argv[2], argv[4])).c_str()); //attach pid, event
|
||||
else if(argc == 5 && !_wcsicmp(argv[1], L"-p") && !_wcsicmp(argv[3], L"-tid")) //4 arguments (PLMDebug)
|
||||
DbgCmdExec(StringUtils::Utf16ToUtf8(StringUtils::sprintf(L"attach .%s, 0, .%s", argv[2], argv[4])).c_str()); //attach pid, 0, tid
|
||||
LocalFree(argv);
|
||||
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "Initialization successful!"));
|
||||
|
|
|
|||
|
|
@ -352,6 +352,28 @@ static BOOL CALLBACK DlgLauncher(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static bool convertNumber(const wchar_t* str, unsigned long & result, int radix)
|
||||
{
|
||||
errno = 0;
|
||||
wchar_t* end;
|
||||
result = wcstoul(str, &end, radix);
|
||||
if(!result && end == str)
|
||||
return false;
|
||||
if(result == ULLONG_MAX && errno)
|
||||
return false;
|
||||
if(*end)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parseId(const wchar_t* str, unsigned long & result)
|
||||
{
|
||||
int radix = 10;
|
||||
if(!wcsncmp(str, L"0x", 2))
|
||||
radix = 16, str += 2;
|
||||
return convertNumber(str, result, radix);
|
||||
}
|
||||
|
||||
const wchar_t* SHELLEXT_EXE_KEY = L"exefile\\shell\\Debug with x64dbg\\Command";
|
||||
const wchar_t* SHELLEXT_ICON_EXE_KEY = L"exefile\\shell\\Debug with x64dbg";
|
||||
const wchar_t* SHELLEXT_DLL_KEY = L"dllfile\\shell\\Debug with x64dbg\\Command";
|
||||
|
|
@ -417,9 +439,26 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||
_tcscpy_s(sz64Dir, sz64Path);
|
||||
PathRemoveFileSpec(sz64Dir);
|
||||
|
||||
//Functions to load the relevant debugger with a command line
|
||||
auto load32 = [](const wchar_t* cmdLine)
|
||||
{
|
||||
if(sz32Path[0])
|
||||
ShellExecute(nullptr, TEXT("open"), sz32Path, cmdLine, sz32Dir, SW_SHOWNORMAL);
|
||||
else
|
||||
MessageBox(nullptr, LoadResString(IDS_INVDPATH32), LoadResString(IDS_ERROR), MB_ICONERROR);
|
||||
};
|
||||
auto load64 = [](const wchar_t* cmdLine)
|
||||
{
|
||||
if(sz64Path[0])
|
||||
ShellExecute(nullptr, TEXT("open"), sz64Path, cmdLine, sz64Dir, SW_SHOWNORMAL);
|
||||
else
|
||||
MessageBox(nullptr, LoadResString(IDS_INVDPATH64), LoadResString(IDS_ERROR), MB_ICONERROR);
|
||||
};
|
||||
|
||||
//Handle command line
|
||||
auto argc = 0;
|
||||
auto argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
unsigned long pid = 0;
|
||||
if(argc <= 1) //no arguments -> launcher dialog
|
||||
{
|
||||
if(!FileExists(sz32Path) && BrowseFileOpen(nullptr, TEXT("x32dbg.exe\0x32dbg.exe\0\0"), nullptr, sz32Path, MAX_PATH, szCurrentDir))
|
||||
|
|
@ -475,6 +514,32 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||
if(bDoneSomething)
|
||||
MessageBox(nullptr, LoadResString(IDS_NEWCFGWRITTEN), LoadResString(IDS_DONE), MB_ICONINFORMATION);
|
||||
}
|
||||
else if(argc >= 3 && !wcscmp(argv[1], L"-p") && parseId(argv[2], pid)) //-p PID
|
||||
{
|
||||
wchar_t cmdLine[32] = L"";
|
||||
unsigned long tid;
|
||||
if(argc >= 5 && !wcscmp(argv[3], L"-tid") && parseId(argv[4], tid)) //-p PID -tid TID
|
||||
wsprintfW(cmdLine, L"-p %u -tid %u", pid, tid);
|
||||
else
|
||||
wsprintfW(cmdLine, L"-p %u", pid);
|
||||
if(isWoW64())
|
||||
{
|
||||
auto hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
||||
if(hProcess)
|
||||
{
|
||||
BOOL bWow64Process = FALSE;
|
||||
if(IsWow64Process(hProcess, &bWow64Process) && bWow64Process)
|
||||
load32(cmdLine);
|
||||
else
|
||||
load64(cmdLine);
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
else
|
||||
load64(cmdLine);
|
||||
}
|
||||
else
|
||||
load32(cmdLine);
|
||||
}
|
||||
else if(argc >= 2) //one or more arguments -> execute debugger
|
||||
{
|
||||
BOOL canDisableRedirect = FALSE;
|
||||
|
|
@ -541,37 +606,22 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||
//MessageBoxW(0, GetCommandLineW(), L"GetCommandLineW", MB_SYSTEMMODAL);
|
||||
//MessageBoxW(0, szCurDir, L"GetCurrentDirectory", MB_SYSTEMMODAL);
|
||||
|
||||
auto load32 = [&]()
|
||||
{
|
||||
if(sz32Path[0])
|
||||
ShellExecute(nullptr, TEXT("open"), sz32Path, cmdLine.c_str(), sz32Dir, SW_SHOWNORMAL);
|
||||
else
|
||||
MessageBox(nullptr, LoadResString(IDS_INVDPATH32), LoadResString(IDS_ERROR), MB_ICONERROR);
|
||||
};
|
||||
auto load64 = [&]()
|
||||
{
|
||||
if(sz64Path[0])
|
||||
ShellExecute(nullptr, TEXT("open"), sz64Path, cmdLine.c_str(), sz64Dir, SW_SHOWNORMAL);
|
||||
else
|
||||
MessageBox(nullptr, LoadResString(IDS_INVDPATH64), LoadResString(IDS_ERROR), MB_ICONERROR);
|
||||
};
|
||||
|
||||
switch(GetPeArch(szPath))
|
||||
{
|
||||
case PeArch::Native86:
|
||||
case PeArch::Dotnet86:
|
||||
case PeArch::DotnetAnyCpuPrefer32:
|
||||
load32();
|
||||
load32(cmdLine.c_str());
|
||||
break;
|
||||
case PeArch::Native64:
|
||||
case PeArch::Dotnet64:
|
||||
load64();
|
||||
load64(cmdLine.c_str());
|
||||
break;
|
||||
case PeArch::DotnetAnyCpu:
|
||||
if(isWoW64())
|
||||
load64();
|
||||
load64(cmdLine.c_str());
|
||||
else
|
||||
load32();
|
||||
load32(cmdLine.c_str());
|
||||
break;
|
||||
case PeArch::Invalid:
|
||||
if(FileExists(szPath))
|
||||
|
|
|
|||
Loading…
Reference in New Issue