From 79f99e126af90cd6232b2e9a2dbdf5df4d9aeae7 Mon Sep 17 00:00:00 2001 From: DavidXanatos Date: Wed, 29 Dec 2021 15:32:51 +0100 Subject: [PATCH] 1.0.6 --- CHANGELOG.md | 3 +- Sandboxie/apps/com/RpcSs/SandboxRpcSs.vcxproj | 3 +- Sandboxie/apps/com/WUAU/SandboxWUAU.vcxproj | 3 +- Sandboxie/core/dll/Win32.c | 2 +- Sandboxie/core/dll/obj.c | 2 +- Sandboxie/core/drv/syscall_util.c | 2 +- Sandboxie/core/drv/syscall_win32.c | 92 +++++++++++++------ Sandboxie/core/low/entry.asm | 2 +- 8 files changed, 72 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f9493eb..158bee09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - fixed box initialization issue in Privacy mode [#1469](https://github.com/sandboxie-plus/Sandboxie/issues/1469) - fixed issue with shortcuts creation introduced in a recent build [#1471](https://github.com/sandboxie-plus/Sandboxie/issues/1471) - fixed various issues in Privacy Enhanced boxes and rule specificity -- fixed issue with SeAccessCheckByType +- fixed issue with SeAccessCheckByType and alike +- fixed issues with win32k hooking on 32 bit windows [#1479](https://github.com/sandboxie-plus/Sandboxie/issues/1479) ### Removed - removed obsolete SkyNet rootkit detection from 32 bit build diff --git a/Sandboxie/apps/com/RpcSs/SandboxRpcSs.vcxproj b/Sandboxie/apps/com/RpcSs/SandboxRpcSs.vcxproj index af71dc73..8b8ae4c8 100644 --- a/Sandboxie/apps/com/RpcSs/SandboxRpcSs.vcxproj +++ b/Sandboxie/apps/com/RpcSs/SandboxRpcSs.vcxproj @@ -82,7 +82,8 @@ true - SbieDll.lib;ws2_32.lib;advapi32.lib;kernel32.lib;ntdll.lib;gdi32.lib;user32.lib;secur32.lib;psapi.lib + SbieDll.lib;ws2_32.lib;advapi32.lib;kernel32.lib;libucrt.lib;ntdll.lib;gdi32.lib;user32.lib;secur32.lib;psapi.lib + libucrt.lib diff --git a/Sandboxie/apps/com/WUAU/SandboxWUAU.vcxproj b/Sandboxie/apps/com/WUAU/SandboxWUAU.vcxproj index e6394554..6d9e30e9 100644 --- a/Sandboxie/apps/com/WUAU/SandboxWUAU.vcxproj +++ b/Sandboxie/apps/com/WUAU/SandboxWUAU.vcxproj @@ -86,7 +86,8 @@ true - SbieDll.lib;secur32.lib;ntdll.lib;psapi.lib;AdvApi32.lib;user32.lib;%(AdditionalDependencies) + SbieDll.lib;secur32.lib;libucrt.lib;ntdll.lib;psapi.lib;AdvApi32.lib;user32.lib;%(AdditionalDependencies) + libucrt.lib diff --git a/Sandboxie/core/dll/Win32.c b/Sandboxie/core/dll/Win32.c index 355a8a59..2f1e53a0 100644 --- a/Sandboxie/core/dll/Win32.c +++ b/Sandboxie/core/dll/Win32.c @@ -390,7 +390,7 @@ finish: _FX BOOLEAN Win32_Init(HMODULE hmodule) { // In Windows 10 all Win32k.sys calls are located in win32u.dll - if (Dll_OsBuild < 10041 || (Dll_ProcessFlags & SBIE_FLAG_WIN32K_HOOKABLE) == 0) + if (Dll_OsBuild < 10041 || (Dll_ProcessFlags & SBIE_FLAG_WIN32K_HOOKABLE) == 0 || !SbieApi_QueryConfBool(NULL, L"EnableWin32kHooks", TRUE)) return TRUE; // just return on older builds, or not enabled if ((Dll_ProcessFlags & SBIE_FLAG_APP_COMPARTMENT) != 0 || SbieApi_data->flags.bNoSysHooks) diff --git a/Sandboxie/core/dll/obj.c b/Sandboxie/core/dll/obj.c index d9d429b2..43f1d8aa 100644 --- a/Sandboxie/core/dll/obj.c +++ b/Sandboxie/core/dll/obj.c @@ -430,7 +430,7 @@ _FX NTSTATUS Obj_NtQueryInformationProcess( status = __sys_NtQueryInformationProcess( ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, &outlen); - if (ProcessInformationClass == ProcessImageFileName) + if (ProcessInformationClass == ProcessImageFileName && ProcessInformation != NULL) { // // since file paths are always shorter without the sandbox prefix we can keep this simple diff --git a/Sandboxie/core/drv/syscall_util.c b/Sandboxie/core/drv/syscall_util.c index a1ec6b5c..6fb8a956 100644 --- a/Sandboxie/core/drv/syscall_util.c +++ b/Sandboxie/core/drv/syscall_util.c @@ -110,7 +110,7 @@ _FX BOOLEAN Syscall_TestHookMap(const UCHAR* name, ULONG name_len, LIST* enabled int disabe_match = Syscall_HookMapMatch(wname, name_len, disabled_hooks); int enable_match = Syscall_HookMapMatch(wname, name_len, enabled_hooks); - if (disabe_match >= enable_match) + if (disabe_match != 0 && disabe_match >= enable_match) return FALSE; if (enable_match != 0) return TRUE; diff --git a/Sandboxie/core/drv/syscall_win32.c b/Sandboxie/core/drv/syscall_win32.c index 2dc1f464..399b795b 100644 --- a/Sandboxie/core/drv/syscall_win32.c +++ b/Sandboxie/core/drv/syscall_win32.c @@ -90,36 +90,46 @@ typedef struct _KSERVICE_TABLE_DESCRIPTOR unsigned long *Base; unsigned long *Reserved1; unsigned long Limit; - unsigned int *Number; + unsigned char *Number; } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR ; - -_FX BOOLEAN Syscall_GetWin32kAddr(ULONG *Base_Copy, +#ifdef _WIN64 +_FX BOOLEAN Syscall_GetWin32kAddr(KSERVICE_TABLE_DESCRIPTOR *ShadowTable, ULONG *Base_Copy, ULONG index, void **pKernelAddr, ULONG *pParamCount) { - KSERVICE_TABLE_DESCRIPTOR *ShadowTable = (KSERVICE_TABLE_DESCRIPTOR *)Syscall_GetServiceTable(); - ShadowTable += 1; // ServiceDescriptorTableShadow[0] -> ntoskrnl.exe, ServiceDescriptorTableShadow[1] -> win32k.sys + ULONG MaxSyscallIndexPlusOne = ShadowTable->Limit; + if ((index >= 0x1000) && + ((index & 0xFFF) < MaxSyscallIndexPlusOne)) { - if (ShadowTable) { + long EntryValue = Base_Copy[index & 0xFFF]; - ULONG MaxSyscallIndexPlusOne = ShadowTable->Limit; - if ((index >= 0x1000) && - ((index & 0xFFF) < MaxSyscallIndexPlusOne)) { - - long EntryValue = Base_Copy[index & 0xFFF]; - - *pKernelAddr = (UCHAR *)ShadowTable->Base + (EntryValue >> 4); - *pParamCount = (ULONG)(EntryValue & 0x0F) + 4; - //DbgPrint(" SysCall32 offset: %d\r\n", (ULONG)(EntryValue >> 4)); - return TRUE; - } - - Log_Msg1(MSG_1113, L"ADDRESS"); + *pKernelAddr = (UCHAR *)ShadowTable->Base + (EntryValue >> 4); + *pParamCount = (ULONG)(EntryValue & 0x0F) + 4; + //DbgPrint(" SysCall32 offset: %d\r\n", (ULONG)(EntryValue >> 4)); + return TRUE; } + Log_Msg1(MSG_1113, L"ADDRESS"); return FALSE; } +#else +_FX BOOLEAN Syscall_GetWin32kAddr(KSERVICE_TABLE_DESCRIPTOR *ShadowTable, ULONG *ProcTable, UCHAR *ParmTable, + ULONG index, void **pKernelAddr, ULONG *pParamCount) +{ + ULONG MaxSyscallIndexPlusOne = ShadowTable->Limit; + if ((index >= 0x1000) && + ((index & 0xFFF) < MaxSyscallIndexPlusOne)) { + *pKernelAddr = (void *)ProcTable[index & 0xFFF]; + *pParamCount = ((ULONG)ParmTable[index & 0xFFF]) / 4; + //DbgPrint(" SysCall32 offset: %d\r\n", (ULONG)(EntryValue >> 4)); + return TRUE; + } + + Log_Msg1(MSG_1113, L"ADDRESS"); + return FALSE; +} +#endif //--------------------------------------------------------------------------- // Syscall_Init_List32 @@ -135,7 +145,10 @@ _FX BOOLEAN Syscall_Init_List32(void) SYSCALL_ENTRY *entry; ULONG proc_index, proc_offset, syscall_index, param_count; ULONG name_len, entry_len; - ULONG* table_copy = NULL; + ULONG* base_copy = NULL; +#ifndef _WIN64 + UCHAR* number_copy = NULL; +#endif List_Init(&Syscall_List32); @@ -159,8 +172,8 @@ _FX BOOLEAN Syscall_Init_List32(void) Log_Msg1(MSG_1113, L"SHADOW_TABLE"); goto finish; } - //DbgPrint(" win32k.sys SysCalls: %d %p %p\n", ShadowTable->Limit, ShadowTable->Base, ShadowTable->Number); - ShadowTable += 1; + //DbgPrint(" ntoskrln.exe SysCalls: %d %p %p\n", ShadowTable->Limit, ShadowTable->Base, ShadowTable->Number); + ShadowTable += 1; // ServiceDescriptorTableShadow[0] -> ntoskrnl.exe, ServiceDescriptorTableShadow[1] -> win32k.sys //DbgPrint(" win32k.sys SysCalls: %d %p %p\n", ShadowTable->Limit, ShadowTable->Base, ShadowTable->Number); if (ShadowTable->Limit > 0xFFF) { // not plausible @@ -180,16 +193,28 @@ _FX BOOLEAN Syscall_Init_List32(void) goto finish; } - table_copy = (ULONG*)Mem_AllocEx(Driver_Pool, ShadowTable->Limit * sizeof(long), TRUE); - if (!table_copy) + base_copy = (ULONG*)Mem_AllocEx(Driver_Pool, ShadowTable->Limit * sizeof(long), TRUE); + if (!base_copy) goto finish; +#ifndef _WIN64 + number_copy = (UCHAR*)Mem_AllocEx(Driver_Pool, ShadowTable->Limit * sizeof(char), TRUE); + if (!number_copy) + goto finish; +#endif PEPROCESS ProcessObject; if (NT_SUCCESS(PsLookupProcessByProcessId(csrssId,&ProcessObject))) { KAPC_STATE ApcState; KeStackAttachProcess(ProcessObject, &ApcState); - if (MmIsAddressValid(ShadowTable->Base)) { - memcpy(table_copy, ShadowTable->Base, ShadowTable->Limit * sizeof(long)); + if (MmIsAddressValid(ShadowTable->Base) +#ifndef _WIN64 + && MmIsAddressValid(ShadowTable->Number) +#endif + ) { + memcpy(base_copy, ShadowTable->Base, ShadowTable->Limit * sizeof(long)); +#ifndef _WIN64 + memcpy(number_copy, ShadowTable->Number, ShadowTable->Limit * sizeof(char)); +#endif success = TRUE; } KeUnstackDetachProcess(&ApcState); @@ -289,7 +314,10 @@ _FX BOOLEAN Syscall_Init_List32(void) if (syscall_index != -1) { - Syscall_GetWin32kAddr(table_copy, + Syscall_GetWin32kAddr(ShadowTable, base_copy, +#ifndef _WIN64 + number_copy, +#endif syscall_index, &ntos_addr, ¶m_count); //BOOLEAN test; @@ -297,7 +325,7 @@ _FX BOOLEAN Syscall_Init_List32(void) //test = MmIsAddressValid(ntos_addr); //KeUnstackDetachProcess(&ApcState); //DbgPrint(" Found SysCall32: %s, pcnt %d; idx: %d; addr: %p %s\r\n", name, param_count, syscall_index, ntos_addr, test ? "valid" : "invalid"); - //DbgPrint(" Found SysCall32: %s, pcnt %d; idx: %d\r\n", name, param_count, syscall_index); + //DbgPrint(" Found SysCall32: %s, pcnt %d; idx: %d; addr: %p\r\n", name, param_count, syscall_index, ntos_addr); } } @@ -370,8 +398,12 @@ finish: Syscall_FreeHookMap(&enabled_hooks); Syscall_FreeHookMap(&disabled_hooks); - if (table_copy) - Mem_Free(table_copy, ShadowTable->Limit * sizeof(long)); + if (base_copy) + Mem_Free(base_copy, ShadowTable->Limit * sizeof(long)); +#ifndef _WIN64 + if (number_copy) + Mem_Free(number_copy, ShadowTable->Limit * sizeof(char)); +#endif return success; } diff --git a/Sandboxie/core/low/entry.asm b/Sandboxie/core/low/entry.asm index efaaa868..e3356d18 100644 --- a/Sandboxie/core/low/entry.asm +++ b/Sandboxie/core/low/entry.asm @@ -262,7 +262,7 @@ else ; 32-bit ; parms[0] = API_INVOKE_SYSCALL (from SbieLowData) ; - and eax, 0FFFh ; keep just service index number + and eax, 1FFFh ; keep just service index number mov dword ptr [esp+2*8], eax lea eax, [ebp+4*3] ; eax -> orig arg 1 on stack