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
|
||||
- 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>
|
||||
<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" />
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
DWORD64 SystemServiceAsm;
|
||||
UCHAR ZwXxxPtr[16];
|
||||
ULONG *SyscallPtr;
|
||||
ULONG SyscallNum;
|
||||
DWORD64 RegionBase;
|
||||
SIZE_T RegionSize;
|
||||
|
@ -300,43 +289,30 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
|||
SystemServiceAsm = data->pSystemService;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
// _WIN64
|
||||
RegionSize = 14;
|
||||
// ! _WIN64
|
||||
|
||||
if (!ReadProcessMemory64(hProcess, RegionBase, ZwXxxPtr, RegionSize, &SizeRead))
|
||||
goto finish;
|
||||
|
||||
//
|
||||
// overwrite the ZwXxx export to call our SystemServiceAsm,
|
||||
// and then restore the original page protection
|
||||
// prepare call to call our SystemServiceAsm
|
||||
//
|
||||
|
||||
// _WIN64
|
||||
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
||||
ZwXxxPtr[1] = 0xC7;
|
||||
ZwXxxPtr[2] = 0xC2;
|
||||
|
@ -345,7 +321,7 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
|||
|
||||
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 - (RegionBase + 13));
|
||||
}
|
||||
else {
|
||||
|
@ -359,20 +335,27 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
|||
*(ULONG *)&ZwXxxPtr[8] = (ULONG)(ULONG_PTR)SystemServiceAsm;
|
||||
*(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))
|
||||
goto finish;
|
||||
|
||||
if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, OldProtect, &OldProtect))
|
||||
if (!VirtualProtectEx64(hProcess, RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &OldProtect)) {
|
||||
SbieApi_Log(2303, L"win32k %d (1)", SyscallNum);
|
||||
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;
|
||||
|
@ -385,7 +368,6 @@ _FX BOOLEAN SbieDll_HookWoW64SysCalls()
|
|||
pos++;
|
||||
}
|
||||
|
||||
|
||||
finish:
|
||||
|
||||
if(syscall_data)
|
||||
|
@ -398,7 +380,44 @@ finish:
|
|||
|
||||
return ok;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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,6 +579,7 @@ _FX ULONG SbieDll_InjectLow(HANDLE hProcess, ULONG init_flags, BOOLEAN dup_drv_h
|
|||
//
|
||||
|
||||
#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;
|
||||
#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;
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
||||
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)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
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
|
||||
// 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,16 +432,9 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
|||
// jmp rax
|
||||
ZwXxxPtr[11] = 0xFF;
|
||||
ZwXxxPtr[12] = 0xE0;
|
||||
|
||||
chrome64Target = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegionBase = ZwXxxPtr;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
else {
|
||||
// bytes overwriten 14;
|
||||
|
||||
ZwXxxPtr[0] = 0x49; // mov r10, SyscallNumber
|
||||
ZwXxxPtr[1] = 0xC7;
|
||||
|
@ -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 {
|
||||
|
@ -462,12 +460,9 @@ _FX void InitSyscalls(SBIELOW_DATA *data, void * SystemService)
|
|||
}
|
||||
}
|
||||
#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] =
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)"
|
||||
|
||||
|
|
Loading…
Reference in New Issue