Search code examples
x86seh

FS register is null


I have to implement a SEH based exception handler. To start with, I have written the following sample code, where i am trying to register an exception handler using fs register.

#include <iostream>
#include <exception>
#include <windows.h>

using namespace std;


EXCEPTION_DISPOSITION myHandler(
    _EXCEPTION_RECORD *ExcRecord,
    void * EstablisherFrame,
    _CONTEXT *ContextRecord,
    void * DispatcherContext)
{
    cout << "In the exception handler" << endl;
    cout << "Just a demo. exiting..." << endl;
    return ExceptionContinueExecution;
}

int main()
{
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!

    EXCEPTION_REGISTRATION myExceptReg;
    EXCEPTION_REGISTRATION *pReg = &myExceptReg;
    myExceptReg.handler = myHandler;
    DWORD prev;

    asm("movl %fs:0 , %eax");
    asm("movl %%eax , %0": "=r" (prev));

    myExceptReg.prev = (EXCEPTION_REGISTRATION*) prev;

    asm ("movl %0, %%eax" : "=m" (pReg));
    asm("movl %eax , %fs:0");

    //      int* ptr = 0;
    //      exception e;

    return 0;
}

When I debug the code, I see that the value of fs register is zero. and the program crashes after executing asm("movl %fs:0 , %eax");

Following is the sample of the assembly equivalent of this code.

000000000000401626:   mov     %rax,%rcx
000000000000401629:   callq   0x44d7a0 <std::ostream::operator<<(std::ostream& (*)(std::ostream&))>
32                  EXCEPTION_REGISTRATION *pReg = &myExceptReg;
00000000000040162e:   lea     0x20(%rbp),%rax
000000000000401632:   mov     %rax,0x18(%rbp)
33                  myExceptReg.handler = myHandler;
000000000000401636:   lea     -0x13d(%rip),%rax        # 0x401500     <myHandler(_EXCEPTION_RECORD*, void*, _CONTEXT*, void*)>
00000000000040163d:   mov     %rax,0x28(%rbp)
36                  asm("movl %fs:0 , %eax");
000000000000401641:   mov     %fs:0x0,%eax
37                  asm("movl %%eax , %0": "=r" (prev));
000000000000401649:   mov     %eax,%ebx
00000000000040164b:   mov     %ebx,0x3c(%rbp)
39                  myExceptReg.prev = (EXCEPTION_REGISTRATION*) prev;
00000000000040164e:   mov     0x3c(%rbp),%eax
000000000000401651:   mov     %rax,0x20(%rbp)
41                  asm ("movl %0, %%eax" : "=m" (pReg));
000000000000401655:   mov     0x18(%rbp),%eax
42                  asm("movl %eax , %fs:0");
000000000000401658:   mov     %eax,%fs:0x0
50                  return 0;

What could be the problem ?


Solution

  • To sum up:

    The debug output shows that the code is being compiled for 64bit, and (as Hans pointed out) the style of exception handling being used is only valid for 32bit. Ensuring that the code compiles for 32bit resolves the problem.

    If this answers your question, please click the checkmark to the left so that karma gets awarded.