From 55832bd1147e252d3d81857e577f07218c0a7749 Mon Sep 17 00:00:00 2001 From: DavidXanatos Date: Sat, 4 Jul 2020 12:07:36 +0200 Subject: [PATCH] Build 0.3 / 5.42 --- CHANGELOG.md | 43 +++ Sandboxie/apps/control/AboutDialog.cpp | 4 +- Sandboxie/apps/control/InitWait.cpp | 2 +- Sandboxie/apps/control/MessageDialog.cpp | 3 +- Sandboxie/apps/control/SbieControl.rc | Bin 70118 -> 70414 bytes Sandboxie/apps/control/resource.h | 19 +- Sandboxie/common/my_version.h | 11 +- Sandboxie/common/win32_ntddk.h | 110 +++++- Sandboxie/core/dll/com.c | 2 + Sandboxie/core/dll/dllmain.c | 12 +- Sandboxie/core/dll/ipc_start.c | 13 +- Sandboxie/core/dll/proc.c | 25 ++ Sandboxie/core/dll/sbieapi.c | 2 + Sandboxie/core/dll/sbieapi.h | 1 + Sandboxie/core/dll/sysinfo.c | 69 +++- Sandboxie/core/drv/api.c | 19 +- Sandboxie/core/drv/api.h | 3 +- Sandboxie/core/drv/api_defs.h | 1 + Sandboxie/core/drv/driver.c | 4 +- Sandboxie/core/drv/file.c | 21 +- Sandboxie/core/drv/file_flt.c | 6 +- Sandboxie/core/drv/gui.c | 2 +- Sandboxie/core/drv/gui_xp.c | 4 +- Sandboxie/core/drv/ipc.c | 7 +- Sandboxie/core/drv/ipc_port.c | 8 +- Sandboxie/core/drv/key.c | 8 +- Sandboxie/core/drv/key_flt.c | 76 +++- Sandboxie/core/drv/log.c | 49 ++- Sandboxie/core/drv/log.h | 27 +- Sandboxie/core/drv/process.c | 21 +- Sandboxie/core/drv/process_api.c | 19 +- Sandboxie/core/drv/process_force.c | 2 +- Sandboxie/core/drv/process_low.c | 6 +- Sandboxie/core/drv/process_util.c | 2 +- Sandboxie/core/drv/syscall_open.c | 2 +- Sandboxie/core/drv/thread.c | 3 +- Sandboxie/core/drv/token.c | 33 +- Sandboxie/core/svc/DriverAssistLog.cpp | 3 +- Sandboxie/core/svc/DriverAssistStart.cpp | 2 +- Sandboxie/core/svc/ProcessServer.cpp | 47 ++- Sandboxie/core/svc/ProcessServer.h | 4 +- Sandboxie/core/svc/sbieiniserver.cpp | 2 +- Sandboxie/core/svc/serviceserver.cpp | 8 +- Sandboxie/core/svc/serviceserver.h | 5 +- Sandboxie/core/svc/serviceserver2.cpp | 155 ++++++-- SandboxiePlus/MiscHelpers/Common/PanelView.h | 10 +- .../QSbieAPI/Sandboxie/BoxBorder.cpp | 346 ++++++++++++++++++ SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.h | 46 +++ .../QSbieAPI/Sandboxie/BoxedProcess.cpp | 5 + .../QSbieAPI/Sandboxie/BoxedProcess.h | 2 + SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp | 14 +- SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h | 4 + SandboxiePlus/QSbieAPI/SbieAPI.cpp | 95 +++-- SandboxiePlus/QSbieAPI/SbieAPI.h | 19 +- SandboxiePlus/QSbieAPI/SbieUtils.cpp | 26 +- SandboxiePlus/SandMan/ApiLog.cpp | 25 +- SandboxiePlus/SandMan/ApiLog.h | 34 +- SandboxiePlus/SandMan/Models/ApiMonModel.cpp | 130 +++++++ SandboxiePlus/SandMan/Models/ApiMonModel.h | 40 ++ SandboxiePlus/SandMan/Models/ResMonModel.cpp | 4 +- SandboxiePlus/SandMan/Models/SbieModel.cpp | 19 +- SandboxiePlus/SandMan/Models/SbieModel.h | 11 +- SandboxiePlus/SandMan/SandMan.cpp | 110 +++--- SandboxiePlus/SandMan/SandMan.h | 15 +- SandboxiePlus/SandMan/SbiePlusAPI.cpp | 100 ++++- SandboxiePlus/SandMan/SbiePlusAPI.h | 26 +- SandboxiePlus/SandMan/Views/SbieView.cpp | 78 +++- SandboxiePlus/SandMan/Views/SbieView.h | 8 + SandboxiePlus/SandMan/main.cpp | 2 +- 69 files changed, 1693 insertions(+), 341 deletions(-) create mode 100644 SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.cpp create mode 100644 SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.h create mode 100644 SandboxiePlus/SandMan/Models/ApiMonModel.cpp create mode 100644 SandboxiePlus/SandMan/Models/ApiMonModel.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 332ca724e2..01f2e1bd54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,49 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [0.2.5 / 5.42] - 2020-07-04 + +### Added +- API_QUERY_PROCESS_INFO can be now used to get the original process token of sandboxed processes +-- Note: this capability is used by TaskExplorer to allow inspecting sandbox internal tokens +- Added option "KeepTokenIntegrity=y" to make the sbie token keep its initial integrity level (debug option) +-- Note: Do NOT USE Debug Options if you dont know their security implications (!) +- Added process id to log messages very usefull for debugging +- Added finder to resource log +- Added option to hide host processes "HideHostProcess=[name]" +-- Note: Sbie hides by default processes from other boxes, this behavioure can now be controlled with "HideOtherBoxes=n" +- Sandboxed RpcSs and DcomLaunch can now be run as system with the option "ProtectRpcSs=y" howeever tht breaks sandboxed explorer and other +- BuiltIn Clsid whitelist can now be disabled with "OpenDefaultClsid=n" +- Processes can be now terminated with the del key, and require a confirmation +- Added sandboxed window border display to SandMan.exe +- Added notification for sbie log messages +- Added Sandbox Presets sub menu allowing to quickly change some settings +-- Enable/Disable API logging, logapi_dll's are now distributed with SbiePlus +-- And other: Drop admin rights; Block/Allow internet access; Block/Allow access to files on te network +- Added more info to the sandbox status column +- Added path column to SbieModel +- Added info tooltips in SbieView + +### Changed +- Reworked ApiLog, added pid and pid filter +- Auto config reload on in change is now delayed by 500ms to not reload multiple times on incremental changes +- Sandbox names now replace "_" witn " " for display allowing to use names that are build of separated words + +### Fixed +- added mising PreferExternalManifest itialization to portable mode +- fixed permission issues with sandboxed system processes +-- Note: you can use "ExposeBoxedSystem=y" for the old behaviour (debug option) +- fixed missing SCM access check for sandboxed services +-- Note: to disable the access check use "UnrestrictedSCM=y" (debug option) +- fixed missing initialization in serviceserver that caused sandboxed programs to crash when querying service status +- fixed many bugs that caused the SbieDrv.sys to BSOD when run with MSFT Driver Verifier active +-- 0xF6 in GetThreadTokenOwnerPid and File_Api_Rename +-- missing non optional parameter for FltGetFileNameInformation in File_PreOperation +-- 0xE3 in Key_StoreValue and Key_PreDataInject + + + ## [0.2.2 / 5.41.2] - 2020-06-19 ### Added diff --git a/Sandboxie/apps/control/AboutDialog.cpp b/Sandboxie/apps/control/AboutDialog.cpp index 5c53d3bf77..3a04df8b10 100644 --- a/Sandboxie/apps/control/AboutDialog.cpp +++ b/Sandboxie/apps/control/AboutDialog.cpp @@ -143,7 +143,7 @@ BOOL CAboutDialog::OnInitDialog() U_PDF = L' '; } text.Format(L"%S %c(%d-bit)%c", - MY_VERSION_STRING_EX, U_LRO, _bitness, U_PDF); + MY_VERSION_STRING, U_LRO, _bitness, U_PDF); CString ver = CMyMsg(MSG_3302, text); GetDlgItem(ID_ABOUT_VERSION)->SetWindowText(ver); @@ -152,7 +152,7 @@ BOOL CAboutDialog::OnInitDialog() // // - text.Format(L"%S", MY_COPYRIGHT_STRING); + text.Format(L"%S\r\n%S", MY_COPYRIGHT_STRING, MY_COPYRIGHT_STRING_OLD); GetDlgItem(ID_ABOUT_COPYRIGHT)->SetWindowText(text); GetDlgItem(IDOK)->SetWindowText(CMyMsg(MSG_3001)); diff --git a/Sandboxie/apps/control/InitWait.cpp b/Sandboxie/apps/control/InitWait.cpp index b4ebc865a8..eaff347663 100644 --- a/Sandboxie/apps/control/InitWait.cpp +++ b/Sandboxie/apps/control/InitWait.cpp @@ -73,7 +73,7 @@ CInitWait::CInitWait(CWinApp *myApp) m_pMenu = NULL; - m_app_ver.Format(L"%S", MY_VERSION_STRING); + m_app_ver.Format(L"%S", MY_VERSION_COMPAT); m_svc_ver = L"?"; m_drv_ver = L"?"; diff --git a/Sandboxie/apps/control/MessageDialog.cpp b/Sandboxie/apps/control/MessageDialog.cpp index d8a308a26a..2d07abb913 100644 --- a/Sandboxie/apps/control/MessageDialog.cpp +++ b/Sandboxie/apps/control/MessageDialog.cpp @@ -254,7 +254,8 @@ void CMessageDialog::OnTimer() ULONG len = m_buf_len; ULONG message_number = m_last_message_number; ULONG code = -1; - LONG status = SbieApi_GetMessage(&message_number, CMyApp::m_session_id, &code, m_buf, len); + ULONG pid = 0; + LONG status = SbieApi_GetMessage(&message_number, CMyApp::m_session_id, &code, &pid, m_buf, len); if (status != 0) break; // error or no more entries diff --git a/Sandboxie/apps/control/SbieControl.rc b/Sandboxie/apps/control/SbieControl.rc index 96c67ec15f5fabdd19ec8f22506d6bc12b70dc02..56163a592e4e75252bbf1b9b94436768d3008a7a 100644 GIT binary patch delta 122 zcmaF1n5AzS%Z7W7llxqkY)*5kW1QTP%`=(LC1LWjGXj$r6l+bMP{XnLoJ&O8A delta 71 zcmV-N0J#5-rUd4r1hC#glZfYZvu;9?0h1t1DwA-oER!%p43k7eC<8G7Fq0olE0e%y dFte;gT85SI0R*!K%kn~(whaLqw_XncumdYe8|451 diff --git a/Sandboxie/apps/control/resource.h b/Sandboxie/apps/control/resource.h index 9bc59de7d1..686ba1ce46 100644 --- a/Sandboxie/apps/control/resource.h +++ b/Sandboxie/apps/control/resource.h @@ -1,20 +1,3 @@ -/* -* Copyright 2004-2020 Sandboxie Holdings, LLC -* -* 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 -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ - //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by SbieControl.rc @@ -264,7 +247,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40013 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 103 diff --git a/Sandboxie/common/my_version.h b/Sandboxie/common/my_version.h index e9ecd49afa..73140ed22c 100644 --- a/Sandboxie/common/my_version.h +++ b/Sandboxie/common/my_version.h @@ -20,9 +20,9 @@ #ifndef _MY_VERSION_H #define _MY_VERSION_H -#define MY_VERSION_BINARY 5,41 -#define MY_VERSION_STRING "5.41" -#define MY_VERSION_STRING_EX "5.41.2" +#define MY_VERSION_BINARY 5,42,0 +#define MY_VERSION_STRING "5.42.0" +#define MY_VERSION_COMPAT "5.42" // These #defines are used by either Resource Compiler, or by NSIC installer #define SBIE_INSTALLER_PATH "..\\Bin\\" @@ -30,8 +30,9 @@ #define SBIE_INSTALLER_PATH_64 "..\\Bin\\x64\\SandboxieInstall64.exe" #define MY_PRODUCT_NAME_STRING "Sandboxie" -#define MY_COMPANY_NAME_STRING "Sandboxie Holdings, LLC" -#define MY_COPYRIGHT_STRING "Copyright © 2004-2020 by Sandboxie Holdings, LLC" +#define MY_COMPANY_NAME_STRING "xanasoft.com" +#define MY_COPYRIGHT_STRING "Copyright © 2020 by David Xanatos (xanasoft.com)" +#define MY_COPYRIGHT_STRING_OLD "Copyright © 2004-2020 by Sandboxie Holdings, LLC" #define SANDBOXIE L"Sandboxie" #define SBIE L"SBIE" diff --git a/Sandboxie/common/win32_ntddk.h b/Sandboxie/common/win32_ntddk.h index 03378c0b54..db9b820412 100644 --- a/Sandboxie/common/win32_ntddk.h +++ b/Sandboxie/common/win32_ntddk.h @@ -1367,6 +1367,113 @@ typedef enum _SYSTEM_INFORMATION_CLASS { SystemProcessorMicrocodeUpdateInformation, SystemProcessorBrandString, SystemVirtualAddressInformation, + SystemLogicalProcessorAndGroupInformation, + SystemProcessorCycleTimeInformation, + SystemStoreInformation, + SystemRegistryAppendString, + SystemAitSamplingValue, + SystemVhdBootInformation, + SystemCpuQuotaInformation, + SystemNativeBasicInformation, + SystemErrorPortTimeouts, + SystemLowPriorityIoInformation, + SystemTpmBootEntropyInformation, + SystemVerifierCountersInformation, + SystemPagedPoolInformationEx, + SystemSystemPtesInformationEx, + SystemNodeDistanceInformation, + SystemAcpiAuditInformation, + SystemBasicPerformanceInformation, + SystemQueryPerformanceCounterInformation, + SystemSessionBigPoolInformation, + SystemBootGraphicsInformation, + SystemScrubPhysicalMemoryInformation, + SystemBadPageInformation, + SystemProcessorProfileControlArea, + SystemCombinePhysicalMemoryInformation, + SystemEntropyInterruptTimingInformation, + SystemConsoleInformation, + SystemPlatformBinaryInformation, + SystemPolicyInformation, + SystemHypervisorProcessorCountInformation, + SystemDeviceDataInformation, + SystemDeviceDataEnumerationInformation, + SystemMemoryTopologyInformation, + SystemMemoryChannelInformation, + SystemBootLogoInformation, + SystemProcessorPerformanceInformationEx, + SystemCriticalProcessErrorLogInformation, + SystemSecureBootPolicyInformation, + SystemPageFileInformationEx, + SystemSecureBootInformation, + SystemEntropyInterruptTimingRawInformation, + SystemPortableWorkspaceEfiLauncherInformation, + SystemFullProcessInformation, + SystemKernelDebuggerInformationEx, + SystemBootMetadataInformation, + SystemSoftRebootInformation, + SystemElamCertificateInformation, + SystemOfflineDumpConfigInformation, + SystemProcessorFeaturesInformation, + SystemRegistryReconciliationInformation, + SystemEdidInformation, + SystemManufacturingInformation, + SystemEnergyEstimationConfigInformation, + SystemHypervisorDetailInformation, + SystemProcessorCycleStatsInformation, + SystemVmGenerationCountInformation, + SystemTrustedPlatformModuleInformation, + SystemKernelDebuggerFlags, + SystemCodeIntegrityPolicyInformation, + SystemIsolatedUserModeInformation, + SystemHardwareSecurityTestInterfaceResultsInformation, + SystemSingleModuleInformation, + SystemAllowedCpuSetsInformation, + SystemVsmProtectionInformation, + SystemInterruptCpuSetsInformation, + SystemSecureBootPolicyFullInformation, + SystemCodeIntegrityPolicyFullInformation, + SystemAffinitizedInterruptProcessorInformation, + SystemRootSiloInformation, + SystemCpuSetInformation, + SystemCpuSetTagInformation, + SystemWin32WerStartCallout, + SystemSecureKernelProfileInformation, + SystemCodeIntegrityPlatformManifestInformation, + SystemInterruptSteeringInformation, + SystemSupportedProcessorArchitectures, + SystemMemoryUsageInformation, + SystemCodeIntegrityCertificateInformation, + SystemPhysicalMemoryInformation, + SystemControlFlowTransition, + SystemKernelDebuggingAllowed, + SystemActivityModerationExeState, + SystemActivityModerationUserSettings, + SystemCodeIntegrityPoliciesFullInformation, + SystemCodeIntegrityUnlockInformation, + SystemIntegrityQuotaInformation, + SystemFlushInformation, + SystemProcessorIdleMaskInformation, + SystemSecureDumpEncryptionInformation, + SystemWriteConstraintInformation, + SystemKernelVaShadowInformation, + SystemHypervisorSharedPageInformation, + SystemFirmwareBootPerformanceInformation, + SystemCodeIntegrityVerificationInformation, + SystemFirmwarePartitionInformation, + SystemSpeculationControlInformation, + SystemDmaGuardPolicyInformation, + SystemEnclaveLaunchControlInformation, + SystemWorkloadAllowedCpuSetsInformation, + SystemCodeIntegrityUnlockModeInformation, + SystemLeapSecondInformation, + SystemFlags2Information, + SystemSecurityModelInformation, + SystemCodeIntegritySyntheticCacheInformation, + SystemFeatureConfigurationInformation, + SystemFeatureConfigurationSectionInformation, + SystemFeatureUsageSubscriptionInformation, + SystemSecureSpeculationControlInformation, MaxSystemInfoClass } SYSTEM_INFORMATION_CLASS; @@ -1405,7 +1512,8 @@ typedef struct _SYSTEM_MODULE_INFORMATION { typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; BYTE Reserved1[52]; - PVOID Reserved2[3]; + UNICODE_STRING ImageName; + PVOID Reserved2[1]; HANDLE UniqueProcessId; HANDLE InheritedFromProcessId; ULONG HandleCount; diff --git a/Sandboxie/core/dll/com.c b/Sandboxie/core/dll/com.c index 2fa95356c5..90703e2f80 100644 --- a/Sandboxie/core/dll/com.c +++ b/Sandboxie/core/dll/com.c @@ -305,6 +305,7 @@ _FX BOOLEAN SbieDll_IsOpenClsid( // check against list of built-in CLSID exclusions // + if (SbieApi_QueryConfBool(BoxName, L"OpenDefaultClsid", TRUE)) if (memcmp(rclsid, &CLSID_WinMgmt, sizeof(GUID)) == 0 || memcmp(rclsid, &CLSID_NetworkListManager, sizeof(GUID)) == 0 || memcmp(rclsid, &CLSID_ShellServiceHostBrokerProvider, sizeof(GUID)) == 0 || @@ -408,6 +409,7 @@ _FX BOOLEAN SbieDll_IsOpenClsid( } } + if (SbieApi_QueryConfBool(BoxName, L"OpenDefaultClsid", TRUE)) if (Com_IsFirewallClsid(rclsid, BoxName)) return TRUE; diff --git a/Sandboxie/core/dll/dllmain.c b/Sandboxie/core/dll/dllmain.c index 92125cea34..c249af60da 100644 --- a/Sandboxie/core/dll/dllmain.c +++ b/Sandboxie/core/dll/dllmain.c @@ -87,7 +87,7 @@ ULONG Dll_Windows = 0; CRITICAL_SECTION VT_CriticalSection; #endif -const UCHAR *SbieDll_Version = MY_VERSION_STRING; +const UCHAR *SbieDll_Version = MY_VERSION_COMPAT; //extern ULONG64 __security_cookie = 0; @@ -389,11 +389,11 @@ _FX void Dll_InitInjected(void) if (! Dll_RestrictedToken) CustomizeSandbox(); - /*while (! IsDebuggerPresent()) { - OutputDebugString(L"BREAK\n"); - Sleep(500); - } - __debugbreak();*/ + /*while (! IsDebuggerPresent()) { + OutputDebugString(L"BREAK\n"); + Sleep(500); + } + __debugbreak();*/ /*if (_wcsicmp(Dll_ImageName, L"iexplore.exe") == 0) { WCHAR *cmd = GetCommandLine(); diff --git a/Sandboxie/core/dll/ipc_start.c b/Sandboxie/core/dll/ipc_start.c index 81acb87df9..a8222ca5de 100644 --- a/Sandboxie/core/dll/ipc_start.c +++ b/Sandboxie/core/dll/ipc_start.c @@ -171,8 +171,17 @@ _FX BOOLEAN Ipc_StartServer(const WCHAR *TruePath, BOOLEAN Async) WCHAR *fullpath = Dll_AllocTemp(512 * sizeof(WCHAR)); Sbie_swprintf(fullpath, L"\"%s\\%s\"", homedir, program); - if (! SbieDll_RunSandboxed( - L"*THREAD*", fullpath, homedir, 0, &si, &pi)) + // + // Note: many proesses started by DcomLaunch must be started as user this is currently a bit broken, + // see Proc_CreateProcessInternalW_RS5 so for successfull operation in most cases we can't run RpcSs with a system token + // Fix-Me: fix Proc_CreateProcessInternalW_RS5 and make prtected RpcSs and subsequently DcomLaunch the deault + // + // Note: ServiceServer::CanAccessSCM has a special case to permit DcomLaunch to start services without being system + // + const WCHAR* box_name = SbieApi_QueryConfBool(NULL, L"ProtectRpcSs", FALSE) ? L"*SYSTEM*" : L"*THREAD*"; + + if (! SbieDll_RunSandboxed(//L"*THREAD*", + box_name, fullpath, homedir, 0, &si, &pi)) errnum = GetLastError(); else errnum = -1; diff --git a/Sandboxie/core/dll/proc.c b/Sandboxie/core/dll/proc.c index 70cfdbda4d..944f1621f1 100644 --- a/Sandboxie/core/dll/proc.c +++ b/Sandboxie/core/dll/proc.c @@ -230,6 +230,20 @@ typedef BOOL(*P_GetTokenInformation)( _In_ DWORD TokenInformationLength, _Out_ PDWORD ReturnLength); +typedef BOOL(*P_SetTokenInformation)( + _In_ HANDLE TokenHandle, + _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, + _In_reads_bytes_(TokenInformationLength) LPVOID TokenInformation, + _In_ DWORD TokenInformationLength); + +typedef BOOL(*P_AddAccessAllowedAceEx)( + _Inout_ PACL pAcl, + _In_ DWORD dwAceRevision, + _In_ DWORD AccessMask, + _In_ PSID pSid); + +typedef BOOL(*P_GetLengthSid)( + _In_ _Post_readable_byte_size_(return) PSID pSid); //--------------------------------------------------------------------------- @@ -255,6 +269,12 @@ static P_NtQueryInformationProcess __sys_NtQueryInformationProcess = NULL; static P_NtCreateProcessEx __sys_NtCreateProcessEx = NULL; static P_GetTokenInformation __sys_GetTokenInformation = NULL; +/*static P_SetTokenInformation __sys_SetTokenInformation = NULL; + +static P_AddAccessAllowedAceEx __sys_AddAccessAllowedAceEx = NULL; + +static P_GetLengthSid __sys_GetLengthSid = NULL;*/ + //--------------------------------------------------------------------------- @@ -381,6 +401,11 @@ _FX BOOLEAN Proc_Init_AdvApi(HMODULE module) } __sys_GetTokenInformation = (P_GetTokenInformation) GetProcAddress(module, "GetTokenInformation"); + /*__sys_SetTokenInformation = (P_SetTokenInformation) GetProcAddress(module, "SetTokenInformation"); + + __sys_AddAccessAllowedAceEx = (P_AddAccessAllowedAceEx) GetProcAddress(module, "AddAccessAllowedAceEx"); + + __sys_GetLengthSid = (P_GetLengthSid) GetProcAddress(module, "GetLengthSid");*/ return TRUE; } diff --git a/Sandboxie/core/dll/sbieapi.c b/Sandboxie/core/dll/sbieapi.c index 2f84827850..a740289d93 100644 --- a/Sandboxie/core/dll/sbieapi.c +++ b/Sandboxie/core/dll/sbieapi.c @@ -284,6 +284,7 @@ _FX LONG SbieApi_GetMessage( ULONG* MessageNum, ULONG SessionId, ULONG *MessageId, + ULONG *Pid, wchar_t *Buffer, ULONG Length) { @@ -302,6 +303,7 @@ _FX LONG SbieApi_GetMessage( args->session_id.val = SessionId; args->msgid.val = MessageId; args->msgtext.val = &msgtext; + args->process_id.val = Pid; status = SbieApi_Ioctl(parms); diff --git a/Sandboxie/core/dll/sbieapi.h b/Sandboxie/core/dll/sbieapi.h index f0967261bb..33e2ce8d5d 100644 --- a/Sandboxie/core/dll/sbieapi.h +++ b/Sandboxie/core/dll/sbieapi.h @@ -73,6 +73,7 @@ LONG SbieApi_GetMessage( ULONG* MessageNum, ULONG SessionId, ULONG *MessageId, + ULONG *Pid, wchar_t *Buffer, ULONG Length); diff --git a/Sandboxie/core/dll/sysinfo.c b/Sandboxie/core/dll/sysinfo.c index e42f9c6b94..6f541841b8 100644 --- a/Sandboxie/core/dll/sysinfo.c +++ b/Sandboxie/core/dll/sysinfo.c @@ -175,7 +175,9 @@ _FX NTSTATUS SysInfo_NtQuerySystemInformation( SystemInformationClass, Buffer, BufferLength, ReturnLength); if (NT_SUCCESS(status) && - SystemInformationClass == SystemProcessInformation) { + (SystemInformationClass == SystemProcessInformation + || SystemInformationClass == SystemExtendedProcessInformation + || SystemInformationClass == SystemFullProcessInformation)) { SysInfo_DiscardProcesses(Buffer); } @@ -195,6 +197,35 @@ _FX void SysInfo_DiscardProcesses(SYSTEM_PROCESS_INFORMATION *buf) SYSTEM_PROCESS_INFORMATION *next; WCHAR boxname[48]; + BOOL hideOther = SbieApi_QueryConfBool(NULL, L"HideOtherBoxes", TRUE); + + WCHAR* hiddenProcesses = NULL; + WCHAR* hiddenProcessesPtr = NULL; + ULONG hiddenProcessesLen = 100 * 110; // we can hide up to 100 processes, sould be enough + WCHAR hiddenProcess[110]; + + for (ULONG index = 0; ; ++index) { + NTSTATUS status = SbieApi_QueryConfAsIs(NULL, L"HideHostProcess", index, hiddenProcess, 108 * sizeof(WCHAR)); + if (NT_SUCCESS(status)) { + if (hiddenProcesses == NULL) { + hiddenProcesses = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, hiddenProcessesLen * sizeof(WCHAR)); + if (!hiddenProcesses) + break; + hiddenProcessesPtr = hiddenProcesses; + } + ULONG nameLen = wcslen(hiddenProcess) + 1; // include terminating 0 + if ((hiddenProcessesPtr - hiddenProcesses) + nameLen + 1 > hiddenProcessesLen) { + SbieApi_Log(2310, L", 'HideProcess'"); // todo add custom message + break; + } + wmemcpy(hiddenProcessesPtr, hiddenProcess, nameLen); + hiddenProcessesPtr += nameLen; + *hiddenProcessesPtr = L'\0'; + } + else if (status != STATUS_BUFFER_TOO_SMALL) + break; + } + // // we assume the first record is always going to be the idle process or // a system process -- in any case, one we're not going to have to skip @@ -202,21 +233,43 @@ _FX void SysInfo_DiscardProcesses(SYSTEM_PROCESS_INFORMATION *buf) while (1) { - next = (SYSTEM_PROCESS_INFORMATION *) - (((UCHAR *)curr) + curr->NextEntryOffset); + next = (SYSTEM_PROCESS_INFORMATION *) (((UCHAR *)curr) + curr->NextEntryOffset); if (next == curr) - return; - - SbieApi_QueryProcess( - next->UniqueProcessId, boxname, NULL, NULL, NULL); + break; - if ((! boxname[0]) || _wcsicmp(boxname, Dll_BoxName) == 0) + SbieApi_QueryProcess(next->UniqueProcessId, boxname, NULL, NULL, NULL); + + BOOL hideProcess = FALSE; + if (hideOther) { + if(boxname[0] && _wcsicmp(boxname, Dll_BoxName) != 0) + hideProcess = TRUE; + } + + if(hiddenProcesses) { + if ((!boxname[0]) && next->ImageName.Buffer) { + WCHAR* imagename = wcschr(next->ImageName.Buffer, L'\\'); + if (imagename) imagename += 1; // skip L'\\' + else imagename = next->ImageName.Buffer; + + for (hiddenProcessesPtr = hiddenProcesses; *hiddenProcessesPtr != L'\0'; hiddenProcessesPtr += wcslen(hiddenProcessesPtr) + 1) { + if (_wcsicmp(imagename, hiddenProcessesPtr) == 0) { + hideProcess = TRUE; + break; + } + } + } + } + + if (!hideProcess) curr = next; else if (next->NextEntryOffset) curr->NextEntryOffset += next->NextEntryOffset; else curr->NextEntryOffset = 0; } + + if(hiddenProcesses) + HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, hiddenProcesses); } diff --git a/Sandboxie/core/drv/api.c b/Sandboxie/core/drv/api.c index 16262777fd..93f027b123 100644 --- a/Sandboxie/core/drv/api.c +++ b/Sandboxie/core/drv/api.c @@ -619,7 +619,7 @@ _FX NTSTATUS Api_LogMessage(PROCESS *proc, ULONG64 *parms) if (status == STATUS_SUCCESS) { text[msgtext_length / sizeof(WCHAR)] = L'\0'; - Log_Popup_Msg(msgid, text, NULL, args->session_id.val); + Log_Popup_Msg(msgid, text, NULL, args->session_id.val, proc->pid); } Mem_Free(text, msgtext_length + 8); @@ -637,7 +637,8 @@ _FX void Api_AddMessage( NTSTATUS error_code, const WCHAR *string1, ULONG string1_len, const WCHAR *string2, ULONG string2_len, - ULONG session_id) + ULONG session_id, + ULONG process_id) { KIRQL irql; @@ -651,15 +652,17 @@ _FX void Api_AddMessage( irql = Api_EnterCriticalSection(); ULONG entry_size = sizeof(ULONG) // session_id + + sizeof(ULONG) // process_id + sizeof(ULONG) // error_code + (string1_len + 1) * sizeof(WCHAR) + (string2_len + 1) * sizeof(WCHAR); CHAR* write_ptr = log_buffer_push_entry((LOG_BUFFER_SIZE_T)entry_size, Api_LogBuffer); if (write_ptr) { - //[session_id 4][error_code 4][string1 n*2][\0 2][string2 n*2][\0 2] + //[session_id 4][process_id 4][error_code 4][string1 n*2][\0 2][string2 n*2][\0 2] WCHAR null_char = L'\0'; log_buffer_push_bytes((CHAR*)&session_id, sizeof(ULONG), &write_ptr, Api_LogBuffer); + log_buffer_push_bytes((CHAR*)&process_id, sizeof(ULONG), &write_ptr, Api_LogBuffer); log_buffer_push_bytes((CHAR*)&error_code, sizeof(ULONG), &write_ptr, Api_LogBuffer); log_buffer_push_bytes((CHAR*)string1, string1_len * sizeof(WCHAR), &write_ptr, Api_LogBuffer); log_buffer_push_bytes((CHAR*)&null_char, sizeof(WCHAR), &write_ptr, Api_LogBuffer); @@ -719,15 +722,23 @@ _FX NTSTATUS Api_GetMessage(PROCESS *proc, ULONG64 *parms) LOG_BUFFER_SIZE_T entry_size = log_buffer_get_size(&read_ptr, Api_LogBuffer); LOG_BUFFER_SEQ_T seq_number = log_buffer_get_seq_num(&read_ptr, Api_LogBuffer); *args->msg_num.val = seq_number; - //[session_id 4][error_code 4][string1 n*2][\0 2][string2 n*2][\0 2] + //[session_id 4][process_id 4][error_code 4][string1 n*2][\0 2][string2 n*2][\0 2] ULONG session_id; log_buffer_get_bytes((CHAR*)&session_id, 4, &read_ptr, Api_LogBuffer); + ULONG process_id; + log_buffer_get_bytes((CHAR*)&process_id, 4, &read_ptr, Api_LogBuffer); if (session_id == args->session_id.val) { log_buffer_get_bytes((CHAR*)args->msgid.val, 4, &read_ptr, Api_LogBuffer); SIZE_T msg_length = entry_size - (4 + 4); + if (args->process_id.val != NULL) + { + ProbeForWrite(args->process_id.val, sizeof(ULONG), sizeof(ULONG)); + *args->process_id.val = process_id; + } + if (msg_length <= msgtext->MaximumLength) { msgtext->Length = (USHORT)msg_length; diff --git a/Sandboxie/core/drv/api.h b/Sandboxie/core/drv/api.h index 8458c5b8a5..c82de52dbb 100644 --- a/Sandboxie/core/drv/api.h +++ b/Sandboxie/core/drv/api.h @@ -121,7 +121,8 @@ void Api_AddMessage( NTSTATUS error_code, const WCHAR *string1, ULONG string1_len, const WCHAR *string2, ULONG string2_len, - ULONG session_id); + ULONG session_id, + ULONG process_id); // diff --git a/Sandboxie/core/drv/api_defs.h b/Sandboxie/core/drv/api_defs.h index 65d1b38bac..55fb189c90 100644 --- a/Sandboxie/core/drv/api_defs.h +++ b/Sandboxie/core/drv/api_defs.h @@ -210,6 +210,7 @@ API_ARGS_FIELD(ULONG *, msg_num) API_ARGS_FIELD(ULONG, session_id) API_ARGS_FIELD(ULONG *, msgid) API_ARGS_FIELD(UNICODE_STRING64 *, msgtext) +API_ARGS_FIELD(ULONG *, process_id) API_ARGS_CLOSE(API_GET_MESSAGE_ARGS) API_ARGS_BEGIN(API_QUERY_PROCESS_ARGS) diff --git a/Sandboxie/core/drv/driver.c b/Sandboxie/core/drv/driver.c index 46c2a74783..77510a6bf5 100644 --- a/Sandboxie/core/drv/driver.c +++ b/Sandboxie/core/drv/driver.c @@ -84,7 +84,7 @@ const WCHAR *Driver_S_1_5_20 = L"S-1-5-20"; DRIVER_OBJECT *Driver_Object; -WCHAR *Driver_Version = TEXT(MY_VERSION_STRING); +WCHAR *Driver_Version = TEXT(MY_VERSION_COMPAT); ULONG Driver_OsVersion = 0; ULONG Driver_OsBuild = 0; @@ -709,7 +709,7 @@ _FX NTSTATUS Driver_Api_Unload(PROCESS *proc, ULONG64 *parms) if (! ok) { Process_ReadyToSandbox = ReadyToSandbox; - Log_Msg0(MSG_CANNOT_UNLOAD_DRIVER); + Log_MsgP0(MSG_CANNOT_UNLOAD_DRIVER, proc->pid); return STATUS_CONNECTION_IN_USE; } diff --git a/Sandboxie/core/drv/file.c b/Sandboxie/core/drv/file.c index f3704d2b13..4ad48a1382 100644 --- a/Sandboxie/core/drv/file.c +++ b/Sandboxie/core/drv/file.c @@ -364,8 +364,7 @@ _FX BOOLEAN File_CreateBoxPath(PROCESS *proc) status = STATUS_UNSUCCESSFUL; if (! NT_SUCCESS(status)) { - Log_Status_Ex( - MSG_FILE_CREATE_BOX_PATH, 0, status, proc->box->file_path); + Log_Status_Ex_Process(MSG_FILE_CREATE_BOX_PATH, 0, status, proc->box->file_path, -1, proc->pid); } return (NT_SUCCESS(status)); @@ -630,7 +629,7 @@ _FX BOOLEAN File_InitPaths(PROCESS *proc, ok = Process_GetPaths(proc, open_file_paths, _OpenPipe, TRUE); if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _OpenPipe); + Log_MsgP1(MSG_INIT_PATHS, _OpenPipe, proc->pid); return FALSE; } @@ -639,7 +638,7 @@ _FX BOOLEAN File_InitPaths(PROCESS *proc, ok = Process_GetPaths(proc, open_file_paths, _OpenFile, TRUE); if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _OpenFile); + Log_MsgP1(MSG_INIT_PATHS, _OpenFile, proc->pid); return FALSE; } } @@ -656,7 +655,7 @@ _FX BOOLEAN File_InitPaths(PROCESS *proc, } if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _OpenPipe); + Log_MsgP1(MSG_INIT_PATHS, _OpenPipe, proc->pid); return FALSE; } @@ -681,7 +680,7 @@ _FX BOOLEAN File_InitPaths(PROCESS *proc, } if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _ClosedPath); + Log_MsgP1(MSG_INIT_PATHS, _ClosedPath, proc->pid); return FALSE; } @@ -693,7 +692,7 @@ _FX BOOLEAN File_InitPaths(PROCESS *proc, if (ok) ok = Process_GetPaths(proc, read_file_paths, _ReadPath, TRUE); if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _ReadPath); + Log_MsgP1(MSG_INIT_PATHS, _ReadPath, proc->pid); return FALSE; } @@ -709,7 +708,7 @@ _FX BOOLEAN File_InitPaths(PROCESS *proc, proc, closed_file_paths, _WritePath, TRUE); } if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _WritePath); + Log_MsgP1(MSG_INIT_PATHS, _WritePath, proc->pid); return FALSE; } @@ -1520,7 +1519,7 @@ _FX NTSTATUS File_Generic_MyParseProc( if (proc->file_warn_direct_access) { - //Log_Msg1(MSG_BLOCKED_DIRECT_DISK_ACCESS, proc->image_name); + //Log_MsgP1(MSG_BLOCKED_DIRECT_DISK_ACCESS, proc->image_name, proc->pid); Process_LogMessage(proc, MSG_BLOCKED_DIRECT_DISK_ACCESS); } } @@ -1834,7 +1833,7 @@ _FX NTSTATUS File_Api_Rename(PROCESS *proc, ULONG64 *parms) info->FileNameLength = name_len; memcpy(info->FileName, name, name_len); - status = ZwSetInformationFile( + status = NtSetInformationFile( args->file_handle.val, &IoStatusBlock, info, info_len, FileRenameInformation); @@ -1845,7 +1844,7 @@ _FX NTSTATUS File_Api_Rename(PROCESS *proc, ULONG64 *parms) Mem_Free(info, info_len); } - ZwClose(dir_handle); + NtClose(dir_handle); Mem_Free(path, path_len); return status; } diff --git a/Sandboxie/core/drv/file_flt.c b/Sandboxie/core/drv/file_flt.c index 51a05d12c2..be863a6dc3 100644 --- a/Sandboxie/core/drv/file_flt.c +++ b/Sandboxie/core/drv/file_flt.c @@ -390,7 +390,7 @@ _FX FLT_PREOP_CALLBACK_STATUS File_PreOperation( // Get normalized full path to target file. // Occasionally, certain PDF apps will send in a short name (containing '~'). That will break all of our folder name checking below. - if (FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED, &pTargetFileNameInfo) != STATUS_SUCCESS) + if (FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &pTargetFileNameInfo) != STATUS_SUCCESS) { status = STATUS_ACCESS_DENIED; // if we can't get the name, just disallow the call } @@ -431,7 +431,7 @@ _FX FLT_PREOP_CALLBACK_STATUS File_PreOperation( pStr2 += pTargetFileNameInfo->Name.Length; memset(pStr2, 0, 2); // add a wchar NULL - Log_Msg_Session(MSG_1319, wcPid, (PWCHAR)pStr, proc->box->session_id); + Log_Msg_Process(MSG_1319, wcPid, (PWCHAR)pStr, proc->box->session_id, proc->pid); Mem_Free(pStr, len); } FltReleaseFileNameInformation(pTargetFileNameInfo); @@ -488,7 +488,7 @@ _FX FLT_PREOP_CALLBACK_STATUS File_PreOperation( { // Get normalized path to target file. FLT_FILE_NAME_INFORMATION *pTargetFileNameInfo = NULL; - if (FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED, &pTargetFileNameInfo) == STATUS_SUCCESS) + if (FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &pTargetFileNameInfo) == STATUS_SUCCESS) { if (pTargetFileNameInfo) { diff --git a/Sandboxie/core/drv/gui.c b/Sandboxie/core/drv/gui.c index aeb4a17786..fb0c8c0197 100644 --- a/Sandboxie/core/drv/gui.c +++ b/Sandboxie/core/drv/gui.c @@ -220,7 +220,7 @@ _FX BOOLEAN Gui_InitProcess(PROCESS *proc) }*/ if (! ok) - Log_Msg1(MSG_INIT_PATHS, Gui_OpenClass_Name); + Log_MsgP1(MSG_INIT_PATHS, Gui_OpenClass_Name, proc->pid); return ok; } diff --git a/Sandboxie/core/drv/gui_xp.c b/Sandboxie/core/drv/gui_xp.c index 13b3a36f3a..9351dd554f 100644 --- a/Sandboxie/core/drv/gui_xp.c +++ b/Sandboxie/core/drv/gui_xp.c @@ -410,7 +410,7 @@ _FX NTSTATUS Gui_Api_Init_XpHook(PROCESS *proc, ULONG64 *parms) if (! ok) { InterlockedExchange(&Gui_HookCount, Gui_HookCount | GUI_HOOK_FAILED); - Log_Msg0(MSG_GUI_INIT_FAILED); + Log_MsgP0(MSG_GUI_INIT_FAILED, proc->pid); return STATUS_UNSUCCESSFUL; } @@ -437,7 +437,7 @@ _FX NTSTATUS Gui_Api_Init_XpHook(PROCESS *proc, ULONG64 *parms) if (! ok) { InterlockedExchange(&Gui_HookCount, Gui_HookCount | GUI_HOOK_FAILED); - Log_Msg0(MSG_GUI_INIT_FAILED); + Log_MsgP0(MSG_GUI_INIT_FAILED, proc->pid); return STATUS_UNSUCCESSFUL; } diff --git a/Sandboxie/core/drv/ipc.c b/Sandboxie/core/drv/ipc.c index bed0d356df..b8fd286ed8 100644 --- a/Sandboxie/core/drv/ipc.c +++ b/Sandboxie/core/drv/ipc.c @@ -351,8 +351,7 @@ _FX BOOLEAN Ipc_CreateBoxPath(PROCESS *proc) status = STATUS_UNSUCCESSFUL; if (! NT_SUCCESS(status)) { - Log_Status_Ex( - MSG_IPC_CREATE_BOX_PATH, 0, status, proc->box->ipc_path); + Log_Status_Ex_Process(MSG_IPC_CREATE_BOX_PATH, 0, status, proc->box->ipc_path, -1, proc->pid); } return (NT_SUCCESS(status)); @@ -632,7 +631,7 @@ _FX BOOLEAN Ipc_InitPaths(PROCESS *proc) } if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _OpenPath); + Log_MsgP1(MSG_INIT_PATHS, _OpenPath, proc->pid); return FALSE; } @@ -642,7 +641,7 @@ _FX BOOLEAN Ipc_InitPaths(PROCESS *proc) ok = Process_GetPaths(proc, &proc->closed_ipc_paths, _ClosedPath, FALSE); if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _ClosedPath); + Log_MsgP1(MSG_INIT_PATHS, _ClosedPath, proc->pid); return FALSE; } diff --git a/Sandboxie/core/drv/ipc_port.c b/Sandboxie/core/drv/ipc_port.c index 2e4eba8ce2..ee44629e9d 100644 --- a/Sandboxie/core/drv/ipc_port.c +++ b/Sandboxie/core/drv/ipc_port.c @@ -342,7 +342,7 @@ _FX NTSTATUS Ipc_CheckPortRequest_SpoolerPort( } if (status == STATUS_ACCESS_DENIED) - Log_Msg0(MSG_1319); + Log_MsgP0(MSG_1319, proc->pid); return status; } @@ -560,7 +560,7 @@ _FX NTSTATUS Ipc_CheckPortRequest_WinApi( } if (msg2->api_code == KERNEL_CHECKVDM) { - Log_Msg0(MSG_BLOCKED_16_BIT); + Log_MsgP0(MSG_BLOCKED_16_BIT, proc->pid); status = STATUS_ACCESS_DENIED; } @@ -576,7 +576,7 @@ _FX NTSTATUS Ipc_CheckPortRequest_WinApi( if ( ((Driver_OsVersion == DRIVER_WINDOWS_XP || Driver_OsVersion == DRIVER_WINDOWS_VISTA) && msg2->api_code == WINAPI_SRVDEVICEEVENT) || (Driver_OsVersion == DRIVER_WINDOWS_7 && msg2->api_code == WINAPI_SRVDEVICEEVENT_WIN7) ) { - Log_Msg0(MSG_1316); + Log_MsgP0(MSG_1316, proc->pid); status = STATUS_ACCESS_DENIED; } } @@ -692,7 +692,7 @@ _FX NTSTATUS Ipc_CheckPortRequest_Lsa( } if (status == STATUS_ACCESS_DENIED) - Log_Msg(MSG_PASSWORD_CHANGE_DENIED, NULL, NULL); + Log_Msg_Process(MSG_PASSWORD_CHANGE_DENIED, NULL, NULL, -1, proc->pid); return status; } diff --git a/Sandboxie/core/drv/key.c b/Sandboxie/core/drv/key.c index 03fa7b630f..03d15befc3 100644 --- a/Sandboxie/core/drv/key.c +++ b/Sandboxie/core/drv/key.c @@ -239,7 +239,7 @@ _FX BOOLEAN Key_InitProcess(PROCESS *proc) ok = Process_GetPaths(proc, &proc->open_key_paths, _OpenPath, TRUE); if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _OpenPath); + Log_MsgP1(MSG_INIT_PATHS, _OpenPath, proc->pid); return FALSE; } @@ -249,7 +249,7 @@ _FX BOOLEAN Key_InitProcess(PROCESS *proc) ok = Process_GetPaths(proc, &proc->closed_key_paths, _ClosedPath, TRUE); if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _ClosedPath); + Log_MsgP1(MSG_INIT_PATHS, _ClosedPath, proc->pid); return FALSE; } @@ -261,7 +261,7 @@ _FX BOOLEAN Key_InitProcess(PROCESS *proc) if (ok) ok = Process_GetPaths(proc, &proc->read_key_paths, _ReadPath, TRUE); if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _ReadPath); + Log_MsgP1(MSG_INIT_PATHS, _ReadPath, proc->pid); return FALSE; } @@ -279,7 +279,7 @@ _FX BOOLEAN Key_InitProcess(PROCESS *proc) proc, &proc->closed_key_paths, _WritePath, TRUE); } if (! ok) { - Log_Msg1(MSG_INIT_PATHS, _WritePath); + Log_MsgP1(MSG_INIT_PATHS, _WritePath, proc->pid); return FALSE; } } diff --git a/Sandboxie/core/drv/key_flt.c b/Sandboxie/core/drv/key_flt.c index 592ea84a09..f36a3c3116 100644 --- a/Sandboxie/core/drv/key_flt.c +++ b/Sandboxie/core/drv/key_flt.c @@ -312,14 +312,35 @@ NTSTATUS Key_StoreValue(PROCESS *proc, REG_SET_VALUE_KEY_INFORMATION *pSetInfo, rc = ZwCreateKey(&handle, KEY_WRITE, &target, 0, NULL, REG_OPTION_NON_VOLATILE, &Disp); if (rc == STATUS_SUCCESS) { - __try - { - rc = ZwSetValueKey(handle, pSetInfo->ValueName, pSetInfo->TitleIndex, pSetInfo->Type, pSetInfo->Data, pSetInfo->DataSize); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - rc = STATUS_ACCESS_DENIED; //Block Path - } + rc = STATUS_ACCESS_DENIED; //Block Path + + // Note: Driver verifyer does not like ZwXxx unctions being fed userspace memory + PUNICODE_STRING ValueName = (pSetInfo->ValueName && pSetInfo->ValueName->MaximumLength > 0) ? + (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, sizeof(UNICODE_STRING) + pSetInfo->ValueName->MaximumLength, tzuk) : NULL; + if (ValueName) + { + ValueName->Length = pSetInfo->ValueName->Length; + ValueName->MaximumLength = pSetInfo->ValueName->MaximumLength; + ValueName->Buffer = (PWCH)(((UCHAR*)ValueName) + sizeof(UNICODE_STRING)); + memcpy(ValueName->Buffer, pSetInfo->ValueName->Buffer, pSetInfo->ValueName->Length); + + PVOID Data = pSetInfo->DataSize > 0 ? ExAllocatePoolWithTag(NonPagedPool, pSetInfo->DataSize, tzuk) : NULL; + if (Data) + { + if (pSetInfo->Data) memcpy(Data, pSetInfo->Data, pSetInfo->DataSize); + + __try + { + rc = ZwSetValueKey(handle, ValueName, pSetInfo->TitleIndex, pSetInfo->Type, Data, pSetInfo->DataSize); + } + __except (EXCEPTION_EXECUTE_HANDLER) { } + + ExFreePoolWithTag(Data, tzuk); + } + + ExFreePoolWithTag(ValueName, tzuk); + } + //DbgPrint("SBIE: Write redirect to sandbox: %x, %S, disp = %d\n",rc,targetName,Disp); ZwClose(handle); } @@ -361,14 +382,37 @@ NTSTATUS Key_PreDataInject(REG_QUERY_VALUE_KEY_INFORMATION *pPreInfo, ULONG spid rc = ZwOpenKey(&handle, KEY_READ, &target); if (rc == STATUS_SUCCESS) { - __try - { - rc = ZwQueryValueKey(handle, pPreInfo->ValueName, pPreInfo->KeyValueInformationClass, pPreInfo->KeyValueInformation, pPreInfo->Length, pPreInfo->ResultLength); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - rc = STATUS_SUCCESS; // Read from host - } + + // Note: Driver verifyer does not like ZwXxx unctions being fed userspace memory + PUNICODE_STRING ValueName = (pPreInfo->ValueName && pPreInfo->ValueName->MaximumLength > 0) ? + (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, sizeof(UNICODE_STRING) + pPreInfo->ValueName->MaximumLength, tzuk) : NULL; + if (ValueName) + { + ValueName->Length = pPreInfo->ValueName->Length; + ValueName->MaximumLength = pPreInfo->ValueName->MaximumLength; + ValueName->Buffer = (PWCH)(((UCHAR*)ValueName) + sizeof(UNICODE_STRING)); + memcpy(ValueName->Buffer, pPreInfo->ValueName->Buffer, pPreInfo->ValueName->Length); + + PVOID KeyValueInformation = pPreInfo->Length > 0 ? ExAllocatePoolWithTag(NonPagedPool, pPreInfo->Length, tzuk) : NULL; + if (KeyValueInformation) + { + __try + { + ULONG ResultLength = pPreInfo->ResultLength ? *pPreInfo->ResultLength : 0; + + rc = ZwQueryValueKey(handle, ValueName, pPreInfo->KeyValueInformationClass, KeyValueInformation, pPreInfo->Length, &ResultLength); + + if (pPreInfo->ResultLength) *pPreInfo->ResultLength = ResultLength; + if (pPreInfo->KeyValueInformation) memcpy(pPreInfo->KeyValueInformation, KeyValueInformation, ResultLength); + } + __except (EXCEPTION_EXECUTE_HANDLER) {} + + ExFreePoolWithTag(KeyValueInformation, tzuk); + } + + ExFreePoolWithTag(ValueName, tzuk); + } + if (rc == STATUS_SUCCESS) { status = STATUS_CALLBACK_BYPASS; diff --git a/Sandboxie/core/drv/log.c b/Sandboxie/core/drv/log.c index d3fdff8d75..1f0e900197 100644 --- a/Sandboxie/core/drv/log.c +++ b/Sandboxie/core/drv/log.c @@ -105,7 +105,8 @@ _FX void Log_Popup_Msg( NTSTATUS error_code, const WCHAR *string1, const WCHAR *string2, - ULONG session_id) + ULONG session_id, + HANDLE pid) { ULONG string1_len, string2_len; @@ -134,7 +135,7 @@ _FX void Log_Popup_Msg( //Log_Popup_Msg_2( Api_AddMessage( - error_code, string1, string1_len, string2, string2_len, session_id); + error_code, string1, string1_len, string2, string2_len, session_id, (ULONG)pid); // // log message to SbieSvc and trigger SbieSvc to wake up and collect it @@ -142,7 +143,7 @@ _FX void Log_Popup_Msg( //Log_Popup_Msg_2( Api_AddMessage( - error_code, string1, string1_len, string2, string2_len, -1); + error_code, string1, string1_len, string2, string2_len, -1, (ULONG)pid); string1_len = 0; Api_SendServiceMessage(SVC_LOG_MESSAGE, sizeof(ULONG), &string1_len); @@ -231,13 +232,27 @@ _FX void Log_Msg_Session( const WCHAR *string2, ULONG session_id) { - ULONG facility = (error_code >> 16) & 0x0F; - if (facility & MSG_FACILITY_EVENT) - Log_Event_Msg(error_code, string1, string2); - if (facility & MSG_FACILITY_POPUP) - Log_Popup_Msg(error_code, string1, string2, session_id); + Log_Msg_Process(error_code, string1, string2, session_id, (HANDLE)4); } +//--------------------------------------------------------------------------- +// Log_Msg_Process +//--------------------------------------------------------------------------- + + +_FX void Log_Msg_Process( + NTSTATUS error_code, + const WCHAR *string1, + const WCHAR *string2, + ULONG session_id, + HANDLE process_id) +{ + ULONG facility = (error_code >> 16) & 0x0F; + if (facility & MSG_FACILITY_EVENT) + Log_Event_Msg(error_code, string1, string2); + if (facility & MSG_FACILITY_POPUP) + Log_Popup_Msg(error_code, string1, string2, session_id, process_id); +} //--------------------------------------------------------------------------- // Log_Status_Ex @@ -265,6 +280,22 @@ _FX void Log_Status_Ex_Session( NTSTATUS nt_status, const WCHAR *string2, ULONG session_id) +{ + Log_Status_Ex_Process(error_code, error_subcode, nt_status, string2, session_id, (HANDLE)4); +} + +//--------------------------------------------------------------------------- +// Log_Status_Ex_Process +//--------------------------------------------------------------------------- + + +_FX void Log_Status_Ex_Process( + NTSTATUS error_code, + ULONG error_subcode, + NTSTATUS nt_status, + const WCHAR *string2, + ULONG session_id, + HANDLE process_id) { WCHAR str[100]; @@ -273,7 +304,7 @@ _FX void Log_Status_Ex_Session( else swprintf(str, L"[%08X]", nt_status); - Log_Msg_Session(error_code, str, string2, session_id); + Log_Msg_Process(error_code, str, string2, session_id, process_id); } diff --git a/Sandboxie/core/drv/log.h b/Sandboxie/core/drv/log.h index 86133130a5..9b69eafb63 100644 --- a/Sandboxie/core/drv/log.h +++ b/Sandboxie/core/drv/log.h @@ -108,11 +108,19 @@ void Log_Msg_Session( const WCHAR *string2, ULONG session_id); +void Log_Msg_Process( + NTSTATUS error_code, + const WCHAR *string1, + const WCHAR *string2, + ULONG session_id, + HANDLE process_id); + void Log_Popup_Msg( NTSTATUS error_code, const WCHAR *string1, const WCHAR *string2, - ULONG session_id); + ULONG session_id, + HANDLE pid); void Log_Status_Ex( NTSTATUS error_code, @@ -127,6 +135,14 @@ void Log_Status_Ex_Session( const WCHAR *string2 OPTIONAL, ULONG session_id); +void Log_Status_Ex_Process( + NTSTATUS error_code, + ULONG error_subcode, + NTSTATUS nt_status, + const WCHAR *string2 OPTIONAL, + ULONG session_id, + HANDLE pocess_id); + #define Log_Msg0(error_code) \ Log_Msg(error_code,NULL,NULL) @@ -136,6 +152,15 @@ void Log_Status_Ex_Session( #define Log_Msg2(error_code,str1,str2) \ Log_Msg(error_code,str1,str2) +#define Log_MsgP0(error_code, proc_id) \ + Log_Msg_Process(error_code,NULL,NULL, -1, proc_id) + +#define Log_MsgP1(error_code,str1, proc_id) \ + Log_Msg_Process(error_code,str1,NULL, -1, proc_id) + +#define Log_MsgP2(error_code,str1,str2, proc_id) \ + Log_Msg_Process(error_code,str1,str2, -1, proc_id) + #define Log_Status(error_code,error_subcode,ntstatus) \ Log_Status_Ex(error_code, error_subcode, ntstatus, NULL) diff --git a/Sandboxie/core/drv/process.c b/Sandboxie/core/drv/process.c index 3320f648f4..0c9e85dda5 100644 --- a/Sandboxie/core/drv/process.c +++ b/Sandboxie/core/drv/process.c @@ -512,7 +512,7 @@ _FX void Process_CreateTerminated(HANDLE ProcessId, ULONG SessionId) if (pid_str.Buffer) { RtlIntPtrToUnicodeString((ULONG_PTR)ProcessId, 10, &pid_str); - Log_Msg_Session(MSG_1211, pid_str.Buffer, NULL, SessionId); + Log_Msg_Process(MSG_1211, pid_str.Buffer, NULL, SessionId, ProcessId); Mem_Free(pid_str.Buffer, pid_str.MaximumLength); } @@ -558,7 +558,7 @@ _FX PROCESS *Process_Create( pool = Pool_Create(); if (! pool) { - Log_Msg_Session(MSG_1201, NULL, NULL, box->session_id); + Log_Msg_Process(MSG_1201, NULL, NULL, box->session_id, ProcessId); Process_CreateTerminated(ProcessId, box->session_id); return NULL; } @@ -566,7 +566,7 @@ _FX PROCESS *Process_Create( proc = Mem_Alloc(pool, sizeof(PROCESS)); if (! proc) { // first allocation from a new pool should never fail - Log_Msg_Session(MSG_1201, NULL, NULL, box->session_id); + Log_Msg_Process(MSG_1201, NULL, NULL, box->session_id, ProcessId); Pool_Delete(pool); Process_CreateTerminated(ProcessId, box->session_id); return NULL; @@ -591,8 +591,7 @@ _FX PROCESS *Process_Create( status = PsLookupProcessByProcessId(proc->pid, &ProcessObject); if (! NT_SUCCESS(status)) { - Log_Status_Ex_Session( - MSG_1231, 0x33, status, L"???", box->session_id); + Log_Status_Ex_Process(MSG_1231, 0x33, status, L"???", box->session_id, ProcessId); Pool_Delete(pool); Process_CreateTerminated(ProcessId, box->session_id); @@ -645,7 +644,7 @@ _FX PROCESS *Process_Create( memcpy(proc->image_name, image_name, proc->image_name_len); } else - Log_Msg_Session(MSG_1201, NULL, NULL, box->session_id); + Log_Msg_Process(MSG_1201, NULL, NULL, box->session_id, proc->pid); } } @@ -655,8 +654,7 @@ _FX PROCESS *Process_Create( if ((! proc->image_name) || (! proc->image_path)) { const ULONG status = STATUS_INVALID_IMAGE_FORMAT; - Log_Status_Ex_Session( - MSG_1231, 0x11, status, L"???", box->session_id); + Log_Status_Ex_Process(MSG_1231, 0x11, status, L"???", box->session_id, proc->pid); Pool_Delete(pool); Process_CreateTerminated(ProcessId, box->session_id); @@ -685,7 +683,7 @@ _FX PROCESS *Process_Create( if (proc->gui_lock) Mem_FreeLockResource(&proc->gui_lock); - Log_Msg_Session(MSG_1201, NULL, NULL, box->session_id); + Log_Msg_Process(MSG_1201, NULL, NULL, box->session_id, ProcessId); Pool_Delete(pool); Process_CreateTerminated(ProcessId, box->session_id); return NULL; @@ -1263,15 +1261,14 @@ _FX void Process_NotifyImage( } else { - Log_Status_Ex_Session( - MSG_1231, fail, STATUS_UNSUCCESSFUL, NULL, proc->box->session_id); + Log_Status_Ex_Process(MSG_1231, fail, STATUS_UNSUCCESSFUL, NULL, proc->box->session_id, proc->pid); proc->terminated = TRUE; proc->reason = 0xA0 + fail; Process_CancelProcess(proc); } - //DbgPrint("IMAGE LOADED, PROCESS INITIALIZATION %d COMPLETE %d\n", proc->pid, ok); + //DbgPrint("IMAGE LOADED, PROCESS INITIALIZATION %d COMPLETE %d\n", proc->pid, !fail); } diff --git a/Sandboxie/core/drv/process_api.c b/Sandboxie/core/drv/process_api.c index 139ef8c26c..ccc5b6cc6d 100644 --- a/Sandboxie/core/drv/process_api.c +++ b/Sandboxie/core/drv/process_api.c @@ -388,7 +388,24 @@ _FX NTSTATUS Process_Api_QueryInfo(PROCESS *proc, ULONG64 *parms) *data = proc->ntdll32_base; - } else + } else if (args->info_type.val == 'ptok') { + + void *PrimaryTokenObject = proc->primary_token; + if (PrimaryTokenObject) + { + ObReferenceObject(PrimaryTokenObject); + + HANDLE MyTokenHandle; + status = ObOpenObjectByPointer(PrimaryTokenObject, 0, NULL, TOKEN_QUERY | TOKEN_DUPLICATE, *SeTokenObjectType, UserMode, &MyTokenHandle); + + ObDereferenceObject(PrimaryTokenObject); + + *data = (ULONG64)MyTokenHandle; + } + else + status = STATUS_NOT_FOUND; + } + else status = STATUS_INVALID_INFO_CLASS; // diff --git a/Sandboxie/core/drv/process_force.c b/Sandboxie/core/drv/process_force.c index 5dc592e4eb..26b51b4cfb 100644 --- a/Sandboxie/core/drv/process_force.c +++ b/Sandboxie/core/drv/process_force.c @@ -273,7 +273,7 @@ _FX BOX *Process_GetForcedStartBox( if ((alert == 1) && (! same_image_name)) { - Log_Msg_Session(MSG_1301, ImageName, NULL, SessionId); + Log_Msg_Process(MSG_1301, ImageName, NULL, SessionId, ProcessId); } if (box) { diff --git a/Sandboxie/core/drv/process_low.c b/Sandboxie/core/drv/process_low.c index 474a57f136..ac888a9454 100644 --- a/Sandboxie/core/drv/process_low.c +++ b/Sandboxie/core/drv/process_low.c @@ -231,8 +231,7 @@ _FX BOOLEAN Process_Low_Inject( Process_CancelProcess(&dummy_proc); } - Log_Status_Ex_Session( - MSG_1231, 0x22, status, image_name, session_id); + Log_Status_Ex_Process(MSG_1231, 0x22, status, image_name, session_id, process_id); return FALSE; } @@ -410,8 +409,7 @@ _FX BOOLEAN Process_Low_InitConsole(PROCESS *proc) finish: if (! NT_SUCCESS(status)) { - Log_Status_Ex_Session(MSG_1231, 0x66, status, - proc->image_name, proc->box->session_id); + Log_Status_Ex_Process(MSG_1231, 0x66, status, proc->image_name, proc->box->session_id, proc->pid); return FALSE; } diff --git a/Sandboxie/core/drv/process_util.c b/Sandboxie/core/drv/process_util.c index 4a4e120a5c..b2f4c1fb6b 100644 --- a/Sandboxie/core/drv/process_util.c +++ b/Sandboxie/core/drv/process_util.c @@ -974,7 +974,7 @@ _FX void Process_LogMessage(PROCESS *proc, ULONG msgid) swprintf(text, L"%s [%s]", proc->image_name, box->name); if (proc->image_copy) wcscat(text, L" *"); - Log_Msg1(msgid, text); + Log_MsgP1(msgid, text, proc->pid); Mem_Free(text, len); } diff --git a/Sandboxie/core/drv/syscall_open.c b/Sandboxie/core/drv/syscall_open.c index 8e06c3b707..39ca214162 100644 --- a/Sandboxie/core/drv/syscall_open.c +++ b/Sandboxie/core/drv/syscall_open.c @@ -195,7 +195,7 @@ _FX NTSTATUS Syscall_CheckObject( WCHAR msg[256]; swprintf(msg, L"%S (%08X) access=%08X initialized=%d", syscall_entry->name, status, HandleInfo->GrantedAccess, proc->initialized); - Log_Msg(MSG_2101, msg, Name != NULL ? Name->Name.Buffer : L"Unnamed object"); + Log_Msg_Process(MSG_2101, msg, Name != NULL ? Name->Name.Buffer : L"Unnamed object", -1, proc->pid); } if (Name != &Obj_Unnamed) diff --git a/Sandboxie/core/drv/thread.c b/Sandboxie/core/drv/thread.c index 7dd38c2892..4e36102b50 100644 --- a/Sandboxie/core/drv/thread.c +++ b/Sandboxie/core/drv/thread.c @@ -328,8 +328,7 @@ _FX BOOLEAN Thread_InitProcess(PROCESS *proc) if (! NT_SUCCESS(status)) { - Log_Status_Ex_Session( - MSG_1231, 0x44, status, NULL, proc->box->session_id); + Log_Status_Ex_Process( MSG_1231, 0x44, status, NULL, proc->box->session_id, proc->pid); return FALSE; } } diff --git a/Sandboxie/core/drv/token.c b/Sandboxie/core/drv/token.c index 39af060ef1..1218e9426f 100644 --- a/Sandboxie/core/drv/token.c +++ b/Sandboxie/core/drv/token.c @@ -61,7 +61,7 @@ static void *Token_RestrictHelper1( void *TokenObject, ULONG *OutIntegrityLevel, PROCESS *proc); static NTSTATUS Token_RestrictHelper2( - void *TokenObject, ULONG *OutIntegrityLevel, ULONG SessionId); + void *TokenObject, ULONG *OutIntegrityLevel, PROCESS *proc); static void *Token_RestrictHelper3( void *TokenObject, TOKEN_GROUPS *Groups, TOKEN_PRIVILEGES *Privileges, @@ -464,8 +464,7 @@ _FX void *Token_FilterPrimary(PROCESS *proc, void *ProcessObject) PrimaryToken = PsReferencePrimaryToken(ProcessObject); if (!PrimaryToken) { - Log_Status_Ex_Session( - MSG_1222, 0x31, STATUS_NO_TOKEN, NULL, proc->box->session_id); + Log_Status_Ex_Process(MSG_1222, 0x31, STATUS_NO_TOKEN, NULL, proc->box->session_id, proc->pid); return NULL; } @@ -916,8 +915,7 @@ _FX BOOLEAN Token_ResetPrimary(PROCESS *proc) status = PsLookupProcessByProcessId(proc->pid, &ProcessObject); if (!NT_SUCCESS(status)) { - Log_Status_Ex_Session( - MSG_1222, 0x37, status, NULL, proc->box->session_id); + Log_Status_Ex_Process(MSG_1222, 0x37, status, NULL, proc->box->session_id, proc->pid); } else { @@ -925,8 +923,7 @@ _FX BOOLEAN Token_ResetPrimary(PROCESS *proc) void *TokenObject = PsReferencePrimaryToken(ProcessObject); if (!TokenObject) { - Log_Status_Ex_Session( - MSG_1222, 0x31, STATUS_NO_TOKEN, NULL, proc->box->session_id); + Log_Status_Ex_Process(MSG_1222, 0x31, STATUS_NO_TOKEN, NULL, proc->box->session_id, proc->pid); } else @@ -1264,7 +1261,7 @@ _FX void *Token_RestrictHelper1( if (NT_SUCCESS(status)) { status = Token_RestrictHelper2( - NewTokenObject, OutIntegrityLevel, proc->box->session_id); + NewTokenObject, OutIntegrityLevel, proc); } if (!NT_SUCCESS(status)) { @@ -1279,7 +1276,7 @@ _FX void *Token_RestrictHelper1( // if (!NT_SUCCESS(status)) - Log_Status_Ex_Session(MSG_1222, 0x32, status, NULL, proc->box->session_id); + Log_Status_Ex_Process(MSG_1222, 0x32, status, NULL, proc->box->session_id, proc->pid); return NewTokenObject; } @@ -1291,7 +1288,7 @@ _FX void *Token_RestrictHelper1( _FX NTSTATUS Token_RestrictHelper2( - void *TokenObject, ULONG *OutIntegrityLevel, ULONG SessionId) + void *TokenObject, ULONG *OutIntegrityLevel, PROCESS *proc) { NTSTATUS status; ULONG label; @@ -1300,11 +1297,16 @@ _FX NTSTATUS Token_RestrictHelper2( return STATUS_SUCCESS; label = (ULONG)(ULONG_PTR)Token_Query( - TokenObject, TokenIntegrityLevel, SessionId); + TokenObject, TokenIntegrityLevel, proc->box->session_id); if (OutIntegrityLevel) *OutIntegrityLevel = label; + // OpenToken BEGIN + if (Conf_Get_Boolean(proc->box->name, L"KeepTokenIntegrity", 0, FALSE)) + return STATUS_SUCCESS; + // OpenToken END + if (label & 0xFFFF00FF) status = STATUS_INVALID_LEVEL; @@ -1732,8 +1734,7 @@ _FX BOOLEAN Token_ReplacePrimary(PROCESS *proc) status = PsLookupProcessByProcessId(proc->pid, &ProcessObject); if (!NT_SUCCESS(status)) { - Log_Status_Ex_Session( - MSG_1222, 0x37, status, NULL, proc->box->session_id); + Log_Status_Ex_Process(MSG_1222, 0x37, status, NULL, proc->box->session_id, proc->pid); } else { @@ -1975,8 +1976,8 @@ ULONG GetThreadTokenOwnerPid() ULONG ulResult = 0; PVOID impToken = NULL; - if (NT_SUCCESS(ZwOpenThreadToken(NtCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &hHandle)) && - NT_SUCCESS(ObReferenceObjectByHandle(hHandle, TOKEN_ALL_ACCESS, *SeTokenObjectType, KernelMode, &impToken, NULL))) + if (NT_SUCCESS(ZwOpenThreadToken(NtCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &hHandle)) && + NT_SUCCESS(ObReferenceObjectByHandle(hHandle, TOKEN_ALL_ACCESS, *SeTokenObjectType, UserMode, &impToken, NULL))) { // first field is token source TOKEN_SOURCE* tokenName = (TOKEN_SOURCE*)impToken; @@ -1987,7 +1988,7 @@ ULONG GetThreadTokenOwnerPid() } } if (hHandle) - ZwClose(hHandle); + NtClose(hHandle); if (impToken) ObDereferenceObject(impToken); return ulResult; diff --git a/Sandboxie/core/svc/DriverAssistLog.cpp b/Sandboxie/core/svc/DriverAssistLog.cpp index b521908b67..7a06be5476 100644 --- a/Sandboxie/core/svc/DriverAssistLog.cpp +++ b/Sandboxie/core/svc/DriverAssistLog.cpp @@ -52,7 +52,8 @@ void DriverAssist::LogMessage() ULONG len = m_workItemLen; ULONG message_number = m_last_message_number; ULONG code = -1; - ULONG status = SbieApi_GetMessage(&message_number, -1, &code, (wchar_t*)m_workItemBuf, len); + ULONG pid = 0; + ULONG status = SbieApi_GetMessage(&message_number, -1, &code, &pid, (wchar_t*)m_workItemBuf, len); if (status == STATUS_BUFFER_TOO_SMALL) { HeapFree(GetProcessHeap(), 0, m_workItemBuf); diff --git a/Sandboxie/core/svc/DriverAssistStart.cpp b/Sandboxie/core/svc/DriverAssistStart.cpp index 8e5a3d980f..a3e124b98e 100644 --- a/Sandboxie/core/svc/DriverAssistStart.cpp +++ b/Sandboxie/core/svc/DriverAssistStart.cpp @@ -136,7 +136,7 @@ ULONG DriverAssist::StartDriverAsync(void *arg) } WCHAR application_version[16]; - wsprintf(application_version, L"%S", MY_VERSION_STRING); + wsprintf(application_version, L"%S", MY_VERSION_COMPAT); if (wcscmp(application_version, driver_version) != 0) { LogEvent(MSG_9234, 0x9154, 0); diff --git a/Sandboxie/core/svc/ProcessServer.cpp b/Sandboxie/core/svc/ProcessServer.cpp index ad6a9b0ceb..69bfa4ef8b 100644 --- a/Sandboxie/core/svc/ProcessServer.cpp +++ b/Sandboxie/core/svc/ProcessServer.cpp @@ -485,7 +485,7 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg) } HANDLE PrimaryTokenHandle = RunSandboxedGetToken( - CallerProcessHandle, CallerInSandbox, req->boxname); + CallerProcessHandle, CallerInSandbox, req->boxname, CallerPid); if (PrimaryTokenHandle) { @@ -659,7 +659,7 @@ WCHAR *ProcessServer::RunSandboxedCopyString( HANDLE ProcessServer::RunSandboxedGetToken( - HANDLE CallerProcessHandle, bool CallerInSandbox, const WCHAR *BoxName) + HANDLE CallerProcessHandle, bool CallerInSandbox, const WCHAR *BoxName, ULONG idProcess) { const ULONG TOKEN_RIGHTS = TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID @@ -769,7 +769,15 @@ HANDLE ProcessServer::RunSandboxedGetToken( // then we want to adjust the dacl in the new token // - ok = RunSandboxedSetDacl(CallerProcessHandle, NewTokenHandle); + WCHAR boxname[48] = { 0 }; + if (CallerInSandbox) + SbieApi_QueryProcess((HANDLE)(ULONG_PTR)idProcess, boxname, NULL, NULL, NULL); + else + wcscpy(boxname, BoxName); + if (SbieApi_QueryConfBool(boxname, L"ExposeBoxedSystem", FALSE)) + ok = RunSandboxedSetDacl(CallerProcessHandle, NewTokenHandle, GENERIC_ALL, TRUE); + else + ok = RunSandboxedSetDacl(CallerProcessHandle, NewTokenHandle, GENERIC_READ, FALSE); } if (! ok) { @@ -795,9 +803,11 @@ HANDLE ProcessServer::RunSandboxedGetToken( BOOL ProcessServer::RunSandboxedSetDacl( - HANDLE CallerProcessHandle, HANDLE NewTokenHandle) + HANDLE CallerProcessHandle, HANDLE NewTokenHandle, DWORD AccessMask, bool useUserSID) { ULONG LastError; + HANDLE hToken; + ULONG len; BOOL ok; // @@ -812,26 +822,39 @@ BOOL ProcessServer::RunSandboxedSetDacl( if (! WorkSpace) return FALSE; + TOKEN_GROUPS *pLogOn = (TOKEN_GROUPS *)WorkSpace; TOKEN_USER *pUser = (TOKEN_USER *)WorkSpace; TOKEN_DEFAULT_DACL *pDacl = (TOKEN_DEFAULT_DACL *)(WorkSpace + 512); + PSID pSid; // // get the token for the calling process, extract the user SID // - HANDLE OldTokenHandle; + - ok = OpenProcessToken(CallerProcessHandle, TOKEN_QUERY, &OldTokenHandle); + ok = OpenProcessToken(CallerProcessHandle, TOKEN_QUERY, &hToken); LastError = GetLastError(); if (! ok) goto finish; - ULONG len; - ok = GetTokenInformation(OldTokenHandle, TokenUser, pUser, 512, &len); - LastError = GetLastError(); + if (useUserSID) + { + ok = GetTokenInformation(hToken, TokenUser, pUser, 512, &len); + LastError = GetLastError(); - CloseHandle(OldTokenHandle); + pSid = pUser->User.Sid; + } + else + { + ok = GetTokenInformation(hToken, TokenLogonSid, pLogOn, 512, &len); + LastError = GetLastError(); + + pSid = pLogOn->Groups[0].Sid; // use the LogonSessionId token + } + + CloseHandle(hToken); if (! ok) goto finish; @@ -851,9 +874,9 @@ BOOL ProcessServer::RunSandboxedSetDacl( pAcl->AclSize += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) // minus SidStart member - + (WORD)GetLengthSid(pUser->User.Sid); + + (WORD)GetLengthSid(pSid); - AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pUser->User.Sid); + AddAccessAllowedAce(pAcl, ACL_REVISION, AccessMask, pSid); ok = SetTokenInformation( NewTokenHandle, TokenDefaultDacl, pDacl, (8192 - 512)); diff --git a/Sandboxie/core/svc/ProcessServer.h b/Sandboxie/core/svc/ProcessServer.h index 0d43c1f60f..a47cc102b1 100644 --- a/Sandboxie/core/svc/ProcessServer.h +++ b/Sandboxie/core/svc/ProcessServer.h @@ -60,9 +60,9 @@ class ProcessServer WCHAR *RunSandboxedCopyString(MSG_HEADER *msg, ULONG ofs, ULONG len); HANDLE RunSandboxedGetToken( HANDLE CallerProcessHandle, bool CallerInSandbox, - const WCHAR *BoxName); + const WCHAR *BoxName, ULONG idProcess); BOOL RunSandboxedSetDacl( - HANDLE CallerProcessHandle, HANDLE NewTokenHandle); + HANDLE CallerProcessHandle, HANDLE NewTokenHandle, DWORD AccessMask, bool useUserSID); BOOL RunSandboxedStartProcess( HANDLE PrimaryTokenHandle, LONG_PTR BoxNameOrModelPid, ULONG CallerProcessId, diff --git a/Sandboxie/core/svc/sbieiniserver.cpp b/Sandboxie/core/svc/sbieiniserver.cpp index c325ee8cda..c74ee33b34 100644 --- a/Sandboxie/core/svc/sbieiniserver.cpp +++ b/Sandboxie/core/svc/sbieiniserver.cpp @@ -233,7 +233,7 @@ MSG_HEADER *SbieIniServer::Handler2(MSG_HEADER *msg) MSG_HEADER *SbieIniServer::GetVersion(MSG_HEADER *msg) { WCHAR ver_str[16]; - wsprintf(ver_str, L"%S", MY_VERSION_STRING); + wsprintf(ver_str, L"%S", MY_VERSION_COMPAT); ULONG ver_len = wcslen(ver_str); ULONG rpl_len = sizeof(SBIE_INI_GET_USER_RPL) diff --git a/Sandboxie/core/svc/serviceserver.cpp b/Sandboxie/core/svc/serviceserver.cpp index 78d7cb4e0b..4e81b0402a 100644 --- a/Sandboxie/core/svc/serviceserver.cpp +++ b/Sandboxie/core/svc/serviceserver.cpp @@ -59,11 +59,11 @@ MSG_HEADER *ServiceServer::Handler(void *_this, MSG_HEADER *msg) HANDLE idProcess = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId(); - if (msg->msgid == MSGID_SERVICE_START) + if (msg->msgid == MSGID_SERVICE_START) // start unboxed service on the host return pThis->StartHandler(msg, idProcess); - if (msg->msgid == MSGID_SERVICE_RUN) - return pThis->RunHandler(msg, idProcess); + if (msg->msgid == MSGID_SERVICE_RUN) // start a sandboxed service inside a particular box + return pThis->RunHandler(msg, idProcess); HANDLE idThread = (HANDLE)(ULONG_PTR)PipeServer::GetCallerThreadId(); @@ -210,6 +210,8 @@ MSG_HEADER *ServiceServer::QueryHandler(MSG_HEADER *msg) SERVICE_QUERY_RPL *rpl = (SERVICE_QUERY_RPL *)LONG_REPLY(rpl_len); if (rpl) { + memzero(((UCHAR *)rpl) + sizeof(MSG_HEADER), rpl_len - sizeof(MSG_HEADER)); + if (req->with_service_status) { ULONG len = sizeof(rpl->service_status); diff --git a/Sandboxie/core/svc/serviceserver.h b/Sandboxie/core/svc/serviceserver.h index 46f764ee97..5f451b66c7 100644 --- a/Sandboxie/core/svc/serviceserver.h +++ b/Sandboxie/core/svc/serviceserver.h @@ -56,6 +56,8 @@ class ServiceServer bool CanCallerDoElevation( HANDLE idProcess, const WCHAR *ServiceName, ULONG *pSessionId); + bool CanAccessSCM(HANDLE idProcess); + static void ReportError2218(HANDLE idProcess, ULONG errlvl); static WCHAR *BuildPathForStartExe( @@ -68,7 +70,8 @@ class ServiceServer HANDLE idProcess, ULONG idSession, const WCHAR *devmap, const WCHAR *svcname, const WCHAR *path); - void SetTokenDefaultDacl(HANDLE hNewToken, HANDLE idProcess); + void SetTokenCustomDacl( + HANDLE hNewToken, HANDLE idProcess, DWORD AccessMask, bool useUserSID); MSG_HEADER *UacHandler( MSG_HEADER *msg, HANDLE idProcess, HANDLE idThread); diff --git a/Sandboxie/core/svc/serviceserver2.cpp b/Sandboxie/core/svc/serviceserver2.cpp index 6bb409093c..3eb516d67d 100644 --- a/Sandboxie/core/svc/serviceserver2.cpp +++ b/Sandboxie/core/svc/serviceserver2.cpp @@ -29,6 +29,7 @@ #include "common/defines.h" #include "common/my_version.h" #include "core/dll/sbiedll.h" +#include #define MISC_H_WITHOUT_WIN32_NTDDK_H #include "misc.h" @@ -85,6 +86,69 @@ bool ServiceServer::CanCallerDoElevation( return true; } +//--------------------------------------------------------------------------- +// CanCallerDoElevation +//--------------------------------------------------------------------------- + + +bool ServiceServer::CanAccessSCM(HANDLE idProcess) +{ + WCHAR boxname[48] = { 0 }; + WCHAR imagename[128] = { 0 }; + SbieApi_QueryProcess(idProcess, boxname, imagename, NULL, NULL); // if this fail we take the global config if present + if (SbieApi_QueryConfBool(boxname, L"UnrestrictedSCM", FALSE)) + return true; + + // + // Note: when RpcSs and DcomLaunch are not running as system, thay still are alowed to access the SCM + // + if (!SbieApi_QueryConfBool(boxname, L"ProtectRpcSs", FALSE)) + { + if (_wcsicmp(imagename, SANDBOXIE L"DcomLaunch.exe") == 0) + return true; + } + + bool bRet = false; + + PSECURITY_DESCRIPTOR securityDescriptor = NULL; + SC_HANDLE scHandle = OpenSCManager(NULL, NULL, READ_CONTROL); + if (scHandle != NULL) { + GetSecurityInfo(scHandle, SE_SERVICE, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &securityDescriptor); + CloseServiceHandle(scHandle); + } + if (!securityDescriptor) + return bRet; + + /*HANDLE hToken = NULL; + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)(UINT_PTR)idProcess); + if (hProcess != NULL) { + OpenProcessToken(hProcess, TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &hToken); + CloseHandle(hProcess); + }*/ + + HANDLE hToken = (HANDLE)SbieApi_QueryProcessInfo(idProcess, 'ptok'); + if (hToken) { + HANDLE hImpersonatedToken = NULL; + if (DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken)) { + DWORD accessRights = SC_MANAGER_ALL_ACCESS; + GENERIC_MAPPING mapping = { 0xFFFFFFFF }; + PRIVILEGE_SET privileges = { 0 }; + DWORD grantedAccess = 0, privilegesLength = sizeof(privileges); + BOOL result = FALSE; + //::MapGenericMask(&genericAccessRights, &mapping); + if (::AccessCheck(securityDescriptor, hImpersonatedToken, accessRights, + &mapping, &privileges, &privilegesLength, &grantedAccess, &result)) { + bRet = (result == TRUE); + } + CloseHandle(hImpersonatedToken); + } + CloseHandle(hToken); + } + LocalFree(securityDescriptor); + + return bRet; +} + //--------------------------------------------------------------------------- // ReportError2218 @@ -188,7 +252,7 @@ MSG_HEADER *ServiceServer::RunHandler(MSG_HEADER *msg, HANDLE idProcess) ULONG error; ULONG idSession; - if (! CanCallerDoElevation(idProcess, req->name, &idSession)) + if (! CanCallerDoElevation(idProcess, req->name, &idSession) || !CanAccessSCM(idProcess)) error = ERROR_ACCESS_DENIED; else { WCHAR *svcname = NULL; @@ -252,7 +316,13 @@ ULONG ServiceServer::RunHandler2( } if (ok) { - SetTokenDefaultDacl(hNewToken, idProcess); + WCHAR boxname[48] = { 0 }; + SbieApi_QueryProcess(idProcess, boxname, NULL, NULL, NULL); // if this fail we take the global config if present + if (SbieApi_QueryConfBool(boxname, L"ExposeBoxedSystem", FALSE)) + SetTokenCustomDacl(hNewToken, idProcess, GENERIC_ALL, TRUE); + else //if (_wcsicmp(svcname, L"MSIServer") == 0) + // The MSIServer needs to be extra allowances to work correctly + SetTokenCustomDacl(hNewToken, idProcess, GENERIC_READ, FALSE); } if (ok) { @@ -295,11 +365,11 @@ ULONG ServiceServer::RunHandler2( //--------------------------------------------------------------------------- -// SetTokenDefaultDacl +// SetTokenCustomDacl //--------------------------------------------------------------------------- -void ServiceServer::SetTokenDefaultDacl(HANDLE hNewToken, HANDLE idProcess) +void ServiceServer::SetTokenCustomDacl(HANDLE hNewToken, HANDLE idProcess, DWORD AccessMask, bool useUserSID) { static UCHAR AnonymousLogonSid[12] = { 1, // Revision @@ -325,9 +395,11 @@ void ServiceServer::SetTokenDefaultDacl(HANDLE hNewToken, HANDLE idProcess) if (! WorkSpace) return; + TOKEN_GROUPS *pLogOn = (TOKEN_GROUPS *)WorkSpace; TOKEN_USER *pUser = (TOKEN_USER *)WorkSpace; TOKEN_DEFAULT_DACL *pDacl = (TOKEN_DEFAULT_DACL *)(WorkSpace + 128); - + PSID pSid; + // // get the token for the calling process, extract the user SID // @@ -344,35 +416,46 @@ void ServiceServer::SetTokenDefaultDacl(HANDLE hNewToken, HANDLE idProcess) if (! ok) goto finish; - ok = GetTokenInformation(hToken, TokenUser, pUser, 128, &len); - - CloseHandle(hToken); - - if (! ok) - goto finish; - - // - // in Sandboxie version 4, the primary process token is going to be - // the anonymous token which isn't very useful here, so get the - // textual SID string and convert it into a SID value - // - - if (memcmp(pUser->User.Sid, AnonymousLogonSid, - sizeof(AnonymousLogonSid)) == 0) { - - PSID TempSid; - WCHAR SidString[96]; - SbieApi_QueryProcess(idProcess, NULL, NULL, SidString, NULL); - if (SidString[0]) { - if (ConvertStringSidToSid(SidString, &TempSid)) { - memcpy(pUser + 1, TempSid, GetLengthSid(TempSid)); - pUser->User.Sid = (PSID)(pUser + 1); - LocalFree(TempSid); - } - } - } - - // + if (useUserSID) + { + ok = GetTokenInformation(hToken, TokenUser, pUser, 128, &len); + + // + // in Sandboxie version 4, the primary process token is going to be + // the anonymous token which isn't very useful here, so get the + // textual SID string and convert it into a SID value + // + + if (ok && memcmp(pUser->User.Sid, AnonymousLogonSid, + sizeof(AnonymousLogonSid)) == 0) { + + PSID TempSid; + WCHAR SidString[96]; + SbieApi_QueryProcess(idProcess, NULL, NULL, SidString, NULL); + if (SidString[0]) { + if (ConvertStringSidToSid(SidString, &TempSid)) { + memcpy(pUser + 1, TempSid, GetLengthSid(TempSid)); + pUser->User.Sid = (PSID)(pUser + 1); + LocalFree(TempSid); + } + } + } + + pSid = pUser->User.Sid; + } + else + { + ok = GetTokenInformation(hToken, TokenLogonSid, pLogOn, 128, &len); + + pSid = pLogOn->Groups[0].Sid; // use the LogonSessionId token + } + + CloseHandle(hToken); + + if (!ok) + goto finish; + + // // extract the default DACL, update it and store it back // @@ -385,9 +468,9 @@ void ServiceServer::SetTokenDefaultDacl(HANDLE hNewToken, HANDLE idProcess) pAcl->AclSize += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) // minus SidStart member - + (WORD)GetLengthSid(pUser->User.Sid); + + (WORD)GetLengthSid(pSid); - AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pUser->User.Sid); + AddAccessAllowedAce(pAcl, ACL_REVISION, AccessMask, pSid); ok = SetTokenInformation( hNewToken, TokenDefaultDacl, pDacl, (1024 - 128)); diff --git a/SandboxiePlus/MiscHelpers/Common/PanelView.h b/SandboxiePlus/MiscHelpers/Common/PanelView.h index 2d1338f439..66e6677b44 100644 --- a/SandboxiePlus/MiscHelpers/Common/PanelView.h +++ b/SandboxiePlus/MiscHelpers/Common/PanelView.h @@ -133,12 +133,12 @@ private slots: }; #include "TreeViewEx.h" +#include "SortFilterProxyModel.h" -template -class CPanelViewImpl: public CPanelWidget +class CPanelViewEx: public CPanelWidget { public: - CPanelViewImpl(T* pModel, QWidget *parent = 0) : CPanelWidget(parent) + CPanelViewEx(QAbstractItemModel* pModel, QWidget *parent = 0) : CPanelWidget(parent) { m_pModel = pModel; @@ -162,9 +162,11 @@ class CPanelViewImpl: public CPanelWidget m_pTreeList->setColumnReset(1); //connect(m_pTreeList, SIGNAL(ResetColumns()), m_pTreeList, SLOT(OnResetColumns())); //connect(m_pBoxTree, SIGNAL(ColumnChanged(int, bool)), this, SLOT(OnColumnsChanged())); + + m_pMainLayout->addWidget(CFinder::AddFinder(m_pTreeList, m_pSortProxy)); } protected: - T* m_pModel; + QAbstractItemModel* m_pModel; QSortFilterProxyModel* m_pSortProxy; }; \ No newline at end of file diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.cpp b/SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.cpp new file mode 100644 index 0000000000..87312ea85a --- /dev/null +++ b/SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.cpp @@ -0,0 +1,346 @@ +/* + * + * Copyright (c) 2020, David Xanatos + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "stdafx.h" +#include "BoxBorder.h" +#include "../SbieAPI.h" + +#include + +typedef HRESULT(*P_DwmIsCompositionEnabled)(BOOL *enabled); +typedef HRESULT(*P_DwmGetWindowAttribute)(HWND hWnd, DWORD dwAttribute, void *pvAttribute, DWORD cbAttribute); + +struct SBoxBorder +{ + CSandBox* pCurrentBox; + COLORREF BorderColor; + int BorderMode; + int BorderWidth; + + ULONG ActivePid; + HWND ActiveWnd; + RECT ActiveRect; + RECT TitleRect; + int TitleState; + + BOOL IsBorderVisible; + HWND BorderWnd; + HBRUSH BorderBrush; + + int ThumbWidth; + int ThumbHeight; + + P_DwmIsCompositionEnabled DwmIsCompositionEnabled; + P_DwmGetWindowAttribute DwmGetWindowAttribute; +}; + +const WCHAR *Sandboxie_WindowClassName = L"Sandboxie_BorderWindow"; + +CBoxBorder::CBoxBorder(CSbieAPI* pApi, QObject* parent) : QObject(parent) +{ + m_Api = pApi; + + m = new SBoxBorder; + + m->pCurrentBox = NULL; + m->BorderColor = RGB(0, 0, 0); + m->BorderMode = 0; + m->BorderWidth = 0; + + m->ActivePid = 0; + m->ActiveWnd = NULL; + + m->IsBorderVisible = FALSE; + m->BorderWnd = NULL; + m->BorderBrush = NULL; + + m->ThumbWidth = GetSystemMetrics(SM_CXHTHUMB); + m->ThumbHeight = GetSystemMetrics(SM_CYVTHUMB); + + HMODULE dwmapi = LoadLibrary(L"dwmapi.dll"); + if (dwmapi) { + m->DwmIsCompositionEnabled = (P_DwmIsCompositionEnabled)GetProcAddress(dwmapi, "DwmIsCompositionEnabled"); + if (m->DwmIsCompositionEnabled) { + m->DwmGetWindowAttribute = (P_DwmGetWindowAttribute)GetProcAddress(dwmapi, "DwmGetWindowAttribute"); + if (!m->DwmGetWindowAttribute) + m->DwmIsCompositionEnabled = NULL; + } + } + + WNDCLASSEX wc; + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; + wc.lpfnWndProc = ::DefWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = NULL; // (HINSTANCE)::GetModuleHandle(NULL); + wc.hIcon = NULL; // ::LoadIcon(wc.hInstance, L"AAAPPICON"); + wc.hCursor = NULL; // ::LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = Sandboxie_WindowClassName; + wc.hIconSm = NULL; + if (ATOM lpClassName = RegisterClassEx(&wc)) + { + m->BorderWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, (LPCWSTR)lpClassName, + Sandboxie_WindowClassName, WS_POPUP | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); + } + if (!m->BorderWnd) + return; + + SetLayeredWindowAttributes(m->BorderWnd, 0, 192, LWA_ALPHA); + ::ShowWindow(m->BorderWnd, SW_HIDE); + + m_uTimerID = startTimer(10); +} + +CBoxBorder::~CBoxBorder() +{ + killTimer(m_uTimerID); + + if (m->BorderWnd) + { + DestroyWindow(m->BorderWnd); + m->BorderWnd = NULL; + } + + delete m; +} + +void CBoxBorder::timerEvent(QTimerEvent* pEvent) +{ + if (pEvent->timerId() != m_uTimerID) + return; + + HWND hWnd = GetForegroundWindow(); + if (!hWnd) + return; + ULONG Style = GetWindowLong(hWnd, GWL_STYLE); + if (!(Style & WS_VISIBLE)) + return; + ULONG pid = 0; + GetWindowThreadProcessId(hWnd, &pid); + + CSandBoxPtr pProcessBox = m_Api->GetBoxByProcessId(pid); + + if (m->pCurrentBox != pProcessBox.data()) + { + m->pCurrentBox = pProcessBox.data(); + if(!m->pCurrentBox) + m->BorderMode = 0; + else + { + m->BorderMode = 1; + m->BorderColor = RGB(255, 255, 0); + m->BorderWidth = 6; + + QStringList BorderCfg = pProcessBox->GetText("BorderColor").split(","); + if (BorderCfg.first().left(1) == L'#') + { + bool ok = false; + m->BorderColor = BorderCfg.first().mid(1).toInt(&ok, 16); + if(!ok) + m->BorderColor = RGB(255, 255, 0); + else + { + if (BorderCfg.count() >= 2) + { + QString StrMode = BorderCfg.at(1); + if (StrMode.compare("ttl", Qt::CaseInsensitive) == 0) + m->BorderMode = 2; + else if (StrMode.compare("off", Qt::CaseInsensitive) == 0) + m->BorderMode = 0; + } + + if (BorderCfg.count() >= 3) + { + m->BorderWidth = BorderCfg.at(2).toInt(); + if (!m->BorderWidth) + m->BorderWidth = 6; + } + } + } + + HBRUSH hbr = CreateSolidBrush(m->BorderColor); + SetClassLongPtr(m->BorderWnd, GCLP_HBRBACKGROUND, (LONG_PTR)hbr); + if (m->BorderBrush) + DeleteObject(m->BorderBrush); + m->BorderBrush = hbr; + } + } + + if (m->BorderMode == 0) // no border enabled or unsandboxed + { + m->ActiveWnd = NULL; + m->ActivePid = 0; + + if (m->IsBorderVisible) + { + ::ShowWindow(m->BorderWnd, SW_HIDE); + m->IsBorderVisible = FALSE; + } + } + else + { + RECT rect; + GetActiveWindowRect(hWnd, &rect); + if (NothingChanged(hWnd, &rect, pid)) + return; + + if (m->IsBorderVisible) + ::ShowWindow(m->BorderWnd, SW_HIDE); + m->IsBorderVisible = FALSE; + + m->ActiveWnd = hWnd; + m->ActivePid = pid; + memcpy(&m->ActiveRect, &rect, sizeof(RECT)); + m->TitleState = 0; + if (rect.right - rect.left <= 2 || rect.bottom - rect.top <= 2) + return; + + HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONULL); + if (!hMonitor) + return; + MONITORINFO Monitor; + memset(&Monitor, 0, sizeof(MONITORINFO)); + Monitor.cbSize = sizeof(MONITORINFO); + if (!GetMonitorInfo(hMonitor, &Monitor)) + return; + + const RECT *Desktop = &Monitor.rcMonitor; + if (rect.left <= Desktop->left && rect.top <= Desktop->top && + rect.right >= Desktop->right && rect.bottom >= Desktop->bottom && + (Style & WS_CAPTION) != WS_CAPTION) + return; + + if (m->BorderMode == 2) { + if(!IsMounseOnTitle(hWnd, &rect, Desktop)) + return; + } + + Desktop = &Monitor.rcWork; + + int ax = rect.left; + if (ax < Desktop->left) + ax = Desktop->left; + int ay = rect.top; + if (ay < Desktop->top) + ay = Desktop->top; + int aw = -ax; + if (rect.right <= Desktop->right) + aw += rect.right; + else + aw += Desktop->right; + int ah = -ay; + if (rect.bottom <= Desktop->bottom) + ah += rect.bottom; + else + ah += Desktop->bottom; + + + POINT Points[10]; + int PointCount = 0; + +#define ADD_POINT(xx,yy) \ + Points[PointCount].x = (xx); \ + Points[PointCount].y = (yy); \ + PointCount++; + +#define ADD_SQUARE(_w,_h,_b) \ + ADD_POINT(0 + _b, 0 + _b); \ + ADD_POINT(_w - _b, 0 + _b); \ + ADD_POINT(_w - _b, _h - _b); \ + ADD_POINT(0 + _b, _h - _b); \ + ADD_POINT(0 + _b, 0 + _b); + + ADD_SQUARE(aw, ah, 0); + ADD_SQUARE(aw, ah, m->BorderWidth); + + HRGN hrgn = CreatePolygonRgn(Points, PointCount, ALTERNATE); + SetWindowRgn(m->BorderWnd, hrgn, TRUE); + SetWindowPos(m->BorderWnd, NULL, ax, ay, aw, ah, SWP_SHOWWINDOW | SWP_NOACTIVATE); + + m->IsBorderVisible = TRUE; + } +} + +bool CBoxBorder::NothingChanged(struct HWND__* hWnd, struct tagRECT* rect, quint32 pid) +{ + if (pid == m->ActivePid && hWnd == m->ActiveWnd) { + if (memcmp(rect, &m->ActiveRect, sizeof(RECT)) == 0) { + if (!m->TitleState || m->TitleState == (CheckMousePointer() ? 1 : -1)) + return true; + } + } + return false; +} + +void CBoxBorder::GetActiveWindowRect(struct HWND__* hWnd, struct tagRECT* rect) +{ + if (m->DwmIsCompositionEnabled) { + BOOL bEnabled = FALSE; + if (SUCCEEDED(m->DwmIsCompositionEnabled(&bEnabled)) && bEnabled) { + const ULONG DWMWA_EXTENDED_FRAME_BOUNDS = 9; + if (SUCCEEDED(m->DwmGetWindowAttribute(hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, rect, sizeof(RECT)))) + return; + } + } + GetWindowRect(hWnd, rect); +} + +bool CBoxBorder::IsMounseOnTitle(struct HWND__* hWnd, struct tagRECT* rect, const struct tagRECT* Desktop) +{ + TITLEBARINFO TitleBarInfo; + TitleBarInfo.cbSize = sizeof(TITLEBARINFO); + GetTitleBarInfo(hWnd, &TitleBarInfo); + memcpy(&m->TitleRect, &TitleBarInfo.rcTitleBar, sizeof(RECT)); + + if (m->TitleRect.left < rect->left || m->TitleRect.left > rect->right || + m->TitleRect.top < rect->top || m->TitleRect.top > rect->bottom || + m->TitleRect.right < rect->left || m->TitleRect.right > rect->right || + m->TitleRect.bottom < rect->top || m->TitleRect.bottom > rect->bottom || + m->TitleRect.right - m->TitleRect.left <= m->ThumbWidth || + m->TitleRect.bottom - m->TitleRect.top <= m->ThumbHeight + ) { + m->TitleRect.left = rect->left; + m->TitleRect.top = rect->top; + m->TitleRect.right = rect->right; + m->TitleRect.bottom = rect->top + m->ThumbHeight * 2; + } + + m->TitleRect.top -= 8; + if (m->TitleRect.top < Desktop->top) + m->TitleRect.top = Desktop->top; + + m->TitleState = CheckMousePointer() ? 1 : -1; + if (m->TitleState == -1) + return false; + return true; +} + +bool CBoxBorder::CheckMousePointer() +{ + POINT Cursor; + if (GetCursorPos(&Cursor) + && Cursor.x >= m->TitleRect.left + && Cursor.x <= m->TitleRect.right + && Cursor.y >= m->TitleRect.top + && Cursor.y <= m->TitleRect.bottom) + return true; + return false; +} diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.h b/SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.h new file mode 100644 index 0000000000..5101fd2abe --- /dev/null +++ b/SandboxiePlus/QSbieAPI/Sandboxie/BoxBorder.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2020, David Xanatos + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +#include "../qsbieapi_global.h" + +class CSbieAPI; + +class QSBIEAPI_EXPORT CBoxBorder: public QObject +{ + Q_OBJECT +public: + CBoxBorder(CSbieAPI* pApi, QObject* parent = 0); + virtual ~CBoxBorder(); + +protected: + void timerEvent(QTimerEvent* pEvent); + int m_uTimerID; + + CSbieAPI* m_Api; + +private: + struct SBoxBorder* m; + + void GetActiveWindowRect(struct HWND__* hWnd, struct tagRECT* rect); + bool NothingChanged(struct HWND__* hWnd, struct tagRECT* rect, quint32 pid); + bool IsMounseOnTitle(struct HWND__* hWnd, struct tagRECT* rect, const struct tagRECT* Desktop); + bool CheckMousePointer(); +}; + diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.cpp b/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.cpp index 78bc5860a1..ae328a3c4d 100644 --- a/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.cpp +++ b/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.cpp @@ -153,4 +153,9 @@ bool CBoxedProcess::IsSuspended() const CloseHandle(hThreadSnap); return isSuspended; +} + +QString CBoxedProcess::GetBoxName() const +{ + return m_pBox->GetName(); } \ No newline at end of file diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.h b/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.h index 00566208ad..66137f4e15 100644 --- a/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.h +++ b/SandboxiePlus/QSbieAPI/Sandboxie/BoxedProcess.h @@ -45,6 +45,8 @@ class QSBIEAPI_EXPORT CBoxedProcess : public QObject virtual SB_STATUS SetSuspend(bool bSet); virtual bool IsSuspended() const; + virtual QString GetBoxName() const; + protected: friend class CSbieAPI; diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp index b67dd9a304..d2d0c8f71f 100644 --- a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp +++ b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp @@ -96,14 +96,18 @@ SB_STATUS CSandBox::CleanBox() SB_STATUS CSandBox::RenameBox(const QString& NewName) { - if (QDir(m_pAPI->Nt2DosPath(m_FilePath)).exists()) - return SB_ERR("A sandbox must be emptied before it can be renamed."); - return RenameSection(NewName); + if (QDir(m_FilePath).exists()) + return SB_ERR(tr("A sandbox must be emptied before it can be renamed.")); + if(NewName.length() > 32) + return SB_ERR(tr("The sandbox name can not be longer than 32 charakters.")); + + return RenameSection(QString(NewName).replace(" ", "_")); } SB_STATUS CSandBox::RemoveBox() { - if (QDir(m_pAPI->Nt2DosPath(m_FilePath)).exists()) - return SB_ERR("A sandbox must be emptied before it can be deleted."); + if (QDir(m_FilePath).exists()) + return SB_ERR(tr("A sandbox must be emptied before it can be deleted.")); + return RemoveSection(); } diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h index b4d55624ad..e32a1989b3 100644 --- a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h +++ b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h @@ -34,6 +34,10 @@ class QSBIEAPI_EXPORT CSandBox : public CIniSection virtual QString GetName() const { return m_Name; } + virtual QString GetFileRoot() const { return m_FilePath; } + virtual QString GetRegRoot() const { return m_RegPath; } + virtual QString GetIpcRoot() const { return m_IpcPath; } + virtual QMap GetProcessList() const { return m_ProcessList; } virtual SB_STATUS RunStart(const QString& Command); diff --git a/SandboxiePlus/QSbieAPI/SbieAPI.cpp b/SandboxiePlus/QSbieAPI/SbieAPI.cpp index b44f898223..6ab7ccc5d8 100644 --- a/SandboxiePlus/QSbieAPI/SbieAPI.cpp +++ b/SandboxiePlus/QSbieAPI/SbieAPI.cpp @@ -34,7 +34,6 @@ typedef long NTSTATUS; #include "..\..\Sandboxie\core\svc\ProcessWire.h" #include "..\..\Sandboxie\core\svc\sbieiniwire.h" - struct SSbieAPI { SSbieAPI() @@ -112,6 +111,8 @@ CSbieAPI::CSbieAPI(QObject* parent) : QThread(parent) { m = new SSbieAPI(); + m_bReloadPending = false; + connect(&m_IniWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(OnIniChanged(const QString&))); } @@ -122,6 +123,35 @@ CSbieAPI::~CSbieAPI() delete m; } +bool CSbieAPI::IsSbieCtrlRunning() +{ + static const WCHAR *SbieCtrlMutexName = SANDBOXIE L"_SingleInstanceMutex_Control"; + + HANDLE hSbieCtrlMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, SbieCtrlMutexName); + if (hSbieCtrlMutex) { + CloseHandle(hSbieCtrlMutex); + return true; + } + return false; +} + +bool CSbieAPI::TerminateSbieCtrl() +{ + static const WCHAR *WindowClassName = L"SandboxieControlWndClass"; + + HWND hwnd = FindWindow(WindowClassName, NULL); + if (hwnd) { + PostMessage(hwnd, WM_QUIT, 0, 0); + } + + for (int i = 0; i < 10 && hwnd != NULL; i++) { + QThread::msleep(100); + hwnd = FindWindow(WindowClassName, NULL); + } + + return hwnd == NULL; +} + CSandBox* CSbieAPI::NewSandBox(const QString& BoxName, class CSbieAPI* pAPI) { return new CSandBox(BoxName, pAPI); @@ -132,7 +162,7 @@ CBoxedProcess* CSbieAPI::NewBoxedProcess(quint64 ProcessId, class CSandBox* pBox return new CBoxedProcess(ProcessId, pBox); } -SB_STATUS CSbieAPI::Connect(bool takeOver, bool andLoad) +SB_STATUS CSbieAPI::Connect() { if (IsConnected()) return SB_OK; @@ -169,12 +199,6 @@ SB_STATUS CSbieAPI::Connect(bool takeOver, bool andLoad) m_IniPath = GetIniPath(&bHome); qDebug() << "Config file:" << m_IniPath << (bHome ? "(home)" : "(system)"); - if (takeOver) - TakeOver(); - - if (andLoad) - ReloadBoxes(); - emit StatusChanged(); return SB_OK; } @@ -501,6 +525,15 @@ SB_STATUS CSbieAPI::WatchIni(bool bEnable) } void CSbieAPI::OnIniChanged(const QString &path) +{ + if (!m_bReloadPending) + { + m_bReloadPending = true; + QTimer::singleShot(500, this, SLOT(OnReloadConfig())); + } +} + +void CSbieAPI::OnReloadConfig() { ReloadConfig(); } @@ -603,7 +636,7 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, QPr return SB_OK; } -SB_STATUS CSbieAPI::ReloadBoxes(bool bFull) +SB_STATUS CSbieAPI::ReloadBoxes() { QMap OldSandBoxes = m_SandBoxes; @@ -615,20 +648,16 @@ SB_STATUS CSbieAPI::ReloadBoxes(bool bFull) if (!IsBoxEnabled(BoxName)) continue; - CSandBoxPtr pBox = OldSandBoxes.take(BoxName); + CSandBoxPtr pBox = OldSandBoxes.take(BoxName.toLower()); if (!pBox) { pBox = CSandBoxPtr(NewSandBox(BoxName, this)); - m_SandBoxes.insert(BoxName, pBox); - - SetBoxPaths(pBox); + m_SandBoxes.insert(BoxName.toLower(), pBox); } - else if (!bFull) - continue; - pBox->UpdateDetails(); + UpdateBoxPaths(pBox); - // todo: + pBox->UpdateDetails(); } foreach(const QString& BoxName, OldSandBoxes.keys()) @@ -761,7 +790,7 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox) pBox->m_ProcessList.insert(ProcessId, pProcess); m_BoxedProxesses.insert(ProcessId, pProcess); - SetProcessInfo(pProcess); + UpdateProcessInfo(pProcess); pProcess->InitProcessInfo(); } @@ -814,7 +843,7 @@ SB_STATUS CSbieAPI__QueryBoxPath(SSbieAPI* m, const WCHAR *box_name, WCHAR *out_ return SB_OK; } -SB_STATUS CSbieAPI::SetBoxPaths(const CSandBoxPtr& pSandBox) +SB_STATUS CSbieAPI::UpdateBoxPaths(const CSandBoxPtr& pSandBox) { wstring boxName = pSandBox->GetName().toStdWString(); @@ -825,20 +854,20 @@ SB_STATUS CSbieAPI::SetBoxPaths(const CSandBoxPtr& pSandBox) if (!Status) return Status; - wstring FileRoot(filePathLength + 1, '0'); - wstring KeyRoot(filePathLength + 1, '0'); - wstring IpcRoot(filePathLength + 1, '0'); + wstring FileRoot(filePathLength / 2 + 1, '\0'); + wstring KeyRoot(keyPathLength / 2 + 1, '\0'); + wstring IpcRoot(ipcPathLength / 2 + 1, '\0'); Status = CSbieAPI__QueryBoxPath(m, boxName.c_str(), (WCHAR*)FileRoot.data(), (WCHAR*)KeyRoot.data(), (WCHAR*)IpcRoot.data(), &filePathLength, &keyPathLength, &ipcPathLength); if (!Status) return Status; - pSandBox->m_FilePath = QString::fromStdWString(FileRoot); + pSandBox->m_FilePath = Nt2DosPath(QString::fromStdWString(FileRoot)); pSandBox->m_RegPath = QString::fromStdWString(KeyRoot); pSandBox->m_IpcPath = QString::fromStdWString(IpcRoot); return SB_OK; } -SB_STATUS CSbieAPI::SetProcessInfo(const CBoxedProcessPtr& pProcess) +SB_STATUS CSbieAPI::UpdateProcessInfo(const CBoxedProcessPtr& pProcess) { //WCHAR box_name_wchar34[34] = { 0 }; WCHAR image_name[MAX_PATH]; @@ -849,7 +878,6 @@ SB_STATUS CSbieAPI::SetProcessInfo(const CBoxedProcessPtr& pProcess) //__declspec(align(8)) UNICODE_STRING64 BoxName = { 0, sizeof(box_name_wchar34) , (ULONG64)box_name_wchar34 }; __declspec(align(8)) UNICODE_STRING64 ImageName = { 0, sizeof(image_name), (ULONG64)image_name }; //__declspec(align(8)) UNICODE_STRING64 SidString = { 0, sizeof(sid), (ULONG64)sid }; - __declspec(align(8)) UNICODE_STRING64 SidString; __declspec(align(8)) ULONG64 parms[API_NUM_ARGS]; API_QUERY_PROCESS_ARGS *args = (API_QUERY_PROCESS_ARGS*)parms; @@ -874,6 +902,14 @@ SB_STATUS CSbieAPI::SetProcessInfo(const CBoxedProcessPtr& pProcess) return SB_OK; } +CSandBoxPtr CSbieAPI::GetBoxByProcessId(quint64 ProcessId) const +{ + CBoxedProcessPtr pProcess = m_BoxedProxesses.value(ProcessId); + if (!pProcess) + return CSandBoxPtr(); + return m_SandBoxes.value(pProcess->GetBoxName().toLower()); +} + SB_STATUS CSbieAPI::TerminateAll(const QString& BoxName) { PROCESS_KILL_ALL_REQ req; @@ -1122,9 +1158,9 @@ SB_STATUS CSbieAPI::ReloadConfig(quint32 SessionId) if (!NT_SUCCESS(status)) return SB_ERR(status); - emit LogMessage("Sandboxie config has been reloaded."); + emit LogMessage("Sandboxie config has been reloaded.", false); - ReloadBoxes(true); + ReloadBoxes(); return SB_OK; } @@ -1178,6 +1214,7 @@ bool CSbieAPI::GetLog() ULONG Length = ARRAYSIZE(Buffer); ULONG MessageId = 0; + ULONG ProcessId = 0; ULONG MessageNum = m->lastMessageNum; __declspec(align(8)) UNICODE_STRING64 msgtext = { 0, (USHORT)Length, (ULONG64)Buffer }; @@ -1190,6 +1227,7 @@ bool CSbieAPI::GetLog() args->session_id.val = m->sessionId; args->msgid.val = &MessageId; args->msgtext.val = &msgtext; + args->process_id.val = &ProcessId; NTSTATUS status = m->IoControl(parms); if (!NT_SUCCESS(status)) @@ -1208,7 +1246,8 @@ bool CSbieAPI::GetLog() ULONG str2_len = wcslen(str2); QString Message = CSbieAPI__FormatSbieMsg(m, MessageId, str1, str2); - + if(ProcessId != 4) // if its not from the driver add the pid + Message += tr(" by process: %1").arg(ProcessId); emit LogMessage(Message); return true; diff --git a/SandboxiePlus/QSbieAPI/SbieAPI.h b/SandboxiePlus/QSbieAPI/SbieAPI.h index 88edb4ea24..83c1bcda0c 100644 --- a/SandboxiePlus/QSbieAPI/SbieAPI.h +++ b/SandboxiePlus/QSbieAPI/SbieAPI.h @@ -62,7 +62,10 @@ class QSBIEAPI_EXPORT CSbieAPI : public QThread CSbieAPI(QObject* parent = 0); virtual ~CSbieAPI(); - virtual SB_STATUS Connect(bool takeOver = false, bool andLoad = true); + static bool IsSbieCtrlRunning(); + static bool TerminateSbieCtrl(); + + virtual SB_STATUS Connect(); virtual SB_STATUS Disconnect(); virtual bool IsConnected() const; @@ -77,7 +80,7 @@ class QSBIEAPI_EXPORT CSbieAPI : public QThread virtual void UpdateDriveLetters(); virtual QString Nt2DosPath(QString NtPath) const; - virtual SB_STATUS ReloadBoxes(bool bFull = false); + virtual SB_STATUS ReloadBoxes(); virtual SB_STATUS CreateBox(const QString& BoxName); virtual SB_STATUS UpdateProcesses(bool bKeep); @@ -87,6 +90,9 @@ class QSBIEAPI_EXPORT CSbieAPI : public QThread virtual int TotalProcesses() const { return m_BoxedProxesses.count(); } + virtual CSandBoxPtr GetBoxByProcessId(quint64 ProcessId) const; + virtual CSandBoxPtr GetBoxByName(const QString &BoxName) const { return m_SandBoxes.value(BoxName.toLower()); } + virtual SB_STATUS TerminateAll(); enum ESetMode @@ -112,11 +118,12 @@ class QSBIEAPI_EXPORT CSbieAPI : public QThread signals: void StatusChanged(); - void LogMessage(const QString& Message); + void LogMessage(const QString& Message, bool bNotify = true); private slots: //virtual void OnMonitorEntry(quint64 ProcessId, quint32 Type, const QString& Value); virtual void OnIniChanged(const QString &path); + virtual void OnReloadConfig(); protected: friend class CSandBox; @@ -138,8 +145,8 @@ private slots: virtual SB_STATUS RunSandboxed(const QString& BoxName, const QString& Command, QString WrkDir = QString(), quint32 Flags = 0); - virtual SB_STATUS SetBoxPaths(const CSandBoxPtr& pSandBox); - virtual SB_STATUS SetProcessInfo(const CBoxedProcessPtr& pProcess); + virtual SB_STATUS UpdateBoxPaths(const CSandBoxPtr& pSandBox); + virtual SB_STATUS UpdateProcessInfo(const CBoxedProcessPtr& pProcess); virtual QString GetDeviceMap(); virtual QByteArray MakeEnvironment(bool AddDeviceMap); @@ -158,6 +165,8 @@ private slots: QString m_IniPath; QFileSystemWatcher m_IniWatcher; + bool m_bReloadPending; + bool m_bTerminate; private: diff --git a/SandboxiePlus/QSbieAPI/SbieUtils.cpp b/SandboxiePlus/QSbieAPI/SbieUtils.cpp index 282178b907..e5b5dfa4e8 100644 --- a/SandboxiePlus/QSbieAPI/SbieUtils.cpp +++ b/SandboxiePlus/QSbieAPI/SbieUtils.cpp @@ -61,7 +61,8 @@ SB_STATUS CSbieUtils::DoAssist() SB_STATUS CSbieUtils::Start(EComponent Component) { QStringList Ops; - Install(Component, Ops); + if(!IsInstalled(Component)) + Install(Component, Ops); Start(Component, Ops); return ElevateOps(Ops); } @@ -69,9 +70,9 @@ SB_STATUS CSbieUtils::Start(EComponent Component) void CSbieUtils::Start(EComponent Component, QStringList& Ops) { if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) != SERVICE_RUNNING) - Ops.append(QString::fromWCharArray(L"start|" SBIEDRV)); + Ops.append(QString::fromWCharArray(L"kmdutil.exe|start|" SBIEDRV)); if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) != SERVICE_RUNNING) - Ops.append(QString::fromWCharArray(L"start|" SBIESVC)); + Ops.append(QString::fromWCharArray(L"kmdutil.exe|start|" SBIESVC)); } SB_STATUS CSbieUtils::Stop(EComponent Component) @@ -84,9 +85,9 @@ SB_STATUS CSbieUtils::Stop(EComponent Component) void CSbieUtils::Stop(EComponent Component, QStringList& Ops) { if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) != SERVICE_STOPPED) - Ops.append(QString::fromWCharArray(L"stop|" SBIESVC)); + Ops.append(QString::fromWCharArray(L"kmdutil.exe|stop|" SBIESVC)); if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) != SERVICE_STOPPED) - Ops.append(QString::fromWCharArray(L"stop|" SBIEDRV)); + Ops.append(QString::fromWCharArray(L"kmdutil.exe|stop|" SBIEDRV)); } bool CSbieUtils::IsRunning(EComponent Component) @@ -109,9 +110,11 @@ void CSbieUtils::Install(EComponent Component, QStringList& Ops) { QString HomePath = QCoreApplication::applicationDirPath().replace("/", "\\"); // "C:\\Program Files\\Sandboxie " if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) == 0) - Ops.append(QString::fromWCharArray(L"install|" SBIEDRV L"|") + "\"" + HomePath + "\\" + QString::fromWCharArray(SBIEDRV_SYS) + "\"" + "|type=kernel|start=demand|altitude=86900"); - if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) == 0) - Ops.append(QString::fromWCharArray(L"install|" SBIESVC L"|") + "\"" + HomePath + "\\" + QString::fromWCharArray(SBIESVC_EXE) + "\"" + "|type=own|start=auto|display=\"Sandboxie Service\"|group=UIGroup"); + Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIEDRV L"|") + "\"" + HomePath + "\\" + QString::fromWCharArray(SBIEDRV_SYS) + "\"" + "|type=kernel|start=demand|altitude=86900"); + if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) == 0) { + Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIESVC L"|") + "\"" + HomePath + "\\" + QString::fromWCharArray(SBIESVC_EXE) + "\"" + "|type=own|start=auto|display=\"Sandboxie Service\"|group=UIGroup"); + Ops.append("reg.exe|ADD|HKLM\\SYSTEM\\ControlSet001\\Services\\SbieSvc|/v|PreferExternalManifest|/t|REG_DWORD|/d|1"); + } } SB_STATUS CSbieUtils::Uninstall(EComponent Component) @@ -125,9 +128,9 @@ SB_STATUS CSbieUtils::Uninstall(EComponent Component) void CSbieUtils::Uninstall(EComponent Component, QStringList& Ops) { if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) != 0) - Ops.append(QString::fromWCharArray(L"delete|" SBIESVC)); + Ops.append(QString::fromWCharArray(L"kmdutil.exe|delete|" SBIESVC)); if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) != 0) - Ops.append(QString::fromWCharArray(L"delete|" SBIEDRV)); + Ops.append(QString::fromWCharArray(L"kmdutil.exe|delete|" SBIEDRV)); } bool CSbieUtils::IsInstalled(EComponent Component) @@ -170,9 +173,10 @@ SB_STATUS CSbieUtils::ExecOps(const QStringList& Ops) foreach(const QString& Op, Ops) { QStringList Args = Op.split("|"); + QString Prog = Args.takeFirst(); QProcess Proc; - Proc.execute("kmdutil.exe", Args); + Proc.execute(Prog, Args); Proc.waitForFinished(); int ret = Proc.exitCode(); if (ret != 0) diff --git a/SandboxiePlus/SandMan/ApiLog.cpp b/SandboxiePlus/SandMan/ApiLog.cpp index c21a7d18bb..bf555c688a 100644 --- a/SandboxiePlus/SandMan/ApiLog.cpp +++ b/SandboxiePlus/SandMan/ApiLog.cpp @@ -1,5 +1,20 @@ #include "stdafx.h" #include "ApiLog.h" +#include + +CApiLogEntry::CApiLogEntry(quint64 ProcessId, const QString& Message) +{ + m_ProcessId = ProcessId; + m_Message = Message; + m_TimeStamp = QDateTime::currentDateTime(); // ms resolution + + static atomic uid = 0; + m_uid = uid.fetch_add(1); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// CApiLog::CApiLog(QObject* parent) : QThread(parent) { @@ -51,7 +66,10 @@ void CApiLogServer::OnPipe() connect(pSocket, SIGNAL(readyRead()), this, SLOT(OnData())); connect(pSocket, SIGNAL(disconnected()), this, SLOT(OnClose())); - m_pClients.insert(pSocket, new SApiLog()); + ULONG ClientProcessId = 0; + GetNamedPipeClientProcessId((HANDLE)pSocket->socketDescriptor(), &ClientProcessId); + + m_pClients.insert(pSocket, new SApiLog(ClientProcessId)); } void CApiLogServer::OnData() @@ -69,8 +87,11 @@ void CApiLogServer::OnData() if (endPos == -1) break; - emit m_pApiLog->ApiLogEntry(QString(ApiLog->Buffer.data())); + CApiLogEntryPtr LogEntry = CApiLogEntryPtr(new CApiLogEntry(ApiLog->ProcessId, QString(ApiLog->Buffer.data()))); ApiLog->Buffer.remove(0, endPos + 1); + + QWriteLocker Lock(&m_pApiLog->m_ApiLogMutex); + m_pApiLog->m_ApiLogList.append(LogEntry); } } diff --git a/SandboxiePlus/SandMan/ApiLog.h b/SandboxiePlus/SandMan/ApiLog.h index e55dae9bd7..c01af9d7da 100644 --- a/SandboxiePlus/SandMan/ApiLog.h +++ b/SandboxiePlus/SandMan/ApiLog.h @@ -1,5 +1,25 @@ #pragma once +class CApiLogEntry : public QSharedData +{ +public: + CApiLogEntry(quint64 ProcessId, const QString& Message); + + quint64 GetProcessId() const { return m_ProcessId; } + QDateTime GetTimeStamp() const { return m_TimeStamp; } + QString GetMessage() const { return m_Message; } + + quint64 GetUID() const { return m_uid; } + +protected: + quint64 m_ProcessId; + QDateTime m_TimeStamp; + QString m_Message; + + quint64 m_uid; +}; + +typedef QSharedDataPointer CApiLogEntryPtr; class CApiLog : public QThread { @@ -8,13 +28,18 @@ class CApiLog : public QThread CApiLog(QObject* parent = 0); virtual ~CApiLog(); -signals: - void ApiLogEntry(const QString& Message); + virtual QList GetApiLog() const { QReadLocker Lock(&m_ApiLogMutex); return m_ApiLogList; } + virtual void ClearApiLog() { QWriteLocker Lock(&m_ApiLogMutex); m_ApiLogList.clear(); } protected: + friend class CApiLogServer; + virtual void run(); - class CApiLogServer*m_pServer; + mutable QReadWriteLock m_ApiLogMutex; + QList m_ApiLogList; + + CApiLogServer* m_pServer; }; ///////////////////////////////////////////////////////////////////////////////////// @@ -36,7 +61,10 @@ public slots: struct SApiLog { + SApiLog(quint64 pid) { ProcessId = pid; } + QByteArray Buffer; + quint64 ProcessId; }; QLocalServer* m_pServer; diff --git a/SandboxiePlus/SandMan/Models/ApiMonModel.cpp b/SandboxiePlus/SandMan/Models/ApiMonModel.cpp new file mode 100644 index 0000000000..9d8affd060 --- /dev/null +++ b/SandboxiePlus/SandMan/Models/ApiMonModel.cpp @@ -0,0 +1,130 @@ +#include "stdafx.h" +#include "ApiMonModel.h" +#include "../MiscHelpers/Common/Common.h" + +CApiMonModel::CApiMonModel(QObject *parent) +:CListItemModel(parent) +{ +} + +CApiMonModel::~CApiMonModel() +{ +} + +void CApiMonModel::Sync(const QList& List, QSet PIDs) +{ + QList New; + QHash Old = m_Map; + + foreach (const CApiLogEntryPtr& pEntry, List) + { + QVariant ID = pEntry->GetUID(); + + if (!PIDs.isEmpty() && !PIDs.contains(pEntry->GetProcessId())) + continue; + + int Row = -1; + QHash::iterator I = Old.find(ID); + SApiLogNode* pNode = I != Old.end() ? static_cast(I.value()) : NULL; + if(!pNode) + { + pNode = static_cast(MkNode(ID)); + pNode->Values.resize(columnCount()); + pNode->pEntry = pEntry; + New.append(pNode); + } + else + { + I.value() = NULL; + Row = GetRow(pNode); + } + + int Col = 0; + bool State = false; + int Changed = 0; + + /*int RowColor = CTaskExplorer::eNone; + if (pGDI->IsMarkedForRemoval() && CTaskExplorer::UseListColor(CTaskExplorer::eToBeRemoved)) RowColor = CTaskExplorer::eToBeRemoved; + else if (pGDI->IsNewlyCreated() && CTaskExplorer::UseListColor(CTaskExplorer::eAdded)) RowColor = CTaskExplorer::eAdded; + + if (pNode->iColor != RowColor) { + pNode->iColor = RowColor; + pNode->Color = CTaskExplorer::GetListColor(RowColor); + Changed = 2; + }*/ + + for(int section = 0; section < columnCount(); section++) + { + if (!m_Columns.contains(section)) + continue; // ignore columns which are hidden + + QVariant Value; + switch(section) + { + case eProcess: Value = pEntry->GetProcessId(); break; + case eTimeStamp: Value = pEntry->GetTimeStamp(); break; + case eMessage: Value = pEntry->GetMessage(); break; + } + + SApiLogNode::SValue& ColValue = pNode->Values[section]; + + if (ColValue.Raw != Value) + { + if(Changed == 0) + Changed = 1; + ColValue.Raw = Value; + + switch (section) + { + case eProcess: ColValue.Formated = QString::number(pEntry->GetProcessId()); break; + case eTimeStamp: ColValue.Formated = pEntry->GetTimeStamp().toString("hh:mm:ss.zzz"); break; + //case eType: ColValue.Formated = ; break; + //case eValue: ColValue.Formated = ; break; + } + } + + if(State != (Changed != 0)) + { + if(State && Row != -1) + emit dataChanged(createIndex(Row, Col), createIndex(Row, section-1)); + State = (Changed != 0); + Col = section; + } + if(Changed == 1) + Changed = 0; + } + if(State && Row != -1) + emit dataChanged(createIndex(Row, Col, pNode), createIndex(Row, columnCount()-1, pNode)); + + } + + CListItemModel::Sync(New, Old); +} + +CApiLogEntryPtr CApiMonModel::GetEntry(const QModelIndex &index) const +{ + if (!index.isValid()) + return CApiLogEntryPtr(); + + SApiLogNode* pNode = static_cast(index.internalPointer()); + return pNode->pEntry; +} + +int CApiMonModel::columnCount(const QModelIndex &parent) const +{ + return eCount; +} + +QVariant CApiMonModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + switch(section) + { + case eProcess: return tr("Process"); + case eTimeStamp: return tr("Time Stamp"); + case eMessage: return tr("Message"); + } + } + return QVariant(); +} diff --git a/SandboxiePlus/SandMan/Models/ApiMonModel.h b/SandboxiePlus/SandMan/Models/ApiMonModel.h new file mode 100644 index 0000000000..ac9f46b0de --- /dev/null +++ b/SandboxiePlus/SandMan/Models/ApiMonModel.h @@ -0,0 +1,40 @@ +#pragma once +#include +#include "../ApiLog.h" +#include "../../MiscHelpers/Common/ListItemModel.h" + +class CApiMonModel : public CListItemModel +{ + Q_OBJECT + +public: + CApiMonModel(QObject *parent = 0); + ~CApiMonModel(); + + void Sync(const QList& List, QSet PIDs); + + CApiLogEntryPtr GetEntry(const QModelIndex &index) const; + + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + enum EColumns + { + eProcess = 0, + eTimeStamp, + eMessage, + eCount + }; + +protected: + struct SApiLogNode: SListNode + { + SApiLogNode(const QVariant& Id) : SListNode(Id), iColor(0) {} + + CApiLogEntryPtr pEntry; + + int iColor; + }; + + virtual SListNode* MkNode(const QVariant& Id) { return new SApiLogNode(Id); } +}; \ No newline at end of file diff --git a/SandboxiePlus/SandMan/Models/ResMonModel.cpp b/SandboxiePlus/SandMan/Models/ResMonModel.cpp index f230baab31..fa0bb114f4 100644 --- a/SandboxiePlus/SandMan/Models/ResMonModel.cpp +++ b/SandboxiePlus/SandMan/Models/ResMonModel.cpp @@ -123,8 +123,8 @@ QVariant CResMonModel::headerData(int section, Qt::Orientation orientation, int switch(section) { case eProcess: return tr("Process"); - case eTimeStamp: return tr("TimeStamp"); - case eType: return tr("Time"); + case eTimeStamp: return tr("Time Stamp"); + case eType: return tr("Type"); case eValue: return tr("Value"); } } diff --git a/SandboxiePlus/SandMan/Models/SbieModel.cpp b/SandboxiePlus/SandMan/Models/SbieModel.cpp index 3dc76af0f4..b704836e4c 100644 --- a/SandboxiePlus/SandMan/Models/SbieModel.cpp +++ b/SandboxiePlus/SandMan/Models/SbieModel.cpp @@ -104,11 +104,13 @@ QList CSbieModel::Sync(const QMap& BoxList) bool HasActive = Sync(pBox, ProcessList, New, Old, Added); int inUse = (HasActive ? 1 : 0); - int boxType = pBoxEx && pBoxEx->HasLogApi() ? eLogApi : eNormal; - if (pBoxEx && pBoxEx->NoAnonymousLogon()) - boxType = eCyan; - if (pBoxEx && pBoxEx->HasOpenToken()) - boxType = eOpenBox;// : eOpenInSys; + int boxType = eYelow; + if(pBoxEx->HasLogApi()) + boxType = eRed; + if (pBoxEx->IsUnsecureDebugging()) + boxType = eMagenta; + else if (pBoxEx->IsSecurityRestricted()) + boxType = eOrang; if (pNode->inUse != inUse || pNode->boxType != boxType) { @@ -128,7 +130,8 @@ QList CSbieModel::Sync(const QMap& BoxList) switch(section) { case eName: Value = pBox->GetName(); break; - case eStatus: Value = boxType; break; + case eStatus: Value = pBox.objectCast()->GetStatusStr(); break; + case ePath: Value = pBox->GetFileRoot(); break; } SSandBoxNode::SValue& ColValue = pNode->Values[section]; @@ -141,7 +144,7 @@ QList CSbieModel::Sync(const QMap& BoxList) switch (section) { - case eStatus: ColValue.Formated = boxType == eLogApi ? tr("LogApi Enabled") : tr("Normal"); break; // todo: add more + case eName: ColValue.Formated = Value.toString().replace("_", " "); break; } } @@ -234,6 +237,7 @@ bool CSbieModel::Sync(const CSandBoxPtr& pBox, const QMapGetResourceLog().count(); break; case eTimeStamp: Value = pProcess->GetTimeStamp(); break; + case ePath: Value = pProcess->GetFileName(); break; } SSandBoxNode::SValue& ColValue = pNode->Values[section]; @@ -308,6 +312,7 @@ QVariant CSbieModel::headerData(int section, Qt::Orientation orientation, int ro //case eTitle: return tr("Title"); //case eLogCount: return tr("Log Count"); case eTimeStamp: return tr("Start Time"); + case ePath: return tr("Path"); } } return QVariant(); diff --git a/SandboxiePlus/SandMan/Models/SbieModel.h b/SandboxiePlus/SandMan/Models/SbieModel.h index f75e604f75..f15d2d97d7 100644 --- a/SandboxiePlus/SandMan/Models/SbieModel.h +++ b/SandboxiePlus/SandMan/Models/SbieModel.h @@ -28,6 +28,7 @@ class CSbieModel : public CTreeItemModel //eTitle, //eLogCount, eTimeStamp, + ePath, eCount }; @@ -63,15 +64,7 @@ class CSbieModel : public CTreeItemModel eCyan, eMagenta, eOrang, - eMaxColor, - - eNormal = eYelow, - eLogApi = eRed, - // = eCyan, - eOpenBox = eGreen, - // = eMagenta, - // = eOrang, - eAnonBox = eBlue + eMaxColor }; QMap > m_BoxIcons; diff --git a/SandboxiePlus/SandMan/SandMan.cpp b/SandboxiePlus/SandMan/SandMan.cpp index 2aa902136f..b825a9ab34 100644 --- a/SandboxiePlus/SandMan/SandMan.cpp +++ b/SandboxiePlus/SandMan/SandMan.cpp @@ -9,6 +9,7 @@ #include "ApiLog.h" #include "./Dialogs/MultiErrorDialog.h" #include "../QSbieAPI/SbieUtils.h" +#include "../QSbieAPI/Sandboxie/BoxBorder.h" CSbiePlusAPI* theAPI = NULL; @@ -88,6 +89,8 @@ CSandMan::CSandMan(QWidget *parent) QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion()); this->setWindowTitle(appTitle); + m_pBoxBorder = new CBoxBorder(theAPI, this); + m_ApiLog = NULL; m_bConnectPending = false; @@ -180,7 +183,7 @@ CSandMan::CSandMan(QWidget *parent) m_pResMonModel = new CResMonModel(); //m_pResMonModel->SetUseIcons(true); - m_pResourceLog = new CPanelViewImpl(m_pResMonModel); + m_pResourceLog = new CPanelViewEx(m_pResMonModel); //m_pResourceLog->GetView()->setItemDelegate(theGUI->GetItemDelegate()); @@ -190,16 +193,17 @@ CSandMan::CSandMan(QWidget *parent) // // Api Log - m_pApiLog = new CPanelWidgetEx(); + m_pApiMonModel = new CApiMonModel(); + //m_pApiMonModel->SetUseIcons(true); + + m_pApiCallLog = new CPanelViewEx(m_pApiMonModel); - //m_pApiLog->GetView()->setItemDelegate(theGUI->GetItemDelegate()); - ((QTreeWidgetEx*)m_pApiLog->GetView())->setHeaderLabels(tr("Time|Entry").split("|")); + //m_pApiCallLog->GetView()->setItemDelegate(theGUI->GetItemDelegate()); - m_pApiLog->GetView()->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_pApiLog->GetView()->setSortingEnabled(false); + m_pApiCallLog->GetView()->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_pLogTabs->addTab(m_pApiLog, tr("Api Call Log")); - m_pApiLog->setEnabled(false); + m_pLogTabs->addTab(m_pApiCallLog, tr("Api Call Log")); + m_pApiCallLog->setEnabled(false); // connect(menuBar(), SIGNAL(hovered(QAction*)), this, SLOT(OnMenuHover(QAction*))); @@ -315,7 +319,7 @@ CSandMan::CSandMan(QWidget *parent) bool bAutoRun = QApplication::arguments().contains("-autorun"); m_pTrayIcon->show(); // Note: qt bug; without a first show hide does not work :/ - if(!bAutoRun && !theConf->GetBool("SysTray/Show", true)) + if(!bAutoRun && !theConf->GetBool("Options/ShowSysTray", true)) m_pTrayIcon->hide(); restoreGeometry(theConf->GetBlob("MainWindow/Window_Geometry")); @@ -326,7 +330,11 @@ CSandMan::CSandMan(QWidget *parent) ((QTreeViewEx*)m_pResourceLog->GetView())->OnResetColumns(); else ((QTreeViewEx*)m_pResourceLog->GetView())->restoreState(Columns); - m_pApiLog->GetView()->header()->restoreState(theConf->GetBlob("GUI/ApiLogList_Columns")); + Columns = theConf->GetBlob("GUI/ApiLogList_Columns"); + if (!Columns.isEmpty()) + ((QTreeViewEx*)m_pApiCallLog->GetView())->OnResetColumns(); + else + ((QTreeViewEx*)m_pApiCallLog->GetView())->restoreState(Columns); m_pLogSplitter->restoreState(theConf->GetBlob("MainWindow/Log_Splitter")); m_pPanelSplitter->restoreState(theConf->GetBlob("MainWindow/Panel_Splitter")); m_pLogTabs->setCurrentIndex(theConf->GetInt("GUI/LogTab", 0)); @@ -336,20 +344,16 @@ CSandMan::CSandMan(QWidget *parent) else if (theConf->GetBool("Options/NoSizeGrip", false)) statusBar()->setSizeGripEnabled(false); - bool bIsMonitoring = theAPI->IsMonitoring(); - m_pResourceLog->setEnabled(bIsMonitoring); - m_pEnableMonitoring->setChecked(bIsMonitoring); - m_pKeepTerminated->setChecked(theConf->GetBool("Options/KeepTerminated")); m_pProgressDialog = new CProgressDialog("Maintenance operation progress...", this); m_pProgressDialog->setWindowModality(Qt::ApplicationModal); - connect(theAPI, SIGNAL(LogMessage(const QString&)), this, SLOT(OnLogMessage(const QString&))); - if (CSbieUtils::IsRunning(CSbieUtils::eAll) || theConf->GetBool("Options/StartIfStopped", true)) ConnectSbie(); + connect(theAPI, SIGNAL(LogMessage(const QString&, bool)), this, SLOT(OnLogMessage(const QString&, bool))); + m_uTimerID = startTimer(250); } @@ -366,7 +370,7 @@ CSandMan::~CSandMan() //theConf->SetBlob("GUI/BoxTree_Columns", m_pBoxTree->saveState()); theConf->SetBlob("GUI/LogList_Columns", m_pMessageLog->GetView()->header()->saveState()); theConf->SetBlob("GUI/ResMonList_Columns", m_pResourceLog->GetView()->header()->saveState()); - theConf->SetBlob("GUI/ApiLogList_Columns", m_pApiLog->GetView()->header()->saveState()); + theConf->SetBlob("GUI/ApiLogList_Columns", m_pApiCallLog->GetView()->header()->saveState()); theConf->SetBlob("MainWindow/Log_Splitter", m_pLogSplitter->saveState()); theConf->SetBlob("MainWindow/Panel_Splitter", m_pPanelSplitter->saveState()); theConf->SetValue("GUI/LogTab", m_pLogTabs->currentIndex()); @@ -463,7 +467,7 @@ void CSandMan::OnMessage(const QString& Message) { OnLogMessage(tr("Maintenance operation Successful")); if (m_bConnectPending) - theAPI->Connect(true); + ConnectSbieImpl(); } m_pProgressDialog->hide(); m_bConnectPending = false; @@ -506,6 +510,7 @@ void CSandMan::timerEvent(QTimerEvent* pEvent) OnSelectionChanged(); } + void CSandMan::OnSelectionChanged() { QList Processes = m_pBoxView->GetSelectedProcesses(); @@ -518,13 +523,15 @@ void CSandMan::OnSelectionChanged() QSet Pids; foreach(const CBoxedProcessPtr& pProcess, Processes) - { Pids.insert(pProcess->GetProcessId()); - } QList ResourceLog = theAPI->GetResLog(); - m_pResMonModel->Sync(ResourceLog, Pids); + + if (m_ApiLog) { + QList ApiCallLog = m_ApiLog->GetApiLog(); + m_pApiMonModel->Sync(ApiCallLog, Pids); + } } void CSandMan::OnStatusChanged() @@ -535,11 +542,6 @@ void CSandMan::OnStatusChanged() appTitle.append(tr(" - Driver: v%1").arg(theAPI->GetVersion())); //appTitle.append(tr(" - %1").arg(theAPI->GetIniPath())); - if (theAPI->GetAllBoxes().count() == 0) { - OnLogMessage(tr("No sandboxes found; creating: %1").arg("DefaultBox")); - theAPI->CreateBox("DefaultBox"); - } - if(IsFullyPortable()) appTitle.append(tr(" - Portable")); @@ -590,7 +592,7 @@ void CSandMan::OnMenuHover(QAction* action) } } -void CSandMan::OnLogMessage(const QString& Message) +void CSandMan::OnLogMessage(const QString& Message, bool bNotify) { QTreeWidgetItem* pItem = new QTreeWidgetItem(); // Time|Message pItem->setText(0, QDateTime::currentDateTime().toString("hh:mm:ss.zzz")); @@ -598,19 +600,19 @@ void CSandMan::OnLogMessage(const QString& Message) m_pMessageLog->GetTree()->addTopLevelItem(pItem); m_pMessageLog->GetView()->verticalScrollBar()->setValue(m_pMessageLog->GetView()->verticalScrollBar()->maximum()); - + statusBar()->showMessage(Message); -} -void CSandMan::OnApiLogEntry(const QString& Message) -{ - QTreeWidgetItem* pItem = new QTreeWidgetItem(); // Time|Message - pItem->setText(0, QDateTime::currentDateTime().toString("hh:mm:ss.zzz")); - pItem->setText(1, Message); - m_pApiLog->GetTree()->addTopLevelItem(pItem); - - m_pApiLog->GetView()->verticalScrollBar()->setValue(m_pApiLog->GetView()->verticalScrollBar()->maximum()); + if (bNotify) + { + int iNotify = theConf->GetInt("Options/Notifications", 1); + if (iNotify & 1) + m_pTrayIcon->showMessage("Sandboxie-Plus", Message); + if (iNotify & 2) + QApplication::beep(); + } } + /* void CSandMan::OnResetColumns() { @@ -669,11 +671,33 @@ SB_STATUS CSandMan::ConnectSbie() if (Status.GetStatus() == OP_ASYNC) m_bConnectPending = true; else if (!Status.IsError()) - Status = theAPI->Connect(true); + Status = ConnectSbieImpl(); return Status; } +SB_STATUS CSandMan::ConnectSbieImpl() +{ + SB_STATUS Status = theAPI->Connect(); + + if (Status && !CSbieAPI::IsSbieCtrlRunning()) // don't take over when SbieCtrl is up and running + Status = theAPI->TakeOver(); + + if (Status) + Status = theAPI->ReloadBoxes(); + + if (theAPI->GetAllBoxes().count() == 0) { + OnLogMessage(tr("No sandboxes found; creating: %1").arg("DefaultBox")); + theAPI->CreateBox("DefaultBox"); + } + + bool bIsMonitoring = theAPI->IsMonitoring(); + m_pResourceLog->setEnabled(bIsMonitoring); + m_pEnableMonitoring->setChecked(bIsMonitoring); + + return SB_OK; +} + SB_STATUS CSandMan::DisconnectSbie() { return theAPI->Disconnect(); @@ -746,7 +770,7 @@ void CSandMan::OnCleanUp() theAPI->ClearResLog(); if (sender() == m_pCleanUpApiLog || sender() == m_pCleanUpButton) - m_pApiLog->GetTree()->clear(); + if(m_ApiLog) m_ApiLog->ClearApiLog(); if (sender() == m_pCleanUpProcesses || sender() == m_pCleanUpButton) theAPI->UpdateProcesses(false); @@ -755,6 +779,9 @@ void CSandMan::OnCleanUp() void CSandMan::OnSetKeep() { theConf->SetValue("Options/KeepTerminated", m_pKeepTerminated->isChecked()); + + if(!m_pKeepTerminated->isChecked()) // clear on disable + theAPI->UpdateProcesses(false); } void CSandMan::OnEditIni() @@ -828,14 +855,13 @@ void CSandMan::OnSetLogging() if (!m_ApiLog) { m_ApiLog = new CApiLog(); - connect(m_ApiLog, SIGNAL(ApiLogEntry(const QString&)), this, SLOT(OnApiLogEntry(const QString&))); - m_pApiLog->setEnabled(true); + m_pApiCallLog->setEnabled(true); } } else { if (m_ApiLog) { - m_pApiLog->setEnabled(false); + m_pApiCallLog->setEnabled(false); m_ApiLog->deleteLater(); m_ApiLog = NULL; } diff --git a/SandboxiePlus/SandMan/SandMan.h b/SandboxiePlus/SandMan/SandMan.h index 9599cc0b86..bd33c29457 100644 --- a/SandboxiePlus/SandMan/SandMan.h +++ b/SandboxiePlus/SandMan/SandMan.h @@ -7,10 +7,11 @@ #include "../MiscHelpers/Common/PanelView.h" #include "../MiscHelpers/Common/ProgressDialog.h" #include "Models/ResMonModel.h" +#include "Models/ApiMonModel.h" #define VERSION_MJR 0 #define VERSION_MIN 2 -#define VERSION_REV 2 +#define VERSION_REV 5 #define VERSION_UPD 0 @@ -19,6 +20,7 @@ class CSbieView; class CApiLog; +class CBoxBorder; class CSandMan : public QMainWindow { @@ -36,6 +38,7 @@ class CSandMan : public QMainWindow protected: SB_STATUS ConnectSbie(); + SB_STATUS ConnectSbieImpl(); SB_STATUS DisconnectSbie(); SB_STATUS StopSbie(bool andRemove = false); @@ -46,15 +49,16 @@ class CSandMan : public QMainWindow int m_uTimerID; bool m_bConnectPending; bool m_bStopPending; + CBoxBorder* m_pBoxBorder; CApiLog* m_ApiLog; + public slots: void OnMessage(const QString&); void OnStatusChanged(); - void OnLogMessage(const QString& Message); - void OnApiLogEntry(const QString& Message); + void OnLogMessage(const QString& Message, bool bNotify = false); private slots: void OnSelectionChanged(); @@ -101,9 +105,10 @@ private slots: QTabWidget* m_pLogTabs; CPanelWidgetEx* m_pMessageLog; - CPanelViewImpl* m_pResourceLog; + CPanelViewEx* m_pResourceLog; CResMonModel* m_pResMonModel; - CPanelWidgetEx* m_pApiLog; + CPanelViewEx* m_pApiCallLog; + CApiMonModel* m_pApiMonModel; QMenu* m_pMenuFile; diff --git a/SandboxiePlus/SandMan/SbiePlusAPI.cpp b/SandboxiePlus/SandMan/SbiePlusAPI.cpp index 9c805ca5dc..f49c016b3d 100644 --- a/SandboxiePlus/SandMan/SbiePlusAPI.cpp +++ b/SandboxiePlus/SandMan/SbiePlusAPI.cpp @@ -29,8 +29,13 @@ CBoxedProcess* CSbiePlusAPI::NewBoxedProcess(quint64 ProcessId, class CSandBox* CSandBoxPlus::CSandBoxPlus(const QString& BoxName, class CSbieAPI* pAPI) : CSandBox(BoxName, pAPI) { m_bLogApiFound = false; - m_bNoAnonymousLogon = false; - m_bHasOpenToken = false; + m_bINetBlocked = false; + m_bSharesAllowed = false; + m_bDropRights = false; + + + m_bSecurityRestricted = false; + m_iUnsecureDebugging = 0; } CSandBoxPlus::~CSandBoxPlus() @@ -39,12 +44,93 @@ CSandBoxPlus::~CSandBoxPlus() void CSandBoxPlus::UpdateDetails() { - QStringList List = GetTextList("OpenPipePath"); - m_bLogApiFound = List.contains("\\Device\\NamedPipe\\LogAPI"); + m_bLogApiFound = GetTextList("OpenPipePath").contains("\\Device\\NamedPipe\\LogAPI"); + + m_bINetBlocked = GetTextList("ClosedFilePath").contains("InternetAccessDevices"); + + m_bSharesAllowed = GetBool("BlockNetworkFiles", true) == false; + + m_bDropRights = GetBool("DropAdminRights", false); - m_bNoAnonymousLogon = GetBool("AnonymousLogon", true) == false; + if (CheckOpenToken()) + m_iUnsecureDebugging = 1; + else if(GetBool("ExposeBoxedSystem", false) || GetBool("UnrestrictedSCM", false)) + m_iUnsecureDebugging = 2; + else + m_iUnsecureDebugging = 0; - m_bHasOpenToken = GetBool("OpenToken") || GetBool("UnrestrictedToken") || GetBool("UnfilteredToken"); + //GetBool("SandboxieLogon", false) + + m_bSecurityRestricted = m_iUnsecureDebugging == 0 && (GetBool("DropAdminRights", false) || GetBool("ProtectRpcSs", false) || !GetBool("OpenDefaultClsid", true)); CSandBox::UpdateDetails(); -} \ No newline at end of file +} + +QString CSandBoxPlus::GetStatusStr() const +{ + QStringList Status; + + if (m_iUnsecureDebugging == 1) + Status.append(tr("NOT SECURE (Debug Config)")); + else if (m_iUnsecureDebugging == 2) + Status.append(tr("Reduced Isolation")); + else if(m_bSecurityRestricted) + Status.append(tr("Enhanced Isolation")); + + if (m_bLogApiFound) + Status.append(tr("API Log")); + if (m_bINetBlocked) + Status.append(tr("No INet")); + if (m_bSharesAllowed) + Status.append(tr("Net Share")); + if (m_bDropRights) + Status.append(tr("No Admin")); + + if (Status.isEmpty()) + return tr("Normal"); + return Status.join(", "); +} + +bool CSandBoxPlus::CheckOpenToken() const +{ + if (GetBool("OpenToken", false)) return true; + if(GetBool("UnrestrictedToken", false)) return true; + if (!GetBool("AnonymousLogon", true)) return true; + if (GetBool("KeepTokenIntegrity", false)) return true; + if(GetBool("UnfilteredToken", false)) return true; + return false; +} + +void CSandBoxPlus::SetLogApi(bool bEnable) +{ + if (bEnable) + { + InsertText("OpenPipePath", "\\Device\\NamedPipe\\LogAPI"); + InsertText("InjectDll", "\\LogAPI\\logapi32.dll"); + InsertText("InjectDll64", "\\LogAPI\\logapi64.dll"); + } + else + { + DelValue("OpenPipePath", "\\Device\\NamedPipe\\LogAPI"); + DelValue("InjectDll", "\\LogAPI\\logapi32.dll"); + DelValue("InjectDll64", "\\LogAPI\\logapi64.dll"); + } +} + +void CSandBoxPlus::SetINetBlock(bool bEnable) +{ + if (bEnable) + DelValue("ClosedFilePath", "InternetAccessDevices"); + else + InsertText("ClosedFilePath", "InternetAccessDevices"); +} + +void CSandBoxPlus::SetAllowShares(bool bEnable) +{ + SetBool("BlockNetworkFiles", bEnable); +} + +void CSandBoxPlus::SetDropRights(bool bEnable) +{ + SetBool("DropAdminRights", bEnable); +} diff --git a/SandboxiePlus/SandMan/SbiePlusAPI.h b/SandboxiePlus/SandMan/SbiePlusAPI.h index 83a9738ef2..13fe6c69d2 100644 --- a/SandboxiePlus/SandMan/SbiePlusAPI.h +++ b/SandboxiePlus/SandMan/SbiePlusAPI.h @@ -30,13 +30,31 @@ class CSandBoxPlus : public CSandBox virtual void UpdateDetails(); + virtual QString GetStatusStr() const; + + virtual void SetLogApi(bool bEnable); virtual bool HasLogApi() const { return m_bLogApiFound; } - virtual bool NoAnonymousLogon() const { return m_bNoAnonymousLogon; } - virtual bool HasOpenToken() const { return m_bHasOpenToken; } + + virtual void SetINetBlock(bool bEnable); + virtual bool IsINetBlocked() const { return m_bINetBlocked; } + + virtual void SetAllowShares(bool bEnable); + virtual bool HasSharesAccess() const { return m_bSharesAllowed; } + + virtual void SetDropRights(bool bEnable); + virtual bool IsDropRights() const { return m_bDropRights; } + + virtual bool IsSecurityRestricted() const { return m_bSecurityRestricted; } + virtual bool IsUnsecureDebugging() const { return m_iUnsecureDebugging != 0; } protected: + virtual bool CheckOpenToken() const; + bool m_bLogApiFound; - bool m_bNoAnonymousLogon; - bool m_bHasOpenToken; + bool m_bINetBlocked; + bool m_bSharesAllowed; + bool m_bDropRights; + bool m_bSecurityRestricted; + int m_iUnsecureDebugging; }; \ No newline at end of file diff --git a/SandboxiePlus/SandMan/Views/SbieView.cpp b/SandboxiePlus/SandMan/Views/SbieView.cpp index 197c56442a..65e93c20cd 100644 --- a/SandboxiePlus/SandMan/Views/SbieView.cpp +++ b/SandboxiePlus/SandMan/Views/SbieView.cpp @@ -41,6 +41,9 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent) m_pMainLayout->addWidget(new CFinder(m_pSortProxy, this)); + + connect(m_pSbieModel, SIGNAL(ToolTipCallback(const QVariant&, QString&)), this, SLOT(OnToolTipCallback(const QVariant&, QString&)), Qt::DirectConnection); + m_pMenuRun = m_pMenu->addMenu(tr("Run")); m_pMenuRunAny = m_pMenuRun->addAction(tr("Run Program"), this, SLOT(OnSandBoxAction())); m_pMenuRunBrowser = m_pMenuRun->addAction(tr("Run Web Browser"), this, SLOT(OnSandBoxAction())); @@ -50,11 +53,24 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent) m_pMenu->addSeparator(); m_pMenuCleanUp = m_pMenu->addAction(tr("Delete Content"), this, SLOT(OnSandBoxAction())); m_pMenu->addSeparator(); + m_pMenuPresets = m_pMenu->addMenu(tr("Sandbox Presets")); + m_pMenuPresetsLogApi = m_pMenuPresets->addAction(tr("Enable API Call logging"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsLogApi->setCheckable(true); + m_pMenuPresetsINet = m_pMenuPresets->addAction(tr("Block Internet Access"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsINet->setCheckable(true); + m_pMenuPresetsShares = m_pMenuPresets->addAction(tr("Allow Network Shares"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsShares->setCheckable(true); + m_pMenuPresetsNoAdmin = m_pMenuPresets->addAction(tr("Drop Admin Rights"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsNoAdmin->setCheckable(true); + m_pMenuRename = m_pMenu->addAction(tr("Rename Sandbox"), this, SLOT(OnSandBoxAction())); m_pMenuRemove = m_pMenu->addAction(tr("Remove Sandbox"), this, SLOT(OnSandBoxAction())); m_iMenuBox = m_pMenu->actions().count(); m_pMenuTerminate = m_pMenu->addAction(tr("Terminate"), this, SLOT(OnProcessAction())); + m_pMenuTerminate->setShortcut(QKeySequence::Delete); + m_pMenuTerminate->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuTerminate); m_pMenuSuspend = m_pMenu->addAction(tr("Suspend"), this, SLOT(OnProcessAction())); m_pMenuResume = m_pMenu->addAction(tr("Resume"), this, SLOT(OnProcessAction())); m_iMenuProc = m_pMenu->actions().count(); @@ -88,15 +104,43 @@ void CSbieView::Refresh() } } +void CSbieView::OnToolTipCallback(const QVariant& ID, QString& ToolTip) +{ + if (ID.type() == QVariant::String) + { + QString BoxName = ID.toString(); + CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); + CSandBoxPlus* pBoxEx = qobject_cast(pBox.data()); + if (!pBoxEx) + return; + + // todo more info + + ToolTip = BoxName + "\n"; + ToolTip += tr(" File root: %1\n").arg(pBoxEx->GetFileRoot()); + ToolTip += tr(" Registry root: %1\n").arg(pBoxEx->GetRegRoot()); + ToolTip += tr(" IPC root: %1\n").arg(pBoxEx->GetIpcRoot()); + + ToolTip += tr("Options:\n "); + ToolTip += pBoxEx->GetStatusStr().replace(", ", "\n "); + } + else if (quint64 ProcessId = ID.toULongLong()) + { + // todo proc info + } +} + void CSbieView::OnMenu(const QPoint& Point) { + CSandBoxPtr pBox; + CBoxedProcessPtr pProcess; int iProcessCount = 0; int iSandBoxeCount = 0; int iSuspendedCount = 0; foreach(const QModelIndex& Index, m_pSbieTree->selectedRows()) { QModelIndex ModelIndex = m_pSortProxy->mapToSource(Index); - CBoxedProcessPtr pProcess = m_pSbieModel->GetProcess(ModelIndex); + pProcess = m_pSbieModel->GetProcess(ModelIndex); if (pProcess) { iProcessCount++; @@ -105,7 +149,7 @@ void CSbieView::OnMenu(const QPoint& Point) } else { - CSandBoxPtr pBox = m_pSbieModel->GetSandBox(ModelIndex); + pBox = m_pSbieModel->GetSandBox(ModelIndex); if (pBox) iSandBoxeCount++; } @@ -118,6 +162,13 @@ void CSbieView::OnMenu(const QPoint& Point) m_pMenuRun->setEnabled(iSandBoxeCount == 1); m_pMenuRename->setEnabled(iSandBoxeCount == 1); + m_pMenuPresets->setEnabled(iSandBoxeCount == 1); + m_pMenuPresetsLogApi->setChecked(pBox && pBox.objectCast()->HasLogApi()); + m_pMenuPresetsINet->setChecked(pBox && pBox.objectCast()->IsINetBlocked()); + m_pMenuPresetsShares->setChecked(pBox && pBox.objectCast()->HasSharesAccess()); + m_pMenuPresetsNoAdmin->setChecked(pBox && pBox.objectCast()->IsDropRights()); + + for (int i = m_iMenuBox; i < m_iMenuProc; i++) MenuActions[i]->setVisible(iProcessCount > 0 && iSandBoxeCount == 0); m_pMenuSuspend->setEnabled(iProcessCount > iSuspendedCount); @@ -148,10 +199,20 @@ void CSbieView::OnSandBoxAction() Results.append(SandBoxes.first()->RunCommand("explorer.exe /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")); else if (Action == m_pMenuRunCmd) Results.append(SandBoxes.first()->RunCommand("cmd.exe")); + else if (Action == m_pMenuPresetsLogApi) + SandBoxes.first().objectCast()->SetLogApi(m_pMenuPresetsLogApi->isChecked()); + else if (Action == m_pMenuPresetsINet) + SandBoxes.first().objectCast()->SetINetBlock(m_pMenuPresetsINet->isChecked()); + else if (Action == m_pMenuPresetsShares) + SandBoxes.first().objectCast()->SetAllowShares(m_pMenuPresetsShares->isChecked()); + else if (Action == m_pMenuPresetsNoAdmin) + SandBoxes.first().objectCast()->SetDropRights(m_pMenuPresetsNoAdmin->isChecked()); + else if (Action == m_pMenuRename) { - QString Value = QInputDialog::getText(this, "Sandboxie-Plus", "Please enter a new name for the Sandbox (without spaces).", QLineEdit::Normal, SandBoxes.first()->GetName()); - if (Value.isEmpty() || Value == SandBoxes.first()->GetName()) + QString OldValue = SandBoxes.first()->GetName().replace("_", " "); + QString Value = QInputDialog::getText(this, "Sandboxie-Plus", "Please enter a new name for the Sandbox.", QLineEdit::Normal, OldValue); + if (Value.isEmpty() || Value == OldValue) return; Results.append((SandBoxes.first()->RenameBox(Value))); } @@ -200,6 +261,13 @@ void CSbieView::OnProcessAction() QList Results; QAction* Action = qobject_cast(sender()); + if (Action == m_pMenuTerminate) + { + if (QMessageBox("Sandboxie-Plus", tr("Do you want to %1 the selected process(es)").arg(((QAction*)sender())->text().toLower()) + , QMessageBox::Question, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes) + return; + } + foreach(const CBoxedProcessPtr& pProcess, CSbieView::GetSelectedProcesses()) { if (Action == m_pMenuTerminate) @@ -264,4 +332,4 @@ QList CSbieView::GetSelectedProcesses() List.append(pProcess); } return List; -} +} \ No newline at end of file diff --git a/SandboxiePlus/SandMan/Views/SbieView.h b/SandboxiePlus/SandMan/Views/SbieView.h index 574fcbb138..8c3e41a3c5 100644 --- a/SandboxiePlus/SandMan/Views/SbieView.h +++ b/SandboxiePlus/SandMan/Views/SbieView.h @@ -19,6 +19,8 @@ public slots: void Refresh(); private slots: + void OnToolTipCallback(const QVariant& ID, QString& ToolTip); + void ProcessSelection(const QItemSelection& selected, const QItemSelection& deselected); void OnSandBoxAction(); @@ -45,11 +47,17 @@ private slots: QAction* m_pMenuRunBrowser; QAction* m_pMenuRunExplorer; QAction* m_pMenuRunCmd; + QMenu* m_pMenuPresets; + QAction* m_pMenuPresetsLogApi; + QAction* m_pMenuPresetsINet; + QAction* m_pMenuPresetsShares; + QAction* m_pMenuPresetsNoAdmin; QAction* m_pMenuEmptyBox; QAction* m_pMenuCleanUp; QAction* m_pMenuRemove; QAction* m_pMenuRename; int m_iMenuBox; + QAction* m_pMenuTerminate; QAction* m_pMenuSuspend; QAction* m_pMenuResume; diff --git a/SandboxiePlus/SandMan/main.cpp b/SandboxiePlus/SandMan/main.cpp index 825baf67be..1127d2eeee 100644 --- a/SandboxiePlus/SandMan/main.cpp +++ b/SandboxiePlus/SandMan/main.cpp @@ -113,7 +113,7 @@ bool NotifyCert() "

Unfortunately, such certificates have been abused by malware authors resulting in many Anti Malware Fools being Lazy and flagging Everything signed with them Wrongfully as Malware. " "This Prejudice is Damaging the Open Source Ecosystem as most nonprofit developers can't afford to waste this kind of money every year only to pay that Windows Kernel \"Tax\".

" "

Therefore, the required driver is provided in an obfuscated form and before use must be unpacked. " - "When doing so said said Anti Virus Ass's will complain and attempt to destroy the freshly created file. " + "When doing so said said Anti Viruses will complain and attempt to destroy the freshly created file. " "Please be aware that this is a false positive caused by the necessary use of a compromitted certificate. " "If this happens you will be notified and offered the option to repeat the unpacking operation, for the operation to succeed you will need to configure an aproproate exemption.

"