我正在使用CreateProcess启动一个Explorer.exe实例(标志NORMAL_PRIORITY_CLASS + DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS),然后我这样做:
procedure FakeDebugProcess; var wDebugEvent : DEBUG_EVENT; begin fillchar( wDebugEvent, sizeof( wDebugEvent ), 0 ); repeat if WaitForDebugEvent( wDebugEvent, INFINITE ) then begin if wDebugEvent.dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT then break; ContinueDebugEvent( wDebugEvent.dwProcessId, wDebugEvent.dwThreadId, DBG_CONTINUE ); end; until false; end;
一切都差不多好了,除了我从“C:\ Windows \ System32 \ rpcrt4.dll”中获得了很多EXCEPTION_DEBUG_EVENT
(AdditionalDetails:EXCEPTION_ACCESS_VIOLATION)
77ea3c00 sub_77ea3c00: ; function entry point 77ea3c00 >>mov [ecx+4], eax 77ea3c03 movsx eax, bx 77ea3c06 cdq 77ea3c07 sub eax, edx 77ea3c09 sar eax, 1 77ea3c0b mov [ecx], ax 77ea3c0e xor eax, eax 77ea3c10 pop edi 77ea3c11 pop esi 77ea3c12 pop ebx 77ea3c13 pop ebp 77ea3c14 ret 8
我做错了什么?我该如何解决?
我正在使用Delphi 7,顺便说一句。
答案 0 :(得分:4)
您的代码很好,使用其他调试器进行测试,例如ollydbg,rpcrt4.dll仍会报告附加到某些应用程序的异常。根据异常代码,然后基于模块定义过滤器(ollydbg允许用户做什么)的唯一方法。因此,如果您收到0xC0000005(EXCEPTION_ACCESS_VIOLATION),则检查:EIP >= (UINT_PTR)GetModuleHandle("rpcrt.dll") && EIP <= (UINT_PTR)GetModuleHandle("rpcrt.dll") + getModuleSize("rpcrt.dll")
(当然getModuleSize是一个自定义函数,用于从PE获取模块的虚拟大小,而UINT_PTR是一个足以在目标上保存指针的类型系统),你忽略它,否则处理事件,虽然可能需要钩入KiDispatchUserException(这应该是正确的,否则检查NTInternals)
答案 1 :(得分:3)
我知道这个帖子已经老了,但我有同样的问题并解决了,所以我想我会分享。
如果启动进程并希望使用Windows API调用对其进行调试,则应该知道Windows首次加载时将发送一个EXCEPTION_BREAKPOINT(INT3)。您必须DEBUG_CONTINUE第一个断点异常...如果您有DBG_EXCEPTION_NOT_HANDLED,您将收到弹出消息框:应用程序无法正确初始化(0x80000003)。
现在,对于所有其他异常,您希望返回DBG_EXCEPTION_NOT_HANDLED,以便它们被传回和处理。在Windows生成第一个断点异常之后,您可以随意设置其他断点。
调试循环的简化代码如下所示:
// debug loop... while(debugging) or whatever you want to do.
DEBUG_EVENT DebugEvent;
DWORD ContinueStatus = DBG_CONTINUE;
WaitForDebugEvent(&DebugEvent, INFINITE);
switch (DebugEvent.dwDebugEventCode) {
case EXCEPTION_DEBUG_EVENT:
switch(DebugEvent.u.Exception.ExceptionRecord.ExceptionCode) {
case EXCEPTION_BREAKPOINT:
// stay with DBG_CONTINUE at least for the first breakpoint.
// continue, don't pass this back to process being debugged.
break;
default:
// handles all other stuff like EXCEPTION_ACCESS_VIOLATION
// pass these back to the process being debugged...
ContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
break;
}
break;
default:
break;
}
ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, ContinueStatus);
基础:
答案 2 :(得分:1)
为什么你认为你的代码有什么问题?调试器获得任何SEH异常的第一次机会通知。您正在调试大量代码。不仅是Explorer.exe,您还可以获得所有shell扩展处理程序。周围有很多问题,即使这些扩展存在漏洞,Explorer也会尽力保持活力。
如果您真的想要解决这个问题,那么请使用SysInternals的Autoruns实用程序并禁用任何非Microsoft制作的shell扩展处理程序,而您实际上并不需要。如果你想测试你的调试器,那就试试像Notepad.exe这样无辜的东西吧。虽然File + Open会带回那些shell扩展。