This commit is contained in:
DavidXanatos 2023-10-16 21:35:59 +02:00
parent 5d89916fbf
commit 4034f2ee97
6 changed files with 274 additions and 1 deletions

View File

@ -9,6 +9,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.11.5 / 5.66.5] - 2023-10-
### Added
- added "get_cert SBIEX-XXXXX-XXXXX-XXXXX-XXXXX" command to UpdUtil.exe allowing to get a cert by serial using command line
### Changed
- improved suspend process ahndling [#3375](https://github.com/sandboxie-plus/Sandboxie/issues/3375)

View File

@ -130,4 +130,106 @@ void DbgPrint(const wchar_t* format, ...)
OutputDebugStringW(tmp1);
va_end(va_args);
}
std::multimap<std::wstring, std::wstring> GetArguments(const std::wstring& Arguments, wchar_t Separator, wchar_t Assigner, std::wstring* First, bool bLowerKeys, bool bReadEsc)
{
std::multimap<std::wstring, std::wstring> ArgumentList;
bool bReadValue = false;
std::wstring Name;
std::wstring Value;
wchar_t Prime = L'\0';
bool bEsc = false;
for(size_t i = 0; i < Arguments.size(); i++)
{
wchar_t Char = Arguments.at(i);
if(Prime != L'\0') // inside a string
{
if(bEsc) // ESC sequence handling
{
switch(Char)
{
case L'\\': Value += L'\\'; break;
case L'\'': Value += L'\''; break;
case L'\"': Value += L'\"'; break;
case L'a': Value += L'\a'; break;
case L'b': Value += L'\b'; break;
case L'f': Value += L'\f'; break;
case L'n': Value += L'\n'; break;
case L'r': Value += L'\r'; break;
case L't': Value += L'\t'; break;
case L'v': Value += L'\v'; break;
default: Value += L'?'; break;
}
bEsc = false;
}
else if(bReadEsc && Char == L'\\')
bEsc = true;
else if(Char == Prime) // end of the string
Prime = L'\0';
else
{
if(bReadValue)
Value += Char;
else
Name += Char;
}
continue;
}
else if(Char == L'"' || Char == L'\'') // begin of a string
{
Prime = Char;
continue;
}
if(/*Char == L' ' ||*/ Char == L'\t')
continue;
if(!bReadValue) // reading argument name, or value for default argument
{
if(Char == Separator)
{
if(First) {*First = Name; First = nullptr;}
else ArgumentList.insert({L"", Trimm(Name)});
Name.clear();
}
else if(Char == Assigner)
bReadValue = true;
else
Name += Char;
}
else
{
if(Char == Separator)
{
if (bLowerKeys)
std::transform(Name.begin(), Name.end(), Name.begin(), towlower);
ArgumentList.insert({Trimm(Name), Trimm(Value)});
Name.clear();
Value.clear();
bReadValue = false;
}
else
Value += Char;
}
}
if(!Name.empty())
{
if(bReadValue)
{
if (bLowerKeys)
std::transform(Name.begin(), Name.end(), Name.begin(), towlower);
ArgumentList.insert({Name, Value});
}
else
{
if (First) { *First = Name; }
else ArgumentList.insert({L"", Name});
}
}
return ArgumentList;
}

View File

@ -158,4 +158,6 @@ const T* wildstrcmp(const T* Wild, const T* Str)
bool FileExists(const wchar_t* path);
void DbgPrint(const wchar_t* format, ...);
void DbgPrint(const wchar_t* format, ...);
std::multimap<std::wstring, std::wstring> GetArguments(const std::wstring& Arguments, wchar_t Separator = L';', wchar_t Assigner = L'=', std::wstring* First = NULL, bool bLowerKeys = false, bool bReadEsc = false);

View File

@ -1634,6 +1634,61 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
return ret;
}
else if (arguments.size() >= 2 && arguments[0] == L"get_cert")
{
int ret = 0;
std::wstring serial = arguments[1];
std::wstring path = L"/get_cert.php?SN=" + serial;
if (serial.length() > 5 && toupper(serial[4]) == 'N') { // node locked business use
wchar_t uuid_str[40];
GetDriverInfo(-2, uuid_str, sizeof(uuid_str));
path += L"&HwId=" + std::wstring(uuid_str);
}
std::wstring file_path = base_dir + L"\\Certificate.dat";
char* aCert = NULL;
if (NT_SUCCESS(MyReadFile((wchar_t*)file_path.c_str(), 1024 * 1024, (PVOID*)&aCert, NULL)) && aCert != NULL) {
std::string sCert = aCert;
free(aCert);
auto Cert = GetArguments(std::wstring(sCert.begin(), sCert.end()), L'\n', L':');
auto F = Cert.find(L"UPDATEKEY");
if (F != Cert.end())
path += L"&UpdateKey=" + F->second;
}
ULONG lCert = 0;
if (WebDownload(_T(UPDATE_DOMAIN), path.c_str(), &aCert, &lCert) && aCert != NULL && *aCert)
{
if (aCert[0] == L'{') {
JSONValue* jsonObject = JSON::Parse(aCert);
if (jsonObject) {
if (jsonObject->IsObject() && GetJSONBoolSafe(jsonObject->AsObject(), L"error"))
{
std::wcout << GetJSONStringSafe(jsonObject->AsObject(), L"errorMsg") << std::endl;
ret = ERROR_GET_CERT;
}
delete jsonObject;
}
free(aCert);
}
}
else
{
std::wcout << L"FAILED to call get_cert.php" << std::endl;
ret = ERROR_GET_CERT;
}
if (ret == 0 && !NT_SUCCESS(MyWriteFile((wchar_t*)file_path.c_str(), aCert, lCert)))
ret = ERROR_INTERNAL;
return ret;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@ -1641,3 +1696,111 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
PrintUsage();
return ERROR_INVALID;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Driver API
#define SANDBOXIE L"Sandboxie"
#define SBIESVC_PORT L"\\RPC Control\\SbieSvcPort"
#define MAX_REQUEST_LENGTH (2048 * 1024)
typedef struct _UNICODE_STRING64 {
USHORT Length;
USHORT MaximumLength;
__declspec(align(8)) unsigned __int64 Buffer;
} UNICODE_STRING64;
#include "..\..\Sandboxie\common\defines.h"
#include "..\..\Sandboxie\core\drv\api_defs.h"
#include "..\..\Sandboxie\core\drv\api_flags.h"
HANDLE SbieApi_DeviceHandle = INVALID_HANDLE_VALUE;
NTSTATUS SbieApi_Ioctl(ULONG64 *parms)
{
NTSTATUS status;
OBJECT_ATTRIBUTES objattrs;
UNICODE_STRING uni;
IO_STATUS_BLOCK MyIoStatusBlock;
if (parms == NULL) {
if (SbieApi_DeviceHandle != INVALID_HANDLE_VALUE)
NtClose(SbieApi_DeviceHandle);
SbieApi_DeviceHandle = INVALID_HANDLE_VALUE;
return STATUS_SUCCESS;
}
if (SbieApi_DeviceHandle == INVALID_HANDLE_VALUE) {
RtlInitUnicodeString(&uni, API_DEVICE_NAME);
InitializeObjectAttributes(&objattrs, &uni, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtOpenFile(
&SbieApi_DeviceHandle, FILE_GENERIC_READ, &objattrs, &MyIoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0);
if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_NO_SUCH_DEVICE)
status = STATUS_SERVER_DISABLED;
} else
status = STATUS_SUCCESS;
if (status != STATUS_SUCCESS) {
SbieApi_DeviceHandle = INVALID_HANDLE_VALUE;
} else {
status = NtDeviceIoControlFile(
SbieApi_DeviceHandle, NULL, NULL, NULL, &MyIoStatusBlock,
API_SBIEDRV_CTLCODE, parms, sizeof(ULONG64) * 8, NULL, 0);
}
return status;
}
//LONG SbieApi_Call(ULONG api_code, LONG arg_num, ...)
//{
// va_list valist;
// NTSTATUS status;
// __declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
//
// memzero(parms, sizeof(parms));
// parms[0] = api_code;
//
// if (arg_num >= (API_NUM_ARGS - 1))
// return STATUS_INVALID_PARAMETER;
//
// va_start(valist, arg_num);
// for (LONG i = 1; i <= arg_num; i++)
// parms[i] = (ULONG64)va_arg(valist, ULONG_PTR);
// va_end(valist);
//
// status = SbieApi_Ioctl(parms);
//
// return status;
//}
bool GetDriverInfo(DWORD InfoClass, void* pBuffer, size_t Size)
{
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
API_QUERY_DRIVER_INFO_ARGS *args = (API_QUERY_DRIVER_INFO_ARGS*)parms;
memset(parms, 0, sizeof(parms));
args->func_code = API_QUERY_DRIVER_INFO;
args->info_class.val = InfoClass;
args->info_data.val = pBuffer;
args->info_len.val = Size;
NTSTATUS status = SbieApi_Ioctl(parms);
if (!NT_SUCCESS(status)) {
memset(pBuffer, 0, Size);
return false;
}
return true;
}

View File

@ -40,5 +40,6 @@
#define ERROR_BAD_ADDON (-13)
#define ERROR_BAD_ADDON2 (-14)
#define ERROR_DELETE (-15)
#define ERROR_GET_CERT (-16)

View File

@ -7,6 +7,8 @@
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <ntstatus.h>
#define WIN32_NO_STATUS
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>