This commit is contained in:
DavidXanatos 2024-12-17 11:19:09 +01:00
parent b733669f73
commit 4747d0ecf9
4 changed files with 59 additions and 10 deletions

View File

@ -16,6 +16,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- fixed Firefox tab crashes when running with `ProtectHostImages=y` enabled [#4394](https://github.com/sandboxie-plus/Sandboxie/issues/4394)
- Only default installation locations are considered; Firefox-based browsers installed outside of these locations may still crash.
- To prevent this, manually add `DontCopy=<CustomInstallPath>` for custom installation paths to your configuration
- fixed BSOD "SYSTEM_SERVICE_EXCEPTION (3b)" when opening a DLL from AlertFolder using x64dbg [#4421](https://github.com/sandboxie-plus/Sandboxie/issues/4421)
- fixed BSoD "CRITICAL_PROCESS_DIED" when terminate all sandboxed programs [#1316](https://github.com/sandboxie-plus/Sandboxie/issues/1316)
- Note: we now terminate boxed processes individually instead of terminating using the job object, unless "TerminateJobObject=y" is set

View File

@ -1173,11 +1173,27 @@ _FX NTSTATUS Process_Api_Kill(PROCESS *proc, ULONG64 *parms)
if (NT_SUCCESS(status)) {
status = ObOpenObjectByPointer(ProcessObject, OBJ_KERNEL_HANDLE, NULL, PROCESS_TERMINATE, NULL, KernelMode, &handle);
status = ObOpenObjectByPointer(ProcessObject, OBJ_KERNEL_HANDLE, NULL, PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, NULL, KernelMode, &handle);
ObDereferenceObject(ProcessObject);
if (NT_SUCCESS(status)) {
//
// Check and if needed clear critical process flag
//
ULONG breakOnTermination;
status = ZwQueryInformationProcess(handle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL);
if (NT_SUCCESS(status) && breakOnTermination) {
breakOnTermination = 0;
status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG));
}
//
// Terminate
//
if (NT_SUCCESS(status))
ZwTerminateProcess(handle, DBG_TERMINATE_PROCESS);
ZwClose(handle);
}

View File

@ -319,8 +319,15 @@ _FX NTSTATUS Thread_SetInformationProcess(
PROCESS *proc, SYSCALL_ENTRY *syscall_entry, ULONG_PTR *user_args)
{
NTSTATUS status;
ULONG InfoClass = (ULONG)user_args[1];
if (InfoClass == ProcessBreakOnTermination) {
status = STATUS_ACCESS_DENIED;
//Windows RS5 adds a new "undocumented" Process Information class: 0x5d (93) that is likely ProcessAccessTokenEx
if (((user_args[1] == ProcessAccessToken) || (user_args[1] == ProcessAccessTokenEx)) && proc->primary_token) {
} else if (((InfoClass == ProcessAccessToken) || (InfoClass == ProcessAccessTokenEx)) && proc->primary_token) {
HANDLE ProcessHandle = (HANDLE)user_args[0];
void *InfoBuffer = (void *)user_args[2];
ULONG InfoLength = (ULONG)user_args[3];
@ -1151,7 +1158,11 @@ _FX NTSTATUS Thread_SetInformationThread(
ULONG InfoClass = (ULONG)user_args[1];
if (InfoClass == ThreadImpersonationToken && proc->primary_token) {
if (InfoClass == ThreadBreakOnTermination){
status = STATUS_ACCESS_DENIED;
} else if (InfoClass == ThreadImpersonationToken && proc->primary_token) {
HANDLE ThreadHandle = (HANDLE)user_args[0];
void *InfoBuffer = (void *)user_args[2];

View File

@ -130,13 +130,32 @@ BOOL ProcessServer::KillProcess(ULONG ProcessId)
{
ULONG LastError = 0;
BOOL ok = FALSE;
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, ProcessId);
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, ProcessId);
if (! hProcess)
LastError = GetLastError() * 10000;
else {
//
// Bevore terminating any process, check if still its a sandboxed process as PID's get reused,
// but not as long as a handle is open, hence chacking after OpenProcess remains valid untill CloseHandle
//
// also check if process was marked as critical process
//
if (!SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)ProcessId, 0))
ok = TRUE;
else {
NTSTATUS status;
ULONG breakOnTermination;
status = NtQueryInformationProcess(hProcess, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL);
if (NT_SUCCESS(status) && !breakOnTermination) {
ok = TerminateProcess(hProcess, DBG_TERMINATE_PROCESS);
if (!ok)
LastError = GetLastError();
}
}
CloseHandle(hProcess);
}
@ -269,8 +288,8 @@ MSG_HEADER *ProcessServer::KillAllHandler(MSG_HEADER *msg)
if (status != STATUS_INVALID_CID) // if this is true the caller is boxed, should be rpcss
TerminateJob = FALSE; // if rpcss requests box termination, don't use the job method, fix-me: we get some stuck request in the queue
else
TerminateJob = !SbieApi_QueryConfBool(TargetBoxName, L"NoAddProcessToJob", FALSE);
else if (!SbieApi_QueryConfBool(TargetBoxName, L"NoAddProcessToJob", FALSE) && !SbieApi_QueryConfBool(TargetBoxName, L"NoSecurityIsolation", FALSE))
TerminateJob = SbieApi_QueryConfBool(TargetBoxName, L"TerminateJobObject", FALSE);
//
// match session id and box name