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
|
// 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.
|
// 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
|
// Note: the infinite recursion issue has been resolved int 5.43
|
||||||
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|
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)) {
|
|| (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;
|
SetSecurityInfo = __sys_SetSecurityInfo;
|
||||||
GetSecurityInfo = __sys_GetSecurityInfo;
|
GetSecurityInfo = __sys_GetSecurityInfo;
|
||||||
SBIEDLL_HOOK(AdvApi_, SetSecurityInfo);
|
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);
|
#define GETPROC2(x,s) __sys_Ntmarta_##x##s = (P_##x) Ldr_GetProcAddrNew(DllName_ntmarta, L#x L#s,#x #s);
|
||||||
|
|
||||||
GETPROC2(GetSecurityInfo, );
|
GETPROC2(GetSecurityInfo, );
|
||||||
if (Config_GetSettingsForImageName_bool(L"UseSbieDeskHack", TRUE)
|
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)) {
|
|| (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;
|
GetSecurityInfo = __sys_Ntmarta_GetSecurityInfo;
|
||||||
if (GetSecurityInfo)
|
if (GetSecurityInfo)
|
||||||
|
|
|
@ -1152,11 +1152,17 @@ _FX NTSTATUS File_NtFsControlFile(
|
||||||
handle = File_GetProxyPipe(FileHandle, NULL);
|
handle = File_GetProxyPipe(FileHandle, NULL);
|
||||||
if (! handle) {
|
if (! handle) {
|
||||||
|
|
||||||
|
status = STATUS_BAD_INITIAL_PC;
|
||||||
|
|
||||||
if (IoControlCode == FSCTL_SET_REPARSE_POINT) {
|
if (IoControlCode == FSCTL_SET_REPARSE_POINT) {
|
||||||
|
|
||||||
status = File_SetReparsePoint(
|
BOOLEAN BoxReparsTarget = SbieApi_QueryConfBool(NULL, L"BoxReparsTarget", FALSE);
|
||||||
FileHandle, InputBuffer, InputBufferLength);
|
if(BoxReparsTarget) {
|
||||||
SetLastError(LastError);
|
|
||||||
|
status = File_SetReparsePoint(
|
||||||
|
FileHandle, InputBuffer, InputBufferLength);
|
||||||
|
SetLastError(LastError);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (IoControlCode == FSCTL_PIPE_WAIT) {
|
} else if (IoControlCode == FSCTL_PIPE_WAIT) {
|
||||||
|
|
||||||
|
@ -1172,8 +1178,7 @@ _FX NTSTATUS File_NtFsControlFile(
|
||||||
else
|
else
|
||||||
status = STATUS_ACCESS_DENIED;
|
status = STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
} else
|
}
|
||||||
status = STATUS_BAD_INITIAL_PC;
|
|
||||||
|
|
||||||
if (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___(ClipCursor);
|
||||||
GUI_IMPORT___(GetClipCursor);
|
GUI_IMPORT___(GetClipCursor);
|
||||||
GUI_IMPORT___(GetCursorPos);
|
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___(SetTimer);
|
||||||
GUI_IMPORT___(MsgWaitForMultipleObjects);
|
GUI_IMPORT___(MsgWaitForMultipleObjects);
|
||||||
|
@ -925,6 +936,24 @@ _FX BOOLEAN Gui_ConnectToWindowStationAndDesktop(HMODULE User32)
|
||||||
return FALSE;
|
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)
|
// the first win32k service call (i.e. service number >= 0x1000)
|
||||||
// triggers "thread GUI conversion". the kernel system service
|
// triggers "thread GUI conversion". the kernel system service
|
||||||
|
|
|
@ -102,8 +102,8 @@ typedef HWND(*P_SetActiveWindow)(HWND hWnd);
|
||||||
|
|
||||||
typedef UINT_PTR (*P_SetTimer)(
|
typedef UINT_PTR (*P_SetTimer)(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
UINT_PTR nIDEvent,
|
UINT_PTR nIDEvent,
|
||||||
UINT uElapse,
|
UINT uElapse,
|
||||||
TIMERPROC lpTimerFunc
|
TIMERPROC lpTimerFunc
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ GUI_SYS_VAR_2(SendNotifyMessage)
|
||||||
GUI_SYS_VAR_2(PostMessage)
|
GUI_SYS_VAR_2(PostMessage)
|
||||||
GUI_SYS_VAR_2(PostThreadMessage)
|
GUI_SYS_VAR_2(PostThreadMessage)
|
||||||
GUI_SYS_VAR_2(DispatchMessage)
|
GUI_SYS_VAR_2(DispatchMessage)
|
||||||
|
|
||||||
GUI_SYS_VAR(SetTimer)
|
GUI_SYS_VAR(SetTimer)
|
||||||
|
|
||||||
GUI_SYS_VAR(MapWindowPoints)
|
GUI_SYS_VAR(MapWindowPoints)
|
||||||
|
|
|
@ -234,6 +234,9 @@ _FX BOOLEAN Gui_InitEnum(HMODULE module)
|
||||||
// hook desktop APIs
|
// hook desktop APIs
|
||||||
//
|
//
|
||||||
|
|
||||||
|
if (SbieApi_QueryConfBool(NULL, L"OpenWndStation", FALSE))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
SBIEDLL_HOOK_GUI(EnumDesktopsW);
|
SBIEDLL_HOOK_GUI(EnumDesktopsW);
|
||||||
SBIEDLL_HOOK_GUI(EnumDesktopsA);
|
SBIEDLL_HOOK_GUI(EnumDesktopsA);
|
||||||
SBIEDLL_HOOK_GUI(OpenDesktopW);
|
SBIEDLL_HOOK_GUI(OpenDesktopW);
|
||||||
|
|
|
@ -285,7 +285,7 @@ _FX BOOLEAN Gui_InitMisc(HMODULE module)
|
||||||
__sys_GetThreadDpiAwarenessContext = (P_GetThreadDpiAwarenessContext)
|
__sys_GetThreadDpiAwarenessContext = (P_GetThreadDpiAwarenessContext)
|
||||||
Ldr_GetProcAddrNew(DllName_user32, L"GetThreadDpiAwarenessContext","GetThreadDpiAwarenessContext");
|
Ldr_GetProcAddrNew(DllName_user32, L"GetThreadDpiAwarenessContext","GetThreadDpiAwarenessContext");
|
||||||
|
|
||||||
|
HMODULE current = module;
|
||||||
if (SbieApi_QueryConfBool(NULL, L"BlockInterferePower", FALSE)) {
|
if (SbieApi_QueryConfBool(NULL, L"BlockInterferePower", FALSE)) {
|
||||||
|
|
||||||
SBIEDLL_HOOK_GUI(ShutdownBlockReasonCreate);
|
SBIEDLL_HOOK_GUI(ShutdownBlockReasonCreate);
|
||||||
|
@ -1703,3 +1703,45 @@ _FX void Gui_SwitchToThisWindow(HWND hWnd, BOOL fAlt)
|
||||||
return;
|
return;
|
||||||
__sys_SwitchToThisWindow(hWnd, fAlt);
|
__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
|
// 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())
|
Secure_FakeAdmin = Config_GetSettingsForImageName_bool(L"FakeAdminRights", Secure_IsBuiltInAdmin());
|
||||||
&& (_wcsicmp(Dll_ImageName, L"msedge.exe") != 0); // never for msedge.exe
|
|
||||||
|
|
||||||
|
|
||||||
void* NtAccessCheckByType = GetProcAddress(Dll_Ntdll, "NtAccessCheckByType");
|
void* NtAccessCheckByType = GetProcAddress(Dll_Ntdll, "NtAccessCheckByType");
|
||||||
|
|
|
@ -184,7 +184,8 @@ _FX BOX *Process_GetForcedStartBox(
|
||||||
if (! ProcessObject)
|
if (! ProcessObject)
|
||||||
return NULL;
|
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_19) == 0 || // Local Service
|
||||||
_wcsicmp(pSidString, Driver_S_1_5_20) == 0) // Network Service
|
_wcsicmp(pSidString, Driver_S_1_5_20) == 0) // Network Service
|
||||||
&& (! Process_IsDcomLaunchParent(ParentId)) ){
|
&& (! Process_IsDcomLaunchParent(ParentId)) ){
|
||||||
|
@ -274,7 +275,8 @@ _FX BOX *Process_GetForcedStartBox(
|
||||||
&boxes, DocArg, force_alert, &alert);
|
&boxes, DocArg, force_alert, &alert);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (box && Process_IsImmersiveProcess(
|
if (box && (! Conf_Get_Boolean(NULL, L"AllowForceImmersive", 0, FALSE)) &&
|
||||||
|
Process_IsImmersiveProcess(
|
||||||
ProcessObject, ParentId, SessionId)) {
|
ProcessObject, ParentId, SessionId)) {
|
||||||
box = NULL;
|
box = NULL;
|
||||||
alert = 1;
|
alert = 1;
|
||||||
|
|
|
@ -34,6 +34,60 @@
|
||||||
#include "dyn_data.h"
|
#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
|
// Functions
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -78,7 +132,7 @@ static BOOLEAN Token_AssignPrimary(
|
||||||
|
|
||||||
static void *Token_DuplicateToken(void *TokenObject, PROCESS *proc);
|
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
|
// 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 {
|
else {
|
||||||
|
|
||||||
|
@ -1369,6 +1432,7 @@ _FX void *Token_RestrictHelper3(
|
||||||
BOOLEAN AnonymousLogonSidAlreadyInGroups = FALSE;
|
BOOLEAN AnonymousLogonSidAlreadyInGroups = FALSE;
|
||||||
|
|
||||||
BOOLEAN KeepUserGroup = Conf_Get_Boolean(proc->box->name, L"KeepUserGroup", 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);
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|
||||||
|
@ -1377,6 +1441,9 @@ _FX void *Token_RestrictHelper3(
|
||||||
if (Groups->Groups[i].Attributes & SE_GROUP_INTEGRITY)
|
if (Groups->Groups[i].Attributes & SE_GROUP_INTEGRITY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (OpenWndStation && (Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (RtlEqualSid(Groups->Groups[i].Sid, UserSid)) {
|
if (RtlEqualSid(Groups->Groups[i].Sid, UserSid)) {
|
||||||
if (KeepUserGroup)
|
if (KeepUserGroup)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1704,6 +1771,7 @@ _FX BOOLEAN Token_ReplacePrimary(PROCESS *proc)
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
// OpenToken BEGIN
|
// OpenToken BEGIN
|
||||||
if (!Conf_Get_Boolean(proc->box->name, L"CreateToken", 0, FALSE)
|
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"UnrestrictedToken", 0, FALSE)
|
||||||
&& Conf_Get_Boolean(proc->box->name, L"AnonymousLogon", 0, TRUE))
|
&& Conf_Get_Boolean(proc->box->name, L"AnonymousLogon", 0, TRUE))
|
||||||
// OpenToken END
|
// 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;
|
HANDLE TokenHandle = NULL;
|
||||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||||
|
@ -2141,15 +2209,19 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
||||||
PTOKEN_SOURCE LocalSource = NULL;
|
PTOKEN_SOURCE LocalSource = NULL;
|
||||||
|
|
||||||
PTOKEN_DEFAULT_DACL NewDefaultDacl = NULL;
|
PTOKEN_DEFAULT_DACL NewDefaultDacl = NULL;
|
||||||
PTOKEN_OWNER NewOwner = NULL;
|
|
||||||
ULONG DefaultDacl_Length = 0;
|
ULONG DefaultDacl_Length = 0;
|
||||||
PACL NewDacl = NULL;
|
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;
|
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))
|
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);
|
MandatoryPolicy = (PTOKEN_MANDATORY_POLICY)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_MANDATORY_POLICY), tzuk);
|
||||||
if (MandatoryPolicy) MandatoryPolicy->Policy = TOKEN_MANDATORY_POLICY_NO_WRITE_UP;
|
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
|
// Change the SID
|
||||||
//
|
//
|
||||||
|
@ -2181,37 +2305,28 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
||||||
|
|
||||||
if (proc->SandboxieLogonSid)
|
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));
|
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(
|
status = SbieCreateToken(
|
||||||
&TokenHandle,
|
&TokenHandle,
|
||||||
TOKEN_ALL_ACCESS,
|
TOKEN_ALL_ACCESS,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
LocalStatistics->TokenType,
|
TokenType,
|
||||||
&LocalStatistics->AuthenticationId,
|
&AuthenticationId,
|
||||||
&LocalStatistics->ExpirationTime,
|
&ExpirationTime,
|
||||||
LocalUser,
|
LocalUser,
|
||||||
LocalGroups,
|
LocalGroups,
|
||||||
LocalPrivileges,
|
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 = NewDacl = (PACL)((ULONG_PTR)NewDefaultDacl + sizeof(TOKEN_DEFAULT_DACL));
|
||||||
NewDefaultDacl->DefaultDacl->AclSize += 128;
|
NewDefaultDacl->DefaultDacl->AclSize += 128;
|
||||||
|
|
||||||
NewOwner = (PTOKEN_OWNER)ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_OWNER), tzuk);
|
ExFreePool((PVOID)LocalOwner);
|
||||||
NewOwner->Owner = LocalUser->User.Sid;
|
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(
|
status = SbieCreateToken(
|
||||||
&TokenHandle,
|
&TokenHandle,
|
||||||
TOKEN_ALL_ACCESS,
|
TOKEN_ALL_ACCESS,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
LocalStatistics->TokenType,
|
TokenType,
|
||||||
&LocalStatistics->AuthenticationId,
|
&AuthenticationId,
|
||||||
&LocalStatistics->ExpirationTime,
|
&ExpirationTime,
|
||||||
LocalUser,
|
LocalUser,
|
||||||
LocalGroups,
|
LocalGroups,
|
||||||
LocalPrivileges,
|
LocalPrivileges,
|
||||||
|
@ -2269,7 +2385,7 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
||||||
0, //DeviceGroups,
|
0, //DeviceGroups,
|
||||||
MandatoryPolicy,
|
MandatoryPolicy,
|
||||||
|
|
||||||
NewOwner,
|
LocalOwner,
|
||||||
LocalPrimaryGroup,
|
LocalPrimaryGroup,
|
||||||
NewDefaultDacl,
|
NewDefaultDacl,
|
||||||
LocalSource
|
LocalSource
|
||||||
|
@ -2294,17 +2410,16 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
||||||
ULONG virtualizationAllowed = 1;
|
ULONG virtualizationAllowed = 1;
|
||||||
status = ZwSetInformationToken(TokenHandle, TokenVirtualizationAllowed, &virtualizationAllowed, sizeof(ULONG));
|
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;
|
ULONG len = 0;
|
||||||
status = ZwQueryInformationToken(OldTokenHandle, TokenSecurityAttributes, ptr, PAGE_SIZE, &len);
|
status = ZwQueryInformationToken(OldTokenHandle, TokenSecurityAttributes, ptr, PAGE_SIZE, &len);
|
||||||
if (NT_SUCCESS(status)) {
|
if (NT_SUCCESS(status)) {
|
||||||
|
@ -2320,18 +2435,12 @@ _FX void* Token_CreateNew(void* TokenObject, PROCESS* proc)
|
||||||
|
|
||||||
status = ZwSetInformationToken(TokenHandle, TokenSecurityAttributes, data, len);
|
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:
|
finish:
|
||||||
if (LocalStatistics) ExFreePool((PVOID)LocalStatistics);
|
if (LocalStatistics) ExFreePool((PVOID)LocalStatistics);
|
||||||
|
@ -2350,8 +2459,6 @@ finish:
|
||||||
if (LocalSource) ExFreePool((PVOID)LocalSource);
|
if (LocalSource) ExFreePool((PVOID)LocalSource);
|
||||||
|
|
||||||
if (NewDefaultDacl) ExFreePool((PVOID)NewDefaultDacl);
|
if (NewDefaultDacl) ExFreePool((PVOID)NewDefaultDacl);
|
||||||
if (NewOwner) ExFreePool((PVOID)NewOwner);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// get the actual token object from the handle
|
// get the actual token object from the handle
|
||||||
|
@ -2366,5 +2473,4 @@ finish:
|
||||||
NtClose(TokenHandle);
|
NtClose(TokenHandle);
|
||||||
}
|
}
|
||||||
return NewTokenObject;
|
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/dll/sbiedll.h"
|
||||||
#include "core/drv/api_defs.h"
|
#include "core/drv/api_defs.h"
|
||||||
#include "sbieiniserver.h"
|
#include "sbieiniserver.h"
|
||||||
|
#include "BoxManager.h"
|
||||||
#include "MountManager.h"
|
#include "MountManager.h"
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -613,6 +614,12 @@ void DriverAssist::HiveMounted(void *_msg)
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// notify the manager that this boxed has started
|
||||||
|
//
|
||||||
|
|
||||||
|
//BoxManager::GetInstance()->BoxOpened(reg_root_path, msg->session_id);
|
||||||
|
|
||||||
//
|
//
|
||||||
// lock box root if present
|
// lock box root if present
|
||||||
//
|
//
|
||||||
|
@ -755,6 +762,12 @@ void DriverAssist::UnmountHive(void *_msg)
|
||||||
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// notify the manager that this boxed is finished
|
||||||
|
//
|
||||||
|
|
||||||
|
//BoxManager::GetInstance()->BoxClosed(root_path, msg->session_id);
|
||||||
|
|
||||||
//
|
//
|
||||||
// unmount box container if present
|
// 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
|
// create window station object, then switch to this window station
|
||||||
// to create the desktop object within this window station.
|
// to create the desktop object within this window station.
|
||||||
// WRITE_OWNER access is needed in order to adjust integrity levels
|
// 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());
|
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
|
// GetWindowStationSlave
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -1458,9 +1536,14 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
||||||
{
|
{
|
||||||
ULONG errlvl;
|
ULONG errlvl;
|
||||||
ULONG status;
|
ULONG status;
|
||||||
|
WCHAR boxname[BOXNAME_COUNT];
|
||||||
ULONG session_id;
|
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);
|
| PROCESS_DUP_HANDLE, FALSE, args->pid);
|
||||||
if (! hProcess) {
|
if (! hProcess) {
|
||||||
status = GetLastError();
|
status = GetLastError();
|
||||||
|
@ -1469,7 +1552,7 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
status = SbieApi_QueryProcess((HANDLE)(ULONG_PTR)args->pid,
|
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 || session_id != m_SessionId) {
|
||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
|
@ -1497,8 +1580,25 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
HWINSTA local_winsta = GetProcessWindowStation();
|
local_winsta = GetProcessWindowStation();
|
||||||
HDESK local_desktop = GetThreadDesktop(GetCurrentThreadId());
|
|
||||||
|
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)) {
|
if ((! local_winsta) || (! local_desktop)) {
|
||||||
status = -1;
|
status = -1;
|
||||||
|
@ -1523,6 +1623,35 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
||||||
_WinStaAccess |= WINSTA_WRITEATTRIBUTES;
|
_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,
|
if (! DuplicateHandle(NtCurrentProcess(), local_winsta,
|
||||||
hProcess, (HANDLE *)&rpl->hwinsta,
|
hProcess, (HANDLE *)&rpl->hwinsta,
|
||||||
_WinStaAccess, FALSE, 0)) {
|
_WinStaAccess, FALSE, 0)) {
|
||||||
|
@ -1538,7 +1667,7 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
||||||
errlvl = 0x76;
|
errlvl = 0x76;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1568,6 +1697,9 @@ finish:
|
||||||
if (hProcess)
|
if (hProcess)
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
|
|
||||||
|
if (close_desktop && local_desktop)
|
||||||
|
CloseDesktop(local_desktop);
|
||||||
|
|
||||||
if (errlvl) {
|
if (errlvl) {
|
||||||
ReportError2336(-1, errlvl, status);
|
ReportError2336(-1, errlvl, status);
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
|
@ -411,6 +411,7 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64EC'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="BoxManager.cpp" />
|
||||||
<ClCompile Include="comserver.cpp" />
|
<ClCompile Include="comserver.cpp" />
|
||||||
<ClCompile Include="comserver2.cpp">
|
<ClCompile Include="comserver2.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
|
<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|ARM64EC'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="BoxManager.h" />
|
||||||
<ClInclude Include="comserver.h" />
|
<ClInclude Include="comserver.h" />
|
||||||
<ClInclude Include="comwire.h" />
|
<ClInclude Include="comwire.h" />
|
||||||
<ClInclude Include="DriverAssist.h" />
|
<ClInclude Include="DriverAssist.h" />
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
<ClCompile Include="DriverAssistSid.cpp">
|
<ClCompile Include="DriverAssistSid.cpp">
|
||||||
<Filter>DriverAssist</Filter>
|
<Filter>DriverAssist</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="BoxManager.cpp" />
|
||||||
<ClCompile Include="MountManager.cpp">
|
<ClCompile Include="MountManager.cpp">
|
||||||
<Filter>MountManager</Filter>
|
<Filter>MountManager</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -153,6 +154,7 @@
|
||||||
<ClInclude Include="..\..\common\ini.h">
|
<ClInclude Include="..\..\common\ini.h">
|
||||||
<Filter>common</Filter>
|
<Filter>common</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="BoxManager.h" />
|
||||||
<ClInclude Include="MountManagerWire.h">
|
<ClInclude Include="MountManagerWire.h">
|
||||||
<Filter>MountManager</Filter>
|
<Filter>MountManager</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include <Sddl.h>
|
#include <Sddl.h>
|
||||||
|
#include "BoxManager.h"
|
||||||
#include "MountManager.h"
|
#include "MountManager.h"
|
||||||
#include "DriverAssist.h"
|
#include "DriverAssist.h"
|
||||||
#include "PipeServer.h"
|
#include "PipeServer.h"
|
||||||
|
|
|
@ -46,7 +46,8 @@ typedef enum _COMMAND {
|
||||||
CMD_SCANDLL,
|
CMD_SCANDLL,
|
||||||
CMD_SCANDLL_SILENT,
|
CMD_SCANDLL_SILENT,
|
||||||
CMD_MESSAGE,
|
CMD_MESSAGE,
|
||||||
CMD_FIXDACLS
|
CMD_FIXDACLS,
|
||||||
|
CMD_SWITCHDESK
|
||||||
} COMMAND;
|
} COMMAND;
|
||||||
|
|
||||||
typedef enum _OPTIONS {
|
typedef enum _OPTIONS {
|
||||||
|
@ -231,6 +232,10 @@ BOOL Parse_Command_Line(
|
||||||
*Command = CMD_FIXDACLS;
|
*Command = CMD_FIXDACLS;
|
||||||
num_args_needed = 0;
|
num_args_needed = 0;
|
||||||
|
|
||||||
|
} else if (_wcsicmp(args[1], L"switchdesk") == 0) {
|
||||||
|
*Command = CMD_SWITCHDESK;
|
||||||
|
num_args_needed = 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
*Command = CMD_ERROR;
|
*Command = CMD_ERROR;
|
||||||
MessageBox(NULL, L"Invalid command", L"KmdUtil",
|
MessageBox(NULL, L"Invalid command", L"KmdUtil",
|
||||||
|
@ -741,6 +746,26 @@ BOOL Kmd_Show_Message(
|
||||||
return TRUE;
|
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
|
// WinMain
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -778,6 +803,11 @@ int __stdcall WinMain(
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Command == CMD_SWITCHDESK) {
|
||||||
|
ok = Kmd_SwitchDesk(Driver_Name);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
ScMgr = OpenSCManager(
|
ScMgr = OpenSCManager(
|
||||||
NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
|
NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue