Merge branch 'experimental' into test_x
This commit is contained in:
commit
b577cb6d12
|
@ -244,8 +244,9 @@ _FX BOOLEAN AdvApi_Init(HMODULE module)
|
|||
// only hook SetSecurityInfo if this is Chrome. Outlook 2013 uses delayed loading and will cause infinite callbacks
|
||||
// Starting with Win 10, we only want to hook ntmarta!SetSecurityInfo. Do NOT hook advapi!SetSecurityInfo. Delay loading for advapi will cause infinite recursion.
|
||||
// Note: the infinite recursion issue has been resolved int 5.43
|
||||
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|
||||
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER)) {
|
||||
if ((Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|
||||
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER))
|
||||
&& !SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
|
||||
SetSecurityInfo = __sys_SetSecurityInfo;
|
||||
GetSecurityInfo = __sys_GetSecurityInfo;
|
||||
SBIEDLL_HOOK(AdvApi_, SetSecurityInfo);
|
||||
|
@ -706,8 +707,9 @@ _FX BOOLEAN Ntmarta_Init(HMODULE module)
|
|||
#define GETPROC2(x,s) __sys_Ntmarta_##x##s = (P_##x) Ldr_GetProcAddrNew(DllName_ntmarta, L#x L#s,#x #s);
|
||||
|
||||
GETPROC2(GetSecurityInfo, );
|
||||
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|
||||
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER)) {
|
||||
if ((Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|
||||
|| (Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME) || (Dll_ImageType == DLL_IMAGE_MOZILLA_FIREFOX) || (Dll_ImageType == DLL_IMAGE_ACROBAT_READER))
|
||||
&& !SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
|
||||
|
||||
GetSecurityInfo = __sys_Ntmarta_GetSecurityInfo;
|
||||
if (GetSecurityInfo)
|
||||
|
|
|
@ -1152,11 +1152,17 @@ _FX NTSTATUS File_NtFsControlFile(
|
|||
handle = File_GetProxyPipe(FileHandle, NULL);
|
||||
if (! handle) {
|
||||
|
||||
status = STATUS_BAD_INITIAL_PC;
|
||||
|
||||
if (IoControlCode == FSCTL_SET_REPARSE_POINT) {
|
||||
|
||||
status = File_SetReparsePoint(
|
||||
FileHandle, InputBuffer, InputBufferLength);
|
||||
SetLastError(LastError);
|
||||
BOOLEAN BoxReparsTarget = SbieApi_QueryConfBool(NULL, L"BoxReparsTarget", FALSE);
|
||||
if(BoxReparsTarget) {
|
||||
|
||||
status = File_SetReparsePoint(
|
||||
FileHandle, InputBuffer, InputBufferLength);
|
||||
SetLastError(LastError);
|
||||
}
|
||||
|
||||
} else if (IoControlCode == FSCTL_PIPE_WAIT) {
|
||||
|
||||
|
@ -1172,8 +1178,7 @@ _FX NTSTATUS File_NtFsControlFile(
|
|||
else
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
|
||||
} else
|
||||
status = STATUS_BAD_INITIAL_PC;
|
||||
}
|
||||
|
||||
if (status == STATUS_BAD_INITIAL_PC) {
|
||||
|
||||
|
|
|
@ -416,7 +416,18 @@ _FX BOOLEAN Gui_Init(HMODULE module)
|
|||
GUI_IMPORT___(ClipCursor);
|
||||
GUI_IMPORT___(GetClipCursor);
|
||||
GUI_IMPORT___(GetCursorPos);
|
||||
GUI_IMPORT___(SetCursorPos);
|
||||
GUI_IMPORT___(SetCursorPos);
|
||||
|
||||
GUI_IMPORT___(SetTimer);
|
||||
HMODULE temp = module;
|
||||
module = Dll_Kernel32;
|
||||
GUI_IMPORT___(Sleep);
|
||||
GUI_IMPORT___(SleepEx);
|
||||
GUI_IMPORT___(GetTickCount);
|
||||
GUI_IMPORT___(GetTickCount64);
|
||||
GUI_IMPORT___(QueryUnbiasedInterruptTime);
|
||||
GUI_IMPORT___(QueryPerformanceCounter);
|
||||
module = temp;
|
||||
|
||||
GUI_IMPORT___(SetTimer);
|
||||
GUI_IMPORT___(MsgWaitForMultipleObjects);
|
||||
|
@ -925,6 +936,24 @@ _FX BOOLEAN Gui_ConnectToWindowStationAndDesktop(HMODULE User32)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE)) {
|
||||
|
||||
static BOOLEAN Connected = FALSE;
|
||||
if (Connected)
|
||||
return TRUE;
|
||||
|
||||
ULONG req = GUI_GET_WINDOW_STATION;
|
||||
GUI_GET_WINDOW_STATION_RPL *rpl = Gui_CallProxyEx(
|
||||
&req, sizeof(ULONG), sizeof(*rpl), FALSE);
|
||||
|
||||
if (rpl) {
|
||||
Dll_Free(rpl);
|
||||
Connected = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// the first win32k service call (i.e. service number >= 0x1000)
|
||||
// triggers "thread GUI conversion". the kernel system service
|
||||
|
|
|
@ -102,8 +102,8 @@ typedef HWND(*P_SetActiveWindow)(HWND hWnd);
|
|||
|
||||
typedef UINT_PTR (*P_SetTimer)(
|
||||
HWND hWnd,
|
||||
UINT_PTR nIDEvent,
|
||||
UINT uElapse,
|
||||
UINT_PTR nIDEvent,
|
||||
UINT uElapse,
|
||||
TIMERPROC lpTimerFunc
|
||||
);
|
||||
|
||||
|
@ -621,7 +621,7 @@ GUI_SYS_VAR_2(SendNotifyMessage)
|
|||
GUI_SYS_VAR_2(PostMessage)
|
||||
GUI_SYS_VAR_2(PostThreadMessage)
|
||||
GUI_SYS_VAR_2(DispatchMessage)
|
||||
|
||||
|
||||
GUI_SYS_VAR(SetTimer)
|
||||
|
||||
GUI_SYS_VAR(MapWindowPoints)
|
||||
|
|
|
@ -234,6 +234,9 @@ _FX BOOLEAN Gui_InitEnum(HMODULE module)
|
|||
// hook desktop APIs
|
||||
//
|
||||
|
||||
if (SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE))
|
||||
return TRUE;
|
||||
|
||||
SBIEDLL_HOOK_GUI(EnumDesktopsW);
|
||||
SBIEDLL_HOOK_GUI(EnumDesktopsA);
|
||||
SBIEDLL_HOOK_GUI(OpenDesktopW);
|
||||
|
|
|
@ -285,7 +285,7 @@ _FX BOOLEAN Gui_InitMisc(HMODULE module)
|
|||
__sys_GetThreadDpiAwarenessContext = (P_GetThreadDpiAwarenessContext)
|
||||
Ldr_GetProcAddrNew(DllName_user32, L"GetThreadDpiAwarenessContext","GetThreadDpiAwarenessContext");
|
||||
|
||||
|
||||
HMODULE current = module;
|
||||
if (SbieApi_QueryConfBool(NULL, L"BlockInterferePower", FALSE)) {
|
||||
|
||||
SBIEDLL_HOOK_GUI(ShutdownBlockReasonCreate);
|
||||
|
@ -1703,3 +1703,45 @@ _FX void Gui_SwitchToThisWindow(HWND hWnd, BOOL fAlt)
|
|||
return;
|
||||
__sys_SwitchToThisWindow(hWnd, fAlt);
|
||||
}
|
||||
|
||||
_FX DWORD Gui_GetTickCount() {
|
||||
return __sys_GetTickCount() * SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL,L"LowTickSpeed", 1);
|
||||
}
|
||||
|
||||
_FX ULONGLONG Gui_GetTickCount64() {
|
||||
return __sys_GetTickCount64() * SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
|
||||
}
|
||||
|
||||
_FX BOOL Gui_QueryUnbiasedInterruptTime(
|
||||
PULONGLONG UnbiasedTime
|
||||
) {
|
||||
BOOL rtn = __sys_QueryUnbiasedInterruptTime(UnbiasedTime);
|
||||
*UnbiasedTime *= SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
_FX void Gui_Sleep(DWORD dwMiSecond) {
|
||||
__sys_Sleep(dwMiSecond * SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1));
|
||||
}
|
||||
|
||||
_FX DWORD Gui_SleepEx(DWORD dwMiSecond, BOOL bAlert) {
|
||||
return __sys_SleepEx(dwMiSecond * SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1),bAlert);
|
||||
}
|
||||
|
||||
_FX BOOL Gui_QueryPerformanceCounter(
|
||||
LARGE_INTEGER* lpPerformanceCount
|
||||
) {
|
||||
BOOL rtn = __sys_QueryPerformanceCounter(lpPerformanceCount);
|
||||
lpPerformanceCount->QuadPart = lpPerformanceCount->QuadPart*SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1)/ SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
_FX UINT_PTR Gui_SetTimer(
|
||||
HWND hWnd,
|
||||
UINT_PTR nIDEvent,
|
||||
UINT uElapse,
|
||||
TIMERPROC lpTimerFunc
|
||||
)
|
||||
{
|
||||
return __sys_SetTimer(hWnd, nIDEvent, uElapse * SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1), lpTimerFunc);
|
||||
}
|
||||
|
|
|
@ -416,8 +416,7 @@ _FX BOOLEAN Secure_Init(void)
|
|||
// note: when running as the built in administrator we should always act as if we have admin rights
|
||||
//
|
||||
|
||||
Secure_FakeAdmin = Config_GetSettingsForImageName_bool(L"FakeAdminRights", Secure_IsBuiltInAdmin())
|
||||
&& (_wcsicmp(Dll_ImageName, L"msedge.exe") != 0); // never for msedge.exe
|
||||
Secure_FakeAdmin = Config_GetSettingsForImageName_bool(L"FakeAdminRights", Secure_IsBuiltInAdmin());
|
||||
|
||||
|
||||
void* NtAccessCheckByType = GetProcAddress(Dll_Ntdll, "NtAccessCheckByType");
|
||||
|
|
|
@ -184,7 +184,8 @@ _FX BOX *Process_GetForcedStartBox(
|
|||
if (! ProcessObject)
|
||||
return NULL;
|
||||
|
||||
if ( (_wcsicmp(pSidString, Driver_S_1_5_18) == 0 || // System
|
||||
if ((! Conf_Get_Boolean(NULL, L"AllowForceSystem", 0, FALSE)) &&
|
||||
(_wcsicmp(pSidString, Driver_S_1_5_18) == 0 || // System
|
||||
_wcsicmp(pSidString, Driver_S_1_5_19) == 0 || // Local Service
|
||||
_wcsicmp(pSidString, Driver_S_1_5_20) == 0) // Network Service
|
||||
&& (! Process_IsDcomLaunchParent(ParentId)) ){
|
||||
|
@ -274,7 +275,8 @@ _FX BOX *Process_GetForcedStartBox(
|
|||
&boxes, DocArg, force_alert, &alert);
|
||||
}
|
||||
|
||||
if (box && Process_IsImmersiveProcess(
|
||||
if (box && (! Conf_Get_Boolean(NULL, L"AllowForceImmersive", 0, FALSE)) &&
|
||||
Process_IsImmersiveProcess(
|
||||
ProcessObject, ParentId, SessionId)) {
|
||||
box = NULL;
|
||||
alert = 1;
|
||||
|
|
|
@ -34,6 +34,60 @@
|
|||
#include "dyn_data.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Structures and Types
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*struct _TOKEN// Size=0x2a0
|
||||
{
|
||||
struct _TOKEN_SOURCE TokenSource;// Offset=0x0 Size=0x10
|
||||
struct _LUID TokenId;// Offset=0x10 Size=0x8
|
||||
struct _LUID AuthenticationId;// Offset=0x18 Size=0x8
|
||||
struct _LUID ParentTokenId;// Offset=0x20 Size=0x8
|
||||
union _LARGE_INTEGER ExpirationTime;// Offset=0x28 Size=0x8
|
||||
struct _ERESOURCE *TokenLock;// Offset=0x30 Size=0x4
|
||||
struct _LUID ModifiedId;// Offset=0x34 Size=0x8
|
||||
struct _SEP_TOKEN_PRIVILEGES Privileges;// Offset=0x40 Size=0x18
|
||||
struct _SEP_AUDIT_POLICY AuditPolicy;// Offset=0x58 Size=0x1f
|
||||
unsigned long SessionId;// Offset=0x78 Size=0x4
|
||||
unsigned long UserAndGroupCount;// Offset=0x7c Size=0x4
|
||||
unsigned long RestrictedSidCount;// Offset=0x80 Size=0x4
|
||||
unsigned long VariableLength;// Offset=0x84 Size=0x4
|
||||
unsigned long DynamicCharged;// Offset=0x88 Size=0x4
|
||||
unsigned long DynamicAvailable;// Offset=0x8c Size=0x4
|
||||
unsigned long DefaultOwnerIndex;// Offset=0x90 Size=0x4
|
||||
struct _SID_AND_ATTRIBUTES *UserAndGroups;// Offset=0x94 Size=0x4
|
||||
struct _SID_AND_ATTRIBUTES *RestrictedSids;// Offset=0x98 Size=0x4
|
||||
void *PrimaryGroup;// Offset=0x9c Size=0x4
|
||||
unsigned long *DynamicPart;// Offset=0xa0 Size=0x4
|
||||
struct _ACL *DefaultDacl;// Offset=0xa4 Size=0x4
|
||||
enum _TOKEN_TYPE TokenType;// Offset=0xa8 Size=0x4
|
||||
enum _SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;// Offset=0xac Size=0x4
|
||||
unsigned long TokenFlags;// Offset=0xb0 Size=0x4
|
||||
unsigned int TokenInUse;// Offset=0xb4 Size=0x1
|
||||
unsigned long IntegrityLevelIndex;// Offset=0xb8 Size=0x4
|
||||
unsigned long MandatoryPolicy;// Offset=0xbc Size=0x4
|
||||
struct _SEP_LOGON_SESSION_REFERENCES *LogonSession;// Offset=0xc0 Size=0x4
|
||||
struct _LUID OriginatingLogonSession;// Offset=0xc4 Size=0x8
|
||||
struct _SID_AND_ATTRIBUTES_HASH SidHash;// Offset=0xcc Size=0x88
|
||||
struct _SID_AND_ATTRIBUTES_HASH RestrictedSidHash;// Offset=0x154 Size=0x88
|
||||
struct _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION *pSecurityAttributes;// Offset=0x1dc Size=0x4
|
||||
void *Package;// Offset=0x1e0 Size=0x4
|
||||
struct _SID_AND_ATTRIBUTES *Capabilities;// Offset=0x1e4 Size=0x4
|
||||
unsigned long CapabilityCount;// Offset=0x1e8 Size=0x4
|
||||
struct _SID_AND_ATTRIBUTES_HASH CapabilitiesHash;// Offset=0x1ec Size=0x88
|
||||
struct _SEP_LOWBOX_NUMBER_ENTRY *LowboxNumberEntry;// Offset=0x274 Size=0x4
|
||||
struct _SEP_LOWBOX_HANDLES_ENTRY *LowboxHandlesEntry;// Offset=0x278 Size=0x4
|
||||
struct _AUTHZBASEP_CLAIM_ATTRIBUTES_COLLECTION *pClaimAttributes;// Offset=0x27c Size=0x4
|
||||
void *TrustLevelSid;// Offset=0x280 Size=0x4
|
||||
struct _TOKEN *TrustLinkedToken;// Offset=0x284 Size=0x4
|
||||
void *IntegrityLevelSidValue;// Offset=0x288 Size=0x4
|
||||
struct _SEP_SID_VALUES_BLOCK *TokenSidValues;// Offset=0x28c Size=0x4
|
||||
struct _SEP_LUID_TO_INDEX_MAP_ENTRY *IndexEntry;// Offset=0x290 Size=0x4
|
||||
struct _SEP_TOKEN_DIAG_TRACK_ENTRY *DiagnosticInfo;// Offset=0x294 Size=0x4
|
||||
unsigned long VariablePart;// Offset=0x298 Size=0x4
|
||||
};*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -78,7 +132,7 @@ static BOOLEAN Token_AssignPrimary(
|
|||
|
||||
static void *Token_DuplicateToken(void *TokenObject, PROCESS *proc);
|
||||
|
||||
static void *Token_CreateNew(void *TokenObject, PROCESS *proc);
|
||||
static void *Token_CreateToken(void *TokenObject, BOOLEAN Replicate, PROCESS *proc);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
@ -880,13 +934,22 @@ _FX void *Token_Restrict(
|
|||
// Create a heavily restricted primary token
|
||||
//
|
||||
|
||||
if (Conf_Get_Boolean(proc->box->name, L"CreateToken", 0, FALSE)) {
|
||||
|
||||
if (Conf_Get_Boolean(proc->box->name, L"CreateToken", 0, FALSE)) {
|
||||
|
||||
//
|
||||
// Create a new token from scratch, experimental
|
||||
// Create a custom restricted token from scratch
|
||||
//
|
||||
|
||||
FixedTokenObject = Token_CreateNew(TokenObject, proc);
|
||||
return Token_CreateToken(TokenObject, FALSE, proc);
|
||||
}
|
||||
|
||||
if (Conf_Get_Boolean(proc->box->name, L"ReplicateToken", 0, FALSE)) {
|
||||
|
||||
//
|
||||
// Create a new replicated token from scratch
|
||||
//
|
||||
|
||||
FixedTokenObject = Token_CreateToken(TokenObject, TRUE, proc);
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -1369,6 +1432,7 @@ _FX void *Token_RestrictHelper3(
|
|||
BOOLEAN AnonymousLogonSidAlreadyInGroups = FALSE;
|
||||
|
||||
BOOLEAN KeepUserGroup = Conf_Get_Boolean(proc->box->name, L"KeepUserGroup", 0, FALSE);
|
||||
BOOLEAN OpenWndStation = Conf_Get_Boolean(proc->box->name, L"OpenWndStation", 0, FALSE);
|
||||
|
||||
n = 0;
|
||||
|
||||
|
@ -1377,6 +1441,9 @@ _FX void *Token_RestrictHelper3(
|
|||
if (Groups->Groups[i].Attributes & SE_GROUP_INTEGRITY)
|
||||
continue;
|
||||
|
||||
if (OpenWndStation && (Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID))
|
||||
continue;
|
||||
|
||||
if (RtlEqualSid(Groups->Groups[i].Sid, UserSid)) {
|
||||
if (KeepUserGroup)
|
||||
continue;
|
||||
|
@ -1704,6 +1771,7 @@ _FX BOOLEAN Token_ReplacePrimary(PROCESS *proc)
|
|||
#ifdef _WIN64
|
||||
// OpenToken BEGIN
|
||||
if (!Conf_Get_Boolean(proc->box->name, L"CreateToken", 0, FALSE)
|
||||
&& !Conf_Get_Boolean(proc->box->name, L"ReplicateToken", 0, FALSE)
|
||||
&& !Conf_Get_Boolean(proc->box->name, L"UnrestrictedToken", 0, FALSE)
|
||||
&& Conf_Get_Boolean(proc->box->name, L"AnonymousLogon", 0, TRUE))
|
||||
// OpenToken END
|
||||
|
@ -2116,11 +2184,11 @@ _FX NTSTATUS SbieCreateToken(PHANDLE TokenHandle, ACCESS_MASK DesiredAccess, POB
|
|||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Token_CreateNew
|
||||
// Token_CreateToken
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
||||
_FX void* Token_CreateToken(void* TokenObject, BOOLEAN Replicate, PROCESS* proc)
|
||||
{
|
||||
HANDLE TokenHandle = NULL;
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
|
@ -2141,15 +2209,19 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
|||
PTOKEN_SOURCE LocalSource = NULL;
|
||||
|
||||
PTOKEN_DEFAULT_DACL NewDefaultDacl = NULL;
|
||||
PTOKEN_OWNER NewOwner = NULL;
|
||||
ULONG DefaultDacl_Length = 0;
|
||||
PACL NewDacl = NULL;
|
||||
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
TOKEN_TYPE TokenType = TokenPrimary;
|
||||
LUID AuthenticationId = ANONYMOUS_LOGON_LUID;
|
||||
LARGE_INTEGER ExpirationTime;
|
||||
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
SECURITY_QUALITY_OF_SERVICE SecurityQos;
|
||||
|
||||
//
|
||||
// Get the information from the original token
|
||||
// Gether informations from the original token
|
||||
//
|
||||
|
||||
if ( !NT_SUCCESS(SeQueryInformationToken(TokenObject, TokenStatistics, &LocalStatistics))
|
||||
|
@ -2170,6 +2242,58 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
|||
MandatoryPolicy = (PTOKEN_MANDATORY_POLICY)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_MANDATORY_POLICY), tzuk);
|
||||
if (MandatoryPolicy) MandatoryPolicy->Policy = TOKEN_MANDATORY_POLICY_NO_WRITE_UP;
|
||||
|
||||
//
|
||||
// Create a new token from scratch
|
||||
//
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
SecurityQos.Length = sizeof(SecurityQos);
|
||||
SecurityQos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
|
||||
SecurityQos.EffectiveOnly = FALSE;
|
||||
ObjectAttributes.SecurityQualityOfService = &SecurityQos;
|
||||
|
||||
if (Replicate)
|
||||
{
|
||||
SecurityQos.ImpersonationLevel = LocalStatistics->ImpersonationLevel;
|
||||
|
||||
TokenType = LocalStatistics->TokenType;
|
||||
AuthenticationId = LocalStatistics->AuthenticationId;
|
||||
ExpirationTime = LocalStatistics->ExpirationTime;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
SecurityQos.ImpersonationLevel = SecurityAnonymous;
|
||||
|
||||
ExpirationTime.QuadPart = 0x7FFFFFFFFFFFFFFF;
|
||||
|
||||
if (!Conf_Get_Boolean(proc->box->name, L"UnstrippedToken", 0, FALSE))
|
||||
{
|
||||
BOOLEAN KeepUserGroup = Conf_Get_Boolean(proc->box->name, L"KeepUserGroup", 0, FALSE);
|
||||
BOOLEAN OpenWndStation = Conf_Get_Boolean(proc->box->name, L"OpenWndStation", 0, FALSE);
|
||||
|
||||
for (ULONG i = 0; i < LocalGroups->GroupCount; i++) {
|
||||
|
||||
if (LocalGroups->Groups[i].Attributes & SE_GROUP_INTEGRITY) {
|
||||
if (!Conf_Get_Boolean(proc->box->name, L"KeepTokenIntegrity", 0, FALSE))
|
||||
*RtlSubAuthoritySid(LocalGroups->Groups[i].Sid, 0) = SECURITY_MANDATORY_UNTRUSTED_RID;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (OpenWndStation && (LocalGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID))
|
||||
continue;
|
||||
|
||||
if (RtlEqualSid(LocalGroups->Groups[i].Sid, LocalUser->User.Sid)) {
|
||||
if (KeepUserGroup)
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalGroups->Groups[i].Attributes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Change the SID
|
||||
//
|
||||
|
@ -2181,37 +2305,28 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
|||
|
||||
if (proc->SandboxieLogonSid)
|
||||
{
|
||||
//
|
||||
// free old user and create a new one with the new SID
|
||||
//
|
||||
|
||||
ULONG Attributes = LocalUser->User.Attributes;
|
||||
|
||||
ExFreePool((PVOID)LocalUser);
|
||||
LocalUser = ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_USER) + RtlLengthSid(proc->SandboxieLogonSid), tzuk);
|
||||
|
||||
LocalUser->User.Attributes = Attributes;
|
||||
LocalUser->User.Sid = ((UCHAR*)LocalUser) + sizeof(TOKEN_USER);
|
||||
|
||||
memcpy(LocalUser->User.Sid, proc->SandboxieLogonSid, RtlLengthSid(proc->SandboxieLogonSid));
|
||||
}
|
||||
|
||||
//
|
||||
// Create a new token from scratch
|
||||
//
|
||||
|
||||
SecurityQos.Length = sizeof(SecurityQos);
|
||||
SecurityQos.ImpersonationLevel = LocalStatistics->ImpersonationLevel;
|
||||
SecurityQos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
|
||||
SecurityQos.EffectiveOnly = FALSE;
|
||||
|
||||
ObjectAttributes.SecurityQualityOfService = &SecurityQos;
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&ObjectAttributes,
|
||||
NULL,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
//LUID AuthenticationId = ANONYMOUS_LOGON_LUID;
|
||||
|
||||
|
||||
status = SbieCreateToken(
|
||||
&TokenHandle,
|
||||
TOKEN_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
LocalStatistics->TokenType,
|
||||
&LocalStatistics->AuthenticationId,
|
||||
&LocalStatistics->ExpirationTime,
|
||||
TokenType,
|
||||
&AuthenticationId,
|
||||
&ExpirationTime,
|
||||
LocalUser,
|
||||
LocalGroups,
|
||||
LocalPrivileges,
|
||||
|
@ -2248,18 +2363,19 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
|||
NewDefaultDacl->DefaultDacl = NewDacl = (PACL)((ULONG_PTR)NewDefaultDacl + sizeof(TOKEN_DEFAULT_DACL));
|
||||
NewDefaultDacl->DefaultDacl->AclSize += 128;
|
||||
|
||||
NewOwner = (PTOKEN_OWNER)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_OWNER), tzuk);
|
||||
NewOwner->Owner = LocalUser->User.Sid;
|
||||
ExFreePool((PVOID)LocalOwner);
|
||||
LocalOwner = (PTOKEN_OWNER)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_OWNER), tzuk);
|
||||
LocalOwner->Owner = LocalUser->User.Sid;
|
||||
|
||||
RtlAddAccessAllowedAce(NewDacl, ACL_REVISION2, GENERIC_ALL, NewOwner->Owner);
|
||||
RtlAddAccessAllowedAce(NewDacl, ACL_REVISION2, GENERIC_ALL, LocalOwner->Owner);
|
||||
|
||||
status = SbieCreateToken(
|
||||
&TokenHandle,
|
||||
TOKEN_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
LocalStatistics->TokenType,
|
||||
&LocalStatistics->AuthenticationId,
|
||||
&LocalStatistics->ExpirationTime,
|
||||
TokenType,
|
||||
&AuthenticationId,
|
||||
&ExpirationTime,
|
||||
LocalUser,
|
||||
LocalGroups,
|
||||
LocalPrivileges,
|
||||
|
@ -2269,7 +2385,7 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
|||
0, //DeviceGroups,
|
||||
MandatoryPolicy,
|
||||
|
||||
NewOwner,
|
||||
LocalOwner,
|
||||
LocalPrimaryGroup,
|
||||
NewDefaultDacl,
|
||||
LocalSource
|
||||
|
@ -2294,17 +2410,16 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
|||
ULONG virtualizationAllowed = 1;
|
||||
status = ZwSetInformationToken(TokenHandle, TokenVirtualizationAllowed, &virtualizationAllowed, sizeof(ULONG));
|
||||
|
||||
if (Conf_Get_Boolean(proc->box->name, L"CopyTokenAttributes", 0, FALSE))
|
||||
{
|
||||
HANDLE OldTokenHandle;
|
||||
status = ObOpenObjectByPointer(
|
||||
TokenObject, OBJ_KERNEL_HANDLE, NULL, TOKEN_ALL_ACCESS,
|
||||
*SeTokenObjectType, KernelMode, &OldTokenHandle);
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
void* ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, tzuk);
|
||||
|
||||
/*HANDLE OldTokenHandle;
|
||||
status = ObOpenObjectByPointer(
|
||||
TokenObject, OBJ_KERNEL_HANDLE, NULL, TOKEN_ALL_ACCESS,
|
||||
*SeTokenObjectType, KernelMode, &OldTokenHandle);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
__try {
|
||||
|
||||
void* ptr = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, tzuk);
|
||||
if (ptr) {
|
||||
ULONG len = 0;
|
||||
status = ZwQueryInformationToken(OldTokenHandle, TokenSecurityAttributes, ptr, PAGE_SIZE, &len);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
@ -2320,18 +2435,12 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
|||
|
||||
status = ZwSetInformationToken(TokenHandle, TokenSecurityAttributes, data, len);
|
||||
}
|
||||
|
||||
ExFreePool(ptr);
|
||||
|
||||
ZwClose(OldTokenHandle);
|
||||
}
|
||||
if (ptr)ExFreePool(ptr);
|
||||
|
||||
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode() + 0x01000000;
|
||||
}
|
||||
|
||||
DbgPrint("TokenSecurityAttributes %08x", status);
|
||||
|
||||
ZwClose(OldTokenHandle);
|
||||
}*/
|
||||
}
|
||||
|
||||
finish:
|
||||
if (LocalStatistics) ExFreePool((PVOID)LocalStatistics);
|
||||
|
@ -2350,8 +2459,6 @@ finish:
|
|||
if (LocalSource) ExFreePool((PVOID)LocalSource);
|
||||
|
||||
if (NewDefaultDacl) ExFreePool((PVOID)NewDefaultDacl);
|
||||
if (NewOwner) ExFreePool((PVOID)NewOwner);
|
||||
|
||||
|
||||
//
|
||||
// get the actual token object from the handle
|
||||
|
@ -2366,5 +2473,4 @@ finish:
|
|||
NtClose(TokenHandle);
|
||||
}
|
||||
return NewTokenObject;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,665 @@
|
|||
/*
|
||||
* Copyright 2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Box Manager
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "BoxManager.h"
|
||||
#include "ProcessServer.h"
|
||||
#include "MountManager.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Defines
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Structures and Types
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*typedef struct _LINGER_LEADER {
|
||||
HANDLE orig_pid;
|
||||
HANDLE curr_pid;
|
||||
WCHAR image[1];
|
||||
} LINGER_LEADER;*/
|
||||
|
||||
struct BOX_INSTANCE
|
||||
{
|
||||
std::wstring BoxName;
|
||||
//bool HiveMounted = false;
|
||||
|
||||
std::map<ULONG, BOXED_PROCESS*> ProcessMap;
|
||||
|
||||
/*ULONG linger_count;
|
||||
ULONG leader_count;
|
||||
LINGER_LEADER **lingers;
|
||||
LINGER_LEADER **leaders;
|
||||
BOOLEAN any_leaders;*/
|
||||
};
|
||||
|
||||
struct BOXED_PROCESS
|
||||
{
|
||||
ULONG ProcessId;
|
||||
ULONG SessionId;
|
||||
BOX_INSTANCE* pBox;
|
||||
|
||||
HANDLE hProcHandle;
|
||||
HANDLE hProcWait;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
BoxManager::BoxManager()
|
||||
{
|
||||
InitializeCriticalSection(&m_CritSec);
|
||||
|
||||
LoadProcesses();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// BoxManager
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
BoxManager *BoxManager::GetInstance()
|
||||
{
|
||||
static BoxManager *_instance = NULL;
|
||||
if (! _instance)
|
||||
_instance = new BoxManager();
|
||||
return _instance;
|
||||
}
|
||||
|
||||
|
||||
void BoxManager::LoadProcesses()
|
||||
{
|
||||
ULONG pid_count = 0;
|
||||
SbieApi_EnumProcessEx(NULL, TRUE, -1, NULL, &pid_count); // query count
|
||||
pid_count += 128;
|
||||
|
||||
std::vector<ULONG> pids;
|
||||
pids.resize(pid_count + 1); // allocate oen more for the -1 marker
|
||||
SbieApi_EnumProcessEx(NULL, TRUE, -1, &pids.front(), &pid_count); // query pids
|
||||
|
||||
ULONG reg_root_len = 256;
|
||||
WCHAR* reg_root_path = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, reg_root_len + 16);;
|
||||
|
||||
for (ULONG i = 0; i <= pid_count; ++i) {
|
||||
|
||||
WCHAR boxname[34];
|
||||
ULONG session_id;
|
||||
SbieApi_QueryProcess((HANDLE)(ULONG_PTR)pids[i], boxname, NULL, NULL, &session_id);
|
||||
|
||||
ULONG reg_len = reg_root_len;
|
||||
if (!NT_SUCCESS(SbieApi_QueryProcessPath((HANDLE)(ULONG_PTR)pids[i], NULL, NULL, NULL, NULL, ®_len, NULL)))
|
||||
continue;
|
||||
if (reg_len > reg_root_len) {
|
||||
reg_root_len = reg_len;
|
||||
reg_root_path = (WCHAR*)HeapReAlloc(GetProcessHeap(), 0, reg_root_path, reg_root_len + 16);
|
||||
if (!reg_root_path)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(SbieApi_QueryProcessPath((HANDLE)(ULONG_PTR)pids[i], NULL, reg_root_path, NULL, NULL, ®_len, NULL)))
|
||||
continue;
|
||||
|
||||
ProcessCreated(pids[i], boxname, reg_root_path, session_id);
|
||||
}
|
||||
|
||||
if (reg_root_path)
|
||||
HeapFree(GetProcessHeap(), 0, reg_root_path);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WaitOrTimerCallback
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
|
||||
{
|
||||
BOXED_PROCESS* pProcess = (BOXED_PROCESS*)lpParameter;
|
||||
|
||||
UnregisterWait(pProcess->hProcWait);
|
||||
CloseHandle(pProcess->hProcHandle);
|
||||
|
||||
EnterCriticalSection(&BoxManager::GetInstance()->m_CritSec);
|
||||
|
||||
if (pProcess->pBox) {
|
||||
pProcess->pBox->ProcessMap.erase(pProcess->ProcessId);
|
||||
#if 0
|
||||
BoxManager::GetInstance()->CheckLinger(pProcess->pBox, pProcess->SessionId);
|
||||
#endif
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&BoxManager::GetInstance()->m_CritSec);
|
||||
|
||||
delete pProcess;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
WINBASEAPI DWORD WINAPI GetFinalPathNameByHandleW(
|
||||
_In_ HANDLE hFile,
|
||||
_Out_writes_(cchFilePath) LPWSTR lpszFilePath,
|
||||
_In_ DWORD cchFilePath,
|
||||
_In_ DWORD dwFlags
|
||||
);
|
||||
}
|
||||
|
||||
//std::wstring BoxManager__GetFinalPath(const WCHAR* file_root_path)
|
||||
//{
|
||||
// std::wstring FileRootPath;
|
||||
// FileRootPath.resize(8192);
|
||||
//
|
||||
// //
|
||||
// // get the final file path by opening it and retrieving it from the handle
|
||||
// //
|
||||
//
|
||||
// UNICODE_STRING objname;
|
||||
// RtlInitUnicodeString(&objname, file_root_path);
|
||||
//
|
||||
// OBJECT_ATTRIBUTES objattrs;
|
||||
// InitializeObjectAttributes(
|
||||
// &objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
//
|
||||
// HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
// IO_STATUS_BLOCK IoStatusBlock;
|
||||
// NTSTATUS status = NtCreateFile(
|
||||
// &handle, GENERIC_READ, &objattrs, &IoStatusBlock, NULL, 0,
|
||||
// FILE_SHARE_VALID_FLAGS, FILE_OPEN, 0, NULL, 0);
|
||||
//
|
||||
// DWORD dwRet = GetFinalPathNameByHandleW(handle, (WCHAR*)FileRootPath.c_str(), FileRootPath.size(), VOLUME_NAME_NT);
|
||||
// //if (dwRet == 0 || dwRet > FileRootPath.size()) // failed || buffer to small
|
||||
// // goto finish;
|
||||
//
|
||||
// if (handle != INVALID_HANDLE_VALUE)
|
||||
// NtClose(handle);
|
||||
//
|
||||
// return FileRootPath;
|
||||
//}
|
||||
|
||||
bool BoxManager::ProcessCreated(ULONG ProcessId, const WCHAR* boxname, const WCHAR* reg_root, ULONG session_id)
|
||||
{
|
||||
bool IsFirst = false;
|
||||
|
||||
EnterCriticalSection(&m_CritSec);
|
||||
|
||||
BOX_INSTANCE* &pBox = m_BoxMap[reg_root];
|
||||
|
||||
if (!pBox) {
|
||||
pBox = new BOX_INSTANCE;
|
||||
pBox->BoxName = std::wstring(boxname);
|
||||
|
||||
SbieApi_LogEx(session_id, 2201, L"BoxCreated %S", pBox->BoxName.c_str());
|
||||
|
||||
#if 0
|
||||
InitLinger(pBox);
|
||||
#endif
|
||||
|
||||
IsFirst = true;
|
||||
}
|
||||
|
||||
BOXED_PROCESS* &pProcess = pBox->ProcessMap[ProcessId];
|
||||
if (!pProcess) {
|
||||
pProcess = new BOXED_PROCESS;
|
||||
|
||||
pProcess->ProcessId = ProcessId;
|
||||
pProcess->SessionId = session_id;
|
||||
pProcess->pBox = pBox;
|
||||
|
||||
pProcess->hProcHandle = OpenProcess(SYNCHRONIZE, FALSE, ProcessId);
|
||||
if (pProcess->hProcHandle) {
|
||||
RegisterWaitForSingleObject(&pProcess->hProcWait, pProcess->hProcHandle, WaitOrTimerCallback, (void*)pProcess, INFINITE, WT_EXECUTEONLYONCE);
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_CritSec);
|
||||
|
||||
return IsFirst;
|
||||
}
|
||||
|
||||
void BoxManager::BoxOpened(const WCHAR* reg_root, ULONG session_id)
|
||||
{
|
||||
EnterCriticalSection(&m_CritSec);
|
||||
|
||||
auto I = m_BoxMap.find(reg_root);
|
||||
if (I != m_BoxMap.end()){
|
||||
SbieApi_LogEx(session_id, 2201, L"BoxOpened %S", I->second->BoxName.c_str());
|
||||
//I->second->HiveMounted = TRUE;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_CritSec);
|
||||
}
|
||||
|
||||
void BoxManager::BoxClosed(const WCHAR* reg_root, ULONG session_id)
|
||||
{
|
||||
EnterCriticalSection(&m_CritSec);
|
||||
|
||||
auto I = m_BoxMap.find(reg_root);
|
||||
if (I != m_BoxMap.end()){
|
||||
SbieApi_LogEx(session_id, 2201, L"BoxClosed %S", I->second->BoxName.c_str());
|
||||
|
||||
// the process map should be empty
|
||||
for (auto J = I->second->ProcessMap.begin(); J != I->second->ProcessMap.end(); ++J)
|
||||
{
|
||||
// keep the process around untill the event fires, but set the box pointer to NULL
|
||||
J->second->pBox = NULL;
|
||||
//delete pProcess;
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (ULONG i = 0; i < pBox->linger_count; ++i) {
|
||||
HeapFree(GetProcessHeap(), 0, pBox->lingers[i]);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pBox->lingers);
|
||||
|
||||
for (ULONG i = 0; i < pBox->leader_count; ++i) {
|
||||
HeapFree(GetProcessHeap(), 0, pBox->leaders[i]);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pBox->leaders);
|
||||
#endif
|
||||
|
||||
delete I->second;
|
||||
m_BoxMap.erase(I);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_CritSec);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
#include "../../common/my_version.h"
|
||||
|
||||
|
||||
#define MAX_LINGER_LEADER_COUNT 512
|
||||
|
||||
static const WCHAR *_SandboxieRpcSs = SANDBOXIE L"RpcSs.exe";
|
||||
static const WCHAR *_msiexec = L"msiexec.exe";
|
||||
|
||||
static const WCHAR *_SandboxieDcomLaunch = SANDBOXIE L"DcomLaunch.exe";
|
||||
static const WCHAR *_SandboxieCrypto = SANDBOXIE L"Crypto.exe";
|
||||
static const WCHAR *_SandboxieBITS = SANDBOXIE L"BITS.exe";
|
||||
static const WCHAR *_SandboxieWUAU = SANDBOXIE L"WUAU.exe";
|
||||
static const WCHAR *_wuauclt = L"wuauclt.exe";
|
||||
static const WCHAR *_TrustedInstaller = L"TrustedInstaller.exe";
|
||||
static const WCHAR *_tiworker = L"tiworker.exe";
|
||||
|
||||
|
||||
|
||||
_FX void Add_LL_Entry(
|
||||
LINGER_LEADER **lingers, ULONG *inout_count, const WCHAR *image)
|
||||
{
|
||||
ULONG linger_count = *inout_count;
|
||||
|
||||
if (linger_count >= MAX_LINGER_LEADER_COUNT)
|
||||
return;
|
||||
|
||||
lingers[linger_count] = (LINGER_LEADER*)HeapAlloc(
|
||||
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
|
||||
sizeof(LINGER_LEADER) + (wcslen(image) + 4) * sizeof(WCHAR));
|
||||
|
||||
lingers[linger_count]->orig_pid = NULL;
|
||||
lingers[linger_count]->curr_pid = NULL;
|
||||
wcscpy(lingers[linger_count]->image, image);
|
||||
|
||||
++linger_count;
|
||||
|
||||
*inout_count = linger_count;
|
||||
}
|
||||
|
||||
void BoxManager::InitLinger(BOX_INSTANCE* pBox)
|
||||
{
|
||||
// ULONG i, j;
|
||||
// HANDLE pids_i;
|
||||
WCHAR image[128];
|
||||
// PROCESS_DATA *myData;
|
||||
LONG rc;
|
||||
|
||||
|
||||
if (1) {
|
||||
|
||||
//
|
||||
// read and store LingerProcess configuration
|
||||
//
|
||||
|
||||
pBox->lingers = (LINGER_LEADER**)HeapAlloc(
|
||||
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
|
||||
sizeof(LINGER_LEADER *) * MAX_LINGER_LEADER_COUNT);
|
||||
|
||||
while (1)
|
||||
{
|
||||
rc = SbieApi_QueryConfAsIs(
|
||||
NULL, L"LingerProcess", pBox->linger_count,
|
||||
image, sizeof(WCHAR) * 120);
|
||||
if (rc != 0)
|
||||
break;
|
||||
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, image);
|
||||
}
|
||||
|
||||
//
|
||||
// see which of the LingerProcess programs were already active
|
||||
// before SandboxieRpcSs started. they will not be considered
|
||||
// LingerProcess programs and will not be terminated
|
||||
//
|
||||
|
||||
/*ULONG pid_count = 0;
|
||||
SbieApi_EnumProcessEx(NULL, FALSE, -1, NULL, &pid_count); // query count
|
||||
pid_count += 128;
|
||||
|
||||
ULONG* pids = (ULONG*)HeapAlloc(
|
||||
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(ULONG) * pid_count);
|
||||
SbieApi_EnumProcessEx(NULL, FALSE, -1, pids, &pid_count); // query pids
|
||||
|
||||
AddPid(pids, pid_count);
|
||||
|
||||
for (i = 0; i <= pid_count; ++i) {
|
||||
|
||||
pids_i = (HANDLE) (ULONG_PTR) pids[i];
|
||||
SbieApi_QueryProcess(pids_i, NULL, image, NULL, NULL);
|
||||
|
||||
for (j = 0; j < linger_count; ++j) {
|
||||
if (_wcsicmp(lingers[j]->image, image) == 0) {
|
||||
lingers[j]->orig_pid = pids_i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pids);*/
|
||||
|
||||
//
|
||||
// add standard lingers. note that we don't check if any of
|
||||
// the following processes was already active before we started
|
||||
//
|
||||
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieDcomLaunch);
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieCrypto);
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieBITS);
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _SandboxieWUAU);
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _wuauclt);
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _TrustedInstaller);
|
||||
Add_LL_Entry(pBox->lingers, &pBox->linger_count, _tiworker);
|
||||
|
||||
//
|
||||
// read and store LeaderProcess configuration
|
||||
//
|
||||
|
||||
pBox->leaders = (LINGER_LEADER**)HeapAlloc(
|
||||
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
|
||||
sizeof(LINGER_LEADER *) * MAX_LINGER_LEADER_COUNT);
|
||||
|
||||
while (1) {
|
||||
|
||||
rc = SbieApi_QueryConfAsIs(
|
||||
NULL, L"LeaderProcess", pBox->leader_count,
|
||||
image, sizeof(WCHAR) * 120);
|
||||
if (rc != 0)
|
||||
break;
|
||||
|
||||
Add_LL_Entry(pBox->leaders, &pBox->leader_count, image);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BoxManager::CheckLinger(BOX_INSTANCE* pBox, ULONG SessionId)
|
||||
{
|
||||
// ULONG i, j;
|
||||
ULONG j;
|
||||
WCHAR image[128];
|
||||
ULONG cur_session_id;
|
||||
|
||||
{
|
||||
BOOLEAN any_leaders_local = FALSE;
|
||||
BOOLEAN terminate_and_stop = TRUE;
|
||||
|
||||
//
|
||||
// wait for the process exit event (my_event)
|
||||
//
|
||||
|
||||
// WaitForSingleObject(heventRpcSs, INFINITE);
|
||||
// EnterCriticalSection(&ProcessCritSec);
|
||||
|
||||
// SbieApi_EnumProcessEx(NULL, FALSE, -1, NULL, &process_count); // query count
|
||||
// process_count += 128;
|
||||
|
||||
// ULONG* pids = HeapAlloc(
|
||||
// GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(ULONG) * (process_count + 1)); // allocate oen more for the -1 marker
|
||||
// SbieApi_EnumProcessEx(NULL, FALSE, -1, pids, &process_count); // query pids
|
||||
// pids[process_count] = -1; // set the end marker
|
||||
|
||||
//
|
||||
// query running processes
|
||||
//
|
||||
|
||||
map_iter_t iter = map_iter();
|
||||
while (map_next(&pBox->process_map, &iter)) {
|
||||
BOXED_PROCESS* pProcess = (BOXED_PROCESS*)iter.value;
|
||||
// for (i = 0; i < process_count; ++i) {
|
||||
|
||||
//
|
||||
// if the process in question was started by Start.exe,
|
||||
// then we do not treat the process as lingering. except:
|
||||
//
|
||||
// - if the process is running as LocalSystem, it was probably
|
||||
// spawned using Start.exe by SbieSvc::ServiceServer.
|
||||
//
|
||||
// - if the process is SandboxieCrypto, which can get invoked
|
||||
// by Start.exe in some cases
|
||||
//
|
||||
|
||||
BOOLEAN excluded_from_linger = FALSE;
|
||||
BOOLEAN is_local_system_sid = FALSE;
|
||||
|
||||
//pids_i = (HANDLE)(ULONG_PTR)pids[i];
|
||||
HANDLE pids_i = (HANDLE)(ULONG_PTR)pProcess->ProcessId;
|
||||
image[0] = L'\0';
|
||||
|
||||
if (0 == SbieApi_QueryProcess(pids_i, NULL, image, NULL, &cur_session_id)
|
||||
&& _wcsicmp(image, _SandboxieCrypto) != 0) {
|
||||
|
||||
//
|
||||
// check if this is a local system process
|
||||
//
|
||||
|
||||
HANDLE ProcessHandle = SbieDll_OpenProcess(PROCESS_QUERY_INFORMATION, pids_i);
|
||||
if (ProcessHandle) {
|
||||
if (SbieDll_CheckProcessLocalSystem(ProcessHandle))
|
||||
is_local_system_sid = TRUE;
|
||||
CloseHandle(ProcessHandle);
|
||||
}
|
||||
|
||||
if (!is_local_system_sid) {
|
||||
|
||||
//
|
||||
// then check if the process was started explicitly
|
||||
// (via forced mechanism or as a child of start.exe)
|
||||
// and then don't terminate it as a linger
|
||||
//
|
||||
// (note that sevice processes running as local system
|
||||
// are also children of start.exe, but in that case,
|
||||
// is_local_system_sid would be TRUE and we would not
|
||||
// reach this point.)
|
||||
//
|
||||
// fix-me: services are no longer started by default as system
|
||||
//
|
||||
|
||||
ULONG64 ProcessFlags =
|
||||
SbieApi_QueryProcessInfo(pids_i, 0);
|
||||
|
||||
if (ProcessFlags & (SBIE_FLAG_FORCED_PROCESS |
|
||||
SBIE_FLAG_PARENT_WAS_START_EXE |
|
||||
SBIE_FLAG_PROCESS_IS_START_EXE )) {
|
||||
|
||||
excluded_from_linger = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ignore processes fron other sessions
|
||||
//
|
||||
|
||||
if (cur_session_id != SessionId)
|
||||
continue;
|
||||
|
||||
//
|
||||
// ignore rpcss process
|
||||
//
|
||||
|
||||
if (_wcsicmp(image, _SandboxieRpcSs) == 0)
|
||||
continue;
|
||||
|
||||
//
|
||||
// find a leader process
|
||||
//
|
||||
|
||||
for (j = 0; j < pBox->leader_count; ++j) {
|
||||
if (_wcsicmp(pBox->leaders[j]->image, image) == 0) {
|
||||
any_leaders_local = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// for each process we find, check if the image appears on
|
||||
// the linger list. if so, we update the last known pid
|
||||
// for that linger. but if that process was already active
|
||||
// before RpcSs started, then don't kill any lingers
|
||||
//
|
||||
// alternatively, if the process is not on the linger list,
|
||||
// then we won't be killing any of the LingerProcess yet
|
||||
//
|
||||
|
||||
for (j = 0; j < pBox->linger_count; ++j) {
|
||||
if (_wcsicmp(pBox->lingers[j]->image, image) == 0) {
|
||||
pBox->lingers[j]->curr_pid = pids_i;
|
||||
if (excluded_from_linger)
|
||||
pBox->lingers[j]->orig_pid = pids_i;
|
||||
if (pids_i == pBox->lingers[j]->orig_pid)
|
||||
terminate_and_stop = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == pBox->linger_count) {
|
||||
|
||||
//
|
||||
// we found an active process that is not a linger process,
|
||||
// so reset the flag to kill lingers
|
||||
//
|
||||
|
||||
terminate_and_stop = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// if leader processes ended (i.e. after being active for some time)
|
||||
// then kill all processes
|
||||
//
|
||||
|
||||
if (pBox->any_leaders && (! any_leaders_local)) {
|
||||
|
||||
terminate_and_stop = TRUE;
|
||||
goto do_kill_all;
|
||||
|
||||
} else
|
||||
pBox->any_leaders = any_leaders_local;
|
||||
|
||||
//
|
||||
// don't terminate if a lingering process has an open window
|
||||
//
|
||||
|
||||
/*if (terminate_and_stop) {
|
||||
|
||||
//
|
||||
// if a process in the PID list has a window LingerEnumWindowsProc will return FALSE
|
||||
// what causes the enumeration to abort and EnumWindows to return FALSE as well
|
||||
//
|
||||
|
||||
BOOL ret = EnumWindows(LingerEnumWindowsProc, (LPARAM)pids);
|
||||
if (ret == FALSE)
|
||||
terminate_and_stop = FALSE;
|
||||
}*/
|
||||
|
||||
//
|
||||
// don't terminate if a lingering process has just started recently
|
||||
//
|
||||
|
||||
/*if (terminate_and_stop) {
|
||||
for (i = 0; i < process_count; ++i) {
|
||||
HANDLE hProcess = NULL;
|
||||
ULONG64 ProcessFlags = SbieApi_QueryProcessInfo(
|
||||
pids_i, 0);
|
||||
if (! (ProcessFlags & SBIE_FLAG_IMAGE_FROM_SBIE_DIR)) {
|
||||
hProcess = OpenProcess(
|
||||
PROCESS_QUERY_INFORMATION, FALSE, (DWORD)(UINT_PTR)pids_i);
|
||||
}
|
||||
if (hProcess) {
|
||||
FILETIME time, time1, time2, time3;
|
||||
BOOL ok = GetProcessTimes(
|
||||
hProcess, &time, &time1, &time2, &time3);
|
||||
if (ok) {
|
||||
LARGE_INTEGER liProcess, liCurrent;
|
||||
__int64 diff;
|
||||
liProcess.LowPart = time.dwLowDateTime;
|
||||
liProcess.HighPart = time.dwHighDateTime;
|
||||
GetSystemTimeAsFileTime(&time);
|
||||
liCurrent.LowPart = time.dwLowDateTime;
|
||||
liCurrent.HighPart = time.dwHighDateTime;
|
||||
diff = liCurrent.QuadPart - liProcess.QuadPart;
|
||||
if (diff < SECONDS(5))
|
||||
terminate_and_stop = FALSE;
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
if (! terminate_and_stop)
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
//
|
||||
// kill all programs and quit
|
||||
//
|
||||
|
||||
// LeaveCriticalSection(&ProcessCritSec);
|
||||
do_kill_all:
|
||||
|
||||
// HeapFree(GetProcessHeap(), 0, pids);
|
||||
|
||||
if (terminate_and_stop) {
|
||||
BOOLEAN TerminateJob = FALSE; // todo
|
||||
extern ProcessServer* pProcessServer;
|
||||
pProcessServer->KillAllHelper(pBox->boxname, SessionId, TerminateJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright 2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Box Manager
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef _MY_BOXMANAGER_H
|
||||
#define _MY_BOXMANAGER_H
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include "common/win32_ntddk.h"
|
||||
#include "common/list.h"
|
||||
#include "common/map.h"
|
||||
#include "common/pool.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
struct BOX_INSTANCE;
|
||||
struct BOXED_PROCESS;
|
||||
|
||||
class BoxManager
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
static BoxManager *GetInstance();
|
||||
|
||||
void LoadProcesses();
|
||||
|
||||
bool ProcessCreated(ULONG ProcessId, const WCHAR* boxname, const WCHAR* reg_root, ULONG session_id);
|
||||
|
||||
void BoxOpened(const WCHAR* reg_root, ULONG session_id);
|
||||
|
||||
void BoxClosed(const WCHAR* reg_root, ULONG session_id);
|
||||
|
||||
protected:
|
||||
friend VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);
|
||||
|
||||
BoxManager();
|
||||
|
||||
#if 0
|
||||
void InitLinger(BOX_INSTANCE* pBox);
|
||||
void CheckLinger(BOX_INSTANCE* pBox, ULONG SessionId);
|
||||
#endif
|
||||
|
||||
CRITICAL_SECTION m_CritSec;
|
||||
|
||||
std::map<std::wstring, BOX_INSTANCE*> m_BoxMap;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _MY_BOXMANAGER_H */
|
|
@ -35,6 +35,7 @@
|
|||
#include "core/dll/sbiedll.h"
|
||||
#include "core/drv/api_defs.h"
|
||||
#include "sbieiniserver.h"
|
||||
#include "BoxManager.h"
|
||||
#include "MountManager.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -613,6 +614,12 @@ void DriverAssist::HiveMounted(void *_msg)
|
|||
goto finish;
|
||||
}
|
||||
|
||||
//
|
||||
// notify the manager that this boxed has started
|
||||
//
|
||||
|
||||
//BoxManager::GetInstance()->BoxOpened(reg_root_path, msg->session_id);
|
||||
|
||||
//
|
||||
// lock box root if present
|
||||
//
|
||||
|
@ -755,6 +762,12 @@ void DriverAssist::UnmountHive(void *_msg)
|
|||
|
||||
if (rc == 0) {
|
||||
|
||||
//
|
||||
// notify the manager that this boxed is finished
|
||||
//
|
||||
|
||||
//BoxManager::GetInstance()->BoxClosed(root_path, msg->session_id);
|
||||
|
||||
//
|
||||
// unmount box container if present
|
||||
//
|
||||
|
|
|
@ -1278,6 +1278,7 @@ bool GuiServer::GetWindowStationAndDesktopName(WCHAR *out_name)
|
|||
// create window station object, then switch to this window station
|
||||
// to create the desktop object within this window station.
|
||||
// WRITE_OWNER access is needed in order to adjust integrity levels
|
||||
// administrative privileges are needed to be able to specify a name
|
||||
//
|
||||
|
||||
wsprintf(_CombinedName, L"%s_WinSta_%d", SANDBOXIE, GetTickCount());
|
||||
|
@ -1449,6 +1450,83 @@ finish:
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// SetSecurity
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
BOOL SetSecurity(HANDLE handle, PSID pSid, ULONG Access)
|
||||
{
|
||||
long lRc;
|
||||
static SECURITY_INFORMATION struSecInfo;
|
||||
PSECURITY_DESCRIPTOR pSecDesc;
|
||||
PACL pOldDACL = NULL, pNewDACL = NULL;
|
||||
EXPLICIT_ACCESS ea;
|
||||
|
||||
lRc = GetSecurityInfo(handle, SE_WINDOW_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSecDesc);
|
||||
|
||||
if(lRc != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
//PSID pSid;
|
||||
//ConvertStringSidToSid(L"S-1-5-100-714847823-3683748338-340537075-1126068394-222809190", &pSid);
|
||||
|
||||
LPWSTR pStr;
|
||||
ConvertSidToStringSid(pSid, &pStr);
|
||||
|
||||
memset(&ea, 0, sizeof(EXPLICIT_ACCESS));
|
||||
ea.grfAccessPermissions = Access;
|
||||
ea.grfAccessMode = GRANT_ACCESS;
|
||||
ea.grfInheritance = NO_INHERITANCE;
|
||||
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
|
||||
ea.Trustee.ptstrName = (LPTSTR) pSid;
|
||||
|
||||
lRc = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
|
||||
if (ERROR_SUCCESS != lRc)
|
||||
goto Cleanup;
|
||||
|
||||
//
|
||||
// on Windows Vista, we set the process token to the untrusted integrity
|
||||
// level, so we need to adjust the window station and desktop objects to
|
||||
// allow access from processes at untrusted integrity. the first step
|
||||
// is to create an untrusted integrity sacl. note that the utility
|
||||
// ConvertStringSecurityDescriptorToSecurityDescriptor only supports
|
||||
// low integrity, so we have to manually adjust the sacl to untrusted
|
||||
//
|
||||
|
||||
PACL sacl = NULL;
|
||||
PSECURITY_DESCRIPTOR label_sd = NULL;
|
||||
if (ConvertStringSecurityDescriptorToSecurityDescriptor(
|
||||
L"S:(ML;;NW;;;LW)", SDDL_REVISION_1, &label_sd, NULL)) {
|
||||
|
||||
ULONG_PTR sacl_offset =
|
||||
(ULONG_PTR)((SECURITY_DESCRIPTOR_RELATIVE *)label_sd)->Sacl;
|
||||
ULONG *sacl_ulongs = (ULONG *)((ULONG_PTR)label_sd + sacl_offset);
|
||||
sacl_ulongs[6] = 0; // change "low" to "untrusted" level
|
||||
|
||||
BOOL sacl_present, sacl_defaulted;
|
||||
if (! GetSecurityDescriptorSacl(
|
||||
label_sd, &sacl_present, &sacl, &sacl_defaulted))
|
||||
sacl = NULL;
|
||||
}
|
||||
|
||||
lRc = SetSecurityInfo(handle, SE_WINDOW_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, sacl);
|
||||
|
||||
Cleanup:
|
||||
if(pSecDesc != NULL)
|
||||
LocalFree((HLOCAL) pSecDesc);
|
||||
|
||||
if(pNewDACL != NULL)
|
||||
LocalFree((HLOCAL) pNewDACL);
|
||||
|
||||
if(lRc != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// GetWindowStationSlave
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1458,9 +1536,14 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
|||
{
|
||||
ULONG errlvl;
|
||||
ULONG status;
|
||||
WCHAR boxname[BOXNAME_COUNT];
|
||||
ULONG session_id;
|
||||
HWINSTA local_winsta = NULL;
|
||||
HDESK local_desktop = NULL;
|
||||
BOOLEAN close_desktop = FALSE;
|
||||
HANDLE hProcess = NULL;
|
||||
|
||||
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION
|
||||
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | TOKEN_QUERY
|
||||
| PROCESS_DUP_HANDLE, FALSE, args->pid);
|
||||
if (! hProcess) {
|
||||
status = GetLastError();
|
||||
|
@ -1469,7 +1552,7 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
|||
}
|
||||
|
||||
status = SbieApi_QueryProcess((HANDLE)(ULONG_PTR)args->pid,
|
||||
NULL, NULL, NULL, &session_id);
|
||||
boxname, NULL, NULL, &session_id);
|
||||
if (status != 0 || session_id != m_SessionId) {
|
||||
|
||||
if (status == 0)
|
||||
|
@ -1497,8 +1580,25 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
|||
//
|
||||
//
|
||||
|
||||
HWINSTA local_winsta = GetProcessWindowStation();
|
||||
HDESK local_desktop = GetThreadDesktop(GetCurrentThreadId());
|
||||
local_winsta = GetProcessWindowStation();
|
||||
|
||||
WCHAR deskname[128] = { 0 };
|
||||
/*SbieApi_QueryConfAsIs(boxname, L"SandboxDesktopName", 0, deskname, sizeof(deskname));
|
||||
if(*value)
|
||||
local_desktop = OpenDesktop(value, 0, FALSE, GENERIC_ALL);
|
||||
else*/
|
||||
if (SbieApi_QueryConfBool(boxname, L"UseSandboxDesktop", FALSE)) {
|
||||
|
||||
wsprintf(deskname, L"%s_%s_Session_%d_Desktop", //_%08X",
|
||||
SANDBOXIE, boxname, m_SessionId); //GetTickCount());
|
||||
|
||||
local_desktop = OpenDesktop(deskname, 0, FALSE, GENERIC_ALL);
|
||||
if (!local_desktop)
|
||||
local_desktop = CreateDesktop(deskname, NULL, NULL, 0, GENERIC_ALL, NULL);
|
||||
|
||||
close_desktop = TRUE;
|
||||
} else
|
||||
local_desktop = GetThreadDesktop(GetCurrentThreadId());
|
||||
|
||||
if ((! local_winsta) || (! local_desktop)) {
|
||||
status = -1;
|
||||
|
@ -1523,6 +1623,35 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
|||
_WinStaAccess |= WINSTA_WRITEATTRIBUTES;
|
||||
}
|
||||
|
||||
if (SbieApi_QueryConfBool(boxname, L"OpenWndStation", FALSE))
|
||||
{
|
||||
UCHAR UserBuff[64];
|
||||
PTOKEN_USER pUser = (PTOKEN_USER)UserBuff;
|
||||
|
||||
HANDLE hToken = NULL;
|
||||
if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
|
||||
{
|
||||
DWORD len;
|
||||
GetTokenInformation(hToken, TokenUser, pUser, sizeof(UserBuff), &len);
|
||||
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
|
||||
SetSecurity(local_winsta, pUser->User.Sid, _WinStaAccess | WINSTA_CREATEDESKTOP);
|
||||
|
||||
ULONG _DeskAccess = DESKTOP_READOBJECTS
|
||||
| DESKTOP_CREATEWINDOW
|
||||
| DESKTOP_CREATEMENU
|
||||
// | DESKTOP_HOOKCONTROL
|
||||
// | DESKTOP_JOURNALRECORD
|
||||
// | DESKTOP_JOURNALPLAYBACK
|
||||
| DESKTOP_ENUMERATE
|
||||
| DESKTOP_WRITEOBJECTS
|
||||
// | DESKTOP_SWITCHDESKTOP
|
||||
;
|
||||
SetSecurity(local_desktop, pUser->User.Sid, _DeskAccess);
|
||||
}
|
||||
|
||||
if (! DuplicateHandle(NtCurrentProcess(), local_winsta,
|
||||
hProcess, (HANDLE *)&rpl->hwinsta,
|
||||
_WinStaAccess, FALSE, 0)) {
|
||||
|
@ -1538,7 +1667,7 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
|||
errlvl = 0x76;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
//
|
||||
|
@ -1568,6 +1697,9 @@ finish:
|
|||
if (hProcess)
|
||||
CloseHandle(hProcess);
|
||||
|
||||
if (close_desktop && local_desktop)
|
||||
CloseDesktop(local_desktop);
|
||||
|
||||
if (errlvl) {
|
||||
ReportError2336(-1, errlvl, status);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
|
|
@ -411,6 +411,7 @@
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BoxManager.cpp" />
|
||||
<ClCompile Include="comserver.cpp" />
|
||||
<ClCompile Include="comserver2.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
|
||||
|
@ -584,6 +585,7 @@
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BoxManager.h" />
|
||||
<ClInclude Include="comserver.h" />
|
||||
<ClInclude Include="comwire.h" />
|
||||
<ClInclude Include="DriverAssist.h" />
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
<ClCompile Include="DriverAssistSid.cpp">
|
||||
<Filter>DriverAssist</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BoxManager.cpp" />
|
||||
<ClCompile Include="MountManager.cpp">
|
||||
<Filter>MountManager</Filter>
|
||||
</ClCompile>
|
||||
|
@ -153,6 +154,7 @@
|
|||
<ClInclude Include="..\..\common\ini.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BoxManager.h" />
|
||||
<ClInclude Include="MountManagerWire.h">
|
||||
<Filter>MountManager</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include <Sddl.h>
|
||||
#include "BoxManager.h"
|
||||
#include "MountManager.h"
|
||||
#include "DriverAssist.h"
|
||||
#include "PipeServer.h"
|
||||
|
|
|
@ -46,7 +46,8 @@ typedef enum _COMMAND {
|
|||
CMD_SCANDLL,
|
||||
CMD_SCANDLL_SILENT,
|
||||
CMD_MESSAGE,
|
||||
CMD_FIXDACLS
|
||||
CMD_FIXDACLS,
|
||||
CMD_SWITCHDESK
|
||||
} COMMAND;
|
||||
|
||||
typedef enum _OPTIONS {
|
||||
|
@ -231,6 +232,10 @@ BOOL Parse_Command_Line(
|
|||
*Command = CMD_FIXDACLS;
|
||||
num_args_needed = 0;
|
||||
|
||||
} else if (_wcsicmp(args[1], L"switchdesk") == 0) {
|
||||
*Command = CMD_SWITCHDESK;
|
||||
num_args_needed = 1;
|
||||
|
||||
} else {
|
||||
*Command = CMD_ERROR;
|
||||
MessageBox(NULL, L"Invalid command", L"KmdUtil",
|
||||
|
@ -741,6 +746,26 @@ BOOL Kmd_Show_Message(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Kmd_Show_Message
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
BOOL Kmd_SwitchDesk(
|
||||
const wchar_t *name)
|
||||
{
|
||||
HDESK hDesktop = OpenDesktop(name, 0, FALSE, GENERIC_ALL);
|
||||
if (hDesktop == NULL) {
|
||||
//DWORD err = GetLastError();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL ok = SwitchDesktop(hDesktop);
|
||||
|
||||
CloseDesktop(hDesktop);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WinMain
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -778,6 +803,11 @@ int __stdcall WinMain(
|
|||
goto finish;
|
||||
}
|
||||
|
||||
if (Command == CMD_SWITCHDESK) {
|
||||
ok = Kmd_SwitchDesk(Driver_Name);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
ScMgr = OpenSCManager(
|
||||
NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
|
||||
|
||||
|
|
Loading…
Reference in New Issue