This commit is contained in:
DavidXanatos 2023-08-05 18:19:50 +02:00
parent 1d2509faeb
commit e945290867
6 changed files with 235 additions and 19 deletions

View File

@ -6,10 +6,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.10.3 / 5.65.3] - 2023-08-??
### 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
- improved business certificate handling
- improved business certificate handling, added usage count and machine bount options
### Fixed
- fixed issues with pinned shortcuts

View File

@ -56,6 +56,8 @@ static P_NtQueryObject __sys_NtQueryObject = NULL;
P_NtQueryVirtualMemory __sys_NtQueryVirtualMemory = NULL;
BOOLEAN obj_use_driver_obj_lookup = FALSE;
//---------------------------------------------------------------------------
// Obj_Init
//---------------------------------------------------------------------------
@ -72,6 +74,9 @@ _FX BOOLEAN Obj_Init(void)
SBIEDLL_HOOK(Obj_,NtQueryVirtualMemory);
#endif
if (!Dll_CompartmentMode) // NoDriverAssist
obj_use_driver_obj_lookup = SbieApi_QueryConfBool(NULL, L"UseDriverObjLookup", FALSE);
return TRUE;
}
@ -84,14 +89,17 @@ _FX BOOLEAN Obj_Init(void)
_FX ULONG Obj_GetObjectType(HANDLE ObjectHandle)
{
NTSTATUS status;
PUBLIC_OBJECT_TYPE_INFORMATION info;
union {
PUBLIC_OBJECT_TYPE_INFORMATION info;
wchar_t Buffer[256];
} u;
ULONG length = sizeof(u.Buffer);
ULONG length = sizeof(info);
status = __sys_NtQueryObject(ObjectHandle, ObjectTypeInformation, &u.info, length, &length);
status = __sys_NtQueryObject(ObjectHandle, ObjectTypeInformation, &info, length, &length);
if (NT_SUCCESS(status)) {
const WCHAR *TypeName = info.TypeName.Buffer;
if(NT_SUCCESS(status)) {
const WCHAR* TypeName = u.info.TypeName.Buffer;
if (TypeName[0] == L'D' && _wcsicmp(TypeName, L"Directory") == 0)
return OBJ_TYPE_DIRECTORY;
if (TypeName[0] == L'F' && _wcsicmp(TypeName, L"File") == 0)
@ -125,15 +133,41 @@ _FX ULONG Obj_GetObjectType(HANDLE ObjectHandle)
_FX NTSTATUS Obj_GetObjectName(
HANDLE ObjectHandle, void *ObjectName, ULONG *Length)
{
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
NTSTATUS status;
TlsData->obj_NtQueryObject_lock = TRUE;
//
// 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
//
status = __sys_NtQueryObject(
ObjectHandle, ObjectNameInformation, ObjectName, *Length, Length);
if (obj_use_driver_obj_lookup) {
TlsData->obj_NtQueryObject_lock = FALSE;
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;
status = __sys_NtQueryObject(
ObjectHandle, ObjectNameInformation, ObjectName, *Length, Length);
TlsData->obj_NtQueryObject_lock = FALSE;
}
return status;
}

View File

@ -30,6 +30,7 @@
#include "session.h"
#include "common/my_version.h"
#include "log_buff.h"
#define KERNEL_MODE
#include "verify.h"
@ -1354,6 +1355,16 @@ _FX NTSTATUS Api_QueryDriverInfo(PROCESS* proc, ULONG64* parms)
else
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
status = STATUS_INVALID_INFO_CLASS;

View File

@ -379,8 +379,14 @@ _FX BOOLEAN MyIsCallerSigned(void)
NTSTATUS KphValidateCertificate();
extern wchar_t g_uuid_str[40];
void InitFwUuid();
_FX NTSTATUS MyValidateCertificate(void)
{
if(!*g_uuid_str)
InitFwUuid();
NTSTATUS status = KphValidateCertificate();
if (status == STATUS_ACCOUNT_EXPIRED)

View File

@ -508,6 +508,7 @@ _FX NTSTATUS KphValidateCertificate()
WCHAR* type = NULL;
WCHAR* level = NULL;
LONG amount = 1;
//WCHAR* key = NULL;
LARGE_INTEGER cert_date = { 0 };
@ -516,8 +517,12 @@ _FX NTSTATUS KphValidateCertificate()
if(!NT_SUCCESS(status = MyInitHash(&hashObj)))
goto CleanupExit;
//
// read (Home Path)\Certificate.dat
//
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);
line = Mem_Alloc(Driver_Pool, line_size);
temp = Mem_Alloc(Driver_Pool, line_size);
@ -526,10 +531,6 @@ _FX NTSTATUS KphValidateCertificate()
goto CleanupExit;
}
//
// read (Home Path)\Certificate.dat
//
RtlStringCbPrintfW(path, path_len, path_cert, Driver_HomePathDos);
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) {
// 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
if (_wcsicmp(value, SOFTWARE_NAME) != 0) {
status = STATUS_OBJECT_TYPE_MISMATCH;
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:
status = Conf_Read_Line(stream, line, &line_num);
@ -837,3 +848,154 @@ CleanupExit:
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);
}
}

View File

@ -85,6 +85,8 @@ enum ECertLevel {
#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_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;
#endif