From 9680b3f11c3e22565556029f6a245a845dbea5c2 Mon Sep 17 00:00:00 2001 From: DavidXanatos <3890945+DavidXanatos@users.noreply.github.com> Date: Sun, 16 Jul 2023 11:22:23 +0200 Subject: [PATCH] 1.10.1 --- CHANGELOG.md | 4 + Sandboxie/core/dll/dll.h | 4 +- Sandboxie/core/dll/file_dir.c | 19 +- Sandboxie/core/dll/file_recovery.c | 6 +- Sandboxie/core/dll/handle.c | 115 +++++++---- Sandboxie/core/dll/handle.h | 15 +- Sandboxie/core/dll/ipc.c | 312 ++++++++++++++++++++++++++++- Sandboxie/core/dll/key_merge.c | 10 +- Sandboxie/core/dll/scm_msi.c | 8 +- Sandboxie/core/dll/secure.c | 3 +- 10 files changed, 412 insertions(+), 84 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01c1e643..61cb0c2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - fixed "Disable Security Isolation" causes a game to stop playing audio [#2893](https://github.com/sandboxie-plus/Sandboxie/issues/2893) +- fixed NtQueryDirectoryObject not implemented [#2734](https://github.com/sandboxie-plus/Sandboxie/issues/2734) + +### Changed +- reworked Nt Object Handle handling diff --git a/Sandboxie/core/dll/dll.h b/Sandboxie/core/dll/dll.h index ae815e5e..e0f32d02 100644 --- a/Sandboxie/core/dll/dll.h +++ b/Sandboxie/core/dll/dll.h @@ -506,7 +506,7 @@ BOOLEAN File_IsBlockedNetParam(const WCHAR *BoxName); void File_GetSetDeviceMap(WCHAR *DeviceMap96); -void File_NotifyRecover(HANDLE FileHandle); +void File_NotifyRecover(HANDLE FileHandle, void* CloseParams); //--------------------------------------------------------------------------- // Functions (key) @@ -520,7 +520,7 @@ NTSTATUS Key_MarkDeletedAndClose(HANDLE KeyHandle); void Key_DiscardMergeByPath(const WCHAR *TruePath, BOOLEAN Recurse); -void Key_NtClose(HANDLE KeyHandle); +void Key_NtClose(HANDLE KeyHandle, void* CloseParams); HANDLE Key_GetTrueHandle(HANDLE KeyHandle, BOOLEAN *pIsOpenPath); diff --git a/Sandboxie/core/dll/file_dir.c b/Sandboxie/core/dll/file_dir.c index 5cba9c13..60f9f580 100644 --- a/Sandboxie/core/dll/file_dir.c +++ b/Sandboxie/core/dll/file_dir.c @@ -194,7 +194,7 @@ static NTSTATUS File_NtQueryVolumeInformationFile( NTSTATUS File_NtCloseImpl(HANDLE FileHandle); -VOID File_NtCloseDir(HANDLE FileHandle); +VOID File_NtCloseDir(HANDLE FileHandle, void* CloseParams); //--------------------------------------------------------------------------- // Variables @@ -484,7 +484,7 @@ _FX NTSTATUS File_Merge( } else { - Handle_UnRegisterCloseHandler(merge->handle, File_NtCloseDir); + Handle_UnRegisterHandler(merge->handle, File_NtCloseDir, NULL); List_Remove(&File_DirHandles, merge); File_MergeFree(merge); } @@ -528,7 +528,7 @@ _FX NTSTATUS File_Merge( } List_Insert_After(&File_DirHandles, NULL, merge); - Handle_RegisterCloseHandler(merge->handle, File_NtCloseDir); + Handle_RegisterHandler(merge->handle, File_NtCloseDir, NULL, FALSE); } // @@ -2267,8 +2267,6 @@ _FX NTSTATUS File_NtCloseImpl(HANDLE FileHandle) THREAD_DATA *TlsData = Dll_GetTlsData(&LastError); NTSTATUS status; - ULONG i; - P_CloseHandler CloseHandlers[MAX_CLOSE_HANDLERS]; BOOLEAN DeleteOnClose = FALSE; UNICODE_STRING uni; WCHAR *DeletePath = NULL; @@ -2308,13 +2306,7 @@ _FX NTSTATUS File_NtCloseImpl(HANDLE FileHandle) // and prepare the DeleteOnClose if its set // - if (Handle_FreeCloseHandler(FileHandle, &CloseHandlers[0], &DeleteOnClose)) { - - for (i = 0; i < MAX_CLOSE_HANDLERS; i++) { - if(CloseHandlers[i] != NULL) - CloseHandlers[i](FileHandle); - } - } + Handle_ExecuteCloseHandler(FileHandle, &DeleteOnClose); // // prepare delete disposition if set @@ -2397,7 +2389,7 @@ _FX NTSTATUS File_NtCloseImpl(HANDLE FileHandle) //--------------------------------------------------------------------------- -_FX VOID File_NtCloseDir(HANDLE FileHandle) +_FX VOID File_NtCloseDir(HANDLE FileHandle, void* CloseParams) { FILE_MERGE *merge; @@ -2407,7 +2399,6 @@ _FX VOID File_NtCloseDir(HANDLE FileHandle) while (merge) { FILE_MERGE *next = List_Next(merge); if (merge->handle == FileHandle) { - Handle_UnRegisterCloseHandler(merge->handle, File_NtCloseDir); List_Remove(&File_DirHandles, merge); File_MergeFree(merge); } diff --git a/Sandboxie/core/dll/file_recovery.c b/Sandboxie/core/dll/file_recovery.c index ec65f815..b83acc54 100644 --- a/Sandboxie/core/dll/file_recovery.c +++ b/Sandboxie/core/dll/file_recovery.c @@ -1,6 +1,6 @@ /* * Copyright 2004-2020 Sandboxie Holdings, LLC - * Copyright 2020-2022 David Xanatos, xanasoft.com + * Copyright 2020-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 @@ -348,7 +348,7 @@ _FX BOOLEAN File_RecordRecover(HANDLE FileHandle, const WCHAR *TruePath) //} if (IsRecoverable != FALSE) - Handle_RegisterCloseHandler(FileHandle, File_NotifyRecover); + Handle_RegisterHandler(FileHandle, File_NotifyRecover, NULL, TRUE); return IsRecoverable == TRUE; } @@ -359,7 +359,7 @@ _FX BOOLEAN File_RecordRecover(HANDLE FileHandle, const WCHAR *TruePath) //--------------------------------------------------------------------------- -_FX void File_NotifyRecover(HANDLE FileHandle) +_FX void File_NotifyRecover(HANDLE FileHandle, void* CloseParams) { THREAD_DATA *TlsData = Dll_GetTlsData(NULL); diff --git a/Sandboxie/core/dll/handle.c b/Sandboxie/core/dll/handle.c index 92c5fd5e..c356b028 100644 --- a/Sandboxie/core/dll/handle.c +++ b/Sandboxie/core/dll/handle.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 David Xanatos, xanasoft.com + * Copyright 2021-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 @@ -33,11 +33,24 @@ // Structures and Types //--------------------------------------------------------------------------- + +typedef struct _HANDLE_HANDLER +{ + LIST_ELEM list_elem; + + P_HandlerFunc Close; + void* Param; + + BOOL bPropagate; // incompatible with Param, todo: add duplicate handler + +} HANDLE_HANDLER; + + typedef struct _HANDLE_STATE { BOOLEAN DeleteOnClose; - P_CloseHandler CloseHandlers[MAX_CLOSE_HANDLERS]; - WCHAR* RelocationPath; + LIST CloseHandlers; + WCHAR* RelocationPath; } HANDLE_STATE; @@ -145,21 +158,17 @@ _FX WCHAR* Handle_GetRelocationPath(HANDLE FileHandle, ULONG ExtraLength) //--------------------------------------------------------------------------- -_FX BOOLEAN Handle_FreeCloseHandler(HANDLE FileHandle, P_CloseHandler* CloseHandlers, BOOLEAN* DeleteOnClose) +_FX VOID Handle_ExecuteCloseHandler(HANDLE FileHandle, BOOLEAN* DeleteOnClose) { - BOOLEAN HasCloseHandlers = FALSE; + LIST CloseHandlers; EnterCriticalSection(&Handle_StatusData_CritSec); HANDLE_STATE* state = (HANDLE_STATE*)map_get(&Handle_StatusData, FileHandle); if (state) { - HasCloseHandlers = TRUE; - - if(CloseHandlers) - memcpy(CloseHandlers, state->CloseHandlers, MAX_CLOSE_HANDLERS * sizeof(P_CloseHandler)); - if(DeleteOnClose) *DeleteOnClose = state->DeleteOnClose; - + *DeleteOnClose = state->DeleteOnClose; + CloseHandlers = state->CloseHandlers; if (state->RelocationPath) Dll_Free(state->RelocationPath); } @@ -167,22 +176,33 @@ _FX BOOLEAN Handle_FreeCloseHandler(HANDLE FileHandle, P_CloseHandler* CloseHand LeaveCriticalSection(&Handle_StatusData_CritSec); - return HasCloseHandlers; + // + // execute all close handlers + // + + if (state) { + while (1) { + HANDLE_HANDLER* handler = List_Head(&CloseHandlers); + if (!handler) + break; + handler->Close(FileHandle, handler->Param); + List_Remove(&CloseHandlers, handler); + Pool_Free(handler, sizeof(HANDLE_HANDLER)); + } + } } //--------------------------------------------------------------------------- -// Handle_RegisterCloseHandler +// Handle_RegisterHandler //--------------------------------------------------------------------------- -_FX BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler) +_FX BOOLEAN Handle_RegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void* Params, BOOL bPropagate) { if (!FileHandle || FileHandle == (HANDLE)-1) return FALSE; - ULONG i; - EnterCriticalSection(&Handle_StatusData_CritSec); HANDLE_STATE* state = map_get(&Handle_StatusData, FileHandle); @@ -190,19 +210,30 @@ _FX BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseH state = map_insert(&Handle_StatusData, FileHandle, NULL, sizeof(HANDLE_STATE)); } - for (i = 0; i < MAX_CLOSE_HANDLERS; i++) { - if (state->CloseHandlers[i] == CloseHandler) + HANDLE_HANDLER* handler = List_Head(&state->CloseHandlers); + while (handler) + { + if (handler->Close == CloseHandler) break; // already registered - if (state->CloseHandlers[i] == NULL) { - state->CloseHandlers[i] = CloseHandler; // set to empty slot - break; - } + handler = List_Next(handler); + } + + if (handler == NULL) + { + HANDLE_HANDLER* newNandler = Pool_Alloc(Dll_Pool, sizeof(HANDLE_HANDLER)); + memzero(&newNandler->list_elem, sizeof(LIST_ELEM)); + + newNandler->Close = CloseHandler; + newNandler->Param = Params; + newNandler->bPropagate = bPropagate; + + List_Insert_After(&state->CloseHandlers, NULL, newNandler); } LeaveCriticalSection(&Handle_StatusData_CritSec); - if (i == MAX_CLOSE_HANDLERS) { - SbieApi_Log(2301, L"No free CloseHandlers slot available"); + if (handler != NULL) { + //SbieApi_Log(2301, L"CloseHandlers already registered"); // todo return FALSE; } @@ -211,30 +242,31 @@ _FX BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseH //--------------------------------------------------------------------------- -// Handle_UnRegisterCloseHandler +// Handle_UnRegisterHandler //--------------------------------------------------------------------------- -_FX BOOLEAN Handle_UnRegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler) +_FX VOID Handle_UnRegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void** pParams) { - ULONG i = MAX_CLOSE_HANDLERS; - EnterCriticalSection(&Handle_StatusData_CritSec); HANDLE_STATE* state = map_get(&Handle_StatusData, FileHandle); if (state) { - for (i = 0; i < MAX_CLOSE_HANDLERS; i++) { - if (state->CloseHandlers[i] == CloseHandler) { - state->CloseHandlers[i] = NULL; // clear slot + HANDLE_HANDLER* handler = List_Head(&state->CloseHandlers); + while (handler) + { + if (handler->Close == CloseHandler) + { + if (pParams) pParams = handler->Param; + List_Remove(&state->CloseHandlers, handler); break; } + handler = List_Next(handler); } } LeaveCriticalSection(&Handle_StatusData_CritSec); - - return i != MAX_CLOSE_HANDLERS; } @@ -245,8 +277,6 @@ _FX BOOLEAN Handle_UnRegisterCloseHandler(HANDLE FileHandle, P_CloseHandler Clos _FX void Handle_SetupDuplicate(HANDLE OldFileHandle, HANDLE NewFileHandle) { - ULONG i; - EnterCriticalSection(&Handle_StatusData_CritSec); HANDLE_STATE* state = map_get(&Handle_StatusData, OldFileHandle); @@ -255,17 +285,16 @@ _FX void Handle_SetupDuplicate(HANDLE OldFileHandle, HANDLE NewFileHandle) if(state->RelocationPath) Handle_SetRelocationPath(NewFileHandle, state->RelocationPath); - // todo: add a flag to each CloseHandlers entry to indicate if it should be propagated or not - BOOLEAN found = FALSE; - for (i = 0; i < MAX_CLOSE_HANDLERS; i++) { - if (state->CloseHandlers[i] == File_NotifyRecover) { - found = TRUE; + HANDLE_HANDLER* handler = List_Head(&state->CloseHandlers); + while (handler) + { + if (handler->bPropagate) { + Handle_RegisterHandler(NewFileHandle, handler->Close, NULL, TRUE); break; } + handler = List_Next(handler); } - if(found) - Handle_RegisterCloseHandler(NewFileHandle, File_NotifyRecover); } LeaveCriticalSection(&Handle_StatusData_CritSec); -} +} \ No newline at end of file diff --git a/Sandboxie/core/dll/handle.h b/Sandboxie/core/dll/handle.h index 261aafbf..6babd518 100644 --- a/Sandboxie/core/dll/handle.h +++ b/Sandboxie/core/dll/handle.h @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 David Xanatos, xanasoft.com + * Copyright 2021-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 @@ -21,10 +21,11 @@ //--------------------------------------------------------------------------- -// Defines +// Structures and Types //--------------------------------------------------------------------------- -#define MAX_CLOSE_HANDLERS 4 + +typedef void(*P_HandlerFunc)(HANDLE handle, void* param); //--------------------------------------------------------------------------- @@ -32,19 +33,17 @@ //--------------------------------------------------------------------------- -typedef void(*P_CloseHandler)(HANDLE handle); - VOID Handle_SetDeleteOnClose(HANDLE FileHandle, BOOLEAN DeleteOnClose); -BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler); +BOOLEAN Handle_RegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void* Params, BOOL bPropagate); -BOOLEAN Handle_UnRegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler); +VOID Handle_UnRegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void** pParams); VOID Handle_SetRelocationPath(HANDLE FileHandle, WCHAR* RelocationPath); WCHAR* Handle_GetRelocationPath(HANDLE FileHandle, ULONG ExtraLength); -BOOLEAN Handle_FreeCloseHandler(HANDLE FileHandle, P_CloseHandler* CloseHandlers, BOOLEAN* DeleteOnClose); +VOID Handle_ExecuteCloseHandler(HANDLE FileHandle, BOOLEAN* DeleteOnClose); //--------------------------------------------------------------------------- diff --git a/Sandboxie/core/dll/ipc.c b/Sandboxie/core/dll/ipc.c index e3cd0a0c..e8d411ee 100644 --- a/Sandboxie/core/dll/ipc.c +++ b/Sandboxie/core/dll/ipc.c @@ -23,6 +23,7 @@ #include "dll.h" #include "obj.h" +#include "handle.h" #include #include "common/my_version.h" #include "core/svc/namedpipewire.h" @@ -39,6 +40,32 @@ : 0) +//--------------------------------------------------------------------------- +// Structures and Types +//--------------------------------------------------------------------------- + + +typedef struct _IPC_MERGE { + + LIST_ELEM list_elem; + + HANDLE handle; + + LIST objects; + +} IPC_MERGE; + + +typedef struct _IPC_MERGE_ENTRY +{ + LIST_ELEM list_elem; + + UNICODE_STRING Name; + UNICODE_STRING TypeName; + +} IPC_MERGE_ENTRY; + + //--------------------------------------------------------------------------- // Functions //--------------------------------------------------------------------------- @@ -356,6 +383,8 @@ LIST Ipc_DynamicPortNames; BOOLEAN RpcRt_IsDynamicPortOpen(const WCHAR* wszPortName); +static LIST Ipc_Handles; +static CRITICAL_SECTION Ipc_Handles_CritSec; //--------------------------------------------------------------------------- // IPC (other modules) @@ -374,6 +403,10 @@ _FX BOOLEAN Ipc_Init(void) { HMODULE module = Dll_Ntdll; + InitializeCriticalSection(&Ipc_Handles_CritSec); + + List_Init(&Ipc_Handles); + void *NtAlpcCreatePort; void *NtAlpcConnectPort; void *NtAlpcConnectPortEx; @@ -744,7 +777,7 @@ _FX NTSTATUS Ipc_GetName( name = Dll_GetTlsNameBuffer( TlsData, TRUE_NAME_BUFFER, length + objname_len); - if ((! objname_len) || (! *objname_buf)) { + /*if ((! objname_len) || (! *objname_buf)) { // // an object handle was specified, but the object name is an @@ -760,7 +793,7 @@ _FX NTSTATUS Ipc_GetName( return STATUS_SUCCESS; } - } + }*/ if (objname_len && *objname_buf == L'\\') { @@ -4071,6 +4104,152 @@ OpenTruePath: } +//--------------------------------------------------------------------------- +// Ipc_MergeFree +//--------------------------------------------------------------------------- + + +_FX void Ipc_MergeFree(IPC_MERGE *merge) +{ + while (1) { + IPC_MERGE_ENTRY *entry = List_Head(&merge->objects); + if (! entry) + break; + List_Remove(&merge->objects, entry); + Dll_Free(entry); + } + + Dll_Free(merge); +} + + +//--------------------------------------------------------------------------- +// Ipc_NtClose +//--------------------------------------------------------------------------- + + +_FX void Ipc_NtClose(HANDLE IpcHandle, void* CloseParams) +{ + IPC_MERGE *merge; + + EnterCriticalSection(&Ipc_Handles_CritSec); + + merge = List_Head(&Ipc_Handles); + while (merge) { + if (merge->handle == IpcHandle) { + + Handle_UnRegisterHandler(merge->handle, Ipc_NtClose, NULL); + List_Remove(&Ipc_Handles, merge); + Ipc_MergeFree(merge); + + break; + } + merge = List_Next(merge); + } + + LeaveCriticalSection(&Ipc_Handles_CritSec); +} + + +//--------------------------------------------------------------------------- +// Ipc_MergeDirectoryObject +//--------------------------------------------------------------------------- + + +_FX NTSTATUS Ipc_MergeDirectoryObject(IPC_MERGE *merge, WCHAR* path, BOOLEAN join) +{ + NTSTATUS status; + HANDLE directoryHandle; + OBJECT_ATTRIBUTES objattrs; + UNICODE_STRING objname; + + RtlInitUnicodeString(&objname, path); + + InitializeObjectAttributes( + &objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL); + + status = __sys_NtOpenDirectoryObject(&directoryHandle, DIRECTORY_QUERY, &objattrs); + if (!NT_SUCCESS(status)) + return status; + + ULONG bufferSize = 4096; + PVOID buffer = Dll_Alloc(bufferSize); + BOOLEAN firstTime = TRUE; + ULONG indexCounter = 0; + ULONG returnLength; + + while (1) + { + status = __sys_NtQueryDirectoryObject(directoryHandle, buffer, bufferSize, FALSE, firstTime, &indexCounter, &returnLength); + firstTime = FALSE; + + if (status == STATUS_NO_MORE_ENTRIES) + break; // done + if (!NT_SUCCESS(status)) + break; // error + + for (POBJECT_DIRECTORY_INFORMATION directoryInfo = buffer; directoryInfo->Name.Length != 0; directoryInfo++) + { + ULONG len = sizeof(IPC_MERGE_ENTRY) + (directoryInfo->Name.MaximumLength + directoryInfo->TypeName.MaximumLength) * sizeof(WCHAR); + + // + // when we are joining we remove the older entries when a duplicate is encountered + // + + if (join) { + + IPC_MERGE_ENTRY* entry = List_Head(&merge->objects); + while (entry) { + + if (entry->Name.Length == directoryInfo->Name.Length && memcmp(entry->Name.Buffer, directoryInfo->Name.Buffer, entry->Name.Length) == 0) + break; + + entry = List_Next(entry); + } + + if (entry) { + + if (entry->TypeName.Length == directoryInfo->TypeName.Length && memcmp(entry->TypeName.Buffer, directoryInfo->TypeName.Buffer, entry->TypeName.Length) == 0) + continue; // identical entry, nothign to do + + // same name but different type, remove old entry + List_Remove(&merge->objects, entry); + Dll_Free(entry); + } + } + + // + // add new entry + // + + IPC_MERGE_ENTRY* entry = Dll_Alloc(len); + WCHAR* ptr = entry + 1; + + entry->Name.Length = directoryInfo->Name.Length; + entry->Name.MaximumLength = directoryInfo->Name.MaximumLength; + entry->Name.Buffer = ptr; + memcpy(ptr, directoryInfo->Name.Buffer, directoryInfo->Name.MaximumLength); + ptr += directoryInfo->Name.MaximumLength / sizeof(WCHAR); + + entry->TypeName.Length = directoryInfo->TypeName.Length; + entry->TypeName.MaximumLength = directoryInfo->TypeName.MaximumLength; + entry->TypeName.Buffer = ptr; + memcpy(ptr, directoryInfo->TypeName.Buffer, directoryInfo->TypeName.MaximumLength); + //ptr += directoryInfo->TypeName.MaximumLength / sizeof(WCHAR); + + List_Insert_After(&merge->objects, NULL, entry); + } + } + + Dll_Free(buffer); + + extern P_NtClose __sys_NtClose; + __sys_NtClose(directoryHandle); + + return status; +} + + //--------------------------------------------------------------------------- // Ipc_NtQueryDirectoryObject //--------------------------------------------------------------------------- @@ -4085,8 +4264,133 @@ _FX NTSTATUS Ipc_NtQueryDirectoryObject( PULONG Context, PULONG ReturnLength) { - SbieApi_Log(2205, L"NtQueryDirectoryObject"); - return __sys_NtQueryDirectoryObject(DirectoryHandle, Buffer, Length, ReturnSingleEntry, RestartScan, Context, ReturnLength); + IPC_MERGE *merge; + + EnterCriticalSection(&Ipc_Handles_CritSec); + + merge = List_Head(&Ipc_Handles); + while (merge) { + + IPC_MERGE *next = List_Next(merge); + + if (merge->handle == DirectoryHandle) + break; + + merge = next; + } + + if (RestartScan && merge != NULL) { + + Handle_UnRegisterHandler(merge->handle, Ipc_NtClose, NULL); + List_Remove(&Ipc_Handles, merge); + Ipc_MergeFree(merge); + + merge = NULL; + } + + if (! merge) { + + merge = Dll_Alloc(sizeof(IPC_MERGE)); + memzero(merge, sizeof(IPC_MERGE)); + + merge->handle = DirectoryHandle; + + List_Insert_Before(&Ipc_Handles, NULL, merge); + Handle_RegisterHandler(merge->handle, Ipc_NtClose, NULL, FALSE); + + WCHAR *TruePath; + WCHAR *CopyPath; + NTSTATUS status = Ipc_GetName(DirectoryHandle, NULL, &TruePath, &CopyPath, NULL); + + if (!NT_SUCCESS(status)) + return status; + + Ipc_MergeDirectoryObject(merge, TruePath, FALSE); + + ULONG len = wcslen(CopyPath); // fix root copy path, remove tailing '\\' + if (CopyPath[len - 1] == L'\\') CopyPath[len - 1] = 0; + + Ipc_MergeDirectoryObject(merge, CopyPath, TRUE); + } + + // + // goto index, for better performacne we could cache indexes + // + + IPC_MERGE_ENTRY* entry = List_Head(&merge->objects); + + ULONG indexCounter = 0; + if (Context) { + for (; entry && indexCounter < *Context; indexCounter++) + entry = List_Next(entry); + } + if (!entry) + return STATUS_NO_MORE_ENTRIES; + + // + // count the buffer space + // + + ULONG CountToGo = 0; + ULONG TotalLength = sizeof(OBJECT_DIRECTORY_INFORMATION); + for (IPC_MERGE_ENTRY* cur = entry; cur; cur = List_Next(cur)) { + + ULONG len = sizeof(OBJECT_DIRECTORY_INFORMATION) + (cur->Name.MaximumLength + cur->TypeName.MaximumLength) * sizeof(WCHAR); + + if (TotalLength + len > Length) + break; // not enough space for this entry + + CountToGo++; + TotalLength += len; + + if (ReturnSingleEntry) + break; + } + + // + // fill output buffer + // + + POBJECT_DIRECTORY_INFORMATION directoryInfo = Buffer; + WCHAR* ptr = directoryInfo + CountToGo + 1; + + ULONG EndIndex = indexCounter + CountToGo; + for (; entry && indexCounter < EndIndex; indexCounter++) { + + directoryInfo->Name.Length = entry->Name.Length; + directoryInfo->Name.MaximumLength = entry->Name.MaximumLength; + directoryInfo->Name.Buffer = ptr; + memcpy(ptr, entry->Name.Buffer, entry->Name.MaximumLength); + ptr += directoryInfo->Name.MaximumLength / sizeof(WCHAR); + + directoryInfo->TypeName.Length = entry->TypeName.Length; + directoryInfo->TypeName.MaximumLength = entry->TypeName.MaximumLength; + directoryInfo->TypeName.Buffer = ptr; + memcpy(ptr, entry->TypeName.Buffer, entry->TypeName.MaximumLength); + ptr += directoryInfo->TypeName.MaximumLength / sizeof(WCHAR); + + directoryInfo++; + + entry = List_Next(entry); + } + + // + // terminate listing with an empty entry + // + + directoryInfo->Name.Length = directoryInfo->TypeName.Length = 0; + directoryInfo->Name.MaximumLength = directoryInfo->TypeName.MaximumLength = 0; + directoryInfo->Name.Buffer = directoryInfo->TypeName.Buffer = NULL; + + // + // set return values + // + + if (ReturnLength) *ReturnLength = TotalLength; + if (Context) *Context = indexCounter; + if (indexCounter < (ULONG)merge->objects.count) + return STATUS_MORE_ENTRIES; + return STATUS_SUCCESS; } diff --git a/Sandboxie/core/dll/key_merge.c b/Sandboxie/core/dll/key_merge.c index e8257351..0f05c778 100644 --- a/Sandboxie/core/dll/key_merge.c +++ b/Sandboxie/core/dll/key_merge.c @@ -1,6 +1,6 @@ /* * Copyright 2004-2020 Sandboxie Holdings, LLC - * Copyright 2021-2022 David Xanatos, xanasoft.com + * Copyright 2021-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 @@ -206,7 +206,7 @@ _FX NTSTATUS Key_Merge( // if we got here, we need to discard the stale entry // - Handle_UnRegisterCloseHandler(merge->handle, Key_NtClose); + Handle_UnRegisterHandler(merge->handle, Key_NtClose, NULL); List_Remove(&Key_Handles, merge); Key_MergeFree(merge, TRUE); @@ -234,7 +234,7 @@ _FX NTSTATUS Key_Merge( memcpy(merge->name, TruePath, TruePath_len + sizeof(WCHAR)); List_Insert_Before(&Key_Handles, NULL, merge); - Handle_RegisterCloseHandler(merge->handle, Key_NtClose); + Handle_RegisterHandler(merge->handle, Key_NtClose, NULL, FALSE); } // @@ -1557,7 +1557,7 @@ _FX void Key_DiscardMergeByPath(const WCHAR *TruePath, BOOLEAN Recurse) } } - Handle_UnRegisterCloseHandler(merge->handle, Key_NtClose); + Handle_UnRegisterHandler(merge->handle, Key_NtClose, NULL); List_Remove(&Key_Handles, merge); Key_MergeFree(merge, TRUE); } @@ -1605,7 +1605,7 @@ _FX void Key_DiscardMergeByHandle( //--------------------------------------------------------------------------- -_FX void Key_NtClose(HANDLE KeyHandle) +_FX void Key_NtClose(HANDLE KeyHandle, void* CloseParams) { KEY_MERGE *merge; diff --git a/Sandboxie/core/dll/scm_msi.c b/Sandboxie/core/dll/scm_msi.c index 3a2dbfbb..c17025b6 100644 --- a/Sandboxie/core/dll/scm_msi.c +++ b/Sandboxie/core/dll/scm_msi.c @@ -1,6 +1,6 @@ /* * Copyright 2004-2020 Sandboxie Holdings, LLC - * Copyright 2020-2021 David Xanatos, xanasoft.com + * Copyright 2020-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 @@ -219,7 +219,7 @@ _FX HANDLE Scm_CreateWaitableTimerW( //--------------------------------------------------------------------------- -_FX VOID Scm_TokenCloseHandler(HANDLE Handle) +_FX VOID Scm_TokenCloseHandler(HANDLE Handle, void* CloseParams) { THREAD_DATA *TlsData = Dll_GetTlsData(NULL); @@ -241,7 +241,7 @@ _FX BOOL Scm_OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE if (NT_SUCCESS(status) && ProcessHandle == GetCurrentProcess()) { - Handle_RegisterCloseHandler(*phTokenOut, Scm_TokenCloseHandler); + Handle_RegisterHandler(*phTokenOut, Scm_TokenCloseHandler, NULL, FALSE); TlsData->scm_last_own_token = *phTokenOut; } @@ -262,7 +262,7 @@ _FX BOOL Scm_OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL Open if (NT_SUCCESS(status) && ThreadHandle == GetCurrentThread()) { - Handle_RegisterCloseHandler(*phTokenOut, Scm_TokenCloseHandler); + Handle_RegisterHandler(*phTokenOut, Scm_TokenCloseHandler, NULL, FALSE); TlsData->scm_last_own_token = *phTokenOut; } diff --git a/Sandboxie/core/dll/secure.c b/Sandboxie/core/dll/secure.c index 35b572c2..48a33138 100644 --- a/Sandboxie/core/dll/secure.c +++ b/Sandboxie/core/dll/secure.c @@ -1,5 +1,6 @@ /* * Copyright 2004-2020 Sandboxie Holdings, LLC + * Copyright 2020-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 @@ -738,7 +739,7 @@ _FX NTSTATUS Secure_NtDuplicateObject( } if (SourceHandle) - Key_NtClose(SourceHandle); + Key_NtClose(SourceHandle, NULL); } //