コード例 #1
0
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))
    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))
    log.info('Old seh: %x New seh: %x', old_seh, new_seh)
    myjit.vm.set_mem(tib_address, pck32(new_seh))

    dump_seh(myjit)

    if myjit.cpu.EAX == 0x0:
        # ExceptionContinueExecution
        ctxt_ptr = context_address
        log.info('Seh continues Context: %x', ctxt_ptr)

        # Get registers changes
        ctxt_str = myjit.vm.get_mem(ctxt_ptr, 0x2cc)
        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")

    elif myjit.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
コード例 #2
0
def return_from_seh(jitter):
    """Handle the return from an exception handler
    @jitter: jitter instance"""

    # Get current context
    context_address = upck32(jitter.vm.get_mem(jitter.cpu.ESP + 0x8, 4))
    log.info('Context address: %x', context_address)
    jitter.cpu.ESP = upck32(jitter.vm.get_mem(context_address + 0xc4, 4))
    log.info('New esp: %x', jitter.cpu.ESP)

    # Rebuild SEH
    old_seh = upck32(jitter.vm.get_mem(tib_address, 4))
    new_seh = upck32(jitter.vm.get_mem(old_seh, 4))
    log.info('Old seh: %x New seh: %x', old_seh, new_seh)
    jitter.vm.set_mem(tib_address, pck32(new_seh))

    dump_seh(jitter)

    if jitter.cpu.EAX == 0x0:
        # ExceptionContinueExecution
        ctxt_ptr = context_address
        log.info('Seh continues Context: %x', ctxt_ptr)

        # Get registers changes
        ctxt_str = jitter.vm.get_mem(ctxt_ptr, 0x2cc)
        ctxt2regs(ctxt_str, jitter)
        jitter.pc = jitter.cpu.EIP
        log.info('Context::Eip: %x', jitter.pc)

    elif jitter.cpu.EAX == -1:
        raise NotImplementedError("-> seh try to go to the next handler")

    elif jitter.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
コード例 #3
0
ファイル: testqemu.py プロジェクト: a-vincent/miasm
def xxx___printf_chk(jitter):
    """Tiny implementation of printf_chk"""
    global nb_tests
    ret_ad, args = jitter.func_args_cdecl(["out", "format"])
    if args.out != 1:
        raise RuntimeError("Not implemented")
    fmt = jitter.get_str_ansi(args.format)
    # Manage llx
    fmt = fmt.replace("llx", "lx")
    fmt = fmt.replace("%016lx", "%016z")

    fmt_a = parse_fmt(fmt)
    esp = jitter.cpu.ESP
    args = []
    i = 0

    for x in fmt_a:
        a = upck32(jitter.vm.get_mem(esp + 8 + 4*i, 4))
        if x == "s":
            a = jitter.get_str_ansi(a)
        elif x.lower() in ("x", 'd'):
            pass
        elif x.lower() in ("f", "l"):
            a2 = upck32(jitter.vm.get_mem(esp + 8 + 4*(i+1), 4))
            a = struct.unpack("d", struct.pack("Q", a2 << 32 | a))[0]
            i += 1
        elif x.lower() == 'z':
            a2 = upck32(jitter.vm.get_mem(esp + 8 + 4*(i+1), 4))
            a = a2 << 32 | a
            i += 1
        else:
            raise RuntimeError("Not implemented format")
        args.append(a)
        i += 1

    fmt = fmt.replace("%016z", "%016lx")
    output = fmt%(tuple(args))
    # NaN bad repr in Python
    output = output.replace("nan", "-nan")

    if "\n" not in output:
        raise RuntimeError("Format must end with a \\n")

    # Check with expected result
    line = expected.next()
    if output != line:
        print "Expected:", line
        print "Obtained:", output
        raise RuntimeError("Bad semantic")

    sys.stdout.write("[%d] %s" % (nb_tests, output))
    nb_tests += 1
    jitter.func_ret_cdecl(ret_ad, 0)
コード例 #4
0
ファイル: win_api_x86_32_seh.py プロジェクト: a-vincent/miasm
def return_from_seh(jitter):
    """Handle the return from an exception handler
    @jitter: jitter instance"""

    # Get object addresses
    seh_address = upck32(jitter.vm.get_mem(jitter.cpu.ESP + 0x4, 4))
    context_address = upck32(jitter.vm.get_mem(jitter.cpu.ESP + 0x8, 4))

    # Get registers changes
    log.info('Context address: %x', context_address)
    status = jitter.cpu.EAX
    ctxt2regs(jitter, context_address)

    # Rebuild SEH (remove fake SEH)
    tib = NT_TIB(jitter.vm, tib_address)
    seh = tib.ExceptionList.deref
    log.info('Old seh: %x New seh: %x', seh.get_addr(), seh.Next.val)
    tib.ExceptionList.val = seh.Next.val
    dump_seh(jitter)

    # Handle returned values
    if status == 0x0:
        # ExceptionContinueExecution
        log.info('SEH continue')
        jitter.pc = jitter.cpu.EIP
        log.info('Context::Eip: %x', jitter.pc)

    elif status == 1:
        # ExceptionContinueSearch
        log.info("Delegate to the next SEH handler")
        # exception_base_address: context_address - 0xfc
        # -> exception_record_address: exception_base_address + 0xe8
        exception_record = EXCEPTION_RECORD(jitter.vm,
                                            context_address - 0xfc + 0xe8)

        pc = fake_seh_handler(jitter, exception_record.ExceptionCode,
                              seh_address)
        jitter.pc = pc

    else:
        # https://msdn.microsoft.com/en-us/library/aa260344%28v=vs.60%29.aspx
        # But the type _EXCEPTION_DISPOSITION may take 2 others values:
        #  - ExceptionNestedException = 2
        #  - ExceptionCollidedUnwind = 3
        raise ValueError("Valid values are ExceptionContinueExecution and "
                         "ExceptionContinueSearch")

    # Jitter's breakpoint compliant
    return True
コード例 #5
0
ファイル: disasm_cb.py プロジェクト: carolineLe/miasm
def arm_guess_jump_table(
    mnemo, attrib, pool_bin, cur_bloc, offsets_to_dis, symbol_pool):
    ira = get_ira(mnemo, attrib)

    jra = ExprId('jra')
    jrb = ExprId('jrb')

    sp = AsmSymbolPool()
    ir_arch = ira(sp)
    ir_arch.add_bloc(cur_bloc)

    ir_blocks = ir_arch.blocks.values()
    for irblock in ir_blocks:
        # print 'X'*40
        # print irblock
        pc_val = None
        # lr_val = None
        for exprs in irblock.irs:
            for e in exprs:
                if e.dst == ir_arch.pc:
                    pc_val = e.src
                # if e.dst == mnemo.regs.LR:
                #    lr_val = e.src
        if pc_val is None:
            continue
        if not isinstance(pc_val, ExprMem):
            continue
        assert(pc_val.size == 32)
        print pc_val
        ad = pc_val.arg
        ad = expr_simp(ad)
        print ad
        res = match_expr(ad, jra + jrb, set([jra, jrb]))
        if res is False:
            raise NotImplementedError('not fully functional')
        print res
        if not isinstance(res[jrb], ExprInt):
            raise NotImplementedError('not fully functional')
        base_ad = int(res[jrb])
        print base_ad
        addrs = set()
        i = -1
        max_table_entry = 10000
        max_diff_addr = 0x100000  # heuristic
        while i < max_table_entry:
            i += 1
            try:
                ad = upck32(pool_bin.getbytes(base_ad + 4 * i, 4))
            except:
                break
            if abs(ad - base_ad) > max_diff_addr:
                break
            addrs.add(ad)
        print [hex(x) for x in addrs]
コード例 #6
0
ファイル: win_api_x86_32_seh.py プロジェクト: CaineQT/miasm
def return_from_seh(myjit):
    "Handle return after a call to fake seh handler"

    # Get current context
    myjit.cpu.ESP = upck32(myjit.vm.get_mem(context_address + 0xc4, 4))
    logging.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)
    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)

        # 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)

    elif myjit.cpu.EAX == -1:
        raise NotImplementedError("-> seh try to go to the next handler")

    elif myjit.cpu.EAX == 1:
        # ExceptionContinueSearch
        raise NotImplementedError("-> seh, gameover")
コード例 #7
0
def dump_seh(myjit):
    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 > MAX_SEH:
            log.warn("Too many seh, quit")
            return
        prev_seh, eh = struct.unpack('II', myjit.vm.get_mem(cur_seh_ptr, 8))
        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
        indent += 1
        loop += 1
コード例 #8
0
ファイル: win_api_x86_32_seh.py プロジェクト: CaineQT/miasm
def dump_seh(myjit):
    print 'dump_seh:'
    print '-> tib_address:', hex(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"
            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), '}'
        if prev_seh in [0xFFFFFFFF, 0]:
            break
        cur_seh_ptr = prev_seh
        indent += 1
        loop += 1
コード例 #9
0
def dump_seh(jitter):
    """
    Walk and dump the SEH entries
    @jitter: jitter instance
    """

    log.info('Dump_seh. Tib_address: %x', tib_address)
    cur_seh_ptr = upck32(jitter.vm.get_mem(tib_address, 4))
    indent = 1
    loop = 0
    while True:
        if loop > MAX_SEH:
            log.warn("Too many seh, quit")
            return
        prev_seh, eh = struct.unpack('II', jitter.vm.get_mem(cur_seh_ptr, 8))
        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
        indent += 1
        loop += 1
コード例 #10
0
ファイル: win_api_x86_32_seh.py プロジェクト: CaineQT/miasm
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:]

    ctxt = ctxt[112:]  # skip float

    # regs['seg_gs'] = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    # regs['seg_fs'] = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    # regs['seg_es'] = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    # regs['seg_ds'] = 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])
    ctxt = ctxt[4:]

    # regs['eflag'] = upck32(ctxt[:4])
    ctxt = ctxt[4:]

    regs['ESP'] = upck32(ctxt[:4])
    ctxt = ctxt[4:]

    for a, b in regs.items():
        print a, hex(b)
    # skip extended
    return regs
コード例 #11
0
def fake_seh_handler(jitter, except_code):
    """
    Create an exception context
    @jitter: jitter instance
    @except_code: x86 exception code
    """

    global seh_count, context_address
    regs = jitter.cpu.get_gpreg()
    log.warning('Exception at %x %r', jitter.cpu.EIP, seh_count)
    seh_count += 1

    # Help lambda
    p = lambda s: struct.pack('I', s)

    # Forge a CONTEXT
    ctxt = regs2ctxt(jitter)

    # Get current seh (fs:[0])
    seh_ptr = upck32(jitter.vm.get_mem(tib_address, 4))

    # Retrieve seh fields
    old_seh, eh, safe_place = struct.unpack(
        'III', jitter.vm.get_mem(seh_ptr, 0xc))

    # Get space on stack for exception handling
    jitter.cpu.ESP -= 0x3c8
    exception_base_address = jitter.cpu.ESP
    exception_record_address = exception_base_address + 0xe8
    context_address = exception_base_address + 0xfc
    fake_seh_address = exception_base_address + 0x14

    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
    jitter.vm.set_mem(context_address, ctxt)

    # Write exception_record

    """
    #http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx

    typedef struct _EXCEPTION_RECORD {
      DWORD                    ExceptionCode;
      DWORD                    ExceptionFlags;
      struct _EXCEPTION_RECORD *ExceptionRecord;
      PVOID                    ExceptionAddress;
      DWORD                    NumberParameters;
      ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
    """

    jitter.vm.set_mem(exception_record_address,
                      pck32(except_code) + pck32(0) + pck32(0) +
                      pck32(jitter.cpu.EIP) + pck32(0))

    # Prepare the stack
    jitter.push_uint32_t(context_address)               # Context
    jitter.push_uint32_t(seh_ptr)                       # SEH
    jitter.push_uint32_t(exception_record_address)      # ExceptRecords
    jitter.push_uint32_t(return_from_exception)         # Ret address

    # Set fake new current seh for exception
    log.info("Fake seh ad %x", fake_seh_address)
    jitter.vm.set_mem(fake_seh_address, pck32(seh_ptr) + pck32(
        0xaaaaaaaa) + pck32(0xaaaaaabb) + pck32(0xaaaaaacc))
    jitter.vm.set_mem(tib_address, pck32(fake_seh_address))

    dump_seh(jitter)

    log.info('Jumping at %x', eh)
    jitter.vm.set_exception(0)
    jitter.cpu.set_exception(0)

    # XXX set ebx to nul?
    jitter.cpu.EBX = 0

    return eh
コード例 #12
0
def ctxt2regs(ctxt, jitter):
    """
    Restore x86_32 registers from an exception context
    @ctxt: the serialized context
    @jitter: jitload instance
    """

    ctxt = ctxt[:]
    # ContextFlags
    ctxt = ctxt[4:]
    # DRX XXX TODO
    ctxt = ctxt[4 * 6:]
    # Float context XXX TODO
    ctxt = ctxt[112:]
    # gs
    jitter.cpu.GS = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    # fs
    jitter.cpu.FS = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    # es
    jitter.cpu.ES = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    # ds
    jitter.cpu.DS = upck32(ctxt[:4])
    ctxt = ctxt[4:]

    # Gpregs
    jitter.cpu.EDI = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    jitter.cpu.ESI = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    jitter.cpu.EBX = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    jitter.cpu.EDX = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    jitter.cpu.ECX = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    jitter.cpu.EAX = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    jitter.cpu.EBP = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    jitter.cpu.EIP = upck32(ctxt[:4])
    ctxt = ctxt[4:]

    # CS
    jitter.cpu.CS = upck32(ctxt[:4])
    ctxt = ctxt[4:]
    # Eflag XXX TODO
    ctxt = ctxt[4:]
    # ESP
    jitter.cpu.ESP = upck32(ctxt[:4])
    ctxt = ctxt[4:]
コード例 #13
0
ファイル: jit.py プロジェクト: carolineLe/miasm
 def pop_uint32_t(self):
     value = upck32(self.vm.get_mem(self.cpu.ESP, self.ir_arch.sp.size / 8))
     self.cpu.ESP += self.ir_arch.sp.size / 8
     return value
コード例 #14
0
 def pop_uint32_t(self):
     value = upck32(self.vm.get_mem(self.cpu.ESP, self.ir_arch.sp.size / 8))
     self.cpu.ESP += self.ir_arch.sp.size / 8
     return value
コード例 #15
0
ファイル: jit.py プロジェクト: carolineLe/miasm
 def pop_uint32_t(self):
     value = upck32(self.vm.get_mem(self.cpu.SP, 4))
     self.cpu.SP += 4
     return value
コード例 #16
0
ファイル: jit.py プロジェクト: mhanne0915/miasm
 def pop_uint32_t(self):
     value = upck32(self.vm.get_mem(self.cpu.SP, 4))
     self.cpu.SP += 4
     return value
コード例 #17
0
ファイル: jit.py プロジェクト: RuiKuang/miasm
 def get_stack_arg(self, index):
     return upck32(self.vm.get_mem(self.cpu.SP + 4 * index, 4))
コード例 #18
0
ファイル: win_api_x86_32_seh.py プロジェクト: CaineQT/miasm
def fake_seh_handler(myjit, except_code):
    global seh_count
    regs = myjit.cpu.get_gpreg()
    print '-> exception at', hex(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

    # Get current seh (fs:[0])
    seh_ptr = upck32(myjit.vm.get_mem(tib_address, 4))

    # Retrieve seh fields
    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)

    # Write current seh
    # myjit.vm.add_memory_page(seh, PAGE_READ | PAGE_WRITE, p(old_seh) +
    # p(eh) + p(safe_place) + p(0x99999999))

    # Write context
    myjit.vm.set_mem(context_address, ctxt)

    # Write exception_record

    """
    #http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx

    typedef struct _EXCEPTION_RECORD {
      DWORD                    ExceptionCode;
      DWORD                    ExceptionFlags;
      struct _EXCEPTION_RECORD *ExceptionRecord;
      PVOID                    ExceptionAddress;
      DWORD                    NumberParameters;
      ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } 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))

    # Prepare the stack
    myjit.push_uint32_t(context_address)               # Context
    myjit.push_uint32_t(seh_ptr)                       # SEH
    myjit.push_uint32_t(exception_record_address)      # ExceptRecords
    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(
        0xaaaaaaaa) + pck32(0xaaaaaabb) + pck32(0xaaaaaacc))
    myjit.vm.set_mem(tib_address, pck32(fake_seh_ad))

    dump_seh(myjit)

    print '-> jumping at', hex(eh)
    myjit.vm.set_exception(0)
    myjit.cpu.set_exception(0)

    # XXX set ebx to nul?
    myjit.cpu.EBX = 0

    return eh
コード例 #19
0
ファイル: jit.py プロジェクト: carolineLe/miasm
 def get_stack_arg(self, index):
     return upck32(self.vm.get_mem(self.cpu.SP + 4 * index, 4))
コード例 #20
0
def fake_seh_handler(myjit, except_code):
    global seh_count
    regs = myjit.cpu.get_gpreg()
    print '-> exception at', hex(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

    # Get current seh (fs:[0])
    seh_ptr = upck32(myjit.vm.get_mem(tib_address, 4))

    # Retrieve seh fields
    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)

    # Write current seh
    # myjit.vm.add_memory_page(seh, PAGE_READ | PAGE_WRITE, p(old_seh) +
    # p(eh) + p(safe_place) + p(0x99999999))

    # Write context
    myjit.vm.set_mem(context_address, ctxt)

    # Write exception_record
    """
    #http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx

    typedef struct _EXCEPTION_RECORD {
      DWORD                    ExceptionCode;
      DWORD                    ExceptionFlags;
      struct _EXCEPTION_RECORD *ExceptionRecord;
      PVOID                    ExceptionAddress;
      DWORD                    NumberParameters;
      ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } 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))

    # Prepare the stack
    myjit.push_uint32_t(context_address)  # Context
    myjit.push_uint32_t(seh_ptr)  # SEH
    myjit.push_uint32_t(exception_record_address)  # ExceptRecords
    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(0xaaaaaaaa) + pck32(0xaaaaaabb) +
        pck32(0xaaaaaacc))
    myjit.vm.set_mem(tib_address, pck32(fake_seh_ad))

    dump_seh(myjit)

    print '-> jumping at', hex(eh)
    myjit.vm.set_exception(0)
    myjit.cpu.set_exception(0)

    # XXX set ebx to nul?
    myjit.cpu.EBX = 0

    return eh