]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | ; Copyright Oliver Kowalke 2009. | |
3 | ; Distributed under the Boost Software License, Version 1.0. | |
4 | ; (See accompanying file LICENSE_1_0.txt or copy at | |
5 | ; http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | ; --------------------------------------------------------------------------------- | |
8 | ; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | |
9 | ; --------------------------------------------------------------------------------- | |
10 | ; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | | |
11 | ; --------------------------------------------------------------------------------- | |
12 | ; | fc_strg |fc_deallo| limit | base | fc_seh | EDI | ESI | EBX | | |
13 | ; --------------------------------------------------------------------------------- | |
14 | ; --------------------------------------------------------------------------------- | |
15 | ; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | | |
16 | ; --------------------------------------------------------------------------------- | |
17 | ; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | | |
18 | ; --------------------------------------------------------------------------------- | |
19 | ; | EBP | EIP | to | data | | EH NXT |SEH HNDLR| | | |
20 | ; --------------------------------------------------------------------------------- | |
21 | ||
22 | .386 | |
23 | .XMM | |
24 | .model flat, c | |
25 | ; standard C library function | |
26 | _exit PROTO, value:SDWORD | |
27 | .code | |
28 | ||
29 | make_fcontext PROC BOOST_CONTEXT_EXPORT | |
30 | ; first arg of make_fcontext() == top of context-stack | |
31 | mov eax, [esp+04h] | |
32 | ||
33 | ; reserve space for first argument of context-function | |
34 | ; EAX might already point to a 16byte border | |
35 | lea eax, [eax-08h] | |
36 | ||
37 | ; shift address in EAX to lower 16 byte boundary | |
38 | and eax, -16 | |
39 | ||
40 | ; reserve space for context-data on context-stack | |
41 | ; on context-function entry: (ESP -0x4) % 8 == 0 | |
42 | ; additional space is required for SEH | |
43 | lea eax, [eax-048h] | |
44 | ||
45 | ; first arg of make_fcontext() == top of context-stack | |
46 | mov ecx, [esp+04h] | |
47 | ; save top address of context stack as 'base' | |
48 | mov [eax+0ch], ecx | |
49 | ; second arg of make_fcontext() == size of context-stack | |
50 | mov edx, [esp+08h] | |
51 | ; negate stack size for LEA instruction (== substraction) | |
52 | neg edx | |
53 | ; compute bottom address of context stack (limit) | |
54 | lea ecx, [ecx+edx] | |
55 | ; save bottom address of context-stack as 'limit' | |
56 | mov [eax+08h], ecx | |
57 | ; save bottom address of context-stack as 'dealloction stack' | |
58 | mov [eax+04h], ecx | |
59 | ; set fiber-storage to zero | |
60 | xor ecx, ecx | |
61 | mov [eax], ecx | |
62 | ||
63 | ; third arg of make_fcontext() == address of context-function | |
64 | ; stored in EBX | |
65 | mov ecx, [esp+0ch] | |
66 | mov [eax+01ch], ecx | |
67 | ||
68 | ; compute abs address of label trampoline | |
69 | mov ecx, trampoline | |
70 | ; save address of trampoline as return-address for context-function | |
71 | ; will be entered after calling jump_fcontext() first time | |
72 | mov [eax+024h], ecx | |
73 | ||
74 | ; compute abs address of label finish | |
75 | mov ecx, finish | |
76 | ; save address of finish as return-address for context-function | |
77 | ; will be entered after context-function returns | |
78 | mov [eax+020h], ecx | |
79 | ||
80 | ; traverse current seh chain to get the last exception handler installed by Windows | |
81 | ; note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default | |
82 | ; the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler | |
83 | ; at its end by RaiseException all seh-handlers are disregarded if not present and the | |
84 | ; program is aborted | |
85 | assume fs:nothing | |
86 | ; load NT_TIB into ECX | |
87 | mov ecx, fs:[0h] | |
88 | assume fs:error | |
89 | ||
90 | walk: | |
91 | ; load 'next' member of current SEH into EDX | |
92 | mov edx, [ecx] | |
93 | ; test if 'next' of current SEH is last (== 0xffffffff) | |
94 | inc edx | |
95 | jz found | |
96 | dec edx | |
97 | ; exchange content; ECX contains address of next SEH | |
98 | xchg edx, ecx | |
99 | ; inspect next SEH | |
100 | jmp walk | |
101 | ||
102 | found: | |
103 | ; load 'handler' member of SEH == address of last SEH handler installed by Windows | |
104 | mov ecx, [ecx+04h] | |
105 | ; save address in ECX as SEH handler for context | |
106 | mov [eax+038h], ecx | |
107 | ; set ECX to -1 | |
108 | mov ecx, 0ffffffffh | |
109 | ; save ECX as next SEH item | |
110 | mov [eax+034h], ecx | |
111 | ; load address of next SEH item | |
112 | lea ecx, [eax+034h] | |
113 | ; save next SEH | |
114 | mov [eax+010h], ecx | |
115 | ||
116 | ret ; return pointer to context-data | |
117 | ||
118 | trampoline: | |
119 | ; move transport_t for entering context-function | |
120 | ; FCTX == EAX, DATA == EDX | |
121 | mov [esp], eax | |
122 | mov [esp+04h], edx | |
123 | push ebp | |
124 | ; jump to context-function | |
125 | jmp ebx | |
126 | ||
127 | finish: | |
128 | ; exit code is zero | |
129 | xor eax, eax | |
130 | mov [esp], eax | |
131 | ; exit application | |
132 | call _exit | |
133 | hlt | |
134 | make_fcontext ENDP | |
135 | END |