From 4034f2ee974562771fe97d5f6f5fa507f0f8092d Mon Sep 17 00:00:00 2001 From: DavidXanatos <3890945+DavidXanatos@users.noreply.github.com> Date: Mon, 16 Oct 2023 21:35:59 +0200 Subject: [PATCH] 1.11.5 --- CHANGELOG.md | 3 + SandboxieTools/Common/helpers.cpp | 102 ++++++++++++++++++ SandboxieTools/Common/helpers.h | 4 +- SandboxieTools/UpdUtil/UpdUtil.cpp | 163 +++++++++++++++++++++++++++++ SandboxieTools/UpdUtil/UpdUtil.h | 1 + SandboxieTools/UpdUtil/framework.h | 2 + 6 files changed, 274 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75c20463..848cdff5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/SandboxieTools/Common/helpers.cpp b/SandboxieTools/Common/helpers.cpp index 7bc03aa6..420dc057 100644 --- a/SandboxieTools/Common/helpers.cpp +++ b/SandboxieTools/Common/helpers.cpp @@ -130,4 +130,106 @@ void DbgPrint(const wchar_t* format, ...) OutputDebugStringW(tmp1); va_end(va_args); +} + +std::multimap GetArguments(const std::wstring& Arguments, wchar_t Separator, wchar_t Assigner, std::wstring* First, bool bLowerKeys, bool bReadEsc) +{ + std::multimap 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; } \ No newline at end of file diff --git a/SandboxieTools/Common/helpers.h b/SandboxieTools/Common/helpers.h index 3970f113..2581bdbb 100644 --- a/SandboxieTools/Common/helpers.h +++ b/SandboxieTools/Common/helpers.h @@ -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, ...); \ No newline at end of file +void DbgPrint(const wchar_t* format, ...); + +std::multimap GetArguments(const std::wstring& Arguments, wchar_t Separator = L';', wchar_t Assigner = L'=', std::wstring* First = NULL, bool bLowerKeys = false, bool bReadEsc = false); \ No newline at end of file diff --git a/SandboxieTools/UpdUtil/UpdUtil.cpp b/SandboxieTools/UpdUtil/UpdUtil.cpp index d3863369..7777e0f5 100644 --- a/SandboxieTools/UpdUtil/UpdUtil.cpp +++ b/SandboxieTools/UpdUtil/UpdUtil.cpp @@ -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; +} \ No newline at end of file diff --git a/SandboxieTools/UpdUtil/UpdUtil.h b/SandboxieTools/UpdUtil/UpdUtil.h index 48955f29..eb1c65a8 100644 --- a/SandboxieTools/UpdUtil/UpdUtil.h +++ b/SandboxieTools/UpdUtil/UpdUtil.h @@ -40,5 +40,6 @@ #define ERROR_BAD_ADDON (-13) #define ERROR_BAD_ADDON2 (-14) #define ERROR_DELETE (-15) +#define ERROR_GET_CERT (-16) diff --git a/SandboxieTools/UpdUtil/framework.h b/SandboxieTools/UpdUtil/framework.h index f267d080..1050b3a5 100644 --- a/SandboxieTools/UpdUtil/framework.h +++ b/SandboxieTools/UpdUtil/framework.h @@ -7,6 +7,8 @@ #include "targetver.h" #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files +#include +#define WIN32_NO_STATUS #include // C RunTime Header Files #include