1.10.3
This commit is contained in:
parent
1d2509faeb
commit
e945290867
|
@ -6,10 +6,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
## [1.10.3 / 5.65.3] - 2023-08-??
|
## [1.10.3 / 5.65.3] - 2023-08-??
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- added display of URL shortcut files in Run Menu [#3151](https://github.com/sandboxie-plus/Sandboxie/issues/3151)
|
- added support for URL shortcut files in Run Menu [#3151](https://github.com/sandboxie-plus/Sandboxie/issues/3151)
|
||||||
|
- added workaround for NtQueryObject locking up in egsotic scenarios, to enable it use 'UseDriverObjLookup=y'
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- improved business certificate handling
|
- improved business certificate handling, added usage count and machine bount options
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- fixed issues with pinned shortcuts
|
- fixed issues with pinned shortcuts
|
||||||
|
|
|
@ -56,6 +56,8 @@ static P_NtQueryObject __sys_NtQueryObject = NULL;
|
||||||
P_NtQueryVirtualMemory __sys_NtQueryVirtualMemory = NULL;
|
P_NtQueryVirtualMemory __sys_NtQueryVirtualMemory = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
BOOLEAN obj_use_driver_obj_lookup = FALSE;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Obj_Init
|
// Obj_Init
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -72,6 +74,9 @@ _FX BOOLEAN Obj_Init(void)
|
||||||
SBIEDLL_HOOK(Obj_,NtQueryVirtualMemory);
|
SBIEDLL_HOOK(Obj_,NtQueryVirtualMemory);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!Dll_CompartmentMode) // NoDriverAssist
|
||||||
|
obj_use_driver_obj_lookup = SbieApi_QueryConfBool(NULL, L"UseDriverObjLookup", FALSE);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,14 +89,17 @@ _FX BOOLEAN Obj_Init(void)
|
||||||
_FX ULONG Obj_GetObjectType(HANDLE ObjectHandle)
|
_FX ULONG Obj_GetObjectType(HANDLE ObjectHandle)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
union {
|
||||||
PUBLIC_OBJECT_TYPE_INFORMATION info;
|
PUBLIC_OBJECT_TYPE_INFORMATION info;
|
||||||
|
wchar_t Buffer[256];
|
||||||
|
} u;
|
||||||
|
|
||||||
ULONG length = sizeof(info);
|
ULONG length = sizeof(u.Buffer);
|
||||||
|
|
||||||
status = __sys_NtQueryObject(ObjectHandle, ObjectTypeInformation, &info, length, &length);
|
status = __sys_NtQueryObject(ObjectHandle, ObjectTypeInformation, &u.info, length, &length);
|
||||||
|
|
||||||
if (NT_SUCCESS(status)) {
|
if(NT_SUCCESS(status)) {
|
||||||
const WCHAR *TypeName = info.TypeName.Buffer;
|
const WCHAR* TypeName = u.info.TypeName.Buffer;
|
||||||
if (TypeName[0] == L'D' && _wcsicmp(TypeName, L"Directory") == 0)
|
if (TypeName[0] == L'D' && _wcsicmp(TypeName, L"Directory") == 0)
|
||||||
return OBJ_TYPE_DIRECTORY;
|
return OBJ_TYPE_DIRECTORY;
|
||||||
if (TypeName[0] == L'F' && _wcsicmp(TypeName, L"File") == 0)
|
if (TypeName[0] == L'F' && _wcsicmp(TypeName, L"File") == 0)
|
||||||
|
@ -125,15 +133,41 @@ _FX ULONG Obj_GetObjectType(HANDLE ObjectHandle)
|
||||||
_FX NTSTATUS Obj_GetObjectName(
|
_FX NTSTATUS Obj_GetObjectName(
|
||||||
HANDLE ObjectHandle, void *ObjectName, ULONG *Length)
|
HANDLE ObjectHandle, void *ObjectName, ULONG *Length)
|
||||||
{
|
{
|
||||||
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
|
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// NtQueryObject is known for locking up forever when queried for object name on a pipe handle
|
||||||
|
// opened for synchronous io, and where there are pending read operations.
|
||||||
|
//
|
||||||
|
// To remedy this we ask the driver to lookup the objects name instead
|
||||||
|
//
|
||||||
|
|
||||||
|
if (obj_use_driver_obj_lookup) {
|
||||||
|
|
||||||
|
OBJECT_NAME_INFORMATION* info = (OBJECT_NAME_INFORMATION*)ObjectName;
|
||||||
|
|
||||||
|
wchar_t* NameBuf = (UCHAR*)ObjectName + sizeof(OBJECT_NAME_INFORMATION);
|
||||||
|
ULONG NameLen = *Length - sizeof(OBJECT_NAME_INFORMATION);
|
||||||
|
|
||||||
|
status = SbieApi_GetFileName(ObjectHandle, NameBuf, &NameLen, NULL);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status)) {
|
||||||
|
info->Name.Buffer = NameBuf;
|
||||||
|
info->Name.Length = wcslen(NameBuf) * sizeof(wchar_t);
|
||||||
|
info->Name.MaximumLength = (USHORT)NameLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
THREAD_DATA* TlsData = Dll_GetTlsData(NULL);
|
||||||
|
|
||||||
TlsData->obj_NtQueryObject_lock = TRUE;
|
TlsData->obj_NtQueryObject_lock = TRUE;
|
||||||
|
|
||||||
status = __sys_NtQueryObject(
|
status = __sys_NtQueryObject(
|
||||||
ObjectHandle, ObjectNameInformation, ObjectName, *Length, Length);
|
ObjectHandle, ObjectNameInformation, ObjectName, *Length, Length);
|
||||||
|
|
||||||
TlsData->obj_NtQueryObject_lock = FALSE;
|
TlsData->obj_NtQueryObject_lock = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "common/my_version.h"
|
#include "common/my_version.h"
|
||||||
#include "log_buff.h"
|
#include "log_buff.h"
|
||||||
|
#define KERNEL_MODE
|
||||||
#include "verify.h"
|
#include "verify.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1354,6 +1355,16 @@ _FX NTSTATUS Api_QueryDriverInfo(PROCESS* proc, ULONG64* parms)
|
||||||
else
|
else
|
||||||
status = STATUS_BUFFER_TOO_SMALL;
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
else if (args->info_class.val == -2) {
|
||||||
|
|
||||||
|
if (args->info_len.val >= 37 * sizeof(wchar_t)) {
|
||||||
|
wchar_t* hwid = args->info_data.val;
|
||||||
|
extern wchar_t g_uuid_str[40];
|
||||||
|
wmemcpy(hwid, g_uuid_str, 37);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
status = STATUS_INVALID_INFO_CLASS;
|
status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
|
||||||
|
|
|
@ -379,8 +379,14 @@ _FX BOOLEAN MyIsCallerSigned(void)
|
||||||
|
|
||||||
NTSTATUS KphValidateCertificate();
|
NTSTATUS KphValidateCertificate();
|
||||||
|
|
||||||
|
extern wchar_t g_uuid_str[40];
|
||||||
|
void InitFwUuid();
|
||||||
|
|
||||||
_FX NTSTATUS MyValidateCertificate(void)
|
_FX NTSTATUS MyValidateCertificate(void)
|
||||||
{
|
{
|
||||||
|
if(!*g_uuid_str)
|
||||||
|
InitFwUuid();
|
||||||
|
|
||||||
NTSTATUS status = KphValidateCertificate();
|
NTSTATUS status = KphValidateCertificate();
|
||||||
|
|
||||||
if (status == STATUS_ACCOUNT_EXPIRED)
|
if (status == STATUS_ACCOUNT_EXPIRED)
|
||||||
|
|
|
@ -508,6 +508,7 @@ _FX NTSTATUS KphValidateCertificate()
|
||||||
|
|
||||||
WCHAR* type = NULL;
|
WCHAR* type = NULL;
|
||||||
WCHAR* level = NULL;
|
WCHAR* level = NULL;
|
||||||
|
LONG amount = 1;
|
||||||
//WCHAR* key = NULL;
|
//WCHAR* key = NULL;
|
||||||
LARGE_INTEGER cert_date = { 0 };
|
LARGE_INTEGER cert_date = { 0 };
|
||||||
|
|
||||||
|
@ -516,8 +517,12 @@ _FX NTSTATUS KphValidateCertificate()
|
||||||
if(!NT_SUCCESS(status = MyInitHash(&hashObj)))
|
if(!NT_SUCCESS(status = MyInitHash(&hashObj)))
|
||||||
goto CleanupExit;
|
goto CleanupExit;
|
||||||
|
|
||||||
|
//
|
||||||
|
// read (Home Path)\Certificate.dat
|
||||||
|
//
|
||||||
|
|
||||||
path_len = wcslen(Driver_HomePathDos) * sizeof(WCHAR);
|
path_len = wcslen(Driver_HomePathDos) * sizeof(WCHAR);
|
||||||
path_len += 64; // room for \Certificate.ini
|
path_len += 64; // room for \Certificate.dat
|
||||||
path = Mem_Alloc(Driver_Pool, path_len);
|
path = Mem_Alloc(Driver_Pool, path_len);
|
||||||
line = Mem_Alloc(Driver_Pool, line_size);
|
line = Mem_Alloc(Driver_Pool, line_size);
|
||||||
temp = Mem_Alloc(Driver_Pool, line_size);
|
temp = Mem_Alloc(Driver_Pool, line_size);
|
||||||
|
@ -526,10 +531,6 @@ _FX NTSTATUS KphValidateCertificate()
|
||||||
goto CleanupExit;
|
goto CleanupExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// read (Home Path)\Certificate.dat
|
|
||||||
//
|
|
||||||
|
|
||||||
RtlStringCbPrintfW(path, path_len, path_cert, Driver_HomePathDos);
|
RtlStringCbPrintfW(path, path_len, path_cert, Driver_HomePathDos);
|
||||||
|
|
||||||
status = Stream_Open(&stream, path, FILE_GENERIC_READ, 0, FILE_SHARE_READ, FILE_OPEN, 0);
|
status = Stream_Open(&stream, path, FILE_GENERIC_READ, 0, FILE_SHARE_READ, FILE_OPEN, 0);
|
||||||
|
@ -647,12 +648,22 @@ _FX NTSTATUS KphValidateCertificate()
|
||||||
//else if (_wcsicmp(L"UPDATEKEY", name) == 0 && key == NULL) {
|
//else if (_wcsicmp(L"UPDATEKEY", name) == 0 && key == NULL) {
|
||||||
// key = Mem_AllocString(Driver_Pool, value);
|
// key = Mem_AllocString(Driver_Pool, value);
|
||||||
//}
|
//}
|
||||||
|
else if (_wcsicmp(L"AMOUNT", name) == 0) {
|
||||||
|
amount = _wtol(value);
|
||||||
|
}
|
||||||
else if (_wcsicmp(L"SOFTWARE", name) == 0) { // if software is specified it must be the right one
|
else if (_wcsicmp(L"SOFTWARE", name) == 0) { // if software is specified it must be the right one
|
||||||
if (_wcsicmp(value, SOFTWARE_NAME) != 0) {
|
if (_wcsicmp(value, SOFTWARE_NAME) != 0) {
|
||||||
status = STATUS_OBJECT_TYPE_MISMATCH;
|
status = STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
goto CleanupExit;
|
goto CleanupExit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (_wcsicmp(L"HWID", name) == 0) { // if HwId is specified it must be the right one
|
||||||
|
extern wchar_t g_uuid_str[40];
|
||||||
|
if (_wcsicmp(value, g_uuid_str) != 0) {
|
||||||
|
status = STATUS_FIRMWARE_IMAGE_INVALID;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
status = Conf_Read_Line(stream, line, &line_num);
|
status = Conf_Read_Line(stream, line, &line_num);
|
||||||
|
@ -837,3 +848,154 @@ CleanupExit:
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// SMBIOS Structure header as described at
|
||||||
|
// see https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.3.0.pdf (para 6.1.2)
|
||||||
|
typedef struct _dmi_header
|
||||||
|
{
|
||||||
|
UCHAR type;
|
||||||
|
UCHAR length;
|
||||||
|
USHORT handle;
|
||||||
|
UCHAR data[1];
|
||||||
|
} dmi_header;
|
||||||
|
|
||||||
|
// Structure needed to get the SMBIOS table using GetSystemFirmwareTable API.
|
||||||
|
// see https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable
|
||||||
|
typedef struct _RawSMBIOSData {
|
||||||
|
UCHAR Used20CallingMethod;
|
||||||
|
UCHAR SMBIOSMajorVersion;
|
||||||
|
UCHAR SMBIOSMinorVersion;
|
||||||
|
UCHAR DmiRevision;
|
||||||
|
DWORD Length;
|
||||||
|
UCHAR SMBIOSTableData[1];
|
||||||
|
} RawSMBIOSData;
|
||||||
|
|
||||||
|
#define SystemFirmwareTableInformation 76
|
||||||
|
|
||||||
|
BOOLEAN GetFwUuid(unsigned char* uuid)
|
||||||
|
{
|
||||||
|
BOOLEAN result = FALSE;
|
||||||
|
|
||||||
|
SYSTEM_FIRMWARE_TABLE_INFORMATION sfti;
|
||||||
|
sfti.Action = SystemFirmwareTable_Get;
|
||||||
|
sfti.ProviderSignature = 'RSMB';
|
||||||
|
sfti.TableID = 0;
|
||||||
|
sfti.TableBufferLength = 0;
|
||||||
|
|
||||||
|
ULONG Length = sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION);
|
||||||
|
NTSTATUS status = ZwQuerySystemInformation(SystemFirmwareTableInformation, &sfti, Length, &Length);
|
||||||
|
if (status != STATUS_BUFFER_TOO_SMALL)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
ULONG BufferSize = sfti.TableBufferLength;
|
||||||
|
|
||||||
|
Length = BufferSize + sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION);
|
||||||
|
SYSTEM_FIRMWARE_TABLE_INFORMATION* pSfti = ExAllocatePoolWithTag(PagedPool, Length, 'vhpK');
|
||||||
|
if (!pSfti)
|
||||||
|
return result;
|
||||||
|
*pSfti = sfti;
|
||||||
|
pSfti->TableBufferLength = BufferSize;
|
||||||
|
|
||||||
|
status = ZwQuerySystemInformation(SystemFirmwareTableInformation, pSfti, Length, &Length);
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
RawSMBIOSData* smb = (RawSMBIOSData*)pSfti->TableBuffer;
|
||||||
|
|
||||||
|
for (UCHAR* data = smb->SMBIOSTableData; data < smb->SMBIOSTableData + smb->Length;)
|
||||||
|
{
|
||||||
|
dmi_header* h = (dmi_header*)data;
|
||||||
|
if (h->length < 4)
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Search for System Information structure with type 0x01 (see para 7.2)
|
||||||
|
if (h->type == 0x01 && h->length >= 0x19)
|
||||||
|
{
|
||||||
|
data += 0x08; //UUID is at offset 0x08
|
||||||
|
|
||||||
|
// check if there is a valid UUID (not all 0x00 or all 0xff)
|
||||||
|
BOOLEAN all_zero = TRUE, all_one = TRUE;
|
||||||
|
for (int i = 0; i < 16 && (all_zero || all_one); i++)
|
||||||
|
{
|
||||||
|
if (data[i] != 0x00) all_zero = FALSE;
|
||||||
|
if (data[i] != 0xFF) all_one = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!all_zero && !all_one)
|
||||||
|
{
|
||||||
|
// As off version 2.6 of the SMBIOS specification, the first 3 fields
|
||||||
|
// of the UUID are supposed to be encoded on little-endian. (para 7.2.1)
|
||||||
|
*uuid++ = data[3];
|
||||||
|
*uuid++ = data[2];
|
||||||
|
*uuid++ = data[1];
|
||||||
|
*uuid++ = data[0];
|
||||||
|
*uuid++ = data[5];
|
||||||
|
*uuid++ = data[4];
|
||||||
|
*uuid++ = data[7];
|
||||||
|
*uuid++ = data[6];
|
||||||
|
for (int i = 8; i < 16; i++)
|
||||||
|
*uuid++ = data[i];
|
||||||
|
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//skip over formatted area
|
||||||
|
UCHAR* next = data + h->length;
|
||||||
|
|
||||||
|
//skip over unformatted area of the structure (marker is 0000h)
|
||||||
|
while (next < smb->SMBIOSTableData + smb->Length && (next[0] != 0 || next[1] != 0))
|
||||||
|
next++;
|
||||||
|
|
||||||
|
next += 2;
|
||||||
|
|
||||||
|
data = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePoolWithTag(pSfti, 'vhpK');
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t* hexbyte(UCHAR b, wchar_t* ptr)
|
||||||
|
{
|
||||||
|
static const wchar_t* digits = L"0123456789ABCDEF";
|
||||||
|
*ptr++ = digits[b >> 4];
|
||||||
|
*ptr++ = digits[b & 0x0f];
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t g_uuid_str[40] = { 0 };
|
||||||
|
|
||||||
|
void InitFwUuid()
|
||||||
|
{
|
||||||
|
UCHAR uuid[16];
|
||||||
|
if (GetFwUuid(uuid))
|
||||||
|
{
|
||||||
|
wchar_t* ptr = g_uuid_str;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
ptr = hexbyte(uuid[i], ptr);
|
||||||
|
*ptr++ = '-';
|
||||||
|
for (; i < 6; i++)
|
||||||
|
ptr = hexbyte(uuid[i], ptr);
|
||||||
|
*ptr++ = '-';
|
||||||
|
for (; i < 8; i++)
|
||||||
|
ptr = hexbyte(uuid[i], ptr);
|
||||||
|
*ptr++ = '-';
|
||||||
|
for (; i < 10; i++)
|
||||||
|
ptr = hexbyte(uuid[i], ptr);
|
||||||
|
*ptr++ = '-';
|
||||||
|
for (; i < 16; i++)
|
||||||
|
ptr = hexbyte(uuid[i], ptr);
|
||||||
|
*ptr++ = 0;
|
||||||
|
|
||||||
|
DbgPrint("sbie FW-UUID: %S\n", g_uuid_str);
|
||||||
|
}
|
||||||
|
}
|
|
@ -85,6 +85,8 @@ enum ECertLevel {
|
||||||
#define CERT_IS_TYPE(cert,t) ((cert.type & 0b11100) == t)
|
#define CERT_IS_TYPE(cert,t) ((cert.type & 0b11100) == t)
|
||||||
#define CERT_IS_SUBSCRIPTION(cert) (CERT_IS_TYPE(cert, eCertBusiness) || CERT_IS_TYPE(cert, eCertSubscription) || cert.type == eCertEntryPatreon || CERT_IS_TYPE(cert, eCertEvaluation))
|
#define CERT_IS_SUBSCRIPTION(cert) (CERT_IS_TYPE(cert, eCertBusiness) || CERT_IS_TYPE(cert, eCertSubscription) || cert.type == eCertEntryPatreon || CERT_IS_TYPE(cert, eCertEvaluation))
|
||||||
#define CERT_IS_INSIDER(cert) (CERT_IS_TYPE(cert, eCertEternal) || cert.type == eCertGreatPatreon)
|
#define CERT_IS_INSIDER(cert) (CERT_IS_TYPE(cert, eCertEternal) || cert.type == eCertGreatPatreon)
|
||||||
#define CERT_IS_LEVEL(cert,l) (Verify_CertInfo.active && cert.level >= l)
|
#define CERT_IS_LEVEL(cert,l) (cert.active && cert.level >= l)
|
||||||
|
|
||||||
|
#ifdef KERNEL_MODE
|
||||||
extern SCertInfo Verify_CertInfo;
|
extern SCertInfo Verify_CertInfo;
|
||||||
|
#endif
|
Loading…
Reference in New Issue