Build 0.8.5

This commit is contained in:
DavidXanatos 2021-07-05 13:37:28 +02:00
parent 8a01aea1b3
commit 712617c13c
105 changed files with 4270 additions and 1383 deletions

View File

@ -3,6 +3,56 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [0.8.5 / 5.50.5] - 2021-07-05
### Added
- added global hot key to terminate all boxed processes (by default Ctrl+Break)
- the Run Sandboxed dialog can now handled by the Sandman UI.
- added "AllowBoxedJobs=y" allowing boxed processes to use nested jobs on windows 8 and later
-- note: this allows Chrome and other programs to use the job system for additional isoaltion
- added librewolf.exe to the list of firefox derivatives [#927](https://github.com/sandboxie-plus/Sandboxie/issues/927)
- added run regedit sandboxed menu command
- added new support settings tab to sandman UI for updates and stuff
- added code integrity verification to sbie service and UI
### Changed
- Replaced the Process List used by the driver with a much faster Hash Map implementation
-- Note: this change provides an almost static sys call speed of 1.2us irregardless of the running process count
-- The old list, with 100 programs running required: 4.5µs; with 200: 12µs; and with 300: 18µs per syscall
-- Note: some of the slow down was affecting also non sandboxed applications due to how the driver handles certein callbacks
- Replaced the per process Thread List used by the driver with a much faster Hash Map implementation
- Replaced config section list with a hash map to improve conf performance, and increased line limit to 100000
-- not yet enabled in ptoduction build
- the presence of default box is only checked on connect
- the portable dir dialog now shows the directory [#924](https://github.com/sandboxie-plus/Sandboxie/issues/924)
- when terminated boxed processes we now first try doing that by terminating the job object
- the driver now by default can terminate problematic processes withut the help of the service
- box delete routine now retryed up to 10 times to fix [#954](https://github.com/sandboxie-plus/Sandboxie/issues/954)
- Replaced the Process List used by the service with a much faster Hash Map implementation
- Replaced the per process Thread List used by the service with a much faster Hash Map implementation
### Fixed
- fixed faulty initialization in SetServiceStatus [#921](https://github.com/sandboxie-plus/Sandboxie/issues/921)
- fixed buttons position in Classic UI settings [#914](https://github.com/sandboxie-plus/Sandboxie/issues/914)
- fixed missing password length check in the sandman ui [#925](https://github.com/sandboxie-plus/Sandboxie/issues/925)
- fixed issues opening job objects by name
- fixed missing permission check when re opening job object handles (thanks Diversenok)
- fixed issue with some chromium 90+ hooks affecting pdf plugin in derived browsers [#930](https://github.com/sandboxie-plus/Sandboxie/issues/930) [#817](https://github.com/sandboxie-plus/Sandboxie/issues/817)
- fixed isues with reconnecting broken LPC ports used for communicationw with SbieSvc
- fixed minor setting issue [#957](https://github.com/sandboxie-plus/Sandboxie/issues/957)
- fixed minor ui issue with resource access COM settigns [#958](https://github.com/sandboxie-plus/Sandboxie/issues/958)
- fixed an issue with NtQueryKey using NtQueryObject instead [#951](https://github.com/sandboxie-plus/Sandboxie/issues/951)
- fixed crash in key.c when failing to resolve key paths
- added workaround for top most modality issue [#873](https://github.com/sandboxie-plus/Sandboxie/issues/873)
-- the notification window is not only top most for 5 seconds
- fixed an issue deleteing directories introduced in 5.49.5
### Removed
- removed switch for "BlockPassword=n" as it does not seam to be working [#938](https://github.com/sandboxie-plus/Sandboxie/issues/938)
-- use "OpenSamEndpoint=y" to allow for password change in windows 10
## [0.8.2 / 5.50.2] - 2021-06-15
### Changed

146
Sandboxie/common/base64.c Normal file
View File

@ -0,0 +1,146 @@
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
size_t b64_encoded_size(size_t inlen)
{
size_t ret;
ret = inlen;
if (inlen % 3 != 0)
ret += 3 - (inlen % 3);
ret /= 3;
ret *= 4;
return ret;
}
const wchar_t b64_chars[] = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
wchar_t* b64_encode(const unsigned char *in, size_t inlen)
{
wchar_t* out;
size_t elen;
size_t i;
size_t j;
size_t v;
if (in == NULL || inlen == 0)
return NULL;
elen = b64_encoded_size(inlen);
out = malloc((elen+1) * sizeof(wchar_t));
out[elen] = L'\0';
for (i=0, j=0; i<inlen; i+=3, j+=4) {
v = in[i];
v = i+1 < inlen ? v << 8 | in[i+1] : v << 8;
v = i+2 < inlen ? v << 8 | in[i+2] : v << 8;
out[j] = b64_chars[(v >> 18) & 0x3F];
out[j+1] = b64_chars[(v >> 12) & 0x3F];
if (i+1 < inlen) {
out[j+2] = b64_chars[(v >> 6) & 0x3F];
} else {
out[j+2] = L'=';
}
if (i+2 < inlen) {
out[j+3] = b64_chars[v & 0x3F];
} else {
out[j+3] = L'=';
}
}
return out;
}
size_t b64_decoded_size(const wchar_t *in)
{
size_t len;
size_t ret;
size_t i;
if (in == NULL)
return 0;
len = wcslen(in);
ret = len / 4 * 3;
for (i=len; i-->0; ) {
if (in[i] == L'=') {
ret--;
} else {
break;
}
}
return ret;
}
//static void b64_generate_decode_table()
//{
// int inv[80];
// size_t i;
//
// memset(inv, -1, sizeof(inv));
// for (i=0; i<sizeof(b64_chars)-1; i++) {
// inv[b64_chars[i]-43] = i;
// }
//}
int b64_invs[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51 };
static int b64_isvalidchar(wchar_t c)
{
if (c >= L'0' && c <= L'9')
return 1;
if (c >= L'A' && c <= L'Z')
return 1;
if (c >= L'a' && c <= L'z')
return 1;
if (c == L'+' || c == L'/' || c == L'=')
return 1;
return 0;
}
int b64_decode(const wchar_t *in, unsigned char *out, size_t outlen)
{
size_t len;
size_t i;
size_t j;
int v;
if (in == NULL || out == NULL)
return 0;
len = wcslen(in);
if (outlen < b64_decoded_size(in) || len % 4 != 0)
return 0;
for (i=0; i<len; i++) {
if (!b64_isvalidchar(in[i])) {
return 0;
}
}
for (i=0, j=0; i<len; i+=4, j+=3) {
v = b64_invs[in[i]-43];
v = (v << 6) | b64_invs[in[i+1]-43];
v = in[i+2]=='=' ? v << 6 : (v << 6) | b64_invs[in[i+2]-43];
v = in[i+3]=='=' ? v << 6 : (v << 6) | b64_invs[in[i+3]-43];
out[j] = (v >> 16) & 0xFF;
if (in[i+2] != '=')
out[j+1] = (v >> 8) & 0xFF;
if (in[i+3] != '=')
out[j+2] = v & 0xFF;
}
return 1;
}

319
Sandboxie/common/map.c Normal file
View File

@ -0,0 +1,319 @@
/*
* Copyright 2021 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "map.h"
struct map_node_t {
unsigned int hash;
void *value;
map_node_t *next;
char key[0];
/* char value[]; */
};
VOID* map_alloc(void* pool, size_t size)
{
if (!pool) return NULL;
#ifdef KERNEL_MODE
size_t* base = Mem_Alloc(pool, sizeof(size_t) + size);
#else
size_t* base = (size_t*)Pool_Alloc((POOL*)pool, sizeof(size_t) + size);
#endif
*base++ = size;
return base;
}
VOID map_free(void* pool, void* ptr)
{
size_t* base = (size_t*)ptr;
size_t size = *--base;
#ifdef KERNEL_MODE
Mem_Free(base, size);
#else
Pool_Free(base, size);
#endif
}
static unsigned int map_hash(const void* key, size_t size)
{
/*const int MULTIPLIER = 37;
unsigned int h = 0;
for (unsigned char* p = (unsigned char*)key; p < ((unsigned char*)key) + size; p++)
h = MULTIPLIER * h + *p;
return h;*/
unsigned int hash = 5381;
for (unsigned char* ptr = (unsigned char*)key; ptr < ((unsigned char*)key) + size; ptr++)
hash = ((hash << 5) + hash) ^ *ptr;
return hash;
}
int map_wcssize(const void* key)
{
return (wcslen((const wchar_t*)key) + 1) * sizeof(WCHAR);
}
BOOLEAN map_wcsimatch(const void* key1, const void* key2)
{
return (_wcsicmp((const wchar_t*)key1, (const wchar_t*)key2) == 0);
}
void map_init(map_base_t* m, void* pool)
{
memset(m, 0, sizeof(map_base_t));
m->mem_pool = pool;
m->func_malloc = &map_alloc;
m->func_free = &map_free;
m->func_hash_key = &map_hash;
m->func_key_size = NULL; // use key by value not by reference
m->func_match_key = NULL; // use memcmp by defualt
}
static int map_bucket_idx(map_base_t* m, unsigned int hash)
{
// Note: this works only with bucket sizes which are a power of 2
// this can be generalized by using % instead of &
return hash & (m->nbuckets - 1);
}
static void map_add_node(map_base_t* m, map_node_t* node)
{
int n = map_bucket_idx(m, node->hash);
node->next = m->buckets[n];
m->buckets[n] = node;
}
BOOLEAN map_resize(map_base_t* m, int nbuckets)
{
map_node_t** buckets = (map_node_t**)m->func_malloc(m->mem_pool, sizeof(*m->buckets) * nbuckets);
if (!buckets) return FALSE;
memset(buckets, 0, sizeof(*m->buckets) * nbuckets);
map_node_t* nodes = NULL;
// store all old entries
for (unsigned int i = m->nbuckets; i--; ) {
map_node_t* node = (m->buckets)[i];
while (node) {
map_node_t* next = node->next;
node->next = nodes;
nodes = node;
node = next;
}
}
// swap bucket array
if (m->buckets) m->func_free(m->mem_pool, m->buckets);
m->buckets = buckets;
m->nbuckets = nbuckets;
// re insert all entries from our temporary list back into our buckets
map_node_t* node = nodes;
while (node) {
map_node_t* next = node->next;
map_add_node(m, node);
node = next;
}
return TRUE;
}
static map_node_t* map_new_node(map_base_t* m, const void* _key, void* vdata, size_t vsize)
{
const void* key;
int ksize;
if (m->func_key_size) {
key = _key;
ksize = m->func_key_size(key);
}
else {
key = &_key;
ksize = sizeof(void*);
}
unsigned int hash = m->func_hash_key(key, ksize);
int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
map_node_t* node = (map_node_t*)m->func_malloc(m->mem_pool, sizeof(*node) + voffset + vsize);
if (!node) return NULL;
node->hash = hash;
memcpy(node->key, key, ksize);
node->next = NULL;
if (vsize) {
node->value = vsize ? node->key + voffset : NULL;
memcpy(node->value, vdata, vsize);
}
else
node->value = vdata;
return node;
}
BOOLEAN map_insert(map_base_t* m, const void* key, void* vdata, size_t vsize)
{
// create a new node and fill inn all the blanks
map_node_t* node = map_new_node(m, key, vdata, vsize);
if(!node) goto fail;
// check and if we need to grow our bucker array
//const int reduce_buckets = 0; // average 1.5 nodes/bucket and 49% of buckets used
const int reduce_buckets = 1; // average 1.9 nodes/bucket and 75% of buckets used
//const int reduce_buckets = 2; // average 3.2 nodes/bucket and 91% of buckets used
//const int reduce_buckets = 3; // average 5.9 nodes/bucket and 98% of buckets used
//const int reduce_buckets = 4; // average 11.8 nodes/bucket and 100% of buckets used
if ((m->nnodes >> reduce_buckets) >= m->nbuckets) {
int nbuckets = (m->nbuckets > 0) ? (m->nbuckets << 1) : 1; // *2
if (!map_resize(m, nbuckets)) goto fail;
}
// add new entry to the right bucket
map_add_node(m, node);
m->nnodes++;
return TRUE;
fail:
if (node) m->func_free(m->mem_pool, node);
return FALSE;
}
static map_node_t** map_getref(map_base_t* m, const void* _key)
{
if (!m->buckets) return NULL;
const void* key;
int ksize;
if (m->func_key_size) {
key = _key;
ksize = m->func_key_size(key);
}
else {
key = &_key;
ksize = sizeof(void*);
}
unsigned int hash = m->func_hash_key(key, ksize);
map_node_t** next = &m->buckets[map_bucket_idx(m, hash)];
while (*next) {
if ((*next)->hash == hash && (m->func_match_key
? m->func_match_key((*next)->key, key)
: (memcmp((*next)->key, key, ksize) == 0)
)) {
return next;
}
next = &(*next)->next;
}
return NULL;
}
void* map_get(map_base_t* m, const void* key)
{
map_node_t** next = map_getref(m, key);
return next ? (*next)->value : NULL;
}
void* map_remove(map_base_t* m, const void* key)
{
void* value = NULL;
map_node_t** next = map_getref(m, key);
if (next) {
map_node_t* node = *next;
*next = (*next)->next;
value = node->value;
m->func_free(m->mem_pool, node);
m->nnodes--;
}
return value;
}
void map_deinit(map_base_t* m)
{
for (unsigned int i = m->nbuckets; i--; ) {
map_node_t* node = m->buckets[i];
while (node) {
map_node_t* next = node->next;
m->func_free(m->mem_pool, node);
node = next;
}
}
if (m->buckets) m->func_free(m->mem_pool, m->buckets);
}
map_iter_t map_iter()
{
map_iter_t iter;
memset(&iter, 0, sizeof(map_iter_t));
iter.bucketidx = -1;
return iter;
}
BOOLEAN map_next(map_base_t* m, map_iter_t* iter)
{
if (iter->node) {
iter->node = iter->node->next;
if (iter->node == NULL) goto nextBucket;
}
else {
nextBucket:
do {
if (++iter->bucketidx >= m->nbuckets) {
return FALSE;
}
iter->node = m->buckets[iter->bucketidx];
} while (iter->node == NULL);
}
iter->key = iter->node->key;
iter->value = iter->node->value;
return TRUE;
}
/*
void map_dump(map_base_t *m)
{
int used = 0;
int empty = 0;
int bucketidx = 0;
//printf("start\r\n");
while(++bucketidx < m->nbuckets) {
map_node_t* bucket = m->buckets[bucketidx];
if (bucket) {
used++;
//printf("bucket %d\r\n", bucketidx);
//for(map_node_t* node = bucket; node != NULL; node = node->next) {
// printf("node %d: %d\r\n", node->hash, (int)node->value);
//}
} else {
empty++;
//printf("EMPTY bucket %d\r\n", bucketidx);
}
}
printf("\r\n\r\nBucket usage %d/%d (%d%%), average nodes per used bucket %.2f\r\n", used, used+empty, 100*used/(used+empty), (double)m->nnodes/used);
}*/

72
Sandboxie/common/map.h Normal file
View File

@ -0,0 +1,72 @@
/*
* Copyright 2021 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MAP_H
#define MAP_H
#ifdef __cplusplus
extern "C" {
#endif
struct map_node_t;
typedef struct map_node_t map_node_t;
struct map_base_t;
typedef struct map_base_t map_base_t;
struct map_base_t {
map_node_t **buckets;
unsigned int nbuckets, nnodes;
void* mem_pool;
void*(*func_malloc)(void* pool, size_t size);
void(*func_free)(void* pool, void* ptr);
int(*func_key_size)(const void* key);
unsigned int (*func_hash_key)(const void* key, size_t size);
BOOLEAN (*func_match_key)(const void* key1, const void* key2);
};
typedef map_base_t HASH_MAP;
int map_wcssize(const void* key);
BOOLEAN map_wcsimatch(const void* key1, const void* key2);
void map_init(map_base_t *m, void* pool);
BOOLEAN map_resize(map_base_t* m, int nbuckets);
BOOLEAN map_insert(map_base_t *m, const void* key, void* vdata, size_t vsize);
void* map_get(map_base_t *m, const void* key);
void* map_remove(map_base_t *m, const void* key);
void map_deinit(map_base_t *m);
typedef struct {
unsigned int bucketidx;
map_node_t *node;
void* key;
void* value;
} map_iter_t;
map_iter_t map_iter();
BOOLEAN map_next(map_base_t *m, map_iter_t *iter);
//void map_dump(map_base_t *m);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -21,8 +21,8 @@
#ifndef _MY_VERSION_H
#define _MY_VERSION_H
#define MY_VERSION_BINARY 5,50,2
#define MY_VERSION_STRING "5.50.2"
#define MY_VERSION_BINARY 5,50,5
#define MY_VERSION_STRING "5.50.5"
#define MY_VERSION_COMPAT "5.50.0" // this refers to the driver ABI compatibility
// These #defines are used by either Resource Compiler, or by NSIC installer

View File

@ -463,6 +463,11 @@ typedef NTSTATUS (*P_NtOpenFile)(
IN ULONG ShareAccess,
IN ULONG OpenOptions);
typedef NTSTATUS (*P_NtOpenJobObject)(
OUT PHANDLE JobHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes);
typedef NTSTATUS (*P_NtOpenKey)(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,

321
Sandboxie/common/verify.c Normal file
View File

@ -0,0 +1,321 @@
#include <ntstatus.h>
#define WIN32_NO_STATUS
typedef long NTSTATUS;
#include <windows.h>
#include <bcrypt.h>
//#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <fileapi.h>
#include "..\..\Sandboxie\common\win32_ntddk.h"
static UCHAR KphpTrustedPublicKey[] =
{
0x45, 0x43, 0x53, 0x31, 0x20, 0x00, 0x00, 0x00, 0x05, 0x7A, 0x12, 0x5A, 0xF8, 0x54, 0x01, 0x42,
0xDB, 0x19, 0x87, 0xFC, 0xC4, 0xE3, 0xD3, 0x8D, 0x46, 0x7B, 0x74, 0x01, 0x12, 0xFC, 0x78, 0xEB,
0xEF, 0x7F, 0xF6, 0xAF, 0x4D, 0x9A, 0x3A, 0xF6, 0x64, 0x90, 0xDB, 0xE3, 0x48, 0xAB, 0x3E, 0xA7,
0x2F, 0xC1, 0x18, 0x32, 0xBD, 0x23, 0x02, 0x9D, 0x3F, 0xF3, 0x27, 0x86, 0x71, 0x45, 0x26, 0x14,
0x14, 0xF5, 0x19, 0xAA, 0x2D, 0xEE, 0x50, 0x10
};
#define CST_SIGN_ALGORITHM BCRYPT_ECDSA_P256_ALGORITHM
#define CST_SIGN_ALGORITHM_BITS 256
#define CST_HASH_ALGORITHM BCRYPT_SHA256_ALGORITHM
#define CST_BLOB_PRIVATE BCRYPT_ECCPRIVATE_BLOB
#define CST_BLOB_PUBLIC BCRYPT_ECCPUBLIC_BLOB
#define KPH_SIGNATURE_MAX_SIZE (128 * 1024) // 128 kB
#define FILE_BUFFER_SIZE 4096
NTSTATUS PhCreateFileWin32(_Out_ PHANDLE FileHandle, _In_ PCWSTR FileName, _In_ ACCESS_MASK DesiredAccess,
_In_opt_ ULONG FileAttributes, _In_ ULONG ShareAccess, _In_ ULONG CreateDisposition, _In_ ULONG CreateOptions)
{
UNICODE_STRING uni;
OBJECT_ATTRIBUTES attr;
WCHAR wszBuffer[MAX_PATH];
_snwprintf(wszBuffer, MAX_PATH, L"\\??\\%s", FileName);
RtlInitUnicodeString(&uni, wszBuffer);
InitializeObjectAttributes(&attr, &uni, OBJ_CASE_INSENSITIVE, NULL, 0);
IO_STATUS_BLOCK Iosb;
return NtCreateFile(FileHandle, DesiredAccess, &attr, &Iosb, NULL, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, NULL, 0);
}
NTSTATUS PhGetFileSize(_In_ HANDLE FileHandle, _Out_ PLARGE_INTEGER Size)
{
if (GetFileSizeEx(FileHandle, Size))
return STATUS_SUCCESS;
return STATUS_UNSUCCESSFUL;
}
static NTSTATUS CstReadFile(
_In_ PWSTR FileName,
_In_ ULONG FileSizeLimit,
_Out_ PVOID* Buffer,
_Out_ PULONG FileSize
)
{
NTSTATUS status;
HANDLE fileHandle = INVALID_HANDLE_VALUE;
LARGE_INTEGER fileSize;
PVOID buffer;
IO_STATUS_BLOCK iosb;
if (!NT_SUCCESS(status = PhCreateFileWin32(&fileHandle, FileName, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE)))
goto CleanupExit;
if (!NT_SUCCESS(status = PhGetFileSize(fileHandle, &fileSize)))
goto CleanupExit;
if (fileSize.QuadPart > FileSizeLimit)
goto CleanupExit;
buffer = malloc((ULONG)fileSize.QuadPart);
if (!NT_SUCCESS(status = NtReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, (ULONG)fileSize.QuadPart, NULL, NULL)))
goto CleanupExit;
*Buffer = buffer;
*FileSize = (ULONG)fileSize.QuadPart;
CleanupExit:
if(fileHandle != INVALID_HANDLE_VALUE)
NtClose(fileHandle);
return status;
}
typedef struct {
BCRYPT_ALG_HANDLE hashAlgHandle;
ULONG hashObjectSize;
ULONG hashSize;
PVOID hashObject;
BCRYPT_HASH_HANDLE hashHandle;
} CST_HASH_OBJ;
static VOID CstFreeHash(CST_HASH_OBJ* pHashObj)
{
if (pHashObj->hashHandle)
BCryptDestroyHash(pHashObj->hashHandle);
if (pHashObj->hashObject)
free(pHashObj->hashObject); // must be freed after destroying hash object
if (pHashObj->hashAlgHandle)
BCryptCloseAlgorithmProvider(pHashObj->hashAlgHandle, 0);
}
static NTSTATUS CstInitHash(CST_HASH_OBJ* pHashObj)
{
NTSTATUS status;
ULONG querySize;
memset(pHashObj, 0, sizeof(CST_HASH_OBJ));
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&pHashObj->hashAlgHandle, CST_HASH_ALGORITHM, NULL, 0)))
goto CleanupExit;
if (!NT_SUCCESS(status = BCryptGetProperty(pHashObj->hashAlgHandle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&pHashObj->hashObjectSize, sizeof(ULONG), &querySize, 0)))
goto CleanupExit;
if (!NT_SUCCESS(status = BCryptGetProperty(pHashObj->hashAlgHandle, BCRYPT_HASH_LENGTH, (PUCHAR)&pHashObj->hashSize, sizeof(ULONG), &querySize, 0)))
goto CleanupExit;
pHashObj->hashObject = malloc(pHashObj->hashObjectSize);
if (!pHashObj->hashObject) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
if (!NT_SUCCESS(status = BCryptCreateHash(pHashObj->hashAlgHandle, &pHashObj->hashHandle, (PUCHAR)pHashObj->hashObject, pHashObj->hashObjectSize, NULL, 0, 0)))
goto CleanupExit;
CleanupExit:
if (!NT_SUCCESS(status))
CstFreeHash(pHashObj);
return status;
}
static NTSTATUS CstHashData(
CST_HASH_OBJ* pHashObj,
_Out_ PVOID Data,
_Out_ ULONG DataSize
)
{
return BCryptHashData(pHashObj->hashHandle, (PUCHAR)Data, DataSize, 0);
}
static NTSTATUS CstFinishHash(
CST_HASH_OBJ* pHashObj,
_Out_ PVOID* Hash,
_Out_ PULONG HashSize
)
{
NTSTATUS status;
PVOID hash;
hash = malloc(pHashObj->hashSize);
if (!hash) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
if (!NT_SUCCESS(status = BCryptFinishHash(pHashObj->hashHandle, (PUCHAR)hash, pHashObj->hashSize, 0)))
goto CleanupExit;
*HashSize = pHashObj->hashSize;
*Hash = hash;
return STATUS_SUCCESS;
CleanupExit:
if (hash)
free(hash);
return status;
}
static NTSTATUS CstHashFile(
_In_ PCWSTR FileName,
_Out_ PVOID* Hash,
_Out_ PULONG HashSize
)
{
NTSTATUS status;
HANDLE fileHandle = INVALID_HANDLE_VALUE;
PVOID buffer = NULL;
IO_STATUS_BLOCK iosb;
CST_HASH_OBJ hashObj;
if (!NT_SUCCESS(status = CstInitHash(&hashObj)))
goto CleanupExit;
if (!NT_SUCCESS(status = PhCreateFileWin32(&fileHandle, FileName, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE)))
goto CleanupExit;
buffer = malloc(FILE_BUFFER_SIZE);
if (!buffer) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
while (TRUE)
{
if (!NT_SUCCESS(status = NtReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, FILE_BUFFER_SIZE, NULL, NULL)))
{
if (status == STATUS_END_OF_FILE)
break;
goto CleanupExit;
}
if (!NT_SUCCESS(status = CstHashData(&hashObj, buffer, (ULONG)iosb.Information)))
goto CleanupExit;
}
if (!NT_SUCCESS(status = CstFinishHash(&hashObj, Hash, HashSize)))
goto CleanupExit;
CleanupExit:
if(buffer)
free(buffer);
if(fileHandle != INVALID_HANDLE_VALUE)
NtClose(fileHandle);
CstFreeHash(&hashObj);
return status;
}
static NTSTATUS VerifyHashSignature(
_In_ PVOID Hash,
_In_ ULONG HashSize,
_In_ PVOID Signature,
_In_ ULONG SignatureSize
)
{
NTSTATUS status;
BCRYPT_ALG_HANDLE signAlgHandle = NULL;
BCRYPT_KEY_HANDLE keyHandle = NULL;
// Import the trusted public key.
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&signAlgHandle, CST_SIGN_ALGORITHM, NULL, 0)))
goto CleanupExit;
if (!NT_SUCCESS(status = BCryptImportKeyPair(signAlgHandle, NULL, CST_BLOB_PUBLIC, &keyHandle,
KphpTrustedPublicKey, sizeof(KphpTrustedPublicKey), 0)))
{
goto CleanupExit;
}
// Verify the hash.
if (!NT_SUCCESS(status = BCryptVerifySignature(keyHandle, NULL, (PUCHAR)Hash, HashSize, (PUCHAR)Signature,
SignatureSize, 0)))
{
goto CleanupExit;
}
CleanupExit:
if (keyHandle != NULL)
BCryptDestroyKey(keyHandle);
if (signAlgHandle)
BCryptCloseAlgorithmProvider(signAlgHandle, 0);
return status;
}
NTSTATUS VerifyFileSignature(const wchar_t* FilePath)
{
NTSTATUS status;
ULONG hashSize;
PVOID hash = NULL;
ULONG signatureSize;
PVOID signature = NULL;
WCHAR* signatureFileName = NULL;
// Read the signature.
signatureFileName = (WCHAR*)malloc((wcslen(FilePath) + 4 + 1) * sizeof(WCHAR));
if(!signatureFileName) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
wcscpy(signatureFileName, FilePath);
wcscat(signatureFileName, L".sig");
// Read the signature file.
if (!NT_SUCCESS(status = CstReadFile(signatureFileName, KPH_SIGNATURE_MAX_SIZE, &signature, &signatureSize)))
goto CleanupExit;
// Hash the file.
if (!NT_SUCCESS(status = CstHashFile(FilePath, &hash, &hashSize)))
goto CleanupExit;
// Verify the hash.
if (!NT_SUCCESS(status = VerifyHashSignature((PUCHAR)hash, hashSize, (PUCHAR)signature, signatureSize)))
{
goto CleanupExit;
}
CleanupExit:
if (signature)
free(signature);
if (hash)
free(hash);
if (signatureFileName)
free(signatureFileName);
return status;
}

View File

@ -2284,6 +2284,11 @@ __declspec(dllimport) NTSTATUS __stdcall NtCreateJobObject(
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL);
__declspec(dllimport) NTSTATUS __stdcall NtOpenJobObject(
OUT PHANDLE JobHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes);
__declspec(dllimport) NTSTATUS __stdcall NtAssignProcessToJobObject(
HANDLE hJob, HANDLE hProcess);

View File

@ -375,6 +375,7 @@
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\apps\com\common.h" />
<ClInclude Include="..\..\common\pattern.h" />
<ClInclude Include="..\..\common\pool.h" />
<ClInclude Include="..\..\common\stream.h" />

View File

@ -231,6 +231,9 @@
<ClInclude Include="..\..\common\pattern.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\apps\com\common.h">
<Filter>common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc" />

View File

@ -201,7 +201,7 @@ _FX BOOLEAN Config_MatchImageGroup(
//---------------------------------------------------------------------------
_FX WCHAR* Config_MatchImageAndGetValue(WCHAR* value, const WCHAR* ImageName, ULONG* pMode)
_FX WCHAR* Config_MatchImageAndGetValue(WCHAR* value, const WCHAR* ImageName, ULONG* pLevel)
{
//
// if the setting indicates an image name followed by a comma,
@ -220,8 +220,7 @@ _FX WCHAR* Config_MatchImageAndGetValue(WCHAR* value, const WCHAR* ImageName, UL
if (*value == L'!') {
inv = TRUE;
++value;
}
else
} else
inv = FALSE;
ULONG len = (ULONG)(tmp - value);
@ -230,22 +229,25 @@ _FX WCHAR* Config_MatchImageAndGetValue(WCHAR* value, const WCHAR* ImageName, UL
if (inv)
match = !match;
if (!match)
tmp = NULL;
else if (pMode) {
return NULL;
else if (pLevel) {
if (len == 1 && *value == L'*')
*pMode = 2; // 2 - match all
*pLevel = 2; // 2 - match all
else
*pMode = inv ? 1 : 0; // 1 - match by negation, 0 - exact match
*pLevel = inv ? 1 : 0; // 1 - match by negation, 0 - exact match
}
}
value = tmp ? tmp + 1 : NULL;
value = tmp + 1;
}
else {
if (pMode) *pMode = 2; // 2 - global default
if (pLevel) *pLevel = 2; // 2 - global default
}
if (! *value)
return NULL;
return value;
}
@ -270,10 +272,22 @@ BOOLEAN Config_String2Bool(const WCHAR* value, BOOLEAN defval)
//---------------------------------------------------------------------------
BOOLEAN Config_GetSettingsForImageName_bool(const WCHAR* setting, BOOLEAN defval)
_FX BOOLEAN Config_GetSettingsForImageName_bool(const WCHAR* setting, BOOLEAN defval)
{
return SbieDll_GetSettingsForImageName_bool(NULL, Dll_ImageName, setting, defval);
}
//---------------------------------------------------------------------------
// SbieDll_GetSettingsForImageName_bool
//---------------------------------------------------------------------------
_FX BOOLEAN SbieDll_GetSettingsForImageName_bool(
const WCHAR* boxname, const WCHAR* image_name, const WCHAR* setting, BOOLEAN defval)
{
WCHAR value[16];
Config_GetSettingsForImageName(setting, value, sizeof(value), NULL);
SbieDll_GetSettingsForImageName(boxname, image_name, setting, value, sizeof(value), NULL);
return Config_String2Bool(value, defval);
}
@ -312,43 +326,44 @@ _FX BOOLEAN Config_InitPatternList(const WCHAR* setting, LIST* list)
//---------------------------------------------------------------------------
// Config_GetSettingsForImageName
// SbieDll_GetSettingsForImageName
//---------------------------------------------------------------------------
_FX NTSTATUS Config_GetSettingsForImageName(
const WCHAR* setting, WCHAR* value, ULONG value_size, const WCHAR* deftext)
_FX BOOLEAN SbieDll_GetSettingsForImageName(
const WCHAR* boxname, const WCHAR* image_name, const WCHAR* setting, WCHAR* value, ULONG value_size, const WCHAR* deftext)
{
WCHAR conf_buf[2048];
ULONG found_mode = -1;
ULONG found_level = -1;
ULONG index = 0;
while (1) {
NTSTATUS status = SbieApi_QueryConf(
NULL, setting, index, conf_buf, sizeof(conf_buf) - 16 * sizeof(WCHAR));
boxname, setting, index, conf_buf, sizeof(conf_buf) - 16 * sizeof(WCHAR));
if (!NT_SUCCESS(status))
break;
++index;
ULONG mode = -1;
WCHAR* found_value = Config_MatchImageAndGetValue(conf_buf, Dll_ImageName, &mode);
if (!found_value || mode > found_mode)
ULONG level = -1;
WCHAR* found_value = Config_MatchImageAndGetValue(conf_buf, image_name, &level);
if (!found_value || level > found_level)
continue;
//if (found_value) {
// SbieApi_Log(2302, L"%S - %S [%S]", setting, Dll_ImageName, Dll_BoxName);
// break;
//}
wcscpy_s(value, value_size / sizeof(WCHAR), found_value);
found_mode = mode;
found_level = level;
}
if (found_mode == -1) {
if (found_level == -1) {
if (deftext) wcscpy_s(value, value_size / sizeof(WCHAR), deftext);
else value[0] = L'\0';
return FALSE;
}
return STATUS_SUCCESS;
return TRUE;
}
@ -560,17 +575,45 @@ BOOLEAN SbieDll_CheckStringInList(const WCHAR* string, const WCHAR* boxname, con
//---------------------------------------------------------------------------
// Config_GetTagValue
// Config_SkipWhiteSpace
//---------------------------------------------------------------------------
WCHAR* Config_GetTagValue(WCHAR* str, WCHAR** value, ULONG* len, WCHAR sep)
VOID Config_SkipWhiteSpace(WCHAR** pstr) {
while ((*pstr)[0] == L' '
|| (*pstr)[0] == L'\r'
|| (*pstr)[0] == L'\n'
|| (*pstr)[0] == L'\t')
(*pstr)++;
}
//---------------------------------------------------------------------------
// Config_TrimWhiteSpace
//---------------------------------------------------------------------------
VOID Config_TrimWhiteSpace(WCHAR** pstr, ULONG* len) {
while (*len > 0
&& ((*pstr)[*len-1] == L' '
|| (*pstr)[*len-1] == L'\r'
//|| (*pstr)[*len-1] == L'\n'
|| (*pstr)[*len-1] == L'\t'))
(*len)--;
}
//---------------------------------------------------------------------------
// SbieDll_GetTagValue
//---------------------------------------------------------------------------
WCHAR* SbieDll_GetTagValue(WCHAR* str, WCHAR** value, ULONG* len, WCHAR sep)
{
*value = NULL;
*len = 0;
// skip whitespace
//while (*str == L' ' || *str == L'\t') str++;
Config_SkipWhiteSpace(&str);
WCHAR* tmp;
BOOLEAN alt;
@ -593,6 +636,8 @@ WCHAR* Config_GetTagValue(WCHAR* str, WCHAR** value, ULONG* len, WCHAR sep)
if (!tmp) tmp = wcschr(str, L'\0');
*value = str;
*len = (ULONG)(tmp - *value);
Config_TrimWhiteSpace(value, len);
}
if (tmp && *tmp) tmp++; // skip separator
@ -601,35 +646,77 @@ WCHAR* Config_GetTagValue(WCHAR* str, WCHAR** value, ULONG* len, WCHAR sep)
//---------------------------------------------------------------------------
// Config_FindTagValue
// SbieDll_EnumTagValues
//---------------------------------------------------------------------------
BOOLEAN Config_FindTagValue(WCHAR* string, const WCHAR* tag_name, WCHAR* value, ULONG value_size, const WCHAR* deftext, WCHAR sep)
VOID SbieDll_EnumTagValues(WCHAR* string, SbieDll_TagEnumProc enumProc, void* param, WCHAR eq, WCHAR sep)
{
ULONG tag_len = wcslen(tag_name);
WCHAR* temp = string;
WCHAR* str_ptr = string;
WCHAR* tmp;
WCHAR* name;
ULONG len;
WCHAR* found_value;
ULONG found_len;
while(*temp)
while(*str_ptr)
{
tmp = wcschr(temp, L'=');
Config_SkipWhiteSpace(&str_ptr);
tmp = wcschr(str_ptr, eq);
if (!tmp)
break;
name = temp;
len = (ULONG)(tmp - temp);
name = str_ptr;
len = (ULONG)(tmp - str_ptr);
Config_TrimWhiteSpace(&name, &len);
temp = Config_GetTagValue(tmp + 1, &found_value, &found_len, sep);
str_ptr = SbieDll_GetTagValue(tmp + 1, &found_value, &found_len, sep);
if (tag_len == len && _wcsnicmp(tag_name, name, len) == 0)
if (!str_ptr || !enumProc(name, len, found_value, found_len, param))
break;
}
}
//---------------------------------------------------------------------------
// SbieDll_FindTagValue
//---------------------------------------------------------------------------
typedef struct
{
wcsncpy_s(value, value_size / sizeof(WCHAR), found_value, found_len);
return TRUE;
const WCHAR* tag_name;
ULONG tag_len;
WCHAR* value;
ULONG value_size;
BOOLEAN found;
} TagFindProcParam;
static BOOLEAN Config_TagFindProc(WCHAR* name, ULONG name_len, WCHAR* value, ULONG value_len, void* param)
{
TagFindProcParam* tagFindProcParam = (TagFindProcParam*)param;
if (tagFindProcParam->tag_len == name_len && _wcsnicmp(tagFindProcParam->tag_name, name, name_len) == 0)
{
wcsncpy_s(tagFindProcParam->value, tagFindProcParam->value_size / sizeof(WCHAR), value, value_len);
tagFindProcParam->found = TRUE;
return FALSE; // break
}
return TRUE; // continue
}
BOOLEAN SbieDll_FindTagValue(WCHAR* string, const WCHAR* tag_name, WCHAR* value, ULONG value_size, WCHAR eq, WCHAR sep)
{
if (!string)
return FALSE;
TagFindProcParam tagFindProcParam =
{
tag_name,
wcslen(tag_name),
value,
value_size,
FALSE
};
SbieDll_EnumTagValues(string, &Config_TagFindProc, &tagFindProcParam, eq, sep);
return tagFindProcParam.found;
}

View File

@ -849,21 +849,12 @@ _FX void AutoExec(void)
if (! Dll_FirstProcessInBox)
return;
buf_len = 4096 * sizeof(WCHAR);
buf1 = Dll_AllocTemp(buf_len);
status = SbieApi_EnumProcess(Dll_BoxName, (ULONG *)buf1);
if (status != 0) {
Sbie_snwprintf(error_str, 16, L"%d [%08X]", -1, status);
SbieApi_Log(2206, error_str);
Dll_Free(buf1);
return;
}
//
// query the values in the AutoExec setting
//
buf_len = 4096 * sizeof(WCHAR);
buf1 = Dll_AllocTemp(buf_len);
memzero(buf1, buf_len);
buf2 = Dll_AllocTemp(buf_len);
memzero(buf2, buf_len);

View File

@ -769,17 +769,10 @@ WCHAR* Config_MatchImageAndGetValue(WCHAR* value, const WCHAR* ImageName, ULONG*
BOOLEAN Config_InitPatternList(const WCHAR* setting, LIST* list);
NTSTATUS Config_GetSettingsForImageName(
const WCHAR* setting, WCHAR* value, ULONG value_size, const WCHAR* deftext);
BOOLEAN Config_String2Bool(const WCHAR* value, BOOLEAN defval);
BOOLEAN Config_GetSettingsForImageName_bool(const WCHAR* setting, BOOLEAN defval);
WCHAR* Config_GetTagValue(WCHAR* str, WCHAR** value, ULONG* len, WCHAR sep);
BOOLEAN Config_FindTagValue(WCHAR* string, const WCHAR* name, WCHAR* value, ULONG value_size, const WCHAR* deftext, WCHAR sep);
//---------------------------------------------------------------------------

View File

@ -489,7 +489,6 @@ skip_e9_rewrite: ;
// SbieDll_Hook_CheckChromeHook
//---------------------------------------------------------------------------
#ifdef _WIN64
ULONGLONG * SbieDll_findChromeTarget(unsigned char* addr);
#define MAX_FUNC_SIZE 0x76
//Note any change to this function requires the same modification to the function in LowLevel: see init.c (findChromeTarget)
ULONGLONG * SbieDll_findChromeTarget(unsigned char* addr)
@ -502,6 +501,12 @@ ULONGLONG * SbieDll_findChromeTarget(unsigned char* addr)
//So far the offset has been positive between 0xa00000 and 0xb00000 bytes;
//This may change in a future version of chrome
for (i = 0; i < MAX_FUNC_SIZE; i++) {
// some chromium 90+ derivatives replace the function with a return 1 stub
// mov eax,1
// ret
// int 3
if (addr[i] == 0xB8 && addr[i + 5] == 0xC3 && addr[i + 6] == 0xCC)
return NULL;
if ((*(USHORT *)&addr[i] == 0x8b48)) {
if ((addr[i + 2] == 0x0d || addr[i + 2] == 0x05)) {
LONG delta;

View File

@ -571,6 +571,7 @@ _FX ULONG Dll_GetImageType(const WCHAR *ImageName)
L"basilisk.exe", (WCHAR *)DLL_IMAGE_MOZILLA_FIREFOX,
L"seamonkey.exe", (WCHAR *)DLL_IMAGE_MOZILLA_FIREFOX,
L"k-meleon.exe", (WCHAR *)DLL_IMAGE_MOZILLA_FIREFOX,
L"librewolf.exe", (WCHAR *)DLL_IMAGE_MOZILLA_FIREFOX,
L"wmplayer.exe", (WCHAR *)DLL_IMAGE_WINDOWS_MEDIA_PLAYER,
L"winamp.exe", (WCHAR *)DLL_IMAGE_NULLSOFT_WINAMP,
@ -776,6 +777,7 @@ _FX ULONG_PTR Dll_Ordinal1(
CloseHandle(heventProcessStart);
}
}
//
// workaround for Program Compatibility Assistant (PCA), we have
// to start a second instance of this process outside the PCA job,

View File

@ -80,9 +80,6 @@
#define FGN_REPARSED_CLOSED_PATH 0x0200
#define FGN_REPARSED_WRITE_PATH 0x0400
#define PATH_IS_BOXED(f) (((f) & FGN_IS_BOXED_PATH) != 0)
#define PATH_NOT_BOXED(f) (((f) & FGN_IS_BOXED_PATH) == 0)
#ifndef _WIN64
#define WOW64_FS_REDIR
@ -477,7 +474,7 @@ _FX NTSTATUS File_GetName(
}
}
if (status == STATUS_BUFFER_OVERFLOW) {
if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) {
name = Dll_GetTlsNameBuffer(
TlsData, TRUE_NAME_BUFFER, length + objname_len);
@ -5845,7 +5842,6 @@ _FX NTSTATUS File_SetDisposition(
WCHAR *DosPath;
NTSTATUS status;
ULONG mp_flags;
BOOLEAN is_direct_file;
//
// check if the specified path is an open or closed path
@ -5855,7 +5851,6 @@ _FX NTSTATUS File_SetDisposition(
mp_flags = 0;
DosPath = NULL;
is_direct_file = FALSE;
Dll_PushTlsNameBuffer(TlsData);
@ -5867,6 +5862,12 @@ _FX NTSTATUS File_SetDisposition(
status = File_GetName(
FileHandle, &uni, &TruePath, &CopyPath, &FileFlags);
//
// fix-me: this is broken, instead of deleting files on close it deletes them instantly
// possible workarounds use __sys_NtSetInformationFile for files that reside only in the sandbox
// or implement proper deletion on handle close in File_NtCloseImpl
//
if (NT_SUCCESS(status)) {
mp_flags = File_MatchPath(TruePath, &FileFlags);
@ -5874,22 +5875,7 @@ _FX NTSTATUS File_SetDisposition(
if (PATH_IS_CLOSED(mp_flags))
status = STATUS_ACCESS_DENIED;
else if (PATH_IS_OPEN(mp_flags)) {
is_direct_file = TRUE; // file is open
}
else {
WCHAR* TmplPath = CopyPath;
File_FindSnapshotPath(&TmplPath); // if file is in a snapshot this updates TmplPath to point to it
if (PATH_IS_BOXED(FileFlags) && TmplPath == CopyPath)
is_direct_file = TRUE; // file is boxed and not located in a snapshot
}
if (!is_direct_file) {
else if (PATH_NOT_OPEN(mp_flags)) {
status = File_DeleteDirectory(CopyPath, TRUE);
@ -5929,7 +5915,7 @@ _FX NTSTATUS File_SetDisposition(
// handle the request appropriately
//
if (is_direct_file) {
if (PATH_IS_OPEN(mp_flags)) {
status = __sys_NtSetInformationFile(
FileHandle, IoStatusBlock,

View File

@ -561,7 +561,7 @@ _FX NTSTATUS Ipc_GetName(
status = Obj_GetObjectName(RootDirectory, name, &length);
if (status == STATUS_BUFFER_OVERFLOW) {
if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) {
name = Dll_GetTlsNameBuffer(
TlsData, TRUE_NAME_BUFFER, length + objname_len);

View File

@ -21,6 +21,7 @@
#include "dll.h"
#include "obj.h"
#include "core/svc/FileWire.h"
#include "core/drv/api_defs.h"
#include <stdio.h>
@ -447,25 +448,23 @@ _FX NTSTATUS Key_GetName(
name = Dll_GetTlsNameBuffer(
TlsData, TRUE_NAME_BUFFER, length + objname_len);
status = __sys_NtQueryKey(
RootDirectory, KeyNameInformation, name, length, &length);
status = Obj_GetObjectName(RootDirectory, name, &length);
if (status == STATUS_BUFFER_OVERFLOW) {
if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) {
name = Dll_GetTlsNameBuffer(
TlsData, TRUE_NAME_BUFFER, length + objname_len);
status = __sys_NtQueryKey(
RootDirectory, KeyNameInformation, name, length, &length);
status = Obj_GetObjectName(RootDirectory, name, &length);
}
if (! NT_SUCCESS(status))
return status;
*OutTruePath = ((KEY_NAME_INFORMATION *)name)->Name;
*OutTruePath = ((OBJECT_NAME_INFORMATION *)name)->Name.Buffer;
name = (*OutTruePath)
+ ((KEY_NAME_INFORMATION *)name)->NameLength / sizeof(WCHAR);
+ ((OBJECT_NAME_INFORMATION *)name)->Name.Length / sizeof(WCHAR);
if (objname_len) {
@ -821,6 +820,8 @@ _FX NTSTATUS Key_FixNameWow64(
Dll_Free(NewPtr);
File_NtCloseImpl(handle);
if (NT_SUCCESS(status)) {
//
// the result might contain \Wow6432Node\Wow6432Node,
// so strip one of them away
@ -828,6 +829,7 @@ _FX NTSTATUS Key_FixNameWow64(
if (Key_FixNameWow64_3(OutTruePath))
Key_FixNameWow64_3(OutCopyPath);
}
return status;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2004-2020 Sandboxie Holdings, LLC
* Copyright 2020 David Xanatos, xanasoft.com
* Copyright 2020-2021 David Xanatos, xanasoft.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -142,6 +142,9 @@ static int WSA_WSANSPIoctl(
static int WSA_IsBlockedPort(const short *addr, int addrlen);
//static SOCKET WSA_WSASocketW(
// int af, int type, int protocol, void *lpProtocolInfo, unsigned int g, DWORD dwFlags);
static int WSA_connect(SOCKET s, const void *name, int namelen);
static int WSA_WSAConnect(
@ -158,6 +161,9 @@ typedef int (*P_WSANSPIoctl)(
void *lpvOutBuffer, DWORD cbOutBuffer,
DWORD *lpcbBytesReturned, WSACOMPLETION *lpCompletion);
//typedef int (*P_WSASocketW)(
// int af, int type, int protocol, void *lpProtocolInfo, unsigned int g, DWORD dwFlags);
typedef int (*P_connect)(SOCKET s, const struct sockaddr *name, int namelen);
typedef int (*P_WSAConnect)(
@ -169,6 +175,7 @@ typedef int (*P_WSAConnect)(
static P_WSANSPIoctl __sys_WSANSPIoctl = NULL;
//static P_WSASocketW __sys_WSASocketW = NULL;
static P_connect __sys_connect = NULL;
static P_WSAConnect __sys_WSAConnect = NULL;
@ -246,6 +253,21 @@ _FX int WSA_IsBlockedPort(const short *addr, int addrlen)
}
//---------------------------------------------------------------------------
// WSA_WSASocketW
//---------------------------------------------------------------------------
//const BOOLEAN File_InternetBlockade_ManualBypass();
//
//static SOCKET WSA_WSASocketW(
// int af, int type, int protocol, void* lpProtocolInfo, unsigned int g, DWORD dwFlags)
//{
// // Note: mswsock.dll!WSPSocket is not exported
//
// return __sys_WSASocketW(af, type, protocol, lpProtocolInfo, g, dwFlags);
//}
//---------------------------------------------------------------------------
// WSA_connect
//---------------------------------------------------------------------------
@ -436,6 +458,7 @@ _FX BOOLEAN WSA_Init(HMODULE module)
P_WSANSPIoctl WSANSPIoctl;
P_connect connect;
P_WSAConnect WSAConnect;
// P_WSASocketW WSASocketW;
WSANSPIoctl = (P_WSANSPIoctl)GetProcAddress(module, "WSANSPIoctl");
if (WSANSPIoctl) {
@ -450,6 +473,11 @@ _FX BOOLEAN WSA_Init(HMODULE module)
if (! Dll_SkipHook(L"wsaconn")) {
// WSASocketW = (P_WSASocketW)GetProcAddress(module, "WSASocketW");
// if (WSASocketW) {
// SBIEDLL_HOOK(WSA_,WSASocketW);
// }
connect = (P_connect)GetProcAddress(module, "connect");
if (connect) {
SBIEDLL_HOOK(WSA_,connect);

View File

@ -499,7 +499,9 @@ _FX BOOL Proc_UpdateProcThreadAttribute(
// if(Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME)
if (Attribute == 0x0002000d) //PROC_THREAD_ATTRIBUTE_JOB_LIST
{
if (!SbieApi_QueryConfBool(NULL, L"NoAddProcessToJob", FALSE))
extern BOOLEAN SysInfo_CanUseJobs;
extern BOOLEAN SysInfo_UseSbieJob;
if (!SysInfo_CanUseJobs && SysInfo_UseSbieJob)
return TRUE;
}

View File

@ -420,7 +420,7 @@ _FX NTSTATUS RpcRt_FindModulePreset(
WCHAR* test_value = NULL;
ULONG test_len = 0;
found_value = Config_GetTagValue(found_value, &test_value, &test_len, L',');
found_value = SbieDll_GetTagValue(found_value, &test_value, &test_len, L',');
if (!test_value || !found_value || !*found_value) {
SbieApi_Log(2207, L"RpcPortBinding");
@ -695,7 +695,7 @@ _FX ULONG RpcRt_RpcBindingFromStringBindingW(
if (NT_SUCCESS(RpcRt_FindModulePreset(CallingModule, StringBinding, ModulePreset, sizeof(ModulePreset)))) {
WCHAR tagValue[96];
if (Config_FindTagValue(ModulePreset, L"Resolve", tagValue, sizeof(tagValue), NULL, L','))
if (SbieDll_FindTagValue(ModulePreset, L"Resolve", tagValue, sizeof(tagValue), L'=', L','))
{
WCHAR* pwszTempPortName = GetDynamicLpcPortName(tagValue);
@ -717,7 +717,7 @@ _FX ULONG RpcRt_RpcBindingFromStringBindingW(
// else error let it fail
}
if (Config_FindTagValue(ModulePreset, L"TimeOut", tagValue, sizeof(tagValue), NULL, L','))
if (SbieDll_FindTagValue(ModulePreset, L"TimeOut", tagValue, sizeof(tagValue), L'=', L','))
use_RpcMgmtSetComTimeout = Config_String2Bool(tagValue, use_RpcMgmtSetComTimeout);
}
}
@ -841,17 +841,17 @@ _FX RPC_STATUS RpcRt_RpcBindingCreateW(
WCHAR tagValue[96];
if (RPC_PROTSEQ_LRPC == Template->ProtocolSequence && !Template->StringEndpoint)
{
if (Config_FindTagValue(ModulePreset, L"Resolve", tagValue, sizeof(tagValue), NULL, L','))
if (SbieDll_FindTagValue(ModulePreset, L"Resolve", tagValue, sizeof(tagValue), L'=', L','))
{
Template->StringEndpoint = GetDynamicLpcPortName(tagValue);
}
/*else if (Config_FindTagValue(ModulePreset, L"IpcPort", tagValue, sizeof(tagValue), NULL, L','))
/*else if (SbieDll_FindTagValue(ModulePreset, L"IpcPort", tagValue, sizeof(tagValue), L'=', L','))
{
Template->StringEndpoint = (unsigned short*)...;
}*/
}
if (Config_FindTagValue(ModulePreset, L"TimeOut", tagValue, sizeof(tagValue), NULL, L','))
if (SbieDll_FindTagValue(ModulePreset, L"TimeOut", tagValue, sizeof(tagValue), L'=', L','))
use_RpcMgmtSetComTimeout = Config_String2Bool(tagValue, use_RpcMgmtSetComTimeout);
}
}

View File

@ -206,8 +206,19 @@ SBIEDLL_EXPORT BOOLEAN SbieDll_GetStringForStringList(const WCHAR* string, cons
SBIEDLL_EXPORT BOOLEAN SbieDll_CheckStringInList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting);
//SBIEDLL_EXPORT BOOLEAN SbieDll_GetBoolForStringFromList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting, BOOLEAN def_found, BOOLEAN not_found);
SBIEDLL_EXPORT BOOLEAN SbieDll_GetSettingsForImageName(
const WCHAR* boxname, const WCHAR* image_name, const WCHAR* setting, WCHAR* value, ULONG value_size, const WCHAR* deftext);
SBIEDLL_EXPORT BOOLEAN SbieDll_GetSettingsForImageName_bool(
const WCHAR* boxname, const WCHAR* image_name, const WCHAR* setting, BOOLEAN defval);
SBIEDLL_EXPORT BOOLEAN SbieDll_GetBorderColor(const WCHAR* box_name, COLORREF* color, BOOL* title, int* width);
SBIEDLL_EXPORT WCHAR* SbieDll_GetTagValue(WCHAR* str, WCHAR** value, ULONG* len, WCHAR sep);
typedef BOOLEAN (*SbieDll_TagEnumProc)(WCHAR* name, ULONG name_len, WCHAR* value, ULONG value_len, void* param);
SBIEDLL_EXPORT VOID SbieDll_EnumTagValues(WCHAR* string, SbieDll_TagEnumProc enumProc, void* param, WCHAR eq, WCHAR sep);
SBIEDLL_EXPORT BOOLEAN SbieDll_FindTagValue(WCHAR* string, const WCHAR* name, WCHAR* value, ULONG value_size, WCHAR eq, WCHAR sep);
//---------------------------------------------------------------------------

View File

@ -66,6 +66,10 @@ static NTSTATUS SysInfo_NtCreateJobObject(
HANDLE *JobHandle, ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes);
static NTSTATUS SysInfo_NtOpenJobObject(
HANDLE *JobHandle, ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes);
static NTSTATUS SysInfo_NtAssignProcessToJobObject(
HANDLE JobHandle, HANDLE ProcessHandle);
@ -94,6 +98,7 @@ static P_SetLocaleInfo __sys_SetLocaleInfoW = NULL;
static P_SetLocaleInfo __sys_SetLocaleInfoA = NULL;
static P_NtCreateJobObject __sys_NtCreateJobObject = NULL;
static P_NtOpenJobObject __sys_NtOpenJobObject = NULL;
static P_NtAssignProcessToJobObject __sys_NtAssignProcessToJobObject = NULL;
static P_NtSetInformationJobObject __sys_NtSetInformationJobObject = NULL;
@ -107,6 +112,8 @@ static P_NtTraceEvent __sys_NtTraceEvent = NULL;
static ULONG_PTR *SysInfo_JobCallbackData = NULL;
BOOLEAN SysInfo_UseSbieJob = TRUE;
BOOLEAN SysInfo_CanUseJobs = FALSE;
//---------------------------------------------------------------------------
// SysInfo_Init
@ -122,10 +129,18 @@ _FX BOOLEAN SysInfo_Init(void)
SBIEDLL_HOOK(SysInfo_,NtQuerySystemInformation);
}
extern BOOLEAN Gui_OpenAllWinClasses;
SysInfo_UseSbieJob = !Gui_OpenAllWinClasses && !SbieApi_QueryConfBool(NULL, L"NoAddProcessToJob", FALSE);
if (Dll_OsBuild >= 8400)
SysInfo_CanUseJobs = SbieApi_QueryConfBool(NULL, L"AllowBoxedJobs", FALSE);
SBIEDLL_HOOK(SysInfo_, NtCreateJobObject);
if (!SbieApi_QueryConfBool(NULL, L"NoAddProcessToJob", FALSE))
{
SBIEDLL_HOOK(SysInfo_, NtOpenJobObject);
if (SysInfo_UseSbieJob) {
if (!SysInfo_CanUseJobs) {
SBIEDLL_HOOK(SysInfo_, NtAssignProcessToJobObject);
}
SBIEDLL_HOOK(SysInfo_, NtSetInformationJobObject);
}
@ -375,6 +390,55 @@ _FX void *SysInfo_QueryProcesses(ULONG *out_len)
}
//---------------------------------------------------------------------------
// SysInfo_GetJobName
//---------------------------------------------------------------------------
_FX NTSTATUS SysInfo_GetJobName(OBJECT_ATTRIBUTES* ObjectAttributes, WCHAR** OutCopyPath)
{
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
WCHAR *name;
ULONG objname_len;
WCHAR *objname_buf;
static volatile ULONG JobCounter = 0;
WCHAR dummy_name[MAX_PATH];
*OutCopyPath = NULL;
if (ObjectAttributes && ObjectAttributes->ObjectName) {
objname_len = ObjectAttributes->ObjectName->Length & ~1;
objname_buf = ObjectAttributes->ObjectName->Buffer;
} else {
InterlockedIncrement(&JobCounter);
Sbie_snwprintf(dummy_name, MAX_PATH, L"%s_DummyJob_%s_p%d_t%d_c%d",
SBIE, Dll_ImageName, GetCurrentProcessId(), GetCurrentThreadId(), JobCounter);
objname_len = wcslen(dummy_name);
objname_buf = dummy_name;
}
name = Dll_GetTlsNameBuffer(TlsData, COPY_NAME_BUFFER, Dll_BoxIpcPathLen + objname_len);
*OutCopyPath = name;
wmemcpy(name, Dll_BoxIpcPath, Dll_BoxIpcPathLen);
name += Dll_BoxIpcPathLen;
*name = L'\\';
name++;
wmemcpy(name, objname_buf, objname_len);
name += objname_len;
*name = L'\0';
return STATUS_SUCCESS;
}
//---------------------------------------------------------------------------
// SysInfo_NtCreateJobObject
//---------------------------------------------------------------------------
@ -384,48 +448,56 @@ _FX NTSTATUS SysInfo_NtCreateJobObject(
HANDLE *JobHandle, ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes)
{
static volatile ULONG _JobCounter = 0;
NTSTATUS status;
OBJECT_ATTRIBUTES objattrs;
UNICODE_STRING objname;
WCHAR *jobname;
ULONG jobname_len;
NTSTATUS status;
WCHAR* CopyPath;
//
// the driver requires us to specify a sandboxed path name to a
// job object, and to not request some specific rights
//
if (!SbieApi_QueryConfBool(NULL, L"NoAddProcessToJob", FALSE))
if(!SysInfo_CanUseJobs && SysInfo_UseSbieJob)
DesiredAccess &= ~(JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_TERMINATE);
jobname_len = Dll_BoxIpcPathLen + wcslen(Dll_ImageName) + 64;
jobname = Dll_AllocTemp(jobname_len * sizeof(WCHAR));
while (1) {
InterlockedIncrement(&_JobCounter);
Sbie_snwprintf(jobname, jobname_len, L"%s\\%s_DummyJob_%s_%d",
Dll_BoxIpcPath, SBIE, Dll_ImageName, _JobCounter);
RtlInitUnicodeString(&objname, jobname);
InitializeObjectAttributes(&objattrs,
&objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, Secure_EveryoneSD);
status = __sys_NtCreateJobObject(
JobHandle, DesiredAccess, &objattrs);
//
// we always start each process with _JobCounter = 0 so we have to
// account for the case where a dummy job object was already created
// by another process, and not fail the request
//
if (status != STATUS_OBJECT_NAME_COLLISION)
break;
if (NT_SUCCESS(SysInfo_GetJobName(ObjectAttributes, &CopyPath))) {
RtlInitUnicodeString(&objname, CopyPath);
InitializeObjectAttributes(&objattrs, &objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, Secure_EveryoneSD);
ObjectAttributes = &objattrs;
}
Dll_Free(jobname);
status = __sys_NtCreateJobObject(JobHandle, DesiredAccess, ObjectAttributes);
return status;
}
//---------------------------------------------------------------------------
// SysInfo_NtCreateJobObject
//---------------------------------------------------------------------------
_FX NTSTATUS SysInfo_NtOpenJobObject(
HANDLE* JobHandle, ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES* ObjectAttributes)
{
NTSTATUS status;
OBJECT_ATTRIBUTES objattrs;
UNICODE_STRING objname;
WCHAR* CopyPath;
if(!SysInfo_CanUseJobs && SysInfo_UseSbieJob)
DesiredAccess &= ~(JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_TERMINATE);
if (NT_SUCCESS(SysInfo_GetJobName(ObjectAttributes, &CopyPath))) {
RtlInitUnicodeString(&objname, CopyPath);
InitializeObjectAttributes(&objattrs, &objname, OBJECT_ATTRIBUTES_ATTRIBUTES, NULL, Secure_EveryoneSD);
ObjectAttributes = &objattrs;
}
status = __sys_NtOpenJobObject(JobHandle, DesiredAccess, ObjectAttributes);
return status;
}
@ -461,10 +533,23 @@ _FX NTSTATUS SysInfo_NtSetInformationJobObject(
HANDLE JobHandle, JOBOBJECTINFOCLASS JobObjectInformationClass,
void *JobObjectInformtion, ULONG JobObjectInformtionLength)
{
//
// Since windows 8 we can have nested jobs i.e. we can have all sandboxed processes
// be part of the box isoaltion job and also of for example a chrome sandbox job.
// Howeever we booth jobs can not specify UIRestrictions since our own job allready
// specified those restrictions, we dont allow a boxed process to spesify its own.
//
if (SysInfo_CanUseJobs && JobObjectInformationClass == JobObjectBasicUIRestrictions)
return STATUS_SUCCESS;
NTSTATUS status = __sys_NtSetInformationJobObject(
JobHandle, JobObjectInformationClass,
JobObjectInformtion, JobObjectInformtionLength);
if(SysInfo_CanUseJobs)
return status;
if (NT_SUCCESS(status) &&
JobObjectInformationClass ==
JobObjectAssociateCompletionPortInformation) {

View File

@ -81,8 +81,7 @@ _FX BOOLEAN UserEnv_InitVer(HMODULE module)
void* GetVersionExA;
WCHAR str[32];
NTSTATUS status = Config_GetSettingsForImageName(L"OverrideOsBuild", str, sizeof(str), NULL);
if (NT_SUCCESS(status))
if (SbieDll_GetSettingsForImageName(NULL, Dll_ImageName, L"OverrideOsBuild", str, sizeof(str), NULL))
UserEnv_dwBuildNumber = _wtoi(str);
if (UserEnv_dwBuildNumber == 0 && Dll_OsBuild < 9600)

View File

@ -113,7 +113,7 @@
</ClCompile>
<Link>
<SubSystem>Native</SubSystem>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;Fwpkclnt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
@ -145,7 +145,7 @@
</ClCompile>
<Link>
<SubSystem>Native</SubSystem>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;Fwpkclnt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
@ -185,7 +185,7 @@
</ClCompile>
<Link>
<SubSystem>Native</SubSystem>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;Fwpkclnt.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
@ -215,7 +215,7 @@
</ClCompile>
<Link>
<SubSystem>Native</SubSystem>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ntoskrnl.lib;hal.lib;wmilib.lib;fltmgr.lib;Ksecdd.lib;Fwpkclnt.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
@ -253,12 +253,24 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\map.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\pattern.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\pool.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\stream.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
@ -392,6 +404,7 @@
</ClCompile>
<ClCompile Include="token.c" />
<ClCompile Include="util.c" />
<ClCompile Include="verify.c" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="aulldvrm.asm">
@ -424,6 +437,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\common\map.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\common\my_version.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
@ -436,6 +455,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\common\pool.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\common\stream.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>

View File

@ -124,6 +124,13 @@
<ClCompile Include="file_ctrl.c">
<Filter>file</Filter>
</ClCompile>
<ClCompile Include="..\..\common\map.c">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\common\pool.c">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="verify.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="api.h" />
@ -184,6 +191,12 @@
<ClInclude Include="..\..\common\stream.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\common\map.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\common\pool.h">
<Filter>common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="aulldvrm.asm" />

View File

@ -88,7 +88,7 @@ static NTSTATUS Api_ProcessExemptionControl(PROCESS *proc, ULONG64 *parms);
static P_Api_Function *Api_Functions = NULL;
static DEVICE_OBJECT *Api_DeviceObject = NULL;
DEVICE_OBJECT *Api_DeviceObject = NULL;
static FAST_IO_DISPATCH *Api_FastIoDispatch = NULL;
@ -1072,6 +1072,11 @@ _FX NTSTATUS Api_SetServicePort(PROCESS *proc, ULONG64 *parms)
status = STATUS_SUCCESS;
}
if (NT_SUCCESS(status) && !MyIsCallerSigned()) {
status = STATUS_INVALID_SIGNATURE;
}
//
// take a reference on the specified LPC port object
//

View File

@ -35,12 +35,16 @@
// Defines
//---------------------------------------------------------------------------
//#define USE_CONF_MAP
#define CONF_LINE_LEN 2000 // keep in sync with
#ifdef USE_CONF_MAP
#define CONF_MAX_LINES 100000
#else
#define CONF_MAX_LINES 30000 // SbieCtrl/SbieIni.cpp
#endif
#define CONF_TMPL_LINE_BASE 0x01000000
//---------------------------------------------------------------------------
// Structures
//---------------------------------------------------------------------------
@ -49,7 +53,11 @@
typedef struct _CONF_DATA {
POOL *pool;
#ifdef USE_CONF_MAP
HASH_MAP section_map;
#else
LIST sections; // CONF_SECTION
#endif
BOOLEAN home; // TRUE if configuration read from Driver_Home_Path
ULONG encoding; // 0 - unicode, 1 - utf8, 2 - unicode (byte swaped)
volatile ULONG use_count;
@ -59,7 +67,9 @@ typedef struct _CONF_DATA {
typedef struct _CONF_SECTION {
#ifndef USE_CONF_MAP
LIST_ELEM list_elem;
#endif
WCHAR *name;
LIST settings; // CONF_SETTING
BOOLEAN from_template;
@ -249,7 +259,14 @@ _FX NTSTATUS Conf_Read(ULONG session_id)
else {
data.pool = pool;
#ifdef USE_CONF_MAP
map_init(&data.section_map, data.pool);
data.section_map.func_key_size = &map_wcssize;
data.section_map.func_match_key = &map_wcsimatch;
map_resize(&data.section_map, 16); // prepare some buckets for better performance
#else
List_Init(&data.sections);
#endif
data.home = path_home;
data.use_count = 0;
@ -429,13 +446,16 @@ _FX NTSTATUS Conf_Read_Sections(
//
// find an existing section by that name or create a new one
//
#ifdef USE_CONF_MAP
section = map_get(&data->section_map, &line[1]);
#else
section = List_Head(&data->sections);
while (section) {
if (_wcsicmp(section->name, &line[1]) == 0)
break;
section = List_Next(section);
}
#endif
if (! section) {
@ -458,7 +478,11 @@ _FX NTSTATUS Conf_Read_Sections(
List_Init(&section->settings);
#ifdef USE_CONF_MAP
map_insert(&data->section_map, section->name, section, 0);
#else
List_Insert_After(&data->sections, NULL, section);
#endif
}
// read settings for this section
@ -663,10 +687,17 @@ _FX NTSTATUS Conf_Merge_Templates(CONF_DATA *data, ULONG session_id)
// scan sections to find a sandbox section
//
#ifdef USE_CONF_MAP
map_iter_t iter = map_iter();
while (map_next(&data->section_map, &iter)) {
sandbox = iter.value;
#else
sandbox = List_Head(&data->sections);
while (sandbox) {
CONF_SECTION *next_sandbox = List_Next(sandbox);
#endif
//
// if we found the global section, handle it
@ -679,7 +710,9 @@ _FX NTSTATUS Conf_Merge_Templates(CONF_DATA *data, ULONG session_id)
if (! NT_SUCCESS(status))
return status;
#ifndef USE_CONF_MAP
sandbox = next_sandbox;
#endif
continue;
}
@ -690,7 +723,9 @@ _FX NTSTATUS Conf_Merge_Templates(CONF_DATA *data, ULONG session_id)
if (_wcsnicmp(sandbox->name, Conf_Template_, 9) == 0 ||
_wcsnicmp(sandbox->name, Conf_UserSettings_, 13) == 0) {
#ifndef USE_CONF_MAP
sandbox = next_sandbox;
#endif
continue;
}
@ -731,11 +766,13 @@ _FX NTSTATUS Conf_Merge_Templates(CONF_DATA *data, ULONG session_id)
setting = List_Head(&sandbox->settings);
}
#ifndef USE_CONF_MAP
//
// advance to next section
//
sandbox = next_sandbox;
#endif
}
return STATUS_SUCCESS;
@ -772,10 +809,17 @@ _FX NTSTATUS Conf_Merge_Global(
// scan sections to find a sandbox section
//
#ifdef USE_CONF_MAP
map_iter_t iter = map_iter();
while (map_next(&data->section_map, &iter)) {
sandbox = iter.value;
#else
sandbox = List_Head(&data->sections);
while (sandbox) {
CONF_SECTION *next_sandbox = List_Next(sandbox);
#endif
//
// skip the global section
@ -783,7 +827,9 @@ _FX NTSTATUS Conf_Merge_Global(
if (_wcsicmp(sandbox->name, Conf_GlobalSettings) == 0) {
#ifndef USE_CONF_MAP
sandbox = next_sandbox;
#endif
continue;
}
@ -794,7 +840,9 @@ _FX NTSTATUS Conf_Merge_Global(
if (_wcsnicmp(sandbox->name, Conf_Template_, 9) == 0 ||
_wcsnicmp(sandbox->name, Conf_UserSettings_, 13) == 0) {
#ifndef USE_CONF_MAP
sandbox = next_sandbox;
#endif
continue;
}
@ -808,11 +856,13 @@ _FX NTSTATUS Conf_Merge_Global(
if (! NT_SUCCESS(status))
return status;
#ifndef USE_CONF_MAP
//
// advance to next section
//
sandbox = next_sandbox;
#endif
}
//
@ -839,8 +889,16 @@ _FX NTSTATUS Conf_Merge_Template(
// scan for a matching template section
//
#ifdef USE_CONF_MAP
CONF_SECTION *tmpl = NULL;
map_iter_t iter = map_iter();
while (map_next(&data->section_map, &iter)) {
tmpl = iter.value;
#else
CONF_SECTION *tmpl = List_Head(&data->sections);
while (tmpl) {
#endif
if (wcslen(tmpl->name) >= 10 &&
_wcsnicmp(tmpl->name, Conf_Template_, 9) == 0 &&
@ -849,7 +907,11 @@ _FX NTSTATUS Conf_Merge_Template(
break;
}
#ifndef USE_CONF_MAP
tmpl = List_Next(tmpl);
#else
tmpl = NULL;
#endif
}
//
@ -910,16 +972,19 @@ _FX const WCHAR *Conf_Get_Helper(
value = NULL;
#ifdef USE_CONF_MAP
section = map_get(&Conf_Data.section_map, section_name);
#else
section = List_Head(&Conf_Data.sections);
while (section) {
//DbgPrint(" Examining section at %X name %S (looking for %S)\n", section, section->name, section_name);
if (_wcsicmp(section->name, section_name) == 0) {
if (skip_tmpl && section->from_template)
section = NULL;
if (_wcsicmp(section->name, section_name) == 0)
break;
}
section = List_Next(section);
}
#endif
if (skip_tmpl && section && section->from_template)
section = NULL;
if (section)
setting = List_Head(&section->settings);
@ -958,21 +1023,36 @@ _FX const WCHAR *Conf_Get_Section_Name(ULONG index, BOOLEAN skip_tmpl)
value = NULL;
#ifdef USE_CONF_MAP
map_iter_t iter = map_iter();
while (map_next(&Conf_Data.section_map, &iter)) {
section = iter.value;
#else
section = List_Head(&Conf_Data.sections);
while (section) {
CONF_SECTION *next_section = List_Next(section);
if (_wcsicmp(section->name, Conf_GlobalSettings) == 0)
#endif
if (_wcsicmp(section->name, Conf_GlobalSettings) == 0) {
#ifndef USE_CONF_MAP
section = next_section;
else if (skip_tmpl && section->from_template)
#endif
continue;
}
if (skip_tmpl && section->from_template) {
#ifndef USE_CONF_MAP
section = next_section;
else if (index == 0) {
#endif
continue;
}
if (index == 0) {
value = section->name;
break;
} else {
--index;
section = next_section;
}
--index;
#ifndef USE_CONF_MAP
section = next_section;
#endif
}
return value;
@ -994,15 +1074,18 @@ _FX const WCHAR *Conf_Get_Setting_Name(
value = NULL;
#ifdef USE_CONF_MAP
section = map_get(&Conf_Data.section_map, section_name);
#else
section = List_Head(&Conf_Data.sections);
while (section) {
if (_wcsicmp(section->name, section_name) == 0) {
if (skip_tmpl && section->from_template)
section = NULL;
if (_wcsicmp(section->name, section_name) == 0)
break;
}
section = List_Next(section);
}
#endif
if (skip_tmpl && section && section->from_template)
section = NULL;
if (section)
setting = List_Head(&section->settings);
@ -1193,12 +1276,16 @@ _FX NTSTATUS Conf_IsValidBox(const WCHAR *section_name)
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceSharedLite(Conf_Lock, TRUE);
#ifdef USE_CONF_MAP
section = map_get(&Conf_Data.section_map, section_name);
#else
section = List_Head(&Conf_Data.sections);
while (section) {
if (_wcsicmp(section->name, section_name) == 0)
break;
section = List_Next(section);
}
#endif
if (! section)
status = STATUS_OBJECT_NAME_NOT_FOUND;
@ -1247,7 +1334,14 @@ _FX NTSTATUS Conf_Api_Reload(PROCESS *proc, ULONG64 *parms)
pool = Conf_Data.pool;
Conf_Data.pool = NULL;
#ifdef USE_CONF_MAP
map_init(&Conf_Data.section_map, Conf_Data.pool);
Conf_Data.section_map.func_key_size = &map_wcssize;
Conf_Data.section_map.func_match_key = &map_wcsimatch;
map_resize(&Conf_Data.section_map, 16); // prepare some buckets for better performance
#else
List_Init(&Conf_Data.sections);
#endif
Conf_Data.home = FALSE;
Conf_Data.encoding = 0;
@ -1409,7 +1503,13 @@ release_and_return:
_FX BOOLEAN Conf_Init(void)
{
Conf_Data.pool = NULL;
#ifdef USE_CONF_MAP
map_init(&Conf_Data.section_map, NULL);
Conf_Data.section_map.func_key_size = &map_wcssize;
Conf_Data.section_map.func_match_key = &map_wcsimatch;
#else
List_Init(&Conf_Data.sections);
#endif
Conf_Data.home = FALSE;
Conf_Data.encoding = 0;

View File

@ -718,7 +718,11 @@ _FX NTSTATUS Driver_Api_Unload(PROCESS *proc, ULONG64 *parms)
ExAcquireResourceExclusiveLite(Process_ListLock, TRUE);
ok = FALSE;
#ifdef USE_PROCESS_MAP
if (Process_Map.nnodes == 0) {
#else
if (! List_Count(&Process_List)) {
#endif
if (Api_Disable())
ok = TRUE;
}

View File

@ -37,6 +37,7 @@
#include "common/defines.h"
#include "common/list.h"
#include "common/map.h"
#include "common/pool.h"
#include "common/ntproto.h"
#include "log.h"
@ -66,6 +67,8 @@
#define TRACE_DENY 2
#define TRACE_IGNORE 4
#define USE_PROCESS_MAP
//new FILE_INFORMATION_CLASS type not defined in current wdm.h used in windows 10 FCU
#define SB_FileRenameInformationEx 65
//---------------------------------------------------------------------------

View File

@ -55,6 +55,10 @@ extern const ULONG tzuk;
#include "common/pattern.c"
#undef Pool_Alloc
/* map */
#include "common/map.c"
/* CRC */
//#define CRC_WITH_ADLERTZUK64

View File

@ -1006,9 +1006,10 @@ _FX NTSTATUS Ipc_CheckJobObject(
// is inside the sandbox
//
if (!Conf_Get_Boolean(proc->box->name, L"NoAddProcessToJob", 0, FALSE))
if (!proc->can_use_jobs) {
if (GrantedAccess & (JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_TERMINATE))
return STATUS_ACCESS_DENIED;
}
if (! Name->Length)
return STATUS_ACCESS_DENIED;

View File

@ -599,8 +599,8 @@ _FX NTSTATUS Ipc_Api_OpenDynamicPort(PROCESS* proc, ULONG64* parms)
if (proc) // is caller sandboxed?
return STATUS_ACCESS_DENIED;
//if (PsGetCurrentProcessId() != Api_ServiceProcessId)
// return STATUS_ACCESS_DENIED;
if (PsGetCurrentProcessId() != Api_ServiceProcessId)
return STATUS_ACCESS_DENIED;
if (pArgs->port_name.val == NULL)
return STATUS_INVALID_PARAMETER;

View File

@ -190,10 +190,12 @@ _FX NTSTATUS Key_Callback(void *Context, void *Arg1, void *Arg2)
//
// check if the caller is sandboxed before proceeding
//
if (Driver_OsBuild < DRIVER_BUILD_WINDOWS_10_CU)
{
proc = Process_Find(NULL, NULL);
if (proc == PROCESS_TERMINATED)
return STATUS_PROCESS_IS_TERMINATING;
}
Info = (REG_OPEN_CREATE_KEY_INFORMATION_VISTA *)Arg2;

View File

@ -171,3 +171,4 @@ int __cdecl memcmp(
return (RtlCompareMemory(_Buf1, _Buf2, _Size) == _Size) ? 0 : 1;
}
#endif

View File

@ -71,7 +71,10 @@ BOOLEAN Mem_GetLockResource(PERESOURCE *ppResource, BOOLEAN InitMsg);
void Mem_FreeLockResource(PERESOURCE *ppResource);
//---------------------------------------------------------------------------
#endif // _MY_MEM_H

View File

@ -85,8 +85,13 @@ static void Process_NotifyImage(
//---------------------------------------------------------------------------
#ifdef USE_PROCESS_MAP
HASH_MAP Process_Map;
HASH_MAP Process_MapDfp;
#else
LIST Process_List;
LIST Process_ListDfp;
#endif
PERESOURCE Process_ListLock = NULL;
static BOOLEAN Process_NotifyImageInstalled = FALSE;
@ -110,8 +115,16 @@ _FX BOOLEAN Process_Init(void)
{
NTSTATUS status;
#ifdef USE_PROCESS_MAP
map_init(&Process_Map, Driver_Pool);
map_resize(&Process_Map, 128); // prepare some buckets for better performance
map_init(&Process_MapDfp, Driver_Pool);
map_resize(&Process_MapDfp, 128); // prepare some buckets for better performance
#else
List_Init(&Process_List);
List_Init(&Process_ListDfp);
#endif
if (! Mem_GetLockResource(&Process_ListLock, TRUE))
return FALSE;
@ -421,14 +434,16 @@ _FX PROCESS *Process_Find(HANDLE ProcessId, KIRQL *out_irql)
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceSharedLite(Process_ListLock, TRUE);
#ifdef USE_PROCESS_MAP
proc = map_get(&Process_Map, ProcessId);
if (proc) {
#else
proc = List_Head(&Process_List);
if (check_terminated) {
while (proc) {
if (proc->pid == ProcessId) {
#endif
if (proc->terminated) {
if (check_terminated && proc->terminated) {
//
// ntdll is going to call NtRaiseHardError before
// aborting, so disable hard errors to avoid the
@ -448,19 +463,12 @@ _FX PROCESS *Process_Find(HANDLE ProcessId, KIRQL *out_irql)
proc = PROCESS_TERMINATED;
}
#ifndef USE_PROCESS_MAP
break;
}
proc = List_Next(proc);
}
} else {
while (proc) {
if (proc->pid == ProcessId)
break;
proc = List_Next(proc);
}
#endif
}
if (out_irql) {
@ -530,7 +538,11 @@ _FX void Process_CreateTerminated(HANDLE ProcessId, ULONG SessionId)
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(Process_ListLock, TRUE);
#ifdef USE_PROCESS_MAP
map_insert(&Process_Map, ProcessId, proc, 0);
#else
List_Insert_After(&Process_List, NULL, proc);
#endif
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);
@ -719,7 +731,11 @@ _FX PROCESS *Process_Create(
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(Process_ListLock, TRUE);
#ifdef USE_PROCESS_MAP
map_insert(&Process_Map, ProcessId, proc, 0);
#else
List_Insert_After(&Process_List, NULL, proc);
#endif
*out_irql = irql;
@ -1071,8 +1087,19 @@ _FX void Process_NotifyProcess_Create(
if (new_proc->open_all_win_classes || Conf_Get_Boolean(new_proc->box->name, L"NoAddProcessToJob", 0, FALSE)) {
new_proc->can_use_jobs = TRUE;
add_process_to_job = FALSE;
}
else if (Driver_OsVersion >= DRIVER_WINDOWS_8) {
//
// on windows 8 and later we can have nested jobs so asigning a
// boxed job to a process will not interfear with the job assigned by SbieSvc
//
new_proc->can_use_jobs = Conf_Get_Boolean(new_proc->box->name, L"AllowBoxedJobs", 0, FALSE);
}
//
// on Windows Vista, a forced process may start inside a
@ -1148,6 +1175,9 @@ _FX void Process_Delete(HANDLE ProcessId)
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(Process_ListLock, TRUE);
#ifdef USE_PROCESS_MAP
proc = map_remove(&Process_Map, ProcessId);
#else
proc = List_Head(&Process_List);
while (proc) {
if (proc->pid == ProcessId) {
@ -1156,6 +1186,7 @@ _FX void Process_Delete(HANDLE ProcessId)
}
proc = (PROCESS *)List_Next(proc);
}
#endif
Process_DfpDelete(ProcessId);
@ -1310,7 +1341,7 @@ _FX void Process_NotifyImage(
proc->terminated = TRUE;
proc->reason = (!fail) ? -1 : 0;
Process_CancelProcess(proc);
Process_TerminateProcess(proc);
}
//DbgPrint("IMAGE LOADED, PROCESS INITIALIZATION %d COMPLETE %d\n", proc->pid, ok);

View File

@ -51,7 +51,9 @@ struct _PROCESS {
// changes to the linked list of PROCESS blocks are synchronized by
// an exclusive lock on Process_ListLock
#ifndef USE_PROCESS_MAP
LIST_ELEM list_elem;
#endif
// process id
@ -95,7 +97,11 @@ struct _PROCESS {
PERESOURCE threads_lock;
#ifdef USE_PROCESS_MAP
HASH_MAP thread_map;
#else
LIST threads;
#endif
// flags
@ -120,6 +126,7 @@ struct _PROCESS {
BOOLEAN change_notify_token_flag;
BOOLEAN in_pca_job;
BOOLEAN can_use_jobs;
UCHAR create_console_flag;
@ -263,6 +270,18 @@ const WCHAR *Process_MatchPath(
BOOLEAN *is_open, BOOLEAN *is_closed);
// Process_GetConf: retrives a configuration data value for a given process
// use with Conf_AdjustUseCount to make sure the returned pointer is valid
const WCHAR* Process_GetConf(PROCESS* proc, const WCHAR* setting);
// Process_GetConf_bool: parses a y/n setting. this function does not
// have to be protected with Conf_AdjustUseCount
BOOLEAN Process_GetConf_bool(PROCESS* proc, const WCHAR* setting, BOOLEAN def);
// Build a standard entry for hooks. The standard entry calls
// Process_Find(NULL, NULL). If non-zero (this includes -1 for
// PROCESS_TERMINATED), the entry jumps to NewProc, where
@ -282,10 +301,6 @@ void Process_DisableHookEntry(ULONG_PTR HookEntry);
PROCESS *Process_GetCurrent(void);
// Check for use of multiple sandboxes at once
BOOLEAN Process_CheckTooManyBoxes(const BOX *box);
// Returns ProcessName.exe for idProcess, allocated from the specified pool.
// On return, *out_buf points to a UNICODE_STRING structure which points
@ -362,11 +377,17 @@ void Process_LogMessage(PROCESS *proc, ULONG msgid);
//void Process_TrackProcessLimit(PROCESS *proc);
// Terminate process
BOOLEAN Process_TerminateProcess(PROCESS *proc);
// Cancel process through SbieSvc
void Process_CancelProcess(PROCESS *proc);
BOOLEAN Process_CancelProcess(PROCESS *proc);
// Terminate a process using a helper thread
BOOLEAN Process_ScheduleKill(PROCESS *proc);
// Check if process is running within a
// Program Compatibility Assistant (PCA) job
@ -416,8 +437,13 @@ NTSTATUS Process_Api_Enum(PROCESS *proc, ULONG64 *parms);
//---------------------------------------------------------------------------
#ifdef USE_PROCESS_MAP
extern HASH_MAP Process_Map;
extern HASH_MAP Process_MapDfp;
#else
extern LIST Process_List;
extern LIST Process_ListDfp;
#endif
extern PERESOURCE Process_ListLock;
extern volatile BOOLEAN Process_ReadyToSandbox;

View File

@ -830,9 +830,26 @@ _FX NTSTATUS Process_Enumerate(
__try {
num = 0;
#ifdef USE_PROCESS_MAP
//
// quick shortcut for global count retrival
//
if (pids == NULL && (! boxname[0]) && all_sessions) { // no pids, all boxes, all sessions
num = Process_Map.nnodes;
goto done;
}
map_iter_t iter = map_iter();
while (map_next(&Process_Map, &iter)) {
proc1 = iter.value;
#else
proc1 = List_Head(&Process_List);
while (proc1) {
#endif
BOX *box1 = proc1->box;
if (box1 && !proc1->bHostInject) {
BOOLEAN same_box =
@ -849,9 +866,12 @@ _FX NTSTATUS Process_Enumerate(
}
}
#ifndef USE_PROCESS_MAP
proc1 = (PROCESS *)List_Next(proc1);
#endif
}
done:
*count = num;
status = STATUS_SUCCESS;

View File

@ -70,7 +70,9 @@ typedef struct _FORCE_PROCESS {
typedef struct _FORCE_PROCESS_2 {
#ifndef USE_PROCESS_MAP
LIST_ELEM list_elem;
#endif
HANDLE pid;
BOOLEAN silent;
@ -1648,7 +1650,11 @@ _FX BOOLEAN Process_DfpInsert(HANDLE ParentId, HANDLE ProcessId)
proc->pid = ProcessId;
proc->silent = FALSE;
#ifdef USE_PROCESS_MAP
map_insert(&Process_MapDfp, ProcessId, proc, 0);
#else
List_Insert_After(&Process_ListDfp, NULL, proc);
#endif
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);
@ -1665,23 +1671,34 @@ _FX BOOLEAN Process_DfpInsert(HANDLE ParentId, HANDLE ProcessId)
added = FALSE;
#ifdef USE_PROCESS_MAP
proc = map_get(&Process_MapDfp, ParentId);
if (proc) {
#else
proc = List_Head(&Process_ListDfp);
while (proc) {
if (proc->pid == ParentId) {
#endif
proc = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS_2));
proc->pid = ProcessId;
proc->silent = FALSE;
#ifdef USE_PROCESS_MAP
map_insert(&Process_MapDfp, ProcessId, proc, 0);
#else
List_Insert_After(&Process_ListDfp, NULL, proc);
#endif
added = TRUE;
#ifndef USE_PROCESS_MAP
break;
}
proc = List_Next(proc);
#endif
}
}
@ -1698,6 +1715,11 @@ _FX void Process_DfpDelete(HANDLE ProcessId)
{
FORCE_PROCESS_2 *proc;
#ifdef USE_PROCESS_MAP
proc = map_remove(&Process_MapDfp, ProcessId);
if(proc)
Mem_Free(proc, sizeof(FORCE_PROCESS_2));
#else
proc = List_Head(&Process_ListDfp);
while (proc) {
@ -1712,6 +1734,7 @@ _FX void Process_DfpDelete(HANDLE ProcessId)
proc = List_Next(proc);
}
#endif
}
@ -1729,10 +1752,15 @@ _FX BOOLEAN Process_DfpCheck(HANDLE ProcessId, BOOLEAN *silent)
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(Process_ListLock, TRUE);
#ifdef USE_PROCESS_MAP
proc = map_get(&Process_MapDfp, ProcessId);
if (proc) {
#else
proc = List_Head(&Process_ListDfp);
while (proc) {
if (proc->pid == ProcessId) {
#endif
if (*silent)
proc->silent = TRUE;
@ -1740,10 +1768,12 @@ _FX BOOLEAN Process_DfpCheck(HANDLE ProcessId, BOOLEAN *silent)
*silent = proc->silent;
found = TRUE;
#ifndef USE_PROCESS_MAP
break;
}
proc = List_Next(proc);
#endif
}
ExReleaseResourceLite(Process_ListLock);

View File

@ -228,7 +228,7 @@ _FX BOOLEAN Process_Low_Inject(
dummy_proc.create_time = create_time;
dummy_proc.image_name = (WCHAR *)image_name;
Process_CancelProcess(&dummy_proc);
Process_TerminateProcess(&dummy_proc);
}
Log_Status_Ex_Process(MSG_1231, 0x22, status, image_name, session_id, process_id);

View File

@ -113,46 +113,6 @@ _FX BOOLEAN Process_IsSameBox(
}
//---------------------------------------------------------------------------
// Process_CheckTooManyBoxes
//---------------------------------------------------------------------------
_FX BOOLEAN Process_CheckTooManyBoxes(const BOX *box)
{
PROCESS *proc;
BOOLEAN ok;
KIRQL irql;
// if the user account of the caller has an active sandbox,
// then a new process must be started in that same sandbox.
// note that we intentionally don't look at logon sessions here.
ok = TRUE;
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceSharedLite(Process_ListLock, TRUE);
proc = List_Head(&Process_List);
while (proc) {
if (! proc->terminated) {
if (wcscmp(proc->box->sid, box->sid) == 0) {
if (_wcsicmp(proc->box->name, box->name) != 0) {
ok = FALSE;
break;
}
}
}
proc = (PROCESS *)List_Next(proc);
}
ExReleaseResourceLite(Process_ListLock);
KeLowerIrql(irql);
return (! ok);
}
//---------------------------------------------------------------------------
// Process_MatchImage
//---------------------------------------------------------------------------
@ -319,6 +279,123 @@ _FX BOOLEAN Process_MatchImageGroup(
}
//---------------------------------------------------------------------------
// Process_MatchImageAndGetValue
//---------------------------------------------------------------------------
_FX const WCHAR* Process_MatchImageAndGetValue(BOX *box, const WCHAR* value, const WCHAR* ImageName, ULONG* pLevel)
{
WCHAR* tmp;
ULONG len;
//
// if the setting indicates an image name followed by a comma,
// then match the image name against the executing process.
//
tmp = wcschr(value, L',');
if (tmp) {
BOOLEAN inv, match;
//
// exclamation marks negates the matching
//
if (*value == L'!') {
inv = TRUE;
++value;
} else
inv = FALSE;
len = (ULONG)(tmp - value);
if (len) {
match = Process_MatchImage(box, value, len, ImageName, 1);
if (inv)
match = !match;
if (!match)
return NULL;
else if (pLevel) {
if (len == 1 && *value == L'*')
*pLevel = 2; // 2 - match all
else
*pLevel = inv ? 1 : 0; // 1 - match by negation, 0 - exact match
}
}
value = tmp + 1;
}
else {
if (pLevel) *pLevel = 2; // 2 - global default
}
if (! *value)
return NULL;
return value;
}
//---------------------------------------------------------------------------
// Process_GetConf
//---------------------------------------------------------------------------
_FX const WCHAR* Process_GetConf(PROCESS *proc, const WCHAR* setting)
{
ULONG index = 0;
const WCHAR *value;
const WCHAR *found_value = NULL;
ULONG found_level = -1;
for (index = 0; ; ++index) {
value = Conf_Get(proc->box->name, setting, index);
if (! value)
break;
ULONG level = -1;
value = Process_MatchImageAndGetValue(proc->box, value, proc->image_name, &level);
if (!value || level > found_level)
continue;
found_value = value;
found_level = level;
}
return found_value;
}
//---------------------------------------------------------------------------
// Process_GetConf_bool
//---------------------------------------------------------------------------
_FX BOOLEAN Process_GetConf_bool(PROCESS *proc, const WCHAR* setting, BOOLEAN def)
{
const WCHAR *value;
BOOLEAN retval;
Conf_AdjustUseCount(TRUE);
value = Process_GetConf(proc, setting);
retval = def;
if (value) {
if (*value == 'y' || *value == 'Y')
retval = TRUE;
else if (*value == 'n' || *value == 'N')
retval = FALSE;
}
Conf_AdjustUseCount(FALSE);
return retval;
}
//---------------------------------------------------------------------------
// Process_GetPaths
//---------------------------------------------------------------------------
@ -486,40 +563,9 @@ _FX BOOLEAN Process_AddPath(
}
}
//
// if the setting indicates an image name followed by a comma,
// then match the image name against the executing process.
//
value = Process_MatchImageAndGetValue(proc->box, value, proc->image_name, NULL);
tmp = wcschr(value, L',');
if (tmp) {
BOOLEAN inv, match;
//
// exclamation marks negates the matching
//
if (*value == L'!') {
inv = TRUE;
++value;
} else
inv = FALSE;
len = (ULONG)(tmp - value);
if (len) {
match = Process_MatchImage(
proc->box, value, len, proc->image_name, 1);
if (inv)
match = ! match;
if (! match)
return TRUE;
}
value = tmp + 1;
}
if (! *value)
if (!value)
return TRUE;
//
@ -1032,12 +1078,29 @@ _FX void Process_LogMessage(PROCESS *proc, ULONG msgid)
//}
//---------------------------------------------------------------------------
// Process_TerminateProcess
//---------------------------------------------------------------------------
_FX BOOLEAN Process_TerminateProcess(PROCESS* proc)
{
if (Conf_Get_Boolean(NULL, L"TerminateUsingService", 0, FALSE)) {
if (Process_CancelProcess(proc))
return TRUE;
}
return Process_ScheduleKill(proc);
}
//---------------------------------------------------------------------------
// Process_CancelProcess
//---------------------------------------------------------------------------
_FX void Process_CancelProcess(PROCESS *proc)
_FX BOOLEAN Process_CancelProcess(PROCESS *proc)
{
SVC_PROCESS_MSG msg;
@ -1055,7 +1118,7 @@ _FX void Process_CancelProcess(PROCESS *proc)
msg.add_to_job = FALSE;
msg.reason = proc->reason;
Api_SendServiceMessage(SVC_CANCEL_PROCESS, sizeof(msg), &msg);
return Api_SendServiceMessage(SVC_CANCEL_PROCESS, sizeof(msg), &msg);
}
@ -1107,3 +1170,77 @@ _FX BOOLEAN Process_IsInPcaJob(HANDLE ProcessId)
return IsInPcaJob;
}
//---------------------------------------------------------------------------
// Process_ScheduleKillProc
//---------------------------------------------------------------------------
_FX VOID Process_ScheduleKillProc(IN PVOID StartContext)
{
NTSTATUS status;
HANDLE process_id = (HANDLE)StartContext;
HANDLE handle = NULL;
PEPROCESS ProcessObject;
__try {
status = PsLookupProcessByProcessId(process_id, &ProcessObject);
if (NT_SUCCESS(status)) {
status = ObOpenObjectByPointer(ProcessObject, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, NULL, KernelMode, &handle);
ObDereferenceObject(ProcessObject);
if (NT_SUCCESS(status)) {
ZwTerminateProcess(handle, STATUS_PROCESS_IS_TERMINATING);
ZwClose(handle);
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
}
PsTerminateSystemThread(status);
}
//---------------------------------------------------------------------------
// Process_ScheduleKill
//---------------------------------------------------------------------------
_FX BOOLEAN Process_ScheduleKill(PROCESS *proc)
{
NTSTATUS status;
OBJECT_ATTRIBUTES objattrs;
HANDLE handle;
InitializeObjectAttributes(&objattrs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = PsCreateSystemThread(&handle, THREAD_ALL_ACCESS, &objattrs, NULL, NULL, Process_ScheduleKillProc, proc->pid);
if (NT_SUCCESS(status)) {
ZwClose(handle);
ULONG len = proc->image_name_len + 32 * sizeof(WCHAR);
WCHAR *text = Mem_Alloc(Driver_Pool, len);
if (text) {
if (proc->reason == 0)
RtlStringCbPrintfW(text, len, L"%s", proc->image_name);
else if (proc->reason != -1) // in this case we have SBIE1308 and dont want any other messages
RtlStringCbPrintfW(text, len, L"%s [%d]", proc->image_name, proc->reason);
else
*text = 0;
proc->reason = -1; // avoid repeated messages if this gets re triggered
if (*text)
Log_MsgP1(MSG_2314, text, proc->pid);
Mem_Free(text, len);
}
return TRUE;
}
return FALSE;
}

View File

@ -422,6 +422,8 @@ _FX NTSTATUS Session_Api_Leader(PROCESS *proc, ULONG64 *parms)
if (proc)
status = STATUS_NOT_IMPLEMENTED;
//else if (!MyIsCallerSigned())
// status = STATUS_ACCESS_DENIED;
else {
session = Session_Get(TRUE, -1, &irql);

View File

@ -29,6 +29,7 @@
#include "api.h"
#include "util.h"
#include "session.h"
#include "conf.h"
@ -733,7 +734,7 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
if (proc->terminated) {
Process_CancelProcess(proc);
Process_TerminateProcess(proc);
return STATUS_PROCESS_IS_TERMINATING;
}
@ -902,9 +903,9 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
DbgPrint("[syscall] request p=%06d t=%06d - END (%0X) %s\n", PsGetCurrentProcessId(), PsGetCurrentThreadId(), status, entry->name);
}*/
if (proc->terminated) {
if (proc->terminated || (proc && Conf_Get_Boolean(proc->box->name, L"screwUp", 0, FALSE))) {
Process_CancelProcess(proc);
Process_TerminateProcess(proc);
return STATUS_PROCESS_IS_TERMINATING;
}
@ -951,7 +952,7 @@ _FX NTSTATUS Syscall_Api_Query(PROCESS *proc, ULONG64 *parms)
// caller must be our service process
//
if (proc)// || (PsGetCurrentProcessId() != Api_ServiceProcessId))
if (proc || (PsGetCurrentProcessId() != Api_ServiceProcessId))
return STATUS_ACCESS_DENIED;
//

View File

@ -703,6 +703,7 @@ _FX SYSCALL_ENTRY *Syscall_DuplicateHandle_3(
USHORT TypeLength, WCHAR *TypeBuffer)
{
static const WCHAR *_Port = L"Port";
static const WCHAR *_Job = L"Job";
SYSCALL_ENTRY *entry;
ULONG name_len;
UCHAR SyscallName[32];
@ -723,6 +724,10 @@ _FX SYSCALL_ENTRY *Syscall_DuplicateHandle_3(
strcpy(SyscallName, "ConnectPort");
} else if (TypeLength == 3 && wmemcmp(TypeBuffer, _Job, 3) == 0) {
strcpy(SyscallName, "OpenJobObject");
} else if (TypeLength <= 24) {
memcpy(SyscallName, "Open", 4);

View File

@ -52,7 +52,9 @@
struct _THREAD {
#ifndef USE_PROCESS_MAP
LIST_ELEM list_elem;
#endif
HANDLE tid;
@ -274,12 +276,19 @@ _FX void Thread_Notify(HANDLE ProcessId, HANDLE ThreadId, BOOLEAN Create)
ExAcquireResourceExclusiveLite(proc->threads_lock, TRUE);
#ifdef USE_PROCESS_MAP
if (Create)
thrd = map_get(&proc->thread_map, ThreadId);
else // remove
thrd = map_remove(&proc->thread_map, ThreadId);
#else
thrd = List_Head(&proc->threads);
while (thrd) {
if (thrd->tid == ThreadId)
break;
thrd = List_Next(thrd);
}
#endif
if (thrd) {
@ -293,7 +302,9 @@ _FX void Thread_Notify(HANDLE ProcessId, HANDLE ThreadId, BOOLEAN Create)
TokenObject = InterlockedExchangePointer(
&thrd->token_object, NULL);
#ifndef USE_PROCESS_MAP
List_Remove(&proc->threads, thrd);
#endif
Mem_Free(thrd, sizeof(THREAD));
}
}
@ -321,7 +332,12 @@ _FX BOOLEAN Thread_InitProcess(PROCESS *proc)
if (! proc->threads_lock) {
#ifdef USE_PROCESS_MAP
map_init(&proc->thread_map, proc->pool);
map_resize(&proc->thread_map, 32); // prepare some buckets for better performance
#else
List_Init(&proc->threads);
#endif
ok = Mem_GetLockResource(&proc->threads_lock, FALSE);
if (! ok)
@ -357,15 +373,23 @@ _FX void Thread_ReleaseProcess(PROCESS *proc)
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(proc->threads_lock, TRUE);
#ifdef USE_PROCESS_MAP
map_iter_t iter = map_iter();
while (map_next(&proc->thread_map, &iter)) {
thrd = iter.value;
#else
thrd = List_Head(&proc->threads);
while (thrd) {
#endif
TokenObject = InterlockedExchangePointer(
&thrd->token_object, NULL);
if (TokenObject)
break;
#ifndef USE_PROCESS_MAP
thrd = List_Next(thrd);
#endif
}
ExReleaseResourceLite(proc->threads_lock);
@ -492,12 +516,16 @@ _FX THREAD *Thread_GetCurrent(PROCESS *proc)
KeRaiseIrql(APC_LEVEL, &irql);
ExAcquireResourceExclusiveLite(proc->threads_lock, TRUE);
#ifdef USE_PROCESS_MAP
thrd = map_get(&proc->thread_map, tid);
#else
thrd = List_Head(&proc->threads);
while (thrd) {
if (thrd->tid == tid)
break;
thrd = List_Next(thrd);
}
#endif
ExReleaseResourceLite(proc->threads_lock);
KeLowerIrql(irql);
@ -517,19 +545,27 @@ _FX THREAD *Thread_GetOrCreate(PROCESS *proc, HANDLE tid, BOOLEAN create)
if (! tid)
tid = PsGetCurrentThreadId();
#ifdef USE_PROCESS_MAP
thrd = map_get(&proc->thread_map, tid);
#else
thrd = List_Head(&proc->threads);
while (thrd) {
if (thrd->tid == tid)
break;
thrd = List_Next(thrd);
}
#endif
if ((! thrd) && create) {
thrd = Mem_Alloc(proc->pool, sizeof(THREAD));
if (thrd) {
memzero(thrd, sizeof(THREAD));
thrd->tid = tid;
#ifdef USE_PROCESS_MAP
map_insert(&proc->thread_map, tid, thrd, 0);
#else
List_Insert_After(&proc->threads, NULL, thrd);
#endif
}
}

View File

@ -278,3 +278,27 @@ void *memmem(const void *pSearchBuf,
return NULL;
}
//---------------------------------------------------------------------------
// MyIsCallerSigned
//---------------------------------------------------------------------------
NTSTATUS KphVerifyCurrentProcess();
_FX BOOLEAN MyIsCallerSigned(void)
{
NTSTATUS status;
status = KphVerifyCurrentProcess();
DbgPrint("Image Signature Verification result: 0x%08x\r\n", status);
if (!NT_SUCCESS(status)) {
Log_Status(MSG_1330, 0, status);
return FALSE;
}
return TRUE;
}

View File

@ -92,6 +92,15 @@ BOOLEAN DoesRegValueExist(ULONG RelativeTo, WCHAR *Path, WCHAR *ValueName);
BOOLEAN GetRegString(ULONG RelativeTo, WCHAR *Path, WCHAR *ValueName, UNICODE_STRING* pData);
void *memmem(const void *pSearchBuf, size_t nBufSize, const void *pPattern, size_t nPatternSize);
//
// return TRUE if current process has a valid custom signature
//
BOOLEAN MyIsCallerSigned(void);
//---------------------------------------------------------------------------

340
Sandboxie/core/drv/verify.c Normal file
View File

@ -0,0 +1,340 @@
/*
* Copyright (C) 2016 wj32
* Copyright (C) 2021 David Xanatos, xanasoft.com
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "driver.h"
#include <bcrypt.h>
#ifdef __BCRYPT_H__
#define KPH_SIGN_ALGORITHM BCRYPT_ECDSA_P256_ALGORITHM
#define KPH_SIGN_ALGORITHM_BITS 256
#define KPH_HASH_ALGORITHM BCRYPT_SHA256_ALGORITHM
#define KPH_BLOB_PUBLIC BCRYPT_ECCPUBLIC_BLOB
#endif
#define KPH_SIGNATURE_MAX_SIZE (128 * 1024) // 128 kB
#define FILE_BUFFER_SIZE (2 * PAGE_SIZE)
#define FILE_MAX_SIZE (128 * 1024 * 1024) // 128 MB
static UCHAR KphpTrustedPublicKey[] =
{
0x45, 0x43, 0x53, 0x31, 0x20, 0x00, 0x00, 0x00, 0x05, 0x7A, 0x12, 0x5A, 0xF8, 0x54, 0x01, 0x42,
0xDB, 0x19, 0x87, 0xFC, 0xC4, 0xE3, 0xD3, 0x8D, 0x46, 0x7B, 0x74, 0x01, 0x12, 0xFC, 0x78, 0xEB,
0xEF, 0x7F, 0xF6, 0xAF, 0x4D, 0x9A, 0x3A, 0xF6, 0x64, 0x90, 0xDB, 0xE3, 0x48, 0xAB, 0x3E, 0xA7,
0x2F, 0xC1, 0x18, 0x32, 0xBD, 0x23, 0x02, 0x9D, 0x3F, 0xF3, 0x27, 0x86, 0x71, 0x45, 0x26, 0x14,
0x14, 0xF5, 0x19, 0xAA, 0x2D, 0xEE, 0x50, 0x10
};
NTSTATUS KphHashFile(
_In_ PUNICODE_STRING FileName,
_Out_ PVOID *Hash,
_Out_ PULONG HashSize
)
{
NTSTATUS status;
BCRYPT_ALG_HANDLE hashAlgHandle = NULL;
ULONG querySize;
ULONG hashObjectSize;
ULONG hashSize;
PVOID hashObject = NULL;
PVOID hash = NULL;
BCRYPT_HASH_HANDLE hashHandle = NULL;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK iosb;
HANDLE fileHandle = NULL;
FILE_STANDARD_INFORMATION standardInfo;
ULONG remainingBytes;
ULONG bytesToRead;
PVOID buffer = NULL;
// Open the hash algorithm and allocate memory for the hash object.
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hashAlgHandle, KPH_HASH_ALGORITHM, NULL, 0)))
goto CleanupExit;
if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_OBJECT_LENGTH,
(PUCHAR)&hashObjectSize, sizeof(ULONG), &querySize, 0)))
{
goto CleanupExit;
}
if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_HASH_LENGTH, (PUCHAR)&hashSize,
sizeof(ULONG), &querySize, 0)))
{
goto CleanupExit;
}
if (!(hashObject = ExAllocatePoolWithTag(PagedPool, hashObjectSize, 'vhpK')))
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
if (!(hash = ExAllocatePoolWithTag(PagedPool, hashSize, 'vhpK')))
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
if (!NT_SUCCESS(status = BCryptCreateHash(hashAlgHandle, &hashHandle, hashObject, hashObjectSize,
NULL, 0, 0)))
{
goto CleanupExit;
}
// Open the file and compute the hash.
InitializeObjectAttributes(&objectAttributes, FileName, OBJ_KERNEL_HANDLE, NULL, NULL);
if (!NT_SUCCESS(status = ZwCreateFile(&fileHandle, FILE_GENERIC_READ, &objectAttributes,
&iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0)))
{
goto CleanupExit;
}
if (!NT_SUCCESS(status = ZwQueryInformationFile(fileHandle, &iosb, &standardInfo,
sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation)))
{
goto CleanupExit;
}
if (standardInfo.EndOfFile.QuadPart <= 0)
{
status = STATUS_UNSUCCESSFUL;
goto CleanupExit;
}
if (standardInfo.EndOfFile.QuadPart > FILE_MAX_SIZE)
{
status = STATUS_FILE_TOO_LARGE;
goto CleanupExit;
}
if (!(buffer = ExAllocatePoolWithTag(PagedPool, FILE_BUFFER_SIZE, 'vhpK')))
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
remainingBytes = (ULONG)standardInfo.EndOfFile.QuadPart;
while (remainingBytes != 0)
{
bytesToRead = FILE_BUFFER_SIZE;
if (bytesToRead > remainingBytes)
bytesToRead = remainingBytes;
if (!NT_SUCCESS(status = ZwReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, bytesToRead,
NULL, NULL)))
{
goto CleanupExit;
}
if ((ULONG)iosb.Information != bytesToRead)
{
status = STATUS_INTERNAL_ERROR;
goto CleanupExit;
}
if (!NT_SUCCESS(status = BCryptHashData(hashHandle, buffer, bytesToRead, 0)))
goto CleanupExit;
remainingBytes -= bytesToRead;
}
if (!NT_SUCCESS(status = BCryptFinishHash(hashHandle, hash, hashSize, 0)))
goto CleanupExit;
if (NT_SUCCESS(status))
{
*Hash = hash;
*HashSize = hashSize;
hash = NULL; // Don't free this in the cleanup section
}
CleanupExit:
if (buffer)
ExFreePoolWithTag(buffer, 'vhpK');
if (fileHandle)
ZwClose(fileHandle);
if (hashHandle)
BCryptDestroyHash(hashHandle);
if (hash)
ExFreePoolWithTag(hash, 'vhpK');
if (hashObject)
ExFreePoolWithTag(hashObject, 'vhpK');
if (hashAlgHandle)
BCryptCloseAlgorithmProvider(hashAlgHandle, 0);
return status;
}
NTSTATUS KphVerifyFile(
_In_ PUNICODE_STRING FileName,
_In_ PUCHAR Signature,
_In_ ULONG SignatureSize
)
{
NTSTATUS status;
BCRYPT_ALG_HANDLE signAlgHandle = NULL;
BCRYPT_KEY_HANDLE keyHandle = NULL;
PVOID hash = NULL;
ULONG hashSize;
// Import the trusted public key.
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&signAlgHandle, KPH_SIGN_ALGORITHM, NULL, 0)))
goto CleanupExit;
if (!NT_SUCCESS(status = BCryptImportKeyPair(signAlgHandle, NULL, KPH_BLOB_PUBLIC, &keyHandle,
KphpTrustedPublicKey, sizeof(KphpTrustedPublicKey), 0)))
{
goto CleanupExit;
}
// Hash the file.
if (!NT_SUCCESS(status = KphHashFile(FileName, &hash, &hashSize)))
goto CleanupExit;
// Verify the hash.
if (!NT_SUCCESS(status = BCryptVerifySignature(keyHandle, NULL, hash, hashSize, Signature,
SignatureSize, 0)))
{
goto CleanupExit;
}
CleanupExit:
if (hash)
ExFreePoolWithTag(hash, 'vhpK');
if (keyHandle)
BCryptDestroyKey(keyHandle);
if (signAlgHandle)
BCryptCloseAlgorithmProvider(signAlgHandle, 0);
return status;
}
NTSTATUS KphReadSignature(
_In_ PUNICODE_STRING FileName,
_Out_ PUCHAR *Signature,
_Out_ ULONG *SignatureSize
)
{
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK iosb;
HANDLE fileHandle = NULL;
FILE_STANDARD_INFORMATION standardInfo;
// Open the file and read it.
InitializeObjectAttributes(&objectAttributes, FileName, OBJ_KERNEL_HANDLE, NULL, NULL);
if (!NT_SUCCESS(status = ZwCreateFile(&fileHandle, FILE_GENERIC_READ, &objectAttributes,
&iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0)))
{
goto CleanupExit;
}
if (!NT_SUCCESS(status = ZwQueryInformationFile(fileHandle, &iosb, &standardInfo,
sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation)))
{
goto CleanupExit;
}
if (standardInfo.EndOfFile.QuadPart <= 0)
{
status = STATUS_UNSUCCESSFUL;
goto CleanupExit;
}
if (standardInfo.EndOfFile.QuadPart > KPH_SIGNATURE_MAX_SIZE)
{
status = STATUS_FILE_TOO_LARGE;
goto CleanupExit;
}
*SignatureSize = (ULONG)standardInfo.EndOfFile.QuadPart;
*Signature = ExAllocatePoolWithTag(PagedPool, *SignatureSize, tzuk);
if(!*Signature)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
if (!NT_SUCCESS(status = ZwReadFile(fileHandle, NULL, NULL, NULL, &iosb, *Signature, *SignatureSize,
NULL, NULL)))
{
goto CleanupExit;
}
CleanupExit:
if (fileHandle)
ZwClose(fileHandle);
return status;
}
NTSTATUS KphVerifyCurrentProcess()
{
NTSTATUS status;
PUNICODE_STRING processFileName = NULL;
PUNICODE_STRING signatureFileName = NULL;
ULONG SignatureSize = 0;
PUCHAR Signature = NULL;
if (!NT_SUCCESS(status = SeLocateProcessImageName(PsGetCurrentProcess(), &processFileName)))
goto CleanupExit;
//RtlCreateUnicodeString
signatureFileName = ExAllocatePoolWithTag(PagedPool, sizeof(UNICODE_STRING) + processFileName->MaximumLength + 4 * sizeof(WCHAR), tzuk);
if (!signatureFileName)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto CleanupExit;
}
signatureFileName->Buffer = (PWCH)(((PUCHAR)signatureFileName) + sizeof(UNICODE_STRING));
signatureFileName->MaximumLength = processFileName->MaximumLength + 5 * sizeof(WCHAR);
//RtlCopyUnicodeString
wcscpy(signatureFileName->Buffer, processFileName->Buffer);
signatureFileName->Length = processFileName->Length;
//RtlUnicodeStringCat
wcscat(signatureFileName->Buffer, L".sig");
signatureFileName->Length += 4 * sizeof(WCHAR);
if (!NT_SUCCESS(status = KphReadSignature(signatureFileName, &Signature, &SignatureSize)))
goto CleanupExit;
status = KphVerifyFile(processFileName, Signature, SignatureSize);
CleanupExit:
if (Signature)
ExFreePoolWithTag(Signature, tzuk);
if (processFileName)
ExFreePool(processFileName);
if (signatureFileName)
ExFreePoolWithTag(signatureFileName, tzuk);
return status;
}

View File

@ -526,15 +526,12 @@ void DriverAssist::UnmountHive(void *_msg)
bool ShouldUnmount = false;
ULONG *pids = (ULONG *)HeapAlloc(GetProcessHeap(), 0, PAGE_SIZE);
if (pids) {
for (retries = 0; retries < 20; ++retries) {
ULONG count = 0;
rc = SbieApi_EnumProcessEx(
msg->boxname, FALSE, msg->session_id, pids, NULL);
if (rc == 0 && *pids == 0) {
msg->boxname, FALSE, msg->session_id, NULL, &count);
if (rc == 0 && count == 0) {
ShouldUnmount = true;
break;
@ -543,8 +540,6 @@ void DriverAssist::UnmountHive(void *_msg)
Sleep(100);
}
HeapFree(GetProcessHeap(), 0, pids);
}
//
// unmount. on Windows 2000, the process may appear to disappear

View File

@ -180,7 +180,12 @@ bool GuiServer::InitProcess(
EnterCriticalSection(&m_SlavesLock);
status = SendMessageToSlave(session_id, process_id, add_to_job);
GUI_INIT_PROCESS_REQ data;
data.msgid = GUI_INIT_PROCESS;
data.process_id = process_id;
data.add_to_job = add_to_job;
status = SendMessageToSlave(session_id, &data, sizeof(data));
if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
//
@ -194,7 +199,7 @@ bool GuiServer::InitProcess(
errlvl = 0x22;
else {
status = SendMessageToSlave(session_id, process_id, add_to_job);
status = SendMessageToSlave(session_id, &data, sizeof(data));
if (status != STATUS_SUCCESS)
errlvl = 0x33;
}
@ -248,28 +253,24 @@ finish:
//---------------------------------------------------------------------------
ULONG GuiServer::SendMessageToSlave(ULONG session_id, ULONG process_id,
BOOLEAN add_to_job)
ULONG GuiServer::SendMessageToSlave(ULONG session_id, void* data, ULONG data_len)
{
//
// prepare a QUEUE_PUTREQ_REQ message to send to the slave process
//
const ULONG req_len =
sizeof(QUEUE_PUTREQ_REQ) + sizeof(GUI_INIT_PROCESS_REQ);
ULONG64 req_space[(req_len + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
QUEUE_PUTREQ_REQ *req1 = (QUEUE_PUTREQ_REQ *)req_space;
const ULONG req_len = sizeof(QUEUE_PUTREQ_REQ) + data_len;
//ULONG64 req_space[(req_len + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
//QUEUE_PUTREQ_REQ *req1 = (QUEUE_PUTREQ_REQ *)req_space;
QUEUE_PUTREQ_REQ *req1 = (QUEUE_PUTREQ_REQ *)HeapAlloc(GetProcessHeap(), 0, req_len);
req1->h.length = req_len;
req1->h.msgid = MSGID_QUEUE_PUTREQ;
wsprintf(req1->queue_name, L"*GUIPROXY_%08X", session_id);
req1->event_handle = (ULONG64)(ULONG_PTR)m_QueueEvent;
req1->data_len = sizeof(GUI_INIT_PROCESS_REQ);
GUI_INIT_PROCESS_REQ *data = (GUI_INIT_PROCESS_REQ *)req1->data;
data->msgid = process_id ? GUI_INIT_PROCESS : GUI_SHUTDOWN;
data->process_id = process_id;
data->add_to_job = add_to_job;
req1->data_len = data_len;
memcpy(req1->data, data, data_len);
//
// send the message through the queue service
@ -326,6 +327,8 @@ ULONG GuiServer::SendMessageToSlave(ULONG session_id, ULONG process_id,
status = STATUS_INSUFFICIENT_RESOURCES;
}
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, req1);
return status;
}
@ -768,6 +771,7 @@ bool GuiServer::CreateQueueSlave(const WCHAR *cmdline)
m_SlaveFuncs[GUI_GET_RAW_INPUT_DEVICE_INFO] = &GuiServer::GetRawInputDeviceInfoSlave;
m_SlaveFuncs[GUI_WND_HOOK_NOTIFY] = &GuiServer::WndHookNotifySlave;
m_SlaveFuncs[GUI_WND_HOOK_REGISTER] = &GuiServer::WndHookRegisterSlave;
m_SlaveFuncs[GUI_KILL_JOB] = &GuiServer::KillJob;
//
@ -850,7 +854,7 @@ bool GuiServer::QueueCallbackSlave2(void)
// (with the exception of the GUI_INIT_PROCESS message)
//
if (msgid != GUI_INIT_PROCESS) {
if (msgid != GUI_INIT_PROCESS && msgid != GUI_KILL_JOB) {
ULONG session_id;
status = SbieApi_QueryProcess((HANDLE)(ULONG_PTR)args.pid,
@ -1102,12 +1106,28 @@ HANDLE GuiServer::GetJobObjectForGrant(ULONG pid)
if (status == 0 && SessionId == m_SessionId) {
hJobObject = GetJobObject(BoxName);
}
return hJobObject;
}
//---------------------------------------------------------------------------
// GetJobObject
//---------------------------------------------------------------------------
HANDLE GuiServer::GetJobObject(const WCHAR *boxname)
{
HANDLE hJobObject = NULL;
EnterCriticalSection(&m_SlavesLock);
GUI_JOB *job = (GUI_JOB *)List_Head(&m_SlavesList);
while (job) {
if (_wcsicmp(job->boxname, BoxName) == 0) {
if (_wcsicmp(job->boxname, boxname) == 0) {
hJobObject = job->handle;
if (hJobObject)
@ -1118,7 +1138,6 @@ HANDLE GuiServer::GetJobObjectForGrant(ULONG pid)
}
LeaveCriticalSection(&m_SlavesLock);
}
return hJobObject;
}
@ -4256,6 +4275,8 @@ void GuiServer::RunConsoleSlave(const WCHAR *evtname)
}
}
}
//HeapFree(GetProcessHeap(), 0, pids); // dont bother we ExitProcess aynways
}
ExitProcess(0);
@ -4541,3 +4562,34 @@ ULONG GuiServer::DdeProxyThreadSlave(void *xDdeArgs)
return 0;
}
//---------------------------------------------------------------------------
// KillJob
//---------------------------------------------------------------------------
ULONG GuiServer::KillJob(SlaveArgs* args)
{
GUI_KILL_JOB_REQ *req = (GUI_KILL_JOB_REQ *)args->req_buf;
HANDLE hJobObject;
//
// validate the request
//
if (args->pid != m_ParentPid)
return STATUS_ACCESS_DENIED;
if (args->req_len != sizeof(GUI_KILL_JOB_REQ))
return STATUS_INFO_LENGTH_MISMATCH;
hJobObject = GetJobObject(req->boxname);
if (hJobObject) {
if (!TerminateJobObject(hJobObject, 0))
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}

View File

@ -41,15 +41,14 @@ public:
static void RunSlave(const WCHAR *cmdline);
ULONG StartSlave(ULONG session_id);
ULONG SendMessageToSlave(ULONG session_id, void* data, ULONG data_len);
protected:
GuiServer();
ULONG StartSlave(ULONG session_id);
ULONG SendMessageToSlave(ULONG session_id, ULONG process_id,
BOOLEAN add_to_job);
static void ReportError2336(
ULONG session_id, ULONG errlvl, ULONG status);
@ -77,6 +76,8 @@ protected:
HANDLE GetJobObjectForGrant(ULONG pid);
HANDLE GetJobObject(const WCHAR *boxname);
bool GetWindowStationAndDesktopName(WCHAR *out_name);
protected:
@ -165,6 +166,8 @@ protected:
ULONG WndHookRegisterSlave(SlaveArgs* args);
ULONG KillJob(SlaveArgs *args);
//
// window access check utilities
//
@ -187,6 +190,9 @@ protected:
bool AllowSendPostMessage(
ULONG pid, ULONG msg, bool IsSendMsg, HWND hwnd);
//
// data
//

View File

@ -31,8 +31,7 @@
enum {
GUI_SHUTDOWN = 1,
GUI_INIT_PROCESS,
GUI_INIT_PROCESS = 1,
GUI_GET_WINDOW_STATION,
GUI_CREATE_CONSOLE,
GUI_QUERY_WINDOW,
@ -63,6 +62,7 @@ enum {
GUI_GET_RAW_INPUT_DEVICE_INFO,
GUI_WND_HOOK_NOTIFY,
GUI_WND_HOOK_REGISTER,
GUI_KILL_JOB,
GUI_MAX_REQUEST_CODE
};
@ -750,6 +750,21 @@ struct tagGUI_WND_HOOK_REGISTER_RPL
typedef struct tagGUI_WND_HOOK_REGISTER_REQ GUI_WND_HOOK_REGISTER_REQ;
typedef struct tagGUI_WND_HOOK_REGISTER_RPL GUI_WND_HOOK_REGISTER_RPL;
//---------------------------------------------------------------------------
// Terminate Job
//---------------------------------------------------------------------------
struct tagGUI_KILL_JOB_REQ
{
ULONG msgid;
WCHAR boxname[34];
};
typedef struct tagGUI_KILL_JOB_REQ GUI_KILL_JOB_REQ;
//---------------------------------------------------------------------------

View File

@ -27,7 +27,7 @@
#include "core/dll/sbiedll.h"
#include "common/defines.h"
#include "common/my_version.h"
#include <psapi.h> // For access to GetModuleFileNameEx
//---------------------------------------------------------------------------
// Defines
@ -54,16 +54,24 @@ typedef struct tagTARGET
typedef struct tagCLIENT_PROCESS
{
#ifndef USE_PROCESS_MAP
LIST_ELEM list_elem;
#endif
HANDLE idProcess;
LARGE_INTEGER CreateTime;
#ifdef USE_PROCESS_MAP
HASH_MAP thread_map;
#else
LIST threads;
#endif
} CLIENT_PROCESS;
typedef struct tagCLIENT_THREAD
{
#ifndef USE_PROCESS_MAP
LIST_ELEM list_elem;
#endif
HANDLE idThread;
BOOLEAN replying;
volatile BOOLEAN in_use;
@ -106,8 +114,7 @@ PipeServer *PipeServer::GetPipeServer()
m_instance->m_TlsIndex = TlsIndex;
m_instance->m_pool = Pool_Create();
if (! m_instance->m_pool) {
if (! m_instance->Init()) {
delete m_instance;
m_instance = NULL;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@ -128,7 +135,11 @@ PipeServer::PipeServer()
{
InitializeCriticalSectionAndSpinCount(&m_lock, 1000);
List_Init(&m_targets);
#ifdef USE_PROCESS_MAP
map_init(&m_client_map, NULL);
#else
List_Init(&m_clients);
#endif
m_hServerPort = NULL;
@ -141,6 +152,26 @@ PipeServer::PipeServer()
}
//---------------------------------------------------------------------------
// Initializator
//---------------------------------------------------------------------------
bool PipeServer::Init()
{
m_instance->m_pool = Pool_Create();
if (!m_instance->m_pool)
return false;
#ifdef USE_PROCESS_MAP
m_client_map.mem_pool = m_pool;
map_resize(&m_client_map, 128); // prepare some buckets for better performance
#endif
return true;
}
//---------------------------------------------------------------------------
// Destructor
//---------------------------------------------------------------------------
@ -392,27 +423,7 @@ void PipeServer::PortConnect(PORT_MESSAGE *msg)
EnterCriticalSection(&m_lock);
clientProcess = (CLIENT_PROCESS *)List_Head(&m_clients);
clientThread = NULL;
while (clientProcess) {
if (clientProcess->idProcess == msg->ClientId.UniqueProcess) {
clientThread =
(CLIENT_THREAD *)List_Head(&clientProcess->threads);
while (clientThread) {
if (clientThread->idThread == msg->ClientId.UniqueThread)
break;
clientThread = (CLIENT_THREAD *)List_Next(clientThread);
}
break;
}
clientProcess = (CLIENT_PROCESS *)List_Next(clientProcess);
}
PortFindClientUnsafe(msg->ClientId, clientProcess, clientThread);
//
// create new process and thread structures where needed
@ -425,8 +436,15 @@ void PipeServer::PortConnect(PORT_MESSAGE *msg)
if (clientProcess) {
clientProcess->idProcess = msg->ClientId.UniqueProcess;
#ifdef USE_PROCESS_MAP
map_init(&clientProcess->thread_map, m_pool);
map_resize(&clientProcess->thread_map, 16); // prepare some buckets for better performance
map_insert(&m_client_map, msg->ClientId.UniqueProcess, clientProcess, 0);
#else
List_Init(&clientProcess->threads);
List_Insert_After(&m_clients, NULL, clientProcess);
#endif
//
// prepare for the case where a disconnect message only
@ -465,17 +483,20 @@ void PipeServer::PortConnect(PORT_MESSAGE *msg)
memset(clientThread, 0, sizeof(CLIENT_THREAD));
clientThread->idThread = msg->ClientId.UniqueThread;
#ifdef USE_PROCESS_MAP
map_insert(&clientProcess->thread_map, msg->ClientId.UniqueThread, clientThread, 0);
#else
List_Insert_After(&clientProcess->threads, NULL, clientThread);
#endif
}
}
//
// if we couldn't create a new connection (not enough memory)
// or if a previous connection was found,
// then reject the new connection
// reject the new connection
//
if ((! clientThread) || clientThread->hPort) {
if (! clientThread) {
HANDLE hPort;
NtAcceptConnectPort(&hPort, NULL, msg, FALSE, NULL, NULL);
@ -485,6 +506,27 @@ void PipeServer::PortConnect(PORT_MESSAGE *msg)
return;
}
//
// if a previous connection was found, close it
//
if (clientThread->hPort) {
while (clientThread->in_use)
Sleep(3);
NtClose(clientThread->hPort);
if (clientThread->buf_hdr)
FreeMsg(clientThread->buf_hdr);
clientThread->replying = FALSE;
clientThread->in_use = FALSE;
clientThread->sequence = 0;
clientThread->hPort = NULL;
clientThread->buf_hdr = NULL;
clientThread->buf_ptr = NULL;
}
//
// if a new client structure was created, accept the connection
//
@ -499,6 +541,49 @@ void PipeServer::PortConnect(PORT_MESSAGE *msg)
}
//---------------------------------------------------------------------------
// PortDisconnectHelper
//---------------------------------------------------------------------------
void PipeServer::PortDisconnectHelper(CLIENT_PROCESS *clientProcess, CLIENT_THREAD *clientThread)
{
if (!clientProcess)
return;
if (clientThread) {
while (clientThread->in_use)
Sleep(3);
#ifdef USE_PROCESS_MAP
map_remove(&clientProcess->thread_map, clientThread->idThread);
#else
List_Remove(&clientProcess->threads, clientThread);
#endif
NtClose(clientThread->hPort);
if (clientThread->buf_hdr)
FreeMsg(clientThread->buf_hdr);
Pool_Free(clientThread, sizeof(CLIENT_THREAD));
}
#ifdef USE_PROCESS_MAP
if (clientProcess->thread_map.nnodes == 0) {
#else
if (! List_Head(&clientProcess->threads)) {
#endif
NotifyTargets(clientProcess->idProcess);
#ifdef USE_PROCESS_MAP
map_remove(&m_client_map, clientProcess->idProcess);
#else
List_Remove(&m_clients, clientProcess);
#endif
Pool_Free(clientProcess, sizeof(CLIENT_PROCESS));
}
}
//---------------------------------------------------------------------------
// PortDisconnect
//---------------------------------------------------------------------------
@ -530,46 +615,9 @@ void PipeServer::PortDisconnect(PORT_MESSAGE *msg)
EnterCriticalSection(&m_lock);
clientProcess = (CLIENT_PROCESS *)List_Head(&m_clients);
clientThread = NULL;
PortFindClientUnsafe(msg->ClientId, clientProcess, clientThread);
while (clientProcess) {
if (clientProcess->idProcess == msg->ClientId.UniqueProcess) {
clientThread =
(CLIENT_THREAD *)List_Head(&clientProcess->threads);
while (clientThread) {
if (clientThread->idThread == msg->ClientId.UniqueThread) {
while (clientThread->in_use)
Sleep(3);
List_Remove(&clientProcess->threads, clientThread);
NtClose(clientThread->hPort);
if (clientThread->buf_hdr)
FreeMsg(clientThread->buf_hdr);
Pool_Free(clientThread, sizeof(CLIENT_THREAD));
break;
}
clientThread = (CLIENT_THREAD *)List_Next(clientThread);
}
if (! List_Head(&clientProcess->threads)) {
NotifyTargets(clientProcess->idProcess);
List_Remove(&m_clients, clientProcess);
Pool_Free(clientProcess, sizeof(CLIENT_PROCESS));
}
break;
}
clientProcess = (CLIENT_PROCESS *)List_Next(clientProcess);
}
PortDisconnectHelper(clientProcess, clientThread);
LeaveCriticalSection(&m_lock);
}
@ -613,17 +661,31 @@ void PipeServer::PortDisconnectByCreateTime(LARGE_INTEGER *CreateTime)
EnterCriticalSection(&m_lock);
CLIENT_PROCESS *clientProcess = (CLIENT_PROCESS *)List_Head(&m_clients);
CLIENT_PROCESS *clientProcess = NULL;
CLIENT_THREAD *clientThread = NULL;
#ifdef USE_PROCESS_MAP
map_iter_t iter = map_iter();
while (map_next(&m_client_map, &iter)) {
clientProcess = (CLIENT_PROCESS *)iter.value;
#else
clientProcess = (CLIENT_PROCESS *)List_Head(&m_clients);
while (clientProcess) {
#endif
if (clientProcess->CreateTime.HighPart == CreateTime->HighPart &&
clientProcess->CreateTime.LowPart == CreateTime->LowPart) {
CLIENT_THREAD *clientThread =
(CLIENT_THREAD *)List_Head(&clientProcess->threads);
while (clientThread) {
#ifdef USE_PROCESS_MAP
map_iter_t sub_iter = map_iter();
while (map_next(&clientProcess->thread_map, &sub_iter)) {
clientThread = (CLIENT_THREAD *)sub_iter.value;
#else
clientThread = (CLIENT_THREAD *)List_Head(&clientProcess->threads);
while (clientThread) {
#endif
//
// for each thread in the process, assume it is stale,
// unless we can open it, and it still has the same
@ -642,36 +704,35 @@ void PipeServer::PortDisconnectByCreateTime(LARGE_INTEGER *CreateTime)
CloseHandle(hThread);
}
//
// fix-me: when closing the port without waiting some ms after the
// thread terminated this fails and the client object is not cleared
//
if (DeleteThread) {
while (clientThread->in_use)
Sleep(3);
List_Remove(&clientProcess->threads, clientThread);
NtClose(clientThread->hPort);
if (clientThread->buf_hdr)
FreeMsg(clientThread->buf_hdr);
Pool_Free(clientThread, sizeof(CLIENT_THREAD));
break;
}
#ifndef USE_PROCESS_MAP
clientThread = (CLIENT_THREAD *)List_Next(clientThread);
}
if (! List_Head(&clientProcess->threads)) {
NotifyTargets(clientProcess->idProcess);
List_Remove(&m_clients, clientProcess);
Pool_Free(clientProcess, sizeof(CLIENT_PROCESS));
#else
clientThread = NULL;
#endif
}
break;
}
#ifndef USE_PROCESS_MAP
clientProcess = (CLIENT_PROCESS *)List_Next(clientProcess);
#else
clientProcess = NULL;
#endif
}
PortDisconnectHelper(clientProcess, clientThread);
LeaveCriticalSection(&m_lock);
}
@ -742,6 +803,45 @@ finish:
}
//---------------------------------------------------------------------------
// PortFindClientUnsafe
//---------------------------------------------------------------------------
void PipeServer::PortFindClientUnsafe(const CLIENT_ID& ClientId, CLIENT_PROCESS *&clientProcess, CLIENT_THREAD *&clientThread)
{
//
// Note: this is not thread safe, you must lock m_lock before calling this function
//
#ifdef USE_PROCESS_MAP
clientProcess = (CLIENT_PROCESS *)map_get(&m_client_map, ClientId.UniqueProcess);
clientThread = clientProcess ? (CLIENT_THREAD *)map_get(&clientProcess->thread_map, ClientId.UniqueThread) : NULL;
#else
clientProcess = (CLIENT_PROCESS *)List_Head(&m_clients);
while (clientProcess) {
if (clientProcess->idProcess == ClientId.UniqueProcess) {
clientThread =
(CLIENT_THREAD *)List_Head(&clientProcess->threads);
while (clientThread) {
if (clientThread->idThread == ClientId.UniqueThread)
break;
clientThread = (CLIENT_THREAD *)List_Next(clientThread);
}
break;
}
clientProcess = (CLIENT_PROCESS *)List_Next(clientProcess);
}
#endif
}
//---------------------------------------------------------------------------
// PortFindClient
//---------------------------------------------------------------------------
@ -754,27 +854,7 @@ void *PipeServer::PortFindClient(PORT_MESSAGE *msg)
EnterCriticalSection(&m_lock);
clientProcess = (CLIENT_PROCESS *)List_Head(&m_clients);
clientThread = NULL;
while (clientProcess) {
if (clientProcess->idProcess == msg->ClientId.UniqueProcess) {
clientThread =
(CLIENT_THREAD *)List_Head(&clientProcess->threads);
while (clientThread) {
if (clientThread->idThread == msg->ClientId.UniqueThread)
break;
clientThread = (CLIENT_THREAD *)List_Next(clientThread);
}
break;
}
clientProcess = (CLIENT_PROCESS *)List_Next(clientProcess);
}
PortFindClientUnsafe(msg->ClientId, clientProcess, clientThread);
if (clientThread)
clientThread->in_use = TRUE;
@ -1048,3 +1128,33 @@ MSG_HEADER *PipeServer::Call(MSG_HEADER *msg)
return msg_out;
}
//---------------------------------------------------------------------------
// IsCallerSigned
//---------------------------------------------------------------------------
extern "C" {
NTSTATUS VerifyFileSignature(const wchar_t* FilePath);
}
bool PipeServer::IsCallerSigned()
{
CLIENT_TLS_DATA *TlsData =
(CLIENT_TLS_DATA *)TlsGetValue(m_instance->m_TlsIndex);
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG processId = (ULONG)(ULONG_PTR)TlsData->PortMessage->ClientId.UniqueProcess;
HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
if (processHandle != NULL) {
TCHAR fileName[MAX_PATH];
if (GetModuleFileNameEx(processHandle, NULL, fileName, MAX_PATH)) {
status = VerifyFileSignature(fileName);
}
CloseHandle(processHandle);
}
return NT_SUCCESS(status);
}

View File

@ -27,9 +27,11 @@
#include <windows.h>
#include "common/win32_ntddk.h"
#include "common/list.h"
#include "common/map.h"
#include "common/pool.h"
#include "msgids.h"
#define USE_PROCESS_MAP
/* Recommended maximum length for any single element in a request packet. */
@ -128,6 +130,12 @@ public:
MSG_HEADER *Call(MSG_HEADER *msg);
/*
* Checks if the calling process has a valid signature
*/
static bool IsCallerSigned();
protected:
/*
@ -136,6 +144,12 @@ protected:
PipeServer();
/*
* Private initializator
*/
bool Init();
/*
* Static wrapper for thread function
*/
@ -200,8 +214,16 @@ protected:
protected:
void PortDisconnectHelper(struct tagCLIENT_PROCESS* clientProcess, struct tagCLIENT_THREAD* clientThread);
void PortFindClientUnsafe(const CLIENT_ID& ClientId, struct tagCLIENT_PROCESS *&clientProcess, struct tagCLIENT_THREAD *&clientThread);
LIST m_targets;
#ifdef USE_PROCESS_MAP
HASH_MAP m_client_map;
#else
LIST m_clients;
#endif
CRITICAL_SECTION m_lock;
POOL *m_pool;
ULONG m_TlsIndex;

View File

@ -26,6 +26,8 @@
#include "ProcessServer.h"
#include "Processwire.h"
#include "DriverAssist.h"
#include "GuiServer.h"
#include "GuiWire.h"
#include "misc.h"
#include "common/defines.h"
#include "common/my_version.h"
@ -203,6 +205,7 @@ MSG_HEADER *ProcessServer::KillAllHandler(
WCHAR TargetBoxName[48];
ULONG CallerSessionId;
WCHAR CallerBoxName[48];
BOOLEAN TerminateJob;
NTSTATUS status;
//
@ -234,6 +237,11 @@ MSG_HEADER *ProcessServer::KillAllHandler(
} else if (status != STATUS_SUCCESS)
return SHORT_REPLY(status);
if (status != STATUS_INVALID_CID) // if this is true the caller is boxed, should be rpcss
TerminateJob = FALSE; // if rpcss requests box termination, don't use the job method, fix-me: we get some stuck request in the queue
else
TerminateJob = !SbieApi_QueryConfBool(TargetBoxName, L"NoAddProcessToJob", FALSE);
//
// match session id and box name
//
@ -250,7 +258,7 @@ MSG_HEADER *ProcessServer::KillAllHandler(
// kill target processes
//
status = KillAllHelper(TargetBoxName, TargetSessionId);
status = KillAllHelper(TargetBoxName, TargetSessionId, TerminateJob);
return SHORT_REPLY(status);
}
@ -261,20 +269,45 @@ MSG_HEADER *ProcessServer::KillAllHandler(
//---------------------------------------------------------------------------
NTSTATUS ProcessServer::KillAllHelper(const WCHAR *BoxName, ULONG SessionId)
NTSTATUS ProcessServer::KillAllHelper(const WCHAR *BoxName, ULONG SessionId, BOOLEAN TerminateJob)
{
NTSTATUS status;
ULONG retries, i;
ULONG pids[512];
const ULONG pids_len = 512;
ULONG pids[pids_len];
ULONG count;
for (retries = 0; retries < 10; ++retries) {
if (TerminateJob) {
status = SbieApi_EnumProcessEx(BoxName, FALSE, SessionId, pids, NULL);
//
// try killing the entire job in one go first
//
GUI_KILL_JOB_REQ data;
data.msgid = GUI_KILL_JOB;
if (BoxName) wcscpy(data.boxname, BoxName);
else data.boxname[0] = L'\0';
GuiServer::GetInstance()->SendMessageToSlave(SessionId, &data, sizeof(data));
//
// as fallback and for the case where jobs are not used run the manual termination
//
}
for (retries = 0; retries < 10; ) {
count = pids_len;
status = SbieApi_EnumProcessEx(BoxName, FALSE, SessionId, pids, &count);
if (status != STATUS_SUCCESS)
break;
if (! pids[0])
if (count == 0)
break;
if (count < pids_len)
retries++;
if (retries) {
if (retries >= 10 - 1) {
status = STATUS_UNSUCCESSFUL;
@ -283,7 +316,7 @@ NTSTATUS ProcessServer::KillAllHelper(const WCHAR *BoxName, ULONG SessionId)
Sleep(100);
}
for (i = 1; i <= pids[0]; ++i)
for (i = 0; i <= count; ++i)
KillProcess(pids[i]);
}

View File

@ -51,7 +51,7 @@ protected:
MSG_HEADER *KillAllHandler(HANDLE CallerProcessId, MSG_HEADER *msg);
NTSTATUS KillAllHelper(const WCHAR *BoxName, ULONG SessionId);
NTSTATUS KillAllHelper(const WCHAR *BoxName, ULONG SessionId, BOOLEAN TerminateJob = FALSE);
MSG_HEADER *SetDeviceMap(HANDLE CallerProcessId, MSG_HEADER *msg);

View File

@ -100,7 +100,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib</AdditionalDependencies>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib;bcrypt.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
</Link>
@ -116,7 +116,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib</AdditionalDependencies>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib;bcrypt.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
</Link>
@ -131,7 +131,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib</AdditionalDependencies>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib;bcrypt.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
</Link>
@ -146,7 +146,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib</AdditionalDependencies>
<AdditionalDependencies>SbieDll.lib;ntdll.lib;kernel32.lib;user32.lib;Advapi32.lib;psapi.lib;Ole32.lib;crypt32.lib;Secur32.lib;Userenv.lib;Gdi32.lib;Netapi32.lib;wtsapi32.lib;rpcrt4.lib;bcrypt.lib</AdditionalDependencies>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
</Link>
@ -161,12 +161,40 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\list.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\map.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\pattern.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\pool.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\common\verify.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">NotUsing</PrecompiledHeader>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="comserver.cpp" />
<ClCompile Include="comserver9.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">NotUsing</PrecompiledHeader>
@ -240,6 +268,30 @@
<ClCompile Include="terminalserver.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\common\list.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\common\map.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\common\pattern.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\common\pool.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="comserver.h" />
<ClInclude Include="comwire.h" />
<ClInclude Include="DriverAssist.h" />

View File

@ -54,6 +54,18 @@
<ClCompile Include="serviceserver.cpp" />
<ClCompile Include="serviceserver2.cpp" />
<ClCompile Include="terminalserver.cpp" />
<ClCompile Include="..\..\common\verify.c">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\common\list.c">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\common\map.c">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\common\pattern.c">
<Filter>common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="misc.h" />
@ -102,6 +114,18 @@
<ClInclude Include="servicewire.h" />
<ClInclude Include="terminalserver.h" />
<ClInclude Include="InteractiveWire.h" />
<ClInclude Include="..\..\common\list.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\common\map.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\common\pattern.h">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\common\pool.h">
<Filter>common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc" />

View File

@ -34,12 +34,16 @@ extern "C" {
#include "common/pool.c"
#include "common/map.c"
#define CRC_WITH_ADLER32
#include "common/crc.c"
#define PATTERN XPATTERN
#include "common/pattern.c"
#include "common/verify.c"
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -654,6 +654,15 @@ ULONG SbieIniServer::IsCallerAuthorized(HANDLE hToken, const WCHAR *Password)
{
WCHAR buf[42], buf2[42];
//
// check for valid image signature
//
if (!PipeServer::IsCallerSigned()) {
CloseHandle(hToken);
return STATUS_INVALID_SIGNATURE;
}
//
// check for Administrator-only access
//

View File

@ -285,8 +285,8 @@ void ReadTextFile(const UCHAR *path, LIST *msgs)
{
char* utf8 = BufPtr;
ByteSize *= 2;
Buffer = Alloc(ByteSize + 16);
ByteSize = MultiByteToWideChar(CP_UTF8, 0, utf8, ReadSize, NULL, 0) + 1;
Buffer = Alloc(ByteSize * sizeof(wchar_t));
BufPtr = Buffer;
MultiByteToWideChar(CP_UTF8, 0, utf8, ReadSize, BufPtr, ByteSize);

View File

@ -208,7 +208,7 @@ bool CBoxedProcess::InitProcessInfo()
bool CBoxedProcess::InitProcessInfoEx()
{
if(m_ImageType == -1)
if(m_ImageType == -1 && m_pBox)
m_ImageType = m_pBox->Api()->GetImageType(m_ProcessId);
return true;
@ -306,8 +306,3 @@ bool CBoxedProcess::IsSuspended() const
return isSuspended;
}
*/
QString CBoxedProcess::GetBoxName() const
{
return m_pBox->GetName();
}

View File

@ -49,13 +49,14 @@ public:
virtual bool IsWoW64() const { return m_bIsWoW64; }
virtual QString GetBoxName() const;
virtual QString GetBoxName() const { return m_BoxName; }
virtual class CSandBox* GetBoxPtr() const { return m_pBox; }
protected:
friend class CSbieAPI;
quint32 m_ProcessId;
QString m_BoxName;
quint32 m_ParendPID;
QString m_ImageName;
QString m_ImagePath;

View File

@ -182,7 +182,13 @@ void CSandBox::CleanBoxAsync(const CSbieProgressPtr& pProgress, const QStringLis
foreach(const QString& Folder, BoxFolders)
{
for (int i = 0; i < 10; i++) {
Status = CSandBox__DeleteFolder(pProgress, Folder);
if (!Status.IsError())
break;
QThread::sleep(1); // wait a second
}
if (Status.IsError())
break;
}

View File

@ -330,6 +330,9 @@ SB_STATUS CSbieAPI::Disconnect()
m->SbieApiHandle = INVALID_HANDLE_VALUE;
}
// ensure the client thread is enteirly terminated to avoid the service keeping the reference
// see SbieSvc PortDisconnectByCreateTime
QThread::msleep(250);
if (m->PortHandle) {
NtClose(m->PortHandle);
m->PortHandle = NULL;
@ -690,7 +693,10 @@ SB_STATUS CSbieAPI::CallServer(void* req, void* rpl) const
{
//
// Note: Once we open a port to the server from a threat the service will remember it we can't reconnect after disconnection
// So for every new connection we need a new threat, we achive this by letting our monitor threat issue all requests
// So for every new connection we need a new threat, we achieve this by letting our monitor threat issue all requests
//
// As of Sbie build 5.50.5 the SbieCvc properly handles reconnection attempts so this mechanism is no longer necessary
// Howeever for the queue mechanism we need the communication to be still handled by the helper thread
//
while (InterlockedCompareExchange(&m->SvcLock, SVC_OP_STATE_PREP, SVC_OP_STATE_IDLE) != SVC_OP_STATE_IDLE)
@ -935,7 +941,7 @@ QString CSbieAPI::GetIniPath(bool* IsHome) const
req.h.length = sizeof(SBIE_INI_GET_PATH_REQ);
SBIE_INI_GET_PATH_RPL *rpl = NULL;
SB_STATUS Status = CSbieAPI::CallServer(&req.h, &rpl);
SB_STATUS Status = CallServer(&req.h, &rpl);
if (!Status || !rpl)
return QString();
if (rpl->h.status == 0) {
@ -957,7 +963,7 @@ QString CSbieAPI::GetUserSection(QString* pUserName, bool* pIsAdmin) const
req.h.length = sizeof(SBIE_INI_GET_USER_REQ);
SBIE_INI_GET_USER_RPL *rpl = NULL;
SB_STATUS Status = CSbieAPI::CallServer(&req.h, &rpl);
SB_STATUS Status = CallServer(&req.h, &rpl);
if (!Status || !rpl)
return QString();
@ -986,7 +992,7 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, QPr
QString CSbieAPI::GetStartPath() const
{
return m_SbiePath + "//" + QString::fromWCharArray(SBIESTART_EXE);
return m_SbiePath + "\\" + QString::fromWCharArray(SBIESTART_EXE);
}
SB_STATUS CSbieAPI::ReloadBoxes(bool bFullUpdate)
@ -1024,6 +1030,24 @@ SB_STATUS CSbieAPI::ReloadBoxes(bool bFullUpdate)
return SB_OK;
}
QString CSbieAPI__FormatNtStatus(NTSTATUS nsCode)
{
static HMODULE hNtDll = NULL;
if(!hNtDll)
hNtDll = GetModuleHandle(L"ntdll.dll");
if (hNtDll == NULL)
return "???";
WCHAR* ret_str = NULL;
DWORD dwRes = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
hNtDll, RtlNtStatusToDosError(nsCode), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&ret_str, 0, NULL);
QString qStr = QString::fromWCharArray(ret_str);
LocalFree(ret_str);
return qStr;
}
SB_STATUS CSbieAPI::SbieIniSet(void *RequestBuf, void *pPasswordWithinRequestBuf, const QString& SectionName, const QString& SettingName)
{
retry:
@ -1031,7 +1055,7 @@ retry:
((WCHAR*)pPasswordWithinRequestBuf)[m->Password.length()] = L'\0';
MSG_HEADER *rpl = NULL;
SB_STATUS Status = CSbieAPI::CallServer((MSG_HEADER *)RequestBuf, &rpl);
SB_STATUS Status = CallServer((MSG_HEADER *)RequestBuf, &rpl);
SecureZeroMemory(pPasswordWithinRequestBuf, sizeof(WCHAR) * 64);
if (!Status || !rpl)
return Status;
@ -1050,7 +1074,7 @@ retry:
}
return SB_ERR(SB_NotAuthorized, QVariantList() << SectionName, status);
}
return SB_ERR(SB_ConfigFailed, QVariantList() << SettingName << SectionName << (quint32)status, status);
return SB_ERR(SB_ConfigFailed, QVariantList() << SettingName << SectionName << CSbieAPI__FormatNtStatus(status), status);
}
SB_STATUS CSbieAPI::SbieIniSet(const QString& Section, const QString& Setting, const QString& Value, ESetMode Mode)
@ -1118,6 +1142,18 @@ SB_STATUS CSbieAPI::ValidateName(const QString& BoxName)
if (BoxName.length() > 32)
return SB_ERR(SB_NameLenLimit);
/* invalid file name charakters on windows
< (less than)
> (greater than)
: (colon - sometimes works, but is actually NTFS Alternate Data Streams)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
*/
QStringList DeviceNames = QStringList() <<
"aux" << "clock$" << "con" << "nul" << "prn" <<
"com1" << "com2" << "com3" << "com4" << "com5" << "com6" << "com7" << "com8" << "com9" << "com0" <<
@ -1154,13 +1190,6 @@ SB_STATUS CSbieAPI::CreateBox(const QString& BoxName)
return Status;
}
SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep)
{
foreach(const CSandBoxPtr& pBox, m_SandBoxes)
UpdateProcesses(bKeep, pBox);
return SB_OK;
}
SB_STATUS CSbieAPI__GetProcessPIDs(SSbieAPI* m, const QString& BoxName, ULONG* pids, ULONG* count)
{
WCHAR box_name[34];
@ -1185,14 +1214,94 @@ SB_STATUS CSbieAPI__GetProcessPIDs(SSbieAPI* m, const QString& BoxName, ULONG* p
return SB_OK;
}
SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep)
{
ULONG count = 0;
SB_STATUS Status = CSbieAPI__GetProcessPIDs(m, "", NULL, &count); // query the count
if (Status.IsError())
count += 128; // add some extra space
ULONG* boxed_pids = new ULONG[count];
Status = CSbieAPI__GetProcessPIDs(m, "", boxed_pids, &count); // query the count
if (Status.IsError()) {
delete[] boxed_pids;
return Status;
}
QMap<quint32, CBoxedProcessPtr> OldProcessList;
foreach(const CSandBoxPtr& pBox, m_SandBoxes)
OldProcessList.insert(pBox->m_ProcessList);
for (int i=0; i < count; i++)
{
quint32 ProcessId = (quint32)boxed_pids[i];
CBoxedProcessPtr pProcess = OldProcessList.take(ProcessId);
if (!pProcess)
{
pProcess = CBoxedProcessPtr(NewBoxedProcess(ProcessId, NULL));
UpdateProcessInfo(pProcess);
CSandBoxPtr pBox = GetBoxByName(pProcess->GetBoxName());
if (pBox.isNull())
continue;
pProcess->m_pBox = pBox.data();
pBox->m_ProcessList.insert(ProcessId, pProcess);
m_BoxedProxesses.insert(ProcessId, pProcess);
pProcess->InitProcessInfo();
}
pProcess->InitProcessInfoEx();
}
foreach(const CBoxedProcessPtr& pProcess, OldProcessList)
{
if (!pProcess->IsTerminated())
pProcess->SetTerminated();
else if (!bKeep && pProcess->IsTerminated(1500)) { // keep for at least 1.5 seconds
pProcess->m_pBox->m_ProcessList.remove(pProcess->m_ProcessId);
m_BoxedProxesses.remove(pProcess->m_ProcessId);
}
}
foreach(const CSandBoxPtr& pBox, m_SandBoxes)
{
bool WasBoxClosed = pBox->m_ActiveProcessCount > 0 && count == 0;
pBox->m_ActiveProcessCount = count;
if (WasBoxClosed) {
pBox->CloseBox();
emit BoxClosed(pBox->GetName());
}
}
delete[] boxed_pids;
return SB_OK;
}
/*SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep)
{
foreach(const CSandBoxPtr& pBox, m_SandBoxes)
UpdateProcesses(bKeep, pBox);
return SB_OK;
}
SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox)
{
ULONG count = 1024;
ULONG boxed_pids[1024]; // ULONG [512]
SB_STATUS Status = CSbieAPI__GetProcessPIDs(m, pBox->GetName(), boxed_pids, &count);
ULONG count = 0;
SB_STATUS Status = CSbieAPI__GetProcessPIDs(m, pBox->GetName(), NULL, &count); // query the count
if (Status.IsError())
return Status;
count += 128; // add some extra space
ULONG* boxed_pids = new ULONG[count];
Status = CSbieAPI__GetProcessPIDs(m, pBox->GetName(), boxed_pids, &count); // query the count
if (Status.IsError())
goto finish;
QMap<quint32, CBoxedProcessPtr> OldProcessList = pBox->m_ProcessList;
for (int i=0; i < count; i++)
@ -1230,8 +1339,10 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox)
emit BoxClosed(pBox->GetName());
}
return SB_OK;
}
finish:
delete[] boxed_pids;
return Status;
}*/
bool CSbieAPI::HasProcesses(const QString& BoxName)
{
@ -1296,13 +1407,13 @@ SB_STATUS CSbieAPI::UpdateBoxPaths(const CSandBoxPtr& pSandBox)
SB_STATUS CSbieAPI::UpdateProcessInfo(const CBoxedProcessPtr& pProcess)
{
//WCHAR box_name_wchar34[34] = { 0 };
WCHAR box_name[34] = { 0 };
WCHAR image_name[MAX_PATH];
//WCHAR sid[96];
ULONG session_id;
ULONG64 create_time;
//__declspec(align(8)) UNICODE_STRING64 BoxName = { 0, sizeof(box_name_wchar34) , (ULONG64)box_name_wchar34 };
__declspec(align(8)) UNICODE_STRING64 BoxName = { 0, sizeof(box_name) , (ULONG64)box_name };
__declspec(align(8)) UNICODE_STRING64 ImageName = { 0, sizeof(image_name), (ULONG64)image_name };
//__declspec(align(8)) UNICODE_STRING64 SidString = { 0, sizeof(sid), (ULONG64)sid };
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
@ -1311,7 +1422,7 @@ SB_STATUS CSbieAPI::UpdateProcessInfo(const CBoxedProcessPtr& pProcess)
memset(parms, 0, sizeof(parms));
args->func_code = API_QUERY_PROCESS;
args->process_id.val64 = (ULONG64)pProcess->m_ProcessId;
//args->box_name.val64 = (ULONG64)&BoxName;
args->box_name.val64 = (ULONG64)&BoxName;
args->image_name.val64 = (ULONG64)&ImageName;
//args->sid_string.val64 = (ULONG64)&SidString;
args->session_id.val64 = (ULONG64)&session_id;
@ -1321,6 +1432,7 @@ SB_STATUS CSbieAPI::UpdateProcessInfo(const CBoxedProcessPtr& pProcess)
if(!NT_SUCCESS(status))
return SB_ERR(status);
pProcess->m_BoxName = QString::fromWCharArray(box_name);
pProcess->m_ImageName = QString::fromWCharArray(image_name, ImageName.Length/sizeof(WCHAR));
pProcess->m_SessionId = session_id;
pProcess->m_StartTime = QDateTime::fromMSecsSinceEpoch(FILETIME2ms(create_time));
@ -1334,7 +1446,7 @@ CSandBoxPtr CSbieAPI::GetBoxByProcessId(quint32 ProcessId) const
CBoxedProcessPtr pProcess = m_BoxedProxesses.value(ProcessId);
if (!pProcess)
return CSandBoxPtr();
return m_SandBoxes.value(pProcess->GetBoxName().toLower());
return GetBoxByName(pProcess->GetBoxName());
}
CBoxedProcessPtr CSbieAPI::GetProcessById(quint32 ProcessId) const
@ -1372,7 +1484,7 @@ SB_STATUS CSbieAPI::TerminateAll(const QString& BoxName)
req.boxname[BoxName.size()] = L'\0';
MSG_HEADER *rpl = NULL;
SB_STATUS Status = CSbieAPI::CallServer(&req.h, &rpl);
SB_STATUS Status = CallServer(&req.h, &rpl);
if (!Status || !rpl)
return Status;
if(rpl->status != 0)
@ -1399,7 +1511,7 @@ SB_STATUS CSbieAPI::Terminate(quint32 ProcessId)
req.pid = ProcessId;
MSG_HEADER *rpl = NULL;
SB_STATUS Status = CSbieAPI::CallServer(&req.h, &rpl);
SB_STATUS Status = CallServer(&req.h, &rpl);
if (!Status || !rpl)
return Status;
if (rpl->status != 0)
@ -1562,7 +1674,7 @@ SB_STATUS CSbieAPI::RunSandboxed(const QString& BoxName, const QString& Command,
*ptr++ = L'\0';
PROCESS_RUN_SANDBOXED_RPL *rpl;
SB_STATUS Status = CSbieAPI::CallServer(&req->h, &rpl);
SB_STATUS Status = CallServer(&req->h, &rpl);
free(req);
if (!Status)
return Status;
@ -1789,6 +1901,9 @@ SB_STATUS CSbieAPI::UnlockConfig(const QString& Password)
SB_STATUS CSbieAPI::LockConfig(const QString& NewPassword)
{
if(NewPassword.length() > 64)
return SB_ERR(SB_PasswordBad, STATUS_INVALID_PARAMETER);
SBIE_INI_PASSWORD_REQ *req = (SBIE_INI_PASSWORD_REQ *)malloc(REQUEST_LEN);
req->h.msgid = MSGID_SBIE_INI_SET_PASSWORD;
req->h.length = sizeof(SBIE_INI_PASSWORD_REQ);

View File

@ -60,7 +60,7 @@ public:
virtual SB_STATUS CreateBox(const QString& BoxName);
virtual SB_STATUS UpdateProcesses(bool bKeep);
virtual SB_STATUS UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox);
//virtual SB_STATUS UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox);
virtual QMap<QString, CSandBoxPtr> GetAllBoxes() { return m_SandBoxes; }

View File

@ -39,6 +39,7 @@ enum ESbieMsgCodes
SB_ConfigFailed,
SB_SnapIsEmpty,
SB_NameExists,
SB_PasswordBad,
};
class CSbieStatus

View File

@ -220,11 +220,12 @@ bool CSbieUtils::CheckRegValue(const wchar_t* key)
return true;
}
void CSbieUtils::AddContextMenu(const QString& StartPath)
void CSbieUtils::AddContextMenu(const QString& StartPath, const QString& IconPath)
{
wstring start_path = L"\"" + StartPath.toStdWString() + L"\"";
wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\"";
CreateShellEntry(L"*", L"Run &Sandboxed", start_path, start_path + L" /box:__ask__ \"%1\" %*");
CreateShellEntry(L"*", L"Run &Sandboxed", icon_path, start_path + L" /box:__ask__ \"%1\" %*");
wstring explorer_path(512, L'\0');
@ -249,7 +250,7 @@ void CSbieUtils::AddContextMenu(const QString& StartPath)
explorer_path.append(L"\\explorer.exe");
}
CreateShellEntry(L"Folder", L"Explore &Sandboxed", start_path, start_path + L" /box:__ask__ " + explorer_path + L" \"%1\"");
CreateShellEntry(L"Folder", L"Explore &Sandboxed", icon_path, start_path + L" /box:__ask__ " + explorer_path + L" \"%1\"");
}
void CSbieUtils::CreateShellEntry(const wstring& classname, const wstring& cmdtext, const wstring& iconpath, const wstring& startcmd)

View File

@ -27,7 +27,7 @@ public:
static bool IsInstalled(EComponent Component);
static int IsContextMenu();
static void AddContextMenu(const QString& StartPath);
static void AddContextMenu(const QString& StartPath, const QString& IconPath = QString());
static void RemoveContextMenu();
static bool CreateShortcut(class CSbieAPI* pApi, const QString &LinkPath, const QString &LinkName, const QString &boxname, const QString &arguments, const QString &iconPath = QString(), int iconIndex = 0, const QString &workdir = QString(), bool bRunElevated = false);

View File

@ -42,10 +42,10 @@
</font>
</property>
<property name="tabPosition">
<enum>QTabWidget::West</enum>
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>8</number>
<number>6</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
@ -1527,7 +1527,7 @@ For files access you can use 'Direct All' instead to make it apply to all progra
<layout class="QGridLayout" name="gridLayout_26">
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<item row="11" column="1">
<item row="9" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -1540,13 +1540,6 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</spacer>
</item>
<item row="7" column="1" colspan="2">
<widget class="QCheckBox" name="chkRestrictServices">
<property name="text">
<string>Do not start sandboxed services using a system token (recommended)</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QCheckBox" name="chkNoWindowRename">
<property name="text">
@ -1554,7 +1547,14 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</widget>
</item>
<item row="5" column="0">
<item row="7" column="1" colspan="2">
<widget class="QCheckBox" name="chkRestrictServices">
<property name="text">
<string>Do not start sandboxed services using a system token (recommended)</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_22">
<property name="font">
<font>
@ -1570,10 +1570,17 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="QCheckBox" name="chkProtectSystem">
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="chkPreferExternalManifest">
<property name="text">
<string>Protect sandboxed SYSTEM processes from unprivileged unsandboxed processes</string>
<string>Force usage of custom dummy Manifest files (legacy behaviour)</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="chkProtectSCM">
<property name="text">
<string>Limit access to the emulated service control manager to privileged processes</string>
</property>
</widget>
</item>
@ -1590,21 +1597,14 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QCheckBox" name="chkAddToJob">
<item row="5" column="1" colspan="2">
<widget class="QCheckBox" name="chkUseSbieWndStation">
<property name="text">
<string>Add sandboxed processes to job objects (recommended)</string>
<string>Emulate sandboxed window station for all processes</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="chkPreferExternalManifest">
<property name="text">
<string>Force usage of custom dummy Manifest files (legacy behaviour)</string>
</property>
</widget>
</item>
<item row="11" column="2">
<item row="9" column="2">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -1617,33 +1617,10 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</spacer>
</item>
<item row="8" column="0" colspan="3">
<widget class="QLabel" name="label_12">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string>Protect the sandbox integrity itself</string>
</property>
<property name="text">
<string>Sandbox protection</string>
</property>
</widget>
</item>
<item row="9" column="1" colspan="2">
<widget class="QCheckBox" name="chkProtectSCM">
<property name="text">
<string>Limit access to the emulated service control manager to privileged processes</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="chkUseSbieWndStation">
<widget class="QCheckBox" name="chkNestedJobs">
<property name="text">
<string>Emulate sandboxed window station for all processes</string>
<string>Allow use of nested job objects (experimental, works on windows 8 and later)</string>
</property>
</widget>
</item>
@ -1658,23 +1635,6 @@ For files access you can use 'Direct All' instead to make it apply to all progra
<layout class="QGridLayout" name="gridLayout_39">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_38">
<item row="3" column="1">
<widget class="QCheckBox" name="chkOpenLsaSSPI">
<property name="text">
<string>Allow sandboxed programs to Change User Passwords and alike</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_42">
<property name="text">
<string>Various advanced isolation features can break compatibility, with some applications, if you are using this sandbox &lt;b&gt;NOT for Security&lt;/b&gt; but for simple application portability by changing these options you can restore compatibility by sacrificing some security.&lt;br&gt;These options can be used securely when you don't grant any of the sandboxed process admin rights.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkOpenDevCMApi">
<property name="text">
@ -1682,7 +1642,21 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</widget>
</item>
<item row="6" column="1">
<item row="3" column="1">
<widget class="QCheckBox" name="chkOpenSamEndpoint">
<property name="text">
<string>Open access to Windows Security Account Manager</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="chkOpenLsaEndpoint">
<property name="text">
<string>Open access to windows Local Security Authority</string>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -1695,33 +1669,6 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="chkOpenSamEndpoint">
<property name="text">
<string>Open access to Windows Security Account Manager</string>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer_21">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="chkOpenLsaEndpoint">
<property name="text">
<string>Open access to windows Local Security Authority</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_41">
<property name="font">
@ -1738,6 +1685,29 @@ For files access you can use 'Direct All' instead to make it apply to all progra
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer_21">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_42">
<property name="text">
<string>Various advanced isolation features can break compatibility, with some applications, if you are using this sandbox &lt;b&gt;NOT for Security&lt;/b&gt; but for simple application portability by changing these options you can restore compatibility by sacrificing some security.&lt;br&gt;These options can be used securely when you don't grant any of the sandboxed process admin rights.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -2125,8 +2095,8 @@ instead of &quot;*&quot;.</string>
<rect>
<x>0</x>
<y>0</y>
<width>63</width>
<height>16</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<layout class="QGridLayout" name="dbgLayout">
@ -2490,7 +2460,6 @@ Please note that this values are currently user specific and saved globally for
<tabstop>btnAddStartProg</tabstop>
<tabstop>btnDelStartProg</tabstop>
<tabstop>chkStartBlockMsg</tabstop>
<tabstop>chkBlockINet</tabstop>
<tabstop>chkINetBlockPrompt</tabstop>
<tabstop>treeINet</tabstop>
<tabstop>btnAddINetProg</tabstop>
@ -2516,10 +2485,7 @@ Please note that this values are currently user specific and saved globally for
<tabstop>tabsAdvanced</tabstop>
<tabstop>chkPreferExternalManifest</tabstop>
<tabstop>chkNoWindowRename</tabstop>
<tabstop>chkAddToJob</tabstop>
<tabstop>chkRestrictServices</tabstop>
<tabstop>chkProtectSCM</tabstop>
<tabstop>chkProtectSystem</tabstop>
<tabstop>lstAutoExec</tabstop>
<tabstop>btnAddAutoExec</tabstop>
<tabstop>btnDelAutoExec</tabstop>

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectBoxWindow</class>
<widget class="QWidget" name="SelectBoxWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>280</width>
<height>400</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>SandboxiePlus sellect box</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Select the sandbox in which to start the program, installer or document.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QTreeWidget" name="treeBoxes">
<column>
<property name="text">
<string notr="true">Sandbox</string>
</property>
</column>
</widget>
</item>
<item row="7" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="chkAdmin">
<property name="text">
<string>Run As UAC Administrator</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="radBoxed">
<property name="text">
<string>Run Sandboxed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="radUnBoxed">
<property name="text">
<string>Run Outside the Sandbox</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>579</width>
<height>402</height>
<width>634</width>
<height>399</height>
</rect>
</property>
<property name="sizePolicy">
@ -49,61 +49,11 @@
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
<string>General Options</string>
<string>General Config</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_8">
<item row="12" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="1" colspan="2">
<widget class="QCheckBox" name="chkNotifications">
<property name="text">
<string>Show Notifications for relevant log Messages</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="uiLang"/>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="chkShowTray">
<property name="text">
<string>Show Sys-Tray</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="2">
<widget class="QCheckBox" name="chkSandboxUrls">
<property name="text">
<string>Open urls from this ui sandboxed</string>
</property>
<property name="tristate">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="chkAutoUpdate">
<property name="text">
<string>Check periodically for updates of Sandboxie-Plus</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label">
<property name="text">
@ -114,9 +64,6 @@
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="onClose"/>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkAutoStart">
<property name="text">
@ -125,19 +72,59 @@
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QCheckBox" name="chkShellMenu">
<widget class="QCheckBox" name="chkNotifications">
<property name="text">
<string>Add 'Run Sandboxed' to the explorer context menu</string>
<string>Show Notifications for relevant log Messages</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_18">
<item row="6" column="1" colspan="2">
<widget class="QCheckBox" name="chkSandboxUrls">
<property name="text">
<string>On main window close:</string>
<string>Open urls from this ui sandboxed</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<property name="tristate">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="uiLang"/>
</item>
<item row="8" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="chkPanic">
<property name="text">
<string>Hot-Key for terminating all boxed processes:</string>
</property>
</widget>
</item>
<item>
<widget class="QKeySequenceEdit" name="keyPanic"/>
</item>
</layout>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="onClose"/>
</item>
<item row="7" column="1" colspan="2">
<widget class="QCheckBox" name="chkShowRecovery">
<property name="text">
<string>Show first recovery window when emptying sandboxes</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QCheckBox" name="chkDarkTheme">
<property name="text">
<string>Use Dark Theme (fully applied after a restart)</string>
</property>
<property name="tristate">
<bool>true</bool>
</property>
</widget>
</item>
@ -154,6 +141,40 @@
</property>
</spacer>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="chkShowTray">
<property name="text">
<string>Show Sys-Tray</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="chkShellMenu">
<property name="text">
<string>Add 'Run Sandboxed' to the explorer context menu</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QCheckBox" name="chkSvcStart">
<property name="text">
<string>Start UI when a sandboxed process is started</string>
</property>
</widget>
</item>
<item row="12" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_5">
<property name="font">
@ -167,27 +188,13 @@
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QCheckBox" name="chkSvcStart">
<item row="11" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Start UI when a sandboxed process is started</string>
<string>On main window close:</string>
</property>
</widget>
</item>
<item row="8" column="1" colspan="2">
<widget class="QCheckBox" name="chkShowRecovery">
<property name="text">
<string>Show first recovery window when emptying sandboxes</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QCheckBox" name="chkDarkTheme">
<property name="text">
<string>Use Dark Theme (fully applied after a restart)</string>
</property>
<property name="tristate">
<bool>true</bool>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
@ -197,7 +204,7 @@
</widget>
<widget class="QWidget" name="tabAdvanced">
<attribute name="title">
<string>Advanced Options</string>
<string>Advanced Config</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
@ -416,7 +423,7 @@
</widget>
<widget class="QWidget" name="tabAlerts">
<attribute name="title">
<string>Program Restrictions</string>
<string>Program Control</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
@ -499,7 +506,7 @@
</widget>
<widget class="QWidget" name="tabCompat">
<attribute name="title">
<string>Software Compatibility</string>
<string>Compatibility</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
@ -561,6 +568,99 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Support</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_7">
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Support Settings</string>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../Resources/SandMan.qrc">:/HelpingHand.png</pixmap>
</property>
</widget>
</item>
<item row="6" column="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="3">
<widget class="QCheckBox" name="chkAutoInstall">
<property name="text">
<string>Instal updates automatically</string>
</property>
</widget>
</item>
<item row="6" column="2">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="2" colspan="2">
<widget class="QCheckBox" name="chkAutoUpdate">
<property name="text">
<string>Check periodically for updates of Sandboxie-Plus</string>
</property>
</widget>
</item>
<item row="1" column="2" rowspan="2" colspan="2">
<widget class="QLabel" name="lblSupport">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Keeping Sandboxie up to date with the rolling releases of windows and compatible with modern web browsers is a never ending endeavor. Please consider supporting this work with a donation.&lt;br /&gt;You can support the developement with a direct &lt;a href=&quot;https://sandboxie-plus.com/go.php?to=donate&quot;&gt;PayPal donation&lt;/a&gt;, works also with credit cards.&lt;br /&gt;You can also provide continuous support with a &lt;a href=&quot;https://sandboxie-plus.com/go.php?to=patreon&quot;&gt;Patreon subscription&lt;/a&gt;.</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
@ -580,7 +680,6 @@
<tabstop>chkDarkTheme</tabstop>
<tabstop>chkAutoStart</tabstop>
<tabstop>chkSvcStart</tabstop>
<tabstop>chkAutoUpdate</tabstop>
<tabstop>chkShellMenu</tabstop>
<tabstop>chkNotifications</tabstop>
<tabstop>chkSandboxUrls</tabstop>
@ -610,6 +709,8 @@
<tabstop>btnDelCompat</tabstop>
<tabstop>chkNoCompat</tabstop>
</tabstops>
<resources/>
<resources>
<include location="../Resources/SandMan.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -3,13 +3,11 @@
#include "../../MiscHelpers/Common/Common.h"
#include "../../MiscHelpers/Common/IconExtreactor.h"
#include <QFileIconProvider>
#include "../SandMan.h"
CSbieModel::CSbieModel(QObject *parent)
:CTreeItemModel(parent)
{
for (int i = 0; i < eMaxColor; i++)
m_BoxIcons[(EBoxColors)i] = qMakePair(QIcon(QString(":/Boxes/Empty%1").arg(i)), QIcon(QString(":/Boxes/Full%1").arg(i)));
//m_BoxEmpty = QIcon(":/BoxEmpty");
//m_BoxInUse = QIcon(":/BoxInUse");
m_ExeIcon = QIcon(":/exeIcon32");
@ -128,7 +126,7 @@ QList<QVariant> CSbieModel::Sync(const QMap<QString, CSandBoxPtr>& BoxList, cons
New[pNode->Path].append(pNode);
Added.append(ID);
pNode->Icon = m_BoxIcons[eYelow].first;
pNode->Icon = theGUI->GetBoxIcon(false);
pNode->IsBold = true;
pNode->Values[eName].Raw = Group;
@ -175,22 +173,15 @@ QList<QVariant> CSbieModel::Sync(const QMap<QString, CSandBoxPtr>& BoxList, cons
QMap<quint32, CBoxedProcessPtr> ProcessList = pBox->GetProcessList();
bool HasActive = Sync(pBox, pNode->Path, ProcessList, New, Old, Added);
int inUse = (HasActive ? 1 : 0);
int boxType = eYelow;
if(pBoxEx->HasLogApi())
boxType = eRed;
if (pBoxEx->IsUnsecureDebugging())
boxType = eMagenta;
else if (pBoxEx->IsSecurityRestricted())
boxType = eOrang;
bool inUse = Sync(pBox, pNode->Path, ProcessList, New, Old, Added);
int boxType = pBoxEx->GetType();
if (pNode->inUse != inUse || pNode->boxType != boxType)
{
pNode->inUse = inUse;
pNode->boxType = boxType;
//pNode->Icon = pNode->inUse ? m_BoxInUse : m_BoxEmpty;
pNode->Icon = pNode->inUse ? m_BoxIcons[(EBoxColors)boxType].second : m_BoxIcons[(EBoxColors)boxType].first;
pNode->Icon = theGUI->GetBoxIcon(inUse, boxType);
Changed = 1; // set change for first column
}

View File

@ -46,10 +46,10 @@ protected:
struct SSandBoxNode: STreeNode
{
SSandBoxNode(const QVariant& Id) : STreeNode(Id) { inUse = -1; boxType = -1; }
SSandBoxNode(const QVariant& Id) : STreeNode(Id) { inUse = false; boxType = -1; }
CSandBoxPtr pBox;
int inUse;
bool inUse;
int boxType;
CBoxedProcessPtr pProcess;
@ -68,19 +68,6 @@ protected:
//virtual QVariant GetDefaultIcon() const;
private:
enum EBoxColors
{
eYelow = 0,
eRed,
eGreen,
eBlue,
eCyan,
eMagenta,
eOrang,
eMaxColor
};
QMap<EBoxColors, QPair<QIcon, QIcon> > m_BoxIcons;
//QIcon m_BoxEmpty;
//QIcon m_BoxInUse;

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -47,6 +47,10 @@
<file>SandManN.png</file>
<file>Actions/finder.png</file>
<file>Actions/Tree.png</file>
<file>Actions/Support.png</file>
<file>HelpingHand.png</file>
<file>Actions/RegEdit.png</file>
<file>Actions/Software.png</file>
</qresource>
<qresource prefix="/Boxes">
<file alias="Empty3">Boxes/sandbox-b-empty.png</file>

View File

@ -19,6 +19,8 @@
#include "../MiscHelpers/Common/TreeItemModel.h"
#include "../MiscHelpers/Common/ListItemModel.h"
#include "Views/TraceView.h"
#include "Windows/SelectBoxWindow.h"
#include "../UGlobalHotkey/uglobalhotkeys.h"
CSbiePlusAPI* theAPI = NULL;
@ -27,6 +29,7 @@ CSbiePlusAPI* theAPI = NULL;
#include <QAbstractNativeEventFilter>
#include <dbt.h>
//BOOLEAN OnWM_Notify(NMHDR *Header, LRESULT *Result);
class CNativeEventFilter : public QAbstractNativeEventFilter
@ -177,6 +180,12 @@ CSandMan::CSandMan(QWidget *parent)
m_pTraceView = new CTraceView(this);
m_pLogTabs->addTab(m_pTraceView, tr("Trace Log"));
m_pHotkeyManager = new UGlobalHotkeys(this);
connect(m_pHotkeyManager, SIGNAL(activated(size_t)), SLOT(OnHotKey(size_t)));
SetupHotKeys();
for (int i = 0; i < eMaxColor; i++)
m_BoxIcons[(EBoxColors)i] = qMakePair(QIcon(QString(":/Boxes/Empty%1").arg(i)), QIcon(QString(":/Boxes/Full%1").arg(i)));
// Tray
QIcon Icon;
@ -502,6 +511,17 @@ void CSandMan::closeEvent(QCloseEvent *e)
QApplication::quit();
}
QIcon CSandMan::GetBoxIcon(bool inUse, int boxType)
{
EBoxColors color = eYelow;
switch (boxType) {
case CSandBoxPlus::eHardened: color = eOrang; break;
case CSandBoxPlus::eHasLogApi: color = eRed; break;
case CSandBoxPlus::eInsecure: color = eMagenta; break;
}
return inUse ? m_BoxIcons[color].second : m_BoxIcons[color].first;
}
bool CSandMan::IsFullyPortable()
{
QString SbiePath = theAPI->GetSbiePath();
@ -520,6 +540,12 @@ void CSandMan::OnMessage(const QString& Message)
setWindowState(Qt::WindowActive);
SetForegroundWindow(MainWndHandle);
}
else if (Message.left(3) == "Run")
{
QString CmdLine = Message.mid(4);
RunSandboxed(QStringList(CmdLine));
}
else if (Message.left(6) == "Status")
{
QString Status = Message.mid(7);
@ -556,27 +582,21 @@ void CSandMan::dragEnterEvent(QDragEnterEvent* e)
}
}
void CSandMan::RunSandboxed(const QStringList& Commands)
{
CSelectBoxWindow* pSelectBoxWindow = new CSelectBoxWindow(Commands);
pSelectBoxWindow->show();
}
void CSandMan::dropEvent(QDropEvent* e)
{
QStringList Boxes;
foreach(const CSandBoxPtr &pBox, theAPI->GetAllBoxes())
{
if (pBox->IsEnabled())
Boxes.append(pBox->GetName().replace("_", " "));
}
bool ok;
QString box = QInputDialog::getItem(this, "Sandboxie-Plus", tr("Select box:"), Boxes, 0, false, &ok);
if (!ok || box.isEmpty())
return;
QStringList Commands;
foreach(const QUrl & url, e->mimeData()->urls()) {
if (!url.isLocalFile())
continue;
QString FileName = url.toLocalFile().replace("/", "\\");
theAPI->RunStart(box.replace(" ", "_"), FileName);
if (url.isLocalFile())
Commands.append(url.toLocalFile().replace("/", "\\"));
}
RunSandboxed(Commands);
}
void CSandMan::timerEvent(QTimerEvent* pEvent)
@ -590,11 +610,6 @@ void CSandMan::timerEvent(QTimerEvent* pEvent)
{
SB_STATUS Status = theAPI->ReloadBoxes();
if (!Status.IsError() && !theAPI->GetAllBoxes().contains("defaultbox")) {
OnLogMessage(tr("Default sandbox not found; creating: %1").arg("DefaultBox"));
theAPI->CreateBox("DefaultBox");
}
theAPI->UpdateProcesses(m_pKeepTerminated->isChecked());
bForceProcessDisabled = theAPI->AreForceProcessDisabled();
@ -717,7 +732,7 @@ void CSandMan::OnBoxClosed(const QString& BoxName)
if (!pBox->GetBool("NeverDelete", false) && pBox->GetBool("AutoDelete", false) && !pBox->IsEmpty())
{
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox);
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox, this);
if (pRecoveryWindow->FindFiles() == 0)
delete pRecoveryWindow;
else if (pRecoveryWindow->exec() != 1)
@ -762,11 +777,16 @@ void CSandMan::OnStatusChanged()
{
appTitle.append(tr(" - Portable"));
QString BoxPath = QDir::cleanPath(QApplication::applicationDirPath() + "/../Sandbox").replace("/", "\\");
int PortableRootDir = theConf->GetInt("Options/PortableRootDir", -1);
if (PortableRootDir == -1)
{
bool State = false;
PortableRootDir = CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Sandboxie-Plus was started in portable mode, do you want to put the SandBox folder into its parent directory?")
PortableRootDir = CCheckableMessageBox::question(this, "Sandboxie-Plus",
tr("Sandboxie-Plus was started in portable mode, do you want to put the Sandbox folder into its parent directory?\r\nYes will choose: %1\r\nNo will choose: %2")
.arg(BoxPath)
.arg("C:\\Sandbox") // todo resolve os drive properly
, tr("Don't show this message again."), &State, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes, QMessageBox::Information) == QDialogButtonBox::Yes ? 1 : 0;
if (State)
@ -774,10 +794,7 @@ void CSandMan::OnStatusChanged()
}
if (PortableRootDir)
{
QString BoxPath = QDir::cleanPath(QApplication::applicationDirPath() + "/../Sandbox/%SANDBOX%").replace("/", "\\");
theAPI->GetGlobalSettings()->SetText("FileRootPath", BoxPath);
}
theAPI->GetGlobalSettings()->SetText("FileRootPath", BoxPath + "\\%SANDBOX%");
}
if (theConf->GetBool("Options/AutoRunSoftCompat", true))
@ -802,6 +819,14 @@ void CSandMan::OnStatusChanged()
if (theConf->GetBool("Options/WatchIni", true))
theAPI->WatchIni(true);
SB_STATUS Status = theAPI->ReloadBoxes();
if (!Status.IsError() && !theAPI->GetAllBoxes().contains("defaultbox")) {
OnLogMessage(tr("Default sandbox not found; creating: %1").arg("DefaultBox"));
theAPI->CreateBox("DefaultBox");
}
}
else
{
@ -860,6 +885,26 @@ void CSandMan::OnMenuHover(QAction* action)
}
}
#define HK_PANIC 1
void CSandMan::SetupHotKeys()
{
m_pHotkeyManager->unregisterAllHotkeys();
if (theConf->GetBool("Options/EnablePanicKey", false))
m_pHotkeyManager->registerHotkey(theConf->GetString("Options/PanicKeySequence", "Ctrl+Cancel"), HK_PANIC);
}
void CSandMan::OnHotKey(size_t id)
{
switch (id)
{
case HK_PANIC:
theAPI->TerminateAll();
break;
}
}
void CSandMan::OnLogMessage(const QString& Message, bool bNotify)
{
QTreeWidgetItem* pItem = new QTreeWidgetItem(); // Time|Message
@ -1281,6 +1326,8 @@ void CSandMan::UpdateSettings()
//m_pBoxView->UpdateRunMenu();
SetupHotKeys();
if (theConf->GetBool("Options/ShowSysTray", true))
m_pTrayIcon->show();
else
@ -1473,6 +1520,7 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
case SB_ConfigFailed: Message = tr("Failed to set configuration setting %1 in section %2: %3"); break;
case SB_SnapIsEmpty: Message = tr("Can not create snapshot of an empty sandbox"); break;
case SB_NameExists: Message = tr("A sandbox with that name already exists"); break;
case SB_PasswordBad: Message = tr("The config password must not be longer than 64 charakters"); break;
default: return tr("Unknown Error Status: %1").arg(Error.GetStatus());
}
@ -1532,7 +1580,6 @@ void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason)
}
show();
case QSystemTrayIcon::Trigger:
#ifdef WIN32
if (isVisible() && !TriggerSet)
{
TriggerSet = true;
@ -1546,7 +1593,7 @@ void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason)
SetForegroundWindow(MainWndHandle);
} );
}
#endif
m_pPopUpWindow->Poke();
break;
}
}
@ -1905,6 +1952,7 @@ void CSandMan::SetUITheme()
QApplication::setPalette(m_DefaultPalett);
}
m_DarkTheme = bDark;
CTreeItemModel::SetDarkMode(bDark);
CListItemModel::SetDarkMode(bDark);
CPopUpWindow::SetDarkMode(bDark);
@ -2022,8 +2070,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
wstring info = CSandMan::tr("Drag the Finder Tool over a window to select it, then release the mouse to check if the window is sandboxed.").toStdWString();
CreateWindow(L"Static", L"", SS_BITMAP | SS_NOTIFY | WS_VISIBLE | WS_CHILD, 10, 10, 32, 32, hwnd, (HMENU)ID_FINDER_TARGET, NULL, NULL);
CreateWindow(L"Static", info.c_str(), WS_VISIBLE | WS_CHILD, 60, 10, 180, 50, hwnd, (HMENU)ID_FINDER_EXPLAIN, NULL, NULL);
CreateWindow(L"Static", L"", WS_CHILD, 60, 70, 180, 50, hwnd, (HMENU)ID_FINDER_RESULT, NULL, NULL);
CreateWindow(L"Static", info.c_str(), WS_VISIBLE | WS_CHILD, 60, 10, 180, 65, hwnd, (HMENU)ID_FINDER_EXPLAIN, NULL, NULL);
CreateWindow(L"Static", L"", WS_CHILD, 60, 80, 180, 50, hwnd, (HMENU)ID_FINDER_RESULT, NULL, NULL);
MakeFinderTool(GetDlgItem(hwnd, ID_FINDER_TARGET), FindProc);
@ -2075,7 +2123,7 @@ DWORD WINAPI FinderThreadFunc(LPVOID lpParam)
// child windows with the same parent window.
HWND hwnd = CreateWindow(mainWindowClass.lpszClassName, CSandMan::tr("Sandboxie-Plus - Window Finder").toStdWString().c_str()
, WS_SYSMENU | WS_CAPTION | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 275, 100, NULL, 0, hInstance, NULL);
, WS_SYSMENU | WS_CAPTION | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 275, 115, NULL, 0, hInstance, NULL);
HFONT hFont = CreateFont(13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Tahoma"));

View File

@ -23,6 +23,7 @@ class CBoxBorder;
class CSbieTemplates;
class CTraceView;
class CSandMan : public QMainWindow
{
Q_OBJECT
@ -49,6 +50,10 @@ public:
CSbieView* GetBoxView() { return m_pBoxView; }
void RunSandboxed(const QStringList& Commands);
QIcon GetBoxIcon(bool inUse, int boxType = 0);
protected:
SB_STATUS ConnectSbie();
SB_STATUS ConnectSbieImpl();
@ -76,6 +81,22 @@ protected:
QStringList m_MissingTemplates;
enum EBoxColors
{
eYelow = 0,
eRed,
eGreen,
eBlue,
eCyan,
eMagenta,
eOrang,
eMaxColor
};
QMap<EBoxColors, QPair<QIcon, QIcon> > m_BoxIcons;
class UGlobalHotkeys* m_pHotkeyManager;
public slots:
void OnMessage(const QString&);
@ -93,6 +114,9 @@ public slots:
void UpdateSettings();
void OnIniReloaded();
void SetupHotKeys();
void OnHotKey(size_t id);
void OnAsyncFinished();
void OnAsyncFinished(CSbieProgress* pProgress);
void OnAsyncMessage(const QString& Text);
@ -233,6 +257,7 @@ private:
void LoadLanguage();
QTranslator m_Translator;
QByteArray m_Translation;
public:
quint32 m_LanguageId;
bool m_DarkTheme;

View File

@ -18,7 +18,8 @@ HEADERS += ./stdafx.h \
./Windows/PopUpWindow.h \
./Windows/SnapshotsWindow.h \
./Windows/SettingsWindow.h \
./Windows/OptionsWindow.h
./Windows/OptionsWindow.h \
./Windows/SelectBoxWindow.h
SOURCES += ./main.cpp \
./stdafx.cpp \
@ -37,18 +38,21 @@ SOURCES += ./main.cpp \
./Windows/PopUpWindow.cpp \
./Windows/RecoveryWindow.cpp \
./Windows/SettingsWindow.cpp \
./Windows/SnapshotsWindow.cpp
./Windows/SnapshotsWindow.cpp \
./Windows/SelectBoxWindow.cpp
FORMS += ./Forms/NewBoxWindow.ui \
./Forms/OptionsWindow.ui \
./Forms/PopUpWindow.ui \
./Forms/RecoveryWindow.ui \
./Forms/SettingsWindow.ui \
./Forms/SnapshotsWindow.ui
./Forms/SnapshotsWindow.ui \
./Forms/SelectBoxWindow.ui
TRANSLATIONS += sandman_de.ts \
sandman_es.ts \
sandman_it.ts \
sandman_nl.ts \
sandman_pt.ts \
sandman_ru.ts \
sandman_pl.ts \

View File

@ -12,7 +12,7 @@ CONFIG(release, debug|release):contains(QMAKE_HOST.arch, x86_64):LIBS += -L../Bi
CONFIG(debug, debug|release):!contains(QMAKE_HOST.arch, x86_64):LIBS += -L../Bin/Win32/Debug
CONFIG(release, debug|release):!contains(QMAKE_HOST.arch, x86_64):LIBS += -L../Bin/Win32/Release
LIBS += -lNtdll -lAdvapi32 -lOle32 -lUser32 -lShell32 -lGdi32 -lQSbieAPI -lMiscHelpers -lqtsingleapp
LIBS += -lNtdll -lAdvapi32 -lOle32 -lUser32 -lShell32 -lGdi32 -lQSbieAPI -lMiscHelpers -lqtsingleapp -lUGlobalHotkey
CONFIG(release, debug|release):{
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO

View File

@ -121,7 +121,7 @@
<SubSystem>Windows</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -146,7 +146,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalOptions> /SUBSYSTEM:WINDOWS</AdditionalOptions>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -167,7 +167,7 @@
<SubSystem>Windows</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -191,7 +191,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalOptions> /SUBSYSTEM:WINDOWS</AdditionalOptions>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@ -216,10 +216,12 @@
<ClCompile Include="Windows\OptionsWindow.cpp" />
<ClCompile Include="Windows\PopUpWindow.cpp" />
<ClCompile Include="Windows\RecoveryWindow.cpp" />
<ClCompile Include="Windows\SelectBoxWindow.cpp" />
<ClCompile Include="Windows\SettingsWindow.cpp" />
<ClCompile Include="Windows\SnapshotsWindow.cpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="Windows\SelectBoxWindow.h" />
<QtMoc Include="Views\TraceView.h" />
<QtMoc Include="Windows\NewBoxWindow.h" />
<QtMoc Include="Windows\RecoveryWindow.h" />
@ -251,6 +253,7 @@
<QtUic Include="Forms\OptionsWindow.ui" />
<QtUic Include="Forms\PopUpWindow.ui" />
<QtUic Include="Forms\RecoveryWindow.ui" />
<QtUic Include="Forms\SelectBoxWindow.ui" />
<QtUic Include="Forms\SettingsWindow.ui" />
<QtUic Include="Forms\SnapshotsWindow.ui" />
</ItemGroup>

View File

@ -102,6 +102,9 @@
<ClCompile Include="Views\TraceView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="Windows\SelectBoxWindow.cpp">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -157,6 +160,9 @@
<QtMoc Include="Views\TraceView.h">
<Filter>Views</Filter>
</QtMoc>
<QtMoc Include="Windows\SelectBoxWindow.h">
<Filter>Windows</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<QtRcc Include="Resources\SandMan.qrc">
@ -193,6 +199,9 @@
<QtUic Include="Forms\NewBoxWindow.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="Forms\SelectBoxWindow.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
<ItemGroup>
<None Include="sandman_de.ts">

View File

@ -375,6 +375,17 @@ int CSandBoxPlus::IsLeaderProgram(const QString& ProgName)
return FindInStrList(Programs, ProgName) != Programs.end() ? 1 : 0;
}
CSandBoxPlus::EBoxTypes CSandBoxPlus::GetType() const
{
if (m_bLogApiFound)
return eHasLogApi;
if (m_iUnsecureDebugging != 0)
return eInsecure;
if (m_bSecurityRestricted)
return eHardened;
return eDefault;
}
///////////////////////////////////////////////////////////////////////////////
// CSbieProcess
//

View File

@ -72,6 +72,19 @@ public:
const QSet<QString>& GetRecentPrograms() { return m_RecentPrograms; }
enum EBoxTypes
{
eDefault = 0,
eHardened,
eHasLogApi,
eInsecure,
eUnknown = -1
};
EBoxTypes GetType() const;
protected:
friend class CSbiePlusAPI;
virtual bool CheckOpenToken() const;

View File

@ -68,11 +68,13 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
m_pMenuRun = m_pMenu->addMenu(CSandMan::GetIcon("Start"), tr("Run"));
m_pMenuRunAny = m_pMenuRun->addAction(CSandMan::GetIcon("Run"), tr("Run Program"), this, SLOT(OnSandBoxAction()));
m_pMenuRunMenu = m_pMenuRun->addAction(CSandMan::GetIcon("StartMenu"), tr("Run from Start Menu"), this, SLOT(OnSandBoxAction()));
m_pMenuRunBrowser = m_pMenuRun->addAction(CSandMan::GetIcon("Internet"), tr("Run Web Browser"), this, SLOT(OnSandBoxAction()));
m_pMenuRunMailer = m_pMenuRun->addAction(CSandMan::GetIcon("Email"), tr("Run eMail Client"), this, SLOT(OnSandBoxAction()));
m_pMenuRunExplorer = m_pMenuRun->addAction(CSandMan::GetIcon("Explore"), tr("Run Explorer"), this, SLOT(OnSandBoxAction()));
m_pMenuRunCmd = m_pMenuRun->addAction(CSandMan::GetIcon("Cmd"), tr("Run Cmd.exe"), this, SLOT(OnSandBoxAction()));
m_pMenuRunCmdAdmin = m_pMenuRun->addAction(CSandMan::GetIcon("Cmd"), tr("Run Cmd.exe as Admin"), this, SLOT(OnSandBoxAction()));
m_pMenuRunBrowser = m_pMenuRun->addAction(CSandMan::GetIcon("Internet"), tr("Default Web Browser"), this, SLOT(OnSandBoxAction()));
m_pMenuRunMailer = m_pMenuRun->addAction(CSandMan::GetIcon("Email"), tr("Default eMail Client"), this, SLOT(OnSandBoxAction()));
m_pMenuRunExplorer = m_pMenuRun->addAction(CSandMan::GetIcon("Explore"), tr("Windows Explorer"), this, SLOT(OnSandBoxAction()));
m_pMenuRunRegEdit = m_pMenuRun->addAction(CSandMan::GetIcon("RegEdit"), tr("Registry Editor"), this, SLOT(OnSandBoxAction()));
m_pMenuRunAppWiz = m_pMenuRun->addAction(CSandMan::GetIcon("Software"), tr("Programs and Features"), this, SLOT(OnSandBoxAction()));
m_pMenuRunCmd = m_pMenuRun->addAction(CSandMan::GetIcon("Cmd"), tr("Terminal"), this, SLOT(OnSandBoxAction()));
m_pMenuRunCmdAdmin = m_pMenuRun->addAction(CSandMan::GetIcon("Cmd"), tr("Terminal (as Admin)"), this, SLOT(OnSandBoxAction()));
m_pMenuRun->addSeparator();
m_iMenuRun = m_pMenuRun->actions().count();
m_pMenuEmptyBox = m_pMenu->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate All Programs"), this, SLOT(OnSandBoxAction()));
@ -500,23 +502,9 @@ void CSbieView::OnGroupAction()
m_pSbieModel->Clear(); //todo improve that
}
StoreGroups();
UpdateGroupMenu();
}
void CSbieView::StoreGroups()
{
QMap<QString, CSandBoxPtr> Boxes = theAPI->GetAllBoxes();
for (auto I = m_Groups.begin(); I != m_Groups.end(); ++I) {
for (auto J = I->begin(); J != I->end(); ) {
if (!Boxes.take(J->toLower()).isNull() || m_Groups.contains(*J)) ++J;
else J = I->erase(J);
}
}
QString Grouping = CSbieView__SerializeGroup(m_Groups);
theAPI->GetUserSettings()->SetText("BoxDisplayOrder", Grouping);
UpdateGroupMenu();
}
QString CSbieView::AddNewBox()
@ -575,6 +563,10 @@ void CSbieView::OnSandBoxAction(QAction* Action)
Results.append(SandBoxes.first()->RunStart("explorer.exe /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"));
}
else if (Action == m_pMenuRunRegEdit)
Results.append(SandBoxes.first()->RunStart("regedit.exe"));
else if (Action == m_pMenuRunAppWiz)
Results.append(SandBoxes.first()->RunStart("\"C:\\WINDOWS\\System32\\control.exe\" \"C:\\Windows\\System32\\appwiz.cpl\""));
else if (Action == m_pMenuRunCmd)
Results.append(SandBoxes.first()->RunStart("cmd.exe"));
else if (Action == m_pMenuRunCmdAdmin)
@ -639,22 +631,11 @@ void CSbieView::OnSandBoxAction(QAction* Action)
}
else if (Action == m_pMenuRename)
{
QString OldName = SandBoxes.first()->GetName();
QString OldValue = OldName.replace("_", " ");
QString OldValue = SandBoxes.first()->GetName().replace("_", " ");
QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a new name for the Sandbox."), QLineEdit::Normal, OldValue);
if (Value.isEmpty() || Value == OldValue)
return;
QString NewName = Value.replace(" ", "_");
Results.append((SandBoxes.first()->RenameBox(NewName)));
// update grouping
for (auto I = m_Groups.begin(); I != m_Groups.end(); ++I) {
int pos = I->indexOf(OldName);
if (pos != -1)
I->replace(pos, NewName);
}
StoreGroups();
Results.append((SandBoxes.first()->RenameBox(Value.replace(" ", "_"))));
}
else if (Action == m_pMenuRemove)
{
@ -662,21 +643,7 @@ void CSbieView::OnSandBoxAction(QAction* Action)
return;
foreach(const CSandBoxPtr& pBox, SandBoxes)
{
QString Name = pBox->GetName();
SB_STATUS Status = pBox->RemoveBox();
// update grouping
if (!Status.IsError()) {
for (auto I = m_Groups.begin(); I != m_Groups.end(); ++I) {
I->removeAll(Name);
}
}
Results.append(Status);
}
StoreGroups();
Results.append(pBox->RemoveBox());
}
else if (Action == m_pMenuRecover)
{
@ -693,7 +660,7 @@ void CSbieView::OnSandBoxAction(QAction* Action)
if (theConf->GetBool("Options/ShowRecovery", false))
{
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(SandBoxes.first());
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(SandBoxes.first(), this);
pRecoveryWindow->FindFiles();
if (pRecoveryWindow->exec() != 1)
return;

View File

@ -27,7 +27,6 @@ signals:
public slots:
void Clear();
void Refresh();
void StoreGroups();
void ReloadGroups();
private slots:
@ -73,6 +72,8 @@ private:
QAction* m_pMenuRunBrowser;
QAction* m_pMenuRunMailer;
QAction* m_pMenuRunExplorer;
QAction* m_pMenuRunRegEdit;
QAction* m_pMenuRunAppWiz;
QAction* m_pMenuRunCmd;
QAction* m_pMenuRunCmdAdmin;
QAction* m_pMenuMkLink;

View File

@ -7,8 +7,6 @@
CNewBoxWindow::CNewBoxWindow(QWidget *parent)
: QDialog(parent)
{
this->setWindowTitle(tr("Sandboxie-Plus - Create New Box"));
Qt::WindowFlags flags = windowFlags();
flags |= Qt::CustomizeWindowHint;
//flags &= ~Qt::WindowContextHelpButtonHint;
@ -21,6 +19,7 @@ CNewBoxWindow::CNewBoxWindow(QWidget *parent)
setWindowFlags(flags);
ui.setupUi(this);
this->setWindowTitle(tr("Sandboxie-Plus - Create New Box"));
connect(ui.buttonBox, SIGNAL(accepted()), SLOT(CreateBox()));
connect(ui.buttonBox, SIGNAL(rejected()), SLOT(reject()));

View File

@ -1,45 +1,12 @@
#include "stdafx.h"
#include "OptionsWindow.h"
#include "SandMan.h"
#include "SettingsWindow.h"
#include "../MiscHelpers/Common/Settings.h"
#include "../MiscHelpers/Common/Common.h"
#include "../MiscHelpers/Common/ComboInputDialog.h"
#include "../MiscHelpers/Common/SettingsWidgets.h"
#include "Helpers/WinAdmin.h"
#include <QProxyStyle>
class CustomTabStyle : public QProxyStyle {
public:
CustomTabStyle(QStyle* style = 0) : QProxyStyle(style) {}
QSize sizeFromContents(ContentsType type, const QStyleOption* option,
const QSize& size, const QWidget* widget) const {
QSize s = QProxyStyle::sizeFromContents(type, option, size, widget);
if (type == QStyle::CT_TabBarTab) {
s.transpose();
if(theGUI->m_DarkTheme)
s.setHeight(s.height() * 13 / 10);
else
s.setHeight(s.height() * 15 / 10);
s.setWidth(s.width() * 11 / 10); // for the the icon
}
return s;
}
void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
if (element == CE_TabBarTabLabel) {
if (const QStyleOptionTab* tab = qstyleoption_cast<const QStyleOptionTab*>(option)) {
QStyleOptionTab opt(*tab);
opt.shape = QTabBar::RoundedNorth;
//opt.iconSize = QSize(32, 32);
opt.iconSize = QSize(24, 24);
QProxyStyle::drawControl(element, &opt, painter, widget);
return;
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
};
COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QString& Name, QWidget *parent)
@ -72,6 +39,19 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
ui.tabs->setTabPosition(QTabWidget::West);
ui.tabs->tabBar()->setStyle(new CustomTabStyle(ui.tabs->tabBar()->style()));
ui.tabs->setTabIcon(0, CSandMan::GetIcon("Box"));
ui.tabs->setTabIcon(1, CSandMan::GetIcon("Group"));
ui.tabs->setTabIcon(2, CSandMan::GetIcon("Force"));
ui.tabs->setTabIcon(3, CSandMan::GetIcon("Stop"));
ui.tabs->setTabIcon(4, CSandMan::GetIcon("Start"));
ui.tabs->setTabIcon(5, CSandMan::GetIcon("Internet"));
ui.tabs->setTabIcon(6, CSandMan::GetIcon("Wall"));
ui.tabs->setTabIcon(7, CSandMan::GetIcon("Recover"));
ui.tabs->setTabIcon(8, CSandMan::GetIcon("Advanced"));
ui.tabs->setTabIcon(9, CSandMan::GetIcon("Template"));
ui.tabs->setTabIcon(10, CSandMan::GetIcon("EditIni"));
QStringList DebugOptions = theConf->ListKeys("DebugOptions");
if(DebugOptions.isEmpty())
ui.tabsAdvanced->removeTab(ui.tabsAdvanced->count() - 1);
@ -123,18 +103,6 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
//ui.chkWithTemplates->setEnabled(false);
}
ui.tabs->setTabIcon(0, CSandMan::GetIcon("Box"));
ui.tabs->setTabIcon(1, CSandMan::GetIcon("Group"));
ui.tabs->setTabIcon(2, CSandMan::GetIcon("Force"));
ui.tabs->setTabIcon(3, CSandMan::GetIcon("Stop"));
ui.tabs->setTabIcon(4, CSandMan::GetIcon("Start"));
ui.tabs->setTabIcon(5, CSandMan::GetIcon("Internet"));
ui.tabs->setTabIcon(6, CSandMan::GetIcon("Wall"));
ui.tabs->setTabIcon(7, CSandMan::GetIcon("Recover"));
ui.tabs->setTabIcon(8, CSandMan::GetIcon("Advanced"));
ui.tabs->setTabIcon(9, CSandMan::GetIcon("Template"));
ui.tabs->setTabIcon(10, CSandMan::GetIcon("EditIni"));
ui.tabs->setCurrentIndex(m_Template ? 10 : 0);
//connect(ui.chkWithTemplates, SIGNAL(clicked(bool)), this, SLOT(OnWithTemplates()));
@ -252,7 +220,7 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
connect(ui.chkShowAccessTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowAccessTmpl()));
connect(ui.btnDelAccess, SIGNAL(clicked(bool)), this, SLOT(OnDelAccess()));
connect(ui.treeAccess, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnAccessItemClicked(QTreeWidgetItem*, int)));
//connect(ui.treeAccess, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnAccessItemClicked(QTreeWidgetItem*, int)));
connect(ui.treeAccess, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnAccessItemDoubleClicked(QTreeWidgetItem*, int)));
connect(ui.treeAccess, SIGNAL(itemSelectionChanged()), this, SLOT(OnAccessSelectionChanged()));
//
@ -273,20 +241,19 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
// Advanced
connect(ui.chkPreferExternalManifest, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkNoWindowRename, SIGNAL(clicked(bool)), this, SLOT(OnNoWindowRename()));
connect(ui.chkNestedJobs, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkUseSbieWndStation, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkProtectSCM, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkRestrictServices, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkProtectSystem, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
//connect(ui.chkProtectSystem, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkOpenDevCMApi, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkOpenLsaSSPI, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
//connect(ui.chkOpenLsaSSPI, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkOpenSamEndpoint, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkOpenLsaEndpoint, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkAddToJob, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkDisableMonitor, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkCallTrace, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
@ -534,22 +501,20 @@ void COptionsWindow::LoadConfig()
{
ui.chkPreferExternalManifest->setChecked(m_pBox->GetBool("PreferExternalManifest", false));
ui.chkNestedJobs->setChecked(m_pBox->GetBool("AllowBoxedJobs", false));
ui.chkUseSbieWndStation->setChecked(m_pBox->GetBool("UseSbieWndStation", false));
ui.chkProtectSCM->setChecked(!m_pBox->GetBool("UnrestrictedSCM", false));
ui.chkRestrictServices->setChecked(!m_pBox->GetBool("RunServicesAsSystem", false));
ui.chkProtectSystem->setChecked(!m_pBox->GetBool("ExposeBoxedSystem", false));
//ui.chkProtectSystem->setChecked(!m_pBox->GetBool("ExposeBoxedSystem", false));
ui.chkOpenDevCMApi->setChecked(m_pBox->GetBool("OpenDevCMApi", false));
ui.chkOpenLsaSSPI->setChecked(!m_pBox->GetBool("BlockPassword", true)); // OpenLsaSSPI
//ui.chkOpenLsaSSPI->setChecked(!m_pBox->GetBool("BlockPassword", true)); // OpenLsaSSPI
ui.chkOpenSamEndpoint->setChecked(m_pBox->GetBool("OpenSamEndpoint", false));
ui.chkOpenLsaEndpoint->setChecked(m_pBox->GetBool("OpenLsaEndpoint", false));
ui.chkAddToJob->setChecked(!m_pBox->GetBool("NoAddProcessToJob", false));
QStringList AutoExec = m_pBox->GetTextList("AutoExec", m_Template);
ui.lstAutoExec->clear();
ui.lstAutoExec->addItems(AutoExec);
@ -601,8 +566,14 @@ void COptionsWindow::LoadConfig()
void COptionsWindow::WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name, const QString& Value)
{
if (pCheck->checkState() == Qt::Checked) m_pBox->SetText(Name, Value);
else if (pCheck->checkState() == Qt::Unchecked) m_pBox->DelValue(Name);
SB_STATUS Status;
if (pCheck->checkState() == Qt::Checked)
Status = m_pBox->SetText(Name, Value);
else if (pCheck->checkState() == Qt::Unchecked)
Status = m_pBox->DelValue(Name);
if (!Status)
throw Status;
}
void COptionsWindow::WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name, const QString& OnValue, const QString& OffValue)
@ -610,33 +581,53 @@ void COptionsWindow::WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name,
//if (pCheck->checkState() == Qt::PartiallyChecked)
// return;
SB_STATUS Status;
if (pCheck->checkState() == Qt::Checked)
{
if(!OnValue.isEmpty())
m_pBox->SetText(Name, OnValue);
Status = m_pBox->SetText(Name, OnValue);
else
m_pBox->DelValue(Name);
Status = m_pBox->DelValue(Name);
}
else if (pCheck->checkState() == Qt::Unchecked)
{
if (!OffValue.isEmpty())
m_pBox->SetText(Name, OffValue);
Status = m_pBox->SetText(Name, OffValue);
else
m_pBox->DelValue(Name);
Status = m_pBox->DelValue(Name);
}
if (!Status)
throw Status;
}
void COptionsWindow::WriteText(const QString& Name, const QString& Value)
{
SB_STATUS Status = m_pBox->SetText(Name, Value);
if (!Status)
throw Status;
}
void COptionsWindow::WriteTextList(const QString& Setting, const QStringList& List)
{
SB_STATUS Status = m_pBox->UpdateTextList(Setting, List, m_Template);
if (!Status)
throw Status;
}
void COptionsWindow::SaveConfig()
{
try
{
if (m_GeneralChanged)
{
m_pBox->SetText("BoxNameTitle", ui.cmbBoxIndicator->currentData().toString());
WriteText("BoxNameTitle", ui.cmbBoxIndicator->currentData().toString());
QStringList BorderCfg;
BorderCfg.append(QString("#%1%2%3").arg(m_BorderColor.blue(), 2, 16, QChar('0')).arg(m_BorderColor.green(), 2, 16, QChar('0')).arg(m_BorderColor.red(), 2, 16, QChar('0')));
BorderCfg.append(ui.cmbBoxBorder->currentData().toString());
BorderCfg.append(QString::number(ui.spinBorderWidth->value()));
m_pBox->SetText("BorderColor", BorderCfg.join(","));
WriteText("BorderColor", BorderCfg.join(","));
WriteAdvancedCheck(ui.chkBlockNetShare, "BlockNetworkFiles", "", "n");
WriteAdvancedCheck(ui.chkBlockNetParam, "BlockNetParam", "", "n");
@ -664,18 +655,18 @@ void COptionsWindow::SaveConfig()
else
StartProgram.append(pItem->text(1));
}
m_pBox->UpdateTextList("StartProgram", StartProgram, m_Template);
m_pBox->UpdateTextList("StartService", StartService, m_Template);
WriteTextList("StartProgram", StartProgram);
WriteTextList("StartService", StartService);
QStringList RunCommands;
for (int i = 0; i < ui.treeRun->topLevelItemCount(); i++) {
QTreeWidgetItem* pItem = ui.treeRun->topLevelItem(i);
RunCommands.append(pItem->text(0) + "|" + pItem->text(1));
}
m_pBox->UpdateTextList("RunCommand", RunCommands, m_Template);
WriteTextList("RunCommand", RunCommands);
m_pBox->SetNum("CopyLimitKb", ui.chkCopyLimit->isChecked() ? ui.txtCopyLimit->text().toInt() : -1);
WriteText("CopyLimitKb", ui.chkCopyLimit->isChecked() ? ui.txtCopyLimit->text() : "-1");
WriteAdvancedCheck(ui.chkCopyPrompt, "PromptForFileMigration", "", "n");
WriteAdvancedCheck(ui.chkNoCopyWarn, "CopyLimitSilent", "", "y");
@ -724,20 +715,20 @@ void COptionsWindow::SaveConfig()
WriteAdvancedCheck(ui.chkUseSbieWndStation, "UseSbieWndStation", "y", "");
WriteAdvancedCheck(ui.chkProtectSCM, "UnrestrictedSCM", "", "y");
WriteAdvancedCheck(ui.chkNestedJobs, "AllowBoxedJobs", "y", "");
WriteAdvancedCheck(ui.chkRestrictServices, "RunServicesAsSystem", "", "y");
WriteAdvancedCheck(ui.chkProtectSystem, "ExposeBoxedSystem", "", "y");
//WriteAdvancedCheck(ui.chkProtectSystem, "ExposeBoxedSystem", "", "y");
WriteAdvancedCheck(ui.chkOpenDevCMApi, "OpenDevCMApi", "y", "");
WriteAdvancedCheck(ui.chkOpenLsaSSPI, "BlockPassword", "n", ""); // OpenLsaSSPI
//WriteAdvancedCheck(ui.chkOpenLsaSSPI, "BlockPassword", "n", ""); // OpenLsaSSPI
WriteAdvancedCheck(ui.chkOpenSamEndpoint, "OpenSamEndpoint", "y", "");
WriteAdvancedCheck(ui.chkOpenLsaEndpoint, "OpenLsaEndpoint", "y", "");
WriteAdvancedCheck(ui.chkAddToJob, "NoAddProcessToJob", "", "y");
QStringList AutoExec;
for (int i = 0; i < ui.lstAutoExec->count(); i++)
AutoExec.append(ui.lstAutoExec->item(i)->text());
m_pBox->UpdateTextList("AutoExec", AutoExec, m_Template);
WriteTextList("AutoExec", AutoExec);
bool bGlobalNoMon = m_pBox->GetAPI()->GetGlobalSettings()->GetBool("DisableResourceMonitor", false);
WriteAdvancedCheck(ui.chkDisableMonitor, "DisableResourceMonitor", bGlobalNoMon ? "" : "y", bGlobalNoMon ? "n" : "");
@ -759,12 +750,12 @@ void COptionsWindow::SaveConfig()
QStringList Processes;
for (int i = 0; i < ui.lstProcesses->count(); i++)
Processes.append(ui.lstProcesses->item(i)->text());
m_pBox->UpdateTextList("HideHostProcess", Processes, m_Template);
WriteTextList("HideHostProcess", Processes);
QStringList Users;
for (int i = 0; i < ui.lstUsers->count(); i++)
Users.append(ui.lstUsers->item(i)->text());
m_pBox->SetText("Enabled", Users.count() > 0 ? "y," + Users.join(",") : "y");
WriteText("Enabled", Users.count() > 0 ? "y," + Users.join(",") : "y");
WriteAdvancedCheck(ui.chkMonitorAdminOnly, "MonitorAdminOnly");
m_AdvancedChanged = false;
@ -785,6 +776,11 @@ void COptionsWindow::SaveConfig()
if (m_FoldersChanged)
SaveFolders();
}
catch (SB_STATUS Status)
{
theGUI->CheckResults(QList<SB_STATUS>() << Status);
}
}
void COptionsWindow::apply()
{
@ -1009,6 +1005,8 @@ void COptionsWindow::LoadGroups()
pItem->setText(0, GroupName);
for (int i = 0; i < Entries.count(); i++)
{
if (Entries[i].isEmpty())
continue;
QTreeWidgetItem* pSubItem = new QTreeWidgetItem();
SetProgramItem(Entries[i], pSubItem, 0);
pItem->addChild(pSubItem);
@ -1036,7 +1034,7 @@ void COptionsWindow::SaveGroups()
ProcessGroups.append(Group);
}
m_pBox->UpdateTextList("ProcessGroup", ProcessGroups, m_Template);
WriteTextList("ProcessGroup", ProcessGroups);
m_GroupsChanged = false;
}
@ -1129,7 +1127,6 @@ void COptionsWindow::OnDelProg()
void COptionsWindow::CopyGroupToList(const QString& Groupe, QTreeWidget* pTree)
{
pTree->clear();
for (int i = 0; i < ui.treeGroups->topLevelItemCount(); i++)
{
QTreeWidgetItem* pItem = ui.treeGroups->topLevelItem(i);
@ -1217,8 +1214,8 @@ void COptionsWindow::SaveForced()
}
}
m_pBox->UpdateTextList("ForceProcess", ForceProcess, m_Template);
m_pBox->UpdateTextList("ForceFolder", ForceFolder, m_Template);
WriteTextList("ForceProcess", ForceProcess);
WriteTextList("ForceFolder", ForceFolder);
m_ForcedChanged = false;
}
@ -1316,8 +1313,8 @@ void COptionsWindow::SaveStop()
}
}
m_pBox->UpdateTextList("LingerProcess", LingerProcess, m_Template);
m_pBox->UpdateTextList("LeaderProcess", LeaderProcess, m_Template);
WriteTextList("LingerProcess", LingerProcess);
WriteTextList("LeaderProcess", LeaderProcess);
m_StopChanged = false;
}
@ -1743,13 +1740,13 @@ QString COptionsWindow::MakeAccessStr(EAccessType Type, EAccessMode Mode)
return "Unknown";
}
void COptionsWindow::OnAccessItemClicked(QTreeWidgetItem* pItem, int Column)
/*void COptionsWindow::OnAccessItemClicked(QTreeWidgetItem* pItem, int Column)
{
if (Column != 0)
return;
CloseAccessEdit(pItem);
}
}*/
void COptionsWindow::CloseAccessEdit(bool bSave)
{
@ -1782,7 +1779,7 @@ void COptionsWindow::CloseAccessEdit(QTreeWidgetItem* pItem, bool bSave)
if (bSave)
{
if (pItem->data(0, Qt::UserRole).toInt() == eCOM)
if (pItem->data(0, Qt::UserRole).toInt() == eCOM && !pPath->text().isEmpty())
{
bool isGUID = pPath->text().length() == 38 && pPath->text().left(1) == "{" && pPath->text().right(1) == "}";
switch (pMode->currentData().toInt())
@ -1809,13 +1806,13 @@ void COptionsWindow::CloseAccessEdit(QTreeWidgetItem* pItem, bool bSave)
pItem->setData(2, Qt::UserRole, pMode->currentData());
pItem->setText(3, pPath->text());
pItem->setData(3, Qt::UserRole, pPath->text());
m_AccessChanged = true;
}
ui.treeAccess->setItemWidget(pItem, 1, NULL);
ui.treeAccess->setItemWidget(pItem, 2, NULL);
ui.treeAccess->setItemWidget(pItem, 3, NULL);
m_AccessChanged = true;
}
QList<COptionsWindow::EAccessMode> COptionsWindow::GetAccessModes(EAccessType Type)
@ -1937,7 +1934,7 @@ void COptionsWindow::SaveAccessList()
}
foreach(const QString& Key, Keys)
m_pBox->UpdateTextList(Key, AccessMap[Key], m_Template);
WriteTextList(Key, AccessMap[Key]);
m_AccessChanged = false;
}
@ -2014,8 +2011,8 @@ void COptionsWindow::SaveRecoveryList()
}
}
m_pBox->UpdateTextList("RecoverFolder", RecoverFolder, m_Template);
m_pBox->UpdateTextList("AutoRecoverIgnore", AutoRecoverIgnore, m_Template);
WriteTextList("RecoverFolder", RecoverFolder);
WriteTextList("AutoRecoverIgnore", AutoRecoverIgnore);
WriteAdvancedCheck(ui.chkAutoRecovery, "AutoRecover", "y", "");
@ -2411,7 +2408,7 @@ void COptionsWindow::OnDelTemplates()
void COptionsWindow::SaveTemplates()
{
m_pBox->UpdateTextList("Template", m_BoxTemplates, m_Template);
WriteTextList("Template", m_BoxTemplates);
m_TemplatesChanged = false;
}

View File

@ -60,7 +60,7 @@ private slots:
void OnAddINetProg();
void OnDelINetProg();
void OnAccessItemClicked(QTreeWidgetItem* pItem, int Column);
//void OnAccessItemClicked(QTreeWidgetItem* pItem, int Column);
void OnAccessItemDoubleClicked(QTreeWidgetItem* pItem, int Column);
void OnAccessSelectionChanged() { CloseAccessEdit(); }
@ -264,6 +264,8 @@ private:
void ReadAdvancedCheck(const QString& Name, QCheckBox* pCheck, const QString& Value = "y");
void WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name, const QString& Value = "y");
void WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name, const QString& OnValue, const QString& OffValue);
void WriteText(const QString& Name, const QString& Value);
void WriteTextList(const QString& Setting, const QStringList& List);
Ui::OptionsWindow ui;

View File

@ -39,14 +39,18 @@ CPopUpWindow::CPopUpWindow(QWidget* parent) : QMainWindow(parent)
m_pActionCopy->setShortcutContext(Qt::WidgetWithChildrenShortcut);
this->addAction(m_pActionCopy);
// set always on top
SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
m_iTopMost = 0;
SetWindowPos((HWND)this->winId(), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
m_uTimerID = startTimer(1000);
m_ResetPosition = !restoreGeometry(theConf->GetBlob("PopUpWindow/Window_Geometry"));
}
CPopUpWindow::~CPopUpWindow()
{
killTimer(m_uTimerID);
theConf->SetBlob("PopUpWindow/Window_Geometry", saveGeometry());
}
@ -79,6 +83,8 @@ void CPopUpWindow::RemoveEntry(CPopUpEntry* pEntry)
void CPopUpWindow::Show()
{
Poke();
QScreen *screen = this->windowHandle()->screen();
QRect scrRect = screen->availableGeometry();
@ -100,6 +106,14 @@ void CPopUpWindow::Show()
this->show();
}
void CPopUpWindow::Poke()
{
if (!this->isVisible() || m_iTopMost <= -5) {
SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
m_iTopMost = 5;
}
}
void CPopUpWindow::closeEvent(QCloseEvent *e)
{
for (int i = 0; i < ui.table->rowCount(); i++)
@ -117,6 +131,16 @@ void CPopUpWindow::closeEvent(QCloseEvent *e)
this->hide();
}
void CPopUpWindow::timerEvent(QTimerEvent* pEvent)
{
if (pEvent->timerId() != m_uTimerID)
return;
if (m_iTopMost > -5 && (--m_iTopMost == 0)) {
SetWindowPos((HWND)this->winId(), HWND_NOTOPMOST , 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
}
void CPopUpWindow::AddLogMessage(const QString& Message, quint32 MsgCode, const QStringList& MsgData, quint32 ProcessId)
{
if (IsMessageHidden(MsgCode, MsgData))

View File

@ -428,6 +428,7 @@ signals:
public slots:
virtual void Show();
virtual void Poke();
virtual void ReloadHiddenMessages();
private slots:
@ -447,6 +448,8 @@ private slots:
protected:
virtual void closeEvent(QCloseEvent *e);
void timerEvent(QTimerEvent* pEvent);
virtual void AddEntry(CPopUpEntry* pEntry);
virtual void RemoveEntry(CPopUpEntry* pEntry);
@ -459,5 +462,7 @@ protected:
private:
bool m_ResetPosition;
QAction* m_pActionCopy;
int m_uTimerID;
int m_iTopMost;
Ui::PopUpWindow ui;
};

View File

@ -94,6 +94,7 @@ CRecoveryWindow::~CRecoveryWindow()
int CRecoveryWindow::exec()
{
//QDialog::setWindowModality(Qt::WindowModal);
ui.btnDeleteAll->setVisible(true);
return QDialog::exec();
}

View File

@ -0,0 +1,112 @@
#include "stdafx.h"
#include "SelectBoxWindow.h"
#include "SandMan.h"
#include "../MiscHelpers/Common/Settings.h"
#include "../SbiePlusAPI.h"
#if defined(Q_OS_WIN)
#include <wtypes.h>
#include <QAbstractNativeEventFilter>
#include <dbt.h>
#endif
CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, QWidget *parent)
: QDialog(parent)
{
m_Commands = Commands;
Qt::WindowFlags flags = windowFlags();
flags |= Qt::CustomizeWindowHint;
//flags &= ~Qt::WindowContextHelpButtonHint;
//flags &= ~Qt::WindowSystemMenuHint;
//flags &= ~Qt::WindowMinMaxButtonsHint;
//flags |= Qt::WindowMinimizeButtonHint;
//flags &= ~Qt::WindowCloseButtonHint;
flags &= ~Qt::WindowContextHelpButtonHint;
//flags &= ~Qt::WindowSystemMenuHint;
setWindowFlags(flags);
//setWindowState(Qt::WindowActive);
SetForegroundWindow((HWND)QWidget::winId());
ui.setupUi(this);
this->setWindowTitle(tr("Sandboxie-Plus - Run Sandboxed"));
connect(ui.radBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
connect(ui.radUnBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
connect(ui.buttonBox, SIGNAL(accepted()), SLOT(OnRun()));
connect(ui.buttonBox, SIGNAL(rejected()), SLOT(reject()));
QMap<QString, CSandBoxPtr> Boxes = theAPI->GetAllBoxes();
foreach(const CSandBoxPtr & pBox, Boxes)
{
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(pBox.data());
QTreeWidgetItem* pItem = new QTreeWidgetItem();
pItem->setText(0, pBox->GetName().replace("_", " "));
pItem->setData(0, Qt::UserRole, pBox->GetName());
pItem->setData(0, Qt::DecorationRole, theGUI->GetBoxIcon(pBox->GetActiveProcessCount(), pBoxEx->GetType()));
ui.treeBoxes->addTopLevelItem(pItem);
if (pBox->GetName().toLower() == "defaultbox")
ui.treeBoxes->setCurrentItem(pItem);
}
//restoreGeometry(theConf->GetBlob("SelectBoxWindow/Window_Geometry"));
}
CSelectBoxWindow::~CSelectBoxWindow()
{
//theConf->SetBlob("SelectBoxWindow/Window_Geometry", saveGeometry());
}
void CSelectBoxWindow::closeEvent(QCloseEvent *e)
{
//emit Closed();
this->deleteLater();
}
void CSelectBoxWindow::OnBoxType()
{
ui.treeBoxes->setEnabled(!ui.radUnBoxed->isChecked());
}
void CSelectBoxWindow::OnRun()
{
QTreeWidgetItem* pItem = ui.treeBoxes->currentItem();
QString BoxName;
if (ui.radUnBoxed->isChecked())
{
if (QMessageBox("Sandboxie-Plus", tr("Are you shure you want to run the program outside the sandbox?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
return;
pItem = NULL;
}
else if (pItem == NULL) {
QMessageBox("Sandboxie-Plus", tr("Please select a sandbox."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this).exec();
return;
}
else {
BoxName = pItem->data(0, Qt::UserRole).toString();
}
//QList<SB_STATUS> Results;
foreach(const QString & Command, m_Commands)
{
QString StartCmd = "\"" + theAPI->GetStartPath() + "\"" + (ui.chkAdmin->isChecked() ? " /elevated" : "");
if (!BoxName.isEmpty())
StartCmd += " /box:" + BoxName + " ";
else
StartCmd += " /disable_force ";
StartCmd += Command;
QProcess::startDetached(StartCmd);
}
//CSandMan::CheckResults(Results);
close();
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_SelectBoxWindow.h"
#include "SbiePlusAPI.h"
class CSelectBoxWindow : public QDialog
{
Q_OBJECT
public:
CSelectBoxWindow(const QStringList& Commands, QWidget *parent = Q_NULLPTR);
~CSelectBoxWindow();
private slots:
void OnBoxType();
void OnRun();
protected:
void closeEvent(QCloseEvent* e);
QStringList m_Commands;
private:
Ui::SelectBoxWindow ui;
};

View File

@ -7,6 +7,35 @@
#include "../QSbieAPI/SbieUtils.h"
QSize CustomTabStyle::sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const {
QSize s = QProxyStyle::sizeFromContents(type, option, size, widget);
if (type == QStyle::CT_TabBarTab) {
s.transpose();
if(theGUI->m_DarkTheme)
s.setHeight(s.height() * 13 / 10);
else
s.setHeight(s.height() * 15 / 10);
s.setWidth(s.width() * 11 / 10); // for the the icon
}
return s;
}
void CustomTabStyle::drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
if (element == CE_TabBarTabLabel) {
if (const QStyleOptionTab* tab = qstyleoption_cast<const QStyleOptionTab*>(option)) {
QStyleOptionTab opt(*tab);
opt.shape = QTabBar::RoundedNorth;
//opt.iconSize = QSize(32, 32);
opt.iconSize = QSize(24, 24);
QProxyStyle::drawControl(element, &opt, painter, widget);
return;
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
int CSettingsWindow__Chk2Int(Qt::CheckState state)
{
switch (state) {
@ -45,6 +74,17 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
/*ui.tabs->setTabPosition(QTabWidget::West);
ui.tabs->tabBar()->setStyle(new CustomTabStyle(ui.tabs->tabBar()->style()));*/
ui.tabs->setTabIcon(0, CSandMan::GetIcon("Options"));
ui.tabs->setTabIcon(1, CSandMan::GetIcon("Maintenance"));
ui.tabs->setTabIcon(2, CSandMan::GetIcon("Wall"));
ui.tabs->setTabIcon(3, CSandMan::GetIcon("Advanced"));
ui.tabs->setTabIcon(4, CSandMan::GetIcon("Support"));
ui.tabs->setCurrentIndex(0);
ui.uiLang->addItem(tr("Auto Detection"), "");
@ -57,12 +97,85 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
QString Lang = Locale.nativeLanguageName();
ui.uiLang->addItem(Lang, Code);
}
LoadSettings();
connect(ui.chkShowTray, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
//connect(ui.chkUseCycles, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
m_WarnProgsChanged = false;
connect(ui.chkPassRequired, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
connect(ui.btnSetPassword, SIGNAL(clicked(bool)), this, SLOT(OnSetPassword()));
connect(ui.chkStartBlock, SIGNAL(stateChanged(int)), this, SLOT(OnWarnChanged()));
connect(ui.chkStartBlockMsg, SIGNAL(stateChanged(int)), this, SLOT(OnWarnChanged()));
connect(ui.btnAddWarnProg, SIGNAL(clicked(bool)), this, SLOT(OnAddWarnProg()));
connect(ui.btnAddWarnFolder, SIGNAL(clicked(bool)), this, SLOT(OnAddWarnFolder()));
connect(ui.btnDelWarnProg, SIGNAL(clicked(bool)), this, SLOT(OnDelWarnProg()));
connect(ui.btnBrowse, SIGNAL(clicked(bool)), this, SLOT(OnBrowse()));
connect(ui.chkAutoRoot, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
connect(ui.btnAddCompat, SIGNAL(clicked(bool)), this, SLOT(OnAddCompat()));
connect(ui.btnDelCompat, SIGNAL(clicked(bool)), this, SLOT(OnDelCompat()));
m_CompatLoaded = 0;
m_CompatChanged = false;
ui.chkNoCompat->setChecked(!theConf->GetBool("Options/AutoRunSoftCompat", true));
connect(ui.treeCompat, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateClicked(QTreeWidgetItem*, int)));
connect(ui.lblSupport, SIGNAL(linkActivated(const QString&)), this, SLOT(OnSupport(const QString&)));
connect(ui.tabs, SIGNAL(currentChanged(int)), this, SLOT(OnTab()));
connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked(bool)), this, SLOT(ok()));
connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked(bool)), this, SLOT(apply()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
restoreGeometry(theConf->GetBlob("SettingsWindow/Window_Geometry"));
}
CSettingsWindow::~CSettingsWindow()
{
theConf->SetBlob("SettingsWindow/Window_Geometry",saveGeometry());
}
void CSettingsWindow::OnSupport(const QString& url)
{
QDesktopServices::openUrl(url);
}
void CSettingsWindow::showCompat()
{
m_CompatLoaded = 2;
ui.tabs->setCurrentWidget(ui.tabCompat);
show();
}
void CSettingsWindow::closeEvent(QCloseEvent *e)
{
emit Closed();
this->deleteLater();
}
void CSettingsWindow::LoadSettings()
{
ui.uiLang->setCurrentIndex(ui.uiLang->findData(theConf->GetString("Options/UiLanguage")));
ui.chkAutoStart->setChecked(IsAutorunEnabled());
ui.chkSvcStart->setChecked(theAPI->GetUserSettings()->GetBool("SbieCtrl_EnableAutoStart", true));
ui.chkAutoUpdate->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForUpdates", 2)));
if (theAPI->GetUserSettings()->GetBool("SbieCtrl_EnableAutoStart", true)) {
if (theAPI->GetUserSettings()->GetText("SbieCtrl_AutoStartAgent", "") != "SandMan.exe")
ui.chkSvcStart->setChecked(true);
else
ui.chkSvcStart->setCheckState(Qt::PartiallyChecked);
} else
ui.chkSvcStart->setChecked(false);
ui.chkShellMenu->setCheckState((Qt::CheckState)CSbieUtils::IsContextMenu());
@ -74,6 +187,9 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
ui.chkShowRecovery->setChecked(theConf->GetBool("Options/ShowRecovery", false));
ui.chkPanic->setChecked(theConf->GetBool("Options/EnablePanicKey", false));
ui.keyPanic->setKeySequence(QKeySequence(theConf->GetString("Options/PanicKeySequence", "Ctrl+Cancel")));
ui.chkWatchConfig->setChecked(theConf->GetBool("Options/WatchIni", true));
ui.onClose->addItem(tr("Close to Tray"), "ToTray");
@ -83,8 +199,6 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
ui.chkShowTray->setChecked(theConf->GetBool("Options/ShowSysTray", true));
connect(ui.chkShowTray, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
//connect(ui.chkUseCycles, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
if (theAPI->IsConnected())
{
@ -100,18 +214,11 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
ui.chkAdminOnly->setChecked(theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false));
ui.chkPassRequired->setChecked(!theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty());
connect(ui.chkPassRequired, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
connect(ui.btnSetPassword, SIGNAL(clicked(bool)), this, SLOT(OnSetPassword()));
ui.chkAdminOnlyFP->setChecked(theAPI->GetGlobalSettings()->GetBool("ForceDisableAdminOnly", false));
ui.chkClearPass->setChecked(theAPI->GetGlobalSettings()->GetBool("ForgetPassword", false));
ui.chkStartBlock->setChecked(theAPI->GetGlobalSettings()->GetBool("StartRunAlertDenied", false));
connect(ui.chkStartBlock, SIGNAL(stateChanged(int)), this, SLOT(OnWarnChanged()));
ui.chkStartBlockMsg->setChecked(theAPI->GetGlobalSettings()->GetBool("NotifyStartRunAccessDenied", true));
connect(ui.chkStartBlockMsg, SIGNAL(stateChanged(int)), this, SLOT(OnWarnChanged()));
connect(ui.btnAddWarnProg, SIGNAL(clicked(bool)), this, SLOT(OnAddWarnProg()));
connect(ui.btnAddWarnFolder, SIGNAL(clicked(bool)), this, SLOT(OnAddWarnFolder()));
connect(ui.btnDelWarnProg, SIGNAL(clicked(bool)), this, SLOT(OnDelWarnProg()));
foreach(const QString& Value, theAPI->GetGlobalSettings()->GetTextList("AlertProcess", false))
AddWarnEntry(Value, 1);
@ -137,72 +244,41 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
ui.btnAddCompat->setEnabled(false);
ui.btnDelCompat->setEnabled(false);
}
m_WarnProgsChanged = false;
connect(ui.btnBrowse, SIGNAL(clicked(bool)), this, SLOT(OnBrowse()));
int PortableRootDir = theConf->GetInt("Options/PortableRootDir", -1);
if (PortableRootDir != -1 && theConf->IsPortable())
ui.chkAutoRoot->setChecked(PortableRootDir == 0 ? Qt::Unchecked : Qt::Checked);
else
ui.chkAutoRoot->setVisible(false);
connect(ui.chkAutoRoot, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
connect(ui.btnAddCompat, SIGNAL(clicked(bool)), this, SLOT(OnAddCompat()));
connect(ui.btnDelCompat, SIGNAL(clicked(bool)), this, SLOT(OnDelCompat()));
m_CompatLoaded = 0;
m_CompatChanged = false;
ui.chkNoCompat->setChecked(!theConf->GetBool("Options/AutoRunSoftCompat", true));
connect(ui.treeCompat, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateClicked(QTreeWidgetItem*, int)));
connect(ui.tabs, SIGNAL(currentChanged(int)), this, SLOT(OnTab()));
connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked(bool)), this, SLOT(ok()));
connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked(bool)), this, SLOT(apply()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
restoreGeometry(theConf->GetBlob("SettingsWindow/Window_Geometry"));
ui.chkAutoUpdate->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForUpdates", 2)));
ui.chkAutoInstall->setVisible(false); // todo implement smart auto updater
OnChange();
}
CSettingsWindow::~CSettingsWindow()
{
theConf->SetBlob("SettingsWindow/Window_Geometry",saveGeometry());
}
void CSettingsWindow::showCompat()
{
m_CompatLoaded = 2;
ui.tabs->setCurrentWidget(ui.tabCompat);
show();
}
void CSettingsWindow::closeEvent(QCloseEvent *e)
{
emit Closed();
this->deleteLater();
}
void CSettingsWindow::apply()
void CSettingsWindow::SaveSettings()
{
theConf->SetValue("Options/UiLanguage", ui.uiLang->currentData());
theConf->SetValue("Options/UseDarkTheme", CSettingsWindow__Chk2Int(ui.chkDarkTheme->checkState()));
AutorunEnable(ui.chkAutoStart->isChecked());
theAPI->GetUserSettings()->SetBool("SbieCtrl_EnableAutoStart", ui.chkSvcStart->isChecked());
theConf->SetValue("Options/CheckForUpdates", CSettingsWindow__Chk2Int(ui.chkAutoUpdate->checkState()));
if (ui.chkSvcStart->checkState() == Qt::Checked) {
theAPI->GetUserSettings()->SetBool("SbieCtrl_EnableAutoStart", true);
theAPI->GetUserSettings()->SetText("SbieCtrl_AutoStartAgent", "SandMan.exe");
} else if (ui.chkSvcStart->checkState() == Qt::Unchecked)
theAPI->GetUserSettings()->SetBool("SbieCtrl_EnableAutoStart", false);
if (ui.chkShellMenu->checkState() != CSbieUtils::IsContextMenu())
{
if (ui.chkShellMenu->isChecked())
CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
else
if (ui.chkShellMenu->isChecked()) {
CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe",
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
} else
CSbieUtils::RemoveContextMenu();
}
@ -212,6 +288,9 @@ void CSettingsWindow::apply()
theConf->SetValue("Options/ShowRecovery", ui.chkShowRecovery->isChecked());
theConf->SetValue("Options/EnablePanicKey", ui.chkPanic->isChecked());
theConf->SetValue("Options/PanicKeySequence", ui.keyPanic->keySequence().toString());
theConf->SetValue("Options/WatchIni", ui.chkWatchConfig->isChecked());
theConf->SetValue("Options/OnClose", ui.onClose->currentData());
@ -305,9 +384,15 @@ void CSettingsWindow::apply()
emit OptionsChanged();
}
void CSettingsWindow::apply()
{
SaveSettings();
LoadSettings();
}
void CSettingsWindow::ok()
{
apply();
SaveSettings();
this->close();
}

View File

@ -2,6 +2,16 @@
#include <QtWidgets/QMainWindow>
#include "ui_SettingsWindow.h"
#include <QProxyStyle>
class CustomTabStyle : public QProxyStyle {
public:
CustomTabStyle(QStyle* style = 0) : QProxyStyle(style) {}
QSize sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const;
void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const;
};
class CSettingsWindow : public QDialog
{
@ -42,11 +52,16 @@ private slots:
void OnAddCompat();
void OnDelCompat();
void OnSupport(const QString& url);
protected:
void closeEvent(QCloseEvent *e);
void AddWarnEntry(const QString& Name, int type);
void LoadSettings();
void SaveSettings();
int m_CompatLoaded;
QString m_NewPassword;
bool m_WarnProgsChanged;

Some files were not shown because too many files have changed in this diff Show More