MCH and SEH

c++ / delphi package - dll injection and api hooking

MCH and SEH

Postby EaSy » Mon Jun 20, 2016 7:12 am

Hi,
i'd like to solve an issue with MCH hooks breaking the SEH handling when the default setting.

Let's say we hook RPC function NdrClientCall2. RPC error reporting relies on exceptions. The problem is that MCH modifies return address to watch the hook counts. So once the exception is raised it does not propagate to the top of the stack and it ends as an unhandled exception.

Is there any way to enable SEH propagation in the MCH hooks? One way is to use NO_HOOK_COUNT flag, but that is only temporary solution, because app will then crash sometimes in manual unhooking.

One way would be to repair stack (that return address that MCH modifies) in the hook which i succesfully tried and it worked then. But the problem is the exception itself, because it does not call your "lower the hook count code" in the hook return so introducing a deadlock. It needs to be fixed by own exception handler that does calls your code "lower the hook count code" and then continues an exception.

It would nice to have some API for "fix ret address and handle SEH exception built-in MCH library". It would be also nice to have this feature available in all of the MCH hooks. Also debuggers stack trace will work better.

Any thoughts?

Sicerely
PP
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby madshi » Mon Jun 20, 2016 7:19 am

Interesting problem. And a rather difficult one. Especially x64 will be tricky because the x64 exception handling is so much different. Basically each dll/exe has a list of except handlers. But the hook stubs installed by madExcept are dynamically created, so they don't have a registered except handler.

I'll add this as a possible feature to my madCodeHook 4.0 to do list, but I'm not sure yet if I'll be able to pull this off completely automatically in both x86 and x64.
madshi
Site Admin
 
Posts: 9199
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH and SEH

Postby EaSy » Mon Jun 20, 2016 7:27 am

Well,
as i think about that the best way would be not to modify ret address before the hook call, but at the end of that. So for the whole time of the hook and orig call the ret address will be original, but at the end of the hook we manually call function MchFixRetAddress. This function woud know the stack address of the last ret address of the caller of the hook and change it as your code does it now.
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby madshi » Mon Jun 20, 2016 7:29 am

But that wouldn't help with "in use" counter. It would still not be decreased, making madCodeHook believe that the hook callback function is still in use.
madshi
Site Admin
 
Posts: 9199
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH and SEH

Postby EaSy » Mon Jun 20, 2016 7:31 am

now:

caller calls Orig
jmp Hook, count++, modify ret address
Hook BC
call Orig
Hook AC
count--, jmp Orig Caller

new

caller calls Orig
jmp Hook, count++
Hook BC
call Orig
Hook AC, modify ret address
count--, jmp Orig Caller
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby EaSy » Mon Jun 20, 2016 7:32 am

i see, in case of wxception it wont work
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby madshi » Mon Jun 20, 2016 7:52 am

An exception in the hooked API is really problematic. I think I do need to add an option to HookAPI() to enable "exception passthrough". But as I said, it will be *very* difficult to achieve, especially in x64.
madshi
Site Admin
 
Posts: 9199
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH and SEH

Postby EaSy » Mon Jun 20, 2016 7:57 am

what if we add try-finally in our hook and call some MCH api to lower the count?

and use function if AbnormalTermination
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby madshi » Mon Jun 20, 2016 8:02 am

EaSy wrote:what if we add try-finally in our hook and call some MCH api to lower the count?

Hmmmm... Good thinking, I think that should work! At least as a workaround, until I (maybe) manage to implement this properly in madCodeHook.
madshi
Site Admin
 
Posts: 9199
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH and SEH

Postby EaSy » Mon Jun 20, 2016 8:13 am

Great,
are you able to add some support to the MCH beta for this? It would help us to use RPC calls with MCH hook counting enabled!

Thx.
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby EaSy » Mon Jun 20, 2016 8:16 am

One more problem comes in my mind is the EXCEPTION_CONTINUE_EXECUTION, does it mean that we will still need to have ret address fixed during the RaiseException? Because i think that finally is not called in this case during the exception.
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby EaSy » Mon Jun 20, 2016 8:25 am

so we need something like this?

now:

caller calls Orig
count++, modify ret address, jmp Hook
Hook BC
call Orig
Hook AC
ret
count--, jmp Orig Caller

new

caller calls Orig
count++, jmp Hook
try {
Hook BC
call Orig
Hook AC
}
finally { count-- }
modify ret address
ret
count--, jmp Orig Caller

EDIT: i changed the code, because finally behaves differently in SEH
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby madshi » Mon Jun 20, 2016 1:34 pm

Oh well, I think I misjudged it. For some reason I thought that your try..finally block would be "outside" of madCodeHook's hook stubs. But it would be inside, which makes things so much more complicated. I suppose you could use a try..except block instead of a try..finally block, and then in the except block decrease the "in use" counter *and* fix the return address, and then re-raise the exception. But that sounds really awful.
madshi
Site Admin
 
Posts: 9199
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH and SEH

Postby EaSy » Tue Jun 21, 2016 8:58 am

I was able to implement SEH handling using __finally. It is very very ugly since I have to abuse your counting trampoline and fix ret address during the origcall processing both for 32b and 64b and call that trampoline manually in case of exception. But it works and SEH is propagated up the stack now. :D

This won't be crash free 100% since the __finally handler is in our DLL and it is not part of your hook trampoline, but I think we can live with 99% for now.

The best solution would be to support propagating SEH exceptions natively in all MCH hooks, but that is something you need to implement something like __try _finally in your trampoline and fix the stack accordingly. On 64b you said it is harder, but you could use this function RtlInstallFunctionTableCallbackmto register that callback.

PP
EaSy
 
Posts: 146
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH and SEH

Postby madshi » Tue Jun 21, 2016 12:38 pm

Yes, I'm aware of RtlInstallFunctionTableCallback, it's still not an easy thing to implement in a dynamically created assembler stub. Not something I want to introduce in a minor madCodeHook 3.x build, especially since I'm already working on v4. But it's on my to do list...
madshi
Site Admin
 
Posts: 9199
Joined: Sun Mar 21, 2004 5:25 pm


Return to madCodeHook

Who is online

Users browsing this forum: No registered users and 1 guest

cron