I'm trying to debug a child process while it's in a suspended state. The problem is that when I attempt to do that, the application doesn't start (it starts but exits instantly). That helps against reverse engineering, but however I can't manage doing it.
static void DebuggingTest(PROCESS_INFORMATION pi, int imageBase, int sizeOfHeaders)
{
int oldProtection = 0;
const uint STATUS_GUARD_PAGE_VIOLATION = 0x80000001;
const int DBG_CONTINUE = 0x00010002;
DEBUG_EVENT evt = new DEBUG_EVENT();
if (!DebugActiveProcess(Convert.ToInt32(pi.dwProcessId)))
throw new Win32Exception();
else
MessageBox.Show(pi.dwProcessId + " process is being debugged.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
while (true)
{
if (!WaitForDebugEvent(out evt, -1))
throw new Win32Exception();
else
MessageBox.Show("WaitForDebugEvent executed.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
switch (evt.dwDebugEventCode)
{
case DebugEventType.CREATE_PROCESS_DEBUG_EVENT:
//if (!VirtualProtectEx(pi.hProcess, imageBase, sizeOfHeaders, 320, ref oldProtection))
// throw new Exception();
ResumeThread(pi.hThread);
MessageBox.Show("CREATE_PROCESS_DEBUG_EVENT executed.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
case DebugEventType.EXCEPTION_DEBUG_EVENT:
if (evt.Exception.ExceptionRecord.ExceptionCode == STATUS_GUARD_PAGE_VIOLATION)
{
if (!VirtualProtectEx(pi.hProcess, imageBase, sizeOfHeaders, 320, ref oldProtection))
throw new Exception();
}
MessageBox.Show("EXCEPTION_DEBUG_EVENT executed.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
case DebugEventType.EXIT_PROCESS_DEBUG_EVENT:
if (!DebugActiveProcessStop(Convert.ToInt32(pi.dwProcessId)))
throw new Win32Exception();
if (!TerminateProcess(pi.hProcess, 0))
throw new Win32Exception();
MessageBox.Show("EXIT_PROCESS_DEBUG_EVENT executed.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
case DebugEventType.LOAD_DLL_DEBUG_EVENT:
if (CloseHandle(evt.LoadDll.hFile))
MessageBox.Show("CloseHandle executed.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
}
if (ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, DBG_CONTINUE))
MessageBox.Show("Last ContinueDebugEvent executed.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
Edit: VirtualProtectEx calls are failing, they are the actual problem. If I comment their lines, the application executes. Also it is lagging, probably because of the debugging loop. Is there a solution for it?
Edit2: I edited the code as you suggested me, apart from DEBUG_PROCESS, because it stops the whole process, I can't even kill it through Task Manager, the only way to kill it, is to restart PC. Perhaps, I'm doing something wrong, but I don't know what. So the order the messageboxes appear: DebugActiveProcess executed -> WaitForDebugEvent executed -> CREATE_PROCESS_DEBUG_EVENT executed -> Last ContinueDebugEvent executed. Then Wait... -> CloseHandle -> ContinueDebug...
1) when you want debug process created via CreateProcess
set the DEBUG_PROCESS
in dwCreationFlags
2) never call DebugActiveProcess
in this case - this api internal create remote thread in process - DbgUiRemoteBreakIn
- so process begin initialize not in it main thread but on this thread. say on xp this cause process initialization fail always. latter (begin form win7 ?) this fixed.
3) ContinueDebugEvent
need call always, after every debug event. after EXIT_PROCESS_DEBUG_EVENT
- also - need understand that this message send to you last thread in process when it exited. and he wait for your call ContinueDebugEvent
- process still alive and not terminated when you got EXIT_PROCESS_DEBUG_EVENT
- so you must have one common call to ContinueDebugEvent
after swith
4) what you try todo with VirtualProtectEx
must make infinite STATUS_GUARD_PAGE_VIOLATION
exceptions. so even not look more - main logic of "protection" is invalid
5) handle LOAD_DLL_DEBUG_EVENT
is mandatory - you must close handle (hFile to the loaded DLL)
6) on CREATE_PROCESS_DEBUG_EVENT
you also must close handle to file
7) when we call CreateProcess
with DEBUG_PROCESS
flag - use the CREATE_SUSPENDED
- absolutely senseless - for what ?? usually this flag used for do some task with process, before it thread begin execute in user mode and after this call ResumeThread
. but when we use DEBUG_PROCESS
initial thread in process, when it begin execute (yet in kernel mode) send to us CREATE_PROCESS_DEBUG_EVENT
and wait for reply (until debugger not call ContinueDebugEvent
. as result all special task with process we can done in CREATE_PROCESS_DEBUG_EVENT
handler. misunderstandings how windows work internal leads to gross errors
User contributions licensed under CC BY-SA 3.0