about summary refs log tree commit diff stats
path: root/test/arch/x86/unit/mn_seh.py
blob: 8575cc4647fdfefdec19efa3f6232cf4ad71f568 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#! /usr/bin/env python2
from __future__ import print_function
import sys

from miasm.os_dep.win_api_x86_32_seh import fake_seh_handler, build_teb, \
    set_win_fs_0, return_from_exception, EXCEPTION_PRIV_INSTRUCTION, \
    return_from_seh, DEFAULT_SEH
from miasm.os_dep.win_32_structs import ContextException

from asm_test import Asm_Test_32

from pdb import pm

class Test_SEH(Asm_Test_32):
    """SEH Handling"""

    @staticmethod
    def deal_exception_priv(jitter):
        print('Exception Priv', hex(jitter.cpu.ESP))
        pc = fake_seh_handler(jitter, EXCEPTION_PRIV_INSTRUCTION)
        jitter.pc = pc
        jitter.cpu.EIP = pc
        return True

    def init_machine(self):
        super(Test_SEH, self).init_machine()
        set_win_fs_0(self.myjit)
        tib_ad = self.myjit.cpu.get_segm_base(self.myjit.cpu.FS)
        build_teb(self.myjit, tib_ad)
        self.myjit.add_exception_handler((1 << 17),
                                         Test_SEH.deal_exception_priv)
        self.myjit.add_breakpoint(return_from_exception, return_from_seh)


class Test_SEH_simple(Test_SEH):
    TXT = '''
    main:
       XOR EAX, EAX
       XOR EDX, EDX

       PUSH handler
       PUSH DWORD PTR FS:[EDX]
       MOV DWORD PTR FS:[EDX], ESP

       STI

       MOV EBX, DWORD PTR [ESP]
       MOV DWORD PTR FS:[EDX], EBX
       ADD ESP, 0x8

       RET

    handler:
       MOV ECX, DWORD PTR [ESP+0xC]
       INC DWORD PTR [ECX+0x%08x]
       MOV DWORD PTR [ECX+0x%08x], 0xcafebabe
       XOR EAX, EAX
       RET
    ''' % (ContextException.get_offset("eip"),
           ContextException.get_offset("eax"))

    def check(self):
        assert(self.myjit.cpu.EAX == 0xcafebabe)
        assert(self.myjit.cpu.EBX == DEFAULT_SEH)


class Test_SEH_double(Test_SEH_simple):
    TXT = '''
    main:
       XOR EAX, EAX
       XOR EDX, EDX

       PUSH handler1
       PUSH DWORD PTR FS:[EDX]
       MOV DWORD PTR FS:[EDX], ESP

       PUSH handler2
       PUSH DWORD PTR FS:[EDX]
       MOV DWORD PTR FS:[EDX], ESP

       STI

       MOV EBX, DWORD PTR [ESP]
       MOV DWORD PTR FS:[EDX], EBX
       ADD ESP, 0x8

       MOV EBX, DWORD PTR [ESP]
       MOV DWORD PTR FS:[EDX], EBX
       ADD ESP, 0x8

       RET

    handler1:
       MOV EAX, 0x1
       RET

    handler2:
       MOV ECX, DWORD PTR [ESP+0xC]
       INC DWORD PTR [ECX+0x%08x]
       MOV DWORD PTR [ECX+0x%08x], 0xcafebabe
       XOR EAX, EAX
       RET
    ''' % (ContextException.get_offset("eip"),
           ContextException.get_offset("eax"))


if __name__ == "__main__":
    [test(*sys.argv[1:])() for test in [Test_SEH_simple, Test_SEH_double]]