VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMainA-win.asm@ 81118

Last change on this file since 81118 was 81118, checked in by vboxsync, 5 years ago

SUPHardNt: Try hook KiUserExceptionDispatcher and log exceptions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1; $Id: SUPR3HardenedMainA-win.asm 81118 2019-10-06 01:02:53Z vboxsync $
2;; @file
3; VirtualBox Support Library - Hardened main(), Windows assembly bits.
4;
5
6;
7; Copyright (C) 2012-2019 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27;*******************************************************************************
28;* Header Files *
29;*******************************************************************************
30%define RT_ASM_WITH_SEH64
31%include "iprt/asmdefs.mac"
32
33
34; External code.
35extern NAME(supR3HardenedEarlyProcessInit)
36extern NAME(supR3HardenedMonitor_KiUserApcDispatcher_C)
37%ifndef VBOX_WITHOUT_HARDENDED_XCPT_LOGGING
38extern NAME(supR3HardenedMonitor_KiUserExceptionDispatcher_C)
39%endif
40
41
42BEGINCODE
43
44
45;;
46; Alternative code for LdrInitializeThunk that performs the early process startup
47; for the Stub and VM processes.
48;
49; This does not concern itself with any arguments on stack or in registers that
50; may be passed to the LdrIntializeThunk routine as we just save and restore
51; them all before we restart the restored LdrInitializeThunk routine.
52;
53; @sa supR3HardenedEarlyProcessInit
54;
55BEGINPROC supR3HardenedEarlyProcessInitThunk
56 ;
57 ; Prologue.
58 ;
59
60 ; Reserve space for the "return" address.
61 push 0
62
63 ; Create a stack frame, saving xBP.
64 push xBP
65 SEH64_PUSH_xBP
66 mov xBP, xSP
67 SEH64_SET_FRAME_xBP 0 ; probably wrong...
68
69 ; Save all volatile registers.
70 push xAX
71 push xCX
72 push xDX
73%ifdef RT_ARCH_AMD64
74 push r8
75 push r9
76 push r10
77 push r11
78%endif
79
80 ; Reserve spill space and align the stack.
81 sub xSP, 20h
82 and xSP, ~0fh
83 SEH64_END_PROLOGUE
84
85 ;
86 ; Call the C/C++ code that does the actual work. This returns the
87 ; resume address in xAX, which we put in the "return" stack position.
88 ;
89 call NAME(supR3HardenedEarlyProcessInit)
90 mov [xBP + xCB], xAX
91
92 ;
93 ; Restore volatile registers.
94 ;
95 mov xAX, [xBP - xCB*1]
96 mov xCX, [xBP - xCB*2]
97 mov xDX, [xBP - xCB*3]
98%ifdef RT_ARCH_AMD64
99 mov r8, [xBP - xCB*4]
100 mov r9, [xBP - xCB*5]
101 mov r10, [xBP - xCB*6]
102 mov r11, [xBP - xCB*7]
103%endif
104 ;
105 ; Use the leave instruction to restore xBP and set up xSP to point at
106 ; the resume address. Then use the 'ret' instruction to resume process
107 ; initializaton.
108 ;
109 leave
110 ret
111ENDPROC supR3HardenedEarlyProcessInitThunk
112
113
114;;
115; Hook for KiUserApcDispatcher that validates user APC calls during early process
116; init to prevent calls going to or referring to executable memory we've freed
117; already.
118;
119; We just call C code here, just like supR3HardenedEarlyProcessInitThunk does.
120;
121; @sa supR3HardenedMonitor_KiUserApcDispatcher_C
122;
123BEGINPROC supR3HardenedMonitor_KiUserApcDispatcher
124 ;
125 ; Prologue.
126 ;
127
128 ; Reserve space for the "return" address.
129 push 0
130
131 ; Create a stack frame, saving xBP.
132 push xBP
133 SEH64_PUSH_xBP
134 mov xBP, xSP
135 SEH64_SET_FRAME_xBP 0 ; probably wrong...
136
137 ; Save all volatile registers.
138 push xAX
139 push xCX
140 push xDX
141%ifdef RT_ARCH_AMD64
142 push r8
143 push r9
144 push r10
145 push r11
146%endif
147
148 ; Reserve spill space and align the stack.
149 sub xSP, 20h
150 and xSP, ~0fh
151 SEH64_END_PROLOGUE
152
153 ;
154 ; Call the C/C++ code that does the actual work. This returns the
155 ; resume address in xAX, which we put in the "return" stack position.
156 ;
157 ; On AMD64, a CONTEXT structure is found at our RSP address when we're called.
158 ; On x86, there a 16 byte structure containing the two routines and their
159 ; arguments followed by a CONTEXT structure.
160 ;
161 lea xCX, [xBP + xCB + xCB]
162%ifdef RT_ARCH_X86
163 mov [xSP], xCX
164%endif
165 call NAME(supR3HardenedMonitor_KiUserApcDispatcher_C)
166 mov [xBP + xCB], xAX
167
168 ;
169 ; Restore volatile registers.
170 ;
171 mov xAX, [xBP - xCB*1]
172 mov xCX, [xBP - xCB*2]
173 mov xDX, [xBP - xCB*3]
174%ifdef RT_ARCH_AMD64
175 mov r8, [xBP - xCB*4]
176 mov r9, [xBP - xCB*5]
177 mov r10, [xBP - xCB*6]
178 mov r11, [xBP - xCB*7]
179%endif
180 ;
181 ; Use the leave instruction to restore xBP and set up xSP to point at
182 ; the resume address. Then use the 'ret' instruction to execute the
183 ; original KiUserApcDispatcher code as if we've never been here...
184 ;
185 leave
186 ret
187ENDPROC supR3HardenedMonitor_KiUserApcDispatcher
188
189
190%ifndef VBOX_WITHOUT_HARDENDED_XCPT_LOGGING
191;;
192; Hook for KiUserExceptionDispatcher that logs exceptions.
193;
194; For the AMD64 variant, we're not directly intercepting the function itself, but
195; patching into a Wow64 callout that's done at the very start of the routine. RCX
196; and RDX are set to PEXCEPTION_RECORD and PCONTEXT respectively and there is a
197; return address. Also, we don't need to do any return-via-copied-out-code stuff.
198;
199; For X86 we hook the function and have PEXCEPTION_RECORD and PCONTEXT pointers on
200; the stack, but no return address.
201
202; We just call C code here, just like supR3HardenedEarlyProcessInitThunk and
203; supR3HardenedMonitor_KiUserApcDispatcher does.
204;
205; @sa supR3HardenedMonitor_KiUserExceptionDispatcher_C
206;
207BEGINPROC supR3HardenedMonitor_KiUserExceptionDispatcher
208 ;
209 ; Prologue.
210 ;
211
212 %ifndef RT_ARCH_AMD64
213 ; Reserve space for the "return" address.
214 push 0
215 %endif
216
217 ; Create a stack frame, saving xBP.
218 push xBP
219 SEH64_PUSH_xBP
220 mov xBP, xSP
221 SEH64_SET_FRAME_xBP 0 ; probably wrong...
222
223 ; Save all volatile registers.
224 push xAX
225 push xCX
226 push xDX
227 %ifdef RT_ARCH_AMD64
228 push r8
229 push r9
230 push r10
231 push r11
232 %endif
233
234 ; Reserve spill space and align the stack.
235 sub xSP, 20h
236 and xSP, ~0fh
237 SEH64_END_PROLOGUE
238
239 ;
240 ; Call the C/C++ code that does the actual work. For x86 this returns
241 ; the resume address in xAX, which we put in the "return" stack position.
242 ;
243 ; On both AMD64 and X86 we have two parameters on the stack that we
244 ; passes along to the C code (see function description for details).
245 ;
246 %ifdef RT_ARCH_X86
247 mov xCX, [xBP + xCB*2]
248 mov xDX, [xBP + xCB*3]
249 mov [xSP], xCX
250 mov [xSP+4], xDX
251 %endif
252 call NAME(supR3HardenedMonitor_KiUserExceptionDispatcher_C)
253 %ifdef RT_ARCH_X86
254 mov [xBP + xCB], xAX
255 %endif
256
257 ;
258 ; Restore volatile registers.
259 ;
260 mov xAX, [xBP - xCB*1]
261 mov xCX, [xBP - xCB*2]
262 mov xDX, [xBP - xCB*3]
263 %ifdef RT_ARCH_AMD64
264 mov r8, [xBP - xCB*4]
265 mov r9, [xBP - xCB*5]
266 mov r10, [xBP - xCB*6]
267 mov r11, [xBP - xCB*7]
268 %endif
269 ;
270 ; Use the leave instruction to restore xBP and set up xSP to point at
271 ; the resume address. Then use the 'ret' instruction to execute the
272 ; original KiUserExceptionDispatcher code as if we've never been here...
273 ;
274 leave
275 ret
276ENDPROC supR3HardenedMonitor_KiUserExceptionDispatcher
277%endif ; !VBOX_WITHOUT_HARDENDED_XCPT_LOGGING
278
279;;
280; Composes a standard call name.
281%ifdef RT_ARCH_X86
282 %define SUPHNTIMP_STDCALL_NAME(a,b) _ %+ a %+ @ %+ b
283%else
284 %define SUPHNTIMP_STDCALL_NAME(a,b) NAME(a)
285%endif
286
287;; Concats two litterals.
288%define SUPHNTIMP_CONCAT(a,b) a %+ b
289
290
291;;
292; Import data and code for an API call.
293;
294; @param 1 The plain API name.
295; @param 2 The parameter frame size on x86. Multiple of dword.
296; @param 3 Non-zero expression if system call.
297; @param 4 Non-zero expression if early available call
298;
299%define SUPHNTIMP_SYSCALL 1
300%macro SupHardNtImport 4
301 ;
302 ; The data.
303 ;
304BEGINDATA
305global __imp_ %+ SUPHNTIMP_STDCALL_NAME(%1,%2) ; The import name used via dllimport.
306__imp_ %+ SUPHNTIMP_STDCALL_NAME(%1,%2):
307GLOBALNAME g_pfn %+ %1 ; The name we like to refer to.
308 RTCCPTR_DEF 0
309%if %3
310GLOBALNAME g_uApiNo %+ %1
311 RTCCPTR_DEF 0
312%endif
313
314 ;
315 ; The code: First a call stub.
316 ;
317BEGINCODE
318global SUPHNTIMP_STDCALL_NAME(%1, %2)
319SUPHNTIMP_STDCALL_NAME(%1, %2):
320 jmp RTCCPTR_PRE [NAME(g_pfn %+ %1) xWrtRIP]
321
322%if %3
323 ;
324 ; Make system calls.
325 ;
326 %ifdef RT_ARCH_AMD64
327BEGINPROC %1 %+ _SyscallType1
328 SEH64_END_PROLOGUE
329 mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
330 mov r10, rcx
331 syscall
332 ret
333ENDPROC %1 %+ _SyscallType1
334BEGINPROC %1 %+ _SyscallType2 ; Introduced with build 10525
335 SEH64_END_PROLOGUE
336 mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
337 test byte [07ffe0308h], 1 ; SharedUserData!Something
338 mov r10, rcx
339 jnz .int_alternative
340 syscall
341 ret
342.int_alternative:
343 int 2eh
344 ret
345ENDPROC %1 %+ _SyscallType2
346 %else
347BEGINPROC %1 %+ _SyscallType1
348 mov edx, 07ffe0300h ; SharedUserData!SystemCallStub
349 mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
350 call dword [edx]
351 ret %2
352ENDPROC %1 %+ _SyscallType1
353BEGINPROC %1 %+ _SyscallType2
354 push .return
355 mov edx, esp
356 mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
357 sysenter
358 add esp, 4
359.return:
360 ret %2
361ENDPROC %1 %+ _SyscallType2
362 %endif
363%endif
364
365%if %4 == 0
366global NAME(SUPHNTIMP_CONCAT(%1,_Early))
367NAME(SUPHNTIMP_CONCAT(%1,_Early)):
368 int3
369 %ifdef RT_ARCH_AMD64
370 ret
371 %else
372 ret %2
373 %endif
374%endif
375%endmacro
376
377%define SUPHARNT_COMMENT(a_Comment)
378%define SUPHARNT_IMPORT_SYSCALL(a_Name, a_cbParamsX86) SupHardNtImport a_Name, a_cbParamsX86, SUPHNTIMP_SYSCALL, 1
379%define SUPHARNT_IMPORT_STDCALL(a_Name, a_cbParamsX86) SupHardNtImport a_Name, a_cbParamsX86, 0, 0
380%define SUPHARNT_IMPORT_STDCALL_OPTIONAL(a_Name, a_cbParamsX86) SUPHARNT_IMPORT_STDCALL(a_Name, a_cbParamsX86)
381%define SUPHARNT_IMPORT_STDCALL_EARLY(a_Name, a_cbParamsX86) SupHardNtImport a_Name, a_cbParamsX86, 0, 1
382%define SUPHARNT_IMPORT_STDCALL_EARLY_OPTIONAL(a_Name, a_cbParamsX86) SUPHARNT_IMPORT_STDCALL_EARLY(a_Name, a_cbParamsX86)
383%include "import-template-ntdll.h"
384%include "import-template-kernel32.h"
385
386
387;
388; For simplified LdrLoadDll patching we define a special writable, readable and
389; exectuable section of 4KB where we can put jump back code.
390;
391section .rwxpg bss execute read write align=4096
392GLOBALNAME g_abSupHardReadWriteExecPage
393 resb 4096
394
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette