Log in

View Full Version : problem with SEH


Elenil
August 27th, 2009, 18:24
hello i got a problem with SEH

push offset MY_EXCEPTION
push dword ptr fs:[0]
mov dword ptr fs:[0], esp
xor eax,eax
mov ebx,[eax] // make dummy error



MY_EXCEPTION:
// some handling code here but it never reach here



im noob with SEH but what could be reason it never reach my handler what i called MY_EXCEPTION ?

Ricardo Narvaja
August 27th, 2009, 18:47
safeseh?

ricnar

Elenil
August 27th, 2009, 20:10
i could solve the problem else
but still i debugged a method what exactly doing the code i posted above his dont crash
mine do

D-Jester
August 27th, 2009, 21:06
I'm not sure...try call INT3 like this

PUSH OFFSET MY_EXCEPTION
PUSH DWORD PTR FS:[0]
MOV DWORD PTR FS:[0], ESP
MOV EAX, 000000CC
CALL EAX
..
..
..
MY_EXCEPTION:

evlncrn8
August 28th, 2009, 05:58
that wont call an int 3, it'll try and run code from 0xCC in memory, which will cause a crash due to that area of memory being inaccessible
same as

xor eax,eax
mov eax, [eax]

would do..

D-Jester
August 28th, 2009, 14:00
Yeah you're right. I dunno what I was thinking.

Kayaker
August 28th, 2009, 15:56
As a side note, I found this a very good article

Reversing Microsoft Visual C++ Part I: Exception Handling
http://www.openrce.org/articles/full_view/21

Mind you, while it gets pretty complex, the IDC scripts supplied are useful for defining the more advanced exception handlers such as those that use a scopetable, recognized by a different format from the simple inline SEH.

push ebp
mov ebp, esp
push -1
push offset _func1_scopetable
push offset _except_handler3
mov eax, large fs:0
push eax
mov large fs:0, esp

Scopetable is an array of records which describe each __try block and relationships between them:

Code:
struct _SCOPETABLE_ENTRY {
DWORD EnclosingLevel;
void* FilterFunc;
void* HandlerFunc;
}


IDA Scripts: Microsoft VC++ Reversing Helpers
http://www.openrce.org/downloads/details/196

Elenil
August 28th, 2009, 18:15
pretty complex what you posted kayaker ty
sorry i didnt make it clear i didnt want create a int 3 i wanted to catch the "test dummy error" with the asm code i posted

BanMe
August 28th, 2009, 18:32
http://www.rohitab.com/sourcecode/seh.html that should help.. to be more poignant..Your code is wrong..
push = +4 to esp

so..say esp == 0x1000
Code:

push My_Handler //0x1004
push fs:[0] //0x1008
mov fs:[0],esp //esp (0x1008 to fs:[0])
//not My_Handler to fs:[0]...


to fix this, code such as the macros on rohitab should be able to guide you

regards BanMe

Elenil
August 28th, 2009, 19:35
hi BanMe ty for your answer
doesnt the code on rohitab come with the same conditions ?
this:
mov esi, offset Handler
push esi
push dword ptr fs:[0]
mov dword ptr fs:[0], esp

Handler:

compared with that:

push offset MY_EXCEPTION
; sounds same as mov esi,MY_EXCEPTION then push esi
push dword ptr fs:[0]
mov dword ptr fs:[0], esp

MY_EXCEPTION:

BanMe
August 28th, 2009, 20:16
yea I was wrong,and you are correct in that the code is congruent.. I forgot about the SEH chain as it has been a while since I did Asm SEH. I make mistakes, I am human sadly..So if both codes insert the handler properly and if both don't call the 'handler' then the program is not generating a exception properly... does the program error and crash? If it does then you are generating the error properly and its not catching it.. :[ if that is the case.. I'm not sure how to continue further :[

BanMe

Elenil
August 28th, 2009, 21:59
i did wrote the routine in the softice driver dbgmsg.sys but using that on the error instruction -> bsod
that code i wrote above works in a SSDT function but i dont know the reason why it bsod on the place i created it
basicly i solved that with MmIsAddressValid so its nvm anymore but it would good to know if this dont work on some conditions
the patched dbgmsg.sys is avalible with IceStealth and the int2d problem is gone

BanMe
August 28th, 2009, 22:45
http://www.osronline.com/showThread.CFM?link=133781 here is what little I could find ill post some more if it pertains to kernel mode..some ppl there say a BSOD cannot be avoided with SEH,and some that say it can..my thought is you should 'code' a SEH only if there is no other way to accomplish the task(ie redundancy) without hitting a errors..parameter validation might help there..especially in kmode..

BanMe

Kayaker
August 29th, 2009, 02:43
Ah you didn't mention you were mucking around patching drivers, I shoulda known Elenil

I don't know if you can use simple SEH for that. The WDK states that you must wrap a try/except block around driver code which might generate an exception. From the sounds of it, an access violation, such as writing to a read-only page, will still generate a BSOD, even with an exception handler in place. I think that's what the guy in OSR was getting at.

Take a look at Four-F's MASM KMD docs, he may have written some try/except macros you can use.


Here is what a basic try/except block looks like as generated by VC6++. It is of a scopetable type like mentioned above.


Basic try/except block wrapped around a simple inline _asm{nop}:

Code:

void TestSEH()
{
__try {

_asm{nop}

} __except (EXCEPTION_EXECUTE_HANDLER) {

DbgPrint ("ERROR ExceptionCode: %x\n", GetExceptionCode() );

} // end __try{
}



And here is the disassembly with the ms_ehseh.idc IDC script by igorsk applied and the scopetable functions named:

Code:

:00011000 TestSEH proc near ; CODE XREF: DeviceControl+AC
:00011000
:00011000 var_1C = dword ptr -1Ch
:00011000 __$SEHRec$ = SEHRegistrationNode ptr -18h
:00011000
:00011000 push ebp
:00011001 mov ebp, esp
:00011003 push 0FFFFFFFFh
:00011005 push offset _func1_scopetable
:0001100A push offset __except_handler3
:0001100F mov eax, large fs:0
:00011015 push eax
:00011016 mov large fs:0, esp
:0001101D sub esp, 0Ch
:00011020 push ebx
:00011021 push esi
:00011022 push edi
:00011023 mov [ebp+__$SEHRec$.SavedESP], esp
:00011026 and [ebp+__$SEHRec$.TryLevel], 0
:0001102A nop
:0001102B jmp short _endoftry0
:0001102D ; ---------------------------------------------------------------------------
:0001102D ; __except() filter for try block 0
:0001102D
:0001102D FilterFunc: ; DATA XREF: .rdata:0001206C
:0001102D mov eax, [ebp+__$SEHRec$.ExceptionPointers]
:00011030 mov eax, [eax]
:00011032 mov eax, [eax]
:00011034 mov [ebp+var_1C], eax
:00011037 xor eax, eax
:00011039 inc eax
:0001103A retn
:0001103B ; ---------------------------------------------------------------------------
:0001103B ; __except {} handler for try block 0
:0001103B
:0001103B HandlerFunc: ; DATA XREF: .rdata:00012070
:0001103B mov esp, [ebp+__$SEHRec$.SavedESP]
:0001103E push [ebp+var_1C]
:00011041 push offset aErrorExceptioncodeX ; "ERROR ExceptionCode: %x\n"
:00011046 call _DbgPrint
:0001104B pop ecx
:0001104C pop ecx
:0001104D
:0001104D _endoftry0: ; CODE XREF: TestSEH+2B
:0001104D or [ebp+__$SEHRec$.TryLevel], 0FFFFFFFFh
:00011051 mov ecx, [ebp+__$SEHRec$.Next]
:00011054 mov large fs:0, ecx
:0001105B pop edi
:0001105C pop esi
:0001105D pop ebx
:0001105E leave
:0001105F retn
:0001105F TestSEH endp



Here is what the scopetable looks like:

Code:

.rdata:00012068 _func1_scopetable dd 0FFFFFFFFh ; DATA XREF: TestSEH+5
.rdata:00012068 ; try block 0, enclosed by -1
.rdata:00012068 ; EnclosingLevel
.rdata:0001206C dd offset FilterFunc ; FilterFunc
.rdata:00012070 dd offset HandlerFunc ; HandlerFunc



So, you've got a bit of work to do if you want to emulate a try/except block in a driver patch.

Kayaker

evaluator
September 15th, 2009, 02:39
NO!. normal SEH block works for drivers also, but with limits > User-address space memory faults allowed only.

Elenil's problem mostly related to Sice, bcoz it handles internal faults via it's INT0E handler, not by SEH