This commit is contained in:
DavidXanatos 2021-12-31 22:41:13 +01:00
parent 747c85735e
commit da1c97b794
6 changed files with 152 additions and 249 deletions

View File

@ -4,6 +4,20 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.0.7 / 5.55.7] - 2022-01-??
### Changed
- reworked syscall invocation code in the driver
### Fixed
- Win32k hooking is now compatible with HVCI [#1483](https://github.com/sandboxie-plus/Sandboxie/issues/1483)
## [1.0.6 / 5.55.6] - 2021-12-31 ## [1.0.6 / 5.55.6] - 2021-12-31
### Added ### Added

View File

@ -21,8 +21,8 @@
#ifndef _MY_VERSION_H #ifndef _MY_VERSION_H
#define _MY_VERSION_H #define _MY_VERSION_H
#define MY_VERSION_BINARY 5,55,6 #define MY_VERSION_BINARY 5,55,7
#define MY_VERSION_STRING "5.55.6" #define MY_VERSION_STRING "5.55.7"
#define MY_VERSION_COMPAT "5.55.0" // this refers to the driver ABI compatibility #define MY_VERSION_COMPAT "5.55.0" // this refers to the driver ABI compatibility
// These #defines are used by either Resource Compiler, or by NSIC installer // These #defines are used by either Resource Compiler, or by NSIC installer
@ -32,7 +32,7 @@
#define MY_PRODUCT_NAME_STRING "Sandboxie" #define MY_PRODUCT_NAME_STRING "Sandboxie"
#define MY_COMPANY_NAME_STRING "sandboxie-plus.com" #define MY_COMPANY_NAME_STRING "sandboxie-plus.com"
#define MY_COPYRIGHT_STRING "Copyright © 2020-2021 by David Xanatos (xanasoft.com)" #define MY_COPYRIGHT_STRING "Copyright © 2020-2022 by David Xanatos (xanasoft.com)"
#define MY_COPYRIGHT_STRING_OLD "Copyright © 2004-2020 by Sandboxie Holdings, LLC" #define MY_COPYRIGHT_STRING_OLD "Copyright © 2004-2020 by Sandboxie Holdings, LLC"
#define SANDBOXIE L"Sandboxie" #define SANDBOXIE L"Sandboxie"

View File

@ -108,86 +108,6 @@ static BOOLEAN Syscall_GetKernelAddr(
#endif #endif
//---------------------------------------------------------------------------
typedef NTSTATUS (*P_SystemService00)(void);
typedef NTSTATUS (*P_SystemService01)(
ULONG_PTR arg01);
typedef NTSTATUS (*P_SystemService02)(
ULONG_PTR arg01, ULONG_PTR arg02);
typedef NTSTATUS (*P_SystemService03)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03);
typedef NTSTATUS (*P_SystemService04)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04);
typedef NTSTATUS (*P_SystemService05)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05);
typedef NTSTATUS (*P_SystemService06)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06);
typedef NTSTATUS (*P_SystemService07)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07);
typedef NTSTATUS (*P_SystemService08)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08);
typedef NTSTATUS (*P_SystemService09)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09);
typedef NTSTATUS (*P_SystemService10)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10);
typedef NTSTATUS (*P_SystemService11)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11);
typedef NTSTATUS (*P_SystemService12)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12);
typedef NTSTATUS (*P_SystemService13)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13);
typedef NTSTATUS (*P_SystemService14)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14);
typedef NTSTATUS (*P_SystemService15)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15);
typedef NTSTATUS (*P_SystemService16)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16);
typedef NTSTATUS (*P_SystemService17)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16,
ULONG_PTR arg17);
typedef NTSTATUS (*P_SystemService18)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16,
ULONG_PTR arg17, ULONG_PTR arg18);
typedef NTSTATUS (*P_SystemService19)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05, ULONG_PTR arg06, ULONG_PTR arg07, ULONG_PTR arg08,
ULONG_PTR arg09, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12,
ULONG_PTR arg13, ULONG_PTR arg14, ULONG_PTR arg15, ULONG_PTR arg16,
ULONG_PTR arg17, ULONG_PTR arg18, ULONG_PTR arg19);
// (count & 0x0F) + 4 -> 19 is absolute maximum
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Variables // Variables
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -221,24 +141,7 @@ _FX BOOLEAN Syscall_Init(void)
return FALSE; return FALSE;
#ifdef HOOK_WIN32K #ifdef HOOK_WIN32K
if (Driver_OsBuild >= 10041 && Conf_Get_Boolean(NULL, L"EnableWin32kHooks", 0, TRUE)) {
//
// Win32k Hooking requirers 10 or later as only thre Win32u.dll is available
//
// Note: Win32k Hooking is not compatible with HVCI causing a BSOD
// KERNEL_SECURITY_CHECK_FAILURE (139)
// A kernel component has corrupted a critical data structure.
// Arguments:
// Arg1: 0000000000000000, A stack-based buffer has been overrun.
// Arg2: 0000000000000000, Address of the trap frame for the exception that caused the bugcheck
// Arg3: 0000000000000000, Address of the exception record for the exception that caused the bugcheck
// Arg4: ffffxxxxxxxxxxxx, Reserved
//
// Note: this feature applied to GdiDdDDI* solves HW Acceleration issues with chromium, hence we enable it if possible
//
if (Driver_OsBuild >= 10041 && Conf_Get_Boolean(NULL, L"EnableWin32kHooks", 0, TRUE)
&& Driver_GetRegDword(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceGuard\\Scenarios\\HypervisorEnforcedCodeIntegrity", L"Enabled") == 0) {
if (!Syscall_Init_List32()) if (!Syscall_Init_List32())
return FALSE; return FALSE;
@ -619,147 +522,23 @@ _FX void Syscall_ErrorForAsciiName(const UCHAR *name_a)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
extern unsigned int g_TrapFrameOffset; extern unsigned int g_TrapFrameOffset;
_FX NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args);
_FX NTSTATUS Syscall_Invoke(SYSCALL_ENTRY *entry, ULONG_PTR *stack) _FX NTSTATUS Syscall_Invoke(SYSCALL_ENTRY *entry, ULONG_PTR *stack)
{ {
NTSTATUS status; NTSTATUS status;
//
// Note: when directly calling win32k functions with "Core Isolation" (HVCI) enabled
// the nt!guard_dispatch_icall will cause a bugcheck!
// Hence we use a call proxy Sbie_InvokeSyscall_asm instead of a direct call
//
__try { __try {
//DbgPrint("[syscall] request param count = %d\n", entry->param_count); //DbgPrint("[syscall] request param count = %d\n", entry->param_count);
if (entry->param_count == 0) { status = Sbie_InvokeSyscall_asm(entry->ntos_func, entry->param_count, stack);
P_SystemService00 nt = (P_SystemService00)entry->ntos_func;
status = nt();
} else if (entry->param_count == 1) {
P_SystemService01 nt = (P_SystemService01)entry->ntos_func;
status = nt(stack[0]);
} else if (entry->param_count == 2) {
P_SystemService02 nt = (P_SystemService02)entry->ntos_func;
status = nt(stack[0], stack[1]);
} else if (entry->param_count == 3) {
P_SystemService03 nt = (P_SystemService03)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2]);
} else if (entry->param_count == 4) {
P_SystemService04 nt = (P_SystemService04)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3]);
} else if (entry->param_count == 5) {
P_SystemService05 nt = (P_SystemService05)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4]);
} else if (entry->param_count == 6) {
P_SystemService06 nt = (P_SystemService06)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5]);
} else if (entry->param_count == 7) {
P_SystemService07 nt = (P_SystemService07)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6]);
} else if (entry->param_count == 8) {
P_SystemService08 nt = (P_SystemService08)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7]);
} else if (entry->param_count == 9) {
P_SystemService09 nt = (P_SystemService09)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8]);
} else if (entry->param_count == 10) {
P_SystemService10 nt = (P_SystemService10)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9]);
} else if (entry->param_count == 11) {
P_SystemService11 nt = (P_SystemService11)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10]);
} else if (entry->param_count == 12) {
P_SystemService12 nt = (P_SystemService12)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11]);
} else if (entry->param_count == 13) {
P_SystemService13 nt = (P_SystemService13)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12]);
} else if (entry->param_count == 14) {
P_SystemService14 nt = (P_SystemService14)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13]);
} else if (entry->param_count == 15) {
P_SystemService15 nt = (P_SystemService15)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14]);
} else if (entry->param_count == 16) {
P_SystemService16 nt = (P_SystemService16)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15]);
} else if (entry->param_count == 17) {
P_SystemService17 nt = (P_SystemService17)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15], stack[16]);
} else if (entry->param_count == 18) {
P_SystemService18 nt = (P_SystemService18)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15], stack[16], stack[17]);
} else if (entry->param_count == 19) {
P_SystemService19 nt = (P_SystemService19)entry->ntos_func;
status = nt(stack[0], stack[1], stack[2], stack[3], stack[4],
stack[5], stack[6], stack[7], stack[8], stack[9],
stack[10], stack[11], stack[12], stack[13],
stack[14], stack[15], stack[16], stack[17],
stack[18]);
} else {
status = STATUS_INVALID_SYSTEM_SERVICE;
}
} __except (EXCEPTION_EXECUTE_HANDLER) { } __except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode(); status = GetExceptionCode();

View File

@ -2026,7 +2026,7 @@ _FX NTSTATUS Sbie_SepFilterToken_KernelMode(
return statusRet; return statusRet;
} }
_FX NTSTATUS Sbie_SepFilterTokenHandler_asm(void* TokenObject, ULONG_PTR SidCount, ULONG_PTR SidPtr, ULONG_PTR LengthIncrease, void** NewToken); _FX NTSTATUS Sbie_SepFilterTokenHandler_asm(void* TokenObject, ULONG_PTR SidCount, ULONG_PTR SidPtr, ULONG_PTR LengthIncrease, void** NewToken);
_FX NTSTATUS Sbie_SepFilterTokenHandler(void *TokenObject, _FX NTSTATUS Sbie_SepFilterTokenHandler(void *TokenObject,
ULONG_PTR SidCount, ULONG_PTR SidCount,
@ -2038,9 +2038,9 @@ _FX NTSTATUS Sbie_SepFilterTokenHandler(void *TokenObject,
#ifdef _WIN64 #ifdef _WIN64
// //
// When built with VS2019 on systems with enabled "Core Isolation" we get a BSOD pointing to _chkstk, // When built with VS2019 on systems with enabled "Core Isolation" (HVCI) we get a BSOD.
// this is a function added by the compiler under certain conditions. // This is caused by "Control Flow Guard", we could eider disable it for this file or,
// We work around this issue by providing a hand crafter wrapper function that performs the call. // work around this issue by providing a hand crafted wrapper function that performs the call.
// //
status = Sbie_SepFilterTokenHandler_asm(TokenObject, SidCount, SidPtr, LengthIncrease, NewToken); status = Sbie_SepFilterTokenHandler_asm(TokenObject, SidCount, SidPtr, LengthIncrease, NewToken);

View File

@ -229,6 +229,7 @@ endif
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
ifdef _WIN64 ifdef _WIN64
EXTERN Token_SepFilterToken : QWORD EXTERN Token_SepFilterToken : QWORD
Sbie_SepFilterTokenHandler_asm PROC Sbie_SepFilterTokenHandler_asm PROC
@ -237,32 +238,141 @@ Sbie_SepFilterTokenHandler_asm PROC
mov qword ptr [rsp+18h],r8 mov qword ptr [rsp+18h],r8
mov qword ptr [rsp+10h],rdx mov qword ptr [rsp+10h],rdx
mov qword ptr [rsp+8],rcx mov qword ptr [rsp+8],rcx
sub rsp,78h sub rsp,78h
mov dword ptr [rsp+60h],0 mov dword ptr [rsp+60h],0
mov rax,qword ptr [rsp+00000000000000A0h] mov rax,qword ptr [rsp+00000000000000A0h] ; NewToken
mov qword ptr [rsp+50h],rax mov qword ptr [rsp+50h],rax
mov rax,qword ptr [rsp+0000000000000098h] mov rax,qword ptr [rsp+0000000000000098h] ; LengthIncrease
mov qword ptr [rsp+48h],rax mov qword ptr [rsp+48h],rax
mov rax,qword ptr [rsp+0000000000000090h] mov rax,qword ptr [rsp+0000000000000090h] ; SidPtr
mov qword ptr [rsp+40h],rax mov qword ptr [rsp+40h],rax
mov rax,qword ptr [rsp+0000000000000088h] mov rax,qword ptr [rsp+0000000000000088h] ; SidCount
mov qword ptr [rsp+38h],rax mov qword ptr [rsp+38h],rax
mov qword ptr [rsp+30h],0 mov qword ptr [rsp+30h],0
mov qword ptr [rsp+28h],0 mov qword ptr [rsp+28h],0
mov qword ptr [rsp+20h],0 mov qword ptr [rsp+20h],0
xor r9d,r9d mov r9d,0
xor r8d,r8d mov r8d,0
xor edx,edx mov edx,0
mov rcx,qword ptr [rsp+0000000000000080h] mov rcx,qword ptr [rsp+0000000000000080h] ; TokenObject
call Token_SepFilterToken call Token_SepFilterToken
mov dword ptr [rsp+60h],eax
mov eax,dword ptr [rsp+60h]
add rsp,78h add rsp,78h
ret ret
Sbie_SepFilterTokenHandler_asm ENDP Sbie_SepFilterTokenHandler_asm ENDP
endif endif
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
ifdef _WIN64
Sbie_InvokeSyscall_asm PROC
mov qword ptr [rsp+20h], r9
mov qword ptr [rsp+18h], r8
mov qword ptr [rsp+10h], rdx
mov qword ptr [rsp+8], rcx
; note: (count & 0x0F) + 4 = 19 arguments are the absolute maximum
; quick sanity check
cmp rdx, 13h ; if count > 19
jle arg_count_ok
mov rax, 0C000001Ch ; return STATUS_INVALID_SYSTEM_SERVICE
ret
arg_count_ok:
push rsi
push rdi
; prepare enough stack for up to 19 arguments
sub rsp, 98h
; save our 3 relevant arguments to spare registers
mov r11, r8 ; args
mov r10, rdx ; count
mov rax, rcx ; func
; check if we have higher arguments and if not skip
cmp r10, 4
jle copy_reg_args
; copy arguments 5-19
mov rsi, r11 ; source
add rsi, 20h
mov rdi, rsp ; destination
add rdi, 20h
mov rcx, r10 ; arg count
sub rcx, 4 ; skip the register passed args
rep movsq
copy_reg_args:
; copy arguments 1-4
mov r9, qword ptr [r11+18h]
mov r8, qword ptr [r11+10h]
mov rdx, qword ptr [r11+08h]
mov rcx, qword ptr [r11+00h]
; call the function
call rax
; clear stack
add rsp, 98h
pop rdi
pop rsi
ret
Sbie_InvokeSyscall_asm ENDP
else
_Sbie_InvokeSyscall_asm@12 PROC
; NTSTATUS Sbie_InvokeSyscall_asm(void* func, int count, void* args);
; quick sanity check
cmp dword ptr [esp+04h+4h], 13h ; @count
jle args_ok
mov eax, 0C000001Ch ; return STATUS_INVALID_SYSTEM_SERVICE
ret
args_ok:
; prepare enough stack for up to 19 arguments
push ebp
push esi
push edi
mov ebp, esp
sub esp, 4Ch
; copy arguments 0-19
mov esi, dword ptr [ebp+10h+8h] ; source @args
mov edi, esp ; destination
mov ecx, dword ptr [ebp+10h+4h] ; arg count @count
rep movsd
; call the function
mov eax, dword ptr [ebp+10h+0h] ; @func
call eax
; clear stack
function_end:
mov esp,ebp
pop edi
pop esi
pop ebp
ret
_Sbie_InvokeSyscall_asm@12 ENDP
PUBLIC _Sbie_InvokeSyscall_asm@12
endif
;----------------------------------------------------------------------------
end end

View File

@ -2,7 +2,7 @@
#define VERSION_MJR 1 #define VERSION_MJR 1
#define VERSION_MIN 0 #define VERSION_MIN 0
#define VERSION_REV 6 #define VERSION_REV 7
#define VERSION_UPD 0 #define VERSION_UPD 0
#ifndef STR #ifndef STR