This commit is contained in:
DavidXanatos 2024-05-10 17:50:03 +02:00
parent 965110e4b2
commit f5c5224a26
7 changed files with 221 additions and 7 deletions

View File

@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Add option to limit the memory of sandboxed process and the number of process in single sandbox through job object. (thanks Yeyixiao)
- Add ability to modified sandboxed process logic speed (reduced fixed latency, modified single-player speed, etc.) (thanks Yeyixiao)
- Added /fcp /force_children commandline option to start.exe it allows to start a program unsandboxed but have all its children sandboxed

View File

@ -28,6 +28,7 @@
#include "core/svc/SbieIniWire.h"
#include "common/my_version.h"
#include "msgs/msgs.h"
#include "core/drv/api_defs.h"
//---------------------------------------------------------------------------
@ -88,6 +89,7 @@ BOOL execute_auto_run = FALSE;
BOOL execute_open_with = FALSE;
BOOL run_elevated_2 = FALSE;
BOOL disable_force_on_this_program = FALSE;
BOOL force_children_on_this_program = FALSE;
BOOL auto_select_default_box = FALSE;
WCHAR *StartMenuSectionName = NULL;
BOOL run_silent = FALSE;
@ -716,6 +718,17 @@ BOOL Parse_Command_Line(void)
disable_force_on_this_program = TRUE;
//
// Command line switch /force_children or /fcp
//
} else if (_wcsnicmp(cmd, L"force_children", 14) == 0 ||
_wcsnicmp(cmd, L"fcp", 3) == 0) {
cmd = Eat_String(cmd);
force_children_on_this_program = TRUE;
//
// Command line switch /hide_window
//
@ -1193,7 +1206,7 @@ int Program_Start(void)
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shExecInfo.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_DOENVSUBST
| SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOZONECHECKS;
if (wait_for_process || keep_alive)
if (wait_for_process || keep_alive || force_children_on_this_program)
shExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = NULL;
@ -1337,6 +1350,8 @@ int Program_Start(void)
if (ok && (wait_for_process || keep_alive))
hNewProcess = shExecInfo.hProcess;
else if(ok && force_children_on_this_program)
pi.dwProcessId = GetProcessId(shExecInfo.hProcess);
if (! ok) {
@ -1364,9 +1379,16 @@ int Program_Start(void)
// we know for sure that SandboxieRpcSs has opened it
//
if (ok && (! disable_force_on_this_program)) {
if (ok) {
SbieDll_StartCOM(FALSE);
if (force_children_on_this_program) {
SbieApi_Call(API_FORCE_CHILDREN, 2, pi.dwProcessId, BoxName);
} else if (!disable_force_on_this_program) {
SbieDll_StartCOM(FALSE);
}
}
//
@ -1395,7 +1417,9 @@ int Program_Start(void)
}
}
} else if (GetModuleHandle(L"protect.dll")) {
}
// $Workaround$ - 3rd party fix
else if (GetModuleHandle(L"protect.dll")) {
//
// hack for FortKnox firewall -- keep Start.exe around for a few
@ -1833,8 +1857,9 @@ int __stdcall WinMainCRTStartup(
ULONG NewState = DISABLE_JUST_THIS_PROCESS;
SbieApi_DisableForceProcess(&NewState, NULL);
return die(Program_Start());
}
if (disable_force_on_this_program || force_children_on_this_program)
return die(Program_Start());
}
return die(RestartInSandbox());

View File

@ -162,6 +162,7 @@ enum {
API_PROTECT_ROOT,
API_UNPROTECT_ROOT,
API_KILL_PROCESS,
API_FORCE_CHILDREN,
API_LAST
};

View File

@ -101,9 +101,11 @@ static NTSTATUS Process_CreateUserProcess(
#ifdef USE_PROCESS_MAP
HASH_MAP Process_Map;
HASH_MAP Process_MapDfp;
HASH_MAP Process_MapFcp;
#else
LIST Process_List;
LIST Process_ListDfp;
LIST Process_ListFcp;
#endif
PERESOURCE Process_ListLock = NULL;
@ -136,9 +138,13 @@ _FX BOOLEAN Process_Init(void)
map_init(&Process_MapDfp, Driver_Pool);
map_resize(&Process_MapDfp, 128); // prepare some buckets for better performance
map_init(&Process_MapFcp, Driver_Pool);
map_resize(&Process_MapFcp, 128); // prepare some buckets for better performance
#else
List_Init(&Process_List);
List_Init(&Process_ListDfp);
List_Init(&Process_ListFcp);
#endif
if (! Mem_GetLockResource(&Process_ListLock, TRUE))
@ -1537,6 +1543,8 @@ _FX void Process_Delete(HANDLE ProcessId)
Process_DfpDelete(ProcessId);
Process_FcpDelete(ProcessId);
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);

View File

@ -447,6 +447,11 @@ void Process_DfpDelete(HANDLE ProcessId);
BOOLEAN Process_DfpCheck(HANDLE ProcessId, BOOLEAN *silent);
// Force Child Processes
VOID Process_FcpInsert(HANDLE ProcessId, const WCHAR* boxname);
void Process_FcpDelete(HANDLE ProcessId);
BOOLEAN Process_FcpCheck(HANDLE ProcessId, WCHAR* boxname);
// Enumerate or count processes in a sandbox
@ -533,9 +538,11 @@ NTSTATUS Process_Api_Kill(PROCESS *proc, ULONG64 *parms);
#ifdef USE_PROCESS_MAP
extern HASH_MAP Process_Map;
extern HASH_MAP Process_MapDfp;
extern HASH_MAP Process_MapFcp;
#else
extern LIST Process_List;
extern LIST Process_ListDfp;
extern LIST Process_ListFcp;
#endif
extern PERESOURCE Process_ListLock;

View File

@ -79,6 +79,16 @@ typedef struct _FORCE_PROCESS_2 {
} FORCE_PROCESS_2;
typedef struct _FORCE_PROCESS_3 {
#ifndef USE_PROCESS_MAP
LIST_ELEM list_elem;
#endif
HANDLE pid;
WCHAR boxname[BOXNAME_COUNT];
} FORCE_PROCESS_3;
//---------------------------------------------------------------------------
// Functions
//---------------------------------------------------------------------------
@ -274,6 +284,23 @@ _FX BOX *Process_GetForcedStartBox(
Process_DfpInsert(PROCESS_TERMINATED, ProcessId);
}
if (!box) {
WCHAR boxname[BOXNAME_COUNT];
if (Process_FcpCheck(ParentId, boxname)) {
ULONG boxname_len = (wcslen(boxname) + 1) * sizeof(WCHAR);
for (FORCE_BOX* cur_box = List_Head(&boxes); cur_box; cur_box = List_Next(cur_box)) {
if (cur_box->box->name_len == boxname_len
&& _wcsicmp(cur_box->box->name, boxname) == 0) {
box = cur_box->box;
break;
}
}
}
}
if (alert != 1)
force_alert = FALSE;
@ -794,7 +821,6 @@ _FX BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name)
_FX BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId)
{
return Process_IsProcessParent(ParentId,L"explorer.exe");
}
@ -1399,10 +1425,12 @@ _FX BOX *Process_CheckForceProcess(
return box->box;
}
//if (Process_IsWindowsExplorerParent(ParentId) && Conf_Get_Boolean(box->box->name, L"ForceExplorerChild", FALSE)) {
//if (Process_IsWindowsExplorerParent(ParentId) && Conf_Get_Boolean(box->box->name, L"ForceExplorerChild", 0, FALSE)) {
// if(_wcsicmp(name,L"Sandman.exe")!=0)
// return box->box;
//}
box = List_Next(box);
}
@ -1758,3 +1786,112 @@ _FX BOOLEAN Process_DfpCheck(HANDLE ProcessId, BOOLEAN *silent)
return found;
}
//---------------------------------------------------------------------------
// Process_FcpInsert
//---------------------------------------------------------------------------
_FX VOID Process_FcpInsert(HANDLE ProcessId, const WCHAR* boxname)
{
FORCE_PROCESS_3 *proc;
KIRQL irql;
//
// called by Session_Api_ForceChildren, process list not locked
//
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(Process_ListLock, TRUE);
Process_FcpDelete(ProcessId);
proc = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS_3));
proc->pid = ProcessId;
wmemcpy(proc->boxname, boxname, BOXNAME_COUNT);
#ifdef USE_PROCESS_MAP
map_insert(&Process_MapFcp, ProcessId, proc, 0);
#else
List_Insert_After(&Process_ListFcp, NULL, proc);
#endif
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);
}
//---------------------------------------------------------------------------
// Process_FcpDelete
//---------------------------------------------------------------------------
_FX void Process_FcpDelete(HANDLE ProcessId)
{
FORCE_PROCESS_3 *proc;
#ifdef USE_PROCESS_MAP
if(map_take(&Process_MapFcp, ProcessId, &proc, 0))
Mem_Free(proc, sizeof(FORCE_PROCESS_3));
#else
proc = List_Head(&Process_ListFcp);
while (proc) {
if (proc->pid == ProcessId) {
List_Remove(&Process_ListFcp, proc);
Mem_Free(proc, sizeof(FORCE_PROCESS_3));
return;
}
proc = List_Next(proc);
}
#endif
}
//---------------------------------------------------------------------------
// Process_FcpCheck
//---------------------------------------------------------------------------
_FX BOOLEAN Process_FcpCheck(HANDLE ProcessId, WCHAR* boxname)
{
FORCE_PROCESS_3 *proc;
KIRQL irql;
BOOLEAN found = FALSE;
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(Process_ListLock, TRUE);
#ifdef USE_PROCESS_MAP
proc = map_get(&Process_MapFcp, ProcessId);
if (proc) {
#else
proc = List_Head(&Process_ListFcp);
while (proc) {
if (proc->pid == ProcessId) {
#endif
if(boxname)
wmemcpy(boxname, proc->boxname, BOXNAME_COUNT);
found = TRUE;
#ifndef USE_PROCESS_MAP
break;
}
proc = List_Next(proc);
#endif
}
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);
return found;
}

View File

@ -104,6 +104,8 @@ static NTSTATUS Session_Api_Leader(PROCESS *proc, ULONG64 *parms);
static NTSTATUS Session_Api_DisableForce(PROCESS *proc, ULONG64 *parms);
static NTSTATUS Session_Api_ForceChildren(PROCESS *proc, ULONG64 *parms);
static NTSTATUS Session_Api_MonitorControl(PROCESS *proc, ULONG64 *parms);
//static NTSTATUS Session_Api_MonitorPut(PROCESS *proc, ULONG64 *parms);
@ -141,6 +143,7 @@ _FX BOOLEAN Session_Init(void)
Api_SetFunction(API_SESSION_LEADER, Session_Api_Leader);
Api_SetFunction(API_DISABLE_FORCE_PROCESS, Session_Api_DisableForce);
Api_SetFunction(API_FORCE_CHILDREN, Session_Api_ForceChildren);
Api_SetFunction(API_MONITOR_CONTROL, Session_Api_MonitorControl);
//Api_SetFunction(API_MONITOR_PUT, Session_Api_MonitorPut);
Api_SetFunction(API_MONITOR_PUT2, Session_Api_MonitorPut2);
@ -496,6 +499,38 @@ _FX BOOLEAN Session_IsForceDisabled(ULONG SessionId)
}
//---------------------------------------------------------------------------
// Session_Api_ForceChildren
//---------------------------------------------------------------------------
_FX NTSTATUS Session_Api_ForceChildren(PROCESS *proc, ULONG64 *parms)
{
HANDLE process_id;
WCHAR *user_boxname;
WCHAR boxname[BOXNAME_COUNT];
if (proc)
return STATUS_NOT_IMPLEMENTED;
process_id = (HANDLE)parms[1];
memzero(boxname, sizeof(boxname));
user_boxname = (WCHAR *)parms[2];
if (user_boxname) {
ProbeForRead(user_boxname, sizeof(WCHAR) * (BOXNAME_COUNT - 2), sizeof(UCHAR));
if (user_boxname[0])
wcsncpy(boxname, user_boxname, (BOXNAME_COUNT - 2));
}
if(!process_id || process_id == (HANDLE)-1 || !boxname[0])
return STATUS_INVALID_PARAMETER;
Process_FcpInsert(process_id, boxname);
return STATUS_SUCCESS;
}
//---------------------------------------------------------------------------
// Session_IsLeader
//---------------------------------------------------------------------------