views:

92

answers:

2

I'm starting an Explorer.exe instance with CreateProcess (flags NORMAL_PRIORITY_CLASS + DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS), and then I'm doing this:

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;

Everything almost works OK, except I'm getting a lot of EXCEPTION_DEBUG_EVENTs from what appears to be "C:\Windows\System32\rpcrt4.dll"

(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

What am I doing wrong? How do I fix it?

I'm using Delphi 7, btw.

+1  A: 

Why do you assume there's anything wrong with your code? A debugger gets a first-chance notifications for any SEH exception. You are debugging an enormous amount of code. Not just Explorer.exe, you also get all of the shell extension handlers. There's plenty of crud around, Explorer does its best to stay alive even when those extensions have bugs.

If you actually want to solve this, not a bad idea, then use SysInternals' Autoruns utility and disable any shell extension handler that wasn't made by Microsoft and you don't really need. If you want to test your debugger then try something more innocent like Notepad.exe. Although File + Open brings those shell extensions back.

Hans Passant
What I mean is my code needs to work no matter what shell extensions are installed. What I'd like to know is what am I doing wrong that is triggering the exceptions. The exceptions keep coming at such rate that Explorer.exe becomes unusable.
TheDelphiGuy
And it's not really a debugger. What I'm trying is more like protecting Explorer.exe from unwanted intrusions.
TheDelphiGuy
Erm, Windows doesn't know that you don't want to be a debugger. You asked for it, you got it.
Hans Passant
Indeed, I'm aware of that. As I said the thing is Explorer becomes unusable with the flood. Either the exceptions were already being triggered (which I doubt), and the debug notifications are making the process too slow, or somehow I'm provoking these exceptions, even if indirectly. I just don't see how I might be able to fix this.
TheDelphiGuy
I don't see it either. Looks like your base assumption that you could use the debugger API to make this work is all shot to pieces.
Hans Passant
Well, if you check Google for those keywords, it seems a lot of viruses and trojans manage to do something like it, without any problem.
TheDelphiGuy
+3  A: 

Your code is fine, testing using other debuggers, like ollydbg, rpcrt4.dll still reports exceptions on attaching to some applications. The only way around this to be define filters(what ollydbg allows the user to do), based on the exception code, then based on the module. Thus if you recieve 0xC0000005(EXCEPTION_ACCESS_VIOLATION), you check for: EIP >= (UINT_PTR)GetModuleHandle("rpcrt.dll") && EIP <= (UINT_PTR)GetModuleHandle("rpcrt.dll") + getModuleSize("rpcrt.dll") (of course getModuleSize is a custom func to get the modules virtualized size from the PE, and UINT_PTR is a type big enough to hold a pointer on your target system), you ignore it, else process the event, though might be require hooks into KiDispatchUserException(this should be the right one, else check NTInternals)

Necrolis