Vulnerability Development mailing list archives

Re: Win32: Using SEH to search memory


From: "Nicolas RUFF (lists)" <ruff.lists () edelweb fr>
Date: Thu, 25 Sep 2003 14:48:33 +0200

Windows XP Exception Handler has new protections, such as :
- clearing registers before transferring control to the handler code
AND
- do not transfer control to a handler code located on the stack

Cf . http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1462.pdf

If you run your code on a Windows 2000, it should work fine I guess.

Regards,
- Nicolas RUFF
-----------------------------------
Security Consultant
EdelWeb (http://www.edelweb.fr/)
-----------------------------------

I'm trying to search through memory using structured exception handling to avoid crashing when accessing bad memory. Various buffer overflow exploits have used this technique for locating the address of GetProcAdd() or for locating shellcode planted in memory.

I have an example written in inline assembly and compiled with Visual Studio on XP. It implements seh and searches through memory just fine. My handler handles the memory access violations. (Example 1 code below) However, if I stick my handler on the stack, then Windows doesn't send the exception to my handler. (Example 2 code below)

Does anyone have any suggestions as to what I might be doing wrong? Does Windows care where a handler lives in memory? Can anyone recommend a good reference for implementing seh in shellcode?


Example 1:
*****************************************

#include<stdio.h>

//simple test for SEH with handler

void main()
{
    unsigned int cint = 0;

    __asm{

        jmp gethandler
start:
        xor ebx,ebx
        xor ecx,ecx
        push dword ptr fs:[ecx]
        mov dword ptr fs:[ecx],esp
search:
        inc ebx
        cmp dword ptr[ebx],0x00000000    ;//causes exception

//exception cleanup
        xor    ecx,ecx        ;
        mov     eax,[ESP]        ; // Get pointer to previous record
              mov     FS:[ecx], eax        ; // Install previous record
              add     esp, 8        ; //clean handler & fs[0] off stack
        jmp printit

gethandler:
        call start
handler:
        push ebp
                    mov ebp,esp
        push ebx
        mov ebx,[ebp+10h]
        add ebx,0xa4
        inc dword ptr[ebx]  ;//increment ebx
        xor eax,eax
        pop ebx
        mov esp,ebp
        pop ebp
        ret
printit:
        mov [cint],ebx
    }
    printf("Last ebx = %x\n",cint);

}

Example 2:
*****************************************

#include<stdio.h>

//simple test for SEH with handler located on stack

void main()
{
    unsigned int cint = 0;

    char unsigned bytes[] =
        "\xEB\x1B"                // jmp         gethandler
//start:
        "\x33\xDB"                // xor         ebx,ebx
        "\x33\xC9"                // xor         ecx,ecx
        "\x64\xFF\x31"           // push        dword ptr fs:[ecx]
        "\x64\x89\x21"           // mov         dword ptr fs:[ecx],esp
//search:
        "\x43"                   // inc         ebx
        "\x83\x3B\x00"           // cmp         dword ptr [ebx],0
//SEH cleanup
        "\x33\xC9"               // xor         ecx,ecx
        "\x8B\x04\x24"           // mov         eax,dword ptr [esp]
        "\x64\x89\x01"           // mov         dword ptr fs:[ecx],eax
        "\x83\xC4\x08"           // add         esp,8
        "\xEB\x1B"                // jmp         printit
//gethandler:
        "\xE8\xE0\xFF\xFF\xFF" // call        start
//handler:
        "\x55"                    // push        ebp
        "\x8B\xEC"                // mov         ebp,esp
        "\x53"                    // push        ebx
        "\x8B\x5D\x10"             // mov         ebx,dword ptr [ebp+10h]
        "\x81\xC3\xA4\x00\x00\x00"//add         ebx,0A4h
        "\xFF\x03"                 // inc         dword ptr [ebx]
        "\x33\xC0"                // xor         eax,eax
        "\x5B"                   // pop         ebx
        "\x8B\xE5"                // mov         esp,ebp
        "\x5D"                    // pop         ebp
        "\xC3"         // ret
//printit: (clean exit?)
        "\xff\xd2";              //jump edx

    __asm{
        lea eax,bytes
        lea edx,printit
        jmp eax
printit:
        mov [cint],ebx
    }

    printf("Last ebx = %x\n",cint);    //probably will never make it here.

}

_________________________________________________________________
High-speed Internet access as low as $29.95/month (depending on the local service providers in your area). Click here. https://broadband.msn.com





Current thread: