Launching the JIT debugger when you want.
When you use
SetWindowsHookEx
function or are doing API hooking, most times you need to inject (manually or automatically) a DLL into a target process.
Touching some
registry entries, you can make some process to be launched
always under the control of a debugger but it is not always the desired method specially if you are dealing with system components or when more than one application instance is active.
Also adding
__asm int 3; or calling
DebugBreak() API do not always raise an exception as one might expect.
And if you are fixing bugs, launching the target application inside another instance of Visual Studio may became a pain if you have to repeat the process many times.
With the following code snippets, you can do a self-attach by calling the jit debugger. For e.g., when some exported function of your library is called.
BOOL AttachCurrentProcessToDebugger()
{
STARTUPINFO sSi;
PROCESS_INFORMATION sPi;
TCHAR szBufW[2560];
SIZE_T i;
BOOL b;
DWORD dwExitCode;
if (::IsDebuggerPresent() == FALSE) {
memset(&sSi, 0, sizeof(sSi));
memset(&sPi, 0, sizeof(sPi));
szBufW[0] = L'"';
::GetSystemDirectoryW(szBufW+1, 2000);
i = wcslen(szBufW);
if (i>0 && szBufW[i]!=L'/' && szBufW[i]!=L'\\')
szBufW[i++] = L'\\';
swprintf_s(szBufW+i, 2560-i, L"VSJitDebugger.exe\" -p %lu", ::GetCurrentProcessId());
b = ::CreateProcessW(NULL, szBufW, NULL, NULL, FALSE, 0, NULL, NULL, &sSi, &sPi);
if (b != FALSE) {
::WaitForSingleObject(sPi.hProcess, INFINITE);
::GetExitCodeProcess(sPi.hProcess, &dwExitCode);
if (dwExitCode != 0) b = FALSE;
}
if (sPi.hThread != NULL)
::CloseHandle(sPi.hThread);
if (sPi.hProcess != NULL)
::CloseHandle(sPi.hProcess);
if (b == FALSE)
return FALSE;
for (i=0; i<5*60; i++) {
if (::IsDebuggerPresent() != FALSE)
break;
::Sleep(200);
}
}
#if defined _M_IX86
_asm { int 3 };
#elif defined _M_X64
__debugbreak();
#else
::DebugBreak();
#endif
return TRUE;
}
The code is simple. If the process is not under the control of a debugger, it launches the jit-debugger (usually located in the
System folder) and waits for the debugger attachment.