我正在尝试调试处于挂起状态的子进程。问题是,当我尝试这样做时,应用程序不会启动(它启动但立即退出)。这有助于防止逆向工程,但我无法做到这一点。
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);
}
}
编辑:VirtualProtectEx 调用失败,它们是实际问题。如果我注释他们的行,应用程序就会执行。它也很滞后,可能是因为调试循环。有解决办法吗?
Edit2:我按照你的建议编辑了代码,除了DEBUG_PROCESS之外,因为它停止了整个过程,我什至无法通过任务管理器杀死它,杀死它的唯一方法是重新启动PC 。也许,我做错了什么,但我不知道是什么。因此消息框出现的顺序是:执行 DebugActiveProcess -> 执行 WaitForDebugEvent -> 执行 CREATE_PROCESS_DEBUG_EVENT -> 执行最后一个ContinueDebugEvent。然后等待... -> CloseHandle -> 继续调试...
最佳答案
1) 当您希望通过 CreateProcess
创建调试进程时设置DEBUG_PROCESS
在dwCreationFlags
2) 在这种情况下永远不要调用 DebugActiveProcess
- 此 api 内部在进程中创建远程线程 - DbgUiRemoteBreakIn
- 因此进程开始初始化不是在主线程中而是在此线程上。说在 xp 上这会导致进程初始化总是失败。后者(从win7开始?)这个修复了。
3) ContinueDebugEvent
需要在每次调试事件之后始终调用。 EXIT_PROCESS_DEBUG_EVENT
之后 - 另外 - 需要了解此消息在退出时发送给进程中的最后一个线程。他等待你的调用 ContinueDebugEvent
- 当你得到 EXIT_PROCESS_DEBUG_EVENT
时,进程仍然存在并且没有终止 - 因此你必须在之后对 ContinueDebugEvent
进行一次公共(public)调用开关
4) 您尝试使用 VirtualProtectEx
执行的操作必须产生无限的 STATUS_GUARD_PAGE_VIOLATION
异常。所以即使不看更多 - “保护”的主要逻辑是无效的
5) 句柄 LOAD_DLL_DEBUG_EVENT
是强制 - 您必须关闭句柄(hFile 到已加载的 DLL)
6) 在CREATE_PROCESS_DEBUG_EVENT
上,您还必须关闭文件句柄
7) 当我们使用 DEBUG_PROCESS
标志调用 CreateProcess
时 - 使用 CREATE_SUSPENDED
- 绝对毫无意义 - 为了什么??通常此标志用于在线程开始在用户模式下执行之前以及在此调用 ResumeThread
之后对进程执行某些任务。但是当我们在进程中使用DEBUG_PROCESS
初始线程时,当它开始执行时(但处于内核模式)发送给我们CREATE_PROCESS_DEBUG_EVENT
并等待回复(直到调试器不调用 ContinueDebugEvent
。因此,我们可以在 CREATE_PROCESS_DEBUG_EVENT
处理程序中完成所有特殊的进程任务。误解 Windows 内部工作方式会导致严重错误
关于c# - 调试ActiveProcess崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44422619/