SEH stands for Structured Exception Handling developed by Borland and that gave license to Microsoft. This is the reason why SEH is available in Windows only. Exception is an error that disrupts the program execution. SEH is a software method of dispatching and handling exception, for software as well as hardware. If any exception occur then it first goes to OS that checks if any suitable handler is present/ define or not. If user define handler for that exception is present then OS pass exception to that handler otherwise pass to default OS handler.
Different type of errors like divide by zero, out of bound, access violation etc. happen during unsafe programming. In OS corresponding defined exception handlers are present for them. We can also define our own handler by using try, except or try, catch block. In Try block place the code that will be check for exception. If any exception occur then passes to catch/except block means except block will executed when exception occur. In except block we can define our own handler that will we invoke message when that exception occur.
Syntax for try, catch block is ::
__try {
// the block of code to try
…
}
__except (exception filter) {
// the code to run in the event of an exception
…
}
The information about SEH is stored in Exception Registration Record. Exception Registration Record is the first record in the TIB(Thread Information Block). We can see TIB in the main thread of the process. Exception registration is the linked list that can be assess by FS [0] register. ERR has 8 bytes that point to two variables one is the pointer to next ERR and another variable is the pointer to handler. Registration of exceptional handler happen at run time (for proof we use Immunity debugger explained later) and depends upon where we are in the program. The linked list may be grows when program proceed. All records store on the stack and when new record add up using LIFO fashion. If new records added then OS handler is at the last and stack may shrink dynamically when handler remove from the list.
The prototype of exceptional handler is defined in except.h in win32. As I mentioned in ERR, there are two variables, the second variable that is pointer to the handler(or SEH handler)has two main components
- user defined call back function(_except_handler)
- exception record ( _exception_record )
User defined call back function takes four parameters that can be seen in figure 1. This function tells what to do when exception occur. Some focus on important parameters –
- Establisher Frame point back to the stack.
- Context Record tells the register value at the time of exception.
- Dispatcher context gives the various information like what type of exception occurred, where exception occurred. The call back function decide what to do using that information.
- The remaining parameter is the pointer to Exception Record structure.
The Exception Record structure can be seen in figure 1,
- Exception code tells about which number assign to the exception by operating system.
- Exception Address is the address at which exception occurred.
fig 1
SEH chain during RUN Time!!
First open the program into Immunity Debugger, press F9 to execute instruction by instruction.
To see the SEH chain press ALT+S.
You can see that only one exceptional handler is at this state when program proceed our handler will added and will appear on the SEH chain.
Now our exception handler added in the link list of ERR(Exception registration Record).
Now time to Handel the Exception!!
As I explained earlier ERR can be access by using FS register. If you want to see then write d FS:[0].
We can also see that our exceptional handler point to the next SEH record which is the OS default Handler. If our handler will not able to handle exception then the OS default handler will handle it.
To pass the exception press Shift+ F7/F8/F9.
The memory access violation is successfully handled by our handler and it prints the message. After handling the exception this will remove from the SEH list and FS:[0] point again to the OS default handler.
MY CODE!!
.386
.model flat ,stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
;Define the Macros Here
TRY MACRO Handler
pushad ;Save Current State
mov esi, offset Handler ;Address of New(user created) Exception Handler
push esi ;Save Old Exception Handler
push dword ptr fs:[0] ;Install New Handler
mov dword ptr fs:[0], esp
ENDM
CATCH MACRO Handler
Handler:
mov esp, [esp + 8] ;Exception Occured, Get old ESP
pop dword ptr fs:[0] ;Restore previous Exception Handler
popad ;Restore previous State
ENDM
.data
title1 db ‘SEH !!’, 0
exception db ‘Exception handled successfully !!’, 0dh, 0ah
db ‘Press OK to terminate’, 0
noException db ‘No Exception occured’, 0
.code
start:
ASSUME fs:NOTHING ;if we want to use fs set nothing
TRY Access
mov ebx, 0 ;Prepare to write to address 0
mov [ebx], ebx ;Write to address 0 (Access Violation)
CATCH Access
;This code will get executed if an exception occurs.
invoke MessageBox, NULL, addr exception, addr title1, MB_OK
jmp ExitProgram
ExitProgram:
invoke MessageBox, NULL, addr noException, addr title1, MB_OK
invoke ExitProcess, 0
end start
References:
http://www.microsoft.com/msj/0197/exception/exception.aspx
http://uninformed.org/index.cgi?v=5&a=2&p=4#fig-exdispatch
http://www.securitysift.com/windows-exploit-development-part-6-seh-exploits/ (image source)
No Comments Yet