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-
### Added
- 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 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 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 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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,10 +37,21 @@
#include "core/drv/api_defs.h"
#include <sddl.h>
#include "sbieiniserver.h"
#include <string>
#define SECONDS(n64) (((LONGLONG)n64) * 10000000L)
#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
@ -65,19 +76,17 @@ MSG_HEADER *ProcessServer::Handler(void *_this, MSG_HEADER *msg)
if (msg->msgid == MSGID_PROCESS_CHECK_INIT_COMPLETE)
return pThis->CheckInitCompleteHandler();
HANDLE idProcess = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
if (msg->msgid == MSGID_PROCESS_KILL_ONE)
return pThis->KillOneHandler(idProcess, msg);
return pThis->KillOneHandler(msg);
if (msg->msgid == MSGID_PROCESS_KILL_ALL)
return pThis->KillAllHandler(idProcess, msg);
return pThis->KillAllHandler(msg);
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)
return pThis->OpenDeviceMap(idProcess, msg);
return pThis->OpenDeviceMap(msg);
if (msg->msgid == MSGID_PROCESS_RUN_SANDBOXED)
return pThis->RunSandboxedHandler(msg);
@ -85,6 +94,15 @@ MSG_HEADER *ProcessServer::Handler(void *_this, MSG_HEADER *msg)
if (msg->msgid == MSGID_PROCESS_RUN_UPDATER)
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;
}
@ -131,9 +149,9 @@ BOOL ProcessServer::KillProcess(ULONG ProcessId)
//---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::KillOneHandler(
HANDLE CallerProcessId, MSG_HEADER *msg)
MSG_HEADER *ProcessServer::KillOneHandler(MSG_HEADER *msg)
{
HANDLE CallerProcessId;
ULONG TargetSessionId;
WCHAR TargetBoxName[BOXNAME_COUNT];
ULONG CallerSessionId;
@ -162,6 +180,8 @@ MSG_HEADER *ProcessServer::KillOneHandler(
// get session id for caller. if sandboxed, get also box name
//
CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
status = SbieApi_QueryProcess(CallerProcessId, CallerBoxName,
NULL, NULL, &CallerSessionId);
@ -202,9 +222,9 @@ MSG_HEADER *ProcessServer::KillOneHandler(
//---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::KillAllHandler(
HANDLE CallerProcessId, MSG_HEADER *msg)
MSG_HEADER *ProcessServer::KillAllHandler(MSG_HEADER *msg)
{
HANDLE CallerProcessId;
ULONG TargetSessionId;
WCHAR TargetBoxName[BOXNAME_COUNT];
ULONG CallerSessionId;
@ -229,6 +249,8 @@ MSG_HEADER *ProcessServer::KillAllHandler(
// get session id for caller. if sandboxed, get also box name
//
CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
status = SbieApi_QueryProcess(CallerProcessId, CallerBoxName,
NULL, NULL, &CallerSessionId);
@ -333,8 +355,7 @@ NTSTATUS ProcessServer::KillAllHelper(const WCHAR *BoxName, ULONG SessionId, BOO
//---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::SetDeviceMap(
HANDLE CallerProcessId, MSG_HEADER *msg)
MSG_HEADER *ProcessServer::SetDeviceMap(MSG_HEADER *msg)
{
//
// 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
//
NTSTATUS status = STATUS_SUCCESS;
PROCESS_SET_DEVICE_MAP_REQ *req = (PROCESS_SET_DEVICE_MAP_REQ *)msg;
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)(ULONG_PTR)CallerProcessId, 0))
status = STATUS_ACCESS_DENIED;
HANDLE CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
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 {
HANDLE CallerProcessHandle = OpenProcess(
PROCESS_SET_INFORMATION | PROCESS_DUP_HANDLE,
FALSE, (ULONG)(ULONG_PTR)CallerProcessId);
if (! CallerProcessHandle)
PROCESS_DEVICEMAP_INFORMATION info;
BOOL ok = DuplicateHandle(
CallerProcessHandle, (HANDLE)(ULONG_PTR)req->DirectoryHandle,
NtCurrentProcess(), &info.Set.DirectoryHandle,
DIRECTORY_TRAVERSE, FALSE, 0);
if (! ok)
status = RtlNtStatusToDosError(GetLastError());
else {
PROCESS_DEVICEMAP_INFORMATION info;
BOOL ok = DuplicateHandle(
CallerProcessHandle, (HANDLE)(ULONG_PTR)req->DirectoryHandle,
NtCurrentProcess(), &info.Set.DirectoryHandle,
DIRECTORY_TRAVERSE, FALSE, 0);
if (! ok)
status = RtlNtStatusToDosError(GetLastError());
else {
status = NtSetInformationProcess(
CallerProcessHandle, ProcessDeviceMap,
&info, sizeof(info.Set));
status = NtSetInformationProcess(
CallerProcessHandle, ProcessDeviceMap,
&info, sizeof(info.Set));
NtClose(info.Set.DirectoryHandle);
}
NtClose(CallerProcessHandle);
NtClose(info.Set.DirectoryHandle);
}
NtClose(CallerProcessHandle);
}
return SHORT_REPLY(status);
@ -390,8 +408,7 @@ MSG_HEADER *ProcessServer::SetDeviceMap(
//---------------------------------------------------------------------------
MSG_HEADER *ProcessServer::OpenDeviceMap(
HANDLE CallerProcessId, MSG_HEADER *msg)
MSG_HEADER *ProcessServer::OpenDeviceMap(MSG_HEADER *msg)
{
//
// 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.
//
NTSTATUS status = STATUS_SUCCESS;
PROCESS_OPEN_DEVICE_MAP_REQ *req = (PROCESS_OPEN_DEVICE_MAP_REQ *)msg;
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)(ULONG_PTR)CallerProcessId, 0))
status = STATUS_ACCESS_DENIED;
HANDLE CallerProcessId = (HANDLE)(ULONG_PTR)PipeServer::GetCallerProcessId();
else {
if (! SbieApi_QueryProcessInfo((HANDLE)(ULONG_PTR)CallerProcessId, 0))
return SHORT_REPLY(STATUS_ACCESS_DENIED);
HANDLE LocalDirectoryHandle;
UNICODE_STRING objname;
OBJECT_ATTRIBUTES objattrs;
NTSTATUS status = STATUS_SUCCESS;
HANDLE LocalDirectoryHandle;
UNICODE_STRING objname;
OBJECT_ATTRIBUTES objattrs;
RtlInitUnicodeString(&objname, req->DirectoryName);
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
RtlInitUnicodeString(&objname, req->DirectoryName);
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtOpenDirectoryObject(
&LocalDirectoryHandle, DIRECTORY_TRAVERSE, &objattrs);
status = NtOpenDirectoryObject(
&LocalDirectoryHandle, DIRECTORY_TRAVERSE, &objattrs);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status)) {
HANDLE CallerProcessHandle = OpenProcess(PROCESS_DUP_HANDLE
| PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
FALSE, (ULONG)(ULONG_PTR)CallerProcessId);
if (! CallerProcessHandle)
HANDLE CallerProcessHandle = OpenProcess(PROCESS_DUP_HANDLE
| PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
FALSE, (ULONG)(ULONG_PTR)CallerProcessId);
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());
else {
HANDLE RemoteDirectoryHandle;
BOOL ok = DuplicateHandle(
NtCurrentProcess(), LocalDirectoryHandle,
CallerProcessHandle, (HANDLE *)&RemoteDirectoryHandle,
DIRECTORY_TRAVERSE, FALSE, 0);
ok = WriteProcessMemory(
CallerProcessHandle, (void *)req->DirectoryHandlePtr,
&RemoteDirectoryHandle, sizeof(HANDLE), NULL);
if (! ok)
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);
@ -543,7 +557,8 @@ MSG_HEADER *ProcessServer::RunSandboxedHandler(MSG_HEADER *msg)
//ULONG flags = 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();
// SbieApi_LogEx(SessionId, 6004, L"%S", boxname);
// const WCHAR* strings[] = { boxname, L"Breakout*", NULL };
// SbieApi_LogMsgExt(SessionId, 6004, strings);
// lvl = 0x66;
// err = ERROR_NOT_SUPPORTED;
// goto end;
@ -1635,3 +1650,521 @@ MSG_HEADER *ProcessServer::RunUpdaterHandler(MSG_HEADER *msg)
}
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);
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);
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
@ -81,6 +81,16 @@ protected:
//
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;
//---------------------------------------------------------------------------
// 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_OPEN_DEVICE_MAP 0x1207
#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_START 0x1301

View File

@ -27,7 +27,7 @@ typedef long NTSTATUS;
#include <windows.h>
#include "..\..\Sandboxie\common\win32_ntddk.h"
#include <psapi.h> // For access to GetModuleFileNameEx
//#include <psapi.h> // For access to GetModuleFileNameEx
#include <winnt.h>
@ -56,7 +56,7 @@ CBoxedProcess::CBoxedProcess(quint32 ProcessId, class CSandBox* pBox)
m_uTerminated = 0;
m_bSuspended = false;
m_bIsWoW64 = false;
m_ProcessInfo.Flags = 0;
}
CBoxedProcess::~CBoxedProcess()
@ -67,222 +67,255 @@ CBoxedProcess::~CBoxedProcess()
}
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);
QString CBoxedProcess__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 QString();
}
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 QString();
ULONG procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)peb32 + processParametersOffset), &procParams, sizeof(ULONG), NULL)))
return QString();
UNICODE_STRING32 us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING32), NULL)))
return QString();
if ((us.Buffer == 0) || (us.Length == 0))
return QString();
s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return QString();
}
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 QString();
ULONGLONG procParams;
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)((ULONGLONG)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONGLONG), NULL)))
return QString();
UNICODE_STRING64 us;
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)(procParams + offset), &us, sizeof(UNICODE_STRING64), NULL)))
return QString();
if ((us.Buffer == 0) || (us.Length == 0))
return QString();
s.resize(us.Length / 2);
if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)us.Buffer, (PVOID64)s.c_str(), s.length() * 2, NULL)))
return QString();
}
else // Os,Cur,Tar : 64 or 32
{
PROCESS_BASIC_INFORMATION pbi;
if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)))
return QString();
ULONG_PTR procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONG_PTR), NULL)))
return QString();
UNICODE_STRING us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING), NULL)))
return QString();
if ((us.Buffer == 0) || (us.Length == 0))
return QString();
s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return QString();
}
return QString::fromWCharArray(s.c_str());
}
//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);
//
//
//QString CBoxedProcess__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 QString();
// }
//
// 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 QString();
//
// ULONG procParams;
// if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)peb32 + processParametersOffset), &procParams, sizeof(ULONG), NULL)))
// return QString();
//
// UNICODE_STRING32 us;
// if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING32), NULL)))
// return QString();
//
// if ((us.Buffer == 0) || (us.Length == 0))
// return QString();
//
// s.resize(us.Length / 2);
// if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
// return QString();
// }
// 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 QString();
//
// ULONGLONG procParams;
// if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)((ULONGLONG)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONGLONG), NULL)))
// return QString();
//
// UNICODE_STRING64 us;
// if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)(procParams + offset), &us, sizeof(UNICODE_STRING64), NULL)))
// return QString();
//
// if ((us.Buffer == 0) || (us.Length == 0))
// return QString();
//
// s.resize(us.Length / 2);
// if (!NT_SUCCESS(read(ProcessHandle, (PVOID64)us.Buffer, (PVOID64)s.c_str(), s.length() * 2, NULL)))
// return QString();
// }
// else // Os,Cur,Tar : 64 or 32
// {
// PROCESS_BASIC_INFORMATION pbi;
// if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)))
// return QString();
//
// ULONG_PTR procParams;
// if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONG_PTR), NULL)))
// return QString();
//
// UNICODE_STRING us;
// if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING), NULL)))
// return QString();
//
// if ((us.Buffer == 0) || (us.Length == 0))
// return QString();
//
// s.resize(us.Length / 2);
// if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
// return QString();
// }
//
// return QString::fromWCharArray(s.c_str());
//}
bool CBoxedProcess::InitProcessInfo()
{
HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, (DWORD)m_ProcessId);
if (ProcessHandle == NULL) // try with less rights
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)m_ProcessId);
if (ProcessHandle == NULL) // try with even less rights
HANDLE ProcessHandle;
//ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, (DWORD)m_ProcessId);
//if (ProcessHandle == NULL) // try with 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);
if (ProcessHandle == NULL)
return false;
m->Handle = ProcessHandle;
if (ProcessHandle != NULL)
{
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)
{
PROCESS_BASIC_INFORMATION BasicInformation;
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))
m_ImagePath = QString::fromWCharArray(filename);
BOOL isTargetWow64Process = FALSE;
IsWow64Process(ProcessHandle, &isTargetWow64Process);
m_bIsWoW64 = isTargetWow64Process;
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);
}
if (m_WorkingDir.isEmpty())
{
m_WorkingDir = CBoxedProcess__GetPebString(ProcessHandle, PhpoCurrentDirectory);
}
TestSuspended();
}
//SID SeLocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SYSTEM_RID } };
//
//void CBoxedProcess::InitProcessInfoImpl(void* ProcessHandle)
//{
// PROCESS_BASIC_INFORMATION BasicInformation;
// 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))
// m_ImagePath = QString::fromWCharArray(filename);
//
// BOOL isTargetWow64Process = FALSE;
// IsWow64Process(ProcessHandle, &isTargetWow64Process);
// m_ProcessInfo.IsWoW64 = isTargetWow64Process;
//
// 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);
// }
//
// 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()
{
@ -294,20 +327,14 @@ void CBoxedProcess::UpdateProcessInfo()
TestSuspended();
}
extern "C"
{
NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess(_In_opt_ HANDLE ProcessHandle, _In_ NTSTATUS ExitStatus);
NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess(_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);
#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>
//extern "C"
//{
//NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess(_In_opt_ HANDLE ProcessHandle, _In_ NTSTATUS ExitStatus);
//NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess(_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);
//}
SB_STATUS CBoxedProcess::Terminate()
{
@ -336,60 +363,74 @@ bool CBoxedProcess::IsTerminated(quint64 forMs) const
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);
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();
SB_STATUS Status = m_pBox->Api()->SetSuspended(m_ProcessId, bSuspended);
if (!Status.IsError())
m_bSuspended = bSuspended;
return Status;
}
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;
m_pBox->Api()->GetProcessInfo(m_ProcessId, NULL, NULL, &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)
{
foreach(quint64 Address, Addresses)

View File

@ -47,11 +47,16 @@ public:
virtual bool IsTerminated(quint64 forMs = 0) const;
virtual void SetTerminated();
virtual SB_STATUS SetSuspend(bool bSet);
virtual SB_STATUS SetSuspended(bool bSuspended);
//virtual bool IsSuspended() const;
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 class CSandBox* GetBoxPtr() const { return m_pBox; }
@ -65,7 +70,7 @@ public slots:
protected:
friend class CSbieAPI;
virtual void InitProcessInfoImpl(void* ProcessHandle);
//virtual void InitProcessInfoImpl(void* ProcessHandle);
quint32 m_ProcessId;
QString m_BoxName;
@ -81,7 +86,21 @@ protected:
quint32 m_ReturnCode;
quint64 m_uTerminated;
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;

View File

@ -160,6 +160,11 @@ SB_STATUS CSandBox::TerminateAll()
return m_pAPI->TerminateAll(m_Name);
}
SB_STATUS CSandBox::SetSuspendedAll(bool bSuspended)
{
return m_pAPI->SetSuspendedAll(m_Name, bSuspended);
}
bool CSandBox::IsEmpty() const
{
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 RunSandboxed(const QString& Command);
virtual SB_STATUS TerminateAll();
virtual SB_STATUS SetSuspendedAll(bool bSuspended);
virtual void OpenBox() {}
virtual void CloseBox() {}

View File

@ -1585,6 +1585,40 @@ SB_STATUS CSbieAPI::UpdateProcessInfo(const CBoxedProcessPtr& pProcess)
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
{
CBoxedProcessPtr pProcess = m_BoxedProxesses.value(ProcessId);
@ -1667,6 +1701,42 @@ SB_STATUS CSbieAPI::Terminate(quint32 ProcessId)
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)
{
__declspec(align(8)) ULONG64 ResultHandle;

View File

@ -217,11 +217,16 @@ protected:
virtual SB_STATUS TerminateAll(const QString& BoxName);
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 UpdateBoxPaths(CSandBox* pSandBox);
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 QString GetDeviceMap();

View File

@ -174,8 +174,12 @@ void CScriptManager::LoadIssues(const QString& IssueDir)
Translation = ReadFileAsString(IssueDir + "lang_" + LangAux + ".json");
}
if(!Translation.isEmpty())
m_Translation = QJsonDocument::fromJson(Translation.toUtf8()).toVariant().toMap();
if (!Translation.isEmpty()) {
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)

View File

@ -954,7 +954,7 @@ bool COnlineUpdater::RunInstaller(bool bSilent)
bool COnlineUpdater::RunInstaller2(const QString& FilePath, bool bSilent)
{
if (bSilent)
if (bSilent && !theGUI->IsFullyPortable())
{
QStringList Params;
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 wParams;
if(theGUI->IsFullyPortable())
wParams = L"/PORTABLE=1";
#ifndef _DEBUG
wParams = L"/SILENT";
else
wParams = L"/SILENT";
#endif
return RunElevated(wFile, wParams) == 0;

View File

@ -13,7 +13,6 @@ typedef long NTSTATUS;
CSbieProcess::CSbieProcess(quint32 ProcessId, class CSandBox* pBox)
: CBoxedProcess(ProcessId, pBox)
{
m_ProcessInfo.Flags = 0;
}
QString CSbieProcess::ImageTypeToStr(quint32 type)
@ -123,40 +122,7 @@ QString CSbieProcess::GetStatusStr() const
return Status;
}
SID SeLocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SYSTEM_RID } };
void CSbieProcess::InitProcessInfoImpl(void* 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);
}
}
//void CSbieProcess::InitProcessInfoImpl(void* ProcessHandle)
//{
// CBoxedProcess::InitProcessInfoImpl(ProcessHandle);
//}

View File

@ -27,29 +27,9 @@ public:
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:
virtual void InitProcessInfoImpl(void* ProcessHandle);
//virtual void InitProcessInfoImpl(void* ProcessHandle);
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)
pProcess.objectCast<CSbieProcess>()->SetLeaderProgram(m_pMenuMarkLeader->isChecked());
else if (Action == m_pMenuSuspend)
Results.append(pProcess->SetSuspend(true));
Results.append(pProcess->SetSuspended(true));
else if (Action == m_pMenuResume)
Results.append(pProcess->SetSuspend(false));
Results.append(pProcess->SetSuspended(false));
}
theGUI->CheckResults(Results, this);