PROLOG and epilog in seh

Source: Internet
Author: User

Initially released in the QQ space, see:PROLOG and epilog in seh, Contains textures.

All Codes Using seh need to build stack tokens that support Exception Processing, while repeated codes should be extracted into functions. Microsoft will naturally not be an exception. For this reason, the system provides PROLOG and epilog series. Similar functions have many versions, but they are similar. This time, you don't need a debugger to analyze the two functions _ seh_prolog4_gs and _ seh_epilog4_gs to see how they work with Stack rollback structures that support exceptions.

Let's take a look at Prolog. This is the code for calling the kernel function kidispatchexception _ seh_prolog4_gs,

000 push    0F8h004 push    offset off_8488DCE0008 call    __SEH_prolog4_GS

Two parameters are passed before the function is called. One is the size of the stack to be retained, and the other is the pointer.
Let's look at the Function Code itself. The detailed comments are behind the code,

   ; two instrucitons before call it.    ;    ; take KiDispatchException as example,    ;    ; 000 push    0F8h ; it's used as a stack size    ; 004 push    offset off_8488DCE0 ; it's pointer to scope table entry.    __SEH_prolog4_GS proc near    arg_4= dword ptr  8000 push    offset __except_handler4004 push    large dword ptr fs:0008 mov     eax, [esp+8+arg_4] ; so now there are 5 values in stack.                            ;                            ; f8                            ; 8488dce0                            ; return address of call                            ; _except_handler4                            ; old fs:0                            ; ; follwing is additional information                            ; to be pointer to EXCEPTION_POINTERS                            ; to be esp value                            ; to be cookie value008 mov     [esp+8+arg_4], ebp ; push current ebp value into place                            ;  where 0f8 is here.008 lea     ebp, [esp+8+arg_4] ; update ebp to current frame pointer008 sub     esp, eax        ; reserve stack008 push    ebx00C push    esi010 push    edi014 mov     eax, ___security_cookie014 xor     [ebp-4], eax    ; encrypt pointer to scope table entry014 xor     eax, ebp014 mov     [ebp-1Ch], eax  ; store cookie value014 push    eax018 mov     [ebp-18h], esp  ; store current esp; middle part018 push    dword ptr [ebp-8] ; push "return address" of current call                            ; for next ret instruction01C mov     eax, [ebp-4]    ; mov [ebp-4] to [ebp-8]01C mov     dword ptr [ebp-4], 0FFFFFFFEh ; initialize try level01C mov     [ebp-8], eax    ; so far, the stack is following:                            ;                            ; ebp                            ; -1                            ; 8488DCE0 xor ___security_cookie                            ; _except_handler4                            ; old fs:[0]                            ; to be pointer to EXCEPTION_POINTERS                            ; current esp value                            ; cookie value (___security_cookie xor ebp)                            ; ...                            ; ebx                            ; esi                            ; edi                            ; cookie value                            ; return address to parent function01C lea     eax, [ebp-10h]01C mov     large fs:0, eax ; update fs:[0] to current frame01C retn                    ; return to parent function.

Since the annotations are more detailed, I will not talk much about them. I will add a few images.
The stack after the function starts to execute two push commands,

The stack at the center is as follows. Pay attention to the numerical order.

Execute the stack before the final retn, at this time (ebp-10) has built the exception stack stacking structure, (ebp-18) (ebp-1c) also assigned the corresponding value.
Next, analyze the epilog to see how kidispatchexception calls it,

            ; why is there 118?11C lea     esp, [ebp-118h] ; sizeof exception_frame + F8(includes additional information) + sizeof( ebx + esi + edi + cookie )                            ; ebp - (10+F8+10)000 call    __SEH_epilog4_GS000 retn    14h

Correct the stack pointer to the appropriate position, which is actually the position of the stack after the _ seh_prolog4_gs function returns. Then call the function _ seh_epilog4_gs. Note that the call command will push the returned address to the stack.
Let's look at the implementation part of the function,

    __SEH_epilog4_GS proc near000 mov     ecx, [ebp-1Ch]  ; cookie value (___security_cookie xor ebp)000 xor     ecx, ebp000 call    @__security_check_cookie@4 ;                            ; cmp     ecx, ___security_cookie                            ; jnz     ___report_gsfailure                            ; retn000 jmp     __SEH_epilog4    __SEH_epilog4_GS endp

Check whether the cookie is damaged. If no problem exists, jump to _ seh_epilog4.

    __SEH_epilog4 proc near000 mov     ecx, [ebp-10h]  ; restore old fs:[0]000 mov     large fs:0, ecx000 pop     ecx             ; return address of parent function-04 pop     edi             ; another cookie value besides [ebp-1c]-08 pop     edi-0C pop     esi-10 pop     ebx-14 mov     esp, ebp        ; restore esp and ebp000 pop     ebp-04 push    ecx000 retn    __SEH_epilog4 endp

This function is much simpler than Prolog, restoring FS: [0], restoring registers, and returning to the place where _ seh_epilog4_gs is called.
The analysis of these two functions eventually evolved into an understanding of the data structure in the stack. The observed data structure in IDA is as follows, and comments are added to the members:

EXCEPTION_POINTERS struc ; (sizeof=0x8, standard type)ExceptionRecord dd ? ; pointer to ExceptionRecordContextRecord dd ? ; pointer to ContextRecordEXCEPTION_POINTERS ends
CPPEH_RECORD struc ; old_esp dd ? ; esp positionexc_ptr dd ? ; pointer to EXCEPTION_POINTERSprev_er dd ? ; pointer to old fs:[0]handler dd ? ; exception handlermsEH_ptr dd ? ; pointer to scope table entry (might be encrytped)disabled dd ? ; try levelCPPEH_RECORD ends

Note that the order of stack data is from high to low, and the data members in the above structure are from low to high, which is the opposite. In addition, cppeh_record actually has two different values, one of which is on old_esp to put the cookie value. The other is under disabled and used to store the previous EBP value (compared with the previous figure ). In the exception handling function, you can access this data structure to obtain the information you need.

This reminds me of a sentence in the Mythical man-month. "Show me your flowchart while hiding your table. I am still confused. Show me the flowchart hidden in your table. They are so obvious. "The" table "here refers to the data structure, which ultimately determines the implementation of the Code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.