1.10.0
This commit is contained in:
parent
830d5f607d
commit
c7e49c7031
|
@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
## [1.10.0 / 5.65.0] - 2023-07-??
|
||||
|
||||
### Added
|
||||
- added box scripting engine to make sandman more flexible
|
||||
- added scriptable troubleshooting wizard [#1875](https://github.com/sandboxie-plus/Sandboxie/issues/1875)
|
||||
- added addon manager which helps to install additional and third-party components, available addons:
|
||||
- [ImDisk Toolkit](https://sourceforge.net/projects/imdisk-toolkit/) - used to create RAM Disks and other virtual drives
|
||||
|
@ -23,24 +24,30 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- added option to set the update interval to 1, 7, 14 and 30 days
|
||||
- added `What's new in Sandboxie-Plus` dialog in SbieCtrl.exe to praise the new features of the Plus UI
|
||||
- Note: this is shown after the installation of Sandboxie Classic
|
||||
- added "fixdacls" command to KmdUtil.exe it repairs broken DACL entries on the SbieHome folder to fix issues where SbieDll.dll fails to load
|
||||
|
||||
### Changed
|
||||
- setup wizard has now a dedicated update configuration page
|
||||
- this page will be shown for all users once which do not have updates enabled
|
||||
- split the support page into Sandboxie Support and Sandboxie Updater tabs
|
||||
- when the troubleshooting.7z file is available, the script engine will be used to match compatibility templates
|
||||
- this allows a better granularity in template selection by using the AppCompatibility.js script
|
||||
- reworked low level code injection mechanism to improve flexibility and debugging
|
||||
- the main injection detour code is now writen in C instead of Assembler and can proeprly report SbieDll.dll load errors as SBIE2181
|
||||
- improved session agent startup to be more flexible
|
||||
- improved SBIEMSG help handling
|
||||
|
||||
### Fixed
|
||||
- fixed uninstall issue in the Sandboxie Classic installer [d1863ff](https://github.com/sandboxie-plus/Sandboxie/commit/d1863ffadfe105c695de71c9e841c2fd568116fe)
|
||||
- added workaround for Chrome not starting on Windows 11 with KB5027231 [#3040](https://github.com/sandboxie-plus/Sandboxie/issues/3040)
|
||||
- improved compatybility with procmon/stack traces for debug builds
|
||||
|
||||
### Removed
|
||||
- cleaned up duplicate code (thanks lmou523) [#3067](https://github.com/sandboxie-plus/Sandboxie/pull/3067)
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.9.8 / 5.64.8] - 2023-06-21
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -281,10 +281,10 @@ extern ULONG64 Dll_ProcessFlags;
|
|||
#ifndef _WIN64
|
||||
extern BOOLEAN Dll_IsWow64;
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
#ifdef _M_ARM64EC
|
||||
extern BOOLEAN Dll_IsArm64ec;
|
||||
#endif
|
||||
#ifndef _M_ARM64
|
||||
#ifndef _WIN64
|
||||
extern BOOLEAN Dll_IsXtAjit;
|
||||
#endif
|
||||
extern BOOLEAN Dll_IsSystemSid;
|
||||
|
|
|
@ -90,10 +90,10 @@ ULONG64 Dll_ProcessFlags = 0;
|
|||
#ifndef _WIN64
|
||||
BOOLEAN Dll_IsWow64 = FALSE;
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
#ifdef _M_ARM64EC
|
||||
BOOLEAN Dll_IsArm64ec = FALSE;
|
||||
#endif
|
||||
#ifndef _M_ARM64
|
||||
#ifndef _WIN64
|
||||
BOOLEAN Dll_IsXtAjit = FALSE;
|
||||
#endif
|
||||
BOOLEAN Dll_IsSystemSid = FALSE;
|
||||
|
@ -772,46 +772,20 @@ _FX void Dll_SelectImageType(void)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX ULONG_PTR Dll_Ordinal1(
|
||||
ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
|
||||
ULONG_PTR arg4, ULONG_PTR arg5)
|
||||
_FX VOID Dll_Ordinal1(INJECT_DATA * inject)
|
||||
{
|
||||
typedef ULONG_PTR (*P_RtlFindActivationContextSectionString)(
|
||||
ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
|
||||
ULONG_PTR arg4, ULONG_PTR arg5);
|
||||
P_RtlFindActivationContextSectionString RtlFindActCtx;
|
||||
|
||||
#if defined(_M_ARM64) || defined(_M_ARM64EC)
|
||||
//
|
||||
// on ARM64 we hook LdrLoadDll instead, using the prototype for
|
||||
// RtlFindActCtx is fine though as arguments 1-8 are passed in registers
|
||||
// so if we set x4 or not does not matter in the least
|
||||
//
|
||||
#endif
|
||||
|
||||
INJECT_DATA *inject;
|
||||
SBIELOW_DATA *data;
|
||||
ULONG dummy_prot;
|
||||
SBIELOW_DATA *data = (SBIELOW_DATA *)inject->sbielow_data;
|
||||
BOOLEAN bHostInject = FALSE;
|
||||
|
||||
extern HANDLE SbieApi_DeviceHandle;
|
||||
|
||||
//
|
||||
// this code is invoked from our RtlFindActivationContextSectionString
|
||||
// hook in core/low/entry.asm, with a parameter that points to the
|
||||
// syscall/inject data area. the first ULONG64 in this data area
|
||||
// includes a pointer to the SbieLow data area
|
||||
//
|
||||
|
||||
inject = (struct _INJECT_DATA *)arg1;
|
||||
|
||||
data = (SBIELOW_DATA *)inject->sbielow_data;
|
||||
|
||||
SbieApi_data = data;
|
||||
#ifdef _M_ARM64EC
|
||||
// get the pointer to sys_call_list in the SYS_CALL_DATA struct
|
||||
SbieApi_SyscallPtr = (ULONG*)((ULONG64)data->syscall_data + sizeof(ULONG) + sizeof(ULONG) + (NATIVE_FUNCTION_SIZE * NATIVE_FUNCTION_COUNT));
|
||||
#endif
|
||||
|
||||
extern HANDLE SbieApi_DeviceHandle;
|
||||
SbieApi_DeviceHandle = (HANDLE)data->api_device_handle;
|
||||
|
||||
//
|
||||
// the SbieLow data area includes values that are useful to us
|
||||
// so we copy them into dedicated variables if we are going to use them more often
|
||||
|
@ -820,38 +794,15 @@ _FX ULONG_PTR Dll_Ordinal1(
|
|||
bHostInject = data->flags.bHostInject == 1;
|
||||
|
||||
#ifndef _WIN64
|
||||
Dll_IsWow64 = data->flags.is_wow64 == 1;
|
||||
Dll_IsWow64 = data->flags.is_wow64 == 1; // x86 on x64 or arm64
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
Dll_IsArm64ec = data->flags.is_arm64ec == 1;
|
||||
#ifdef _M_ARM64EC
|
||||
Dll_IsArm64ec = data->flags.is_arm64ec == 1; // x64 on arm64
|
||||
#endif
|
||||
#ifndef _M_ARM64
|
||||
Dll_IsXtAjit = data->flags.is_xtajit == 1;
|
||||
#ifndef _WIN64
|
||||
Dll_IsXtAjit = data->flags.is_xtajit == 1; // x86 on arm64
|
||||
#endif
|
||||
|
||||
SbieApi_DeviceHandle = (HANDLE)data->api_device_handle;
|
||||
|
||||
//
|
||||
// our RtlFindActivationContextSectionString hook already restored
|
||||
// the original bytes, but we should still restore the page protection
|
||||
//
|
||||
|
||||
VirtualProtect((void *)(ULONG_PTR)inject->RtlFindActCtx, 5,
|
||||
inject->RtlFindActCtx_Protect, &dummy_prot);
|
||||
|
||||
arg1 = (ULONG_PTR)inject->RtlFindActCtx_SavedArg1;
|
||||
|
||||
RtlFindActCtx = (P_RtlFindActivationContextSectionString)
|
||||
inject->RtlFindActCtx;
|
||||
|
||||
//
|
||||
// make sbielow_data read only, as it contsins required
|
||||
// nt dll function copies it must stay executive
|
||||
//
|
||||
|
||||
VirtualProtect((void *)data, sizeof(SBIELOW_DATA),
|
||||
PAGE_EXECUTE_READ, &dummy_prot);
|
||||
|
||||
|
||||
if (!bHostInject)
|
||||
{
|
||||
|
@ -928,25 +879,6 @@ _FX ULONG_PTR Dll_Ordinal1(
|
|||
{
|
||||
Ldr_Inject_Init(TRUE);
|
||||
}
|
||||
|
||||
//
|
||||
// free the syscall/inject data area which is no longer needed
|
||||
//
|
||||
|
||||
#ifdef _M_ARM64EC
|
||||
SbieApi_SyscallPtr = NULL;
|
||||
#endif
|
||||
VirtualFree(inject, 0, MEM_RELEASE);
|
||||
|
||||
|
||||
//
|
||||
// conclude the detour by passing control back to the original
|
||||
// RtlFindActivationContextSectionString. the detour code used
|
||||
// jump rather than call to invoke this function (see entry.asm)
|
||||
// so RtlFindActivationContextSectionString returns to its caller
|
||||
//
|
||||
|
||||
return RtlFindActCtx(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -412,7 +412,7 @@ _FX VOID File_SavePathTree_internal(LIST* Root, const WCHAR* name)
|
|||
|
||||
HANDLE hPathsFile;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
if (!NT_SUCCESS(NtCreateFile(&hPathsFile, GENERIC_WRITE | SYNCHRONIZE , &objattrs, &IoStatusBlock, NULL, 0, FILE_SHARE_READ, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0)))
|
||||
if (!NT_SUCCESS(NtCreateFile(&hPathsFile, GENERIC_WRITE | SYNCHRONIZE, &objattrs, &IoStatusBlock, NULL, 0, FILE_SHARE_READ, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0)))
|
||||
return;
|
||||
|
||||
WCHAR* Path = (WCHAR *)Dll_Alloc((0x7FFF + 1)*sizeof(WCHAR)); // max nt path
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct _FILE_SNAPSHOT {
|
|||
WCHAR ID[FILE_MAX_SNAPSHOT_ID];
|
||||
ULONG IDlen;
|
||||
ULONG ScramKey;
|
||||
//WCHAR Name[34];
|
||||
//WCHAR Name[BOXNAME_COUNT];
|
||||
struct _FILE_SNAPSHOT* Parent;
|
||||
LIST PathRoot;
|
||||
} FILE_SNAPSHOT, *PFILE_SNAPSHOT;
|
||||
|
@ -480,8 +480,8 @@ _FX void File_InitSnapshots(void)
|
|||
File_LoadPathTree_internal(&Cur_Snapshot->PathRoot, PathFile);
|
||||
}
|
||||
|
||||
//WCHAR SnapshotName[34] = { 0 };
|
||||
//GetPrivateProfileStringW(SnapshotId, L"Name", L"", SnapshotName, 34, SnapshotsIni);
|
||||
//WCHAR SnapshotName[BOXNAME_COUNT] = { 0 };
|
||||
//GetPrivateProfileStringW(SnapshotId, L"Name", L"", SnapshotName, BOXNAME_COUNT, SnapshotsIni);
|
||||
//wcscpy(Cur_Snapshot->Name, SnapshotName);
|
||||
|
||||
GetPrivateProfileStringW(SnapshotId, L"Parent", L"", Snapshot, 16, SnapshotsIni);
|
||||
|
|
|
@ -282,22 +282,15 @@ void CALLBACK Ldr_LdrDllNotification(ULONG NotificationReason, PLDR_DLL_NOTIFICA
|
|||
{
|
||||
ULONG_PTR LdrCookie = 0;
|
||||
NTSTATUS status = 0;
|
||||
WCHAR text[4096];
|
||||
|
||||
if (NotificationReason == 1) {
|
||||
status = __sys_LdrLockLoaderLock(0, NULL, &LdrCookie);
|
||||
Ldr_MyDllCallbackNew(NotificationData->Loaded.BaseDllName->Buffer, (HMODULE)NotificationData->Loaded.DllBase, TRUE);
|
||||
__sys_LdrUnlockLoaderLock(0, LdrCookie);
|
||||
|
||||
Sbie_snwprintf(text, ARRAYSIZE(text), L"%s (loaded)", NotificationData->Loaded.BaseDllName->Buffer);
|
||||
}
|
||||
else if (NotificationReason == 2) {
|
||||
Ldr_MyDllCallbackNew(NotificationData->Unloaded.BaseDllName->Buffer, (HMODULE)NotificationData->Loaded.DllBase, FALSE);
|
||||
|
||||
Sbie_snwprintf(text, ARRAYSIZE(text), L"%s (unloaded)", NotificationData->Loaded.BaseDllName->Buffer);
|
||||
}
|
||||
|
||||
SbieApi_MonitorPutMsg(MONITOR_IMAGE, text);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1090,19 +1083,25 @@ _FX void Ldr_MyDllCallbackA(const CHAR *ImageName, HMODULE ImageBase, BOOL LoadS
|
|||
WCHAR ImageNameW[128];
|
||||
Sbie_snwprintf(ImageNameW, ARRAYSIZE(ImageNameW), L"%S", ImageName);
|
||||
|
||||
Ldr_MyDllCallbackW(ImageNameW, ImageBase, LoadState);
|
||||
Ldr_MyDllCallbackNew(ImageNameW, ImageBase, LoadState);
|
||||
}
|
||||
|
||||
|
||||
_FX void Ldr_MyDllCallbackW(const WCHAR *ImageName, HMODULE ImageBase, BOOL LoadState) // Windows XP
|
||||
{
|
||||
// call new function
|
||||
Ldr_MyDllCallbackNew(ImageName, ImageBase, LoadState);
|
||||
Ldr_MyDllCallbackNew(ImageName, ImageBase, LoadState);
|
||||
}
|
||||
|
||||
|
||||
_FX void Ldr_MyDllCallbackNew(const WCHAR *ImageName, HMODULE ImageBase, BOOL LoadState) // Windows 8.1 and later
|
||||
{
|
||||
WCHAR text[4096];
|
||||
if(LoadState)
|
||||
Sbie_snwprintf(text, ARRAYSIZE(text), L"%s (loaded)", ImageName);
|
||||
else
|
||||
Sbie_snwprintf(text, ARRAYSIZE(text), L"%s (unloaded)", ImageName);
|
||||
SbieApi_MonitorPutMsg(MONITOR_IMAGE, text);
|
||||
|
||||
//
|
||||
// invoke our sub-modules as necessary
|
||||
//
|
||||
|
@ -1187,12 +1186,12 @@ _FX void *Ldr_GetProcAddrOld(const WCHAR *DllName, const WCHAR *ProcNameW)
|
|||
_FX void *Ldr_GetProcAddrNew(const WCHAR *DllName, const WCHAR *ProcNameW, char * ProcNameA)
|
||||
{
|
||||
NTSTATUS status;
|
||||
void *proc;
|
||||
void *proc = NULL;
|
||||
// char buffer[768];
|
||||
// sprintf(buffer,"GetProcAddrNew: DllName = %S, ProcW = %S, ProcA = %s\n",DllName,ProcNameW,ProcNameA);
|
||||
// OutputDebugStringA(buffer);
|
||||
|
||||
if (Dll_OsBuild < 9600) {
|
||||
if (Dll_OsBuild < 9600) { // Windows 8.0 or earlier
|
||||
proc = Ldr_GetProcAddr_2(DllName, ProcNameW);
|
||||
if (!proc) {
|
||||
ULONG_PTR LdrCookie;
|
||||
|
@ -1223,7 +1222,7 @@ _FX void *Ldr_GetProcAddrNew(const WCHAR *DllName, const WCHAR *ProcNameW, char
|
|||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else { // Windows 8.1 and later
|
||||
HMODULE DllBase;
|
||||
DllBase = GetModuleHandle(DllName);
|
||||
if (!DllBase) {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
|
||||
#include "dll.h"
|
||||
#include "core/low/lowdata.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
@ -880,6 +881,22 @@ _FX void* Ldr_Inject_Entry(ULONG_PTR *pPtr)
|
|||
{
|
||||
Ldr_LoadInjectDlls(g_bHostInject);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// free the syscall/inject data area which is no longer needed
|
||||
//
|
||||
|
||||
#ifdef _M_ARM64EC
|
||||
extern ULONG* SbieApi_SyscallPtr;
|
||||
SbieApi_SyscallPtr = NULL;
|
||||
#endif
|
||||
extern SBIELOW_DATA* SbieApi_data;
|
||||
VirtualFree((void*)SbieApi_data->syscall_data, 0, MEM_RELEASE);
|
||||
|
||||
//
|
||||
// return original entry point address to jump to
|
||||
//
|
||||
|
||||
return entrypoint;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
// Copyright 2023 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
|
||||
|
@ -54,11 +55,10 @@
|
|||
#ifdef BUILD_UTILITY_PASS2
|
||||
|
||||
#if MY_ARM64_FLAG
|
||||
LOWLEVEL RCDATA "../low/obj/ARM64/LowLevel.dll"
|
||||
LOWLEVEL64 RCDATA "../low/obj/ARM64/LowLevel.dll"
|
||||
#elif MY_WIN64_FLAG
|
||||
LOWLEVEL RCDATA "../low/obj/amd64/LowLevel.dll"
|
||||
#else
|
||||
LOWLEVEL RCDATA "../low/obj/i386/LowLevel.dll"
|
||||
LOWLEVEL64 RCDATA "../low/obj/amd64/LowLevel.dll"
|
||||
#endif // MY_WIN64_FLAG
|
||||
LOWLEVEL32 RCDATA "../low/obj/i386/LowLevel.dll"
|
||||
|
||||
#endif // BUILD_UTILITY_PASS2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 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
|
||||
|
@ -48,6 +48,7 @@
|
|||
typedef struct _MY_TARGETS {
|
||||
unsigned long long entry;
|
||||
unsigned long long data;
|
||||
unsigned long long detour;
|
||||
} MY_TARGETS;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
|
@ -85,7 +86,7 @@ typedef PVOID (*P_VirtualAlloc2)(
|
|||
SBIEDLL_EXPORT HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess);
|
||||
|
||||
void *SbieDll_InjectLow_CopyCode(
|
||||
HANDLE hProcess, SIZE_T lowLevel_size, UCHAR *code, ULONG code_len
|
||||
HANDLE hProcess, SIZE_T total_size, SIZE_T lowLevel_size, const void* lowLevel_ptr
|
||||
#ifdef _M_ARM64
|
||||
, BOOLEAN use_arm64ec
|
||||
#endif
|
||||
|
@ -129,11 +130,16 @@ ULONG Hook_GetSysCallFunc(ULONG* aCode, void** pHandleStubHijack);
|
|||
|
||||
|
||||
void *m_sbielow_ptr = NULL;
|
||||
ULONG m_sbielow_len = 0;
|
||||
//adding two offsets variables to replace the "head" and "tail" dependency
|
||||
ULONG m_sbielow_start_offset = 0;
|
||||
ULONG m_sbielow_data_offset = 0;
|
||||
|
||||
ULONG m_sbielow_len = 0;
|
||||
#ifdef _WIN64
|
||||
void *m_sbielow32_ptr = NULL;
|
||||
ULONG m_sbielow32_len = 0;
|
||||
ULONG m_sbielow32_detour_offset = 0;
|
||||
#endif
|
||||
|
||||
ULONG *m_syscall_data = NULL;
|
||||
|
||||
|
@ -149,19 +155,19 @@ P_VirtualAlloc2 __sys_VirtualAlloc2 = NULL;
|
|||
|
||||
#endif
|
||||
|
||||
#include "core/low/lowlevel_code.c"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// InjectLow_InitHelper
|
||||
// SbieDll_InjectLow_LoadLow
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX ULONG SbieDll_InjectLow_InitHelper()
|
||||
_FX ULONG SbieDll_InjectLow_LoadLow(BOOLEAN arch_64bit, void **sbielow_ptr, ULONG *sbielow_len, ULONG *start_offset, ULONG* data_offset, ULONG* detour_offset)
|
||||
{
|
||||
//
|
||||
// lock the SbieLow resource (embedded within the SbieSvc executable,
|
||||
// see lowlevel.rc) and find the offset to executable code, and length
|
||||
//
|
||||
|
||||
IMAGE_DOS_HEADER *dos_hdr = 0;
|
||||
IMAGE_NT_HEADERS *nt_hdrs = 0;
|
||||
IMAGE_SECTION_HEADER *section = 0;
|
||||
|
@ -171,8 +177,8 @@ _FX ULONG SbieDll_InjectLow_InitHelper()
|
|||
|
||||
ULONG errlvl = 0x11;
|
||||
|
||||
HRSRC hrsrc = FindResource(Dll_Instance, L"LOWLEVEL", RT_RCDATA);
|
||||
if (! hrsrc)
|
||||
HRSRC hrsrc = FindResource(Dll_Instance, arch_64bit ? L"LOWLEVEL64" : L"LOWLEVEL32", RT_RCDATA);
|
||||
if (! hrsrc)
|
||||
return errlvl;
|
||||
|
||||
ULONG binsize = SizeofResource(Dll_Instance, hrsrc);
|
||||
|
@ -193,44 +199,33 @@ _FX ULONG SbieDll_InjectLow_InitHelper()
|
|||
if (dos_hdr->e_magic == 'MZ' || dos_hdr->e_magic == 'ZM') {
|
||||
nt_hdrs = (IMAGE_NT_HEADERS *)((UCHAR *)dos_hdr + dos_hdr->e_lfanew);
|
||||
|
||||
if (nt_hdrs->Signature == IMAGE_NT_SIGNATURE) { // 'PE\0\0'
|
||||
#ifndef _WIN64
|
||||
if (nt_hdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
IMAGE_NT_HEADERS32 *nt_hdrs_32 = (IMAGE_NT_HEADERS32 *)nt_hdrs;
|
||||
IMAGE_OPTIONAL_HEADER32 *opt_hdr_32 = &nt_hdrs_32->OptionalHeader;
|
||||
data_dirs = &opt_hdr_32->DataDirectory[0];
|
||||
imageBase = opt_hdr_32->ImageBase;
|
||||
}
|
||||
#else
|
||||
if (nt_hdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||
IMAGE_NT_HEADERS64 *nt_hdrs_64 = (IMAGE_NT_HEADERS64 *)nt_hdrs;
|
||||
IMAGE_OPTIONAL_HEADER64 *opt_hdr_64 = &nt_hdrs_64->OptionalHeader;
|
||||
data_dirs = &opt_hdr_64->DataDirectory[0];
|
||||
imageBase = (ULONG_PTR)opt_hdr_64->ImageBase;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
|
||||
return errlvl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (nt_hdrs->Signature != IMAGE_NT_SIGNATURE) // 'PE\0\0'
|
||||
return errlvl;
|
||||
if (nt_hdrs->OptionalHeader.Magic != (arch_64bit ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC))
|
||||
return errlvl;
|
||||
|
||||
if (!arch_64bit) {
|
||||
IMAGE_NT_HEADERS32 *nt_hdrs_32 = (IMAGE_NT_HEADERS32 *)nt_hdrs;
|
||||
IMAGE_OPTIONAL_HEADER32 *opt_hdr_32 = &nt_hdrs_32->OptionalHeader;
|
||||
data_dirs = &opt_hdr_32->DataDirectory[0];
|
||||
imageBase = opt_hdr_32->ImageBase;
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS64 *nt_hdrs_64 = (IMAGE_NT_HEADERS64 *)nt_hdrs;
|
||||
IMAGE_OPTIONAL_HEADER64 *opt_hdr_64 = &nt_hdrs_64->OptionalHeader;
|
||||
data_dirs = &opt_hdr_64->DataDirectory[0];
|
||||
imageBase = (ULONG_PTR)opt_hdr_64->ImageBase;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG zzzzz;
|
||||
|
||||
ULONG zzzzz = 1;
|
||||
#ifdef _M_ARM64
|
||||
zzzzz = 4;
|
||||
#else
|
||||
if (imageBase != 0) {
|
||||
return errlvl;
|
||||
}
|
||||
|
||||
zzzzz = 1;
|
||||
if (arch_64bit)
|
||||
zzzzz = 4; // ARM64 only
|
||||
else
|
||||
#endif
|
||||
if (imageBase != 0) // x64 or x86
|
||||
return errlvl;
|
||||
|
||||
section = IMAGE_FIRST_SECTION(nt_hdrs);
|
||||
if (nt_hdrs->FileHeader.NumberOfSections < 2) return errlvl;
|
||||
|
@ -241,13 +236,32 @@ _FX ULONG SbieDll_InjectLow_InitHelper()
|
|||
|
||||
|
||||
targets = (MY_TARGETS *)& bindata[section[zzzzz].PointerToRawData];
|
||||
m_sbielow_start_offset = (ULONG)(targets->entry - imageBase - section[0].VirtualAddress);
|
||||
m_sbielow_data_offset = (ULONG)(targets->data - imageBase - section[0].VirtualAddress);
|
||||
if(start_offset) *start_offset = (ULONG)(targets->entry - imageBase - section[0].VirtualAddress);
|
||||
if(data_offset) *data_offset = (ULONG)(targets->data - imageBase - section[0].VirtualAddress);
|
||||
if(detour_offset) *detour_offset = (ULONG)(targets->detour - imageBase - section[0].VirtualAddress);
|
||||
|
||||
m_sbielow_ptr = bindata + section[0].PointerToRawData; //Old version: head;
|
||||
m_sbielow_len = section[0].SizeOfRawData; //Old version: (ULONG)(ULONG_PTR)(tail - head);
|
||||
*sbielow_ptr = bindata + section[0].PointerToRawData; //Old version: head;
|
||||
*sbielow_len = section[0].SizeOfRawData; //Old version: (ULONG)(ULONG_PTR)(tail - head);
|
||||
|
||||
if ((!m_sbielow_start_offset) || (!m_sbielow_data_offset))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// InjectLow_InitHelper
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX ULONG SbieDll_InjectLow_InitHelper()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
ULONG errlvl = SbieDll_InjectLow_LoadLow(TRUE, &m_sbielow_ptr, &m_sbielow_len, &m_sbielow_start_offset, &m_sbielow_data_offset, NULL);
|
||||
if(!errlvl)
|
||||
errlvl = SbieDll_InjectLow_LoadLow(FALSE, &m_sbielow32_ptr, &m_sbielow32_len, NULL, NULL, &m_sbielow32_detour_offset);
|
||||
#else
|
||||
ULONG errlvl = SbieDll_InjectLow_LoadLow(FALSE, &m_sbielow_ptr, &m_sbielow_len, &m_sbielow_start_offset, &m_sbielow_data_offset, NULL);
|
||||
#endif
|
||||
if (errlvl)
|
||||
return errlvl;
|
||||
|
||||
//
|
||||
|
@ -403,6 +417,10 @@ _FX ULONG SbieDll_InjectLow_InitSyscalls(BOOLEAN drv_init)
|
|||
// Get the SbieDll Location
|
||||
//
|
||||
|
||||
/*if (1) {
|
||||
GetSystemDirectory(sbie_home, 512);
|
||||
}
|
||||
else */
|
||||
if (drv_init)
|
||||
{
|
||||
status = SbieApi_GetHomePath(NULL, 0, sbie_home, 512);
|
||||
|
@ -531,6 +549,15 @@ _FX ULONG SbieDll_InjectLow_InitSyscalls(BOOLEAN drv_init)
|
|||
extra->LdrGetProcAddr_offset = ULONG_DIFF(ptr, extra);
|
||||
ptr += 28 / sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// write an ASCII string for NtProtectVirtualMemory
|
||||
//
|
||||
|
||||
strcpy((char *)ptr, "NtProtectVirtualMemory");
|
||||
|
||||
extra->NtProtectVirtualMemory_offset = ULONG_DIFF(ptr, extra);
|
||||
ptr += 28 / sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// write an ASCII string for NtRaiseHardError
|
||||
//
|
||||
|
@ -540,6 +567,15 @@ _FX ULONG SbieDll_InjectLow_InitSyscalls(BOOLEAN drv_init)
|
|||
extra->NtRaiseHardError_offset = ULONG_DIFF(ptr, extra);
|
||||
ptr += 20 / sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// write an ASCII string for NtDeviceIoControlFile
|
||||
//
|
||||
|
||||
strcpy((char *)ptr, "NtDeviceIoControlFile");
|
||||
|
||||
extra->NtDeviceIoControlFile_offset = ULONG_DIFF(ptr, extra);
|
||||
ptr += 28 / sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// write an ASCII string for RtlFindActivationContextSectionString
|
||||
//
|
||||
|
@ -615,15 +651,6 @@ _FX ULONG SbieDll_InjectLow_InitSyscalls(BOOLEAN drv_init)
|
|||
|
||||
extra->InjectData_offset = ULONG_DIFF(ptr, extra);
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
//
|
||||
// Copy the required non shell code into INJECT_DATA.DetourCode_*
|
||||
//
|
||||
|
||||
memcpy((UCHAR*)ptr + FIELD_OFFSET(INJECT_DATA, DetourCode_x86), SbieDll_ShellCode_x86, sizeof(SbieDll_ShellCode_x86));
|
||||
#endif
|
||||
|
||||
//
|
||||
// adjust size of syscall buffer to include path strings
|
||||
//
|
||||
|
@ -852,6 +879,7 @@ _FX ULONG SbieDll_InjectLow(HANDLE hProcess, ULONG init_flags, BOOLEAN dup_drv_h
|
|||
#endif
|
||||
|
||||
lowdata.RealNtDeviceIoControlFile = (ULONG64)GetProcAddress((HMODULE)lowdata.ntdll_base, "NtDeviceIoControlFile");
|
||||
lowdata.NativeNtProtectVirtualMemory = (ULONG64)GetProcAddress((HMODULE)lowdata.ntdll_base, "NtProtectVirtualMemory");
|
||||
lowdata.NativeNtRaiseHardError = (ULONG64)GetProcAddress((HMODULE)lowdata.ntdll_base, "NtRaiseHardError");
|
||||
|
||||
//
|
||||
|
@ -885,16 +913,76 @@ _FX ULONG SbieDll_InjectLow(HANDLE hProcess, ULONG init_flags, BOOLEAN dup_drv_h
|
|||
#endif
|
||||
lowLevel_size = m_sbielow_len;
|
||||
|
||||
void *remote_addr = SbieDll_InjectLow_CopyCode(hProcess, lowLevel_size, lowdata.LdrInitializeThunk_tramp, sizeof(lowdata.LdrInitializeThunk_tramp)
|
||||
void *remote_addr = SbieDll_InjectLow_CopyCode(hProcess, lowLevel_size, m_sbielow_len, m_sbielow_ptr
|
||||
#ifdef _M_ARM64
|
||||
, (BOOLEAN)lowdata.flags.is_arm64ec
|
||||
#endif
|
||||
);
|
||||
|
||||
if (remote_addr) {
|
||||
|
||||
void* pLdrInitializeThunk = (void*)m_LdrInitializeThunk;
|
||||
#ifdef _M_ARM64
|
||||
if (lowdata.flags.is_arm64ec)
|
||||
pLdrInitializeThunk = (void*)m_LdrInitializeThunkEC;
|
||||
#endif
|
||||
|
||||
//
|
||||
// copy code at LdrInitializeThunk from new process
|
||||
//
|
||||
|
||||
SIZE_T len1 = sizeof(lowdata.LdrInitializeThunk_tramp);
|
||||
SIZE_T len2 = 0;
|
||||
/*
|
||||
sprintf(buffer,"CopyCode: copy ldr size %d\n",code_len);
|
||||
OutputDebugStringA(buffer);
|
||||
*/
|
||||
BOOL vm_ok = ReadProcessMemory(
|
||||
hProcess, pLdrInitializeThunk, lowdata.LdrInitializeThunk_tramp,
|
||||
len1, &len2);
|
||||
|
||||
if (!vm_ok || len1 != len2) {
|
||||
|
||||
remote_addr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!remote_addr) {
|
||||
errlvl = 0x33;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
void *remote_addr32 = NULL;
|
||||
if (lowdata.flags.is_wow64) {
|
||||
|
||||
//
|
||||
// when this is a 32 bit process runing under WoW we need to inject also some 32 bit code
|
||||
//
|
||||
|
||||
remote_addr32 = SbieDll_InjectLow_CopyCode(hProcess, m_sbielow32_len, m_sbielow32_len, m_sbielow32_ptr
|
||||
#ifdef _M_ARM64
|
||||
, FALSE
|
||||
#endif
|
||||
);
|
||||
|
||||
if (remote_addr32) {
|
||||
|
||||
ULONG protect;
|
||||
BOOL vm_ok = VirtualProtectEx(hProcess, remote_addr32, m_sbielow32_len,
|
||||
PAGE_EXECUTE_READ, &protect);
|
||||
if (vm_ok) {
|
||||
lowdata.ptr_32bit_detour = (ULONG64)((UCHAR*)remote_addr32 + m_sbielow32_detour_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (!lowdata.ptr_32bit_detour) {
|
||||
errlvl = 0x88;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _M_ARM64
|
||||
#ifdef _WIN64
|
||||
lowdata.flags.long_diff = 1;
|
||||
|
@ -1041,8 +1129,8 @@ _FX void* InjectLow_AllocMemory(HANDLE hProcess, SIZE_T size, BOOLEAN executable
|
|||
void *remote_addr = NULL;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
if (use_arm64ec && executable)
|
||||
{
|
||||
if (use_arm64ec && executable) {
|
||||
|
||||
MEM_EXTENDED_PARAMETER Parameter = { 0 };
|
||||
Parameter.Type = MemExtendedParameterAttributeFlags;
|
||||
Parameter.ULong64 = MEM_EXTENDED_PARAMETER_EC_CODE;
|
||||
|
@ -1051,8 +1139,9 @@ _FX void* InjectLow_AllocMemory(HANDLE hProcess, SIZE_T size, BOOLEAN executable
|
|||
|
||||
remote_addr = __sys_VirtualAlloc2(hProcess, (void*)base_addr, region_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE, &Parameter, 1);
|
||||
}
|
||||
|
||||
return remote_addr;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -1127,20 +1216,13 @@ _FX HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void *SbieDll_InjectLow_CopyCode(HANDLE hProcess, SIZE_T lowLevel_size, UCHAR *code, ULONG code_len
|
||||
_FX void *SbieDll_InjectLow_CopyCode(HANDLE hProcess, SIZE_T total_size, SIZE_T lowLevel_size, const void* lowLevel_ptr
|
||||
#ifdef _M_ARM64
|
||||
, BOOLEAN use_arm64ec
|
||||
#endif
|
||||
) {
|
||||
void* remote_addr;
|
||||
void* pLdrInitializeThunk = (void*)m_LdrInitializeThunk;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
if (use_arm64ec)
|
||||
pLdrInitializeThunk = (void*)m_LdrInitializeThunkEC;
|
||||
#endif
|
||||
|
||||
remote_addr = InjectLow_AllocMemory(hProcess, lowLevel_size, TRUE
|
||||
void* remote_addr = InjectLow_AllocMemory(hProcess, total_size, TRUE
|
||||
#ifdef _M_ARM64
|
||||
, use_arm64ec
|
||||
#endif
|
||||
|
@ -1152,32 +1234,15 @@ _FX void *SbieDll_InjectLow_CopyCode(HANDLE hProcess, SIZE_T lowLevel_size, UCHA
|
|||
// copy SbieLow into the allocated region in the new process
|
||||
//
|
||||
|
||||
SIZE_T len1 = m_sbielow_len;
|
||||
SIZE_T len1 = lowLevel_size;
|
||||
SIZE_T len2 = 0;
|
||||
BOOL vm_ok = WriteProcessMemory(
|
||||
hProcess, remote_addr, m_sbielow_ptr,
|
||||
hProcess, remote_addr, lowLevel_ptr,
|
||||
len1, &len2);
|
||||
|
||||
if (vm_ok && len1 == len2) {
|
||||
|
||||
//
|
||||
// copy code at LdrInitializeThunk from new process
|
||||
//
|
||||
|
||||
len1 = code_len;
|
||||
len2 = 0;
|
||||
/*
|
||||
sprintf(buffer,"CopyCode: copy ldr size %d\n",code_len);
|
||||
OutputDebugStringA(buffer);
|
||||
*/
|
||||
vm_ok = ReadProcessMemory(
|
||||
hProcess, pLdrInitializeThunk, code,
|
||||
len1, &len2);
|
||||
|
||||
if (vm_ok && len1 == len2) {
|
||||
|
||||
return remote_addr;
|
||||
}
|
||||
return remote_addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1356,10 +1421,8 @@ _FX void *SbieDll_InjectLow_CopySyscalls(HANDLE hProcess, BOOLEAN is_wow64
|
|||
data = m_syscall_data;
|
||||
SIZE_T region_size = *data;
|
||||
|
||||
remote_addr = InjectLow_AllocMemory(hProcess, region_size
|
||||
, is_wow64 // we copy the detour code into this area, hence executable = TRUE
|
||||
remote_addr = InjectLow_AllocMemory(hProcess, region_size , FALSE
|
||||
#ifdef _M_ARM64
|
||||
//|| use_arm64ec
|
||||
, FALSE
|
||||
#endif
|
||||
);
|
||||
|
@ -1406,10 +1469,7 @@ _FX BOOLEAN SbieDll_InjectLow_CopyData(
|
|||
|
||||
ULONG protect;
|
||||
vm_ok = VirtualProtectEx(hProcess, remote_addr, m_sbielow_len,
|
||||
// we want to be able to pass data from the low level dll we do this here
|
||||
// we set PAGE_EXECUTE_READ in SbieDll.dll Dll_Ordinal1
|
||||
PAGE_EXECUTE_READWRITE, &protect);
|
||||
//PAGE_EXECUTE_READ, &protect);
|
||||
PAGE_EXECUTE_READ, &protect);
|
||||
if (vm_ok) {
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -667,7 +667,7 @@ _FX ULONG64 SbieApi_QueryProcessInfoEx(
|
|||
|
||||
|
||||
_FX LONG SbieApi_QueryBoxPath(
|
||||
const WCHAR *box_name, // WCHAR [34]
|
||||
const WCHAR *box_name, // WCHAR [BOXNAME_COUNT]
|
||||
WCHAR *out_file_path,
|
||||
WCHAR *out_key_path,
|
||||
WCHAR *out_ipc_path,
|
||||
|
@ -828,7 +828,7 @@ _FX LONG SbieApi_QueryPathList(
|
|||
|
||||
|
||||
_FX LONG SbieApi_EnumProcessEx(
|
||||
const WCHAR *box_name, // WCHAR [34]
|
||||
const WCHAR *box_name, // WCHAR [BOXNAME_COUNT]
|
||||
BOOLEAN all_sessions,
|
||||
ULONG which_session, // -1 for current session
|
||||
ULONG *boxed_pids, // ULONG [512]
|
||||
|
@ -1432,7 +1432,7 @@ _FX ULONG SbieApi_QueryConfNumber(
|
|||
|
||||
_FX LONG SbieApi_EnumBoxes(
|
||||
LONG index, // initialize to -1
|
||||
WCHAR *box_name) // WCHAR [34]
|
||||
WCHAR *box_name) // WCHAR [BOXNAME_COUNT]
|
||||
{
|
||||
return SbieApi_EnumBoxesEx(index, box_name, FALSE);
|
||||
}
|
||||
|
@ -1445,7 +1445,7 @@ _FX LONG SbieApi_EnumBoxes(
|
|||
|
||||
_FX LONG SbieApi_EnumBoxesEx(
|
||||
LONG index, // initialize to -1
|
||||
WCHAR *box_name, // WCHAR [34]
|
||||
WCHAR *box_name, // WCHAR [BOXNAME_COUNT]
|
||||
BOOLEAN return_all_sections)
|
||||
{
|
||||
LONG rc;
|
||||
|
@ -1738,7 +1738,7 @@ _FX LONG SbieApi_SessionLeader(HANDLE TokenHandle, HANDLE *ProcessId)
|
|||
|
||||
|
||||
_FX LONG SbieApi_IsBoxEnabled(
|
||||
const WCHAR *box_name) // WCHAR [34]
|
||||
const WCHAR *box_name) // WCHAR [BOXNAME_COUNT]
|
||||
{
|
||||
NTSTATUS status;
|
||||
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
|
||||
|
|
|
@ -105,10 +105,6 @@ _FX int Trace_Init(void)
|
|||
|
||||
|
||||
OutputDebugString(L"SbieDll injected...\n");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (SbieApi_data->DebugData[i] != 0)
|
||||
DbgPrint("DebugData[%d]: %p\n", i, (UINT_PTR)SbieApi_data->DebugData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -711,7 +711,7 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
|
|||
if (pTrapFrame) {
|
||||
ret = pTrapFrame->Rip;
|
||||
UserStack = pTrapFrame->Rsp;
|
||||
pTrapFrame->Rsp = pTrapFrame->Rbp; //*pRbp;
|
||||
pTrapFrame->Rsp = pTrapFrame->Rdi; //*pRbp;
|
||||
pTrapFrame->Rip = pTrapFrame->Rbx; //*pRbx;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -554,7 +554,7 @@ _FX NTSTATUS Syscall_Api_Invoke32(PROCESS* proc, ULONG64* parms)
|
|||
if (pTrapFrame) {
|
||||
ret = pTrapFrame->Rip;
|
||||
UserStack = pTrapFrame->Rsp;
|
||||
pTrapFrame->Rsp = pTrapFrame->Rbp; //*pRbp;
|
||||
pTrapFrame->Rsp = pTrapFrame->Rdi; //*pRbp;
|
||||
pTrapFrame->Rip = pTrapFrame->Rbx; //*pRbx;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,11 +159,6 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="init.c" />
|
||||
<ClCompile Include="inject.c" />
|
||||
<ClCompile Include="lowlevel_code.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|ARM64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="lowdata.h" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;------------------------------------------------------------------------
|
||||
; Copyright 2022 David Xanatos, xanasoft.com
|
||||
; Copyright 2022-2023 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
|
||||
|
@ -19,6 +19,8 @@
|
|||
|
||||
IMPORT EntrypointC
|
||||
|
||||
IMPORT DetourFunc
|
||||
|
||||
;EXPORT ServiceDataPtr
|
||||
EXPORT SystemServiceARM64
|
||||
|
||||
|
@ -251,7 +253,7 @@ DeviceIoControlSvc
|
|||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; RtlFindActivationContextSectionString detour code
|
||||
; detour code loading SbieDll.dll
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -272,103 +274,26 @@ DetourCodeARM64 PROC
|
|||
|
||||
ldr x19, InjectDataPtr ; x19 -> inject data area
|
||||
|
||||
;
|
||||
; reatore RtlFindActCtx, copy 16 bytes
|
||||
;
|
||||
|
||||
add x8, x19, #0x20 ; [x19].InjectData.RtlFindActCtx
|
||||
ldr x9, [x8]
|
||||
ldp w10, w11, [x19, #0x2C] ; [x19].InjectData.RtlFindActCtx_Bytes
|
||||
stp w10, w11, [x9, #0x00]
|
||||
ldp w10, w11, [x19, #0x34] ; [x19].InjectData.RtlFindActCtx_Bytes + 8
|
||||
stp w10, w11, [x9, #0x08]
|
||||
|
||||
ldr x0, =0xFFFFFFFFFFFFFFFF ; ProcessHandle
|
||||
mov x1, x9 ; BaseAddress
|
||||
mov x2, #0x10 ; NumberOfBytesToFlush
|
||||
|
||||
;ldr x8, [x19, 0x70] ; [x19].InjectData.NtFlushInstructionCache
|
||||
ldr x9, [x19] ; [x19].InjectData.SBIELOW_DATA
|
||||
add x8, x9, 0xA0 ; SBIELOW_DATA.NtFlushInstructionCache_code
|
||||
blr x8
|
||||
|
||||
;
|
||||
; call LdrLoadDll for kernel32
|
||||
; call DetourFunc
|
||||
;
|
||||
|
||||
mov x20, #0x10 ; retry count
|
||||
mov x0, x19 ; [x19].InjectData
|
||||
bl DetourFunc
|
||||
|
||||
LdrLoadRetry
|
||||
mov x0, #0x00 ; PathToFile
|
||||
mov x1, #0x00 ; Flags
|
||||
add x2, x19, 0x40 ; [x19].InjectData.KernelDll_Unicode
|
||||
add x3, x19, 0x60 ; [x19].InjectData.ModuleHandle
|
||||
|
||||
ldr x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
blr x8
|
||||
|
||||
cmp x0, #0x00
|
||||
beq LdrLoadGood
|
||||
sub x20, x20, #0x01
|
||||
cmp x20, #0x00
|
||||
bne LdrLoadRetry
|
||||
b RtlFindActivationContextSectionStringError
|
||||
|
||||
LdrLoadGood
|
||||
;
|
||||
; call LdrLoadDll for sbiedll
|
||||
;
|
||||
|
||||
mov x0, #0x00 ; PathToFile
|
||||
mov x1, #0x00 ; Flags
|
||||
add x2, x19, 0x50 ; [x19].InjectData.SbieDll_Unicode
|
||||
add x3, x19, 0x60 ; [x19].InjectData.ModuleHandle
|
||||
|
||||
ldr x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
blr x8
|
||||
cmp x0, #0x00
|
||||
bne RtlFindActivationContextSectionStringError
|
||||
; cmp x0, #0x00
|
||||
; bne DetourError
|
||||
|
||||
;
|
||||
; call the custom MyGetProcedureAddress implemented in c
|
||||
; which calls LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
; this forces ntdll to initialize sbiedll and returns the address to call
|
||||
;
|
||||
; in ARM64EC mode it returns the native function address instead of the FFS sequence
|
||||
; resume execution or original function
|
||||
;
|
||||
|
||||
ldr x0, [x19, 0x60] ; [x19].InjectData.ModuleHandle
|
||||
mov x1, #0x00 ; FunctionName
|
||||
mov x2, #0x01 ; Ordinal
|
||||
add x3, x19, 0x68 ; [x19].InjectData.SbieDllOrdinal1
|
||||
mov x4, x19 ; [x19].InjectData
|
||||
|
||||
;ldr x8, [x19, 0x10] ; [x19].InjectData.LdrGetProcAddr
|
||||
ldr x8, [x19, 0x70] ; [x19].InjectData.MyGetProcAddr
|
||||
blr x8
|
||||
cmp x0, #0x00
|
||||
bne RtlFindActivationContextSectionStringError
|
||||
|
||||
;
|
||||
; pass control to ordinal 1, which will free the inject
|
||||
; data area, and pass control to the original function
|
||||
; RtlFindActivationContextSectionString
|
||||
;
|
||||
; note that we need to pass the address of the inject
|
||||
; data area to ordinal 1, which we do by overwriting the
|
||||
; first argument. the original argument is saved in
|
||||
; the inject data area
|
||||
;
|
||||
|
||||
ldr x8, [sp, #0x00]
|
||||
str x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
mov x0, x19
|
||||
ldr x1, [sp, #0x08]
|
||||
ldp x0, x1, [sp, #0x00]
|
||||
ldp x2, x3, [sp, #0x10]
|
||||
ldp x4, x5, [sp, #0x20]
|
||||
ldp x6, x7, [sp, #0x30]
|
||||
|
||||
ldr x8, [x19, 0x68] ; [x19].InjectData.SbieDllOrdinal1
|
||||
ldr x8, [x19, 0x08] ; [x19].InjectData.RtlFindActCtx
|
||||
|
||||
add sp, sp, #0x40
|
||||
ldp x19, x20, [sp], #0x10
|
||||
|
@ -376,34 +301,170 @@ LdrLoadGood
|
|||
|
||||
br x8
|
||||
|
||||
RtlFindActivationContextSectionStringError
|
||||
|
||||
str x0, [sp, #0x38] ; save ntstatus
|
||||
|
||||
add x8, x19, 0x50 ; [x19].InjectData.SbieDll_Unicode
|
||||
str x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
|
||||
add x5, x19, 0x10 ; out_response - [x19].InjectData.LdrGetProcAddr
|
||||
mov x4, #0x01 ; response_buttons - ERROR_OK
|
||||
mov x3, x8 ; list_of_pointers_to_parameters
|
||||
mov x2, #0x01 ; mask_of_strings_in_list
|
||||
mov x1, #0x01 ; number_of_parameters_in_list
|
||||
ldr x0, =0xD0000142 ; ntstatus_message_code - (STATUS_DLL_INIT_FAILED or FORCE_ERROR_MESSAGE_BOX)
|
||||
|
||||
ldr x8, [x19, 0x18] ; [x19].InjectData.LdrGetProcAddr
|
||||
blr x8
|
||||
|
||||
ldr x0, [sp, #0x38] ; restore ntstatus
|
||||
|
||||
add sp, sp, #0x40
|
||||
ldp x19, x20, [sp], #0x10
|
||||
ldp fp, lr, [sp], #0x10
|
||||
|
||||
ret
|
||||
;DetourError
|
||||
;
|
||||
; add sp, sp, #0x40
|
||||
; ldp x19, x20, [sp], #0x10
|
||||
; ldp fp, lr, [sp], #0x10
|
||||
;
|
||||
; ret
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
;;----------------------------------------------------------------------------
|
||||
;; RtlFindActivationContextSectionString detour code
|
||||
;;----------------------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
;InjectDataPtr
|
||||
; DCQ 0
|
||||
;DetourCodeARM64 PROC
|
||||
;
|
||||
; ;brk #0xF000
|
||||
;
|
||||
; stp fp, lr, [sp, #-0x10]!
|
||||
; stp x19, x20, [sp, #-0x10]!
|
||||
; sub sp, sp, #0x40
|
||||
;
|
||||
; stp x0, x1, [sp, #0x00]
|
||||
; stp x2, x3, [sp, #0x10]
|
||||
; stp x4, x5, [sp, #0x20]
|
||||
; stp x6, x7, [sp, #0x30]
|
||||
;
|
||||
; ldr x19, InjectDataPtr ; x19 -> inject data area
|
||||
;
|
||||
; ;
|
||||
; ; reatore RtlFindActCtx, copy 16 bytes
|
||||
; ;
|
||||
;
|
||||
; add x8, x19, #0x20 ; [x19].InjectData.RtlFindActCtx
|
||||
; ldr x9, [x8]
|
||||
; ldp w10, w11, [x19, #0x2C] ; [x19].InjectData.RtlFindActCtx_Bytes
|
||||
; stp w10, w11, [x9, #0x00]
|
||||
; ldp w10, w11, [x19, #0x34] ; [x19].InjectData.RtlFindActCtx_Bytes + 8
|
||||
; stp w10, w11, [x9, #0x08]
|
||||
;
|
||||
; ldr x0, =0xFFFFFFFFFFFFFFFF ; ProcessHandle
|
||||
; mov x1, x9 ; BaseAddress
|
||||
; mov x2, #0x10 ; NumberOfBytesToFlush
|
||||
;
|
||||
; ;ldr x8, [x19, 0x70] ; [x19].InjectData.NtFlushInstructionCache
|
||||
; ldr x9, [x19] ; [x19].InjectData.SBIELOW_DATA
|
||||
; add x8, x9, 0xA0 ; SBIELOW_DATA.NtFlushInstructionCache_code
|
||||
; blr x8
|
||||
;
|
||||
; ;
|
||||
; ; call LdrLoadDll for kernel32
|
||||
; ;
|
||||
;
|
||||
; mov x20, #0x10 ; retry count
|
||||
;
|
||||
;LdrLoadRetry
|
||||
; mov x0, #0x00 ; PathToFile
|
||||
; mov x1, #0x00 ; Flags
|
||||
; add x2, x19, 0x40 ; [x19].InjectData.KernelDll_Unicode
|
||||
; add x3, x19, 0x60 ; [x19].InjectData.ModuleHandle
|
||||
;
|
||||
; ldr x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
; blr x8
|
||||
;
|
||||
; cmp x0, #0x00
|
||||
; beq LdrLoadGood
|
||||
; sub x20, x20, #0x01
|
||||
; cmp x20, #0x00
|
||||
; bne LdrLoadRetry
|
||||
; b RtlFindActivationContextSectionStringError
|
||||
;
|
||||
;LdrLoadGood
|
||||
; ;
|
||||
; ; call LdrLoadDll for sbiedll
|
||||
; ;
|
||||
;
|
||||
; mov x0, #0x00 ; PathToFile
|
||||
; mov x1, #0x00 ; Flags
|
||||
; add x2, x19, 0x50 ; [x19].InjectData.SbieDll_Unicode
|
||||
; add x3, x19, 0x60 ; [x19].InjectData.ModuleHandle
|
||||
;
|
||||
; ldr x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
; blr x8
|
||||
; cmp x0, #0x00
|
||||
; bne RtlFindActivationContextSectionStringError
|
||||
;
|
||||
; ;
|
||||
; ; call the custom MyGetProcedureAddress implemented in c
|
||||
; ; which calls LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
; ; this forces ntdll to initialize sbiedll and returns the address to call
|
||||
; ;
|
||||
; ; in ARM64EC mode it returns the native function address instead of the FFS sequence
|
||||
; ;
|
||||
;
|
||||
; ldr x0, [x19, 0x60] ; [x19].InjectData.ModuleHandle
|
||||
; mov x1, #0x00 ; FunctionName
|
||||
; mov x2, #0x01 ; Ordinal
|
||||
; add x3, x19, 0x68 ; [x19].InjectData.SbieDllOrdinal1
|
||||
; mov x4, x19 ; [x19].InjectData
|
||||
;
|
||||
; ;ldr x8, [x19, 0x10] ; [x19].InjectData.LdrGetProcAddr
|
||||
; ldr x8, [x19, 0x70] ; [x19].InjectData.MyGetProcAddr
|
||||
; blr x8
|
||||
; cmp x0, #0x00
|
||||
; bne RtlFindActivationContextSectionStringError
|
||||
;
|
||||
; ;
|
||||
; ; pass control to ordinal 1, which will free the inject
|
||||
; ; data area, and pass control to the original function
|
||||
; ; RtlFindActivationContextSectionString
|
||||
; ;
|
||||
; ; note that we need to pass the address of the inject
|
||||
; ; data area to ordinal 1, which we do by overwriting the
|
||||
; ; first argument. the original argument is saved in
|
||||
; ; the inject data area
|
||||
; ;
|
||||
;
|
||||
; ldr x8, [sp, #0x00]
|
||||
; str x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
; mov x0, x19
|
||||
; ldr x1, [sp, #0x08]
|
||||
; ldp x2, x3, [sp, #0x10]
|
||||
; ldp x4, x5, [sp, #0x20]
|
||||
; ldp x6, x7, [sp, #0x30]
|
||||
;
|
||||
; ldr x8, [x19, 0x68] ; [x19].InjectData.SbieDllOrdinal1
|
||||
;
|
||||
; add sp, sp, #0x40
|
||||
; ldp x19, x20, [sp], #0x10
|
||||
; ldp fp, lr, [sp], #0x10
|
||||
;
|
||||
; br x8
|
||||
;
|
||||
;RtlFindActivationContextSectionStringError
|
||||
;
|
||||
; str x0, [sp, #0x38] ; save ntstatus
|
||||
;
|
||||
; add x8, x19, 0x50 ; [x19].InjectData.SbieDll_Unicode
|
||||
; str x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll
|
||||
;
|
||||
; add x5, x19, 0x10 ; out_response - [x19].InjectData.LdrGetProcAddr
|
||||
; mov x4, #0x01 ; response_buttons - ERROR_OK
|
||||
; mov x3, x8 ; list_of_pointers_to_parameters
|
||||
; mov x2, #0x01 ; mask_of_strings_in_list
|
||||
; mov x1, #0x01 ; number_of_parameters_in_list
|
||||
; ldr x0, =0xD0000142 ; ntstatus_message_code - (STATUS_DLL_INIT_FAILED or FORCE_ERROR_MESSAGE_BOX)
|
||||
;
|
||||
; ldr x8, [x19, 0x18] ; [x19].InjectData.LdrGetProcAddr
|
||||
; blr x8
|
||||
;
|
||||
; ldr x0, [sp, #0x38] ; restore ntstatus
|
||||
;
|
||||
; add sp, sp, #0x40
|
||||
; ldp x19, x20, [sp], #0x10
|
||||
; ldp fp, lr, [sp], #0x10
|
||||
;
|
||||
; ret
|
||||
;
|
||||
; ENDP
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Parameters stored by SbieSvc
|
||||
|
@ -433,8 +494,9 @@ SbieLowData
|
|||
|
||||
DCQ Start ; entry point for the detour
|
||||
DCQ SbieLowData ; data location
|
||||
DCQ DetourCodeARM64 ; detour code location
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
END
|
||||
END
|
|
@ -1,6 +1,6 @@
|
|||
;------------------------------------------------------------------------
|
||||
; Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
; Copyright 2021-2022 David Xanatos, xanasoft.com
|
||||
; Copyright 2021-2023 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
|
||||
|
@ -74,16 +74,14 @@ _001: pop rcx
|
|||
; removed hard coded position dependency
|
||||
; key symbols are now passed as arguments to EntrypointC
|
||||
; 64 bit version takes 4 arguments
|
||||
; _EntrypointC(SbieLowData,_RtlFindActivationContextSectionString,_SystemService,_RtlFindActivationContextSectionString64)
|
||||
; _EntrypointC(SbieLowData,_DetourCode,_SystemService)
|
||||
|
||||
mov rbx,rcx
|
||||
add rcx, offset SbieLowData - _001
|
||||
mov rdx,rbx
|
||||
add rdx, offset _RtlFindActivationContextSectionString64 - _001
|
||||
add rdx, offset _DetourCode - _001
|
||||
mov r8,rbx
|
||||
add r8, offset _SystemService - _001
|
||||
;mov r9,rbx
|
||||
;add r9, offset _RtlFindActivationContextSectionString - _001
|
||||
|
||||
call EntrypointC
|
||||
|
||||
|
@ -99,21 +97,24 @@ else ; 32-bit
|
|||
EXTERN _EntrypointC@12 : PROC
|
||||
_Start:
|
||||
call $+5
|
||||
_001: pop eax
|
||||
mov edx,eax
|
||||
_001: pop eax
|
||||
mov edx,eax
|
||||
; removed hard coded position dependency
|
||||
; key symbols are now passed as arguments to EntrypointC
|
||||
; 32 bit version takes 3 arguments
|
||||
;_EntrypointC(SbieLowData,_RtlFindActivationContextSectionString,_SystemService)
|
||||
;_EntrypointC(SbieLowData,_DetourCode,_SystemService)
|
||||
|
||||
add eax, offset _SystemService - _001 ;old + 96 offset
|
||||
push eax
|
||||
mov eax,edx
|
||||
add eax, offset _RtlFindActivationContextSectionString - _001; old + 256 offset
|
||||
add eax, offset _DetourCode - _001; old + 256 offset
|
||||
push eax
|
||||
mov eax, edx
|
||||
add eax, offset SbieLowData - _001
|
||||
push eax
|
||||
|
||||
call _EntrypointC@12
|
||||
|
||||
jmp eax ; jump to LdrInitializeThunk trampoline
|
||||
|
||||
endif ; 32-bit or 64-bit
|
||||
|
@ -126,7 +127,6 @@ endif ; 32-bit or 64-bit
|
|||
|
||||
_SystemService:
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
ifdef _WIN64 ; 64-bit
|
||||
myService Proc
|
||||
db 48h, 0B8h ; rax -> SbieLowData
|
||||
|
@ -141,17 +141,17 @@ myService Proc
|
|||
; because of x64 calling convention.
|
||||
;
|
||||
|
||||
push rbp; target rsp
|
||||
push rdi; target rsp
|
||||
push rbx; target rip
|
||||
|
||||
mov r11,[rax + 0e0h] ; SbieLow.RealNtDeviceIoControlFile
|
||||
add r11b,0fh
|
||||
add r11b,0fh
|
||||
|
||||
mov rbx, r11 ; pass new rip in rbx
|
||||
mov r11, rsp ; restore stack in r11
|
||||
mov rbx, r11 ; pass new rip in rbx
|
||||
mov r11, rsp ; restore stack in r11
|
||||
add r11, 10h
|
||||
|
||||
mov rbp, r11 ; pass stack frame in rbp
|
||||
mov rdi, r11 ; pass stack frame in rbp
|
||||
|
||||
API_NUM_ARGS = 8
|
||||
sub rsp, (API_NUM_ARGS + 1 + 2 + 10) * 8
|
||||
|
@ -225,17 +225,16 @@ myService Proc
|
|||
mov qword ptr [rsp+8*8], rdx
|
||||
mov qword ptr [rsp+9*8], rdx
|
||||
|
||||
lea r10, [r10+80h] ; r10 -> SbieLow.NtDeviceIoControlFile
|
||||
lea r10, [r10+80h] ; r10 -> SbieLow.NtDeviceIoControlFile_code
|
||||
|
||||
call r10
|
||||
add rsp, (API_NUM_ARGS + 1 + 2 + 10) * 8
|
||||
|
||||
pop rbx
|
||||
pop rbp
|
||||
pop rdi
|
||||
ret
|
||||
|
||||
myService ENDP
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
else ; 32-bit
|
||||
|
||||
|
@ -297,7 +296,7 @@ else ; 32-bit
|
|||
push 0
|
||||
push [edx+2*8] ; push SbieLow.api_device_handle
|
||||
|
||||
lea eax, [edx+80h] ; eax -> SbieLow.NtDeviceIoControlFile
|
||||
lea eax, [edx+80h] ; eax -> SbieLow.NtDeviceIoControlFile_code
|
||||
call eax
|
||||
|
||||
;
|
||||
|
@ -316,160 +315,25 @@ else ; 32-bit
|
|||
neg ecx
|
||||
mov ecx, [esp+ecx]
|
||||
jmp ecx ; return to caller
|
||||
|
||||
endif ; 32-bit or 64-bit
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Inject Data Area for our RtlFindActivationContextSectionString
|
||||
; detour code
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
InjectData struct ; keep in sync with inject.c
|
||||
dq ? ; 0x00
|
||||
LdrLoadDll dq ? ; 0x08
|
||||
LdrGetProcAddr dq ? ; 0x10
|
||||
NtRaiseHardError dq ? ; 0x18
|
||||
RtlFindActCtx dq ? ; 0x20
|
||||
RtlFindActCtx_Protect dd ? ; 0x28
|
||||
RtlFindActCtx_Bytes db 20 dup (?) ; 0x2C
|
||||
KernelDll_Unicode dq 2 dup (?) ; 0x40
|
||||
SbieDll_Unicode dq 2 dup (?) ; 0x50
|
||||
ModuleHandle dq ? ; 0x60
|
||||
SbieDllOrdinal1 dq ? ; 0x68
|
||||
sbielow_data dq ? ; 0x00
|
||||
RtlFindActCtx dq ? ; 0x08
|
||||
InjectData ends
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; 32-bit RtlFindActivationContextSectionString detour code
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
_RtlFindActivationContextSectionString:
|
||||
ifndef _WIN64 ; 32-bit
|
||||
|
||||
mov edx, 0 ; edx -> inject data area
|
||||
|
||||
push esi
|
||||
mov esi, edx ; esi -> inject data area
|
||||
|
||||
mov eax, dword ptr [esi].InjectData.RtlFindActCtx
|
||||
mov dl, byte ptr [esi].InjectData.RtlFindActCtx_Bytes
|
||||
mov byte ptr [eax], dl
|
||||
mov edx, dword ptr [esi].InjectData.RtlFindActCtx_Bytes+1
|
||||
mov dword ptr [eax+1], edx
|
||||
|
||||
;
|
||||
; call LdrLoadDll for kernel32
|
||||
;
|
||||
mov ecx, 10h ;number of retries
|
||||
LdrLoadDll_Retry:
|
||||
push ecx
|
||||
lea eax, [esi].InjectData.ModuleHandle
|
||||
push eax
|
||||
lea eax, [esi].InjectData.KernelDll_Unicode
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
call dword ptr [esi].InjectData.LdrLoadDll
|
||||
pop ecx
|
||||
test eax, eax
|
||||
jz LdrLoadDll_Good
|
||||
loop LdrLoadDll_Retry
|
||||
; retry failed 16 times: raise error
|
||||
jmp RtlFindActivationContextSectionStringError
|
||||
LdrLoadDll_Good:
|
||||
;
|
||||
; call LdrLoadDll for sbiedll
|
||||
;
|
||||
|
||||
lea eax, [esi].InjectData.ModuleHandle
|
||||
push eax
|
||||
lea eax, [esi].InjectData.SbieDll_Unicode
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
call dword ptr [esi].InjectData.LdrLoadDll
|
||||
|
||||
test eax, eax
|
||||
jnz RtlFindActivationContextSectionStringError
|
||||
|
||||
;
|
||||
; call LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
; which forces ntdll to initialize sbiedll
|
||||
;
|
||||
|
||||
lea eax, [esi].InjectData.SbieDllOrdinal1
|
||||
push eax
|
||||
push 1
|
||||
push 0
|
||||
push dword ptr [esi].InjectData.ModuleHandle
|
||||
call dword ptr [esi].InjectData.LdrGetProcAddr
|
||||
|
||||
test eax, eax
|
||||
jnz RtlFindActivationContextSectionStringError
|
||||
|
||||
;
|
||||
; pass control to ordinal 1, which will free the inject
|
||||
; data area, and pass control to the original function
|
||||
; RtlFindActivationContextSectionString
|
||||
;
|
||||
; note that we need to pass the address of the inject
|
||||
; data area to ordinal 1, which we do by overwriting the
|
||||
; first argument. the original argument is saved in
|
||||
; the inject data area
|
||||
;
|
||||
|
||||
mov eax, esi
|
||||
xchg eax, dword ptr [esp+4*2]
|
||||
mov dword ptr [esi].InjectData.LdrLoadDll, eax
|
||||
mov eax, esi
|
||||
pop esi
|
||||
jmp dword ptr [eax].InjectData.SbieDllOrdinal1
|
||||
|
||||
;
|
||||
; display error message, invoke NtRaiseHardError(
|
||||
; NTSTATUS ntstatus_message_code,
|
||||
; ULONG number_of_parameters_in_list,
|
||||
; ULONG mask_of_strings_in_list,
|
||||
; ULONG_PTR *list_of_pointers_to_parameters,
|
||||
; ULONG response_buttons,
|
||||
; ULONG *out_response)
|
||||
;
|
||||
|
||||
RtlFindActivationContextSectionStringError:
|
||||
|
||||
STATUS_DLL_INIT_FAILED = 0C0000142h
|
||||
FORCE_ERROR_MESSAGE_BOX = 010000000h
|
||||
|
||||
push eax ; save ntstatus
|
||||
|
||||
lea edx, [esi].InjectData.SbieDll_Unicode
|
||||
mov dword ptr [esi].InjectData.LdrLoadDll, edx
|
||||
|
||||
lea edx, [esi].InjectData.LdrGetProcAddr
|
||||
push edx ; out_response
|
||||
push 1 ; response_buttons - ERROR_OK
|
||||
lea edx, [esi].InjectData.LdrLoadDll
|
||||
push edx ; list_of_pointers_to_parameters
|
||||
push 1 ; mask_of_strings_in_list
|
||||
push 1 ; number_of_parameters_in_list
|
||||
push (STATUS_DLL_INIT_FAILED or FORCE_ERROR_MESSAGE_BOX)
|
||||
call dword ptr [esi].InjectData.NtRaiseHardError
|
||||
|
||||
pop eax ; pop error ntstatus to return
|
||||
pop esi
|
||||
ret 14h ; return to caller with error
|
||||
|
||||
endif ; 32-bit or 64-bit
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; 64-bit RtlFindActivationContextSectionString detour code
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
ifdef _WIN64 ; 64-bit
|
||||
dq 0h ;inject data area address
|
||||
_RtlFindActivationContextSectionString64:
|
||||
|
||||
EXTERN DetourFunc : PROC
|
||||
|
||||
dq 0h ;inject data area address
|
||||
_DetourCode:
|
||||
mov rax, qword ptr [$-8] ; rax -> inject data area
|
||||
|
||||
push rsi ; save rsi, and align stack
|
||||
|
@ -482,134 +346,367 @@ dq 0h ;inject data area address
|
|||
|
||||
mov rsi, rax ; rsi -> inject data area
|
||||
|
||||
mov rax, qword ptr [rsi].InjectData.RtlFindActCtx
|
||||
|
||||
;replace 12bytes
|
||||
mov rdx, qword ptr [rsi].InjectData.RtlFindActCtx_Bytes
|
||||
mov qword ptr [rax], rdx
|
||||
mov edx, dword ptr [rsi].InjectData.RtlFindActCtx_Bytes + 8
|
||||
mov dword ptr [rax+8], edx
|
||||
|
||||
;
|
||||
; call LdrLoadDll for kernel32
|
||||
;
|
||||
;; retry loop
|
||||
mov qword ptr [rsi].InjectData.RtlFindActCtx_Bytes, rbx
|
||||
mov rbx, 010h
|
||||
|
||||
LdrLoadRetry:
|
||||
xor rcx, rcx
|
||||
xor rdx, rdx
|
||||
lea r8, [rsi].InjectData.KernelDll_Unicode
|
||||
lea r9, [rsi].InjectData.ModuleHandle
|
||||
;cmp rbx,1
|
||||
;jnz LdrTestLoop
|
||||
call qword ptr [rsi].InjectData.LdrLoadDll
|
||||
test eax, eax
|
||||
jz LdrLoadGood
|
||||
;LdrTestLoop:
|
||||
dec rbx
|
||||
test rbx, rbx
|
||||
jnz LdrLoadRetry ;loop LdrLoadRetry
|
||||
jmp RtlFindActivationContextSectionStringError
|
||||
LdrLoadGood:
|
||||
mov rbx, qword ptr [rsi].InjectData.RtlFindActCtx_Bytes
|
||||
|
||||
;
|
||||
; call LdrLoadDll for sbiedll
|
||||
; call DetourFunc
|
||||
;
|
||||
|
||||
xor rcx, rcx
|
||||
xor rdx, rdx
|
||||
lea r8, [rsi].InjectData.SbieDll_Unicode
|
||||
lea r9, [rsi].InjectData.ModuleHandle
|
||||
call qword ptr [rsi].InjectData.LdrLoadDll
|
||||
|
||||
test eax, eax
|
||||
jnz RtlFindActivationContextSectionStringError
|
||||
|
||||
;
|
||||
; call LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
; which forces ntdll to initialize sbiedll
|
||||
;
|
||||
|
||||
mov rcx, qword ptr [rsi].InjectData.ModuleHandle
|
||||
mov rcx, rsi
|
||||
xor rdx, rdx
|
||||
xor r8, r8
|
||||
inc r8
|
||||
lea r9, [rsi].InjectData.SbieDllOrdinal1
|
||||
call qword ptr [rsi].InjectData.LdrGetProcAddr
|
||||
xor r9, r9
|
||||
call DetourFunc
|
||||
|
||||
test eax, eax
|
||||
jnz RtlFindActivationContextSectionStringError
|
||||
; test eax, eax
|
||||
; jnz DetourError
|
||||
|
||||
;
|
||||
; pass control to ordinal 1, which will free the inject
|
||||
; data area, and pass control to the original function
|
||||
; RtlFindActivationContextSectionString
|
||||
;
|
||||
; note that we need to pass the address of the inject
|
||||
; data area to ordinal 1, which we do by overwriting the
|
||||
; first argument. the original argument is saved in
|
||||
; the inject data area
|
||||
; resume execution or original function
|
||||
;
|
||||
|
||||
mov rax, qword ptr [rsp+4*8]
|
||||
mov qword ptr [rsi].InjectData.LdrLoadDll, rax
|
||||
mov rcx, rsi
|
||||
mov rcx, qword ptr [rsp+4*8]
|
||||
mov rdx, qword ptr [rsp+5*8]
|
||||
mov r8, qword ptr [rsp+6*8]
|
||||
mov r9, qword ptr [rsp+7*8]
|
||||
|
||||
add rsp, 8*8
|
||||
mov rax, qword ptr [rsi].InjectData.RtlFindActCtx
|
||||
pop rsi
|
||||
jmp qword ptr [rcx].InjectData.SbieDllOrdinal1
|
||||
jmp rax
|
||||
|
||||
;DetourError:
|
||||
;
|
||||
; add rsp, 8*8
|
||||
; pop rsi
|
||||
; ret ; return to caller with error
|
||||
|
||||
else ; 32-bit
|
||||
|
||||
EXTERN _DetourFunc@4 : PROC
|
||||
|
||||
_DetourCode:
|
||||
|
||||
mov edx, 0 ; edx -> inject data area
|
||||
|
||||
push esi
|
||||
mov esi, edx ; esi -> inject data area
|
||||
|
||||
;
|
||||
; display error message, invoke NtRaiseHardError(
|
||||
; NTSTATUS ntstatus_message_code,
|
||||
; ULONG number_of_parameters_in_list,
|
||||
; ULONG mask_of_strings_in_list,
|
||||
; ULONG_PTR *list_of_pointers_to_parameters,
|
||||
; ULONG response_buttons,
|
||||
; ULONG *out_response)
|
||||
; call DetourFunc
|
||||
;
|
||||
|
||||
push esi
|
||||
call _DetourFunc@4
|
||||
|
||||
; test eax, eax
|
||||
; jnz DetourError
|
||||
|
||||
;
|
||||
; resume execution or original function
|
||||
;
|
||||
|
||||
RtlFindActivationContextSectionStringError:
|
||||
|
||||
STATUS_DLL_INIT_FAILED = 0C0000142h
|
||||
FORCE_ERROR_MESSAGE_BOX = 010000000h
|
||||
|
||||
mov qword ptr [rsp+7*8], rax ; save ntstatus
|
||||
|
||||
mov ecx, \ ; ntstatus_message_code
|
||||
(STATUS_DLL_INIT_FAILED or FORCE_ERROR_MESSAGE_BOX)
|
||||
mov eax, dword ptr [esi].InjectData.RtlFindActCtx
|
||||
pop esi
|
||||
jmp eax
|
||||
|
||||
xor rdx, rdx ; number_of_parameters_in_list
|
||||
inc rdx
|
||||
;DetourError:
|
||||
;
|
||||
; pop esi
|
||||
; ret 14h ; return to caller with error
|
||||
|
||||
mov r8, rdx ; mask_of_strings_in_list
|
||||
endif ; 32-bit or 64-bit
|
||||
|
||||
lea r9, \ ; list_of_pointers_to_parameters
|
||||
[esi].InjectData.LdrLoadDll
|
||||
lea rax, [rsi].InjectData.SbieDll_Unicode
|
||||
mov qword ptr [r9], rax
|
||||
|
||||
mov \ ; response_buttons - ERROR_OK
|
||||
qword ptr [rsp+4*8], rdx
|
||||
|
||||
lea rax, [rsi].InjectData.LdrGetProcAddr
|
||||
mov \ ; out_response
|
||||
qword ptr [rsp+5*8], rax
|
||||
|
||||
call qword ptr [rsi].InjectData.NtRaiseHardError
|
||||
|
||||
mov rax, qword ptr [rsp+7*8] ; restore ntstatus
|
||||
add rsp, 8*8
|
||||
pop rsi
|
||||
ret ; return to caller with error
|
||||
|
||||
endif ; 64-bit
|
||||
|
||||
;;----------------------------------------------------------------------------
|
||||
;; Inject Data Area for our RtlFindActivationContextSectionString
|
||||
;;----------------------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
;InjectData struct ; keep in sync with inject.c
|
||||
; dq ? ; 0x00
|
||||
;LdrLoadDll dq ? ; 0x08
|
||||
;LdrGetProcAddr dq ? ; 0x10
|
||||
;NtRaiseHardError dq ? ; 0x18
|
||||
;RtlFindActCtx dq ? ; 0x20
|
||||
;RtlFindActCtx_Protect dd ? ; 0x28
|
||||
;RtlFindActCtx_Bytes db 20 dup (?) ; 0x2C
|
||||
;KernelDll_Unicode dq 2 dup (?) ; 0x40
|
||||
;SbieDll_Unicode dq 2 dup (?) ; 0x50
|
||||
;ModuleHandle dq ? ; 0x60
|
||||
;SbieDllOrdinal1 dq ? ; 0x68
|
||||
;InjectData ends
|
||||
;
|
||||
;
|
||||
;;----------------------------------------------------------------------------
|
||||
;; 32-bit RtlFindActivationContextSectionString detour code
|
||||
;;----------------------------------------------------------------------------
|
||||
;
|
||||
;_RtlFindActivationContextSectionString:
|
||||
;ifndef _WIN64 ; 32-bit
|
||||
;
|
||||
; mov edx, 0 ; edx -> inject data area
|
||||
;
|
||||
; push esi
|
||||
; mov esi, edx ; esi -> inject data area
|
||||
;
|
||||
; mov eax, dword ptr [esi].InjectData.RtlFindActCtx
|
||||
; mov dl, byte ptr [esi].InjectData.RtlFindActCtx_Bytes
|
||||
; mov byte ptr [eax], dl
|
||||
; mov edx, dword ptr [esi].InjectData.RtlFindActCtx_Bytes+1
|
||||
; mov dword ptr [eax+1], edx
|
||||
;
|
||||
; ;
|
||||
; ; call LdrLoadDll for kernel32
|
||||
; ;
|
||||
; mov ecx, 10h ;number of retries
|
||||
;LdrLoadDll_Retry:
|
||||
; push ecx
|
||||
; lea eax, [esi].InjectData.ModuleHandle
|
||||
; push eax
|
||||
; lea eax, [esi].InjectData.KernelDll_Unicode
|
||||
; push eax
|
||||
; push 0
|
||||
; push 0
|
||||
; call dword ptr [esi].InjectData.LdrLoadDll
|
||||
; pop ecx
|
||||
; test eax, eax
|
||||
; jz LdrLoadDll_Good
|
||||
; loop LdrLoadDll_Retry
|
||||
; ; retry failed 16 times: raise error
|
||||
; jmp RtlFindActivationContextSectionStringError
|
||||
;LdrLoadDll_Good:
|
||||
; ;
|
||||
; ; call LdrLoadDll for sbiedll
|
||||
; ;
|
||||
;
|
||||
; lea eax, [esi].InjectData.ModuleHandle
|
||||
; push eax
|
||||
; lea eax, [esi].InjectData.SbieDll_Unicode
|
||||
; push eax
|
||||
; push 0
|
||||
; push 0
|
||||
; call dword ptr [esi].InjectData.LdrLoadDll
|
||||
;
|
||||
; test eax, eax
|
||||
; jnz RtlFindActivationContextSectionStringError
|
||||
;
|
||||
; ;
|
||||
; ; call LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
; ; which forces ntdll to initialize sbiedll
|
||||
; ;
|
||||
;
|
||||
; lea eax, [esi].InjectData.SbieDllOrdinal1
|
||||
; push eax
|
||||
; push 1
|
||||
; push 0
|
||||
; push dword ptr [esi].InjectData.ModuleHandle
|
||||
; call dword ptr [esi].InjectData.LdrGetProcAddr
|
||||
;
|
||||
; test eax, eax
|
||||
; jnz RtlFindActivationContextSectionStringError
|
||||
;
|
||||
; ;
|
||||
; ; pass control to ordinal 1, which will free the inject
|
||||
; ; data area, and pass control to the original function
|
||||
; ; RtlFindActivationContextSectionString
|
||||
; ;
|
||||
; ; note that we need to pass the address of the inject
|
||||
; ; data area to ordinal 1, which we do by overwriting the
|
||||
; ; first argument. the original argument is saved in
|
||||
; ; the inject data area
|
||||
; ;
|
||||
;
|
||||
; mov eax, esi
|
||||
; xchg eax, dword ptr [esp+4*2]
|
||||
; mov dword ptr [esi].InjectData.LdrLoadDll, eax
|
||||
; mov eax, esi
|
||||
; pop esi
|
||||
; jmp dword ptr [eax].InjectData.SbieDllOrdinal1
|
||||
;
|
||||
; ;
|
||||
; ; display error message, invoke NtRaiseHardError(
|
||||
; ; NTSTATUS ntstatus_message_code,
|
||||
; ; ULONG number_of_parameters_in_list,
|
||||
; ; ULONG mask_of_strings_in_list,
|
||||
; ; ULONG_PTR *list_of_pointers_to_parameters,
|
||||
; ; ULONG response_buttons,
|
||||
; ; ULONG *out_response)
|
||||
; ;
|
||||
;
|
||||
;RtlFindActivationContextSectionStringError:
|
||||
;
|
||||
; STATUS_DLL_INIT_FAILED = 0C0000142h
|
||||
; FORCE_ERROR_MESSAGE_BOX = 010000000h
|
||||
;
|
||||
; push eax ; save ntstatus
|
||||
;
|
||||
; lea edx, [esi].InjectData.SbieDll_Unicode
|
||||
; mov dword ptr [esi].InjectData.LdrLoadDll, edx
|
||||
;
|
||||
; lea edx, [esi].InjectData.LdrGetProcAddr
|
||||
; push edx ; out_response
|
||||
; push 1 ; response_buttons - ERROR_OK
|
||||
; lea edx, [esi].InjectData.LdrLoadDll
|
||||
; push edx ; list_of_pointers_to_parameters
|
||||
; push 1 ; mask_of_strings_in_list
|
||||
; push 1 ; number_of_parameters_in_list
|
||||
; push (STATUS_DLL_INIT_FAILED or FORCE_ERROR_MESSAGE_BOX)
|
||||
; call dword ptr [esi].InjectData.NtRaiseHardError
|
||||
;
|
||||
; pop eax ; pop error ntstatus to return
|
||||
; pop esi
|
||||
; ret 14h ; return to caller with error
|
||||
;
|
||||
;endif ; 32-bit or 64-bit
|
||||
;
|
||||
;
|
||||
;;----------------------------------------------------------------------------
|
||||
;; 64-bit RtlFindActivationContextSectionString detour code
|
||||
;;----------------------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
;ifdef _WIN64 ; 64-bit
|
||||
;dq 0h ;inject data area address
|
||||
; _RtlFindActivationContextSectionString64:
|
||||
; mov rax, qword ptr [$-8] ; rax -> inject data area
|
||||
;
|
||||
; push rsi ; save rsi, and align stack
|
||||
; sub rsp, 8*8 ; set up local stack
|
||||
;
|
||||
; mov qword ptr [rsp+4*8], rcx
|
||||
; mov qword ptr [rsp+5*8], rdx
|
||||
; mov qword ptr [rsp+6*8], r8
|
||||
; mov qword ptr [rsp+7*8], r9
|
||||
;
|
||||
; mov rsi, rax ; rsi -> inject data area
|
||||
;
|
||||
; mov rax, qword ptr [rsi].InjectData.RtlFindActCtx
|
||||
;
|
||||
; ;replace 12bytes
|
||||
; mov rdx, qword ptr [rsi].InjectData.RtlFindActCtx_Bytes
|
||||
; mov qword ptr [rax], rdx
|
||||
; mov edx, dword ptr [rsi].InjectData.RtlFindActCtx_Bytes + 8
|
||||
; mov dword ptr [rax+8], edx
|
||||
;
|
||||
; ;
|
||||
; ; call LdrLoadDll for kernel32
|
||||
; ;
|
||||
; ;; retry loop
|
||||
; mov qword ptr [rsi].InjectData.RtlFindActCtx_Bytes, rbx
|
||||
; mov rbx, 010h
|
||||
;
|
||||
;LdrLoadRetry:
|
||||
; xor rcx, rcx
|
||||
; xor rdx, rdx
|
||||
; lea r8, [rsi].InjectData.KernelDll_Unicode
|
||||
; lea r9, [rsi].InjectData.ModuleHandle
|
||||
; ;cmp rbx,1
|
||||
; ;jnz LdrTestLoop
|
||||
; call qword ptr [rsi].InjectData.LdrLoadDll
|
||||
; test eax, eax
|
||||
; jz LdrLoadGood
|
||||
;;LdrTestLoop:
|
||||
; dec rbx
|
||||
; test rbx, rbx
|
||||
; jnz LdrLoadRetry ;loop LdrLoadRetry
|
||||
; jmp RtlFindActivationContextSectionStringError
|
||||
;LdrLoadGood:
|
||||
; mov rbx, qword ptr [rsi].InjectData.RtlFindActCtx_Bytes
|
||||
;
|
||||
; ;
|
||||
; ; call LdrLoadDll for sbiedll
|
||||
; ;
|
||||
;
|
||||
; xor rcx, rcx
|
||||
; xor rdx, rdx
|
||||
; lea r8, [rsi].InjectData.SbieDll_Unicode
|
||||
; lea r9, [rsi].InjectData.ModuleHandle
|
||||
; call qword ptr [rsi].InjectData.LdrLoadDll
|
||||
;
|
||||
; test eax, eax
|
||||
; jnz RtlFindActivationContextSectionStringError
|
||||
;
|
||||
; ;
|
||||
; ; call LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
; ; which forces ntdll to initialize sbiedll
|
||||
; ;
|
||||
;
|
||||
; mov rcx, qword ptr [rsi].InjectData.ModuleHandle
|
||||
; xor rdx, rdx
|
||||
; xor r8, r8
|
||||
; inc r8
|
||||
; lea r9, [rsi].InjectData.SbieDllOrdinal1
|
||||
; call qword ptr [rsi].InjectData.LdrGetProcAddr
|
||||
;
|
||||
; test eax, eax
|
||||
; jnz RtlFindActivationContextSectionStringError
|
||||
;
|
||||
; ;
|
||||
; ; pass control to ordinal 1, which will free the inject
|
||||
; ; data area, and pass control to the original function
|
||||
; ; RtlFindActivationContextSectionString
|
||||
; ;
|
||||
; ; note that we need to pass the address of the inject
|
||||
; ; data area to ordinal 1, which we do by overwriting the
|
||||
; ; first argument. the original argument is saved in
|
||||
; ; the inject data area
|
||||
; ;
|
||||
;
|
||||
; mov rax, qword ptr [rsp+4*8]
|
||||
; mov qword ptr [rsi].InjectData.LdrLoadDll, rax
|
||||
; mov rcx, rsi
|
||||
; mov rdx, qword ptr [rsp+5*8]
|
||||
; mov r8, qword ptr [rsp+6*8]
|
||||
; mov r9, qword ptr [rsp+7*8]
|
||||
;
|
||||
; add rsp, 8*8
|
||||
; pop rsi
|
||||
; jmp qword ptr [rcx].InjectData.SbieDllOrdinal1
|
||||
;
|
||||
; ;
|
||||
; ; display error message, invoke NtRaiseHardError(
|
||||
; ; NTSTATUS ntstatus_message_code,
|
||||
; ; ULONG number_of_parameters_in_list,
|
||||
; ; ULONG mask_of_strings_in_list,
|
||||
; ; ULONG_PTR *list_of_pointers_to_parameters,
|
||||
; ; ULONG response_buttons,
|
||||
; ; ULONG *out_response)
|
||||
; ;
|
||||
;
|
||||
;RtlFindActivationContextSectionStringError:
|
||||
;
|
||||
; STATUS_DLL_INIT_FAILED = 0C0000142h
|
||||
; FORCE_ERROR_MESSAGE_BOX = 010000000h
|
||||
;
|
||||
; mov qword ptr [rsp+7*8], rax ; save ntstatus
|
||||
;
|
||||
; mov ecx, \ ; ntstatus_message_code
|
||||
; (STATUS_DLL_INIT_FAILED or FORCE_ERROR_MESSAGE_BOX)
|
||||
;
|
||||
; xor rdx, rdx ; number_of_parameters_in_list
|
||||
; inc rdx
|
||||
;
|
||||
; mov r8, rdx ; mask_of_strings_in_list
|
||||
;
|
||||
; lea r9, \ ; list_of_pointers_to_parameters
|
||||
; [esi].InjectData.LdrLoadDll
|
||||
; lea rax, [rsi].InjectData.SbieDll_Unicode
|
||||
; mov qword ptr [r9], rax
|
||||
;
|
||||
; mov \ ; response_buttons - ERROR_OK
|
||||
; qword ptr [rsp+4*8], rdx
|
||||
;
|
||||
; lea rax, [rsi].InjectData.LdrGetProcAddr
|
||||
; mov \ ; out_response
|
||||
; qword ptr [rsp+5*8], rax
|
||||
;
|
||||
; call qword ptr [rsi].InjectData.NtRaiseHardError
|
||||
;
|
||||
; mov rax, qword ptr [rsp+7*8] ; restore ntstatus
|
||||
; add rsp, 8*8
|
||||
; pop rsi
|
||||
; ret ; return to caller with error
|
||||
;
|
||||
;endif ; 64-bit
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
@ -631,6 +728,7 @@ SbieLowData LABEL QWORD
|
|||
|
||||
dq _Start
|
||||
dq SbieLowData
|
||||
dq _DetourCode
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
end
|
||||
|
|
|
@ -148,11 +148,11 @@ _FX NTSTATUS SbieApi_Ioctl(SBIELOW_DATA *data, void *parms)
|
|||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// SbieApi_DebugPrint
|
||||
// SbieApi_LogMsg
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS SbieApi_DebugPrint(SBIELOW_DATA *data, const WCHAR *text)
|
||||
_FX NTSTATUS SbieApi_LogMsg(ULONG64 pNtDeviceIoControlFile, ULONG64 api_device_handle, ULONG code, const WCHAR *text)
|
||||
{
|
||||
NTSTATUS status = 0;
|
||||
__declspec(align(8)) UNICODE_STRING64 msgtext;
|
||||
|
@ -170,9 +170,18 @@ _FX NTSTATUS SbieApi_DebugPrint(SBIELOW_DATA *data, const WCHAR *text)
|
|||
memzero(parms, sizeof(parms));
|
||||
args->func_code = API_LOG_MESSAGE;
|
||||
args->session_id.val = -1;
|
||||
args->msgid.val = 1122;
|
||||
args->msgid.val = code;
|
||||
args->msgtext.val = &msgtext;
|
||||
status = SbieApi_Ioctl(data, parms);
|
||||
//status = SbieApi_Ioctl(data, parms);
|
||||
|
||||
IO_STATUS_BLOCK MyIoStatusBlock;
|
||||
#ifdef _WIN64
|
||||
ULONG MyIoStatusBlock32[2];
|
||||
*(ULONG_PTR *)&MyIoStatusBlock = (ULONG_PTR)MyIoStatusBlock32;
|
||||
#endif _WIN64
|
||||
return ((P_NtDeviceIoControlFile)pNtDeviceIoControlFile)(
|
||||
(HANDLE)api_device_handle, NULL, NULL, NULL, &MyIoStatusBlock,
|
||||
API_SBIEDRV_CTLCODE, parms, sizeof(ULONG64) * 8, NULL, 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -196,7 +205,7 @@ _FX NTSTATUS SbieApi_DebugError(SBIELOW_DATA* data, ULONG error)
|
|||
for(int i=28; i >= 0; i-=4)
|
||||
*ptr++ = table[(error >> i) & 0xF];
|
||||
|
||||
return SbieApi_DebugPrint(data, text);
|
||||
return SbieApi_LogMsg(data->NtDeviceIoControlFile, data->api_device_handle, 2180, text);
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,9 +232,42 @@ _FX void WaitForDebugger(SBIELOW_DATA *data)
|
|||
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WriteMemorySafe
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void WriteMemorySafe(SBIELOW_DATA* data, void *Address, SIZE_T Size, void *Data)
|
||||
{
|
||||
void *RegionBase = Address;
|
||||
SIZE_T RegionSize = Size;
|
||||
ULONG OldProtect;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
|
||||
// memcopy is not available, lets do our own
|
||||
switch (Size) {
|
||||
case 1: *(UCHAR*)Address = *(UCHAR*)Data; break;
|
||||
case 2: *(USHORT*)Address = *(USHORT*)Data; break;
|
||||
case 4: *(ULONG*)Address = *(ULONG*)Data; break;
|
||||
case 8: *(ULONG64*)Address = *(ULONG64*)Data; break;
|
||||
default:
|
||||
for (SIZE_T i = 0; i < Size; i++)
|
||||
((UCHAR*)Address)[i] = ((UCHAR*)Data)[i];
|
||||
}
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// PrepSyscalls
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -233,11 +275,6 @@ _FX void WaitForDebugger(SBIELOW_DATA *data)
|
|||
|
||||
_FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
|
||||
{
|
||||
UCHAR *SystemServiceAsm;
|
||||
void *RegionBase;
|
||||
SIZE_T RegionSize;
|
||||
ULONG OldProtect;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
if (data->flags.is_arm64ec) {
|
||||
|
||||
|
@ -248,7 +285,8 @@ _FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
|
|||
// a replica of the #NtDeviceIoControlFile EC variant
|
||||
//
|
||||
|
||||
data->NtDeviceIoControlFile = (ULONG64)&NtDeviceIoControlFileEC;
|
||||
ULONG64 pNtDeviceIoControlFileEC = (ULONG64)&NtDeviceIoControlFileEC;
|
||||
WriteMemorySafe(data, &data->NtDeviceIoControlFile, sizeof(ULONG64), &pNtDeviceIoControlFileEC);
|
||||
|
||||
|
||||
//
|
||||
|
@ -260,9 +298,9 @@ _FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
|
|||
// we can just copy the ULONG strait out of the native function
|
||||
//
|
||||
|
||||
DeviceIoControlSvc = *(ULONG*)&data->NtDeviceIoControlFile_code[0];
|
||||
WriteMemorySafe(data, &DeviceIoControlSvc, sizeof(ULONG), &data->NtDeviceIoControlFile_code[0]);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// get the EcExitThunkPtr which points to
|
||||
// __os_arm64x_dispatch_call_no_redirect
|
||||
|
@ -275,11 +313,15 @@ _FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
|
|||
|
||||
ULONG* syscall_ec_data = (ULONG*)data->syscall_data;
|
||||
|
||||
EcExitThunkPtr = *(ULONG64*)((UINT_PTR)syscall_ec_data + syscall_ec_data[1] - 8);
|
||||
UINT_PTR pEcExitThunkPtr = *(UINT_PTR*)((UINT_PTR)syscall_ec_data + syscall_ec_data[1] - 8);
|
||||
WriteMemorySafe(data, &EcExitThunkPtr, sizeof(UINT_PTR), &pEcExitThunkPtr);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
data->NtDeviceIoControlFile = (ULONG64)&data->NtDeviceIoControlFile_code[0];
|
||||
{
|
||||
ULONG64 pNtDeviceIoControlFile = (ULONG64)&data->NtDeviceIoControlFile_code[0];
|
||||
WriteMemorySafe(data, &data->NtDeviceIoControlFile, sizeof(ULONG64), &pNtDeviceIoControlFile);
|
||||
}
|
||||
|
||||
const LONG OFFSET_ULONG_PTR =
|
||||
#ifdef _M_ARM64
|
||||
|
@ -295,21 +337,14 @@ _FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
|
|||
// to include the data area pointer
|
||||
//
|
||||
|
||||
SystemServiceAsm = (UCHAR *)SystemService;
|
||||
RegionBase = (void *)(SystemServiceAsm + OFFSET_ULONG_PTR);
|
||||
RegionSize = sizeof(ULONG_PTR);
|
||||
WriteMemorySafe(data, ((UCHAR *)SystemService) + OFFSET_ULONG_PTR, sizeof(ULONG_PTR), &data);
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
//
|
||||
// store the SystemService address in pSystemService
|
||||
//
|
||||
|
||||
*(ULONG_PTR *)(SystemServiceAsm + OFFSET_ULONG_PTR) = (ULONG_PTR)data;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
|
||||
data->pSystemService = (ULONG64)SystemServiceAsm;
|
||||
ULONG64 SystemServicePtr = (ULONG64)SystemService;
|
||||
WriteMemorySafe(data, &data->pSystemService, sizeof(ULONG64), &SystemServicePtr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -597,33 +632,29 @@ _FX void DisableCHPE(SBIELOW_DATA* data)
|
|||
if (!RtlImageOptionsEx)
|
||||
return;
|
||||
|
||||
//
|
||||
// backup bytes for trampoline
|
||||
//
|
||||
|
||||
ULONG DetourSize = 28;
|
||||
memcpy(data->RtlImageOptionsEx_tramp, RtlImageOptionsEx, DetourSize);
|
||||
|
||||
//
|
||||
// make target writable & create detour
|
||||
//
|
||||
|
||||
void *RegionBase;
|
||||
SIZE_T RegionSize;
|
||||
ULONG OldProtect;
|
||||
ULONG* aCode;
|
||||
|
||||
RegionBase = (void*)RtlImageOptionsEx;
|
||||
RegionSize = DetourSize; // 16;
|
||||
//
|
||||
// backup target & create simple trampoline
|
||||
//
|
||||
|
||||
RegionBase = (void*)data->RtlImageOptionsEx_tramp;
|
||||
RegionSize = sizeof(data->RtlImageOptionsEx_tramp);
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
|
||||
ULONG* aCode = (ULONG*)RtlImageOptionsEx;
|
||||
aCode[0] = 0x580000a7; // ldr x7, 20 - data
|
||||
aCode[1] = 0x58000048; // ldr x8, 8 - MyImageOptionsEx
|
||||
aCode[2] = 0xD61F0100; // br x8
|
||||
*(DWORD64*)&aCode[3] = (DWORD64)MyImageOptionsEx;
|
||||
*(DWORD64*)&aCode[5] = (DWORD64)data;
|
||||
ULONG DetourSize = 28;
|
||||
memcpy(data->RtlImageOptionsEx_tramp, RtlImageOptionsEx, DetourSize);
|
||||
|
||||
aCode = (ULONG*)(data->RtlImageOptionsEx_tramp + DetourSize); // 28
|
||||
aCode[0] = 0x58000048; // ldr x8, 8 - Rest of RtlImageOptionsEx
|
||||
aCode[1] = 0xD61F0100; // br x8
|
||||
*(DWORD64*)&aCode[2] = (DWORD64)RtlImageOptionsEx + DetourSize;
|
||||
// 44
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
|
@ -633,13 +664,29 @@ _FX void DisableCHPE(SBIELOW_DATA* data)
|
|||
NtCurrentProcess(), RegionBase, (ULONG)RegionSize);
|
||||
|
||||
//
|
||||
// create simple trampoline
|
||||
// make target writable & create detour
|
||||
//
|
||||
|
||||
aCode = (ULONG*)(data->RtlImageOptionsEx_tramp + DetourSize);
|
||||
aCode[0] = 0x58000048; // ldr x8, 8 - Rest of RtlImageOptionsEx
|
||||
aCode[1] = 0xD61F0100; // br x8
|
||||
*(DWORD64*)&aCode[2] = (DWORD64)RtlImageOptionsEx + DetourSize;
|
||||
RegionBase = (void*)RtlImageOptionsEx;
|
||||
RegionSize = DetourSize;
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
|
||||
aCode = (ULONG*)RtlImageOptionsEx;
|
||||
aCode[0] = 0x580000a7; // ldr x7, 20 - data
|
||||
aCode[1] = 0x58000048; // ldr x8, 8 - MyImageOptionsEx
|
||||
aCode[2] = 0xD61F0100; // br x8
|
||||
*(DWORD64*)&aCode[3] = (DWORD64)MyImageOptionsEx;
|
||||
*(DWORD64*)&aCode[5] = (DWORD64)data;
|
||||
//28
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
|
||||
SBIELOW_CALL(NtFlushInstructionCache)(
|
||||
NtCurrentProcess(), RegionBase, (ULONG)RegionSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -745,7 +792,7 @@ ULONG_PTR EntrypointC(SBIELOW_DATA *data, void *DetourCode, void *SystemService)
|
|||
// WaitForDebugger(data);
|
||||
|
||||
//wchar_t text[] = { 't','e','s','t',0 };
|
||||
//SbieApi_DebugPrint(data, text);
|
||||
//SbieApi_LogMsg(data->NtDeviceIoControlFile, data->api_device_handle, 1122, text);
|
||||
|
||||
PrepSyscalls(data, SystemService);
|
||||
if (!data->flags.bHostInject && !data->flags.bNoSysHooks)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 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
|
||||
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Functions
|
||||
// inject
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <ntstatus.h>
|
||||
|
@ -28,12 +28,13 @@ typedef long NTSTATUS;
|
|||
#include "common/win32_ntddk.h"
|
||||
#include "common/defines.h"
|
||||
#include "lowdata.h"
|
||||
|
||||
#include "core/drv/api_defs.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
_FX NTSTATUS SbieApi_LogMsg(ULONG64 pNtDeviceIoControlFile, ULONG64 api_device_handle, ULONG code, const WCHAR* text);
|
||||
_FX NTSTATUS SbieApi_DebugError(SBIELOW_DATA* data, ULONG error);
|
||||
|
||||
UCHAR *FindDllExport(void *DllBase, const UCHAR *ProcName, ULONG *pErr);
|
||||
|
@ -45,10 +46,27 @@ static UCHAR *FindDllExport2(
|
|||
void* Hook_GetFFSTarget(UCHAR* SourceFunc);
|
||||
#endif
|
||||
|
||||
static void InitInjectWow64(SBIELOW_DATA *data);
|
||||
//static void InitInjectWow64(SBIELOW_DATA *data);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
typedef NTSTATUS(*P_LdrLoadDll)(
|
||||
WCHAR *PathString, ULONG *DllFlags,
|
||||
UNICODE_STRING *ModuleName, HANDLE *ModuleHandle);
|
||||
|
||||
typedef NTSTATUS (*P_LdrGetProcedureAddress)(
|
||||
HANDLE ModuleHandle, ANSI_STRING *ProcName, ULONG ProcNum,
|
||||
ULONG_PTR *Address);
|
||||
|
||||
typedef NTSTATUS (*P_NtProtectVirtualMemory)(
|
||||
HANDLE ProcessHandle, PVOID *BaseAddress,
|
||||
PSIZE_T RegionSize, ULONG NewProtect, PULONG OldProtect);
|
||||
|
||||
typedef NTSTATUS (*P_NtRaiseHardError)(
|
||||
NTSTATUS ErrorStatus, ULONG NumberOfParameters, ULONG UnicodeBitMask,
|
||||
ULONG_PTR *Parameters, ULONG ErrorOption, ULONG *ErrorReturn);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define SBIELOW_CALL(x) ((P_##x)&data->x##_code)
|
||||
|
||||
|
@ -176,34 +194,135 @@ _FX UCHAR *FindDllExport2(
|
|||
return proc;
|
||||
}
|
||||
|
||||
#ifdef _M_ARM64
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// MyGetProcedureAddress
|
||||
// DetourFunc
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS MyGetProcedureAddress(HMODULE ModuleHandle, PANSI_STRING FunctionName, WORD Ordinal, PVOID*FunctionAddress, INJECT_DATA *inject)
|
||||
ULONG_PTR DetourFunc(INJECT_DATA *inject)
|
||||
{
|
||||
SBIELOW_DATA* data = (SBIELOW_DATA*)*(ULONG64*)inject;
|
||||
|
||||
typedef (*P_LdrGetProcedureAddress)(HMODULE, PANSI_STRING, WORD, PVOID*);
|
||||
NTSTATUS status = ((P_LdrGetProcedureAddress)inject->LdrGetProcAddr)(ModuleHandle, FunctionName, Ordinal, FunctionAddress);
|
||||
|
||||
//
|
||||
// in ARM64EC mode unwrap the FFS and return the native function
|
||||
// Note: this function is invoked from the detour code hence when running in WoW64
|
||||
// the used instance of this function will be from the 32 bit version
|
||||
// in which case we are unable to use SBIELOW_CALL and need to have a
|
||||
// pointer to the apropriate 32 bit function
|
||||
//
|
||||
// Further more on ARM64 the SBIELOW_DATA will be allocated past the 4 GB boundry
|
||||
// hence in 32 bit mode we can not access it, only INJECT_DATA is available
|
||||
//
|
||||
|
||||
if (data->flags.is_arm64ec && status >= 0) {
|
||||
*FunctionAddress = Hook_GetFFSTarget(*FunctionAddress);
|
||||
if (!*FunctionAddress)
|
||||
return STATUS_ENTRYPOINT_NOT_FOUND;
|
||||
NTSTATUS status;
|
||||
UNICODE_STRING* pDllPath;
|
||||
HANDLE ModuleHandle;
|
||||
typedef VOID(*P_Dll_Ordinal1)(INJECT_DATA* inject);
|
||||
P_Dll_Ordinal1 SbieDllOrdinal1;
|
||||
void *RegionBase;
|
||||
SIZE_T RegionSize;
|
||||
ULONG OldProtect;
|
||||
|
||||
#ifdef _WIN64
|
||||
SBIELOW_DATA* data = (SBIELOW_DATA*)inject->sbielow_data;
|
||||
#endif
|
||||
|
||||
//
|
||||
// restore original function
|
||||
//
|
||||
|
||||
RegionBase = (void*)inject->RtlFindActCtx;
|
||||
#ifdef _WIN64
|
||||
#ifdef _M_ARM64
|
||||
RegionSize = 16;
|
||||
memcpy((void*)inject->RtlFindActCtx, inject->RtlFindActCtx_Bytes, 16);
|
||||
|
||||
SBIELOW_CALL(NtFlushInstructionCache)(
|
||||
NtCurrentProcess(), (void*)inject->RtlFindActCtx, 16);
|
||||
#else
|
||||
RegionSize = 12;
|
||||
memcpy((void*)inject->RtlFindActCtx, inject->RtlFindActCtx_Bytes, 12);
|
||||
#endif
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
inject->RtlFindActCtx_Protect, &OldProtect);
|
||||
#else
|
||||
RegionSize = 5;
|
||||
memcpy((void*)inject->RtlFindActCtx, inject->RtlFindActCtx_Bytes, 5);
|
||||
|
||||
((P_NtProtectVirtualMemory)inject->NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
inject->RtlFindActCtx_Protect, &OldProtect);
|
||||
#endif
|
||||
|
||||
//
|
||||
// load kernel32.dll
|
||||
//
|
||||
|
||||
pDllPath = (UNICODE_STRING*)&inject->KernelDll;
|
||||
|
||||
status = ((P_LdrLoadDll)inject->LdrLoadDll)(NULL, 0, pDllPath, &ModuleHandle);
|
||||
|
||||
//
|
||||
// load sbiedll.dll
|
||||
//
|
||||
|
||||
if (status == 0) {
|
||||
|
||||
pDllPath = (UNICODE_STRING*)&inject->SbieDll;
|
||||
|
||||
status = ((P_LdrLoadDll)inject->LdrLoadDll)(NULL, 0, pDllPath, &ModuleHandle);
|
||||
}
|
||||
|
||||
//
|
||||
// get ordinal 1 from sbiedll
|
||||
//
|
||||
|
||||
if (status == 0) {
|
||||
|
||||
status = ((P_LdrGetProcedureAddress)inject->LdrGetProcAddr)(ModuleHandle, NULL, 1, (ULONG_PTR*)&SbieDllOrdinal1);
|
||||
#ifdef _M_ARM64
|
||||
//
|
||||
// on ARM64EC we hook the native code hence we need to obtain the address of the native erdinal 1 from our SbieDll.dll
|
||||
// instead of the FFS sequence as given by NtGetProcedureAddress when in ARM64EC mode
|
||||
//
|
||||
|
||||
if (data->flags.is_arm64ec && status >= 0) {
|
||||
SbieDllOrdinal1 = (P_Dll_Ordinal1)Hook_GetFFSTarget((UCHAR*)SbieDllOrdinal1);
|
||||
//if (!SbieDllOrdinal1)
|
||||
// status = STATUS_ENTRYPOINT_NOT_FOUND;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// call ordinal 1 of sbiedll.dll
|
||||
//
|
||||
|
||||
if (status == 0) {
|
||||
|
||||
SbieDllOrdinal1(inject);
|
||||
}
|
||||
|
||||
//
|
||||
// or report error if one occured instead
|
||||
//
|
||||
|
||||
else {
|
||||
|
||||
wchar_t text[] = { 0 };
|
||||
SbieApi_LogMsg(inject->NtDeviceIoControlFile, inject->api_device_handle, 2181, text);
|
||||
|
||||
status = 0xC0000142; // = STATUS_DLL_INIT_FAILED
|
||||
ULONG_PTR Parameters[1] = { (ULONG_PTR)pDllPath };
|
||||
ULONG ErrorReturn;
|
||||
((P_NtRaiseHardError)inject->NtRaiseHardError)(
|
||||
status | 0x10000000, // | FORCE_ERROR_MESSAGE_BOX
|
||||
1, 1, Parameters, 1, &ErrorReturn);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// InitInject
|
||||
|
@ -216,7 +335,7 @@ _FX void InitInject(SBIELOW_DATA *data, void *DetourCode)
|
|||
SYSCALL_DATA* syscall_data;
|
||||
INJECT_DATA *inject;
|
||||
SBIELOW_EXTRA_DATA *extra;
|
||||
UCHAR *LdrCode, *MyHookCode;
|
||||
UCHAR *HookTarget, *HookCode;
|
||||
void *RegionBase;
|
||||
SIZE_T RegionSize;
|
||||
ULONG OldProtect;
|
||||
|
@ -284,67 +403,65 @@ _FX void InitInject(SBIELOW_DATA *data, void *DetourCode)
|
|||
// and RtlFindActivationContextSectionString
|
||||
//
|
||||
|
||||
LdrCode = FindDllExport(ntdll_base,
|
||||
(UCHAR *)extra + extra->LdrLoadDll_offset, &uError);
|
||||
if (!LdrCode) {
|
||||
inject->LdrLoadDll = (ULONG_PTR)FindDllExport(ntdll_base,
|
||||
(UCHAR *)extra + extra->LdrLoadDll_offset, &uError);
|
||||
#ifdef _M_ARM64
|
||||
if (inject->LdrLoadDll && data->flags.is_arm64ec)
|
||||
inject->LdrLoadDll = (ULONG_PTR)Hook_GetFFSTarget((UCHAR*)inject->LdrLoadDll);
|
||||
#endif
|
||||
if (!inject->LdrLoadDll) {
|
||||
SbieApi_DebugError(data, (0x01 << 4) | uError);
|
||||
return;
|
||||
}
|
||||
#ifdef _M_ARM64
|
||||
if (data->flags.is_arm64ec)
|
||||
LdrCode = Hook_GetFFSTarget(LdrCode);
|
||||
#endif
|
||||
if (!LdrCode) {
|
||||
SbieApi_DebugError(data, 0x01d);
|
||||
return;
|
||||
}
|
||||
inject->LdrLoadDll = (ULONG_PTR)LdrCode;
|
||||
|
||||
LdrCode = FindDllExport(ntdll_base,
|
||||
(UCHAR *)extra + extra->LdrGetProcAddr_offset, &uError);
|
||||
if (!LdrCode) {
|
||||
inject->LdrGetProcAddr = (ULONG_PTR)FindDllExport(ntdll_base,
|
||||
(UCHAR *)extra + extra->LdrGetProcAddr_offset, &uError);
|
||||
#ifdef _M_ARM64
|
||||
if (inject->LdrGetProcAddr && data->flags.is_arm64ec)
|
||||
inject->LdrGetProcAddr = (ULONG_PTR)Hook_GetFFSTarget((UCHAR*)inject->LdrGetProcAddr);
|
||||
#endif
|
||||
if (!inject->LdrGetProcAddr) {
|
||||
SbieApi_DebugError(data, (0x02 << 4) | uError);
|
||||
return;
|
||||
}
|
||||
#ifdef _M_ARM64
|
||||
if (data->flags.is_arm64ec)
|
||||
LdrCode = Hook_GetFFSTarget(LdrCode);
|
||||
#endif
|
||||
if (!LdrCode) {
|
||||
SbieApi_DebugError(data, 0x02d);
|
||||
return;
|
||||
}
|
||||
inject->LdrGetProcAddr = (ULONG_PTR)LdrCode;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
|
||||
//
|
||||
// on ARM64EC we hook the native code hence we need the custom MyGetProcedureAddress
|
||||
// to obtain the address of the native original 1 from our SbieDll.dll
|
||||
// instead of the FFS sequence as given by NtGetProcedureAddress
|
||||
//
|
||||
|
||||
inject->MyGetProcAddr = (ULONG_PTR)MyGetProcedureAddress;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
if (data->flags.is_wow64) {
|
||||
LdrCode = FindDllExport(ntdll_base,
|
||||
(UCHAR*)extra + extra->NtRaiseHardError_offset, &uError);
|
||||
if (!LdrCode) {
|
||||
|
||||
inject->NtProtectVirtualMemory = (ULONG_PTR)FindDllExport(ntdll_base,
|
||||
(UCHAR*)extra + extra->NtProtectVirtualMemory_offset, &uError);
|
||||
if (!inject->NtProtectVirtualMemory) {
|
||||
SbieApi_DebugError(data, (0x03 << 4) | uError);
|
||||
return;
|
||||
}
|
||||
inject->NtRaiseHardError = (ULONG_PTR)LdrCode;
|
||||
|
||||
inject->NtRaiseHardError = (ULONG_PTR)FindDllExport(ntdll_base,
|
||||
(UCHAR*)extra + extra->NtRaiseHardError_offset, &uError);
|
||||
if (!inject->NtRaiseHardError) {
|
||||
SbieApi_DebugError(data, (0x04 << 4) | uError);
|
||||
return;
|
||||
}
|
||||
|
||||
inject->NtDeviceIoControlFile = (ULONG_PTR)FindDllExport(ntdll_base,
|
||||
(UCHAR*)extra + extra->NtDeviceIoControlFile_offset, &uError);
|
||||
if (!inject->NtDeviceIoControlFile) {
|
||||
SbieApi_DebugError(data, (0x05 << 4) | uError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
//
|
||||
// for ARM64EC we need native functions, FindDllExport can manage FFS's
|
||||
// however this does not work for syscalls, hence we use the native function directly
|
||||
//
|
||||
|
||||
//
|
||||
// for ARM64EC we need native functions, FindDllExport can manage FFS's
|
||||
// however this does not work for syscalls, hence we use the native function directly
|
||||
//
|
||||
inject->NtProtectVirtualMemory = data->NativeNtProtectVirtualMemory;
|
||||
inject->NtRaiseHardError = data->NativeNtRaiseHardError;
|
||||
inject->NtDeviceIoControlFile = data->NtDeviceIoControlFile;
|
||||
}
|
||||
inject->api_device_handle = data->api_device_handle;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
|
||||
|
@ -355,226 +472,168 @@ _FX void InitInject(SBIELOW_DATA *data, void *DetourCode)
|
|||
//
|
||||
|
||||
if (!data->flags.is_wow64)
|
||||
LdrCode = (UCHAR*)inject->LdrLoadDll;
|
||||
HookTarget = (UCHAR*)inject->LdrLoadDll;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
LdrCode = FindDllExport(ntdll_base,
|
||||
HookTarget = FindDllExport(ntdll_base,
|
||||
(UCHAR *)extra + extra->RtlFindActCtx_offset, &uError);
|
||||
if (!LdrCode) {
|
||||
SbieApi_DebugError(data, (0x04 << 4) | uError);
|
||||
if (!HookTarget) {
|
||||
SbieApi_DebugError(data, (0x05 << 4) | uError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
inject->RtlFindActCtx = (ULONG_PTR)LdrCode;
|
||||
inject->RtlFindActCtx = (ULONG_PTR)HookTarget;
|
||||
|
||||
|
||||
//
|
||||
// prepare unicode strings
|
||||
//
|
||||
|
||||
inject->KernelDll_Length = (USHORT)extra->KernelDll_length;
|
||||
inject->KernelDll_MaxLen = inject->KernelDll_Length + sizeof(WCHAR);
|
||||
inject->KerneDll_Buf32 =
|
||||
inject->KernelDll.Length = (USHORT)extra->KernelDll_length;
|
||||
inject->KernelDll.MaxLen = inject->KernelDll.Length + sizeof(WCHAR);
|
||||
inject->KernelDll.Buf32 =
|
||||
(ULONG)((ULONG_PTR)extra + extra->KernelDll_offset);
|
||||
inject->KerneDll_Buf64 =
|
||||
(ULONG64)((ULONG_PTR)extra + extra->KernelDll_offset);
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
if (data->flags.is_wow64) {
|
||||
inject->KernelDll.Buf64 =
|
||||
(ULONG64)((ULONG_PTR)extra + extra->KernelDll_offset);
|
||||
#endif
|
||||
|
||||
InitInjectWow64(data);
|
||||
return;
|
||||
}
|
||||
#endif _WIN64
|
||||
//
|
||||
// sellect the right version of SbieDll.dll
|
||||
//
|
||||
|
||||
#ifdef _M_ARM64
|
||||
if (data->flags.is_arm64ec) {
|
||||
|
||||
inject->SbieDll_Length = (SHORT)extra->Arm64ecSbieDll_length;
|
||||
inject->SbieDll_MaxLen = inject->SbieDll_Length + sizeof(WCHAR);
|
||||
inject->SbieDll_Buf64 =
|
||||
inject->SbieDll.Length = (SHORT)extra->Arm64ecSbieDll_length;
|
||||
inject->SbieDll.MaxLen = inject->SbieDll.Length + sizeof(WCHAR);
|
||||
inject->SbieDll.Buf64 =
|
||||
(ULONG64)((ULONG_PTR)extra + extra->Arm64ecSbieDll_offset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef _WIN64
|
||||
if (data->flags.is_wow64)
|
||||
{
|
||||
inject->SbieDll_Length = (SHORT)extra->NativeSbieDll_length;
|
||||
inject->SbieDll_MaxLen = inject->SbieDll_Length + sizeof(WCHAR);
|
||||
inject->SbieDll_Buf32 =
|
||||
(ULONG)((ULONG_PTR)extra + extra->NativeSbieDll_offset);
|
||||
inject->SbieDll_Buf64 =
|
||||
inject->SbieDll.Length = (SHORT)extra->Wow64SbieDll_length;
|
||||
inject->SbieDll.MaxLen = inject->SbieDll.Length + sizeof(WCHAR);
|
||||
inject->SbieDll.Buf32 =
|
||||
(ULONG)((ULONG_PTR)extra + extra->Wow64SbieDll_offset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
inject->SbieDll.Length = (SHORT)extra->NativeSbieDll_length;
|
||||
inject->SbieDll.MaxLen = inject->SbieDll.Length + sizeof(WCHAR);
|
||||
#ifdef _WIN64
|
||||
inject->SbieDll.Buf64 =
|
||||
(ULONG64)((ULONG_PTR)extra + extra->NativeSbieDll_offset);
|
||||
#else
|
||||
inject->SbieDll.Buf32 =
|
||||
(ULONG)((ULONG_PTR)extra + extra->NativeSbieDll_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// select version of RtlFindActivationContextSectionString detour code:
|
||||
// because both the 32-bit and 64-bit versions of this SbieLow code must
|
||||
// handle 32-bit programs, both versions include the 32-bit detour code.
|
||||
// (see entry.asm)
|
||||
// modify our detour code in entry.asm to include a hard coded pointer to the inject data area.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// modify our RtlFindActivationContextSectionString detour code in
|
||||
// entry.asm to include a hard coded pointer to the inject data area.
|
||||
|
||||
#ifdef _WIN64
|
||||
if (!data->flags.is_wow64) {
|
||||
|
||||
#ifdef _M_ARM64
|
||||
|
||||
MyHookCode = (UCHAR *) DetourCode;
|
||||
RegionBase = (void *)(MyHookCode - 8);
|
||||
RegionSize = sizeof(ULONG_PTR);
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
HookCode = (UCHAR*)DetourCode;
|
||||
RegionBase = (void*)(HookCode - 8);
|
||||
RegionSize = sizeof(ULONG_PTR);
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
|
||||
*(ULONG_PTR *)(MyHookCode - 8) = (ULONG_PTR)inject;
|
||||
*(ULONG_PTR*)(HookCode - 8) = (ULONG_PTR)inject;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
|
||||
RegionBase = (void *)&LdrCode[0]; // RtlFindActCtx
|
||||
RegionSize = 16;
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
|
||||
memcpy(&inject->RtlFindActCtx_Bytes, LdrCode, 16);
|
||||
RegionBase = (void*)&HookTarget[0]; // RtlFindActCtx
|
||||
RegionSize = 16;
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
|
||||
memcpy(inject->RtlFindActCtx_Bytes, HookTarget, 16);
|
||||
|
||||
ULONG* aCode = (ULONG*)LdrCode;
|
||||
*aCode++ = 0x58000048; // ldr x8, 8
|
||||
*aCode++ = 0xD61F0100; // br x8
|
||||
*(DWORD64*)aCode = (DWORD64)MyHookCode;
|
||||
ULONG* aCode = (ULONG*)HookTarget;
|
||||
*aCode++ = 0x58000048; // ldr x8, 8
|
||||
*aCode++ = 0xD61F0100; // br x8
|
||||
*(DWORD64*)aCode = (DWORD64)HookCode;
|
||||
|
||||
SBIELOW_CALL(NtFlushInstructionCache)(
|
||||
NtCurrentProcess(), RegionBase, (ULONG)RegionSize);
|
||||
|
||||
#elif _WIN64
|
||||
|
||||
MyHookCode = (UCHAR *) DetourCode;
|
||||
RegionBase = (void *)(MyHookCode - 8);
|
||||
RegionSize = sizeof(ULONG_PTR);
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
|
||||
*(ULONG_PTR *)(MyHookCode - 8) = (ULONG_PTR)inject;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
|
||||
RegionBase = (void *)&LdrCode[0]; // RtlFindActCtx
|
||||
RegionSize = 12;
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
|
||||
memcpy(&inject->RtlFindActCtx_Bytes, LdrCode, 12);
|
||||
|
||||
LdrCode[0] = 0x48;
|
||||
LdrCode[1] = 0xb8;
|
||||
*(ULONG_PTR *)&LdrCode[2] = (ULONG_PTR)MyHookCode;
|
||||
LdrCode[10] = 0xff;
|
||||
LdrCode[11] = 0xe0;
|
||||
SBIELOW_CALL(NtFlushInstructionCache)(
|
||||
NtCurrentProcess(), RegionBase, (ULONG)RegionSize);
|
||||
|
||||
#else
|
||||
|
||||
MyHookCode = (UCHAR *)DetourCode;
|
||||
RegionBase = (void *)(MyHookCode + 1);
|
||||
RegionSize = sizeof(ULONG_PTR);
|
||||
HookCode = (UCHAR*)DetourCode;
|
||||
RegionBase = (void*)(HookCode - 8);
|
||||
RegionSize = sizeof(ULONG_PTR);
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
*(ULONG_PTR*)(HookCode - 8) = (ULONG_PTR)inject;
|
||||
|
||||
*(ULONG *)(MyHookCode + 1) = (ULONG)(ULONG_PTR)inject;
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
RegionBase = (void*)&HookTarget[0]; // RtlFindActCtx
|
||||
RegionSize = 12;
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
|
||||
memcpy(inject->RtlFindActCtx_Bytes, HookTarget, 12);
|
||||
|
||||
RegionBase = (void *)LdrCode; // RtlFindActCtx
|
||||
RegionSize = 5;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
|
||||
|
||||
memcpy(&inject->RtlFindActCtx_Bytes, LdrCode, 5);
|
||||
|
||||
LdrCode[0] = 0xE9;
|
||||
*(ULONG *)&LdrCode[1] = (ULONG)(MyHookCode - (LdrCode + 5));
|
||||
HookTarget[0] = 0x48;
|
||||
HookTarget[1] = 0xb8;
|
||||
*(ULONG_PTR*)&HookTarget[2] = (ULONG_PTR)HookCode;
|
||||
HookTarget[10] = 0xff;
|
||||
HookTarget[11] = 0xe0;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
HookCode = (UCHAR*)data->ptr_32bit_detour;
|
||||
#else
|
||||
{
|
||||
HookCode = (UCHAR*)DetourCode;
|
||||
#endif
|
||||
RegionBase = (void*)(HookCode + 1);
|
||||
RegionSize = sizeof(ULONG_PTR);
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &OldProtect);
|
||||
|
||||
*(ULONG*)(HookCode + 1) = (ULONG)(ULONG_PTR)inject;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
OldProtect, &OldProtect);
|
||||
|
||||
RegionBase = (void*)HookTarget; // RtlFindActCtx
|
||||
RegionSize = 5;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
|
||||
|
||||
memcpy(inject->RtlFindActCtx_Bytes, HookTarget, 5);
|
||||
|
||||
HookTarget[0] = 0xE9;
|
||||
*(ULONG*)&HookTarget[1] = (ULONG)(HookCode - (HookTarget + 5));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// InitInjectWow64
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
_FX void InitInjectWow64(SBIELOW_DATA *data)
|
||||
{
|
||||
SYSCALL_DATA* syscall_data;
|
||||
INJECT_DATA *inject;
|
||||
SBIELOW_EXTRA_DATA *extra;
|
||||
UCHAR *LdrCode, *MyCode;
|
||||
void *RegionBase;
|
||||
SIZE_T RegionSize;
|
||||
|
||||
//
|
||||
// find inject and extra data areas, same as in InitInject()
|
||||
//
|
||||
|
||||
syscall_data = (SYSCALL_DATA *)data->syscall_data;
|
||||
|
||||
extra = (SBIELOW_EXTRA_DATA *) (data->syscall_data + syscall_data->extra_data_offset);
|
||||
|
||||
inject = (INJECT_DATA *) ((UCHAR *)extra + extra->InjectData_offset);
|
||||
|
||||
//
|
||||
// prepare unicode strings
|
||||
//
|
||||
|
||||
inject->SbieDll_Length = (SHORT)extra->Wow64SbieDll_length;
|
||||
inject->SbieDll_MaxLen = inject->SbieDll_Length + sizeof(WCHAR);
|
||||
inject->SbieDll_Buf32 =
|
||||
(ULONG)((ULONG_PTR)extra + extra->Wow64SbieDll_offset);
|
||||
|
||||
//
|
||||
// the service fills INJECT_DATA.DetourCode_x86 with the right non native code
|
||||
//
|
||||
|
||||
MyCode = inject->DetourCode_x86;
|
||||
|
||||
//
|
||||
// modify our copied detour code to include a hard coded pointer to
|
||||
// the inject data area (which is the syscall data area)
|
||||
//
|
||||
|
||||
*(ULONG *)(MyCode + 1) = (ULONG)(ULONG_PTR)inject;
|
||||
|
||||
//
|
||||
// hook the top of RtlFindActivationContextSectionString
|
||||
// to jump to our copied detour
|
||||
//
|
||||
|
||||
LdrCode = (UCHAR *)inject->RtlFindActCtx;
|
||||
|
||||
RegionBase = (void *)LdrCode;
|
||||
RegionSize = 5;
|
||||
|
||||
SBIELOW_CALL(NtProtectVirtualMemory)(
|
||||
NtCurrentProcess(), &RegionBase, &RegionSize,
|
||||
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
|
||||
|
||||
memcpy(&inject->RtlFindActCtx_Bytes, LdrCode, 5);
|
||||
|
||||
LdrCode[0] = 0xE9;
|
||||
*(ULONG *)&LdrCode[1] = (ULONG)(MyCode - (LdrCode + 5));
|
||||
}
|
||||
#endif _WIN64
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 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
|
||||
|
@ -103,16 +103,16 @@ typedef struct _SBIELOW_DATA {
|
|||
|
||||
ULONG64 RealNtDeviceIoControlFile; // offset 224
|
||||
ULONG64 NtDeviceIoControlFile; // for ARM64 // offset 232
|
||||
ULONG64 NativeNtRaiseHardError; // offset 240
|
||||
ULONG64 NativeNtProtectVirtualMemory; // offset 240
|
||||
ULONG64 NativeNtRaiseHardError; // offset 248
|
||||
|
||||
ULONG64 pSystemService;
|
||||
|
||||
ULONG64 DebugData[16];
|
||||
|
||||
#ifdef _WIN64
|
||||
SBIELOW_J_TABLE * Sbie64bitJumpTable;
|
||||
|
||||
ULONG64 ntdll_wow64_base;
|
||||
ULONG64 ptr_32bit_detour;
|
||||
#endif
|
||||
|
||||
#ifdef _M_ARM64
|
||||
|
@ -142,7 +142,9 @@ typedef struct _SBIELOW_EXTRA_DATA {
|
|||
|
||||
ULONG LdrLoadDll_offset;
|
||||
ULONG LdrGetProcAddr_offset;
|
||||
ULONG NtProtectVirtualMemory_offset;
|
||||
ULONG NtRaiseHardError_offset;
|
||||
ULONG NtDeviceIoControlFile_offset;
|
||||
ULONG RtlFindActCtx_offset;
|
||||
#ifdef _M_ARM64
|
||||
ULONG RtlImageOptionsEx_offset;
|
||||
|
@ -206,51 +208,45 @@ typedef struct _SYSCALL_DATA32 { // win32u.dll
|
|||
|
||||
} SYSCALL_DATA32;
|
||||
|
||||
//
|
||||
// UNICIDE_STRING compatible with 32 and 64 bit API
|
||||
//
|
||||
|
||||
typedef struct _UNIVERSAL_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaxLen;
|
||||
ULONG Buf32;
|
||||
ULONG64 Buf64;
|
||||
} UNIVERSAL_STRING;
|
||||
|
||||
|
||||
//
|
||||
// temporary data used by the Detour Code any changed to
|
||||
// this structure must be synchronized with all 3 versions of the
|
||||
// Detour Code as well as with the binary copies of the x86 and x64 code
|
||||
//
|
||||
// entry_asm.asm, entry_arm.asm and lowlevel_code.c
|
||||
// in entry_asm.asm and entry_arm.asm
|
||||
//
|
||||
|
||||
typedef struct _INJECT_DATA {
|
||||
|
||||
ULONG64 sbielow_data; // 0
|
||||
|
||||
union {
|
||||
ULONG64 LdrLoadDll; // 8
|
||||
ULONG64 RtlFindActCtx_SavedArg1; // todo: split this
|
||||
};
|
||||
ULONG64 LdrGetProcAddr; // 16
|
||||
ULONG64 NtRaiseHardError; // 24
|
||||
ULONG64 RtlFindActCtx; // 32
|
||||
ULONG64 RtlFindActCtx; // 8
|
||||
ULONG RtlFindActCtx_Protect;
|
||||
UCHAR RtlFindActCtx_Bytes[20];
|
||||
|
||||
ULONG RtlFindActCtx_Protect; // 40
|
||||
UCHAR RtlFindActCtx_Bytes[20]; // 44
|
||||
ULONG64 LdrLoadDll;
|
||||
ULONG64 LdrGetProcAddr;
|
||||
ULONG64 NtProtectVirtualMemory;
|
||||
ULONG64 NtRaiseHardError;
|
||||
ULONG64 NtDeviceIoControlFile;
|
||||
ULONG64 api_device_handle;
|
||||
|
||||
USHORT KernelDll_Length; // 64
|
||||
USHORT KernelDll_MaxLen;
|
||||
ULONG KerneDll_Buf32;
|
||||
ULONG64 KerneDll_Buf64;
|
||||
|
||||
USHORT SbieDll_Length; // 80
|
||||
USHORT SbieDll_MaxLen;
|
||||
ULONG SbieDll_Buf32;
|
||||
ULONG64 SbieDll_Buf64;
|
||||
|
||||
ULONG64 ModuleHandle; // 96
|
||||
ULONG64 SbieDllOrdinal1; // 104
|
||||
|
||||
ULONG64 MyGetProcAddr; // 112
|
||||
|
||||
#ifdef _WIN64
|
||||
UCHAR DetourCode_x86[128]; // 120
|
||||
#endif _WIN64
|
||||
UNIVERSAL_STRING KernelDll;
|
||||
UNIVERSAL_STRING SbieDll;
|
||||
|
||||
} INJECT_DATA;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -1,279 +0,0 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 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/>.
|
||||
*/
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
//
|
||||
// we need the 32-bit version of RtlFindActivationContextSectionString
|
||||
// on both 32-bit and 64-bit versions of SbieLow, because of wow64
|
||||
//
|
||||
// it will not compile correctly as assembly on 64-bit, so we simply
|
||||
// dump the machine code bytes here
|
||||
//
|
||||
|
||||
UCHAR SbieDll_ShellCode_x86[] =
|
||||
{
|
||||
0xBA, 0, 0, 0, 0, // mov edx, 0 ; edx -> inject data area
|
||||
|
||||
//0xCC, // int3
|
||||
|
||||
0x56, // push esi
|
||||
0x8B, 0xF2, // mov esi, edx ; esi -> inject data area
|
||||
|
||||
//
|
||||
// restore bytes
|
||||
//
|
||||
|
||||
0x8B, 0x46, 0x20, // mov eax,dword ptr [esi+20h] ; ... [esi].InjectData.RtlFindActCtx
|
||||
0x8A, 0x56, 0x2C, // mov dl,byte ptr [esi+2Ch] ; ... [esi].InjectData.RtlFindActCtx_Bytes
|
||||
0x88, 0x10, // mov byte ptr [eax],dl
|
||||
0x8B, 0x56, 0x2D, // mov edx,dword ptr [esi+2Dh] ; ... [esi].InjectData.RtlFindActCtx_Bytes+1
|
||||
0x89, 0x50, 0x01, // mov dword ptr [eax+1],edx
|
||||
|
||||
//
|
||||
// call LdrLoadDll for kernel32
|
||||
//
|
||||
|
||||
0xb9, 0x10, 0, 0, 0, // mov ecx, 10h
|
||||
// LdrLoadDll_Retry:
|
||||
//for(i = 0; i < 0x10; i++) {
|
||||
0x51, // push ecx
|
||||
0x8D, 0x46, 0x60, // lea eax,[esi+60h] ; ... [esi].InjectData.ModuleHandle
|
||||
0x50, // push eax
|
||||
0x8D, 0x46, 0x40, // lea eax,[esi+40h] ; ... [esi].InjectData.KernelDll_Unicode
|
||||
0x50, // push eax
|
||||
0x6A, 0x00, // push 0
|
||||
0x6A, 0x00, // push 0
|
||||
0xFF, 0x56, 0x08, // call dword ptr [esi+8] ; ... [esi].InjectData.LdrLoadDll
|
||||
0x59, // pop ecx
|
||||
0x85, 0xC0, // test eax,eax
|
||||
0x74, 0x04, // jz LdrLoadDll_Good
|
||||
//}
|
||||
0xE2, 0xE9, // loop LdrLoadDll_Retry
|
||||
0xEB, 0x34, // jmp error
|
||||
// LdrLoadDll_Good:
|
||||
|
||||
//
|
||||
// call LdrLoadDll for sbiedll
|
||||
//
|
||||
|
||||
0x8D, 0x46, 0x60, // lea eax,[esi+60h] ; ... [esi].InjectData.ModuleHandle
|
||||
0x50, // push eax
|
||||
0x8D, 0x46, 0x50, // lea eax,[esi+50h] ; ... [esi].InjectData.SbieDll_Unicode
|
||||
0x50, // push eax
|
||||
0x6A, 0x00, // push 0
|
||||
0x6A, 0x00, // push 0
|
||||
0xFF, 0x56, 0x08, // call dword ptr [esi+8] ; ... [esi].InjectData.LdrLoadDll
|
||||
|
||||
0x85, 0xC0, // test eax,eax
|
||||
0x75, 0x21, // jnz RtlFindActivationContextSectionStringError
|
||||
|
||||
//
|
||||
// call LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
// which forces ntdll to initialize sbiedll
|
||||
//
|
||||
|
||||
0x8D, 0x46, 0x68, // lea eax,[esi+68h] ; ... [esi].InjectData.SbieDllOrdinal1
|
||||
0x50, // push eax
|
||||
0x6A, 0x01, // push 1
|
||||
0x6A, 0x00, // push 0
|
||||
0xFF, 0x76, 0x60, // push dword ptr [esi+60h] ; ... [esi].InjectData.ModuleHandle
|
||||
0xFF, 0x56, 0x10, // call dword ptr [esi+10h] ; ... [esi].InjectData.LdrGetProcAddr
|
||||
|
||||
0x85, 0xC0, // test eax,eax
|
||||
0x75, 0x0F, // jnz RtlFindActivationContextSectionStringError
|
||||
|
||||
//
|
||||
// pass control to ordinal 1 ...
|
||||
//
|
||||
|
||||
0x8B, 0xC6, // mov eax, esi
|
||||
0x87, 0x44, 0x24, 0x08, // xchg eax, dword ptr [esp+8]
|
||||
0x89, 0x46, 0x08, // mov dword ptr [esi+8],eax ; ... [esi].InjectData.LdrLoadDll ...
|
||||
0x8B, 0xC6, // mov eax, esi
|
||||
0x5E, // pop esi
|
||||
0xFF, 0x60, 0x68, // jmp dword ptr [eax+68h] ; ... [eax].InjectData.SbieDllOrdinal1
|
||||
|
||||
//
|
||||
// display error message ...
|
||||
//
|
||||
|
||||
// RtlFindActivationContextSectionStringError:
|
||||
0x50, // push eax
|
||||
|
||||
0x8D, 0x56, 0x50, // lea edx,[esi+50h] ; ... [esi].InjectData.SbieDll_Unicode
|
||||
0x89, 0x56, 0x08, // mov dword ptr [esi+8],edx ; ... [esi].InjectData.LdrLoadDll ...
|
||||
|
||||
0x8d, 0x56, 0x10, // lea edx,[esi+10h] ; ... [esi].InjectData.LdrGetProcAddr
|
||||
0x52, // push edx
|
||||
0x6A, 0x01, // push 1
|
||||
0x8D, 0x56, 0x08, // lea edx,[esi+8] ; ... [esi].InjectData.LdrLoadDll
|
||||
0x52, // push edx
|
||||
0x6A, 0x01, // push 1
|
||||
0x6A, 0x01, // push 1
|
||||
0x68, 0x42, 0x01, 0x00, 0xD0, // push 0D0000142h
|
||||
0xFF, 0x56, 0x18, // call dword ptr [esi+18h] ; ... [esi].InjectData.NtRaiseHardError
|
||||
|
||||
0x58, // pop eax
|
||||
0x5E, // pop esi
|
||||
0xC2, 0x14, 0 // ret 14h
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _M_ARM64
|
||||
|
||||
//
|
||||
// we need the x64 version of RtlFindActivationContextSectionString
|
||||
//
|
||||
// it will not compile correctly as assembly on arm64, so we simply
|
||||
// dump the machine code bytes here
|
||||
//
|
||||
|
||||
//UCHAR SbieDll_ShellCode_x64[] =
|
||||
//{
|
||||
//
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // inject data area address
|
||||
//
|
||||
// 0x48, 0x8B, 0x05, 0xF1, 0xFF, 0xFF, 0xFF, // mov rax, qword ptr [rip - 0xf] ; rax -> inject data area
|
||||
//
|
||||
// // 0xCC, // int3
|
||||
//
|
||||
// 0x56, // push rsi ; save rsi, and align stack
|
||||
// 0x48, 0x83, 0xEC, 0x40, // sub rsp, 0x40 ; set up local stack
|
||||
//
|
||||
// 0x48, 0x89, 0x4C, 0x24, 0x20, // mov qword ptr [rsp + 0x20], rcx
|
||||
// 0x48, 0x89, 0x54, 0x24, 0x28, // mov qword ptr [rsp + 0x28], rdx
|
||||
// 0x4C, 0x89, 0x44, 0x24, 0x30, // mov qword ptr [rsp + 0x30], r8
|
||||
// 0x4C, 0x89, 0x4C, 0x24, 0x38, // mov qword ptr [rsp + 0x38], r9
|
||||
//
|
||||
// 0x48, 0x8B, 0xF0, // mov rsi, rax ; rsi -> inject data area
|
||||
//
|
||||
// 0x48, 0x8B, 0x46, 0x20, // mov rax, qword ptr [rsi + 0x20] ; ... [rsi].InjectData.RtlFindActCtx
|
||||
//
|
||||
// // replace 12bytes
|
||||
// 0x48, 0x8B, 0x56, 0x2C, // mov rdx, qword ptr [rsi + 0x2c] ; ... [rsi].InjectData.RtlFindActCtx_Bytes
|
||||
// 0x48, 0x89, 0x10, // mov qword ptr [rax], rdx
|
||||
// 0x8B, 0x56, 0x34, // mov edx, dword ptr [rsi + 0x34] ; ... [rsi].InjectData.RtlFindActCtx_Bytes + 8
|
||||
// 0x89, 0x50, 0x08, // mov dword ptr [rax + 8], edx
|
||||
//
|
||||
// //
|
||||
// // call LdrLoadDll for kernel32
|
||||
// //
|
||||
// //// retry loop
|
||||
// 0x48, 0x89, 0x5E, 0x2C, // mov qword ptr [rsi + 0x2c], rbx ; ... [rsi].InjectData.RtlFindActCtx_Bytes ...
|
||||
// 0x48, 0xC7, 0xC3, 0x10, 0x00, 0x00, 0x00, // mov rbx, 0x10
|
||||
//
|
||||
// // LdrLoadRetry:
|
||||
// 0x48, 0x33, 0xC9, // xor rcx, rcx
|
||||
// 0x48, 0x33, 0xD2, // xor rdx, rdx
|
||||
// 0x4C, 0x8D, 0x46, 0x40, // lea r8, [rsi + 0x40] ; ... [rsi].InjectData.KernelDll_Unicode
|
||||
// 0x4C, 0x8D, 0x4E, 0x60, // lea r9, [rsi + 0x60] ; ... [rsi].InjectData.ModuleHandle
|
||||
// //cmp rbx,1
|
||||
// //jnz LdrTestLoop
|
||||
// 0xFF, 0x56, 0x08, // call qword ptr [rsi + 8] ; ... [rsi].InjectData.LdrLoadDll
|
||||
// 0x85, 0xC0, // test eax, eax
|
||||
// 0x74, 0x0A, // je 0x5e ; LdrLoadGood
|
||||
// ////LdrTestLoop:
|
||||
// 0x48, 0xFF, 0xCB, // dec rbx
|
||||
// 0x48, 0x85, 0xDB, // test rbx, rbx
|
||||
// 0x75, 0xE3, // jne 0x3f ; ;loop LdrLoadRetry
|
||||
// 0xEB, 0x54, // jmp 0xb2 ; RtlFindActivationContextSectionStringError
|
||||
//
|
||||
// //
|
||||
// // call LdrLoadDll for sbiedll
|
||||
// //
|
||||
// // LdrLoadGood:
|
||||
// 0x48, 0x8B, 0x5E, 0x2C, // mov rbx, qword ptr [rsi + 0x2c] ; ... [rsi].InjectData.RtlFindActCtx_Bytes
|
||||
// 0x48, 0x33, 0xC9, // xor rcx, rcx
|
||||
// 0x48, 0x33, 0xD2, // xor rdx, rdx
|
||||
// 0x4C, 0x8D, 0x46, 0x50, // lea r8, [rsi + 0x50] ; ... [rsi].InjectData.SbieDll_Unicode
|
||||
// 0x4C, 0x8D, 0x4E, 0x60, // lea r9, [rsi + 0x60] ; ... [rsi].InjectData.ModuleHandle
|
||||
// 0xFF, 0x56, 0x08, // call qword ptr [rsi + 8] ; ... [rsi].InjectData.LdrLoadDll
|
||||
//
|
||||
// 0x85, 0xC0, // test eax, eax
|
||||
// 0x75, 0x3B, // jne 0xb2 ; RtlFindActivationContextSectionStringError
|
||||
//
|
||||
// //
|
||||
// // call LdrGetProcedureAddress for sbiedll ordinal 1,
|
||||
// // which forces ntdll to initialize sbiedll
|
||||
// //
|
||||
//
|
||||
// 0x48, 0x8B, 0x4E, 0x60, // mov rcx, qword ptr [rsi + 0x60] ; ... [rsi].InjectData.ModuleHandle
|
||||
// 0x48, 0x33, 0xD2, // xor rdx, rdx
|
||||
// 0x4D, 0x33, 0xC0, // xor r8, r8
|
||||
// 0x49, 0xFF, 0xC0, // inc r8
|
||||
// 0x4C, 0x8D, 0x4E, 0x68, // lea r9, [rsi + 0x68] ; ... [rsi].InjectData.SbieDllOrdinal1
|
||||
// 0xFF, 0x56, 0x10, // call qword ptr [rsi + 0x10] ; ... [rsi].InjectData.LdrGetProcAddr
|
||||
//
|
||||
// 0x85, 0xC0, // test eax, eax
|
||||
// 0x75, 0x23, // jne 0xb2 ; RtlFindActivationContextSectionStringError
|
||||
//
|
||||
// //
|
||||
// // pass control to ordinal 1, which will free the inject
|
||||
// // data area, and pass control to the original function
|
||||
// // RtlFindActivationContextSectionString
|
||||
// //
|
||||
// // note that we need to pass the address of the inject
|
||||
// // data area to ordinal 1, which we do by overwriting the
|
||||
// // first argument. the original argument is saved in
|
||||
// // the inject data area
|
||||
// //
|
||||
//
|
||||
// 0x48, 0x8B, 0x44, 0x24, 0x20, // mov rax, qword ptr [rsp + 0x20]
|
||||
// 0x48, 0x89, 0x46, 0x08, // mov qword ptr [rsi + 8], rax ; ... [rsi].InjectData.LdrLoadDll ...
|
||||
// 0x48, 0x8B, 0xCE, // mov rcx, rsi
|
||||
// 0x48, 0x8B, 0x54, 0x24, 0x28, // mov rdx, qword ptr [rsp + 0x28]
|
||||
// 0x4C, 0x8B, 0x44, 0x24, 0x30, // mov r8, qword ptr [rsp + 0x30]
|
||||
// 0x4C, 0x8B, 0x4C, 0x24, 0x38, // mov r9, qword ptr [rsp + 0x38]
|
||||
//
|
||||
// 0x48, 0x83, 0xC4, 0x40, // add rsp, 0x40
|
||||
// 0x5E, // pop rsi
|
||||
// 0xFF, 0x61, 0x68, // jmp qword ptr [rcx + 0x68] ; [rcx].InjectData.SbieDllOrdinal1
|
||||
//
|
||||
// //
|
||||
// // display error message, invoke NtRaiseHardError(
|
||||
// // NTSTATUS ntstatus_message_code,
|
||||
// // ULONG number_of_parameters_in_list,
|
||||
// // ULONG mask_of_strings_in_list,
|
||||
// // ULONG_PTR *list_of_pointers_to_parameters,
|
||||
// // ULONG response_buttons,
|
||||
// // ULONG *out_response)
|
||||
// //
|
||||
//
|
||||
// //RtlFindActivationContextSectionStringError:
|
||||
//
|
||||
// 0x48, 0x89, 0x44, 0x24, 0x38, // mov qword ptr [rsp + 0x38], rax ; save ntstatus
|
||||
// 0xB9, 0x42, 0x01, 0x00, 0xD0, // mov ecx, 0xd0000142 ; ntstatus_message_code
|
||||
// 0x48, 0x33, 0xD2, // xor rdx, rdx ; number_of_parameters_in_list
|
||||
// 0x48, 0xFF, 0xC2, // inc rdx
|
||||
// 0x4C, 0x8B, 0xC2, // mov r8, rdx ; mask_of_strings_in_list
|
||||
// 0x67, 0x4C, 0x8D, 0x4E, 0x08, // lea r9, [esi + 8] ; ... [esi].InjectData.LdrLoadDll ; list_of_pointers_to_parameters
|
||||
// 0x48, 0x8D, 0x46, 0x50, // lea rax, [rsi + 0x50] ; ... [rsi].InjectData.SbieDll_Unicode
|
||||
// 0x49, 0x89, 0x01, // mov qword ptr [r9], rax
|
||||
// 0x48, 0x89, 0x54, 0x24, 0x20, // mov qword ptr [rsp + 0x20], rdx ; response_buttons - ERROR_OK
|
||||
// 0x48, 0x8D, 0x46, 0x10, // lea rax, [rsi + 0x10] ; ... [rsi].InjectData.LdrGetProcAddr
|
||||
// 0x48, 0x89, 0x44, 0x24, 0x28, // mov qword ptr [rsp + 0x28], rax ; out_response
|
||||
// 0xFF, 0x56, 0x18, // call qword ptr [rsi + 0x18] ; ... [rsi].InjectData.NtRaiseHardError
|
||||
// 0x48, 0x8B, 0x4C, 0x24, 0x38, // mov rcx, qword ptr [rsp + 0x38] ; restore ntstatus
|
||||
// 0x48, 0x83, 0xC4, 0x40, // add rsp, 0x40
|
||||
// 0x5E, // pop rsi
|
||||
// 0xC3 // ret ; return to caller with error
|
||||
//};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Copyright 2023 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 "stdafx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include <AclAPI.h>
|
||||
#include <Sddl.h>
|
||||
#include "common/defines.h"
|
||||
#include "common/my_version.h"
|
||||
#include "core/dll/sbieapi.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
extern "C" void Display_Error(PWSTR SubFuncName, DWORD LastError);
|
||||
|
||||
struct SDaclEntry
|
||||
{
|
||||
SDaclEntry() : pSid(NULL), AllowMask(0),DenyMask(0) {}
|
||||
BYTE bSid[68];
|
||||
PSID pSid;
|
||||
ACCESS_MASK AllowMask;
|
||||
ACCESS_MASK DenyMask;
|
||||
};
|
||||
|
||||
std::map<std::wstring, SDaclEntry> ListFolderDACLs(const wchar_t* folderPath)
|
||||
{
|
||||
std::map<std::wstring, SDaclEntry> map;
|
||||
|
||||
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
|
||||
DWORD result = GetNamedSecurityInfoW(folderPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSecurityDescriptor);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
Display_Error(L"GetNamedSecurityInfoW", result);
|
||||
return map;
|
||||
}
|
||||
|
||||
BOOL ok;
|
||||
PACL pDacl = NULL;
|
||||
BOOL bDaclPresent = FALSE;
|
||||
BOOL bDaclDefaulted = FALSE;
|
||||
ok = GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted);
|
||||
if (!ok) {
|
||||
Display_Error(L"GetSecurityDescriptorDacl", 0);
|
||||
return map;
|
||||
}
|
||||
if (!bDaclPresent)
|
||||
return map; // empty not an error
|
||||
|
||||
for (DWORD i = 0; i < pDacl->AceCount; ++i) {
|
||||
|
||||
PACE_HEADER pAceHeader = NULL;
|
||||
if (!GetAce(pDacl, i, (LPVOID*)&pAceHeader)) {
|
||||
//Display_Error(L"GetAce", 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
PSID pSid = NULL;
|
||||
ACCESS_MASK AllowMask = 0;
|
||||
ACCESS_MASK DenyMask = 0;
|
||||
switch (pAceHeader->AceType) {
|
||||
case ACCESS_ALLOWED_ACE_TYPE: {
|
||||
PACCESS_ALLOWED_ACE pAce = (PACCESS_ALLOWED_ACE)pAceHeader;
|
||||
pSid = (PSID)&pAce->SidStart;
|
||||
AllowMask = pAce->Mask;
|
||||
break;
|
||||
}
|
||||
case ACCESS_DENIED_ACE_TYPE: {
|
||||
PACCESS_DENIED_ACE pAce = (PACCESS_DENIED_ACE)pAceHeader;
|
||||
pSid = (PSID)&pAce->SidStart;
|
||||
DenyMask = pAce->Mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pSid) {
|
||||
LPWSTR pSidString = NULL;
|
||||
if (ConvertSidToStringSidW(pSid, &pSidString)) {
|
||||
SDaclEntry& entry = map[pSidString];
|
||||
if (!entry.pSid) {
|
||||
CopySid(sizeof(entry.bSid), entry.bSid, pSid);
|
||||
entry.pSid = entry.bSid;
|
||||
}
|
||||
entry.AllowMask |= AllowMask;
|
||||
entry.DenyMask |= DenyMask;
|
||||
LocalFree(pSidString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LocalFree(pSecurityDescriptor);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
BOOL UpdateFolderDACLs(const wchar_t* folderPath, EXPLICIT_ACCESS *ea)
|
||||
{
|
||||
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
|
||||
DWORD result = GetNamedSecurityInfoW(folderPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSecurityDescriptor);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
Display_Error(L"GetNamedSecurityInfoW", result);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL ok;
|
||||
PACL pDacl = NULL;
|
||||
BOOL bDaclPresent = FALSE;
|
||||
BOOL bDaclDefaulted = FALSE;
|
||||
ok = GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted);
|
||||
if (!ok) {
|
||||
Display_Error(L"GetSecurityDescriptorDacl", 0);
|
||||
return FALSE;
|
||||
}
|
||||
if (!bDaclPresent) {
|
||||
Display_Error(L"GetSecurityDescriptorDacl", ERROR_INVALID_ACCESS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
result = SetEntriesInAclW(1, ea, pDacl, &pDacl);
|
||||
if (result != ERROR_SUCCESS)
|
||||
Display_Error(L"SetEntriesInAclW", result);
|
||||
else {
|
||||
result = SetNamedSecurityInfoW((LPWSTR)folderPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
|
||||
if (result != ERROR_SUCCESS)
|
||||
Display_Error(L"SetNamedSecurityInfoW", result);
|
||||
}
|
||||
|
||||
LocalFree(pSecurityDescriptor);
|
||||
return result == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Kmd_FixDacls
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
extern "C" BOOL Kmd_FixDacls()
|
||||
{
|
||||
WCHAR HomePath[MAX_PATH];
|
||||
SbieApi_GetHomePath(NULL, 0, HomePath, MAX_PATH);
|
||||
if (!*HomePath) // sbie not installed or not running
|
||||
return FALSE;
|
||||
|
||||
//
|
||||
// remove problematic permissions created when the
|
||||
// win 11 shell extension was registered
|
||||
// for a folder not being under program files
|
||||
//
|
||||
|
||||
std::map<std::wstring, SDaclEntry> map = ListFolderDACLs(HomePath);
|
||||
|
||||
for (auto I = map.begin(); I != map.end(); ++I) {
|
||||
|
||||
if (I->first.length() > 44 && (
|
||||
(I->first.substr(0, 13) == L"S-1-15-3-1024")
|
||||
|| (I->first.substr(0, 8) == L"S-1-15-2") )) {
|
||||
|
||||
EXPLICIT_ACCESS ea_clear =
|
||||
{
|
||||
GENERIC_ALL,
|
||||
REVOKE_ACCESS,
|
||||
SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
||||
{
|
||||
NULL,
|
||||
NO_MULTIPLE_TRUSTEE,
|
||||
TRUSTEE_IS_SID,
|
||||
TRUSTEE_IS_GROUP,
|
||||
reinterpret_cast<LPTSTR>(I->second.pSid)
|
||||
}
|
||||
};
|
||||
|
||||
UpdateFolderDACLs(HomePath, &ea_clear);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// add read access for ALL_APP_PACKAGES
|
||||
//
|
||||
|
||||
PSID pSid = NULL; // ALL_APP_PACKAGES
|
||||
ConvertStringSidToSidW(L"S-1-15-2-1", &pSid);
|
||||
|
||||
EXPLICIT_ACCESS ea_set =
|
||||
{
|
||||
GENERIC_READ | GENERIC_EXECUTE,
|
||||
SET_ACCESS,
|
||||
SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
||||
{
|
||||
NULL,
|
||||
NO_MULTIPLE_TRUSTEE,
|
||||
TRUSTEE_IS_SID,
|
||||
TRUSTEE_IS_GROUP,
|
||||
reinterpret_cast<LPTSTR>(pSid)
|
||||
}
|
||||
};
|
||||
|
||||
UpdateFolderDACLs(HomePath, &ea_set);
|
||||
|
||||
LocalFree(pSid);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
extern void Kmd_ScanDll(BOOLEAN silent);
|
||||
|
||||
extern BOOL Kmd_FixDacls();
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
@ -43,7 +45,8 @@ typedef enum _COMMAND {
|
|||
CMD_STOP,
|
||||
CMD_SCANDLL,
|
||||
CMD_SCANDLL_SILENT,
|
||||
CMD_MESSAGE
|
||||
CMD_MESSAGE,
|
||||
CMD_FIXDACLS
|
||||
} COMMAND;
|
||||
|
||||
typedef enum _OPTIONS {
|
||||
|
@ -224,6 +227,10 @@ BOOL Parse_Command_Line(
|
|||
*Command = CMD_MESSAGE;
|
||||
num_args_needed = 2;
|
||||
|
||||
} else if (_wcsicmp(args[1], L"fixdacls") == 0) {
|
||||
*Command = CMD_FIXDACLS;
|
||||
num_args_needed = 0;
|
||||
|
||||
} else {
|
||||
*Command = CMD_ERROR;
|
||||
MessageBox(NULL, L"Invalid command", L"KmdUtil",
|
||||
|
@ -761,6 +768,16 @@ int __stdcall WinMain(
|
|||
&Options))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if (Command == CMD_MESSAGE) {
|
||||
ok = Kmd_Show_Message(Driver_Name, Driver_Path);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (Command == CMD_FIXDACLS) {
|
||||
ok = Kmd_FixDacls();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
ScMgr = OpenSCManager(
|
||||
NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
|
||||
|
||||
|
@ -803,9 +820,7 @@ int __stdcall WinMain(
|
|||
if (Command == CMD_STOP)
|
||||
ok = Kmd_Stop_Service(Driver_Name);
|
||||
|
||||
if (Command == CMD_MESSAGE)
|
||||
ok = Kmd_Show_Message(Driver_Name, Driver_Path);
|
||||
|
||||
finish:
|
||||
if (! ok)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
|
|
|
@ -183,6 +183,20 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="fixdacls.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieRelease|ARM64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">NotUsing</PrecompiledHeader>
|
||||
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='SbieRelease|Win32'">Sync</ExceptionHandling>
|
||||
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='SbieDebug|Win32'">Sync</ExceptionHandling>
|
||||
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='SbieRelease|ARM64'">Sync</ExceptionHandling>
|
||||
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='SbieDebug|ARM64'">Sync</ExceptionHandling>
|
||||
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='SbieRelease|x64'">Sync</ExceptionHandling>
|
||||
<ExceptionHandling Condition="'$(Configuration)|$(Platform)'=='SbieDebug|x64'">Sync</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KmdUtil.c" />
|
||||
<ClCompile Include="sbiedrv.c" />
|
||||
<ClCompile Include="scandll.c" />
|
||||
|
|
|
@ -386,6 +386,14 @@ SBIE2114 File is too large to copy into sandbox, denying access - %2
|
|||
SBIE2115 File is too large to copy into sandbox, opening in read only - %2
|
||||
.
|
||||
|
||||
2180;pop;inf;01
|
||||
SBIE2180 LowLevel.dll error %2
|
||||
.
|
||||
|
||||
2181;pop;inf;01
|
||||
SBIE2181 LowLevel.dll detour failed to load SbieDll.dll into target process.
|
||||
.
|
||||
|
||||
# %2 = Mozilla Firefox
|
||||
2191;pop;inf;01
|
||||
SBIE2191 %2 should not be updated while running under Sandboxie.
|
||||
|
|
Loading…
Reference in New Issue