Log in

View Full Version : Help with SEH stuff


THTD
September 9th, 2005, 13:24
Hi to everyone...

I am learning the difficult art of RCE, but I am already encountering difficulties

I am currently looking at crackme #2 from deroko (http://www.crackmes.de/users/deroko/derokos_crackme_2/) and I can't understand what happens when the programs tries to check the serial.

Code:
CODE:004011BD push 100h ; nMaxCount
CODE:004011C2 push offset String ; lpString
CODE:004011C7 push 0 ; nIDDlgItem
CODE:004011C9 push [ebp+hWnd] ; hDlg
CODE:004011CC call GetDlgItemTextA
CODE:004011CC
CODE:004011CC // Reads the string from the form!
CODE:004011CC
CODE:004011CC GetDlgItemTextA(hWnd,0,&String,100);
CODE:004011CC
CODE:004011D1 cmp eax, Serial_Length
CODE:004011D4 jnz short @@wrong_serial
CODE:004011D4
CODE:004011D6 call check_key


As soon as GetDlgItemTextA returns, the EAX register holds the length of the string coming as input. This value is used to perform a simple check on the length of the key (Serial_Length=0xE).

Now, as soon as I enter check key, problems start coming out. The code is the following:

Code:
CODE:004012CA xor edx, edx ; EDX is zeroed
CODE:004012CC push offset Exception_Handler ; Put on the stack the pointer to the exception handler
CODE:004012D1 push dword ptr fs:[edx] ; Puts on the stack the current value at fs:[0]
CODE:004012D4 mov fs:[edx], esp ; Install as new Exception Handler the value in ESP
CODE:004012D7 xor eax, eax ; EAX is zeroed
CODE:004012D9 or eax, 100h ; EAX = EAX | 100h --> EAX = 100h
CODE:004012DE push eax ; Put on the stack 100h
CODE:004012DF popf ; Pop into EFLAGS what is on the stack
CODE:004012E0 jmp short loc_4012E8 ; Proceed
CODE:004012E0

Now my questions:

In order to install another Exception Handler, shouldn't I do something like:

mov large fs:[0], offset Exception_Handler ??

What this three instruction do? they seems to copy the wrong value into fs:[0]:

Code:
CODE:004012CC push offset Exception_Handler
CODE:004012D1 push dword ptr fs:[edx]
CODE:004012D4 mov fs:[edx], esp <-- this puts a wrong value??


Also, when debugging, as soon as the popf instruction is executed, I get the value of 0x202 in the EFLAGS register.... Why? Shouldn't I find 0x100?

Intel reference manual says that (IDA Tells that operandsize attribute is 32bit):

Quote:
These instructions pop a doubleword (POPFD) from the top of the stack (if the current operandsize attribute is 32) and stores the value in the EFLAGS register, or pops a word from the top of the stack (if the operand-size attribute is 16) and stores it in the lower 16 bits of the EFLAGS register (that is, the FLAGS register).


The solution of the crackme just says that the program is setting the singlestep flag...

Also, could anybody point me to a __complete__ tutorial on SEH inner workings?? I seem to find noone...

Best regards,

THTD

LLXX
September 9th, 2005, 18:22
SEH is implemented much like interrupts, i.e. they can be "chained". Explanations are not too plentiful in the Internet, but here are a few I found:

hxxp://www.assembly-journal.com/viewarticle.php?id=69&layout=html
hxxp://wiki.forth.org.ru/StructuredExceptionsHandling (an interesting diagram here)
hxxp://fly.srk.fer.hr/~lethe/Articles/asmjournal/html/apj_5/Structured%20Exception%20Handling%20under%20Win32.shtml

As for the behavior of the flags register... I believe certain flags cannot have their value changed by user-level processes. See page 72 of the Intel manual #253665 for a diagram of the EFLAGS. The 202 value indicates that IF is set, as well as the hard-wired 1 bit in position 1, which cannot be changed. IF cannot be changed while operating at user-level. The note on the next page reads:
Quote:
[Originally Posted by Intel Manual #253665]3.4.3.3 System Flags and IOPL Field
The system flags and IOPL field in the EFLAGS register control operating-system or executive operations. They should not be modified by application programs. The functions of the system flags are as follows:
TF (bit 8) Trap flag — Set to enable single-step mode for debugging; clear to disable
single-step mode.
IF (bit 9) Interrupt enable flag — Controls the response of the processor to maskable
interrupt requests. Set to respond to maskable interrupts; cleared to inhibit
maskable interrupts.
...

THTD
September 10th, 2005, 04:30
Quote:
[Originally Posted by LLXX]SEH is implemented much like interrupts, i.e. they can be "chained". Explanations are not too plentiful in the Internet, but here are a few I found:

hxxp://www.assembly-journal.com/viewarticle.php?id=69&layout=html
hxxp://wiki.forth.org.ru/StructuredExceptionsHandling (an interesting diagram here)
hxxp://fly.srk.fer.hr/~lethe/Articles/asmjournal/html/apj_5/Structured%20Exception%20Handling%20under%20Win32.shtml


Thank you, I'll start studying!

Quote:
[Originally Posted by LLXX]As for the behavior of the flags register... I believe certain flags cannot have their value changed by user-level processes. See page 72 of the Intel manual #253665 for a diagram of the EFLAGS. The 202 value indicates that IF is set, as well as the hard-wired 1 bit in position 1, which cannot be changed. IF cannot be changed while operating at user-level.


So you are saying that it should have been EFLAGS=0x100, BUT, as some of these flags can be modified only while in privileged mode, the actual value comes from a combination of bits from 0x206 (original EFLAGS) and 0x100 (supposed new value)? That seems reasonable. I will investigate the issue further by reading intel manual #3.

Thanks!

blabberer
September 10th, 2005, 06:23
well one of the better exception handling tutorial in my opinion is
jeremy gordons except32 tutorial
which can be found here
http://www.jorgon.freeserve.co.uk/ExceptFrame.htm
read downlaod the zip play with it in ollydbg several times
another one is by matt pietrek in his under the hood series of articles
look into wheaty.net posting a msdn link is useless because those links are like cats kittens (the mother places them in new holes every two hours)

pushfd
or [esp],0x100
popfd

is indeed setting the trap flag
so eflags was 202 orring with 100 will make it 302 and popfd witll set the trap flag
so the next instruction most probably a nop
would cause a single step exception generated if you are not single stepping

well uptill w2k (pre sp4)if you execute popfd it was showing 302 (or celeron or p2 i dont know) in eflags register but recently i noticed that 302 is not shown but only 202 is shown in the eflags register on single stepping (on xp-sp2 and p4 combo (i thought it was os problem and searched a little but couldnt find any info and i didnt think to see the intel manuals(just reading llxx post above i think the processor probably inhibits the setting of trap flag to eflags register) in the recent processors

but the functionality still exists if you just f9 in ollydbg (no exceptions checked to be passed automatically) you will see ollydbg saying single step
exception on blah blah press shift blah blah to pass blah blah
in the staus bar as well as log window

actually if you could lay you hands on daemons articles (anticrack used to host them recently yates was hosting them but i am not aware of its latest place) you could see how all these tricks works he has some nice articles on these anti debugging tricks

THTD
September 10th, 2005, 07:09
Quote:
[Originally Posted by blabberer]well one of the better exception handling tutorial in my opinion is
jeremy gordons except32 tutorial
which can be found here
http://www.jorgon.freeserve.co.uk/ExceptFrame.htm
read downlaod the zip play with it in ollydbg several times


I'll put into the reading-queue


Quote:
[Originally Posted by blabberer]
Code:
pushfd // Save EFLAGS on stack
or [esp],0x100 // or EFLAGS with 0x100 and store result on top of the stack
popfd // Get back eflags


is indeed setting the trap flag
so eflags was 202 orring with 100 will make it 302 and popfd witll set the trap flag
so the next instruction most probably a nop
would cause a single step exception generated if you are not single stepping

well uptill w2k (pre sp4)if you execute popfd it was showing 302 (or celeron or p2 i dont know) in eflags register but recently i noticed that 302 is not shown but only 202 is shown in the eflags register on single stepping (on xp-sp2 and p4 combo (i thought it was os problem and searched a little but couldnt find any info and i didnt think to see the intel manuals(just reading llxx post above i think the processor probably inhibits the setting of trap flag to eflags register) in the recent processors

but the functionality still exists if you just f9 in ollydbg (no exceptions checked to be passed automatically) you will see ollydbg saying single step
exception on blah blah press shift blah blah to pass blah blah
in the staus bar as well as log window

actually if you could lay you hands on daemons articles (anticrack used to host them recently yates was hosting them but i am not aware of its latest place) you could see how all these tricks works he has some nice articles on these anti debugging tricks


So, you are saying that within the IDA debugger I am seeing the value 0x202 while instead I should be seeing 0x302?? That would explain my doubts...

THTD
September 10th, 2005, 07:19
Addition: the popf handling seems to be an error in the IDA Debugger. I have tried stepping through the code with olly and no problem was found:


Code:

EAX 00000100
ECX 77D3F88F USER32.77D3F88F
EDX 00000000
EBX 00000000
ESP 0012FBBC
EBP 0012FBC8
ESI 00401027 crackme.00401027
EDI 0012FC30
EIP 004012E0 crackme.004012E0
C 0 ES 0023 32bit 0(FFFFFFFF)
P 0 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 0 FS 003B 32bit 7FFDF000(FFF)
T 1 GS 0000 NULL
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00000302 (NO,NB,NE,A,NS,PO,GE,G)
ST0 empty -??? FFFF 00FFFFFF 00BFFFFF
ST1 empty -??? FFFF 00000074 00000000
ST2 empty -??? FFFF 00000000 00000000
ST3 empty -??? FFFF 0074BFFF 00000000
ST4 empty 0.0
ST5 empty 0.0
ST6 empty 150.50000000000000000
ST7 empty 130.00000000000000000
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 027F Prec NEAR,53 Mask 1 1 1 1 1 1


blabberer
September 10th, 2005, 07:44
well effectively yes you should see 302 if it was 202 earlier
what is your os and processor
if it was p2 or earlier and w2k without service packs try using a newer processor p4 or xp-sp2 os and see if olllydbg still shows 302
i noticed it didnt show 302 in ollydbg too some days ago when i was
poking around some malware on xp-sp2 p4

LLXX
September 10th, 2005, 17:09
In addition, although the Intel manuals don't explicitly mention it, I believe an exception is caused by setting the trap flag. OllyDbg is basically letting it set TF, while IDA's debugger doesn't let that happen. It's not a bug, it's a feature of the newer processors.

THTD
September 17th, 2005, 04:26
Thank everybody, I have now understood how SEH and SEH chains works

The document that blabberer pointed out was really GREAT! I recommend that to anyone willing to understand the issue:

Quote:
http://www.jorgon.freeserve.co.uk/ExceptFrame.htm


Now, since the document above introduces the idea of single stepping by setting the trap flag, and checks the differences by exception codes 0x80000004 and 0x80000003 (non-debugger and debugger breakpoint), I would like to improve my knowledge of that.

Anybody could point me to a GOOD reference to single step usage? The idea is to get the necessary knowledge to deal with protections that perform checks to see if the program is currently debugged that go beyond calling "InDebuggerPresent"...

Thank you!

Opcode
September 17th, 2005, 11:04
Quote:
[Originally Posted by THTD]The idea is to get the necessary knowledge to deal with protections that perform checks to see if the program is currently debugged that go beyond calling "InDebuggerPresent"...

Take a look in this article:
https://www.openrce.org/articles/full_view/14

Regards,
Opc0de