This commit is contained in:
DavidXanatos 2021-12-15 23:31:28 +01:00
parent 93ae00aba1
commit db2b095d6c
9 changed files with 281 additions and 257 deletions

View File

@ -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

View File

@ -406,6 +406,7 @@
<ItemGroup>
<ClInclude Include="..\..\apps\com\common.h" />
<ClInclude Include="..\..\common\map.h" />
<ClInclude Include="..\..\common\my_version.h" />
<ClInclude Include="..\..\common\ntproto.h" />
<ClInclude Include="..\..\common\str_util.h" />
<ClInclude Include="..\..\common\my_wsa.h" />

View File

@ -295,6 +295,9 @@
<ClInclude Include="..\..\common\wow64ext\wow64ext.h">
<Filter>common\wow64ext</Filter>
</ClInclude>
<ClInclude Include="..\..\common\my_version.h">
<Filter>common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc" />

View File

@ -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
//---------------------------------------------------------------------------
// 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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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, <target>
// jmp rax
else if (ZwXxxPtr[0] == 0x48 && //mov rax,<target>
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, <target>
// jmp rax
else if (ZwXxxPtr[0] == 0x48 && //mov rax,<target>
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] =

View File

@ -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

View File

@ -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)"