Corrected code to support proper C++ stack unwinding. Ofc it will only work if handler is a C++ one.
Corrected code to support proper C++ stack unwinding. Ofc it will only work if handler is a C++ one.
Bump. Are you still alive Cromon?
Im still alive but pretty pissed when it comes to coding. Maybe its the weather, all i did the past few weeks was updating my skype UI and that black market thingy (which took me half an hour).... I totally have to get back on this project but i guess it will be after xmas... I opened several of my projects, looked at them and was like "Meh, maybe tomorrow."![]()
Cypher will get his wish....
![]()
The problem with this (we tried this method) is that the C++ runtimes do extra checks (at least Microsofts C++ runtime does). You have to force their function to return true for all handlers, or it will not work, even with this method.
The way I did it was that I inserted a fake table entry into 'LdrpInvertedFunctionTable' which causes RtlIsValidHandler (or whatever the name was) to access violate when called. I catch this exception with a VEH and manually unwind the stack and registers to make it seem like the call returned 1. The issues with this is that it requires a few magic offsets (LdrpInvertedFunctionTableSRWLock, LdrpInvertedFunctionTable and the address at which RtlIsValidHandler crashes - all of these can be gotten from symbols). When you're down this path you might as well just patch RtlIsValidHandler, but this way is slightly less detectable at least.
[16:15:41] Cypher: caus the CPU is a dick
[16:16:07] kynox: CPU is mad
[16:16:15] Cypher: CPU is all like
[16:16:16] Cypher: whatever, i do what i want
Strange, because i tested it on vc90-vc110 runtimes and everything worked perfectly. Maybe you can give me some code where it fails?
You have enabled DEP, SafeSEH, SEHOP, and ASLR already, right? Other than that I can't think of any cases off the top of my head, it was so long since we looked at it. I might have another look tonight or tomorrow. Really busy over the next week though, so I'll see...
EDIT:
Also, I'm assuming you're doing your tests by using a DLL that is actually being manually mapped into the address space of your target process (which contains the VEH). You can't do the tests from a regularly mapped image, or you won't get the right results.
Last edited by Cypher; 12-15-2012 at 04:00 PM.
Yes, everything is enabled, despite the SEHOP being disabled on client OS's by default.You have enabled DEP, SafeSEH, SEHOP, and ASLR already, right?
I'm using my mapper to map Dll and handler itself into process.Also, I'm assuming you're doing your tests by using a DLL that is actually being manually mapped into the address space of your target process
I notice you said earlier that you tested your code on /EHa. How does it fare under /EHsc (which is the more 'standard' configuration), for both regular SEH (__try/__catch), and C++ EH (try/catch). I'm quite curious, becuase MaiN and I did try what you are doing a while back, and we ran into problems. I can't for the life of me remember what our failing test case was though. >.<
Did some retesting. Everything works in /EHsc just like it does in /EHa (except for catching SE with C++ handlers ofc). Tested both static and dynamic CRT. I can only guess that you have tried it in x64.
I've taken a look today into x64 C++ EH, and found that source of all problems is RtlPcToFileHeader that returns 0 as ImageBase for exception address. But VEH can fix this as always(but unfortunately is uses a dirty hack
)
PHP Code:
// taken from CRT include <Ehdata.h>
#define EH_MAGIC_NUMBER1 0x19930520
#define EH_PURE_MAGIC_NUMBER1 0x01994000
LONG CALLBACK VectoredHandler64( _In_ PEXCEPTION_POINTERS ExceptionInfo )
{
// Assume this is our exception because of ImageBase = 0 and not suitable magic number
// Not sure if this is 100% valid assumption though
if(ExceptionInfo->ExceptionRecord->ExceptionInformation[0] == EH_PURE_MAGIC_NUMBER1
&& ExceptionInfo->ExceptionRecord->ExceptionInformation[3] == 0)
{
// magic number (didn't bother to look if it depends on CRT version; this is for vc110)
ExceptionInfo->ExceptionRecord->ExceptionInformation[0] = (ULONG_PTR)EH_MAGIC_NUMBER1;
// fix exception image base
ExceptionInfo->ExceptionRecord->ExceptionInformation[3] = (ULONG_PTR)s_TargetImageBase; // actual image base of mapped dll
}
return EXCEPTION_CONTINUE_SEARCH;
}
so what does it do