In the previous article vc++6 the analysis of Windows SEH extension has been omitted, this article to complement.
In fact, this article refers to CSDN on a <win32 structured exception handling (SEH)-Exception handler (__try/except), and some questions are raised.
The author lists the vc++6.0 extended SEH nodes in the following structure:
struct _exception_registration {struct _exception_registration *prev; void (*handler) (Pexception_record, Pexception_registration, PCONTEXT, Pexception_record); struct Scopetable_entry *scopetable; int trylevel; int _EBP; Pexception_pointers xpointers; };
As explained in the previous article <vc++6 to Windows SEH Extension analysis >, this structure is a _exception_registration node on the stack when entering functions by pressing the push Ebp/push 0xff sequence of operations. In general, the push EBP is the first statement to enter the function, so who is xpointers the pointer variable with the address above int _ebp in the stack? In general, [Ebp+4] in the stack is the function return address, so you can assume that the author may have written the wrong pexception_pointers xpointers; position in the entire structure. So, where is this field? This article answers this question by debugging the code.
The code that generates the exception is as follows:
#include <windows.h>int filter1 (exception_pointers* excpinfo) {DWORD accaddr = excpinfo->exceptionrecord- >exceptioninformation[1];excpinfo->contextrecord;return Exception_execute_handler;} int main () {int* a = null;__try{(*a) =0xcc;} __except (Filter1 (GetExceptionInformation ())) {MessageBox (NULL, "", "", MB_OK);} return 0;}
The program triggers an exception after passing in 4 parameters and then entering Except_handler3, the prototype is as follows:
int __except_handler3 ( struct _exception_record * pexceptionrecord, struct exception_registration * Pregistrationframe, struct _context *pcontextrecord, void * pdispatchercontext);
Except_handler3 Source No, endure to look at the results of disassembly:
__except_handler3:00401234 push ebp00401235 mov ebp,esp00401237 Sub esp,80040123a Push ebx0040123b push esi0040123c push edi0040123d push ebp0040123e cld0040123f mov ebx,dword ptr [ebp+0ch]; ebx points to the second parameter 00401242 mov eax,dword ptr [ebp+8]; [ EBP+8] point to the first parameter 00401245 test dword ptr [eax+4],60040124c jne __except_handler3+0a0h (004012D4) 00401252 mov dword ptr [ebp-8],eax00401255 mov eax,dword ptr [ebp+10h]; [ EBP+10H] point to the third parameter 00401258 mov dword ptr [ebp-4],eax0040125b lea eax,[ebp-8]0040125e mov DWORD ptr [Ebx-4],eax
Note that ebx points to the second argument, which is actually the one that is pressed into the stack in the main function before the exception occurs.struct _exception_registrationStructure. There are a few sentences in this code:
00401242 mov eax,dword ptr [ebp+8]; [ EBP+8] point to the first parameter <pre name= "code" class= "CPP" >00401252 mov dword ptr [Ebp-8],eax
... 00401255 mov eax,dword ptr [ebp+10h]; [ EBP+10H] point to the third parameter 00401258 mov dword ptr [Ebp-4],eax...<pre name= "code" class= "CPP" >0040125e mov DWORD ptr [Ebx-4],eax; Place the starting address of the structure into the address [pRegistrationFrame-4]
This code, put the parameter 1 3 into a structure, and then pass the address of the structure to [pRegistrationFrame-4], according to <win32 Structured exception handling (SEH)-Exception handler (__try/except) > the author of the article describes that this structure is pexception_pointers xpointer. As I've said many times before, Pregistrationframe is the structure of the IDE on the stack, and pRegistrationFrame-4 the equivalent of pressing a 4-byte variable onto the stack, so you can determine the prototype of the vc++6.0 extension's structure:
<pre name= "code" class= "CPP" ><pre name= "code" class= "CPP" >pexception_pointers xpointers;
struct _exception_registration {
struct _exception_registration *prev; void (*handler) (Pexception_record, Pexception_registration, PCONTEXT, Pexception_record); struct Scopetable_entry *scopetable; int trylevel; int _EBP; };
Two variables close together
Of course, you can also view memory values:
Before triggering an exception, ebp=0x12ff48,trylevel=0x00,handler=0x403118,prev=0x12ff78; 0x12ff34, i.e. XPointer, is 0x83;
Triggering exception execution to
<pre name= "code" class= "CPP" ><pre name= "code" class= "CPP" >mov dword ptr [Ebx-4],eax; Place the start address of the structure into the address [ PREGISTRATIONFRAME-4]
Statement after
The value at 0x12ff34 is 0X12FAEC. The memory at address 0012FAEC is:
0012fae4 xx xx, xx xx ..... 0012FAEC E0 FB FC FB financed .... 0012FAF4 FB-... . YQ 厀
Discerning eye See 0X12FBE0 and 0X12FBFC know is the stack value. You can view function parameters and return addresses at the value of EBP:
0012FAEC E1 + 00 DD AE 6C % 醾 w Raspberry l.0012faf4 fb ... . Yq 厀 0012FAFC E0 FB 12 Financed FF. 8...0012FB04 FC FB B4 FB 12 00
These two values are indeed the two parameters of Except_handler3.
This can at least explain
<pre name= "code" class= "CPP" ><pre name= "code" class= "CPP" ><pre name= "code" class= "CPP" >pexception_ Pointers xpointers;
struct _exception_registration {
struct _exception_registration *prev;
void (*handler) (Pexception_record,pexception_registration,pcontext,pexception_record);
struct Scopetable_entry *scopetable;
int trylevel;
int _EBP;
};
This structure is the VC6 extension of the SEH node. This article can be finished, but the debugging code found an interesting place, is to jump from Except_handler3 to filter function execution, except_handler3 in order to make the filter function can use the exception function defined in the stack variable, save/load ebp Dafa :
00401273 push ebp00401274 Lea ebp,[ebx+10h]00401277 call dword ptr [Edi+ecx*4+4]
The call instruction invokes the filter function defined in the scopetable array, but before Except_handler3 restores the value of EBP from [ebx+10h], what is [ebx+10h]? You can first determine whether EBX is the ebx that is set when you enter Except_handler3, and it points to _exception_registration. _EXCEPTION_REGISTRATION+10H is _EXCEPTION_REGISTRATION!EBP, isn't it? This EBP is a function frame saved when entering the main function, so the variables in the main function can be obtained by offsets relative to EBP.
As for the GetExceptionInformation () function, the XPointer address of the EXCEPT_HANDLER3 setting is taken:
: __except (Filter1 (GetExceptionInformation ())) 004010b5 mov ecx,dword ptr [ebp-14h]004010b8 Push ecx004010b9 call @ILT +5 (filter1) (0040100a) 004010BE add esp,4
After formally entering the filter function, it is not possible to call GetExceptionInformation in the filter function because one of the push EBP has modified the function stack frame.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Vc++6 for Windows SEH Extension analysis article supplements