about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/analysis/sandbox.py4
-rw-r--r--miasm2/jitter/vm_mngr_py.c2
-rw-r--r--miasm2/os_dep/win_api_x86_32_seh.py589
3 files changed, 192 insertions, 403 deletions
diff --git a/miasm2/analysis/sandbox.py b/miasm2/analysis/sandbox.py
index 688c7592..9dc800fc 100644
--- a/miasm2/analysis/sandbox.py
+++ b/miasm2/analysis/sandbox.py
@@ -265,8 +265,8 @@ class OS_Linux_str(OS):
 
 class Arch_x86(Arch):
     _ARCH_ = None # Arch name
-    STACK_SIZE = 0x100000
-    STACK_BASE = 0x123000
+    STACK_SIZE = 0x10000
+    STACK_BASE = 0x130000
 
     def __init__(self):
         super(Arch_x86, self).__init__()
diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c
index 9894fd02..54511c20 100644
--- a/miasm2/jitter/vm_mngr_py.c
+++ b/miasm2/jitter/vm_mngr_py.c
@@ -217,7 +217,7 @@ PyObject* vm_set_mem(VmMngr* self, PyObject* args)
 
        ret = vm_write_mem(&self->vm_mngr, addr, buffer, size);
        if (ret < 0)
-	      RAISE(PyExc_TypeError,"arg must be str");
+	      RAISE(PyExc_TypeError, "Error in set_mem");
 
        check_write_code_bloc(&self->vm_mngr, size*8, addr);
 
diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py
index c86c179d..f33a853f 100644
--- a/miasm2/os_dep/win_api_x86_32_seh.py
+++ b/miasm2/os_dep/win_api_x86_32_seh.py
@@ -28,6 +28,7 @@ from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.core.utils import pck32, upck32
 import miasm2.arch.x86.regs as x86_regs
 
+
 # Constants Windows
 EXCEPTION_BREAKPOINT = 0x80000003
 EXCEPTION_ACCESS_VIOLATION = 0xc0000005
@@ -40,7 +41,7 @@ log = logging.getLogger("seh_helper")
 console_handler = logging.StreamHandler()
 console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
 log.addHandler(console_handler)
-log.setLevel(logging.WARN)
+log.setLevel(logging.INFO)
 
 FS_0_AD = 0x7ff70000
 PEB_AD = 0x7ffdf000
@@ -52,22 +53,20 @@ MAX_MODULES = 0x40
 tib_address = FS_0_AD
 peb_address = PEB_AD
 peb_ldr_data_offset = 0x1ea0
-peb_ldr_data_address = LDR_AD + peb_ldr_data_offset  # PEB_AD + 0x1000
+peb_ldr_data_address = LDR_AD + peb_ldr_data_offset
 
 
 modules_list_offset = 0x1f00
 
-InInitializationOrderModuleList_offset = 0x1ee0  # 0x1f48
+InInitializationOrderModuleList_offset = 0x1ee0
 InInitializationOrderModuleList_address = LDR_AD + \
-    InInitializationOrderModuleList_offset  # PEB_AD + 0x2000
+    InInitializationOrderModuleList_offset
 
 InLoadOrderModuleList_offset = 0x1ee0 + \
-    MAX_MODULES * 0x1000  # 0x1f48 + MAX_MODULES*0x1000
+    MAX_MODULES * 0x1000
 InLoadOrderModuleList_address = LDR_AD + \
-    InLoadOrderModuleList_offset  # PEB_AD + 0x2000
+    InLoadOrderModuleList_offset
 
-# in_load_order_module_1 = LDR_AD +
-# in_load_order_module_list_offset#PEB_AD + 0x3000
 default_seh = PEB_AD + 0x20000
 
 process_environment_address = 0x10000
@@ -85,8 +84,10 @@ loaded_modules = ["ntdll.dll", "kernel32.dll"]
 main_pe = None
 main_pe_name = "c:\\xxx\\toto.exe"
 
+MAX_SEH = 5
+
 
-def build_fake_teb():
+def build_teb(myjit, teb_address):
     """
     +0x000 NtTib                     : _NT_TIB
     +0x01c EnvironmentPointer        : Ptr32 Void
@@ -106,10 +107,10 @@ def build_fake_teb():
     o += pck32(peb_address)
     o += pck32(0x11223344)
 
-    return o
+    myjit.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, o)
 
 
-def build_fake_peb():
+def build_peb(myjit, peb_address):
     """
     +0x000 InheritedAddressSpace    : UChar
     +0x001 ReadImageFileExecOptions : UChar
@@ -121,36 +122,18 @@ def build_fake_peb():
     +0x010 processparameter
     """
 
-    offset_serverdata = 0x100
-    offset_data1 = 0x108
-    offset_data2 = 0x110
+    offset = peb_address + 8
     o = ""
-    o += "\x00" * 0x8
     if main_pe:
         o += pck32(main_pe.NThdr.ImageBase)
     else:
-        o += "AAAA"
+        offset += 4
     o += pck32(peb_ldr_data_address)
     o += pck32(process_parameters_address)
+    myjit.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, o)
 
-    o += (0x54 - len(o)) * "A"
-    o += pck32(peb_address + offset_serverdata)
-    o += (0x64 - len(o)) * "E"
-    o += pck32(1)  # number of cpu
-
-    o += (offset_serverdata - len(o)) * "B"
-    o += pck32(0x33333333)
-    o += pck32(peb_address + offset_data1)
-    o += (offset_data1 - len(o)) * "C"
-    o += pck32(0x44444444)
-    o += pck32(peb_address + offset_data2)
-    o += (offset_data2 - len(o)) * "D"
-    o += pck32(0x55555555)
-    o += pck32(0x0077007C)
-    return o
 
-
-def build_fake_ldr_data(modules_info):
+def build_ldr_data(myjit, modules_info):
     """
     +0x000 Length                          : Uint4B
     +0x004 Initialized                     : UChar
@@ -161,9 +144,7 @@ def build_fake_ldr_data(modules_info):
     """
     o = ""
     # ldr offset pad
-    o += "\x00" * peb_ldr_data_offset
-    o += "\x00" * 0xc
-    # text XXX
+    offset = LDR_AD + peb_ldr_data_offset + 0xC
 
     # get main pe info
     m_e = None
@@ -172,10 +153,11 @@ def build_fake_ldr_data(modules_info):
             m_e = (e, bname, addr)
             break
     if not m_e:
-        log.warn('no main pe, ldr data will be unconsistant')
+        log.warn('No main pe, ldr data will be unconsistant')
+        offset, data = offset + 8, ""
     else:
-        print 'inloadorder first', hex(m_e[2])
-        o += pck32(m_e[2]) + pck32(0)
+        log.info('Ldr %x', m_e[2])
+        data = pck32(m_e[2]) + pck32(0)
 
     # get ntdll
     ntdll_e = None
@@ -184,89 +166,15 @@ def build_fake_ldr_data(modules_info):
             ntdll_e = (e, bname, addr)
             continue
     if not ntdll_e:
-        log.warn('no ntdll, ldr data will be unconsistant')
+        log.warn('No ntdll, ldr data will be unconsistant')
     else:
-        print 'ntdll', hex(ntdll_e[2])
-        o += pck32(ntdll_e[2] + 0x8) + pck32(0)  # XXX TODO
-        o += pck32(ntdll_e[2] + 0x10) + pck32(0)
-
-    return o
-
-# def build_fake_InInitializationOrderModuleList(modules_name):
-#    """
-#    +0x000 Flink : Ptr32                                 -+ This distance
-#    +0x004 Blink : Ptr32                                  | is eight bytes
-#    +0x018 DllBase                        : Ptr32 Void   -+ DllBase
-#    +0x01c EntryPoint                     : Ptr32 Void
-#    +0x020 SizeOfImage                    : Uint4B
-#    +0x024 FullDllName                    : _UNICODE_STRING
-#    +0x02c BaseDllName                    : _UNICODE_STRING
-#    +0x034 Flags                          : Uint4B
-#    +0x038 LoadCount                      : Uint2B
-#    +0x03a TlsIndex                       : Uint2B
-#    +0x03c HashLinks                      : _LIST_ENTRY
-#    +0x03c SectionPointer                 : Ptr32 Void
-#    +0x040 CheckSum                       : Uint4B
-#    +0x044 TimeDateStamp                  : Uint4B
-#    +0x044 LoadedImports                  : Ptr32 Void
-#    +0x048 EntryPointActivationContext    : Ptr32 Void
-#    +0x04c PatchInformation               : Ptr32 Void
-#    """
-#
-#    o = ""
-#    offset_name = 0x700
-#    for i, m in enumerate(modules_name):
-# fname = os.path.join('win_dll', m)
-#        if isinstance(m, tuple):
-#            fname, e = m
-#        else:
-#            fname, e = m, None
-#        bname = os.path.split(fname)[1].lower()
-#        bname = "\x00".join(bname)+"\x00"
-#        print "add module", repr(bname)
-#        print hex(InInitializationOrderModuleList_address+i*0x1000)
-#        if e == None:
-#            e = pe_init.PE(open(fname, 'rb').read())
-#
-#        next_ad = InInitializationOrderModuleList_address + (i+1)*0x1000
-#        if i == len(modules_name) -1:
-#            next_ad = InInitializationOrderModuleList_address
-#        m_o = ""
-#        m_o += pck32(next_ad )
-#        m_o += pck32(InInitializationOrderModuleList_address + (i-1)*0x1000)
-#        m_o += pck32(next_ad + 8 )
-#        m_o += pck32(InInitializationOrderModuleList_address
-#            +  (i-1)*0x1000 + 8)
-#        m_o += pck32(next_ad + 0x10 )
-#        m_o += pck32(InInitializationOrderModuleList_address
-#            +  (i-1)*0x1000 + 0x10)
-#        m_o += pck32(e.NThdr.ImageBase)
-#        m_o += pck32(e.rva2virt(e.Opthdr.AddressOfEntryPoint))
-#        m_o += pck32(e.NThdr.sizeofimage)
-#
-#        m_o += (0x24 - len(m_o))*"A"
-#        print hex(len(bname)), repr(bname)
-#        m_o += struct.pack('HH', len(bname), len(bname)+2)
-#        m_o += pck32(InInitializationOrderModuleList_address
-#            +  i*0x1000+offset_name)
-#
-#        m_o += (0x2C - len(m_o))*"A"
-#        m_o += struct.pack('HH', len(bname), len(bname)+2)
-#        m_o += pck32(InInitializationOrderModuleList_address
-#            +  i*0x1000+offset_name)
-#
-#        m_o += (offset_name - len(m_o))*"B"
-#        m_o += bname
-#        m_o += "\x00"*3
-#
-#
-#        m_o += (0x1000 - len(m_o))*"J"
-#
-#        print "module", "%.8X"%e.NThdr.ImageBase, fname
-#
-#        o += m_o
-#    return o
-#
+        data += pck32(ntdll_e[2] + 0x8) + pck32(0)  # XXX TODO
+        data += pck32(ntdll_e[2] + 0x10) + pck32(0)
+
+    if data:
+        myjit.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, data)
+
+
 dummy_e = pe_init.PE()
 dummy_e.NThdr.ImageBase = 0
 dummy_e.Opthdr.AddressOfEntryPoint = 0
@@ -274,6 +182,28 @@ dummy_e.NThdr.sizeofimage = 0
 
 
 def create_modules_chain(myjit, modules_name):
+    """
+    kd> dt nt!_LDR_DATA_TABLE_ENTRY
+    +0x000 InLoadOrderLinks : _LIST_ENTRY
+    +0x008 InMemoryOrderLinks : _LIST_ENTRY
+    +0x010 InInitializationOrderLinks : _LIST_ENTRY
+    +0x018 DllBase : Ptr32 Void
+    +0x01c EntryPoint : Ptr32 Void
+    +0x020 SizeOfImage : Uint4B
+    +0x024 FullDllName : _UNICODE_STRING
+    +0x02c BaseDllName : _UNICODE_STRING
+    +0x034 Flags : Uint4B
+    +0x038 LoadCount : Uint2B
+    +0x03a TlsIndex : Uint2B
+    +0x03c HashLinks : _LIST_ENTRY
+    +0x03c SectionPointer : Ptr32 Void
+    +0x040 CheckSum : Uint4B
+    +0x044 TimeDateStamp : Uint4B
+    +0x044 LoadedImports : Ptr32 Void
+    +0x048 EntryPointActivationContext : Ptr32 Void
+    +0x04c PatchInformation : Ptr32 Void
+    """
+
     modules_info = {}
     base_addr = LDR_AD + modules_list_offset  # XXXX
     offset_name = 0x500
@@ -281,18 +211,15 @@ def create_modules_chain(myjit, modules_name):
 
     out = ""
     for i, m in enumerate([(main_pe_name, main_pe),
-        ("", dummy_e)] + modules_name):
+                           ("", dummy_e)] + modules_name):
         addr = base_addr + i * 0x1000
-        # fname = os.path.join('win_dll', m)
         if isinstance(m, tuple):
             fname, e = m
         else:
             fname, e = m, None
         bpath = fname.replace('/', '\\')
-        bname = os.path.split(fname)[1].lower()
-        bname = "\x00".join(bname) + "\x00"
-        # print "add module", repr(bname), repr(bpath)
-        # print hex(InInitializationOrderModuleList_address+i*0x1000)
+        bname_str = os.path.split(fname)[1].lower()
+        bname = "\x00".join(bname_str) + "\x00"
         if e is None:
             if i == 0:
                 full_name = fname
@@ -301,11 +228,11 @@ def create_modules_chain(myjit, modules_name):
             try:
                 e = pe_init.PE(open(full_name, 'rb').read())
             except IOError:
-                log.error('no main pe, ldr data will be unconsistant!!')
+                log.error('No main pe, ldr data will be unconsistant!')
                 e = None
         if e is None:
             continue
-        print "add module", hex(e.NThdr.ImageBase), repr(bname)
+        log.info("Add module %x %r", e.NThdr.ImageBase, bname_str)
 
         modules_info[bname] = addr, e
 
@@ -319,30 +246,29 @@ def create_modules_chain(myjit, modules_name):
         m_o += pck32(e.NThdr.ImageBase)
         m_o += pck32(e.rva2virt(e.Opthdr.AddressOfEntryPoint))
         m_o += pck32(e.NThdr.sizeofimage)
-
-        m_o += (0x24 - len(m_o)) * "A"
-        print hex(len(bname)), repr(bname)
         m_o += struct.pack('HH', len(bname), len(bname) + 2)
         m_o += pck32(addr + offset_path)
-
-        m_o += (0x2C - len(m_o)) * "A"
         m_o += struct.pack('HH', len(bname), len(bname) + 2)
         m_o += pck32(addr + offset_name)
+        myjit.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, m_o)
 
-        m_o += (offset_name - len(m_o)) * "B"
+        m_o = ""
         m_o += bname
         m_o += "\x00" * 3
+        myjit.vm.add_memory_page(
+            addr + offset_name, PAGE_READ | PAGE_WRITE, m_o)
 
-        m_o += (offset_path - len(m_o)) * "B"
+        m_o = ""
         m_o += "\x00".join(bpath) + "\x00"
         m_o += "\x00" * 3
-        # out += m_o
-        myjit.vm.set_mem(addr, m_o)
+        myjit.vm.add_memory_page(
+            addr + offset_path, PAGE_READ | PAGE_WRITE, m_o)
+
     return modules_info
 
 
 def fix_InLoadOrderModuleList(myjit, module_info):
-    print "fix inloadorder"
+    log.debug("Fix InLoadOrderModuleList")
     # first binary is PE
     # last is dumm_e
     olist = []
@@ -357,14 +283,14 @@ def fix_InLoadOrderModuleList(myjit, module_info):
 
         if "/" in fname:
             fname = fname[fname.rfind("/") + 1:]
-        bname = '\x00'.join(fname) + '\x00'
+        bname_str = fname
+        bname = '\x00'.join(bname_str) + '\x00'
         if not bname.lower() in module_info:
-            log.warn('module not found, ldr data will be unconsistant')
+            log.warn('Module not found, ldr data will be unconsistant')
             continue
 
         addr, e = module_info[bname.lower()]
-    # for bname, (addr, e) in module_info.items():
-        print bname
+        log.debug(bname_str)
         if e == main_pe:
             m_e = (e, bname, addr)
             continue
@@ -373,7 +299,7 @@ def fix_InLoadOrderModuleList(myjit, module_info):
             continue
         olist.append((e, bname, addr))
     if not m_e or not d_e:
-        log.warn('no main pe, ldr data will be unconsistant')
+        log.warn('No main pe, ldr data will be unconsistant')
     else:
         olist[0:0] = [m_e]
     olist.append(d_e)
@@ -387,6 +313,7 @@ def fix_InLoadOrderModuleList(myjit, module_info):
 
 
 def fix_InMemoryOrderModuleList(myjit, module_info):
+    log.debug("Fix InMemoryOrderModuleList")
     # first binary is PE
     # last is dumm_e
     olist = []
@@ -401,13 +328,13 @@ def fix_InMemoryOrderModuleList(myjit, module_info):
 
         if "/" in fname:
             fname = fname[fname.rfind("/") + 1:]
-        bname = '\x00'.join(fname) + '\x00'
+        bname_str = fname
+        bname = '\x00'.join(bname_str) + '\x00'
         if not bname.lower() in module_info:
-            log.warn('module not found, ldr data will be unconsistant')
+            log.warn('Module not found, ldr data will be unconsistant')
             continue
         addr, e = module_info[bname.lower()]
-    # for bname, (addr, e) in module_info.items():
-        print bname
+        log.debug(bname_str)
         if e == main_pe:
             m_e = (e, bname, addr)
             continue
@@ -416,7 +343,7 @@ def fix_InMemoryOrderModuleList(myjit, module_info):
             continue
         olist.append((e, bname, addr))
     if not m_e or not d_e:
-        log.warn('no main pe, ldr data will be unconsistant')
+        log.warn('No main pe, ldr data will be unconsistant')
     else:
         olist[0:0] = [m_e]
     olist.append(d_e)
@@ -451,7 +378,7 @@ def fix_InInitializationOrderModuleList(myjit, module_info):
             continue
         olist.append((e, bname, addr))
     if not ntdll_e or not kernel_e or not d_e:
-        log.warn('no kernel ntdll, ldr data will be unconsistant')
+        log.warn('No kernel ntdll, ldr data will be unconsistant')
     else:
         olist[0:0] = [ntdll_e]
         olist[1:1] = [kernel_e]
@@ -472,8 +399,8 @@ def add_process_env(myjit):
     env_str = '\x00'.join(env_str)
     env_str += "\x00" * 0x10
     myjit.vm.add_memory_page(process_environment_address,
-                                PAGE_READ | PAGE_WRITE,
-                                env_str)
+                             PAGE_READ | PAGE_WRITE,
+                             env_str)
     myjit.vm.set_mem(process_environment_address, env_str)
 
 
@@ -487,151 +414,27 @@ def add_process_parameters(myjit):
                              o)
 
 
-def build_fake_InLoadOrderModuleList(modules_name):
-    """
-    +0x000 Flink : Ptr32                                 -+ This distance
-    +0x004 Blink : Ptr32                                  | is eight bytes
-    +0x018 DllBase                        : Ptr32 Void   -+ DllBase -> _IMAGE_DOS_HEADER
-    +0x01c EntryPoint                     : Ptr32 Void
-    +0x020 SizeOfImage                    : Uint4B
-    +0x024 FullDllName                    : _UNICODE_STRING
-    +0x02c BaseDllName                    : _UNICODE_STRING
-    +0x034 Flags                          : Uint4B
-    +0x038 LoadCount                      : Uint2B
-    +0x03a TlsIndex                       : Uint2B
-    +0x03c HashLinks                      : _LIST_ENTRY
-    +0x03c SectionPointer                 : Ptr32 Void
-    +0x040 CheckSum                       : Uint4B
-    +0x044 TimeDateStamp                  : Uint4B
-    +0x044 LoadedImports                  : Ptr32 Void
-    +0x048 EntryPointActivationContext    : Ptr32 Void
-    +0x04c PatchInformation               : Ptr32 Void
-    """
-
-    o = ""
-    offset_name = 0x700
-    first_name = "\x00".join(main_pe_name + "\x00\x00")
-
-    o = ""
-    o += pck32(InLoadOrderModuleList_address)
-    o += pck32(InLoadOrderModuleList_address +
-               (len(modules_name) - 1) * 0x1000)
-    o += pck32(InLoadOrderModuleList_address + 8)
-    o += pck32(InLoadOrderModuleList_address +
-               (len(modules_name) - 1) * 0x1000 + 8)
-    o += pck32(InLoadOrderModuleList_address + 0x10)
-    o += pck32(InLoadOrderModuleList_address +
-               (len(modules_name) - 1) * 0x1000 + 0x10)
-
-    if main_pe:
-        o += pck32(main_pe.NThdr.ImageBase)
-        o += pck32(main_pe.rva2virt(main_pe.Opthdr.AddressOfEntryPoint))
-    else:
-        # no fixed values
-        pass
-
-    o += (0x24 - len(o)) * "A"
-    o += struct.pack('HH', len(first_name), len(first_name))
-    o += pck32(InLoadOrderModuleList_address + offset_name)
-
-    o += (0x2C - len(o)) * "A"
-    o += struct.pack('HH', len(first_name), len(first_name))
-    o += pck32(InLoadOrderModuleList_address + offset_name)
-
-    o += (offset_name - len(o)) * "B"
-    o += first_name
-    o += (0x1000 - len(o)) * "C"
-    for i, m in enumerate(modules_name):
-        # fname = os.path.join('win_dll', m)
-        if isinstance(m, tuple):
-            fname, e = m
-        else:
-            fname, e = m, None
-        bname = os.path.split(fname)[1].lower()
-        bname = "\x00".join(bname) + "\x00"
-        print hex(InLoadOrderModuleList_address + i * 0x1000)
-        if e is None:
-            e = pe_init.PE(open(fname, 'rb').read())
-
-        print "add module", hex(e.NThdr.ImageBase), repr(bname)
-
-        next_ad = InLoadOrderModuleList_address + (i + 1) * 0x1000
-        if i == len(modules_name) - 1:
-            next_ad = InLoadOrderModuleList_address
-        m_o = ""
-        m_o += pck32(next_ad)
-        m_o += pck32(InLoadOrderModuleList_address + (i - 1) * 0x1000)
-        m_o += pck32(next_ad + 8)
-        m_o += pck32(InLoadOrderModuleList_address + (i - 1) * 0x1000 + 8)
-        m_o += pck32(next_ad + 0x10)
-        m_o += pck32(InLoadOrderModuleList_address + (i - 1) * 0x1000 + 0x10)
-        m_o += pck32(e.NThdr.ImageBase)
-        m_o += pck32(e.rva2virt(e.Opthdr.AddressOfEntryPoint))
-        m_o += pck32(e.NThdr.sizeofimage)
-
-        m_o += (0x24 - len(m_o)) * "A"
-        print hex(len(bname)), repr(bname)
-        m_o += struct.pack('HH', len(bname), len(bname) + 2)
-        m_o += pck32(InLoadOrderModuleList_address + i * 0x1000 + offset_name)
-
-        m_o += (0x2C - len(m_o)) * "A"
-        m_o += struct.pack('HH', len(bname), len(bname) + 2)
-        m_o += pck32(InLoadOrderModuleList_address + i * 0x1000 + offset_name)
-
-        m_o += (offset_name - len(m_o)) * "B"
-        m_o += bname
-        m_o += "\x00" * 3
-
-        m_o += (0x1000 - len(m_o)) * "J"
-
-        print "module", "%.8X" % e.NThdr.ImageBase, fname
-
-        o += m_o
-    return o
-
-
 all_seh_ad = dict([(x, None)
                   for x in xrange(FAKE_SEH_B_AD, FAKE_SEH_B_AD + 0x1000, 0x20)])
 # http://blog.fireeye.com/research/2010/08/download_exec_notes.html
 seh_count = 0
 
+
 def init_seh(myjit):
     global seh_count
     seh_count = 0
-    # myjit.vm.add_memory_page(tib_address, PAGE_READ | PAGE_WRITE,
-    # p(default_seh) + p(0) * 11 + p(peb_address))
-    myjit.vm.add_memory_page(
-        FS_0_AD, PAGE_READ | PAGE_WRITE, build_fake_teb())
-    # myjit.vm.add_memory_page(peb_address, PAGE_READ | PAGE_WRITE, p(0) *
-    # 3 + p(peb_ldr_data_address))
-    myjit.vm.add_memory_page(
-        peb_address, PAGE_READ | PAGE_WRITE, build_fake_peb())
-    # myjit.vm.add_memory_page(peb_ldr_data_address, PAGE_READ |
-    # PAGE_WRITE, p(0) * 3 + p(in_load_order_module_list_address) + p(0) *
-    # 0x20)
+    build_teb(myjit, FS_0_AD)
+    build_peb(myjit, peb_address)
 
-    """
-    ldr_data += "\x00"*(InInitializationOrderModuleList_offset - len(ldr_data))
-    ldr_data += build_fake_InInitializationOrderModuleList(loaded_modules)
-    ldr_data += "\x00"*(InLoadOrderModuleList_offset - len(ldr_data))
-    ldr_data += build_fake_InLoadOrderModuleList(loaded_modules)
-    """
-    myjit.vm.add_memory_page(
-        LDR_AD, PAGE_READ | PAGE_WRITE, "\x00" * MAX_MODULES * 0x1000)
     module_info = create_modules_chain(myjit, loaded_modules)
     fix_InLoadOrderModuleList(myjit, module_info)
     fix_InMemoryOrderModuleList(myjit, module_info)
     fix_InInitializationOrderModuleList(myjit, module_info)
 
-    ldr_data = build_fake_ldr_data(module_info)
-    myjit.vm.set_mem(LDR_AD, ldr_data)
+    build_ldr_data(myjit, module_info)
     add_process_env(myjit)
     add_process_parameters(myjit)
 
-    # myjit.vm.add_memory_page(in_load_order_module_list_address,
-    #     PAGE_READ | PAGE_WRITE, p(0) * 40)
-    # myjit.vm.add_memory_page(in_load_order_module_list_address,
-    #     PAGE_READ | PAGE_WRITE, build_fake_inordermodule(loaded_modules))
     myjit.vm.add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, pck32(
         0xffffffff) + pck32(0x41414141) + pck32(0x42424242))
 
@@ -646,113 +449,105 @@ def init_seh(myjit):
 # http://www.codeproject.com/KB/system/inject2exe.aspx#RestorethefirstRegistersContext5_1
 
 
-def regs2ctxt(regs):
-    ctxt = ""
-    ctxt += '\x00\x00\x00\x00'  # ContextFlags
-    ctxt += '\x00\x00\x00\x00' * 6  # drX
-    ctxt += '\x00' * 112  # float context
-    ctxt += '\x00\x00\x00\x00' + '\x3b\x00\x00\x00' + \
-        '\x23\x00\x00\x00' + '\x23\x00\x00\x00'  # segment selectors
-    ctxt += pck32(regs['EDI']) + pck32(regs['ESI']) + pck32(regs['EBX']) + \
-        pck32(regs['EDX']) + pck32(regs['ECX']) + pck32(regs['EAX']) + \
-        pck32(regs['EBP']) + pck32(regs['EIP'])  # gpregs
-    ctxt += '\x23\x00\x00\x00'  # cs
-    ctxt += '\x00\x00\x00\x00'  # eflags
-    ctxt += pck32(regs['ESP'])  # esp
-    ctxt += '\x23\x00\x00\x00'  # ss segment selector
-    return ctxt
-
-
-def ctxt2regs(ctxt):
-    ctxt = ctxt[:]
-    regs = {}
-    # regs['ctxtsflags'] = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    for i in xrange(8):
-        if i in [4, 5]:
-            continue
-        # regs['dr%d'%i] = upck32(ctxt[:4])
-        ctxt = ctxt[4:]
+def regs2ctxt(myjit):
+    """
+    Build x86_32 cpu context for exception handling
+    @myjit: jitload instance
+    """
 
-    ctxt = ctxt[112:]  # skip float
+    ctxt = []
+    # ContextFlags
+    ctxt += [pck32(0x0)]
+    # DRX
+    ctxt += [pck32(0x0)] * 6
+    # Float context
+    ctxt += ['\x00' * 112]
+    # Segment selectors
+    ctxt += [pck32(reg) for reg in (myjit.cpu.GS, myjit.cpu.FS,
+                                    myjit.cpu.ES, myjit.cpu.DS)]
+    # Gpregs
+    ctxt += [pck32(reg) for reg in (myjit.cpu.EDI, myjit.cpu.ESI,
+                                    myjit.cpu.EBX, myjit.cpu.EDX,
+                                    myjit.cpu.ECX, myjit.cpu.EAX,
+                                    myjit.cpu.EBP, myjit.cpu.EIP)]
+    # CS
+    ctxt += [pck32(myjit.cpu.CS)]
+    # Eflags
+    # XXX TODO real eflag
+    ctxt += [pck32(0x0)]
+    # ESP
+    ctxt += [pck32(myjit.cpu.ESP)]
+    # SS
+    ctxt += [pck32(myjit.cpu.SS)]
+    return "".join(ctxt)
+
+
+def ctxt2regs(ctxt, myjit):
+    """
+    Restore x86_32 registers from an exception context
+    @ctxt: the serialized context
+    @myjit: jitload instance
+    """
 
-    # regs['seg_gs'] = upck32(ctxt[:4])
+    ctxt = ctxt[:]
+    # ContextFlags
     ctxt = ctxt[4:]
-    # regs['seg_fs'] = upck32(ctxt[:4])
+    # DRX XXX TODO
+    ctxt = ctxt[4 * 6:]
+    # Float context XXX TODO
+    ctxt = ctxt[112:]
+    # gs
+    myjit.cpu.GS = upck32(ctxt[:4])
     ctxt = ctxt[4:]
-    # regs['seg_es'] = upck32(ctxt[:4])
+    # fs
+    myjit.cpu.FS = upck32(ctxt[:4])
     ctxt = ctxt[4:]
-    # regs['seg_ds'] = upck32(ctxt[:4])
+    # es
+    myjit.cpu.ES = upck32(ctxt[:4])
     ctxt = ctxt[4:]
-
-    regs['EDI'], regs['ESI'], regs['EBX'], regs['EDX'], regs['ECX'], regs[
-        'EAX'], regs['EBP'], regs['EIP'] = struct.unpack('I' * 8, ctxt[:4 * 8])
-    ctxt = ctxt[4 * 8:]
-
-    # regs['seg_cs'] = upck32(ctxt[:4])
+    # ds
+    myjit.cpu.DS = upck32(ctxt[:4])
     ctxt = ctxt[4:]
 
-    # regs['eflag'] = upck32(ctxt[:4])
+    # Gpregs
+    myjit.cpu.EDI = upck32(ctxt[:4])
     ctxt = ctxt[4:]
-
-    regs['ESP'] = upck32(ctxt[:4])
+    myjit.cpu.ESI = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
+    myjit.cpu.EBX = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
+    myjit.cpu.EDX = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
+    myjit.cpu.ECX = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
+    myjit.cpu.EAX = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
+    myjit.cpu.EBP = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
+    myjit.cpu.EIP = upck32(ctxt[:4])
     ctxt = ctxt[4:]
 
-    for a, b in regs.items():
-        print a, hex(b)
-    # skip extended
-    return regs
-
-
-def get_free_seh_place():
-    global all_seh_ad
-    ads = all_seh_ad.keys()
-    ads.sort()
-    for ad in ads:
-        v = all_seh_ad[ad]
-        if v is None:
-            print 'TAKING SEH', hex(ad)
-            all_seh_ad[ad] = True
-            return ad
-    raise ValueError('too many stacked seh ')
-
-
-def free_seh_place(ad):
-    print 'RELEASING SEH', hex(ad)
-
-    if not ad in all_seh_ad:
-        raise ValueError('zarb seh ad!', hex(ad))
-    if all_seh_ad[ad] is not True:
-        # @wisk typolol
-        raise ValueError('seh alreaedy remouvede?!!', hex(ad))
-    all_seh_ad[ad] = None
+    # CS
+    myjit.cpu.CS = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
+    # Eflag XXX TODO
+    ctxt = ctxt[4:]
+    # ESP
+    myjit.cpu.ESP = upck32(ctxt[:4])
+    ctxt = ctxt[4:]
 
 
 def fake_seh_handler(myjit, except_code):
-    global seh_count
+    global seh_count, context_address
     regs = myjit.cpu.get_gpreg()
-    print '-> exception at', hex(myjit.cpu.EIP), seh_count
+    log.warning('Exception at %x %r', myjit.cpu.EIP, seh_count)
     seh_count += 1
 
     # Help lambda
     p = lambda s: struct.pack('I', s)
 
-    # dump_gpregs_py()
-    # jitarch.dump_gpregs()
     # Forge a CONTEXT
-    ctxt = '\x00\x00\x00\x00' + '\x00\x00\x00\x00' * 6 + '\x00' * 112
-    ctxt += '\x00\x00\x00\x00' + '\x3b\x00\x00\x00' + '\x23\x00\x00\x00'
-    ctxt += '\x23\x00\x00\x00'
-    ctxt += pck32(myjit.cpu.EDI) + pck32(myjit.cpu.ESI) + \
-            pck32(myjit.cpu.EBX) + pck32(myjit.cpu.EDX) + \
-            pck32(myjit.cpu.ECX) + pck32(myjit.cpu.EAX) + \
-            pck32(myjit.cpu.EBP) + pck32(myjit.cpu.EIP)
-    ctxt += '\x23\x00\x00\x00' + '\x00\x00\x00\x00' + pck32(myjit.cpu.ESP)
-    ctxt += '\x23\x00\x00\x00'
-    # ctxt = regs2ctxt(regs)
-
-    # Find a room for seh
-    # seh = (get_memory_page_max_address_py()+0x1000)&0xfffff000
+    ctxt = regs2ctxt(myjit)
 
     # Get current seh (fs:[0])
     seh_ptr = upck32(myjit.vm.get_mem(tib_address, 4))
@@ -761,13 +556,15 @@ def fake_seh_handler(myjit, except_code):
     old_seh, eh, safe_place = struct.unpack(
         'III', myjit.vm.get_mem(seh_ptr, 0xc))
 
-    print '-> seh_ptr', hex(seh_ptr), '-> { old_seh',
-    print hex(old_seh), 'eh', hex(eh), 'safe_place', hex(safe_place), '}'
-    # print '-> write SEH at', hex(seh&0xffffffff)
+    # Get space on stack for exception handling
+    myjit.cpu.ESP -= 0x3c8
+    exception_base_address = myjit.cpu.ESP
+    exception_record_address = exception_base_address + 0xe8
+    context_address = exception_base_address + 0xfc
+    fake_seh_address = exception_base_address + 0x14
 
-    # Write current seh
-    # myjit.vm.add_memory_page(seh, PAGE_READ | PAGE_WRITE, p(old_seh) +
-    # p(eh) + p(safe_place) + p(0x99999999))
+    log.info('seh_ptr %x { old_seh %x eh %x safe_place %x} ctx_addr %x',
+             seh_ptr, old_seh, eh, safe_place, context_address)
 
     # Write context
     myjit.vm.set_mem(context_address, ctxt)
@@ -787,9 +584,9 @@ def fake_seh_handler(myjit, except_code):
     } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
     """
 
-    myjit.vm.set_mem(exception_record_address, pck32(except_code) +
-                     pck32(0) + pck32(0) + pck32(myjit.cpu.EIP) +
-                     pck32(0) + pck32(0))
+    myjit.vm.set_mem(exception_record_address,
+                     pck32(except_code) + pck32(0) + pck32(0) +
+                     pck32(myjit.cpu.EIP) + pck32(0))
 
     # Prepare the stack
     myjit.push_uint32_t(context_address)               # Context
@@ -798,15 +595,14 @@ def fake_seh_handler(myjit, except_code):
     myjit.push_uint32_t(return_from_exception)         # Ret address
 
     # Set fake new current seh for exception
-    fake_seh_ad = get_free_seh_place()
-    print hex(fake_seh_ad)
-    myjit.vm.set_mem(fake_seh_ad, pck32(seh_ptr) + pck32(
+    log.info("Fake seh ad %x", fake_seh_address)
+    myjit.vm.set_mem(fake_seh_address, pck32(seh_ptr) + pck32(
         0xaaaaaaaa) + pck32(0xaaaaaabb) + pck32(0xaaaaaacc))
-    myjit.vm.set_mem(tib_address, pck32(fake_seh_ad))
+    myjit.vm.set_mem(tib_address, pck32(fake_seh_address))
 
     dump_seh(myjit)
 
-    print '-> jumping at', hex(eh)
+    log.info('Jumping at %x', eh)
     myjit.vm.set_exception(0)
     myjit.cpu.set_exception(0)
 
@@ -819,18 +615,17 @@ fake_seh_handler.base = FAKE_SEH_B_AD
 
 
 def dump_seh(myjit):
-    print 'dump_seh:'
-    print '-> tib_address:', hex(tib_address)
+    log.info('Dump_seh. Tib_address: %x', tib_address)
     cur_seh_ptr = upck32(myjit.vm.get_mem(tib_address, 4))
     indent = 1
     loop = 0
     while True:
-        if loop > 5:
-            print "too many seh, quit"
+        if loop > MAX_SEH:
+            log.warn("Too many seh, quit")
             return
         prev_seh, eh = struct.unpack('II', myjit.vm.get_mem(cur_seh_ptr, 8))
-        print '\t' * indent + 'seh_ptr:', hex(cur_seh_ptr),
-        print ' -> { prev_seh:', hex(prev_seh), 'eh:', hex(eh), '}'
+        log.info('\t' * indent + 'seh_ptr: %x { prev_seh: %x eh %x }',
+                 cur_seh_ptr, prev_seh, eh)
         if prev_seh in [0xFFFFFFFF, 0]:
             break
         cur_seh_ptr = prev_seh
@@ -860,35 +655,29 @@ def return_from_seh(myjit):
     "Handle return after a call to fake seh handler"
 
     # Get current context
+    context_address = upck32(myjit.vm.get_mem(myjit.cpu.ESP + 0x8, 4))
+    log.info('Context address: %x', context_address)
     myjit.cpu.ESP = upck32(myjit.vm.get_mem(context_address + 0xc4, 4))
-    logging.info('-> new esp: %x', myjit.cpu.ESP)
+    log.info('New esp: %x', myjit.cpu.ESP)
 
     # Rebuild SEH
     old_seh = upck32(myjit.vm.get_mem(tib_address, 4))
     new_seh = upck32(myjit.vm.get_mem(old_seh, 4))
-    logging.info('-> old seh: %x', old_seh)
-    logging.info('-> new seh: %x', new_seh)
+    log.info('Old seh: %x New seh: %x', old_seh, new_seh)
     myjit.vm.set_mem(tib_address, pck32(new_seh))
 
     dump_seh(myjit)
 
-    # Release SEH
-    free_seh_place(old_seh)
-
     if myjit.cpu.EAX == 0x0:
         # ExceptionContinueExecution
-        print '-> seh continues'
         ctxt_ptr = context_address
-        print '-> context:', hex(ctxt_ptr)
+        log.info('Seh continues Context: %x', ctxt_ptr)
 
         # Get registers changes
         ctxt_str = myjit.vm.get_mem(ctxt_ptr, 0x2cc)
-        regs = ctxt2regs(ctxt_str)
-        myjit.pc = regs["EIP"]
-        for reg_name, reg_value in regs.items():
-            setattr(myjit.cpu, reg_name, reg_value)
-
-        logging.info('-> context::Eip: %x', myjit.pc)
+        ctxt2regs(ctxt_str, myjit)
+        myjit.pc = myjit.cpu.EIP
+        log.info('Context::Eip: %x', myjit.pc)
 
     elif myjit.cpu.EAX == -1:
         raise NotImplementedError("-> seh try to go to the next handler")