Click here to Skip to main content
Click here to Skip to main content

Self-debugger attach to process

, 14 Sep 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
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) //if exit code is zero, a debugger was selected
        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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mauro Leggieri
Web Developer
Argentina Argentina
My name is Mauro Leggieri. I am 30 year-old, married and have a child.
 
I am a system engineer (UTN university) and am being programming for more than 20 years from the C64 to the PC and some microcontrollers.
 
Mostly of my time, I program games for Windows.
 
Soon, my site http://www.mauroleggieri.com.ar

Comments and Discussions

 
GeneralReason for my vote of 5 Isnt it easier to modify the regist... Pinmembermagicpapacy7-Oct-11 16:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141022.2 | Last Updated 14 Sep 2011
Article Copyright 2011 by Mauro Leggieri
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid