Firstly, the prototype for the exception handler helps:
Code:
EXCEPTION_DISPOSITION _except_handler(
struct EXCEPTION_RECORD *ExceptionRecord,
void *EstablisherFrame,
struct _CONTEXT *ContextRecord,
void *DispatcherContext);
Then, once inside the exception handler, we examine what exception was thrown and act upon it accordingly...
Code:
/*4116F0*/ enter 0, 0 ; this is the seh handler
/*4116F4*/ mov eax, dword ptr [ebp+8] ; get pointer to ExceptionRecord
;; check ExceptionRecord.ExceptionType for 'illegal instruction'
/*4116FD*/ cmp dword ptr [eax], C000001D
;; do some other handling if not illegal instruction
/*411709*/ jnz short 0041176D
;; otherwise, it is illegal instruction, so get pointer to the context
;; information and get saved EIP from context (EIP of faulting instruction)
/*411714*/ mov eax, dword ptr [ebp+10]
/*411717*/ mov edx, dword ptr [eax+_CONTEXT.Eip]
;; patch 33 c0 ("xor eax,eax") at that address (41163f) effectively
;; dealing with the faulting instruction.
/*411720*/ mov word ptr [edx], 0C033
;; DR7 is the DebugControlRegister which controls which breakpoints are
;; enabled and for what operations.
;; assuming decimal 13 => 0dh : Enable Global1,Local1 and Local0
;; assuming hex 13h : Enable Local2, Global0 and Local0
/*411729*/ or dword ptr [eax+_CONTEXT.Dr7], 13
;; ECX := ContextRecord->Eip -1
;; which is the address of the byte prior to the illegal instruction.
/*411732*/ lea ecx, dword ptr [edx-1] ; get ContextRecord->Eip-1
;; set linear address for HW breakpoint 1
/*41173A*/ mov dword ptr [eax+_CONTEXT.Dr1], ecx
/*411740*/ inc edx
;; incrementing ecx looks irrelevant since not used beyond here. Could this
;; be a typo for "inc edx" which would then make sense below (setting a
;; breakpoint just after the patched "xor eax,eax")
/*411744*/ inc ecx
;; set linear address for HW breakpoint 0 to zero, effectively disabling it
/*41174A*/ mov dword ptr [eax+_CONTEXT.Dr0], 0
;; set linear address for HW breakpoint 3
/*411758*/ mov dword ptr [eax+_CONTEXT.Dr3], edx
/*411760*/ xor eax, eax ; return with exception continue exception
/*411767*/ leave
/*411768*/ retn
The linear address for HW breakpoint 0 is cleared, rendering it disabled, and setting an address for HW breakpoint 3 does not gurantee anything since there isnt any explicit enabling of it in DR7.
Breakpoint 1 is enabled and its linear address is set so it points to the byte prior to the faulting instruction.
Because the illegal opcode exception is a "Fault" and thus restartable, upon successful return from the EH EIP should be at the same location (although the bytes there will be different.)
A hardware breakpoint is also set for the addrress prior to where the initial exception was generated however the HW breakpoint type isnt set (could be IO/read/write/exec!) Upon returning from the EH executtion should continue at the now "xor eax,eax" instruction.
Not exactly sure whether the DR7 bitmask is dec. or hex but either way there appear to be some weirdness wrt. enabling breakpoints without properly setting them up.
thats about as much detail as I can provide without seeing more code...
-shadz