1.0.4
This commit is contained in:
parent
93ae00aba1
commit
db2b095d6c
|
@ -9,7 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- mechanism to hook Win32 system calls now also works for 32 bit applications running under WoW64
|
- mechanism to hook Win32 system calls now also works for 32 bit applications running under WoW64
|
||||||
|
- cleaned up low level hooking code a bit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -406,6 +406,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\apps\com\common.h" />
|
<ClInclude Include="..\..\apps\com\common.h" />
|
||||||
<ClInclude Include="..\..\common\map.h" />
|
<ClInclude Include="..\..\common\map.h" />
|
||||||
|
<ClInclude Include="..\..\common\my_version.h" />
|
||||||
<ClInclude Include="..\..\common\ntproto.h" />
|
<ClInclude Include="..\..\common\ntproto.h" />
|
||||||
<ClInclude Include="..\..\common\str_util.h" />
|
<ClInclude Include="..\..\common\str_util.h" />
|
||||||
<ClInclude Include="..\..\common\my_wsa.h" />
|
<ClInclude Include="..\..\common\my_wsa.h" />
|
||||||
|
|
|
@ -295,6 +295,9 @@
|
||||||
<ClInclude Include="..\..\common\wow64ext\wow64ext.h">
|
<ClInclude Include="..\..\common\wow64ext\wow64ext.h">
|
||||||
<Filter>common\wow64ext</Filter>
|
<Filter>common\wow64ext</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\common\my_version.h">
|
||||||
|
<Filter>common</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="resource.rc" />
|
<ResourceCompile Include="resource.rc" />
|
||||||
|
|
|
@ -25,16 +25,18 @@
|
||||||
|
|
||||||
#include "common\pattern.h"
|
#include "common\pattern.h"
|
||||||
|
|
||||||
#define HOOK_WIN32K
|
|
||||||
|
|
||||||
#ifdef HOOK_WIN32K
|
|
||||||
|
|
||||||
#include "core/drv/api_defs.h"
|
#include "core/drv/api_defs.h"
|
||||||
#include "core/low/lowdata.h"
|
#include "core/low/lowdata.h"
|
||||||
|
|
||||||
SBIELOW_DATA* SbieApi_data = NULL;
|
SBIELOW_DATA* SbieApi_data = NULL;
|
||||||
#define SBIELOW_CALL(x) ((P_##x)&data->x##_code)
|
#define SBIELOW_CALL(x) ((P_##x)&data->x##_code)
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// SbieDll_HookWin32SysCalls
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
_FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
_FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
{
|
{
|
||||||
UCHAR *SystemServiceAsm, *ZwXxxPtr;
|
UCHAR *SystemServiceAsm, *ZwXxxPtr;
|
||||||
|
@ -102,7 +104,6 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
SyscallNum = SyscallPtr[0];
|
SyscallNum = SyscallPtr[0];
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
SyscallNum &= 0xFFFF; // clear the not needed param count
|
|
||||||
|
|
||||||
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
||||||
ZwXxxPtr[1] = 0xC7;
|
ZwXxxPtr[1] = 0xC7;
|
||||||
|
@ -112,7 +113,7 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
|
|
||||||
if (data->flags.is_win10) {
|
if (data->flags.is_win10) {
|
||||||
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
|
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
|
||||||
ZwXxxPtr[8] = 0xE9; // jmp SystemServiceAsm
|
ZwXxxPtr[8] = 0xE9;
|
||||||
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (ZwXxxPtr + 13));
|
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (ZwXxxPtr + 13));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -129,7 +130,7 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
|
|
||||||
#else ! _WIN64
|
#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;
|
*(ULONG *)&ZwXxxPtr[1] = SyscallNum;
|
||||||
ZwXxxPtr[5] = 0xE9; // jmp SystemServiceAsm
|
ZwXxxPtr[5] = 0xE9; // jmp SystemServiceAsm
|
||||||
*(ULONG *)&ZwXxxPtr[6] =
|
*(ULONG *)&ZwXxxPtr[6] =
|
||||||
|
@ -148,72 +149,12 @@ _FX BOOLEAN SbieDll_HookWin32SysCalls(HMODULE win32u_base)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN64
|
|
||||||
|
|
||||||
BOOLEAN SbieDll_HookWoW64SysCalls();
|
//---------------------------------------------------------------------------
|
||||||
|
// Win32_WoW64_GetSysCallNumber
|
||||||
#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)) {
|
|
||||||
|
|
||||||
#ifndef _WIN64
|
#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)
|
ULONG Win32_WoW64_GetSysCallNumber(DWORD64 pos, UCHAR* dll_data)
|
||||||
{
|
{
|
||||||
// 4C 8B D1 - r10,rcx
|
// 4C 8B D1 - r10,rcx
|
||||||
|
@ -247,13 +188,52 @@ ULONG Win32_WoW64_GetSysCallNumber(DWORD64 pos, UCHAR* dll_data)
|
||||||
if (!(dll_data[pos + 23] == 0xc3))
|
if (!(dll_data[pos + 23] == 0xc3))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// 0F 1F 84 00 00 00 00 00
|
|
||||||
//
|
//
|
||||||
|
|
||||||
return syscall_index;
|
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;
|
BOOLEAN ok = FALSE;
|
||||||
UCHAR* dll_data = NULL;
|
UCHAR* dll_data = NULL;
|
||||||
|
@ -261,20 +241,28 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
||||||
|
|
||||||
DWORD64 BaseAddress = GetModuleHandle64(L"wow64win.dll");
|
DWORD64 BaseAddress = GetModuleHandle64(L"wow64win.dll");
|
||||||
SIZE_T SizeOfImage = 0x00100000; // 1 MB should be more than enough
|
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;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
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;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
dll_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, (SIZE_T)SizeOfImage);
|
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;
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
SIZE_T SizeRead;
|
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;
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD64 FuncTable = 0;
|
DWORD64 FuncTable = 0;
|
||||||
|
|
||||||
|
@ -285,12 +273,13 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FuncTable == 0)
|
if (FuncTable == 0) {
|
||||||
|
SbieApi_Log(2303, L"win32k, wow64win.dll sys call table not found");
|
||||||
goto finish;
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD64 SystemServiceAsm;
|
DWORD64 SystemServiceAsm;
|
||||||
UCHAR ZwXxxPtr[16];
|
UCHAR ZwXxxPtr[16];
|
||||||
ULONG *SyscallPtr;
|
|
||||||
ULONG SyscallNum;
|
ULONG SyscallNum;
|
||||||
DWORD64 RegionBase;
|
DWORD64 RegionBase;
|
||||||
SIZE_T RegionSize;
|
SIZE_T RegionSize;
|
||||||
|
@ -300,43 +289,30 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
||||||
SystemServiceAsm = data->pSystemService;
|
SystemServiceAsm = data->pSystemService;
|
||||||
|
|
||||||
syscall_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, 16384); // enough room for over 2000 syscalls
|
syscall_data = (UCHAR *)HeapAlloc(GetProcessHeap(), 0, 16384); // enough room for over 2000 syscalls
|
||||||
if (!syscall_data)
|
if (!syscall_data) {
|
||||||
|
SbieApi_Log(2303, L"win32k, alloc failed (2)");
|
||||||
goto finish;
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(SbieApi_Call(API_QUERY_SYSCALLS, 2, (ULONG_PTR)syscall_data, 1))) {
|
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;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DWORD64 pos = FuncTable; pos < SizeRead - 0x20; )
|
for (DWORD64 pos = FuncTable; pos < SizeRead - 0x20; )
|
||||||
{
|
{
|
||||||
ULONG syscall_index = Win32_WoW64_GetSysCallNumber(pos, dll_data);
|
SyscallNum = Win32_WoW64_GetSysCallNumber(pos, dll_data);
|
||||||
if (syscall_index)
|
if (SyscallNum)
|
||||||
|
{
|
||||||
|
if(SbieDll_HasSysCallHook(syscall_data, 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){
|
|
||||||
|
|
||||||
RegionBase = BaseAddress + pos;
|
RegionBase = BaseAddress + pos;
|
||||||
// _WIN64
|
|
||||||
RegionSize = 14;
|
RegionSize = 14;
|
||||||
// ! _WIN64
|
|
||||||
|
|
||||||
if (!ReadProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead))
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// overwrite the ZwXxx export to call our SystemServiceAsm,
|
// prepare call to call our SystemServiceAsm
|
||||||
// and then restore the original page protection
|
|
||||||
//
|
//
|
||||||
|
|
||||||
// _WIN64
|
|
||||||
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
||||||
ZwXxxPtr[1] = 0xC7;
|
ZwXxxPtr[1] = 0xC7;
|
||||||
ZwXxxPtr[2] = 0xC2;
|
ZwXxxPtr[2] = 0xC2;
|
||||||
|
@ -345,7 +321,7 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
||||||
|
|
||||||
if (data->flags.is_win10) {
|
if (data->flags.is_win10) {
|
||||||
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
|
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
|
||||||
ZwXxxPtr[8] = 0xE9; // jmp SystemServiceAsm
|
ZwXxxPtr[8] = 0xE9;
|
||||||
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 13));
|
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (RegionBase + 13));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -359,20 +335,27 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
||||||
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
|
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
|
||||||
*(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
|
*(USHORT *)&ZwXxxPtr[12] = 0xE0FF; // jmp rax
|
||||||
}
|
}
|
||||||
// ! _WIN64
|
|
||||||
|
|
||||||
|
|
||||||
if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &OldProtect))
|
//
|
||||||
goto finish;
|
// overwrite the ZwXxx export to call our SystemServiceAsm,
|
||||||
|
// and then restore the original page protection
|
||||||
|
//
|
||||||
|
|
||||||
if (!WriteProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead))
|
if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &OldProtect)) {
|
||||||
goto finish;
|
SbieApi_Log(2303, L"win32k %d (1)", SyscallNum);
|
||||||
|
|
||||||
if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, OldProtect, &OldProtect))
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
SyscallPtr += 2;
|
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;
|
pos += 0x20;
|
||||||
|
@ -385,7 +368,6 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
|
||||||
if(syscall_data)
|
if(syscall_data)
|
||||||
|
@ -398,7 +380,44 @@ finish:
|
||||||
|
|
||||||
return ok;
|
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
|
#endif
|
||||||
|
SbieDll_HookWin32SysCalls(hmodule); // Native x86/x64 hooks
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -130,7 +130,7 @@ _FX void *SbieDll_Hook(
|
||||||
// (this helps to co-exist with Cisco Security Agent)
|
// (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);
|
signed char offset = *((signed char *)SourceFunc + 1);
|
||||||
SourceFunc = (UCHAR *)SourceFunc + offset + 2;
|
SourceFunc = (UCHAR *)SourceFunc + offset + 2;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ _FX void *SbieDll_Hook(
|
||||||
// otherwise (for 32-bit code) just replace the jump target
|
// 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);
|
diff = *(LONG *)((ULONG_PTR)SourceFunc + 1);
|
||||||
target = (ULONG_PTR)SourceFunc + diff + 5;
|
target = (ULONG_PTR)SourceFunc + diff + 5;
|
||||||
|
@ -192,15 +192,15 @@ skip_e9_rewrite: ;
|
||||||
// can process it
|
// can process it
|
||||||
//
|
//
|
||||||
|
|
||||||
if (*(USHORT *)SourceFunc == 0xE990) {
|
if (*(USHORT *)SourceFunc == 0xE990) { // nop; jmp xx xx xx xx;
|
||||||
diff = *(LONG *)((ULONG_PTR)SourceFunc + 2);
|
diff = *(LONG *)((ULONG_PTR)SourceFunc + 2);
|
||||||
target = (ULONG_PTR)SourceFunc + diff + 6;
|
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;
|
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
|
// resulting in an endless loop, so just dont do that
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -211,13 +211,13 @@ skip_e9_rewrite: ;
|
||||||
// 12 bytes.
|
// 12 bytes.
|
||||||
//
|
//
|
||||||
|
|
||||||
if (*(UCHAR *)SourceFunc == 0x48 &&
|
if (*(UCHAR *)SourceFunc == 0x48 && // rex.W
|
||||||
*(USHORT *)((UCHAR *)SourceFunc + 1) == 0x25FF) {
|
*(USHORT *)((UCHAR *)SourceFunc + 1) == 0x25FF) { // jmp QWORD PTR [rip+xx xx xx xx];
|
||||||
// 4825FF is same as 25FF
|
// 48 FF 25 is same as FF 25
|
||||||
SourceFunc = (UCHAR *)SourceFunc + 1;
|
SourceFunc = (UCHAR *)SourceFunc + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(USHORT *)SourceFunc == 0x25FF) {
|
if (*(USHORT *)SourceFunc == 0x25FF) { // jmp QWORD PTR [rip+xx xx xx xx];
|
||||||
|
|
||||||
void *orig_addr;
|
void *orig_addr;
|
||||||
/*
|
/*
|
||||||
|
@ -254,7 +254,7 @@ skip_e9_rewrite: ;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#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
|
// the call instruction pushes a qword into the stack, we need
|
||||||
|
@ -312,8 +312,8 @@ skip_e9_rewrite: ;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ByteCount = *(ULONG*)(tramp + 80);
|
//ULONG ByteCount = *(ULONG*)(tramp + 80);
|
||||||
ULONG UsedCount = 0;
|
//ULONG UsedCount = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// create the detour
|
// create the detour
|
||||||
|
@ -351,22 +351,20 @@ skip_e9_rewrite: ;
|
||||||
OutputDebugStringA(buffer);
|
OutputDebugStringA(buffer);
|
||||||
*/
|
*/
|
||||||
if (Dll_Windows >= 10) {
|
if (Dll_Windows >= 10) {
|
||||||
func[0] = 0x48; // 32bit relative JMP DetourFunc
|
func[0] = 0x48; // 32bit relative rex.W JMP DetourFunc
|
||||||
func[1] = 0xE9; // 32bit relative JMP DetourFunc
|
func[1] = 0xE9;
|
||||||
*(ULONG *)(&func[2]) = (ULONG)diff;
|
*(ULONG *)(&func[2]) = (ULONG)diff;
|
||||||
UsedCount = 1 + 1 + 4;
|
//UsedCount = 1 + 1 + 4;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
func[0] = 0xE9; // 32bit relative JMP DetourFunc
|
func[0] = 0xE9; // 32bit relative JMP DetourFunc
|
||||||
*(ULONG *)(&func[1]) = (ULONG)diff;
|
*(ULONG *)(&func[1]) = (ULONG)diff;
|
||||||
UsedCount = 1 + 4;
|
//UsedCount = 1 + 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN hookset = FALSE;
|
BOOLEAN hookset = FALSE;
|
||||||
BOOLEAN defaultRange = FALSE;
|
BOOLEAN defaultRange = FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
@ -377,12 +375,12 @@ skip_e9_rewrite: ;
|
||||||
//default step size
|
//default step size
|
||||||
|
|
||||||
for (i = 0; i < NUM_VTABLES && !hookset; i++, ptrVTable++) {
|
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 tempAddr;
|
||||||
ULONG_PTR step = 0x20000;// + VTABLE_SIZE;
|
ULONG_PTR step = 0x20000;// + VTABLE_SIZE;
|
||||||
ULONG_PTR max_attempts = 0x4000000 / step;
|
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)) {
|
if ((ULONG_PTR)func < 0x80000000 && ((ULONG_PTR)func > 0x4000000)) {
|
||||||
step = 0x200000;
|
step = 0x200000;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +412,7 @@ skip_e9_rewrite: ;
|
||||||
ptrVTable->index = 0;
|
ptrVTable->index = 0;
|
||||||
ptrVTable->maxEntries = VTABLE_SIZE / sizeof(void *);
|
ptrVTable->maxEntries = VTABLE_SIZE / sizeof(void *);
|
||||||
}
|
}
|
||||||
if (ptrVTable->offset) {
|
if (ptrVTable->offset) { // check if we have an nitialized vtable
|
||||||
target = (ULONG_PTR)&func[6];
|
target = (ULONG_PTR)&func[6];
|
||||||
diff = (ULONG_PTR) &((ULONG_PTR *)ptrVTable->offset)[ptrVTable->index];
|
diff = (ULONG_PTR) &((ULONG_PTR *)ptrVTable->offset)[ptrVTable->index];
|
||||||
diff = diff - target;
|
diff = diff - target;
|
||||||
|
@ -424,14 +422,14 @@ skip_e9_rewrite: ;
|
||||||
// is DetourFunc in 32bit jump range
|
// is DetourFunc in 32bit jump range
|
||||||
if (delta < 0x80000000 && ptrVTable->index <= ptrVTable->maxEntries) {
|
if (delta < 0x80000000 && ptrVTable->index <= ptrVTable->maxEntries) {
|
||||||
((ULONG_PTR *)ptrVTable->offset)[ptrVTable->index] = (ULONG_PTR)DetourFunc;
|
((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;
|
*(ULONG *)&func[2] = (ULONG)diff;
|
||||||
UsedCount = 2 + 4;
|
//UsedCount = 2 + 4;
|
||||||
ptrVTable->index++;
|
ptrVTable->index++;
|
||||||
hookset = TRUE;
|
hookset = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else { // fail and disable vtable if it could not be initialized
|
||||||
bVTableEable = FALSE;
|
bVTableEable = FALSE;
|
||||||
SbieApi_Log(2303, _fmt1, SourceFuncName, 888);
|
SbieApi_Log(2303, _fmt1, SourceFuncName, 888);
|
||||||
LeaveCriticalSection(&VT_CriticalSection);
|
LeaveCriticalSection(&VT_CriticalSection);
|
||||||
|
@ -529,9 +527,10 @@ ULONGLONG * SbieDll_findChromeTarget(unsigned char* addr)
|
||||||
|
|
||||||
_FX void *SbieDll_Hook_CheckChromeHook(void *SourceFunc)
|
_FX void *SbieDll_Hook_CheckChromeHook(void *SourceFunc)
|
||||||
{
|
{
|
||||||
#ifndef _WIN64
|
if (!SourceFunc)
|
||||||
|
return NULL;
|
||||||
UCHAR *func = (UCHAR *)SourceFunc;
|
UCHAR *func = (UCHAR *)SourceFunc;
|
||||||
|
#ifndef _WIN64
|
||||||
if (func[0] == 0xB8 && // mov eax,?
|
if (func[0] == 0xB8 && // mov eax,?
|
||||||
func[5] == 0xBA && // mov edx,?
|
func[5] == 0xBA && // mov edx,?
|
||||||
*(USHORT *)&func[10] == 0xE2FF) // jmp edx
|
*(USHORT *)&func[10] == 0xE2FF) // jmp edx
|
||||||
|
@ -551,10 +550,7 @@ _FX void *SbieDll_Hook_CheckChromeHook(void *SourceFunc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else if
|
#else if
|
||||||
UCHAR *func = (UCHAR *)SourceFunc;
|
|
||||||
ULONGLONG *chrome64Target = NULL;
|
ULONGLONG *chrome64Target = NULL;
|
||||||
if (!SourceFunc)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (func[0] == 0x50 && //push rax
|
if (func[0] == 0x50 && //push rax
|
||||||
func[1] == 0x48 && //mov rax,?
|
func[1] == 0x48 && //mov rax,?
|
||||||
|
@ -576,7 +572,8 @@ _FX void *SbieDll_Hook_CheckChromeHook(void *SourceFunc)
|
||||||
}
|
}
|
||||||
/*sboxie 64bit jtable hook signature */
|
/*sboxie 64bit jtable hook signature */
|
||||||
/* // use this to hook jtable location (useful for debugging)
|
/* // 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;
|
long long addr;
|
||||||
addr = (ULONG_PTR) *(ULONGLONG **)&func[3] ;
|
addr = (ULONG_PTR) *(ULONGLONG **)&func[3] ;
|
||||||
SourceFunc = (void *) addr;
|
SourceFunc = (void *) addr;
|
||||||
|
|
|
@ -55,7 +55,7 @@ typedef struct _MY_TARGETS {
|
||||||
SBIEDLL_EXPORT HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess);
|
SBIEDLL_EXPORT HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess);
|
||||||
|
|
||||||
SBIEDLL_EXPORT void *SbieDll_InjectLow_CopyCode(
|
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(
|
SBIEDLL_EXPORT BOOLEAN SbieDll_InjectLow_BuildTramp(
|
||||||
BOOLEAN long_diff, UCHAR *code, ULONG_PTR addr);
|
BOOLEAN long_diff, UCHAR *code, ULONG_PTR addr);
|
||||||
SBIEDLL_EXPORT void *SbieDll_InjectLow_CopySyscalls(HANDLE hProcess);
|
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;
|
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) {
|
if (!remote_addr) {
|
||||||
errlvl = 0x33;
|
errlvl = 0x33;
|
||||||
goto finish;
|
goto finish;
|
||||||
|
@ -570,6 +579,7 @@ _FX ULONG SbieDll_InjectLow(HANDLE hProcess, ULONG init_flags, BOOLEAN dup_drv_h
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
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;
|
lowdata.Sbie64bitJumpTable = (SBIELOW_J_TABLE *)((ULONG_PTR)remote_addr + m_sbielow_len + 0x400); //(0x400 - (m_sbielow_len & 0x3ff))+ m_sbielow_len;
|
||||||
#endif
|
#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 region_size;
|
||||||
SIZE_T lowLevel_size;
|
|
||||||
void *remote_addr = NULL;
|
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;
|
region_size = lowLevel_size;
|
||||||
|
|
||||||
//for (int i = 8; !remote_addr && i > 2; i--) {
|
//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];
|
UCHAR jump_code[16];
|
||||||
void * detour = (void *)remote_addr;
|
void * detour = (void *)remote_addr;
|
||||||
UCHAR *func = (UCHAR *)((ULONG_PTR)m_LdrInitializeThunk);;
|
UCHAR *func = (UCHAR *)((ULONG_PTR)m_LdrInitializeThunk);
|
||||||
SIZE_T len1;
|
SIZE_T len1;
|
||||||
BOOL myVM;
|
BOOL myVM;
|
||||||
ULONG myProtect;
|
ULONG myProtect;
|
||||||
|
|
|
@ -208,7 +208,7 @@ _FX void WaitForDebugger(SBIELOW_DATA *data)
|
||||||
ULONGLONG * findChromeTarget(unsigned char* addr)
|
ULONGLONG * findChromeTarget(unsigned char* addr)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
ULONGLONG target = 0;
|
ULONGLONG target;
|
||||||
ULONG_PTR * ChromeTarget = NULL;
|
ULONG_PTR * ChromeTarget = NULL;
|
||||||
if (!addr) return NULL;
|
if (!addr) return NULL;
|
||||||
//Look for mov rcx,[target 4 byte offset] or in some cases mov rax,[target 4 byte offset]
|
//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
|
#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)
|
_FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
{
|
{
|
||||||
UCHAR *SystemServiceAsm;
|
UCHAR *SystemServiceAsm;
|
||||||
|
@ -278,9 +327,6 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
void *RegionBase;
|
void *RegionBase;
|
||||||
SIZE_T RegionSize;
|
SIZE_T RegionSize;
|
||||||
ULONG OldProtect;
|
ULONG OldProtect;
|
||||||
#ifdef _WIN64
|
|
||||||
ULONGLONG *chrome64Target = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SystemServiceAsm = (UCHAR *)SystemService;
|
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)
|
// saved by chrome, rather than the chrome hook itself (32-bit only)
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _WIN64 //if not _WIN64
|
ZwXxxPtr = Hook_CheckChromeHook(ZwXxxPtr);
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// make the syscall address writable
|
// make the syscall address writable
|
||||||
//
|
//
|
||||||
|
|
||||||
RegionBase = ZwXxxPtr;
|
RegionBase = ZwXxxPtr;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
RegionSize = 14;
|
RegionSize = data->Sbie64bitJumpTable ? 13 : 14; // 16;
|
||||||
if (!chrome64Target) {
|
|
||||||
chrome64Target = (ULONG_PTR*)ZwXxxPtr;
|
|
||||||
}
|
|
||||||
#else ! _WIN64
|
#else ! _WIN64
|
||||||
RegionSize = 10;
|
RegionSize = 10;
|
||||||
#endif _WIN64
|
#endif _WIN64
|
||||||
|
@ -371,21 +379,18 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
// and then restore the original page protection
|
// and then restore the original page protection
|
||||||
//
|
//
|
||||||
|
|
||||||
SyscallNum = SyscallPtr[0];
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
|
||||||
SyscallNum &= 0xFFFF; // clear the not needed param count
|
|
||||||
|
|
||||||
if (chrome64Target && data->Sbie64bitJumpTable) {
|
|
||||||
RegionSize = 16;
|
|
||||||
ZwXxxPtr = (UCHAR *)chrome64Target;
|
|
||||||
RegionBase = ZwXxxPtr;
|
|
||||||
|
|
||||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||||
|
|
||||||
unsigned char * jTableTarget = (unsigned char *)&data->Sbie64bitJumpTable->entry[SyscallNum & 0x3ff];
|
SyscallNum = SyscallPtr[0];
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
|
||||||
|
if (data->Sbie64bitJumpTable) {
|
||||||
|
// bytes overwriten /*16*/ 13;
|
||||||
|
|
||||||
|
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
|
// 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
|
// 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>
|
// mov r10, <4 byte SyscallNum>
|
||||||
|
@ -427,16 +432,9 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
// jmp rax
|
// jmp rax
|
||||||
ZwXxxPtr[11] = 0xFF;
|
ZwXxxPtr[11] = 0xFF;
|
||||||
ZwXxxPtr[12] = 0xE0;
|
ZwXxxPtr[12] = 0xE0;
|
||||||
|
|
||||||
chrome64Target = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
// bytes overwriten 14;
|
||||||
RegionBase = ZwXxxPtr;
|
|
||||||
|
|
||||||
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[1] = 0xC7;
|
||||||
|
@ -446,7 +444,7 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
|
|
||||||
if (data->flags.is_win10) {
|
if (data->flags.is_win10) {
|
||||||
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
|
ZwXxxPtr[7] = 0x48; // jmp SystemServiceAsm
|
||||||
ZwXxxPtr[8] = 0xE9; // jmp SystemServiceAsm
|
ZwXxxPtr[8] = 0xE9;
|
||||||
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (ZwXxxPtr + 13));
|
*(ULONG *)&ZwXxxPtr[9] = (ULONG)(ULONG_PTR)(SystemServiceAsm - (ZwXxxPtr + 13));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -462,12 +460,9 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else ! _WIN64
|
#else ! _WIN64
|
||||||
|
// bytes overwriten 10;
|
||||||
|
|
||||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
ZwXxxPtr[0] = 0xB8; // mov eax, SyscallNumber, with param count in the highest byte
|
||||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
|
||||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
|
||||||
|
|
||||||
ZwXxxPtr[0] = 0xB8; // mov eax, SyscallNumber
|
|
||||||
*(ULONG *)&ZwXxxPtr[1] = SyscallNum;
|
*(ULONG *)&ZwXxxPtr[1] = SyscallNum;
|
||||||
ZwXxxPtr[5] = 0xE9; // jmp SystemServiceAsm
|
ZwXxxPtr[5] = 0xE9; // jmp SystemServiceAsm
|
||||||
*(ULONG *)&ZwXxxPtr[6] =
|
*(ULONG *)&ZwXxxPtr[6] =
|
||||||
|
|
|
@ -88,7 +88,7 @@ BEGIN
|
||||||
BLOCK "0c0704b0"
|
BLOCK "0c0704b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", MY_COMPANY_NAME_STRING
|
VALUE "CompanyName", MY_COMPANY_NAME_STRING
|
||||||
VALUE "FileDescription", "SandBox Manager"
|
VALUE "FileDescription", "SandBoxie Manager"
|
||||||
VALUE "FileVersion", VERSION_STR
|
VALUE "FileVersion", VERSION_STR
|
||||||
VALUE "InternalName", "SandMan.exe"
|
VALUE "InternalName", "SandMan.exe"
|
||||||
VALUE "LegalCopyright", MY_COPYRIGHT_STRING
|
VALUE "LegalCopyright", MY_COPYRIGHT_STRING
|
||||||
|
|
|
@ -10,10 +10,15 @@
|
||||||
#define STR(X) STR2(X)
|
#define STR(X) STR2(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VERSION_BIN VERSION_MJR,VERSION_MIN,VERSION_REV,VERSION_UPD
|
#if VERSION_UPD > 0
|
||||||
#define VERSION_STR STR(VERSION_MJR.VERSION_MIN.VERSION_REV.VERSION_UPD)
|
#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_PRODUCT_NAME_STRING "Sandboxie-Plus"
|
||||||
#define MY_COMPANY_NAME_STRING "sandboxie-plus.com"
|
#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)"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue