This commit is contained in:
DavidXanatos 2023-11-27 19:14:16 +01:00
parent 4ed04092ae
commit 12a85fbcb4
20 changed files with 1146 additions and 426 deletions

View File

@ -7,17 +7,29 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.12.3 / 5.67.3] - 2023-11-
### Fixed
- FIXED SECURITY ISSUE ID-23 SeManageVolumePrivilege is now blocked, as it allowed to read MFT data (thanks Diversenok)
- fixed Program launch when forcing prcesses into a confidential box [#3173](https://github.com/sandboxie-plus/Sandboxie/issues/3173)
## [1.12.2 / 5.67.2] - 2023-11- ## [1.12.2 / 5.67.2] - 2023-11-
### Added ### Added
- added options dialog when exporting a box [#3409](https://github.com/sandboxie-plus/Sandboxie/issues/3409) - added options dialog when exporting a box [#3409](https://github.com/sandboxie-plus/Sandboxie/issues/3409)
### Changed
- moved process info retreival to SbieSvc, resolves some information not being available in comaprtment type boxes when sandman does not run as admin.
- moved Process Suspend/Resume to SbieSvc [#3156](https://github.com/sandboxie-plus/Sandboxie/issues/3156)
### Fixed ### Fixed
- FIXED SECURITY ISSUE ID-23 SeManageVolumePrivilege is now blocked, as it allowed to read MFT data (thanks Diversenok)
- fixed issue with Microsoft Edge when using AutoDelete option [#post-3173507](https://www.wilderssecurity.com/threads/sandboxie-plus-v1-12-1-pre-release.452939/#post-3173507) - fixed issue with Microsoft Edge when using AutoDelete option [#post-3173507](https://www.wilderssecurity.com/threads/sandboxie-plus-v1-12-1-pre-release.452939/#post-3173507)
- fixed warning issue `Acrobat.exe: SBIE2205 Service not implemented: CredEnumerateA` [#issuecomment-1826280016](https://github.com/sandboxie-plus/Sandboxie/issues/3441#issuecomment-1826280016) - fixed warning issue `Acrobat.exe: SBIE2205 Service not implemented: CredEnumerateA` [#issuecomment-1826280016](https://github.com/sandboxie-plus/Sandboxie/issues/3441#issuecomment-1826280016)
- fixed UNEXPECTED_KERNEL_MODE_TRAP BSOD when opening any web link from sandboxed Microsoft 365 app (e.g. Outlook, Word) [#3427](https://github.com/sandboxie-plus/Sandboxie/issues/3427) - fixed UNEXPECTED_KERNEL_MODE_TRAP BSOD when opening any web link from sandboxed Microsoft 365 app (e.g. Outlook, Word) [#3427](https://github.com/sandboxie-plus/Sandboxie/issues/3427)
- fixed issue with force process warning message - fixed issue with force process warning message
- fixed Online updater does not respect portable mode [#3406](https://github.com/sandboxie-plus/Sandboxie/issues/3406)
## [1.12.1 / 5.67.1] - 2023-11-23 ## [1.12.1 / 5.67.1] - 2023-11-23

View File

@ -1359,9 +1359,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
ULONG session_id = new_proc->box->session_id; ULONG session_id = new_proc->box->session_id;
new_proc->bHostInject = bHostInject; new_proc->bHostInject = bHostInject;
#ifdef DRV_BREAKOUT
new_proc->starter_id = CallerId; new_proc->starter_id = CallerId;
#endif
new_proc->parent_was_start_exe = parent_was_start_exe; new_proc->parent_was_start_exe = parent_was_start_exe;
new_proc->rights_dropped = parent_had_rights_dropped; new_proc->rights_dropped = parent_had_rights_dropped;
new_proc->forced_process = process_is_forced; new_proc->forced_process = process_is_forced;

View File

@ -58,9 +58,7 @@ struct _PROCESS {
// process id // process id
HANDLE pid; HANDLE pid;
#ifdef DRV_BREAKOUT
HANDLE starter_id; HANDLE starter_id;
#endif
// process pool. created on process creation. it is freed in its // process pool. created on process creation. it is freed in its
// entirety when the process terminates // entirety when the process terminates

View File

@ -1239,6 +1239,9 @@ _FX ACCESS_MASK Thread_CheckObject_CommonEx(
protect_process = FALSE; protect_process = FALSE;
} }
if (protect_process && cur_pid == proc2->starter_id && !proc2->initialized)
protect_process = FALSE;
if (protect_process) { if (protect_process) {
if (Conf_Get_Boolean(proc2->box->name, L"NotifyBoxProtected", 0, FALSE)) { if (Conf_Get_Boolean(proc2->box->name, L"NotifyBoxProtected", 0, FALSE)) {

View File

@ -811,7 +811,7 @@ _FX NTSTATUS KphValidateCertificate()
Verify_CertInfo.type = eCertEvaluation; Verify_CertInfo.type = eCertEvaluation;
else if (_wcsicmp(type, L"HOME") == 0 || _wcsicmp(type, L"SUBSCRIPTION") == 0) else if (_wcsicmp(type, L"HOME") == 0 || _wcsicmp(type, L"SUBSCRIPTION") == 0)
Verify_CertInfo.type = eCertHome; Verify_CertInfo.type = eCertHome;
else if (_wcsicmp(type, L"FAMILYPACK") == 0) else if (_wcsicmp(type, L"FAMILYPACK") == 0 || _wcsicmp(type, L"FAMILY") == 0)
Verify_CertInfo.type = eCertFamily; Verify_CertInfo.type = eCertFamily;
// patreon >>> // patreon >>>
else if (wcsstr(type, L"PATREON") != NULL) // TYPE: [CLASS]_PATREON-[LEVEL] else if (wcsstr(type, L"PATREON") != NULL) // TYPE: [CLASS]_PATREON-[LEVEL]

View File

@ -37,10 +37,21 @@
#include "core/drv/api_defs.h" #include "core/drv/api_defs.h"
#include <sddl.h> #include <sddl.h>
#include "sbieiniserver.h" #include "sbieiniserver.h"
#include <string>
#define SECONDS(n64) (((LONGLONG)n64) * 10000000L) #define SECONDS(n64) (((LONGLONG)n64) * 10000000L)
#define MINUTES(n64) (SECONDS(n64) * 60) #define MINUTES(n64) (SECONDS(n64) * 60)
extern "C"
{
WINBASEAPI BOOL WINAPI QueryFullProcessImageNameW(HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD lpdwSize);
NTSYSCALLAPI NTSTATUS NTAPI NtGetNextThread(HANDLE ProcessHandle, HANDLE ThreadHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewThreadHandle);
NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess(_In_ HANDLE ProcessHandle);
NTSYSCALLAPI NTSTATUS NTAPI NtResumeProcess(_In_ HANDLE ProcessHandle);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Constructor // Constructor
@ -65,19 +76,17 @@ MSG_HEADER *ProcessServer::Handler(void *_this, MSG_HEADER *msg)
if (msg->msgid == MSGID_PROCESS_CHECK_INIT_COMPLETE) if (msg->msgid == MSGID_PROCESS_CHECK_INIT_COMPLETE)
return pThis->CheckInitCompleteHandler(); return pThis->CheckInitCompleteHandler();
HANDLE idProcess = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
if (msg->msgid == MSGID_PROCESS_KILL_ONE) if (msg->msgid == MSGID_PROCESS_KILL_ONE)
return pThis->KillOneHandler(idProcess, msg); return pThis->KillOneHandler(msg);
if (msg->msgid == MSGID_PROCESS_KILL_ALL) if (msg->msgid == MSGID_PROCESS_KILL_ALL)
return pThis->KillAllHandler(idProcess, msg); return pThis->KillAllHandler(msg);
if (msg->msgid == MSGID_PROCESS_SET_DEVICE_MAP) if (msg->msgid == MSGID_PROCESS_SET_DEVICE_MAP)
return pThis->SetDeviceMap(idProcess, msg); return pThis->SetDeviceMap(msg);
if (msg->msgid == MSGID_PROCESS_OPEN_DEVICE_MAP) if (msg->msgid == MSGID_PROCESS_OPEN_DEVICE_MAP)
return pThis->OpenDeviceMap(idProcess, msg); return pThis->OpenDeviceMap(msg);
if (msg->msgid == MSGID_PROCESS_RUN_SANDBOXED) if (msg->msgid == MSGID_PROCESS_RUN_SANDBOXED)
return pThis->RunSandboxedHandler(msg); return pThis->RunSandboxedHandler(msg);
@ -85,6 +94,15 @@ MSG_HEADER *ProcessServer::Handler(void *_this, MSG_HEADER *msg)
if (msg->msgid == MSGID_PROCESS_RUN_UPDATER) if (msg->msgid == MSGID_PROCESS_RUN_UPDATER)
return pThis->RunUpdaterHandler(msg); return pThis->RunUpdaterHandler(msg);
if (msg->msgid == MSGID_PROCESS_GET_INFO)
return pThis->ProcInfoHandler(msg);
if (msg->msgid == MSGID_PROCESS_SUSPEND_RESUME_ONE)
return pThis->SuspendOneHandler(msg);
if (msg->msgid == MSGID_PROCESS_SUSPEND_RESUME_ALL)
return pThis->SuspendAllHandler(msg);
return NULL; return NULL;
} }
@ -131,9 +149,9 @@ BOOL ProcessServer::KillProcess(ULONG ProcessId)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::KillOneHandler( MSG_HEADER *ProcessServer::KillOneHandler(MSG_HEADER *msg)
HANDLE CallerProcessId, MSG_HEADER *msg)
{ {
HANDLE CallerProcessId;
ULONG TargetSessionId; ULONG TargetSessionId;
WCHAR TargetBoxName[BOXNAME_COUNT]; WCHAR TargetBoxName[BOXNAME_COUNT];
ULONG CallerSessionId; ULONG CallerSessionId;
@ -162,6 +180,8 @@ MSG_HEADER *ProcessServer::KillOneHandler(
// get session id for caller. if sandboxed, get also box name // get session id for caller. if sandboxed, get also box name
// //
CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
status = SbieApi_QueryProcess(CallerProcessId, CallerBoxName, status = SbieApi_QueryProcess(CallerProcessId, CallerBoxName,
NULL, NULL, &CallerSessionId); NULL, NULL, &CallerSessionId);
@ -202,9 +222,9 @@ MSG_HEADER *ProcessServer::KillOneHandler(
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::KillAllHandler( MSG_HEADER *ProcessServer::KillAllHandler(MSG_HEADER *msg)
HANDLE CallerProcessId, MSG_HEADER *msg)
{ {
HANDLE CallerProcessId;
ULONG TargetSessionId; ULONG TargetSessionId;
WCHAR TargetBoxName[BOXNAME_COUNT]; WCHAR TargetBoxName[BOXNAME_COUNT];
ULONG CallerSessionId; ULONG CallerSessionId;
@ -229,6 +249,8 @@ MSG_HEADER *ProcessServer::KillAllHandler(
// get session id for caller. if sandboxed, get also box name // get session id for caller. if sandboxed, get also box name
// //
CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
status = SbieApi_QueryProcess(CallerProcessId, CallerBoxName, status = SbieApi_QueryProcess(CallerProcessId, CallerBoxName,
NULL, NULL, &CallerSessionId); NULL, NULL, &CallerSessionId);
@ -333,8 +355,7 @@ NTSTATUS ProcessServer::KillAllHelper(const WCHAR *BoxName, ULONG SessionId, BOO
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::SetDeviceMap( MSG_HEADER *ProcessServer::SetDeviceMap(MSG_HEADER *msg)
HANDLE CallerProcessId, MSG_HEADER *msg)
{ {
// //
// 32-bit process on 64-bit Windows can't set its own device map // 32-bit process on 64-bit Windows can't set its own device map
@ -342,43 +363,40 @@ MSG_HEADER *ProcessServer::SetDeviceMap(
// to set the device map for it. see also core/dll/file_init.c // to set the device map for it. see also core/dll/file_init.c
// //
NTSTATUS status = STATUS_SUCCESS;
PROCESS_SET_DEVICE_MAP_REQ *req = (PROCESS_SET_DEVICE_MAP_REQ *)msg; PROCESS_SET_DEVICE_MAP_REQ *req = (PROCESS_SET_DEVICE_MAP_REQ *)msg;
if (req->h.length < sizeof(PROCESS_SET_DEVICE_MAP_REQ)) if (req->h.length < sizeof(PROCESS_SET_DEVICE_MAP_REQ))
status = STATUS_INVALID_PARAMETER; return SHORT_REPLY(STATUS_INVALID_PARAMETER);
else if (! SbieApi_QueryProcessInfo( HANDLE CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
(HANDLE)(ULONG_PTR)CallerProcessId, 0))
status = STATUS_ACCESS_DENIED;
if (! SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)CallerProcessId, 0))
return SHORT_REPLY(STATUS_ACCESS_DENIED);
NTSTATUS status = STATUS_SUCCESS;
HANDLE CallerProcessHandle = OpenProcess(
PROCESS_SET_INFORMATION | PROCESS_DUP_HANDLE,
FALSE, (ULONG)(ULONG_PTR)CallerProcessId);
if (! CallerProcessHandle)
status = RtlNtStatusToDosError(GetLastError());
else { else {
HANDLE CallerProcessHandle = OpenProcess( PROCESS_DEVICEMAP_INFORMATION info;
PROCESS_SET_INFORMATION | PROCESS_DUP_HANDLE, BOOL ok = DuplicateHandle(
FALSE, (ULONG)(ULONG_PTR)CallerProcessId); CallerProcessHandle, (HANDLE)(ULONG_PTR)req->DirectoryHandle,
if (! CallerProcessHandle) NtCurrentProcess(), &info.Set.DirectoryHandle,
DIRECTORY_TRAVERSE, FALSE, 0);
if (! ok)
status = RtlNtStatusToDosError(GetLastError()); status = RtlNtStatusToDosError(GetLastError());
else { else {
PROCESS_DEVICEMAP_INFORMATION info; status = NtSetInformationProcess(
BOOL ok = DuplicateHandle( CallerProcessHandle, ProcessDeviceMap,
CallerProcessHandle, (HANDLE)(ULONG_PTR)req->DirectoryHandle, &info, sizeof(info.Set));
NtCurrentProcess(), &info.Set.DirectoryHandle,
DIRECTORY_TRAVERSE, FALSE, 0);
if (! ok)
status = RtlNtStatusToDosError(GetLastError());
else {
status = NtSetInformationProcess( NtClose(info.Set.DirectoryHandle);
CallerProcessHandle, ProcessDeviceMap,
&info, sizeof(info.Set));
NtClose(info.Set.DirectoryHandle);
}
NtClose(CallerProcessHandle);
} }
NtClose(CallerProcessHandle);
} }
return SHORT_REPLY(status); return SHORT_REPLY(status);
@ -390,8 +408,7 @@ MSG_HEADER *ProcessServer::SetDeviceMap(
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::OpenDeviceMap( MSG_HEADER *ProcessServer::OpenDeviceMap(MSG_HEADER *msg)
HANDLE CallerProcessId, MSG_HEADER *msg)
{ {
// //
// the process may not be able to open the device map it needs. // the process may not be able to open the device map it needs.
@ -400,59 +417,56 @@ MSG_HEADER *ProcessServer::OpenDeviceMap(
// this helper service can open the device map for the caller. // this helper service can open the device map for the caller.
// //
NTSTATUS status = STATUS_SUCCESS;
PROCESS_OPEN_DEVICE_MAP_REQ *req = (PROCESS_OPEN_DEVICE_MAP_REQ *)msg; PROCESS_OPEN_DEVICE_MAP_REQ *req = (PROCESS_OPEN_DEVICE_MAP_REQ *)msg;
if (req->h.length < sizeof(PROCESS_OPEN_DEVICE_MAP_REQ)) if (req->h.length < sizeof(PROCESS_OPEN_DEVICE_MAP_REQ))
status = STATUS_INVALID_PARAMETER; return SHORT_REPLY(STATUS_INVALID_PARAMETER);
else if (! SbieApi_QueryProcessInfo( HANDLE CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
(HANDLE)(ULONG_PTR)CallerProcessId, 0))
status = STATUS_ACCESS_DENIED;
else { if (! SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)CallerProcessId, 0))
return SHORT_REPLY(STATUS_ACCESS_DENIED);
HANDLE LocalDirectoryHandle; NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING objname; HANDLE LocalDirectoryHandle;
OBJECT_ATTRIBUTES objattrs; UNICODE_STRING objname;
OBJECT_ATTRIBUTES objattrs;
RtlInitUnicodeString(&objname, req->DirectoryName); RtlInitUnicodeString(&objname, req->DirectoryName);
InitializeObjectAttributes( InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL); &objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtOpenDirectoryObject( status = NtOpenDirectoryObject(
&LocalDirectoryHandle, DIRECTORY_TRAVERSE, &objattrs); &LocalDirectoryHandle, DIRECTORY_TRAVERSE, &objattrs);
if (NT_SUCCESS(status)) { if (NT_SUCCESS(status)) {
HANDLE CallerProcessHandle = OpenProcess(PROCESS_DUP_HANDLE HANDLE CallerProcessHandle = OpenProcess(PROCESS_DUP_HANDLE
| PROCESS_VM_OPERATION | PROCESS_VM_WRITE, | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
FALSE, (ULONG)(ULONG_PTR)CallerProcessId); FALSE, (ULONG)(ULONG_PTR)CallerProcessId);
if (! CallerProcessHandle) if (! CallerProcessHandle)
status = RtlNtStatusToDosError(GetLastError());
else {
HANDLE RemoteDirectoryHandle;
BOOL ok = DuplicateHandle(
NtCurrentProcess(), LocalDirectoryHandle,
CallerProcessHandle, (HANDLE *)&RemoteDirectoryHandle,
DIRECTORY_TRAVERSE, FALSE, 0);
if (! ok)
status = RtlNtStatusToDosError(GetLastError()); status = RtlNtStatusToDosError(GetLastError());
else { else {
HANDLE RemoteDirectoryHandle; ok = WriteProcessMemory(
BOOL ok = DuplicateHandle( CallerProcessHandle, (void *)req->DirectoryHandlePtr,
NtCurrentProcess(), LocalDirectoryHandle, &RemoteDirectoryHandle, sizeof(HANDLE), NULL);
CallerProcessHandle, (HANDLE *)&RemoteDirectoryHandle,
DIRECTORY_TRAVERSE, FALSE, 0);
if (! ok) if (! ok)
status = RtlNtStatusToDosError(GetLastError()); status = RtlNtStatusToDosError(GetLastError());
else {
ok = WriteProcessMemory(
CallerProcessHandle, (void *)req->DirectoryHandlePtr,
&RemoteDirectoryHandle, sizeof(HANDLE), NULL);
if (! ok)
status = RtlNtStatusToDosError(GetLastError());
}
NtClose(CallerProcessHandle);
} }
NtClose(LocalDirectoryHandle); NtClose(CallerProcessHandle);
} }
NtClose(LocalDirectoryHandle);
} }
return SHORT_REPLY(status); return SHORT_REPLY(status);
@ -543,7 +557,8 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)
//ULONG flags = 0; //ULONG flags = 0;
//if (!NT_SUCCESS(SbieApi_Call(API_QUERY_DRIVER_INFO, 2, 0, (ULONG_PTR)&flags)) || (flags & SBIE_FEATURE_FLAG_CERTIFIED) == 0) { //if (!NT_SUCCESS(SbieApi_Call(API_QUERY_DRIVER_INFO, 2, 0, (ULONG_PTR)&flags)) || (flags & SBIE_FEATURE_FLAG_CERTIFIED) == 0) {
// ULONG SessionId = PipeServer::GetCallerSessionId(); // ULONG SessionId = PipeServer::GetCallerSessionId();
// SbieApi_LogEx(SessionId, 6004, L"%S", boxname); // const WCHAR* strings[] = { boxname, L"Breakout*", NULL };
// SbieApi_LogMsgExt(SessionId, 6004, strings);
// lvl = 0x66; // lvl = 0x66;
// err = ERROR_NOT_SUPPORTED; // err = ERROR_NOT_SUPPORTED;
// goto end; // goto end;
@ -1635,3 +1650,521 @@ MSG_HEADER *ProcessServer::RunUpdaterHandler(MSG_HEADER *msg)
} }
return (MSG_HEADER *)rpl; return (MSG_HEADER *)rpl;
} }
//---------------------------------------------------------------------------
// GetPebString
//---------------------------------------------------------------------------
typedef enum _PEB_OFFSET
{
PhpoCurrentDirectory,
PhpoDllPath,
PhpoImagePathName,
PhpoCommandLine,
PhpoWindowTitle,
PhpoDesktopInfo,
PhpoShellInfo,
PhpoRuntimeData,
PhpoTypeMask = 0xffff,
PhpoWow64 = 0x10000
} PEB_OFFSET;
typedef struct _STRING32
{
USHORT Length;
USHORT MaximumLength;
ULONG Buffer;
} UNICODE_STRING32, * PUNICODE_STRING32;
//typedef struct _STRING64 {
// USHORT Length;
// USHORT MaximumLength;
// PVOID64 Buffer;
//} UNICODE_STRING64, * PUNICODE_STRING64;
//// PROCESS_BASIC_INFORMATION for pure 32 and 64-bit processes
//typedef struct _PROCESS_BASIC_INFORMATION {
// PVOID Reserved1;
// PVOID PebBaseAddress;
// PVOID Reserved2[2];
// ULONG_PTR UniqueProcessId;
// PVOID Reserved3;
//} PROCESS_BASIC_INFORMATION;
// PROCESS_BASIC_INFORMATION for 32-bit process on WOW64
typedef struct _PROCESS_BASIC_INFORMATION_WOW64 {
PVOID Reserved1[2];
PVOID64 PebBaseAddress;
PVOID Reserved2[4];
ULONG_PTR UniqueProcessId[2];
PVOID Reserved3[2];
} PROCESS_BASIC_INFORMATION_WOW64;
typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(IN HANDLE ProcessHandle, ULONG ProcessInformationClass,
OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL );
//typedef NTSTATUS (NTAPI *_NtReadVirtualMemory)(IN HANDLE ProcessHandle, IN PVOID BaseAddress,
// OUT PVOID Buffer, IN SIZE_T Size, OUT PSIZE_T NumberOfBytesRead);
typedef NTSTATUS (NTAPI *_NtWow64ReadVirtualMemory64)(IN HANDLE ProcessHandle,IN PVOID64 BaseAddress,
OUT PVOID Buffer, IN ULONG64 Size, OUT PULONG64 NumberOfBytesRead);
std::wstring GetPebString(HANDLE ProcessHandle, PEB_OFFSET Offset)
{
BOOL is64BitOperatingSystem;
BOOL isWow64Process = FALSE;
#ifdef _WIN64
is64BitOperatingSystem = TRUE;
#else // ! _WIN64
isWow64Process = CSbieAPI::IsWow64();
is64BitOperatingSystem = isWow64Process;
#endif _WIN64
BOOL isTargetWow64Process = FALSE;
IsWow64Process(ProcessHandle, &isTargetWow64Process);
BOOL isTarget64BitProcess = is64BitOperatingSystem && !isTargetWow64Process;
ULONG processParametersOffset = isTarget64BitProcess ? 0x20 : 0x10;
ULONG offset = 0;
switch (Offset)
{
case PhpoCurrentDirectory: offset = isTarget64BitProcess ? 0x38 : 0x24; break;
case PhpoCommandLine: offset = isTarget64BitProcess ? 0x70 : 0x40; break;
default:
return L"";
}
std::wstring s;
if (isTargetWow64Process) // OS : 64Bit, Cur : 32 or 64, Tar: 32bit
{
PVOID peb32;
if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessWow64Information, &peb32, sizeof(PVOID), NULL)))
return L"";
ULONG procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)peb32 + processParametersOffset), &procParams, sizeof(ULONG), NULL)))
return L"";
UNICODE_STRING32 us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING32), NULL)))
return L"";
if ((us.Buffer == 0) || (us.Length == 0))
return L"";
s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return L"";
}
else if (isWow64Process) //Os : 64Bit, Cur 32, Tar 64
{
static _NtQueryInformationProcess query = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64QueryInformationProcess64");
static _NtWow64ReadVirtualMemory64 read = (_NtWow64ReadVirtualMemory64)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64ReadVirtualMemory64");
PROCESS_BASIC_INFORMATION_WOW64 pbi;
if (!NT_SUCCESS(query(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION_WOW64), NULL)))
return L"";
ULONGLONG procParams;
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)((ULONGLONG)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONGLONG), NULL)))
return L"";
UNICODE_STRING64 us;
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)(procParams + offset), &us, sizeof(UNICODE_STRING64), NULL)))
return L"";
if ((us.Buffer == 0) || (us.Length == 0))
return L"";
s.resize(us.Length / 2);
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)us.Buffer, (PVOID64)s.c_str(), s.length() * 2, NULL)))
return L"";
}
else // Os,Cur,Tar : 64 or 32
{
PROCESS_BASIC_INFORMATION pbi;
if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)))
return L"";
ULONG_PTR procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONG_PTR), NULL)))
return L"";
UNICODE_STRING us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING), NULL)))
return L"";
if ((us.Buffer == 0) || (us.Length == 0))
return L"";
s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return L"";
}
return s;
}
//---------------------------------------------------------------------------
// ProcInfoHandler
//---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::ProcInfoHandler(MSG_HEADER *msg)
{
HANDLE CallerProcessId;
//ULONG CallerSessionId;
//
// parse request packet
//
PROCESS_GET_INFO_REQ *req = (PROCESS_GET_INFO_REQ *)msg;
if (req->h.length < sizeof(PROCESS_GET_INFO_REQ))
return SHORT_REPLY(STATUS_INVALID_PARAMETER);
//
// get session id for caller.
//
CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
//CallerSessionId = PipeServer::GetCallerSessionId();
//
// only unsandboxed programs are allowed to use this mechanism
//
if(SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)CallerProcessId, 0))
return SHORT_REPLY(STATUS_ACCESS_DENIED);
HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, req->dwProcessId);
if (ProcessHandle == NULL) // try with less rights
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, req->dwProcessId);
if (ProcessHandle == NULL) // try with even less rights
ProcessHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, req->dwProcessId);
if (!ProcessHandle)
return SHORT_REPLY(STATUS_ACCESS_DENIED);
ULONG dwParentId = -1;
union
{
ULONG Flags;
struct
{
ULONG
IsWoW64 : 1,
IsElevated : 1,
IsSystem : 1,
IsRestricted : 1,
IsAppContainer : 1,
Spare : 27;
};
} Info;
Info.Flags = 0;
BOOLEAN bSuspended = FALSE;
std::wstring ImagePath;
std::wstring CommandLine;
std::wstring WorkingDir;
if (req->dwInfoClasses & SBIE_PROCESS_BASIC_INFO)
{
PROCESS_BASIC_INFORMATION BasicInformation;
NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &BasicInformation, sizeof(PROCESS_BASIC_INFORMATION), NULL);
if (NT_SUCCESS(status))
dwParentId = (ULONG)BasicInformation.InheritedFromUniqueProcessId;
BOOL isTargetWow64Process = FALSE;
if(IsWow64Process(ProcessHandle, &isTargetWow64Process))
Info.IsWoW64 = isTargetWow64Process;
HANDLE TokenHandle = (HANDLE)SbieApi_QueryProcessInfo((HANDLE)req->dwProcessId, 'ptok');
if (!TokenHandle) // app compartment type box
NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &TokenHandle);
if (TokenHandle)
{
ULONG returnLength;
TOKEN_ELEVATION_TYPE elevationType;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenElevationType, &elevationType, sizeof(TOKEN_ELEVATION_TYPE), &returnLength))) {
Info.IsElevated = elevationType == TokenElevationTypeFull;
}
SID SeLocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SYSTEM_RID } };
BYTE tokenUserBuff[0x80] = { 0 };
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenUser, tokenUserBuff, sizeof(tokenUserBuff), &returnLength))){
Info.IsSystem = EqualSid(((PTOKEN_USER)tokenUserBuff)->User.Sid, &SeLocalSystemSid);
}
ULONG restricted;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenIsRestricted, &restricted, sizeof(ULONG), &returnLength))) {
Info.IsRestricted = !!restricted;
}
BYTE appContainerBuffer[0x80];
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenAppContainerSid, appContainerBuffer, sizeof(appContainerBuffer), &returnLength))) {
PTOKEN_APPCONTAINER_INFORMATION appContainerInfo = (PTOKEN_APPCONTAINER_INFORMATION)appContainerBuffer;
Info.IsAppContainer = appContainerInfo->TokenAppContainer != NULL;
}
CloseHandle(TokenHandle);
}
}
if (req->dwInfoClasses & SBIE_PROCESS_EXEC_INFO)
{
int iSuspended = 0;
int iRunning = 0;
for (HANDLE hThread = NULL;;)
{
HANDLE nNextThread = NULL;
NTSTATUS status = NtGetNextThread(ProcessHandle, hThread, THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME, 0, 0, &nNextThread);
if (hThread) NtClose(hThread);
if (!NT_SUCCESS(status))
break;
hThread = nNextThread;
ULONG IsTerminated = 0;
if (!NT_SUCCESS(NtQueryInformationThread(hThread, ThreadIsTerminated, &IsTerminated, sizeof(ULONG), NULL)) || IsTerminated)
continue;
ULONG SuspendCount = 0;
status = NtQueryInformationThread(hThread, (THREADINFOCLASS)35/*ThreadSuspendCount*/, &SuspendCount, sizeof(ULONG), NULL);
if (status == STATUS_INVALID_INFO_CLASS) { // windows 7
SuspendCount = SuspendThread(hThread);
ResumeThread(hThread);
}
if (SuspendCount > 0)
iSuspended++;
else
iRunning++;
}
bSuspended = iSuspended > 0 && iRunning == 0;
}
if (req->dwInfoClasses & SBIE_PROCESS_PATHS_INFO)
{
TCHAR filename[MAX_PATH];
DWORD dwSize = MAX_PATH;
if (QueryFullProcessImageNameW(ProcessHandle, 0, filename, &dwSize))
ImagePath = filename;
// windows 8.1 and later
#define ProcessCommandLineInformation ((PROCESSINFOCLASS)60)
ULONG returnLength = 0;
NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, NULL, 0, &returnLength);
if (!(status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL && status != STATUS_INFO_LENGTH_MISMATCH))
{
PUNICODE_STRING commandLine = (PUNICODE_STRING)malloc(returnLength);
status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, commandLine, returnLength, &returnLength);
if (NT_SUCCESS(status) && commandLine->Buffer != NULL)
CommandLine = commandLine->Buffer;
free(commandLine);
}
#undef ProcessCommandLineInformation
if (CommandLine.empty()) // fall back to the win 7 method - requirers PROCESS_VM_READ
CommandLine = GetPebString(ProcessHandle, PhpoCommandLine);
WorkingDir = GetPebString(ProcessHandle, PhpoCurrentDirectory);
}
CloseHandle(ProcessHandle);
PROCESS_INFO_RPL *rpl = (PROCESS_INFO_RPL *) LONG_REPLY(sizeof(PROCESS_INFO_RPL)
+ (ImagePath.length() + 1 + CommandLine.length() + 1 + WorkingDir.length() + 1) * sizeof(WCHAR));
if (rpl) {
rpl->h.status = STATUS_SUCCESS;
rpl->dwParentId = dwParentId;
rpl->dwInfo = Info.Flags;
rpl->bSuspended = bSuspended;
WCHAR* ptr = (WCHAR*)((ULONG_PTR)rpl + sizeof(PROCESS_INFO_RPL));
rpl->app_ofs = 0;
rpl->app_len = ImagePath.length();
if (rpl->app_len > 0) {
rpl->app_ofs = (ULONG)((UCHAR*)ptr - (UCHAR*)rpl);
wmemcpy(ptr, ImagePath.c_str(), rpl->app_len + 1);
ptr += rpl->app_len + 1;
}
rpl->cmd_ofs = 0;
rpl->cmd_len = CommandLine.length();
if (rpl->cmd_len > 0) {
rpl->cmd_ofs = (ULONG)((UCHAR*)ptr - (UCHAR*)rpl);
wmemcpy(ptr, CommandLine.c_str(), rpl->cmd_len + 1);
ptr += rpl->cmd_len + 1;
}
rpl->dir_ofs = 0;
rpl->dir_len = WorkingDir.length();
if (rpl->dir_len > 0) {
rpl->dir_ofs = (ULONG)((UCHAR*)ptr - (UCHAR*)rpl);
wmemcpy(ptr, WorkingDir.c_str(), rpl->dir_len + 1);
ptr += rpl->dir_len + 1;
}
}
return (MSG_HEADER *)rpl;
}
//---------------------------------------------------------------------------
// SuspendOneHandler
//---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::SuspendOneHandler(MSG_HEADER *msg)
{
HANDLE CallerProcessId;
ULONG TargetSessionId;
WCHAR TargetBoxName[BOXNAME_COUNT];
ULONG CallerSessionId;
NTSTATUS status;
//
// parse request packet
//
PROCESS_SUSPEND_RESUME_ONE_REQ *req = (PROCESS_SUSPEND_RESUME_ONE_REQ *)msg;
if (req->h.length < sizeof(PROCESS_SUSPEND_RESUME_ONE_REQ))
return SHORT_REPLY(STATUS_INVALID_PARAMETER);
//
// get session id and box name for target process
//
status = SbieApi_QueryProcess((HANDLE)(ULONG_PTR)req->pid, TargetBoxName,
NULL, NULL, &TargetSessionId);
if (status != STATUS_SUCCESS)
return SHORT_REPLY(status);
//
// get session id for caller.
//
CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
CallerSessionId = PipeServer::GetCallerSessionId();
//
// only unsandboxed programs are allowed to use this mechanism
//
if(SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)CallerProcessId, 0))
return SHORT_REPLY(STATUS_ACCESS_DENIED);
//
// match session id and box name
//
if (CallerSessionId != TargetSessionId && !PipeServer::IsCallerAdmin())
return SHORT_REPLY(STATUS_ACCESS_DENIED);
//
// suspend/resume target process
//
HANDLE hProcess = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, req->pid);
if (req->suspend)
status = NtSuspendProcess(hProcess);
else
status = NtResumeProcess(hProcess);
CloseHandle(hProcess);
return SHORT_REPLY(status);
}
//---------------------------------------------------------------------------
// SuspendAllHandler
//---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::SuspendAllHandler(MSG_HEADER *msg)
{
return SHORT_REPLY(STATUS_NOT_IMPLEMENTED);
HANDLE CallerProcessId;
ULONG TargetSessionId;
WCHAR TargetBoxName[BOXNAME_COUNT];
ULONG CallerSessionId;
//BOOLEAN FreezeJob;
//NTSTATUS status;
//
// parse request packet
//
PROCESS_SUSPEND_RESUME_ALL_REQ *req = (PROCESS_SUSPEND_RESUME_ALL_REQ *)msg;
if (req->h.length < sizeof(PROCESS_SUSPEND_RESUME_ALL_REQ))
return SHORT_REPLY(STATUS_INVALID_PARAMETER);
TargetSessionId = req->session_id;
wcscpy(TargetBoxName, req->boxname);
if (! TargetBoxName[0])
return SHORT_REPLY(STATUS_INVALID_PARAMETER);
//
// get session id for caller.
//
CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
CallerSessionId = PipeServer::GetCallerSessionId();
//
// only unsandboxed programs are allowed to use this mechanism
//
if(SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)CallerProcessId, 0))
return SHORT_REPLY(STATUS_ACCESS_DENIED);
//FreezeJob = FALSE;
//
// match session id and box name
//
if (TargetSessionId == -1)
TargetSessionId = CallerSessionId;
else if (CallerSessionId != TargetSessionId && !PipeServer::IsCallerAdmin())
return SHORT_REPLY(STATUS_ACCESS_DENIED);
//
// suspend/resume target processes
//
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
for (ULONG i = 0; i < pid_count; ++i) {
DWORD pids_i = pids[i];
HANDLE hProcess = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, pids_i);
if (req->suspend)
NtSuspendProcess(hProcess);
else
NtResumeProcess(hProcess);
CloseHandle(hProcess);
}
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, pids);
return SHORT_REPLY(STATUS_SUCCESS);
}

View File

@ -47,15 +47,15 @@ protected:
BOOL KillProcess(ULONG ProcessId); BOOL KillProcess(ULONG ProcessId);
MSG_HEADER *KillOneHandler(HANDLE CallerProcessId, MSG_HEADER *msg); MSG_HEADER *KillOneHandler(MSG_HEADER *msg);
MSG_HEADER *KillAllHandler(HANDLE CallerProcessId, MSG_HEADER *msg); MSG_HEADER *KillAllHandler(MSG_HEADER *msg);
NTSTATUS KillAllHelper(const WCHAR *BoxName, ULONG SessionId, BOOLEAN TerminateJob = FALSE); NTSTATUS KillAllHelper(const WCHAR *BoxName, ULONG SessionId, BOOLEAN TerminateJob = FALSE);
MSG_HEADER *SetDeviceMap(HANDLE CallerProcessId, MSG_HEADER *msg); MSG_HEADER *SetDeviceMap(MSG_HEADER *msg);
MSG_HEADER *OpenDeviceMap(HANDLE CallerProcessId, MSG_HEADER *msg); MSG_HEADER *OpenDeviceMap(MSG_HEADER *msg);
// //
// Run Sandboxed // Run Sandboxed
@ -81,6 +81,16 @@ protected:
// //
MSG_HEADER *RunUpdaterHandler(MSG_HEADER *msg); MSG_HEADER *RunUpdaterHandler(MSG_HEADER *msg);
//
// Process Management
//
MSG_HEADER *ProcInfoHandler(MSG_HEADER *msg);
MSG_HEADER *SuspendOneHandler(MSG_HEADER *msg);
MSG_HEADER *SuspendAllHandler(MSG_HEADER *msg);
}; };

View File

@ -135,6 +135,75 @@ typedef struct tagPROCESS_RUN_UPDATER PROCESS_RUN_UPDATER_REQ;
typedef struct tagPROCESS_RUN_SANDBOXED_RPL PROCESS_RUN_UPDATER_RPL; typedef struct tagPROCESS_RUN_SANDBOXED_RPL PROCESS_RUN_UPDATER_RPL;
//---------------------------------------------------------------------------
// Get Process Info
//---------------------------------------------------------------------------
#define SBIE_PROCESS_BASIC_INFO 1
#define SBIE_PROCESS_EXEC_INFO 2
#define SBIE_PROCESS_PATHS_INFO 4
#define SBIE_PROCESS_ALL_INFO 7
struct tagPROCESS_GET_INFO_REQ
{
MSG_HEADER h;
ULONG dwProcessId;
ULONG dwInfoClasses;
};
struct tagPROCESS_INFO_RPL
{
MSG_HEADER h;
// basic
ULONG dwParentId;
ULONG dwInfo;
// exec
BOOLEAN bSuspended;
// paths
ULONG app_ofs;
ULONG app_len;
ULONG cmd_ofs;
ULONG cmd_len;
ULONG dir_ofs;
ULONG dir_len;
};
typedef struct tagPROCESS_GET_INFO_REQ PROCESS_GET_INFO_REQ;
typedef struct tagPROCESS_INFO_RPL PROCESS_INFO_RPL;
//---------------------------------------------------------------------------
// Suspend/Resume One Process
//---------------------------------------------------------------------------
struct tagPROCESS_SUSPEND_RESUME_ONE_REQ
{
MSG_HEADER h;
ULONG pid;
BOOLEAN suspend;
};
typedef struct tagPROCESS_SUSPEND_RESUME_ONE_REQ PROCESS_SUSPEND_RESUME_ONE_REQ;
//---------------------------------------------------------------------------
// Suspend/Resume All Process
//---------------------------------------------------------------------------
struct tagPROCESS_SUSPEND_RESUME_ALL_REQ
{
MSG_HEADER h;
ULONG session_id;
WCHAR boxname[34];
BOOLEAN suspend;
};
typedef struct tagPROCESS_SUSPEND_RESUME_ALL_REQ PROCESS_SUSPEND_RESUME_ALL_REQ;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -46,6 +46,9 @@
#define MSGID_PROCESS_SET_DEVICE_MAP 0x1206 #define MSGID_PROCESS_SET_DEVICE_MAP 0x1206
#define MSGID_PROCESS_OPEN_DEVICE_MAP 0x1207 #define MSGID_PROCESS_OPEN_DEVICE_MAP 0x1207
#define MSGID_PROCESS_RUN_UPDATER 0x1208 #define MSGID_PROCESS_RUN_UPDATER 0x1208
#define MSGID_PROCESS_GET_INFO 0x1209
#define MSGID_PROCESS_SUSPEND_RESUME_ONE 0x120A
#define MSGID_PROCESS_SUSPEND_RESUME_ALL 0x120B
#define MSGID_SERVICE 0x1300 #define MSGID_SERVICE 0x1300
#define MSGID_SERVICE_START 0x1301 #define MSGID_SERVICE_START 0x1301

View File

@ -27,7 +27,7 @@ typedef long NTSTATUS;
#include <windows.h> #include <windows.h>
#include "..\..\Sandboxie\common\win32_ntddk.h" #include "..\..\Sandboxie\common\win32_ntddk.h"
#include <psapi.h> // For access to GetModuleFileNameEx //#include <psapi.h> // For access to GetModuleFileNameEx
#include <winnt.h> #include <winnt.h>
@ -56,7 +56,7 @@ CBoxedProcess::CBoxedProcess(quint32 ProcessId, class CSandBox* pBox)
m_uTerminated = 0; m_uTerminated = 0;
m_bSuspended = false; m_bSuspended = false;
m_bIsWoW64 = false; m_ProcessInfo.Flags = 0;
} }
CBoxedProcess::~CBoxedProcess() CBoxedProcess::~CBoxedProcess()
@ -67,222 +67,255 @@ CBoxedProcess::~CBoxedProcess()
} }
typedef enum _PEB_OFFSET //typedef enum _PEB_OFFSET
{ //{
PhpoCurrentDirectory, // PhpoCurrentDirectory,
PhpoDllPath, // PhpoDllPath,
PhpoImagePathName, // PhpoImagePathName,
PhpoCommandLine, // PhpoCommandLine,
PhpoWindowTitle, // PhpoWindowTitle,
PhpoDesktopInfo, // PhpoDesktopInfo,
PhpoShellInfo, // PhpoShellInfo,
PhpoRuntimeData, // PhpoRuntimeData,
PhpoTypeMask = 0xffff, // PhpoTypeMask = 0xffff,
PhpoWow64 = 0x10000 // PhpoWow64 = 0x10000
} PEB_OFFSET; //} PEB_OFFSET;
//
//
typedef struct _STRING32 //typedef struct _STRING32
{ //{
USHORT Length; // USHORT Length;
USHORT MaximumLength; // USHORT MaximumLength;
ULONG Buffer; // ULONG Buffer;
} UNICODE_STRING32, * PUNICODE_STRING32; //} UNICODE_STRING32, * PUNICODE_STRING32;
//
//typedef struct _STRING64 { ////typedef struct _STRING64 {
// USHORT Length; //// USHORT Length;
// USHORT MaximumLength; //// USHORT MaximumLength;
// PVOID64 Buffer; //// PVOID64 Buffer;
//} UNICODE_STRING64, * PUNICODE_STRING64; ////} UNICODE_STRING64, * PUNICODE_STRING64;
//
//
//// PROCESS_BASIC_INFORMATION for pure 32 and 64-bit processes ////// PROCESS_BASIC_INFORMATION for pure 32 and 64-bit processes
//typedef struct _PROCESS_BASIC_INFORMATION { ////typedef struct _PROCESS_BASIC_INFORMATION {
// PVOID Reserved1; //// PVOID Reserved1;
// PVOID PebBaseAddress; //// PVOID PebBaseAddress;
// PVOID Reserved2[2]; //// PVOID Reserved2[2];
// ULONG_PTR UniqueProcessId; //// ULONG_PTR UniqueProcessId;
// PVOID Reserved3; //// PVOID Reserved3;
//} PROCESS_BASIC_INFORMATION; ////} PROCESS_BASIC_INFORMATION;
//
// PROCESS_BASIC_INFORMATION for 32-bit process on WOW64 //// PROCESS_BASIC_INFORMATION for 32-bit process on WOW64
typedef struct _PROCESS_BASIC_INFORMATION_WOW64 { //typedef struct _PROCESS_BASIC_INFORMATION_WOW64 {
PVOID Reserved1[2]; // PVOID Reserved1[2];
PVOID64 PebBaseAddress; // PVOID64 PebBaseAddress;
PVOID Reserved2[4]; // PVOID Reserved2[4];
ULONG_PTR UniqueProcessId[2]; // ULONG_PTR UniqueProcessId[2];
PVOID Reserved3[2]; // PVOID Reserved3[2];
} PROCESS_BASIC_INFORMATION_WOW64; //} PROCESS_BASIC_INFORMATION_WOW64;
//
//
typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(IN HANDLE ProcessHandle, ULONG ProcessInformationClass, //typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(IN HANDLE ProcessHandle, ULONG ProcessInformationClass,
OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL ); // OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL );
//
//typedef NTSTATUS (NTAPI *_NtReadVirtualMemory)(IN HANDLE ProcessHandle, IN PVOID BaseAddress, ////typedef NTSTATUS (NTAPI *_NtReadVirtualMemory)(IN HANDLE ProcessHandle, IN PVOID BaseAddress,
// OUT PVOID Buffer, IN SIZE_T Size, OUT PSIZE_T NumberOfBytesRead); //// OUT PVOID Buffer, IN SIZE_T Size, OUT PSIZE_T NumberOfBytesRead);
//
typedef NTSTATUS (NTAPI *_NtWow64ReadVirtualMemory64)(IN HANDLE ProcessHandle,IN PVOID64 BaseAddress, //typedef NTSTATUS (NTAPI *_NtWow64ReadVirtualMemory64)(IN HANDLE ProcessHandle,IN PVOID64 BaseAddress,
OUT PVOID Buffer, IN ULONG64 Size, OUT PULONG64 NumberOfBytesRead); // OUT PVOID Buffer, IN ULONG64 Size, OUT PULONG64 NumberOfBytesRead);
//
//
QString CBoxedProcess__GetPebString(HANDLE ProcessHandle, PEB_OFFSET Offset) //QString CBoxedProcess__GetPebString(HANDLE ProcessHandle, PEB_OFFSET Offset)
{ //{
BOOL is64BitOperatingSystem; // BOOL is64BitOperatingSystem;
BOOL isWow64Process = FALSE; // BOOL isWow64Process = FALSE;
#ifdef _WIN64 //#ifdef _WIN64
is64BitOperatingSystem = TRUE; // is64BitOperatingSystem = TRUE;
#else // ! _WIN64 //#else // ! _WIN64
isWow64Process = CSbieAPI::IsWow64(); // isWow64Process = CSbieAPI::IsWow64();
is64BitOperatingSystem = isWow64Process; // is64BitOperatingSystem = isWow64Process;
#endif _WIN64 //#endif _WIN64
//
BOOL isTargetWow64Process = FALSE; // BOOL isTargetWow64Process = FALSE;
IsWow64Process(ProcessHandle, &isTargetWow64Process); // IsWow64Process(ProcessHandle, &isTargetWow64Process);
BOOL isTarget64BitProcess = is64BitOperatingSystem && !isTargetWow64Process; // BOOL isTarget64BitProcess = is64BitOperatingSystem && !isTargetWow64Process;
//
ULONG processParametersOffset = isTarget64BitProcess ? 0x20 : 0x10; // ULONG processParametersOffset = isTarget64BitProcess ? 0x20 : 0x10;
//
ULONG offset = 0; // ULONG offset = 0;
switch (Offset) // switch (Offset)
{ // {
case PhpoCurrentDirectory: offset = isTarget64BitProcess ? 0x38 : 0x24; break; // case PhpoCurrentDirectory: offset = isTarget64BitProcess ? 0x38 : 0x24; break;
case PhpoCommandLine: offset = isTarget64BitProcess ? 0x70 : 0x40; break; // case PhpoCommandLine: offset = isTarget64BitProcess ? 0x70 : 0x40; break;
default: // default:
return QString(); // return QString();
} // }
//
std::wstring s; // std::wstring s;
if (isTargetWow64Process) // OS : 64Bit, Cur : 32 or 64, Tar: 32bit // if (isTargetWow64Process) // OS : 64Bit, Cur : 32 or 64, Tar: 32bit
{ // {
PVOID peb32; // PVOID peb32;
if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessWow64Information, &peb32, sizeof(PVOID), NULL))) // if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessWow64Information, &peb32, sizeof(PVOID), NULL)))
return QString(); // return QString();
//
ULONG procParams; // ULONG procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)peb32 + processParametersOffset), &procParams, sizeof(ULONG), NULL))) // if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)peb32 + processParametersOffset), &procParams, sizeof(ULONG), NULL)))
return QString(); // return QString();
//
UNICODE_STRING32 us; // UNICODE_STRING32 us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING32), NULL))) // if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING32), NULL)))
return QString(); // return QString();
//
if ((us.Buffer == 0) || (us.Length == 0)) // if ((us.Buffer == 0) || (us.Length == 0))
return QString(); // return QString();
//
s.resize(us.Length / 2); // s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL))) // if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return QString(); // return QString();
} // }
else if (isWow64Process) //Os : 64Bit, Cur 32, Tar 64 // else if (isWow64Process) //Os : 64Bit, Cur 32, Tar 64
{ // {
static _NtQueryInformationProcess query = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64QueryInformationProcess64"); // static _NtQueryInformationProcess query = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64QueryInformationProcess64");
static _NtWow64ReadVirtualMemory64 read = (_NtWow64ReadVirtualMemory64)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64ReadVirtualMemory64"); // static _NtWow64ReadVirtualMemory64 read = (_NtWow64ReadVirtualMemory64)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtWow64ReadVirtualMemory64");
//
PROCESS_BASIC_INFORMATION_WOW64 pbi; // PROCESS_BASIC_INFORMATION_WOW64 pbi;
if (!NT_SUCCESS(query(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION_WOW64), NULL))) // if (!NT_SUCCESS(query(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION_WOW64), NULL)))
return QString(); // return QString();
//
ULONGLONG procParams; // ULONGLONG procParams;
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)((ULONGLONG)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONGLONG), NULL))) // if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)((ULONGLONG)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONGLONG), NULL)))
return QString(); // return QString();
//
UNICODE_STRING64 us; // UNICODE_STRING64 us;
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)(procParams + offset), &us, sizeof(UNICODE_STRING64), NULL))) // if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)(procParams + offset), &us, sizeof(UNICODE_STRING64), NULL)))
return QString(); // return QString();
//
if ((us.Buffer == 0) || (us.Length == 0)) // if ((us.Buffer == 0) || (us.Length == 0))
return QString(); // return QString();
//
s.resize(us.Length / 2); // s.resize(us.Length / 2);
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)us.Buffer, (PVOID64)s.c_str(), s.length() * 2, NULL))) // if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)us.Buffer, (PVOID64)s.c_str(), s.length() * 2, NULL)))
return QString(); // return QString();
} // }
else // Os,Cur,Tar : 64 or 32 // else // Os,Cur,Tar : 64 or 32
{ // {
PROCESS_BASIC_INFORMATION pbi; // PROCESS_BASIC_INFORMATION pbi;
if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL))) // if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)))
return QString(); // return QString();
//
ULONG_PTR procParams; // ULONG_PTR procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONG_PTR), NULL))) // if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONG_PTR), NULL)))
return QString(); // return QString();
//
UNICODE_STRING us; // UNICODE_STRING us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING), NULL))) // if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING), NULL)))
return QString(); // return QString();
//
if ((us.Buffer == 0) || (us.Length == 0)) // if ((us.Buffer == 0) || (us.Length == 0))
return QString(); // return QString();
//
s.resize(us.Length / 2); // s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL))) // if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return QString(); // return QString();
} // }
//
return QString::fromWCharArray(s.c_str()); // return QString::fromWCharArray(s.c_str());
} //}
bool CBoxedProcess::InitProcessInfo() bool CBoxedProcess::InitProcessInfo()
{ {
HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, (DWORD)m_ProcessId); HANDLE ProcessHandle;
if (ProcessHandle == NULL) // try with less rights //ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, (DWORD)m_ProcessId);
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)m_ProcessId); //if (ProcessHandle == NULL) // try with less rights
if (ProcessHandle == NULL) // try with even less rights // ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)m_ProcessId);
//if (ProcessHandle == NULL) // try with even less rights
ProcessHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)m_ProcessId); ProcessHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)m_ProcessId);
if (ProcessHandle == NULL) if (ProcessHandle != NULL)
return false; {
m->Handle = ProcessHandle; m->Handle = ProcessHandle;
InitProcessInfoImpl(ProcessHandle); //InitProcessInfoImpl(ProcessHandle);
}
return true; SB_STATUS Status = m_pBox->Api()->GetProcessInfo(m_ProcessId, &m_ParendPID, &m_ProcessInfo.Flags, &m_bSuspended,
&m_ImagePath, &m_CommandLine, &m_WorkingDir);
return !Status.IsError();
} }
void CBoxedProcess::InitProcessInfoImpl(void* ProcessHandle) //SID SeLocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SYSTEM_RID } };
{ //
PROCESS_BASIC_INFORMATION BasicInformation; //void CBoxedProcess::InitProcessInfoImpl(void* ProcessHandle)
NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &BasicInformation, sizeof(PROCESS_BASIC_INFORMATION), NULL); //{
if (NT_SUCCESS(status)) { // PROCESS_BASIC_INFORMATION BasicInformation;
m_ParendPID = (quint32)BasicInformation.InheritedFromUniqueProcessId; // NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &BasicInformation, sizeof(PROCESS_BASIC_INFORMATION), NULL);
} // if (NT_SUCCESS(status)) {
// m_ParendPID = (quint32)BasicInformation.InheritedFromUniqueProcessId;
TCHAR filename[MAX_PATH]; // }
DWORD dwSize = MAX_PATH; //
if(QueryFullProcessImageNameW(ProcessHandle, 0, filename, &dwSize)) // TCHAR filename[MAX_PATH];
m_ImagePath = QString::fromWCharArray(filename); // DWORD dwSize = MAX_PATH;
// if(QueryFullProcessImageNameW(ProcessHandle, 0, filename, &dwSize))
BOOL isTargetWow64Process = FALSE; // m_ImagePath = QString::fromWCharArray(filename);
IsWow64Process(ProcessHandle, &isTargetWow64Process); //
m_bIsWoW64 = isTargetWow64Process; // BOOL isTargetWow64Process = FALSE;
// IsWow64Process(ProcessHandle, &isTargetWow64Process);
if (m_CommandLine.isEmpty()) // windows 8.1 and later // m_ProcessInfo.IsWoW64 = isTargetWow64Process;
{ //
#define ProcessCommandLineInformation ((PROCESSINFOCLASS)60) // HANDLE TokenHandle = (HANDLE)m_pBox->Api()->QueryProcessInfo(m_ProcessId, 'ptok');
ULONG returnLength = 0; // if (!TokenHandle)
NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, NULL, 0, &returnLength); // NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &TokenHandle);
if (!(status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL && status != STATUS_INFO_LENGTH_MISMATCH)) // if (TokenHandle)
{ // {
PUNICODE_STRING commandLine = (PUNICODE_STRING)malloc(returnLength); // ULONG returnLength;
status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, commandLine, returnLength, &returnLength); //
if (NT_SUCCESS(status) && commandLine->Buffer != NULL) // TOKEN_ELEVATION_TYPE elevationType;
m_CommandLine = QString::fromWCharArray(commandLine->Buffer); // if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenElevationType, &elevationType, sizeof(TOKEN_ELEVATION_TYPE), &returnLength))) {
free(commandLine); // m_ProcessInfo.IsElevated = elevationType == TokenElevationTypeFull;
} // }
#undef ProcessCommandLineInformation //
} // BYTE tokenUserBuff[0x80] = { 0 };
// if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenUser, tokenUserBuff, sizeof(tokenUserBuff), &returnLength))){
if (m_CommandLine.isEmpty()) // fall back to the win 7 method - requirers PROCESS_VM_READ // m_ProcessInfo.IsSystem = EqualSid(((PTOKEN_USER)tokenUserBuff)->User.Sid, &SeLocalSystemSid);
{ // }
m_CommandLine = CBoxedProcess__GetPebString(ProcessHandle, PhpoCommandLine); //
} // ULONG restricted;
// if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenIsRestricted, &restricted, sizeof(ULONG), &returnLength))) {
if (m_WorkingDir.isEmpty()) // m_ProcessInfo.IsRestricted = !!restricted;
{ // }
m_WorkingDir = CBoxedProcess__GetPebString(ProcessHandle, PhpoCurrentDirectory); //
} // BYTE appContainerBuffer[0x80];
// if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenAppContainerSid, appContainerBuffer, sizeof(appContainerBuffer), &returnLength))) {
TestSuspended(); // PTOKEN_APPCONTAINER_INFORMATION appContainerInfo = (PTOKEN_APPCONTAINER_INFORMATION)appContainerBuffer;
} // m_ProcessInfo.IsAppContainer = appContainerInfo->TokenAppContainer != NULL;
// }
//
// CloseHandle(TokenHandle);
// }
//
// if (m_CommandLine.isEmpty()) // windows 8.1 and later
// {
//#define ProcessCommandLineInformation ((PROCESSINFOCLASS)60)
// ULONG returnLength = 0;
// NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, NULL, 0, &returnLength);
// if (!(status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL && status != STATUS_INFO_LENGTH_MISMATCH))
// {
// PUNICODE_STRING commandLine = (PUNICODE_STRING)malloc(returnLength);
// status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, commandLine, returnLength, &returnLength);
// if (NT_SUCCESS(status) && commandLine->Buffer != NULL)
// m_CommandLine = QString::fromWCharArray(commandLine->Buffer);
// free(commandLine);
// }
//#undef ProcessCommandLineInformation
// }
//
// if (m_CommandLine.isEmpty()) // fall back to the win 7 method - requirers PROCESS_VM_READ
// m_CommandLine = CBoxedProcess__GetPebString(ProcessHandle, PhpoCommandLine);
//
// m_WorkingDir = CBoxedProcess__GetPebString(ProcessHandle, PhpoCurrentDirectory);
//
// TestSuspended();
//}
void CBoxedProcess::UpdateProcessInfo() void CBoxedProcess::UpdateProcessInfo()
{ {
@ -294,20 +327,14 @@ void CBoxedProcess::UpdateProcessInfo()
TestSuspended(); TestSuspended();
} }
extern "C" //extern "C"
{ //{
NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess(_In_opt_ HANDLE ProcessHandle, _In_ NTSTATUS ExitStatus); //NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess(_In_opt_ HANDLE ProcessHandle, _In_ NTSTATUS ExitStatus);
NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess(_In_ HANDLE ProcessHandle); //NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess(_In_ HANDLE ProcessHandle);
NTSYSCALLAPI NTSTATUS NTAPI NtResumeProcess(_In_ HANDLE ProcessHandle); //NTSYSCALLAPI NTSTATUS NTAPI NtResumeProcess(_In_ HANDLE ProcessHandle);
//
NTSYSCALLAPI NTSTATUS NTAPI NtGetNextThread(HANDLE ProcessHandle, HANDLE ThreadHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewThreadHandle); //NTSYSCALLAPI NTSTATUS NTAPI NtGetNextThread(HANDLE ProcessHandle, HANDLE ThreadHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewThreadHandle);
//}
#define OBJ_KERNEL_EXCLUSIVE 0x00010000L
#define OBJ_VALID_PRIVATE_ATTRIBUTES 0x00010000L
#define OBJ_ALL_VALID_ATTRIBUTES (OBJ_VALID_PRIVATE_ATTRIBUTES | OBJ_VALID_ATTRIBUTES)
}
//#include <TlHelp32.h>
SB_STATUS CBoxedProcess::Terminate() SB_STATUS CBoxedProcess::Terminate()
{ {
@ -336,60 +363,74 @@ bool CBoxedProcess::IsTerminated(quint64 forMs) const
return ::GetTickCount64() - m_uTerminated > forMs; return ::GetTickCount64() - m_uTerminated > forMs;
} }
SB_STATUS CBoxedProcess::SetSuspend(bool bSet) SB_STATUS CBoxedProcess::SetSuspended(bool bSuspended)
{ {
HANDLE ProcessHandle = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, (DWORD)m_ProcessId); SB_STATUS Status = m_pBox->Api()->SetSuspended(m_ProcessId, bSuspended);
if (ProcessHandle != INVALID_HANDLE_VALUE) if (!Status.IsError())
{ m_bSuspended = bSuspended;
NTSTATUS status; return Status;
if(bSet)
status = NtSuspendProcess(ProcessHandle);
else
status = NtResumeProcess(ProcessHandle);
NtClose(ProcessHandle);
if (!NT_SUCCESS(status))
return SB_ERR(status);
TestSuspended();
return SB_OK;
}
return SB_ERR();
} }
bool CBoxedProcess::TestSuspended() bool CBoxedProcess::TestSuspended()
{ {
int iSuspended = 0; m_pBox->Api()->GetProcessInfo(m_ProcessId, NULL, NULL, &m_bSuspended);
int iRunning = 0;
for (HANDLE hThread = NULL;;)
{
HANDLE nNextThread = NULL;
NTSTATUS status = NtGetNextThread(m->Handle, hThread, THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME, 0, 0, &nNextThread);
if (hThread) NtClose(hThread);
if (!NT_SUCCESS(status))
break;
hThread = nNextThread;
ULONG IsTerminated = 0;
if (!NT_SUCCESS(NtQueryInformationThread(hThread, ThreadIsTerminated, &IsTerminated, sizeof(ULONG), NULL)) || IsTerminated)
continue;
ULONG SuspendCount = 0;
status = NtQueryInformationThread(hThread, (THREADINFOCLASS)35/*ThreadSuspendCount*/, &SuspendCount, sizeof(ULONG), NULL);
if (status == STATUS_INVALID_INFO_CLASS) { // windows 7
SuspendCount = SuspendThread(hThread);
ResumeThread(hThread);
}
if (SuspendCount > 0)
iSuspended++;
else
iRunning++;
}
m_bSuspended = iSuspended > 0 && iRunning == 0;
return m_bSuspended; return m_bSuspended;
} }
//SB_STATUS CBoxedProcess::SetSuspended(bool bSet)
//{
// HANDLE ProcessHandle = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, (DWORD)m_ProcessId);
// if (ProcessHandle != INVALID_HANDLE_VALUE)
// {
// NTSTATUS status;
// if(bSet)
// status = NtSuspendProcess(ProcessHandle);
// else
// status = NtResumeProcess(ProcessHandle);
// NtClose(ProcessHandle);
//
// if (!NT_SUCCESS(status))
// return SB_ERR(status);
// TestSuspended();
// return SB_OK;
// }
// return SB_ERR();
//}
//
//bool CBoxedProcess::TestSuspended()
//{
// int iSuspended = 0;
// int iRunning = 0;
//
// for (HANDLE hThread = NULL;;)
// {
// HANDLE nNextThread = NULL;
// NTSTATUS status = NtGetNextThread(m->Handle, hThread, THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME, 0, 0, &nNextThread);
// if (hThread) NtClose(hThread);
// if (!NT_SUCCESS(status))
// break;
// hThread = nNextThread;
//
// ULONG IsTerminated = 0;
// if (!NT_SUCCESS(NtQueryInformationThread(hThread, ThreadIsTerminated, &IsTerminated, sizeof(ULONG), NULL)) || IsTerminated)
// continue;
//
// ULONG SuspendCount = 0;
// status = NtQueryInformationThread(hThread, (THREADINFOCLASS)35/*ThreadSuspendCount*/, &SuspendCount, sizeof(ULONG), NULL);
// if (status == STATUS_INVALID_INFO_CLASS) { // windows 7
// SuspendCount = SuspendThread(hThread);
// ResumeThread(hThread);
// }
// if (SuspendCount > 0)
// iSuspended++;
// else
// iRunning++;
// }
//
// m_bSuspended = iSuspended > 0 && iRunning == 0;
// return m_bSuspended;
//}
void CBoxedProcess::ResolveSymbols(const QVector<quint64>& Addresses) void CBoxedProcess::ResolveSymbols(const QVector<quint64>& Addresses)
{ {
foreach(quint64 Address, Addresses) foreach(quint64 Address, Addresses)

View File

@ -47,11 +47,16 @@ public:
virtual bool IsTerminated(quint64 forMs = 0) const; virtual bool IsTerminated(quint64 forMs = 0) const;
virtual void SetTerminated(); virtual void SetTerminated();
virtual SB_STATUS SetSuspend(bool bSet); virtual SB_STATUS SetSuspended(bool bSuspended);
//virtual bool IsSuspended() const; //virtual bool IsSuspended() const;
virtual bool TestSuspended(); virtual bool TestSuspended();
virtual bool IsWoW64() const { return m_bIsWoW64; } virtual bool IsWoW64() const { return m_ProcessInfo.IsWoW64; }
virtual bool HasElevatedToken() const { return m_ProcessInfo.IsElevated; }
virtual bool HasSystemToken() const { return m_ProcessInfo.IsSystem; }
virtual bool HasRestrictedToken() const { return m_ProcessInfo.IsRestricted; }
virtual bool HasAppContainerToken() const { return m_ProcessInfo.IsAppContainer; }
virtual QString GetBoxName() const { return m_BoxName; } virtual QString GetBoxName() const { return m_BoxName; }
virtual class CSandBox* GetBoxPtr() const { return m_pBox; } virtual class CSandBox* GetBoxPtr() const { return m_pBox; }
@ -65,7 +70,7 @@ public slots:
protected: protected:
friend class CSbieAPI; friend class CSbieAPI;
virtual void InitProcessInfoImpl(void* ProcessHandle); //virtual void InitProcessInfoImpl(void* ProcessHandle);
quint32 m_ProcessId; quint32 m_ProcessId;
QString m_BoxName; QString m_BoxName;
@ -81,7 +86,21 @@ protected:
quint32 m_ReturnCode; quint32 m_ReturnCode;
quint64 m_uTerminated; quint64 m_uTerminated;
bool m_bSuspended; bool m_bSuspended;
bool m_bIsWoW64; // Flags
union
{
quint32 Flags;
struct
{
quint32
IsWoW64 : 1,
IsElevated : 1,
IsSystem : 1,
IsRestricted : 1,
IsAppContainer : 1,
Spare : 27;
};
} m_ProcessInfo;
class CSandBox* m_pBox; class CSandBox* m_pBox;

View File

@ -160,6 +160,11 @@ SB_STATUS CSandBox::TerminateAll()
return m_pAPI->TerminateAll(m_Name); return m_pAPI->TerminateAll(m_Name);
} }
SB_STATUS CSandBox::SetSuspendedAll(bool bSuspended)
{
return m_pAPI->SetSuspendedAll(m_Name, bSuspended);
}
bool CSandBox::IsEmpty() const bool CSandBox::IsEmpty() const
{ {
return !QFile::exists(m_FilePath); return !QFile::exists(m_FilePath);

View File

@ -55,6 +55,7 @@ public:
virtual SB_STATUS RunStart(const QString& Command, bool Elevated = false); virtual SB_STATUS RunStart(const QString& Command, bool Elevated = false);
virtual SB_STATUS RunSandboxed(const QString& Command); virtual SB_STATUS RunSandboxed(const QString& Command);
virtual SB_STATUS TerminateAll(); virtual SB_STATUS TerminateAll();
virtual SB_STATUS SetSuspendedAll(bool bSuspended);
virtual void OpenBox() {} virtual void OpenBox() {}
virtual void CloseBox() {} virtual void CloseBox() {}

View File

@ -1585,6 +1585,40 @@ SB_STATUS CSbieAPI::UpdateProcessInfo(const CBoxedProcessPtr& pProcess)
return SB_OK; return SB_OK;
} }
SB_STATUS CSbieAPI::GetProcessInfo(quint32 ProcessId, quint32* pParentId, quint32* pInfo, bool* pSuspended, QString* pImagePath, QString* pCommandLine, QString* pWorkingDir)
{
PROCESS_GET_INFO_REQ req;
req.h.length = sizeof(PROCESS_GET_INFO_REQ);
req.h.msgid = MSGID_PROCESS_GET_INFO;
req.dwProcessId = ProcessId;
req.dwInfoClasses = 0;
if(pParentId || pInfo)
req.dwInfoClasses |= SBIE_PROCESS_BASIC_INFO;
if(pSuspended)
req.dwInfoClasses |= SBIE_PROCESS_EXEC_INFO;
if(pImagePath || pCommandLine || pWorkingDir)
req.dwInfoClasses |= SBIE_PROCESS_PATHS_INFO;
SScoped<PROCESS_INFO_RPL> rpl;
SB_STATUS Status = CallServer(&req.h, &rpl);
if (!Status || !rpl)
return Status;
if (!NT_SUCCESS(rpl->h.status))
return SB_ERR(rpl->h.status);
if (pParentId) *pParentId = rpl->dwParentId;
if (pInfo) *pInfo = rpl->dwInfo;
if (pSuspended) *pSuspended = rpl->bSuspended;
if (pImagePath && rpl->app_ofs && rpl->app_len > 0) *pImagePath = QString::fromWCharArray((WCHAR*)((ULONG_PTR)rpl.Value() + rpl->app_ofs), rpl->app_len);
if (pCommandLine && rpl->cmd_ofs && rpl->cmd_len > 0) *pCommandLine = QString::fromWCharArray((WCHAR*)((ULONG_PTR)rpl.Value() + rpl->cmd_ofs), rpl->cmd_len);
if (pWorkingDir && rpl->dir_ofs && rpl->dir_len > 0) *pWorkingDir = QString::fromWCharArray((WCHAR*)((ULONG_PTR)rpl.Value() + rpl->dir_ofs), rpl->dir_len);
return SB_OK;
}
CSandBoxPtr CSbieAPI::GetBoxByProcessId(quint32 ProcessId) const CSandBoxPtr CSbieAPI::GetBoxByProcessId(quint32 ProcessId) const
{ {
CBoxedProcessPtr pProcess = m_BoxedProxesses.value(ProcessId); CBoxedProcessPtr pProcess = m_BoxedProxesses.value(ProcessId);
@ -1667,6 +1701,42 @@ SB_STATUS CSbieAPI::Terminate(quint32 ProcessId)
return Status; return Status;
} }
SB_STATUS CSbieAPI::SetSuspendedAll(const QString& BoxName, bool bSuspended)
{
PROCESS_SUSPEND_RESUME_ALL_REQ req;
req.h.length = sizeof(PROCESS_SUSPEND_RESUME_ALL_REQ);
req.h.msgid = MSGID_PROCESS_SUSPEND_RESUME_ALL;
req.session_id = -1;
BoxName.toWCharArray(req.boxname); // fix-me: potential overflow
req.boxname[BoxName.size()] = L'\0';
req.suspend = bSuspended ? TRUE : FALSE;
SScoped<MSG_HEADER> rpl;
SB_STATUS Status = CallServer(&req.h, &rpl);
if (!Status || !rpl)
return Status;
if(rpl->status != 0)
Status = SB_ERR(rpl->status);
return Status;
}
SB_STATUS CSbieAPI::SetSuspended(quint32 ProcessId, bool bSuspended)
{
PROCESS_SUSPEND_RESUME_ONE_REQ req;
req.h.length = sizeof(PROCESS_SUSPEND_RESUME_ONE_REQ);
req.h.msgid = MSGID_PROCESS_SUSPEND_RESUME_ONE;
req.pid = ProcessId;
req.suspend = bSuspended ? TRUE : FALSE;
SScoped<MSG_HEADER> rpl;
SB_STATUS Status = CallServer(&req.h, &rpl);
if (!Status || !rpl)
return Status;
if (rpl->status != 0)
Status = SB_ERR(rpl->status);
return Status;
}
LONG CSbieAPI__OpenDeviceMap(SSbieAPI* m, HANDLE *DirectoryHandle) LONG CSbieAPI__OpenDeviceMap(SSbieAPI* m, HANDLE *DirectoryHandle)
{ {
__declspec(align(8)) ULONG64 ResultHandle; __declspec(align(8)) ULONG64 ResultHandle;

View File

@ -217,11 +217,16 @@ protected:
virtual SB_STATUS TerminateAll(const QString& BoxName); virtual SB_STATUS TerminateAll(const QString& BoxName);
virtual SB_STATUS Terminate(quint32 ProcessId); virtual SB_STATUS Terminate(quint32 ProcessId);
virtual SB_STATUS SetSuspendedAll(const QString& BoxName, bool bSuspended);
virtual SB_STATUS SetSuspended(quint32 ProcessId, bool bSuspended);
virtual SB_STATUS RunSandboxed(const QString& BoxName, const QString& Command, QString WrkDir = QString(), quint32 Flags = 0); virtual SB_STATUS RunSandboxed(const QString& BoxName, const QString& Command, QString WrkDir = QString(), quint32 Flags = 0);
virtual SB_STATUS UpdateBoxPaths(CSandBox* pSandBox); virtual SB_STATUS UpdateBoxPaths(CSandBox* pSandBox);
virtual SB_STATUS UpdateProcessInfo(const CBoxedProcessPtr& pProcess); virtual SB_STATUS UpdateProcessInfo(const CBoxedProcessPtr& pProcess);
virtual SB_STATUS GetProcessInfo(quint32 ProcessId, quint32* pParentId = NULL, quint32* pInfo = NULL, bool* pSuspended = NULL, QString* pImagePath = NULL, QString* pCommandLine = NULL, QString* pWorkingDir = NULL);
virtual void GetUserPaths(); virtual void GetUserPaths();
virtual QString GetDeviceMap(); virtual QString GetDeviceMap();

View File

@ -174,8 +174,12 @@ void CScriptManager::LoadIssues(const QString& IssueDir)
Translation = ReadFileAsString(IssueDir + "lang_" + LangAux + ".json"); Translation = ReadFileAsString(IssueDir + "lang_" + LangAux + ".json");
} }
if(!Translation.isEmpty()) if (!Translation.isEmpty()) {
m_Translation = QJsonDocument::fromJson(Translation.toUtf8()).toVariant().toMap(); QJsonParseError error;
m_Translation = QJsonDocument::fromJson(Translation.toUtf8(), &error).toVariant().toMap();
if (m_Translation.isEmpty())
qDebug() << error.errorString() << Translation.mid(error.offset, 100);
}
} }
QString CScriptManager::GetIssueDir(C7zFileEngineHandler& IssueFS, QDateTime* pDate) QString CScriptManager::GetIssueDir(C7zFileEngineHandler& IssueFS, QDateTime* pDate)

View File

@ -954,7 +954,7 @@ bool COnlineUpdater::RunInstaller(bool bSilent)
bool COnlineUpdater::RunInstaller2(const QString& FilePath, bool bSilent) bool COnlineUpdater::RunInstaller2(const QString& FilePath, bool bSilent)
{ {
if (bSilent) if (bSilent && !theGUI->IsFullyPortable())
{ {
QStringList Params; QStringList Params;
Params.append("run_setup"); Params.append("run_setup");
@ -975,8 +975,11 @@ bool COnlineUpdater::RunInstaller2(const QString& FilePath, bool bSilent)
std::wstring wFile = QString(FilePath).replace("/", "\\").toStdWString(); std::wstring wFile = QString(FilePath).replace("/", "\\").toStdWString();
std::wstring wParams; std::wstring wParams;
if(theGUI->IsFullyPortable())
wParams = L"/PORTABLE=1";
#ifndef _DEBUG #ifndef _DEBUG
wParams = L"/SILENT"; else
wParams = L"/SILENT";
#endif #endif
return RunElevated(wFile, wParams) == 0; return RunElevated(wFile, wParams) == 0;

View File

@ -13,7 +13,6 @@ typedef long NTSTATUS;
CSbieProcess::CSbieProcess(quint32 ProcessId, class CSandBox* pBox) CSbieProcess::CSbieProcess(quint32 ProcessId, class CSandBox* pBox)
: CBoxedProcess(ProcessId, pBox) : CBoxedProcess(ProcessId, pBox)
{ {
m_ProcessInfo.Flags = 0;
} }
QString CSbieProcess::ImageTypeToStr(quint32 type) QString CSbieProcess::ImageTypeToStr(quint32 type)
@ -123,40 +122,7 @@ QString CSbieProcess::GetStatusStr() const
return Status; return Status;
} }
SID SeLocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SYSTEM_RID } }; //void CSbieProcess::InitProcessInfoImpl(void* ProcessHandle)
//{
void CSbieProcess::InitProcessInfoImpl(void* ProcessHandle) // CBoxedProcess::InitProcessInfoImpl(ProcessHandle);
{ //}
CBoxedProcess::InitProcessInfoImpl(ProcessHandle);
HANDLE TokenHandle = (HANDLE)m_pBox->Api()->QueryProcessInfo(m_ProcessId, 'ptok');
if (!TokenHandle)
NtOpenProcessToken(ProcessHandle, TOKEN_QUERY, &TokenHandle);
if (TokenHandle)
{
ULONG returnLength;
TOKEN_ELEVATION_TYPE elevationType;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenElevationType, &elevationType, sizeof(TOKEN_ELEVATION_TYPE), &returnLength))) {
m_ProcessInfo.IsElevated = elevationType == TokenElevationTypeFull;
}
BYTE tokenUserBuff[0x80] = { 0 };
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenUser, tokenUserBuff, sizeof(tokenUserBuff), &returnLength))){
m_ProcessInfo.IsSystem = EqualSid(((PTOKEN_USER)tokenUserBuff)->User.Sid, &SeLocalSystemSid);
}
ULONG restricted;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenIsRestricted, &restricted, sizeof(ULONG), &returnLength))) {
m_ProcessInfo.IsRestricted = !!restricted;
}
BYTE appContainerBuffer[0x80];
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, (TOKEN_INFORMATION_CLASS)TokenAppContainerSid, appContainerBuffer, sizeof(appContainerBuffer), &returnLength))) {
PTOKEN_APPCONTAINER_INFORMATION appContainerInfo = (PTOKEN_APPCONTAINER_INFORMATION)appContainerBuffer;
m_ProcessInfo.IsAppContainer = appContainerInfo->TokenAppContainer != NULL;
}
CloseHandle(TokenHandle);
}
}

View File

@ -27,29 +27,9 @@ public:
static QString ImageTypeToStr(quint32 type); static QString ImageTypeToStr(quint32 type);
virtual bool HasElevatedToken() { return m_ProcessInfo.IsElevated; }
virtual bool HasSystemToken() { return m_ProcessInfo.IsSystem; }
virtual bool HasRestrictedToken() { return m_ProcessInfo.IsRestricted; }
virtual bool HasAppContainerToken() { return m_ProcessInfo.IsAppContainer; }
protected: protected:
virtual void InitProcessInfoImpl(void* ProcessHandle); //virtual void InitProcessInfoImpl(void* ProcessHandle);
QMap<int, int> m_RememberedActions; QMap<int, int> m_RememberedActions;
// Flags
union
{
quint32 Flags;
struct
{
quint32
IsElevated : 1,
IsSystem : 1,
IsRestricted : 1,
IsAppContainer : 1,
Spare : 28;
};
} m_ProcessInfo;
}; };

View File

@ -1699,9 +1699,9 @@ void CSbieView::OnProcessAction(QAction* Action, const QList<CBoxedProcessPtr>&
else if (Action == m_pMenuMarkLeader) else if (Action == m_pMenuMarkLeader)
pProcess.objectCast<CSbieProcess>()->SetLeaderProgram(m_pMenuMarkLeader->isChecked()); pProcess.objectCast<CSbieProcess>()->SetLeaderProgram(m_pMenuMarkLeader->isChecked());
else if (Action == m_pMenuSuspend) else if (Action == m_pMenuSuspend)
Results.append(pProcess->SetSuspend(true)); Results.append(pProcess->SetSuspended(true));
else if (Action == m_pMenuResume) else if (Action == m_pMenuResume)
Results.append(pProcess->SetSuspend(false)); Results.append(pProcess->SetSuspended(false));
} }
theGUI->CheckResults(Results, this); theGUI->CheckResults(Results, this);