Skip to content

Commit

Permalink
1.15.5
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidXanatos committed Jan 16, 2025
1 parent 109bee2 commit 91b70a8
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 77 deletions.
1 change: 1 addition & 0 deletions Sandboxie/core/dll/dll.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ extern const WCHAR *Scm_CryptSvc;

extern BOOLEAN Dll_SbieTrace;
extern BOOLEAN Dll_ApiTrace;
extern BOOLEAN Dll_FileTrace;


//---------------------------------------------------------------------------
Expand Down
116 changes: 78 additions & 38 deletions Sandboxie/core/dll/dllhook.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ typedef struct _MODULE_HOOK {

LIST Dll_ModuleHooks;
CRITICAL_SECTION Dll_ModuleHooks_CritSec;
BOOLEAN Dll_HookTrace = FALSE;

#ifdef _M_ARM64EC
P_NtAllocateVirtualMemoryEx __sys_NtAllocateVirtualMemoryEx = NULL;
Expand All @@ -111,6 +112,8 @@ _FX void SbieDll_HookInit()
InitializeCriticalSection(&Dll_ModuleHooks_CritSec);
List_Init(&Dll_ModuleHooks);

Dll_HookTrace = SbieApi_QueryConfBool(NULL, L"HookTrace", FALSE);

#ifdef _M_ARM64EC
__sys_NtAllocateVirtualMemoryEx = (P_NtAllocateVirtualMemoryEx)GetProcAddress(Dll_Ntdll, "NtAllocateVirtualMemoryEx");
#endif
Expand Down Expand Up @@ -1055,25 +1058,14 @@ void* SbieDll_Hook_arm(

func = (UCHAR *)pbTarget;

RegionBase = &func[-8]; // -8 for hotpatch area if present
RegionSize = 24;
RegionBase = &func[0];
RegionSize = 16;

if (!VirtualProtect(RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &prot)) {

//
// if that fails just start at the exact offset and try again
// without the hot patch area which we don't use anyways
//

RegionBase = &func[0];
RegionSize = 16;

if (!VirtualProtect(RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &prot)) {
ULONG err = GetLastError();
SbieApi_Log(2303, _fmt2, SourceFuncName, 33, err);
func = NULL;
goto finish;
}
ULONG err = GetLastError();
SbieApi_Log(2303, _fmt2, SourceFuncName, 33, err);
func = NULL;
goto finish;
}

//
Expand Down Expand Up @@ -1145,7 +1137,7 @@ void* SbieDll_Hook_arm(
}

//
// restore protection and flush instruction cache
// restore protection and fluch instruction cache
//

VirtualProtect(RegionBase, RegionSize, prot, &dummy_prot);
Expand All @@ -1167,22 +1159,29 @@ void* SbieDll_Hook_arm(
// SbieDll_HookFunc
//---------------------------------------------------------------------------

#define HOOK_STAT_CHROME 0x00000001
#define HOOK_STAT_NO_FFS 0x00000002
#define HOOK_STAT_SKIPPED 0x00000004
#define HOOK_STAT_TRACE 0x00000100
#define HOOK_STAT_SYSCALL 0x00000200 // ARM64 EC only
#define HOOK_STAT_INTERESTING 0x000000FF

_FX void *SbieDll_HookFunc(
const char *SourceFuncName, void *SourceFunc, void *DetourFunc, HMODULE module)
const char *SourceFuncName, void *SourceFunc, void *DetourFunc, HMODULE module, DWORD* pHookStats)
{
//
// Chrome sandbox support
//

//void* OldSourceFunc = SourceFunc;
void* OldSourceFunc = SourceFunc;

SourceFunc = Hook_CheckChromeHook(SourceFunc);

//if (OldSourceFunc != SourceFunc) {
if (OldSourceFunc != SourceFunc) {
if (pHookStats) *pHookStats |= HOOK_STAT_CHROME;
// WCHAR* ModuleName = Trace_FindModuleByAddress((void*)module);
// DbgPrint("Found Chrome Hook on: %S!%s\r\n", ModuleName, SourceFuncName);
//}
}


#ifdef _M_ARM64EC
Expand All @@ -1195,12 +1194,14 @@ _FX void *SbieDll_HookFunc(
//
// Note: this mechanism is only available during initialization as
// at the end of Dll_Ordinal1 we dispose of the syscall/inject data area
// therefore any Nt function hooks must be set up from the get go
// there fore any Nt function hooks must be set up from the get go
//

extern ULONG* SbieApi_SyscallPtr;
if (module == Dll_Ntdll && *(USHORT*)&SourceFuncName[0] == 'tN' && SbieApi_SyscallPtr) {

if (pHookStats) *pHookStats |= HOOK_STAT_SYSCALL;

USHORT index = Hook_GetSysCallIndex(SourceFunc);
if (index != 0xFFFF) {

Expand All @@ -1225,7 +1226,10 @@ _FX void *SbieDll_HookFunc(
return SbieDll_Hook_arm(SourceFuncName, SourceFuncEC, DetourFunc, module);
}
else
SbieApi_Log(2303, _fmt1, SourceFuncName, 69);
{

if (pHookStats) *pHookStats |= HOOK_STAT_NO_FFS;
}
}

#endif
Expand All @@ -1245,19 +1249,14 @@ _FX void *SbieDll_HookFunc(
_FX void *SbieDll_Hook(
const char *SourceFuncName, void *SourceFunc, void *DetourFunc, HMODULE module)
{
if (SbieDll_FuncSkipHook(SourceFuncName))
return SourceFunc;

const WCHAR* ModuleName = NULL;
if (Dll_SbieTrace || Dll_ApiTrace) {
ModuleName = Trace_FindModuleByAddress((void*)module);
if (!ModuleName) ModuleName = L"unknown";
}
DWORD HookStats = 0;
void* func = NULL;

if (Dll_SbieTrace) {
WCHAR dbg[1024];
Sbie_snwprintf(dbg, 1024, L"Hooking%s: %s!%S\r\n", DetourFunc ? L"" : L" (trace)", ModuleName, SourceFuncName);
SbieApi_MonitorPutMsg(MONITOR_OTHER | MONITOR_TRACE, dbg);
if (SbieDll_FuncSkipHook(SourceFuncName)) {
HookStats = HOOK_STAT_SKIPPED;
func = SourceFunc;
goto finish;
}

//
Expand All @@ -1267,6 +1266,11 @@ _FX void *SbieDll_Hook(
PDWORD64 pDetourFunc = NULL;
if (Dll_ApiTrace) {

if(!DetourFunc)
HookStats |= HOOK_STAT_TRACE;

ModuleName = Trace_FindModuleByAddress((void*)module);

#ifdef _M_ARM64EC
MODULE_HOOK* mod_hook = SbieDll_GetModuleHookAndLock(module, (tzuk & 0xFFFFFF00) | 0xEC); // 0xEC - executable ARM64 Emulation Compatible
#else
Expand Down Expand Up @@ -1298,7 +1302,11 @@ _FX void *SbieDll_Hook(
*ip.pQ++ = (ULONG_PTR)DetourFunc;

// store full function name
int len = Sbie_snprintf(ip.pB, 96, "%S!%s", ModuleName, SourceFuncName);
int len;
if(ModuleName)
len = Sbie_snprintf(ip.pB, 96, "%S!%s", ModuleName, SourceFuncName);
else
len = Sbie_snprintf(ip.pB, 96, "%s", SourceFuncName);
pTrace->name = ip.pB + wcslen(ModuleName) + 1;
ip.pB += len + 1;

Expand Down Expand Up @@ -1345,10 +1353,10 @@ _FX void *SbieDll_Hook(
// install the hook
//

void* func = SbieDll_HookFunc(SourceFuncName, SourceFunc, DetourFunc, module);
func = SbieDll_HookFunc(SourceFuncName, SourceFunc, DetourFunc, module, &HookStats);

//
// when tracing API calls of functions that are not normally hooked,
// when tracing api calls of normaly not hooked functions,
// we did not have an initial detour and have passed NULL
// in this case we set the trampoline itself as final detour target
//
Expand All @@ -1358,6 +1366,38 @@ _FX void *SbieDll_Hook(
func = NULL;
}

finish:
if (Dll_HookTrace || (HookStats & HOOK_STAT_INTERESTING) || !func) {

if (!ModuleName)
ModuleName = Trace_FindModuleByAddress((void*)module);

WCHAR dbg[1024];
WCHAR* dbg_ptr = dbg;
size_t dbg_size = ARRAYSIZE(dbg);
int len = Sbie_snwprintf(dbg_ptr, dbg_size, L"%sHooking%s: %s!%S",
!func ? L"FAILED " : (HookStats & HOOK_STAT_SKIPPED) ? L"Skipped " : L"",
(HookStats & HOOK_STAT_TRACE) ? L" (trace)" : L"",
ModuleName ? ModuleName : L"unknown",
SourceFuncName);
dbg_ptr += len;
dbg_size -= len;
if (HookStats & HOOK_STAT_CHROME) {
len = Sbie_snwprintf(dbg_ptr, dbg_size, L" (Chrome Hooked)");
dbg_ptr += len;
dbg_size -= len;
}
#ifdef _M_ARM64EC
if (HookStats & HOOK_STAT_NO_FFS) {
len = Sbie_snwprintf(dbg_ptr, dbg_size, L" FFS Target not found, hoocked x86 code instead");
dbg_ptr += len;
dbg_size -= len;
}
#endif
wcscat(dbg_ptr, L"\r\n");
SbieApi_MonitorPutMsg(MONITOR_HOOK | MONITOR_TRACE, dbg);
}

return func;
}

Expand Down
2 changes: 2 additions & 0 deletions Sandboxie/core/dll/dllmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ BOOLEAN Dll_IsWow64 = FALSE;
#endif
#ifdef _M_ARM64EC
BOOLEAN Dll_IsArm64ec = FALSE;
void* Dll_xtajit64 = NULL;
#endif
#ifndef _WIN64
BOOLEAN Dll_IsXtAjit = FALSE;
Expand Down Expand Up @@ -815,6 +816,7 @@ _FX VOID Dll_Ordinal1(INJECT_DATA * inject)
#endif
#ifdef _M_ARM64EC
Dll_IsArm64ec = data->flags.is_arm64ec == 1; // x64 on arm64
Dll_xtajit64 = GetModuleHandle(L"xtajit64.dll");
#endif
#ifndef _WIN64
Dll_IsXtAjit = data->flags.is_xtajit == 1; // x86 on arm64
Expand Down
36 changes: 30 additions & 6 deletions Sandboxie/core/dll/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2498,7 +2498,31 @@ _FX NTSTATUS File_NtOpenFile(
ULONG ShareAccess,
ULONG OpenOptions)
{
NTSTATUS status = File_NtCreateFileImpl(
NTSTATUS status;

#ifdef _M_ARM64EC

//
// TODO: Fix-Me:
// In ARM64EC xtajit64.dll calls NtOpenFile and when this happens __chkstk_arm64ec
// crashes causing a stack overflow. To avoid this we call NtOpenFile directly.
//

extern UINT_PTR Dll_xtajit64;
ULONG_PTR pRetAddr = (ULONG_PTR)_ReturnAddress();

if (pRetAddr > Dll_xtajit64 && pRetAddr < Dll_xtajit64 + 0x180000) {

//SbieApi_Log(2301, L"NtOpenFile bypass on ARM64EC for %S",
// ObjectAttributes && ObjectAttributes->ObjectName && ObjectAttributes->ObjectName->Buffer ? ObjectAttributes->ObjectName->Buffer : L"[UNNAMED]");

status = __sys_NtOpenFile(
FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock,
ShareAccess, OpenOptions);
} else
#endif

status = File_NtCreateFileImpl(
FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock,
NULL, 0, ShareAccess, FILE_OPEN, OpenOptions, NULL, 0);

Expand Down Expand Up @@ -2923,7 +2947,7 @@ _FX NTSTATUS File_NtCreateFileImpl(
}
}

if (Dll_ApiTrace) {
if (Dll_ApiTrace || Dll_FileTrace) {
WCHAR trace_str[2048];
ULONG len = Sbie_snwprintf(trace_str, 2048, L"File_NtCreateFileImpl %s DesiredAccess=0x%08X CreateDisposition=0x%08X CreateOptions=0x%08X", TruePath, DesiredAccess, CreateDisposition, CreateOptions);
SbieApi_MonitorPut2Ex(MONITOR_APICALL | MONITOR_TRACE, len, trace_str, FALSE, FALSE);
Expand Down Expand Up @@ -4086,7 +4110,7 @@ _FX NTSTATUS File_NtCreateFileImpl(
status = GetExceptionCode();
}

if (Dll_ApiTrace) {
if (Dll_ApiTrace || Dll_FileTrace) {
WCHAR trace_str[2048];
ULONG len = Sbie_snwprintf(trace_str, 2048, L"File_NtCreateFileImpl status = 0x%08X", status);
SbieApi_MonitorPut2Ex(MONITOR_APICALL | MONITOR_TRACE, len, trace_str, FALSE, FALSE);
Expand Down Expand Up @@ -5590,7 +5614,7 @@ _FX NTSTATUS File_NtQueryFullAttributesFileImpl(
ObjectAttributes->RootDirectory, ObjectAttributes->ObjectName,
&TruePath, &CopyPath, &FileFlags);

if (Dll_ApiTrace) {
if (Dll_ApiTrace || Dll_FileTrace) {
WCHAR trace_str[2048];
ULONG len = Sbie_snwprintf(trace_str, 2048, L"File_NtQueryFullAttributesFileImpl %s", TruePath);
SbieApi_MonitorPut2Ex(MONITOR_APICALL | MONITOR_TRACE, len, trace_str, FALSE, FALSE);
Expand Down Expand Up @@ -5792,7 +5816,7 @@ _FX NTSTATUS File_NtQueryFullAttributesFileImpl(
status = STATUS_OBJECT_NAME_INVALID;
}

if (Dll_ApiTrace) {
if (Dll_ApiTrace || Dll_FileTrace) {
WCHAR trace_str[2048];
ULONG len = Sbie_snwprintf(trace_str, 2048, L"File_NtQueryFullAttributesFileImpl status = 0x%08X", status);
SbieApi_MonitorPut2Ex(MONITOR_APICALL | MONITOR_TRACE, len, trace_str, FALSE, FALSE);
Expand Down Expand Up @@ -6118,7 +6142,7 @@ _FX ULONG File_GetFinalPathNameByHandleW(
err = GetLastError();
}

if (Dll_ApiTrace) {
if (Dll_ApiTrace || Dll_FileTrace) {
WCHAR trace_str[2048];
ULONG len = Sbie_snwprintf(trace_str, 2048, L"File_GetFinalPathNameByHandleW %s", lpszFilePath);
SbieApi_MonitorPut2Ex(MONITOR_APICALL | MONITOR_TRACE, len, trace_str, FALSE, FALSE);
Expand Down
4 changes: 2 additions & 2 deletions Sandboxie/core/dll/file_del.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ _FX VOID File_AppendPathEntry_internal(HANDLE hPathsFile, const WCHAR* Path, ULO

// write the path
WCHAR* PathEx = TranslatePath ? TranslatePath(Path) : NULL;
NtWriteFile(hPathsFile, NULL, NULL, NULL, &IoStatusBlock, PathEx ? PathEx : Path, wcslen(PathEx ? PathEx : Path) * sizeof(WCHAR), NULL, NULL);
NtWriteFile(hPathsFile, NULL, NULL, NULL, &IoStatusBlock, PathEx ? PathEx : (WCHAR*)Path, wcslen(PathEx ? PathEx : Path) * sizeof(WCHAR), NULL, NULL);
if (PathEx) Dll_Free(PathEx);

// write the flags
Expand All @@ -427,7 +427,7 @@ _FX VOID File_AppendPathEntry_internal(HANDLE hPathsFile, const WCHAR* Path, ULO
NtWriteFile(hPathsFile, NULL, NULL, NULL, &IoStatusBlock, FlagStr, sizeof(WCHAR), NULL, NULL); // write |

WCHAR* RelocationEx = TranslatePath ? TranslatePath(Relocation) : NULL;
NtWriteFile(hPathsFile, NULL, NULL, NULL, &IoStatusBlock, RelocationEx ? RelocationEx : Relocation, wcslen(RelocationEx ? RelocationEx : Relocation) * sizeof(WCHAR), NULL, NULL);
NtWriteFile(hPathsFile, NULL, NULL, NULL, &IoStatusBlock, RelocationEx ? RelocationEx : (WCHAR*)Relocation, wcslen(RelocationEx ? RelocationEx : Relocation) * sizeof(WCHAR), NULL, NULL);
if (RelocationEx) Dll_Free(RelocationEx);
}

Expand Down
15 changes: 7 additions & 8 deletions Sandboxie/core/dll/gdi.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,13 +867,20 @@ _FX BOOLEAN Gdi_InitZero(HMODULE module)
// ntdll loader, but there are cases where this is not so.
//

#if defined(_M_ARM64) || defined(_M_ARM64EC)
GdiDllInitialize = Ldr_GetProcAddrNew(L"gdi32full.dll", L"GdiDllInitialize","GdiDllInitialize");
#else
GdiDllInitialize = Ldr_GetProcAddrNew(DllName_gdi32, L"GdiDllInitialize","GdiDllInitialize");
#endif

if (GdiDllInitialize == Saved_GdiDllInitialize)
return TRUE;

Saved_GdiDllInitialize = GdiDllInitialize;

#if defined(_M_ARM64) || defined(_M_ARM64EC)
Gdi_GdiDllInitialize = Gdi_GdiDllInitialize_Vista;
#else
if (Dll_OsBuild >= 6000)
Gdi_GdiDllInitialize = Gdi_GdiDllInitialize_Vista;

Expand All @@ -883,14 +890,6 @@ _FX BOOLEAN Gdi_InitZero(HMODULE module)

} else
Gdi_GdiDllInitialize = Gdi_GdiDllInitialize_XP;

#ifdef _M_ARM64EC

//
// set module -1 to not try to find the FFS sequence
//

module = (HMODULE)- 1;
#endif

SBIEDLL_HOOK(Gdi_,GdiDllInitialize);
Expand Down
1 change: 1 addition & 0 deletions Sandboxie/core/dll/guimsg.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2004-2020 Sandboxie Holdings, LLC
* Copyright 2023 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
Loading

0 comments on commit 91b70a8

Please sign in to comment.