diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4777ee98..b6c764e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- mechanism to hook Win32 system calls now also works for 32 bit applications running under WoW64
-
+- cleaned up low level hooking code a bit
diff --git a/Sandboxie/core/dll/SboxDll.vcxproj b/Sandboxie/core/dll/SboxDll.vcxproj
index 5fb49941..a42e660e 100644
--- a/Sandboxie/core/dll/SboxDll.vcxproj
+++ b/Sandboxie/core/dll/SboxDll.vcxproj
@@ -406,6 +406,7 @@
+
diff --git a/Sandboxie/core/dll/SboxDll.vcxproj.filters b/Sandboxie/core/dll/SboxDll.vcxproj.filters
index 3684b96f..1dd59a1f 100644
--- a/Sandboxie/core/dll/SboxDll.vcxproj.filters
+++ b/Sandboxie/core/dll/SboxDll.vcxproj.filters
@@ -295,6 +295,9 @@
common\wow64ext
+
+ common
+
diff --git a/Sandboxie/core/dll/Win32.c b/Sandboxie/core/dll/Win32.c
index 3b5c2d9f..69fc6072 100644
--- a/Sandboxie/core/dll/Win32.c
+++ b/Sandboxie/core/dll/Win32.c
@@ -25,16 +25,18 @@
#include "common\pattern.h"
-#define HOOK_WIN32K
-
-#ifdef HOOK_WIN32K
-
#include "core/drv/api_defs.h"
#include "core/low/lowdata.h"
SBIELOW_DATA* SbieApi_data = NULL;
#define SBIELOW_CALL(x) ((P_##x)&data->x##_code)
+
+//---------------------------------------------------------------------------
+// SbieDll_HookWin32SysCalls
+//---------------------------------------------------------------------------
+
+
_FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
{
UCHAR *SystemServiceAsm, *ZwXxxPtr;
@@ -102,7 +104,6 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
SyscallNum = SyscallPtr[0];
#ifdef _WIN64
- SyscallNum &= 0xFFFF; // clear the not needed param count
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
ZwXxxPtr[1] = 0xC7;
@@ -112,7 +113,7 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
if (data->flags.is_win10) {
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
- ZwXxxPtr[8] = 0xE9; // jmp SystemServiceAsm
+ ZwXxxPtr[8] = 0xE9;
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (ZwXxxPtr + 13));
}
else {
@@ -129,7 +130,7 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
#else ! _WIN64
- ZwXxxPtr[0] = 0xB8; // mov eax, SyscallNumber
+ ZwXxxPtr[0] = 0xB8; // mov eax, SyscallNumber, with param count in the highest byte
*(ULONG *)&ZwXxxPtr[1] = SyscallNum;
ZwXxxPtr[5] = 0xE9; // jmp SystemServiceAsm
*(ULONG *)&ZwXxxPtr[6] =
@@ -148,72 +149,12 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
return TRUE;
}
-#ifndef _WIN64
-BOOLEAN SbieDll_HookWoW64SysCalls();
-
-#endif
-
-#endif
-
-_FX BOOLEAN Win32_Init(HMODULE hmodule)
-{
-#ifdef HOOK_WIN32K
- // In Windows 10 all Win32k.sys calls are located in win32u.dll
- if (Dll_OsBuild < 10041 || !SbieApi_QueryConfBool(NULL, L"EnableWin32kHooks", FALSE))
- return TRUE; // just return on older builds
-
- // NoSysCallHooks BEGIN
- if ((Dll_ProcessFlags & SBIE_FLAG_APP_COMPARTMENT) != 0 || SbieApi_QueryConfBool(NULL, L"NoSysCallHooks", FALSE))
- return TRUE;
- // NoSysCallHooks END
-
- // disable Electron Workaround when we are ready to hook the required win32k syscalls
- extern BOOL Dll_ElectronWorkaround;
- Dll_ElectronWorkaround = FALSE;
-
- //
- // chrome needs for a working GPU acceleration the GdiDdDDI* win32k syscalls to have the right user token
- //
-
- WCHAR* cmdline = GetCommandLine();
-
- if ((wcsstr(cmdline, L"--type=gpu-process") != NULL && wcsstr(cmdline, L"--gpu-preferences=") != NULL)
- || SbieDll_GetSettingsForName_bool(NULL, Dll_ImageName, L"AlwaysUseWin32kHooks", FALSE)) {
+//---------------------------------------------------------------------------
+// Win32_WoW64_GetSysCallNumber
+//---------------------------------------------------------------------------
#ifndef _WIN64
- if (Dll_IsWow64)
- SbieDll_HookWoW64SysCalls();
- else
-#endif
- SbieDll_HookWin32SysCalls(hmodule);
- }
-
-#endif
-
- return TRUE;
-}
-
-#ifdef HOOK_WIN32K
-
-#ifndef _WIN64
-
-//#include "../../common/wow64ext/wow64ext.h"
-DWORD64 __cdecl X64Call(DWORD64 func, int argC, ...);
-DWORD64 __cdecl GetModuleHandle64(const wchar_t* lpModuleName);
-DWORD64 __cdecl getNTDLL64();
-DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, const char* funcName);
-SIZE_T __cdecl VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength);
-DWORD64 __cdecl VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
-BOOL __cdecl VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType);
-BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect);
-BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
-BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
-//BOOL __cdecl GetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext);
-//BOOL __cdecl SetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext);
-VOID __cdecl SetLastErrorFromX64Call(DWORD64 status);
-
-
ULONG Win32_WoW64_GetSysCallNumber(DWORD64 pos, UCHAR* dll_data)
{
// 4C 8B D1 - r10,rcx
@@ -247,13 +188,52 @@ ULONG Win32_WoW64_GetSysCallNumber(DWORD64 pos, UCHAR* dll_data)
if (!(dll_data[pos + 23] == 0xc3))
return 0;
- // 0F 1F 84 00 00 00 00 00
//
return syscall_index;
}
-_FX BOOLEAN SbieDll_HookWoW64SysCalls()
+
+//---------------------------------------------------------------------------
+// SbieDll_HasSysCallHook
+//---------------------------------------------------------------------------
+
+
+_FX BOOLEAN SbieDll_HasSysCallHook(UCHAR* syscall_data, ULONG syscall_index)
+{
+ ULONG *SyscallPtr;
+ ULONG SyscallNum;
+
+ SyscallPtr = (ULONG *)(syscall_data + sizeof(ULONG)); // size of buffer
+
+ while (SyscallPtr[0] || SyscallPtr[1]) {
+
+ SyscallNum = SyscallPtr[0];
+
+ SyscallNum &= 0xFFFF; // clear the not needed param count
+
+ if (SyscallNum == syscall_index)
+ return TRUE;
+
+ SyscallPtr += 2;
+ }
+
+ return FALSE;
+}
+
+
+//---------------------------------------------------------------------------
+// SbieDll_HookWin32WoW64
+//---------------------------------------------------------------------------
+
+//#include "../../common/wow64ext/wow64ext.h"
+DWORD64 __cdecl X64Call(DWORD64 func, int argC, ...);
+DWORD64 __cdecl GetModuleHandle64(const wchar_t* lpModuleName);
+BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect);
+BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
+BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
+
+_FX BOOLEAN SbieDll_HookWin32WoW64()
{
BOOLEAN ok = FALSE;
UCHAR* dll_data = NULL;
@@ -261,20 +241,28 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
DWORD64 BaseAddress = GetModuleHandle64(L"wow64win.dll");
SIZE_T SizeOfImage = 0x00100000; // 1 MB should be more than enough
- if (!BaseAddress)
+ if (!BaseAddress) {
+ SbieApi_Log(2303, L"win32k, wow64win.dll base not found");
return FALSE;
+ }
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
- if (hProcess == INVALID_HANDLE_VALUE)
+ if (hProcess == INVALID_HANDLE_VALUE) {
+ SbieApi_Log(2303, L"win32k, can't open process");
return FALSE;
+ }
dll_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, (SIZE_T)SizeOfImage);
- if (!dll_data)
+ if (!dll_data) {
+ SbieApi_Log(2303, L"win32k, alloc failed (1)");
goto finish;
+ }
SIZE_T SizeRead;
- if (!ReadProcessMemory64(hProcess, (PVOID64)BaseAddress, dll_data, SizeOfImage, &SizeRead))
+ if (!ReadProcessMemory64(hProcess, (PVOID64)BaseAddress, dll_data, SizeOfImage, &SizeRead)) {
+ SbieApi_Log(2303, L"win32k, wow64win.dll read failed");
goto finish;
+ }
DWORD64 FuncTable = 0;
@@ -284,13 +272,14 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
break;
}
}
-
- if (FuncTable == 0)
+
+ if (FuncTable == 0) {
+ SbieApi_Log(2303, L"win32k, wow64win.dll sys call table not found");
goto finish;
+ }
DWORD64 SystemServiceAsm;
UCHAR ZwXxxPtr[16];
- ULONG *SyscallPtr;
ULONG SyscallNum;
DWORD64 RegionBase;
SIZE_T RegionSize;
@@ -300,79 +289,73 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
SystemServiceAsm = data->pSystemService;
syscall_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, 16384); // enough room for over 2000 syscalls
- if (!syscall_data)
- goto finish;
+ if (!syscall_data) {
+ SbieApi_Log(2303, L"win32k, alloc failed (2)");
+ goto finish;
+ }
if (!NT_SUCCESS(SbieApi_Call(API_QUERY_SYSCALLS, 2, (ULONG_PTR)syscall_data, 1))) {
- HeapFree(GetProcessHeap(), 0, syscall_data);
+ SbieApi_Log(2303, L"win32k, syscall query failed");
goto finish;
}
for (DWORD64 pos = FuncTable; pos < SizeRead - 0x20; )
{
- ULONG syscall_index = Win32_WoW64_GetSysCallNumber(pos, dll_data);
- if (syscall_index)
+ SyscallNum = Win32_WoW64_GetSysCallNumber(pos, dll_data);
+ if (SyscallNum)
{
- SyscallPtr = (ULONG *)(syscall_data + sizeof(ULONG)); // size of buffer
+ if(SbieDll_HasSysCallHook(syscall_data, SyscallNum))
+ {
+ RegionBase = BaseAddress + pos;
+ RegionSize = 14;
+
+ //
+ // prepare call to call our SystemServiceAsm
+ //
- while (SyscallPtr[0] || SyscallPtr[1]) {
-
- SyscallNum = SyscallPtr[0];
-
- SyscallNum &= 0xFFFF; // clear the not needed param count
-
- if (SyscallNum == syscall_index){
-
- RegionBase = BaseAddress + pos;
- // _WIN64
- RegionSize = 14;
- // ! _WIN64
+ ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
+ ZwXxxPtr[1] = 0xC7;
+ ZwXxxPtr[2] = 0xC2;
+ *(ULONG *)&ZwXxxPtr[3] = SyscallNum;
+ if (!data->flags.long_diff) {
- if (!ReadProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead))
- goto finish;
-
- //
- // overwrite the ZwXxx export to call our SystemServiceAsm,
- // and then restore the original page protection
- //
-
- // _WIN64
- ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
- ZwXxxPtr[1] = 0xC7;
- ZwXxxPtr[2] = 0xC2;
- *(ULONG *)&ZwXxxPtr[3] = SyscallNum;
- if (!data->flags.long_diff) {
-
- if (data->flags.is_win10) {
- ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
- ZwXxxPtr[8] = 0xE9; // jmp SystemServiceAsm
- *(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 13));
- }
- else {
- ZwXxxPtr[7] = 0xe9; // jmp SystemServiceAsm
- *(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 12));
- }
+ if (data->flags.is_win10) {
+ ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
+ ZwXxxPtr[8] = 0xE9;
+ *(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 13));
}
else {
-
- ZwXxxPtr[7] = 0xB8; // mov eax, SystemServiceAsm
- *(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
- *(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
+ ZwXxxPtr[7] = 0xe9; // jmp SystemServiceAsm
+ *(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 12));
}
- // ! _WIN64
+ }
+ else {
-
- if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &OldProtect))
- goto finish;
-
- if (!WriteProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead))
- goto finish;
-
- if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, OldProtect, &OldProtect))
- goto finish;
+ ZwXxxPtr[7] = 0xB8; // mov eax, SystemServiceAsm
+ *(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
+ *(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
}
- SyscallPtr += 2;
+
+ //
+ // overwrite the ZwXxx export to call our SystemServiceAsm,
+ // and then restore the original page protection
+ //
+
+ if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &OldProtect)) {
+ SbieApi_Log(2303, L"win32k %d (1)", SyscallNum);
+ goto finish;
+ }
+
+ if (!WriteProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead)) {
+ SbieApi_Log(2303, L"win32k %d (2)", SyscallNum);
+ goto finish;
+ }
+
+ if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, OldProtect, &OldProtect)) {
+ SbieApi_Log(2303, L"win32k %d (3)", SyscallNum);
+ goto finish;
+ }
}
pos += 0x20;
@@ -385,7 +368,6 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
pos++;
}
-
finish:
if(syscall_data)
@@ -398,7 +380,44 @@ finish:
return ok;
}
-
#endif
-#endif
\ No newline at end of file
+//---------------------------------------------------------------------------
+// Win32_Init
+//---------------------------------------------------------------------------
+
+
+_FX BOOLEAN Win32_Init(HMODULE hmodule)
+{
+ // In Windows 10 all Win32k.sys calls are located in win32u.dll
+ if (Dll_OsBuild < 10041 || !SbieApi_QueryConfBool(NULL, L"EnableWin32kHooks", FALSE))
+ return TRUE; // just return on older builds
+
+ // NoSysCallHooks BEGIN
+ if ((Dll_ProcessFlags & SBIE_FLAG_APP_COMPARTMENT) != 0 || SbieApi_QueryConfBool(NULL, L"NoSysCallHooks", FALSE))
+ return TRUE;
+ // NoSysCallHooks END
+
+ // disable Electron Workaround when we are ready to hook the required win32k syscalls
+ extern BOOL Dll_ElectronWorkaround;
+ Dll_ElectronWorkaround = FALSE;
+
+ //
+ // chrome needs for a working GPU acceleration the GdiDdDDI* win32k syscalls to have the right user token
+ //
+
+ WCHAR* cmdline = GetCommandLine();
+
+ if ((wcsstr(cmdline, L"--type=gpu-process") != NULL && wcsstr(cmdline, L"--gpu-preferences=") != NULL)
+ || SbieDll_GetSettingsForName_bool(NULL, Dll_ImageName, L"AlwaysUseWin32kHooks", FALSE)) {
+
+#ifndef _WIN64
+ if (Dll_IsWow64)
+ SbieDll_HookWin32WoW64(); // WoW64 hooks
+ else
+#endif
+ SbieDll_HookWin32SysCalls(hmodule); // Native x86/x64 hooks
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/Sandboxie/core/dll/dllhook.c b/Sandboxie/core/dll/dllhook.c
index 141504c3..2d0d1ca4 100644
--- a/Sandboxie/core/dll/dllhook.c
+++ b/Sandboxie/core/dll/dllhook.c
@@ -130,7 +130,7 @@ _FX void *SbieDll_Hook(
// (this helps to co-exist with Cisco Security Agent)
//
- if (*(UCHAR *)SourceFunc == 0xEB) {
+ if (*(UCHAR *)SourceFunc == 0xEB) { // jmp xx;
signed char offset = *((signed char *)SourceFunc + 1);
SourceFunc = (UCHAR *)SourceFunc + offset + 2;
}
@@ -142,7 +142,7 @@ _FX void *SbieDll_Hook(
// otherwise (for 32-bit code) just replace the jump target
//
- while (*(UCHAR *)SourceFunc == 0xE9) {
+ while (*(UCHAR *)SourceFunc == 0xE9) { // jmp xx xx xx xx;
diff = *(LONG *)((ULONG_PTR)SourceFunc + 1);
target = (ULONG_PTR)SourceFunc + diff + 5;
@@ -192,15 +192,15 @@ skip_e9_rewrite: ;
// can process it
//
- if (*(USHORT *)SourceFunc == 0xE990) {
+ if (*(USHORT *)SourceFunc == 0xE990) { // nop; jmp xx xx xx xx;
diff = *(LONG *)((ULONG_PTR)SourceFunc + 2);
target = (ULONG_PTR)SourceFunc + diff + 6;
- if (*(USHORT *)target == 0x25FF)
+ if (*(USHORT *)target == 0x25FF) // jmp QWORD PTR [rip+xx xx xx xx];
SourceFunc = (void *)target;
}
//
- // DX: this simplification fails for delay loaded libraries, see coments about SetSecurityInfo,
+ // DX: this simplification fails for delay loaded libraries, see comments about SetSecurityInfo,
// resulting in an endless loop, so just dont do that
//
@@ -211,13 +211,13 @@ skip_e9_rewrite: ;
// 12 bytes.
//
- if (*(UCHAR *)SourceFunc == 0x48 &&
- *(USHORT *)((UCHAR *)SourceFunc + 1) == 0x25FF) {
- // 4825FF is same as 25FF
+ if (*(UCHAR *)SourceFunc == 0x48 && // rex.W
+ *(USHORT *)((UCHAR *)SourceFunc + 1) == 0x25FF) { // jmp QWORD PTR [rip+xx xx xx xx];
+ // 48 FF 25 is same as FF 25
SourceFunc = (UCHAR *)SourceFunc + 1;
}
- if (*(USHORT *)SourceFunc == 0x25FF) {
+ if (*(USHORT *)SourceFunc == 0x25FF) { // jmp QWORD PTR [rip+xx xx xx xx];
void *orig_addr;
/*
@@ -254,7 +254,7 @@ skip_e9_rewrite: ;
#ifdef _WIN64
- if (*(USHORT *)SourceFunc == 0x15FF) {
+ if (*(USHORT *)SourceFunc == 0x15FF) { // call QWORD PTR [rip+xx xx xx xx];
//
// the call instruction pushes a qword into the stack, we need
@@ -312,8 +312,8 @@ skip_e9_rewrite: ;
return NULL;
}
- ULONG ByteCount = *(ULONG*)(tramp + 80);
- ULONG UsedCount = 0;
+ //ULONG ByteCount = *(ULONG*)(tramp + 80);
+ //ULONG UsedCount = 0;
//
// create the detour
@@ -351,22 +351,20 @@ skip_e9_rewrite: ;
OutputDebugStringA(buffer);
*/
if (Dll_Windows >= 10) {
- func[0] = 0x48; // 32bit relative JMP DetourFunc
- func[1] = 0xE9; // 32bit relative JMP DetourFunc
+ func[0] = 0x48; // 32bit relative rex.W JMP DetourFunc
+ func[1] = 0xE9;
*(ULONG *)(&func[2]) = (ULONG)diff;
- UsedCount = 1 + 1 + 4;
+ //UsedCount = 1 + 1 + 4;
}
else {
func[0] = 0xE9; // 32bit relative JMP DetourFunc
*(ULONG *)(&func[1]) = (ULONG)diff;
- UsedCount = 1 + 4;
+ //UsedCount = 1 + 4;
}
}
else {
-
-
BOOLEAN hookset = FALSE;
BOOLEAN defaultRange = FALSE;
int i;
@@ -377,12 +375,12 @@ skip_e9_rewrite: ;
//default step size
for (i = 0; i < NUM_VTABLES && !hookset; i++, ptrVTable++) {
- if (!ptrVTable->offset) {
+ if (!ptrVTable->offset) { // if the vtable is not yet initialized initialize it
ULONG_PTR tempAddr;
ULONG_PTR step = 0x20000;// + VTABLE_SIZE;
ULONG_PTR max_attempts = 0x4000000 / step;
- // optimization for windows 7 and low memory DLL's
+ // optimization for windows 7 and low memory DLL's
if ((ULONG_PTR)func < 0x80000000 && ((ULONG_PTR)func > 0x4000000)) {
step = 0x200000;
}
@@ -414,7 +412,7 @@ skip_e9_rewrite: ;
ptrVTable->index = 0;
ptrVTable->maxEntries = VTABLE_SIZE / sizeof(void *);
}
- if (ptrVTable->offset) {
+ if (ptrVTable->offset) { // check if we have an nitialized vtable
target = (ULONG_PTR)&func[6];
diff = (ULONG_PTR) &((ULONG_PTR *)ptrVTable->offset)[ptrVTable->index];
diff = diff - target;
@@ -424,14 +422,14 @@ skip_e9_rewrite: ;
// is DetourFunc in 32bit jump range
if (delta < 0x80000000 && ptrVTable->index <= ptrVTable->maxEntries) {
((ULONG_PTR *)ptrVTable->offset)[ptrVTable->index] = (ULONG_PTR)DetourFunc;
- *(USHORT *)&func[0] = 0x25ff;
+ *(USHORT *)&func[0] = 0x25ff; // jmp QWORD PTR [rip+diff];
*(ULONG *)&func[2] = (ULONG)diff;
- UsedCount = 2 + 4;
+ //UsedCount = 2 + 4;
ptrVTable->index++;
hookset = TRUE;
}
}
- else {
+ else { // fail and disable vtable if it could not be initialized
bVTableEable = FALSE;
SbieApi_Log(2303, _fmt1, SourceFuncName, 888);
LeaveCriticalSection(&VT_CriticalSection);
@@ -529,9 +527,10 @@ ULONGLONG * SbieDll_findChromeTarget(unsigned char* addr)
_FX void *SbieDll_Hook_CheckChromeHook(void *SourceFunc)
{
-#ifndef _WIN64
-
+ if (!SourceFunc)
+ return NULL;
UCHAR *func = (UCHAR *)SourceFunc;
+#ifndef _WIN64
if (func[0] == 0xB8 && // mov eax,?
func[5] == 0xBA && // mov edx,?
*(USHORT *)&func[10] == 0xE2FF) // jmp edx
@@ -551,10 +550,7 @@ _FX void *SbieDll_Hook_CheckChromeHook(void *SourceFunc)
}
}
#else if
- UCHAR *func = (UCHAR *)SourceFunc;
ULONGLONG *chrome64Target = NULL;
- if (!SourceFunc)
- return NULL;
if (func[0] == 0x50 && //push rax
func[1] == 0x48 && //mov rax,?
@@ -576,7 +572,8 @@ _FX void *SbieDll_Hook_CheckChromeHook(void *SourceFunc)
}
/*sboxie 64bit jtable hook signature */
/* // use this to hook jtable location (useful for debugging)
- else if(func[0] == 0x51 && func[1] == 0x48 && func[2] == 0xb8 ) {
+ //else if(func[0] == 0x51 && func[1] == 0x48 && func[2] == 0xb8 ) {
+ else if(func[0] == 0x90 && func[1] == 0x48 && func[2] == 0xb8 ) {
long long addr;
addr = (ULONG_PTR) *(ULONGLONG **)&func[3] ;
SourceFunc = (void *) addr;
diff --git a/Sandboxie/core/dll/lowlevel_inject.c b/Sandboxie/core/dll/lowlevel_inject.c
index 7f680f4e..44fa97e6 100644
--- a/Sandboxie/core/dll/lowlevel_inject.c
+++ b/Sandboxie/core/dll/lowlevel_inject.c
@@ -55,7 +55,7 @@ typedef struct _MY_TARGETS {
SBIEDLL_EXPORT HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess);
SBIEDLL_EXPORT void *SbieDll_InjectLow_CopyCode(
- HANDLE hProcess, BOOLEAN iswow64, UCHAR *code, ULONG code_len);
+ HANDLE hProcess, SIZE_T lowLevel_size, UCHAR *code, ULONG code_len);
SBIEDLL_EXPORT BOOLEAN SbieDll_InjectLow_BuildTramp(
BOOLEAN long_diff, UCHAR *code, ULONG_PTR addr);
SBIEDLL_EXPORT void *SbieDll_InjectLow_CopySyscalls(HANDLE hProcess);
@@ -519,7 +519,16 @@ _FX ULONG SbieDll_InjectLow(HANDLE hProcess, ULONG init_flags, BOOLEAN dup_drv_h
lowdata.flags.is_win10 = 1;
}
- void *remote_addr = SbieDll_InjectLow_CopyCode(hProcess, lowdata.flags.is_wow64 == 1, lowdata.LdrInitializeThunk_tramp, sizeof(lowdata.LdrInitializeThunk_tramp));
+ SIZE_T lowLevel_size;
+#ifdef _WIN64
+ BOOLEAN use_jump_Table = FALSE;
+ if(use_jump_Table)
+ lowLevel_size = m_sbielow_len + sizeof(SBIELOW_J_TABLE) + 0x400;
+ else
+#endif
+ lowLevel_size = m_sbielow_len;
+
+ void *remote_addr = SbieDll_InjectLow_CopyCode(hProcess, lowLevel_size, lowdata.LdrInitializeThunk_tramp, sizeof(lowdata.LdrInitializeThunk_tramp));
if (!remote_addr) {
errlvl = 0x33;
goto finish;
@@ -570,7 +579,8 @@ _FX ULONG SbieDll_InjectLow(HANDLE hProcess, ULONG init_flags, BOOLEAN dup_drv_h
//
#ifdef _WIN64
- lowdata.Sbie64bitJumpTable = (SBIELOW_J_TABLE *)((ULONG_PTR)remote_addr + m_sbielow_len + 0x400); //(0x400 - (m_sbielow_len & 0x3ff))+ m_sbielow_len;
+ if(use_jump_Table)
+ lowdata.Sbie64bitJumpTable = (SBIELOW_J_TABLE *)((ULONG_PTR)remote_addr + m_sbielow_len + 0x400); //(0x400 - (m_sbielow_len & 0x3ff))+ m_sbielow_len;
#endif
//
@@ -693,16 +703,10 @@ _FX HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess)
//---------------------------------------------------------------------------
-_FX void *SbieDll_InjectLow_CopyCode(HANDLE hProcess, BOOLEAN iswow64, UCHAR *code, ULONG code_len)
+_FX void *SbieDll_InjectLow_CopyCode(HANDLE hProcess, SIZE_T lowLevel_size, UCHAR *code, ULONG code_len)
{
SIZE_T region_size;
- SIZE_T lowLevel_size;
void *remote_addr = NULL;
-#ifdef _WIN64
- lowLevel_size = m_sbielow_len + sizeof(SBIELOW_J_TABLE) + 0x400;
-#else
- lowLevel_size = m_sbielow_len;
-#endif
region_size = lowLevel_size;
//for (int i = 8; !remote_addr && i > 2; i--) {
@@ -1097,7 +1101,7 @@ _FX BOOLEAN SbieDll_InjectLow_WriteJump(HANDLE hProcess, void *remote_addr, BOOL
//
UCHAR jump_code[16];
void * detour = (void *)remote_addr;
- UCHAR *func = (UCHAR *)((ULONG_PTR)m_LdrInitializeThunk);;
+ UCHAR *func = (UCHAR *)((ULONG_PTR)m_LdrInitializeThunk);
SIZE_T len1;
BOOL myVM;
ULONG myProtect;
diff --git a/Sandboxie/core/low/init.c b/Sandboxie/core/low/init.c
index ce2c6557..bc4026ba 100644
--- a/Sandboxie/core/low/init.c
+++ b/Sandboxie/core/low/init.c
@@ -208,7 +208,7 @@ _FX void WaitForDebugger(SBIELOW_DATA *data)
ULONGLONG * findChromeTarget(unsigned char* addr)
{
int i = 0;
- ULONGLONG target = 0;
+ ULONGLONG target;
ULONG_PTR * ChromeTarget = NULL;
if (!addr) return NULL;
//Look for mov rcx,[target 4 byte offset] or in some cases mov rax,[target 4 byte offset]
@@ -234,6 +234,55 @@ ULONGLONG * findChromeTarget(unsigned char* addr)
}
#endif
+void *Hook_CheckChromeHook(void *SourceFunc)
+{
+ if (!SourceFunc)
+ return NULL;
+ UCHAR *ZwXxxPtr = (UCHAR *)SourceFunc;
+#ifndef _WIN64 //if not _WIN64
+ if (ZwXxxPtr[0] == 0xB8 && // mov eax,?
+ ZwXxxPtr[5] == 0xBA && // mov edx,?
+ *(USHORT *)&ZwXxxPtr[10] == 0xE2FF) // jmp edx
+ {
+ ULONG i = 0;
+
+ ULONG *longs = *(ULONG **)&ZwXxxPtr[6];
+ for (i = 0; i < 20; i++, longs++)
+ {
+ if (longs[0] == 0x5208EC83 && longs[1] == 0x0C24548B &&
+ longs[2] == 0x08245489 && longs[3] == 0x0C2444C7 &&
+ longs[5] == 0x042444C7)
+ {
+ ZwXxxPtr = (UCHAR *)longs[4];
+ break;
+ }
+ }
+ }
+#else // _WIN64
+ ULONGLONG *chrome64Target = NULL;
+
+ if (ZwXxxPtr[0] == 0x50 && //push rax
+ ZwXxxPtr[1] == 0x48 && //mov rax,?
+ ZwXxxPtr[2] == 0xb8) {
+ ULONGLONG* longlongs = *(ULONGLONG**)&ZwXxxPtr[3];
+ chrome64Target = findChromeTarget((unsigned char*)longlongs);
+ }
+ // Chrome 49+ 64bit hook
+ // mov rax,
+ // jmp rax
+ else if (ZwXxxPtr[0] == 0x48 && //mov rax,
+ ZwXxxPtr[1] == 0xb8 &&
+ *(USHORT*)&ZwXxxPtr[10] == 0xe0ff)/* jmp rax */ {
+ ULONGLONG* longlongs = *(ULONGLONG**)&ZwXxxPtr[2];
+ chrome64Target = findChromeTarget((unsigned char*)longlongs);
+ }
+ if (chrome64Target != NULL) {
+ ZwXxxPtr = (UCHAR *)chrome64Target;
+ }
+#endif
+ return ZwXxxPtr;
+}
+
_FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
{
UCHAR *SystemServiceAsm;
@@ -278,9 +327,6 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
void *RegionBase;
SIZE_T RegionSize;
ULONG OldProtect;
-#ifdef _WIN64
- ULONGLONG *chrome64Target = NULL;
-#endif
SystemServiceAsm = (UCHAR *)SystemService;
@@ -310,54 +356,16 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
// saved by chrome, rather than the chrome hook itself (32-bit only)
//
-#ifndef _WIN64 //if not _WIN64
-
- if (ZwXxxPtr[0] == 0xB8 && // mov eax,?
- ZwXxxPtr[5] == 0xBA && // mov edx,?
- *(USHORT *)&ZwXxxPtr[10] == 0xE2FF) // jmp edx
- {
- ULONG i = 0;
-
- ULONG *longs = *(ULONG **)&ZwXxxPtr[6];
- for (i = 0; i < 20; i++, longs++)
- {
- if (longs[0] == 0x5208EC83 && longs[1] == 0x0C24548B &&
- longs[2] == 0x08245489 && longs[3] == 0x0C2444C7 &&
- longs[5] == 0x042444C7)
- {
- ZwXxxPtr = (UCHAR *)longs[4];
- break;
- }
- }
- }
-#else // _WIN64
- if (ZwXxxPtr[0] == 0x50 && //push rax
- ZwXxxPtr[1] == 0x48 && //mov rax,?
- ZwXxxPtr[2] == 0xb8) {
- ULONGLONG *longlongs = *(ULONGLONG **)&ZwXxxPtr[3];
- chrome64Target = findChromeTarget((unsigned char *)longlongs);
- }
- // Chrome 49+ 64bit hook
- // mov rax,
- // jmp rax
- else if (ZwXxxPtr[0] == 0x48 && //mov rax,
- ZwXxxPtr[1] == 0xb8 &&
- *(USHORT *)&ZwXxxPtr[10] == 0xe0ff)/* jmp rax */ {
- ULONGLONG *longlongs = *(ULONGLONG **)&ZwXxxPtr[2];
- chrome64Target = findChromeTarget((unsigned char *)longlongs);
- }
-#endif
+ ZwXxxPtr = Hook_CheckChromeHook(ZwXxxPtr);
//
// make the syscall address writable
//
+
RegionBase = ZwXxxPtr;
#ifdef _WIN64
- RegionSize = 14;
- if (!chrome64Target) {
- chrome64Target = (ULONG_PTR*)ZwXxxPtr;
- }
+ RegionSize = data->Sbie64bitJumpTable ? 13 : 14; // 16;
#else ! _WIN64
RegionSize = 10;
#endif _WIN64
@@ -371,21 +379,18 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
// and then restore the original page protection
//
+ SBIELOW_CALL(NtProtectVirtualMemory)(
+ NtCurrentProcess(), &RegionBase, &RegionSize,
+ PAGE_EXECUTE_READWRITE, &OldProtect);
+
SyscallNum = SyscallPtr[0];
#ifdef _WIN64
- SyscallNum &= 0xFFFF; // clear the not needed param count
- if (chrome64Target && data->Sbie64bitJumpTable) {
- RegionSize = 16;
- ZwXxxPtr = (UCHAR *)chrome64Target;
- RegionBase = ZwXxxPtr;
+ if (data->Sbie64bitJumpTable) {
+ // bytes overwriten /*16*/ 13;
- SBIELOW_CALL(NtProtectVirtualMemory)(
- NtCurrentProcess(), &RegionBase, &RegionSize,
- PAGE_EXECUTE_READWRITE, &OldProtect);
-
- unsigned char * jTableTarget = (unsigned char *)&data->Sbie64bitJumpTable->entry[SyscallNum & 0x3ff];
+ unsigned char * jTableTarget = (unsigned char *)&data->Sbie64bitJumpTable->entry[SyscallNum & 0x3ff]; // jump table is sized for up to 1024 entries
// write new patch for jump table
// The jTable is now injected in the same memory module with lowlevel; no need for a 64 bit long jump
// mov r10, <4 byte SyscallNum>
@@ -427,18 +432,11 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
// jmp rax
ZwXxxPtr[11] = 0xFF;
ZwXxxPtr[12] = 0xE0;
-
- chrome64Target = NULL;
}
- else
- {
- RegionBase = ZwXxxPtr;
+ else {
+ // bytes overwriten 14;
- SBIELOW_CALL(NtProtectVirtualMemory)(
- NtCurrentProcess(), &RegionBase, &RegionSize,
- PAGE_EXECUTE_READWRITE, &OldProtect);
-
- ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
+ ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
ZwXxxPtr[1] = 0xC7;
ZwXxxPtr[2] = 0xC2;
*(ULONG *)&ZwXxxPtr[3] = SyscallNum;
@@ -446,7 +444,7 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
if (data->flags.is_win10) {
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
- ZwXxxPtr[8] = 0xE9; // jmp SystemServiceAsm
+ ZwXxxPtr[8] = 0xE9;
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (ZwXxxPtr + 13));
}
else {
@@ -456,18 +454,15 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
}
else {
- ZwXxxPtr[7] = 0xB8; // mov eax, SystemServiceAsm
+ ZwXxxPtr[7] = 0xB8; // mov eax, SystemServiceAsm
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
*(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
}
}
#else ! _WIN64
+ // bytes overwriten 10;
- SBIELOW_CALL(NtProtectVirtualMemory)(
- NtCurrentProcess(), &RegionBase, &RegionSize,
- PAGE_EXECUTE_READWRITE, &OldProtect);
-
- ZwXxxPtr[0] = 0xB8; // mov eax, SyscallNumber
+ ZwXxxPtr[0] = 0xB8; // mov eax, SyscallNumber, with param count in the highest byte
*(ULONG *)&ZwXxxPtr[1] = SyscallNum;
ZwXxxPtr[5] = 0xE9; // jmp SystemServiceAsm
*(ULONG *)&ZwXxxPtr[6] =
diff --git a/SandboxiePlus/SandMan/SandMan.rc b/SandboxiePlus/SandMan/SandMan.rc
index 24f47c5f..2b70207a 100644
--- a/SandboxiePlus/SandMan/SandMan.rc
+++ b/SandboxiePlus/SandMan/SandMan.rc
@@ -88,7 +88,7 @@ BEGIN
BLOCK "0c0704b0"
BEGIN
VALUE "CompanyName", MY_COMPANY_NAME_STRING
- VALUE "FileDescription", "SandBox Manager"
+ VALUE "FileDescription", "SandBoxie Manager"
VALUE "FileVersion", VERSION_STR
VALUE "InternalName", "SandMan.exe"
VALUE "LegalCopyright", MY_COPYRIGHT_STRING
diff --git a/SandboxiePlus/version.h b/SandboxiePlus/version.h
index 71743aab..7db323bb 100644
--- a/SandboxiePlus/version.h
+++ b/SandboxiePlus/version.h
@@ -10,10 +10,15 @@
#define STR(X) STR2(X)
#endif
-#define VERSION_BIN VERSION_MJR,VERSION_MIN,VERSION_REV,VERSION_UPD
-#define VERSION_STR STR(VERSION_MJR.VERSION_MIN.VERSION_REV.VERSION_UPD)
+#if VERSION_UPD > 0
+ #define VERSION_BIN VERSION_MJR,VERSION_MIN,VERSION_REV,VERSION_UPD
+ #define VERSION_STR STR(VERSION_MJR.VERSION_MIN.VERSION_REV.VERSION_UPD)
+#else
+ #define VERSION_BIN VERSION_MJR,VERSION_MIN,VERSION_REV
+ #define VERSION_STR STR(VERSION_MJR.VERSION_MIN.VERSION_REV)
+#endif
#define MY_PRODUCT_NAME_STRING "Sandboxie-Plus"
#define MY_COMPANY_NAME_STRING "sandboxie-plus.com"
-#define MY_COPYRIGHT_STRING "Copyright (C) 2020-2021 by David Xanatos (xanasoft.com)"
+#define MY_COPYRIGHT_STRING "Copyright (C) 2020-2022 by David Xanatos (xanasoft.com)"