This commit is contained in:
DavidXanatos 2023-07-05 21:07:40 +02:00
parent 830d5f607d
commit c7e49c7031
24 changed files with 1441 additions and 1200 deletions

View File

@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.10.0 / 5.65.0] - 2023-07-?? ## [1.10.0 / 5.65.0] - 2023-07-??
### Added ### Added
- added box scripting engine to make sandman more flexible
- added scriptable troubleshooting wizard [#1875](https://github.com/sandboxie-plus/Sandboxie/issues/1875) - 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: - 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 - [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 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 - 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 - 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 ### Changed
- setup wizard has now a dedicated update configuration page - 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 - 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 - 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 - 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 session agent startup to be more flexible
- improved SBIEMSG help handling - improved SBIEMSG help handling
### Fixed ### Fixed
- fixed uninstall issue in the Sandboxie Classic installer [d1863ff](https://github.com/sandboxie-plus/Sandboxie/commit/d1863ffadfe105c695de71c9e841c2fd568116fe) - 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) - 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 ### Removed
- cleaned up duplicate code (thanks lmou523) [#3067](https://github.com/sandboxie-plus/Sandboxie/pull/3067) - cleaned up duplicate code (thanks lmou523) [#3067](https://github.com/sandboxie-plus/Sandboxie/pull/3067)
## [1.9.8 / 5.64.8] - 2023-06-21 ## [1.9.8 / 5.64.8] - 2023-06-21
### Changed ### Changed

View File

@ -281,10 +281,10 @@ extern ULONG64 Dll_ProcessFlags;
#ifndef _WIN64 #ifndef _WIN64
extern BOOLEAN Dll_IsWow64; extern BOOLEAN Dll_IsWow64;
#endif #endif
#ifdef _M_X64 #ifdef _M_ARM64EC
extern BOOLEAN Dll_IsArm64ec; extern BOOLEAN Dll_IsArm64ec;
#endif #endif
#ifndef _M_ARM64 #ifndef _WIN64
extern BOOLEAN Dll_IsXtAjit; extern BOOLEAN Dll_IsXtAjit;
#endif #endif
extern BOOLEAN Dll_IsSystemSid; extern BOOLEAN Dll_IsSystemSid;

View File

@ -90,10 +90,10 @@ ULONG64 Dll_ProcessFlags = 0;
#ifndef _WIN64 #ifndef _WIN64
BOOLEAN Dll_IsWow64 = FALSE; BOOLEAN Dll_IsWow64 = FALSE;
#endif #endif
#ifdef _M_X64 #ifdef _M_ARM64EC
BOOLEAN Dll_IsArm64ec = FALSE; BOOLEAN Dll_IsArm64ec = FALSE;
#endif #endif
#ifndef _M_ARM64 #ifndef _WIN64
BOOLEAN Dll_IsXtAjit = FALSE; BOOLEAN Dll_IsXtAjit = FALSE;
#endif #endif
BOOLEAN Dll_IsSystemSid = FALSE; BOOLEAN Dll_IsSystemSid = FALSE;
@ -772,46 +772,20 @@ _FX void Dll_SelectImageType(void)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
_FX ULONG_PTR Dll_Ordinal1( _FX VOID Dll_Ordinal1(INJECT_DATA * inject)
ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
ULONG_PTR arg4, ULONG_PTR arg5)
{ {
typedef ULONG_PTR (*P_RtlFindActivationContextSectionString)( SBIELOW_DATA *data = (SBIELOW_DATA *)inject->sbielow_data;
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;
BOOLEAN bHostInject = FALSE; 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; SbieApi_data = data;
#ifdef _M_ARM64EC #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)); SbieApi_SyscallPtr = (ULONG*)((ULONG64)data->syscall_data + sizeof(ULONG) + sizeof(ULONG) + (NATIVE_FUNCTION_SIZE * NATIVE_FUNCTION_COUNT));
#endif #endif
extern HANDLE SbieApi_DeviceHandle;
SbieApi_DeviceHandle = (HANDLE)data->api_device_handle;
// //
// the SbieLow data area includes values that are useful to us // 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 // 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; bHostInject = data->flags.bHostInject == 1;
#ifndef _WIN64 #ifndef _WIN64
Dll_IsWow64 = data->flags.is_wow64 == 1; Dll_IsWow64 = data->flags.is_wow64 == 1; // x86 on x64 or arm64
#endif #endif
#ifdef _M_X64 #ifdef _M_ARM64EC
Dll_IsArm64ec = data->flags.is_arm64ec == 1; Dll_IsArm64ec = data->flags.is_arm64ec == 1; // x64 on arm64
#endif #endif
#ifndef _M_ARM64 #ifndef _WIN64
Dll_IsXtAjit = data->flags.is_xtajit == 1; Dll_IsXtAjit = data->flags.is_xtajit == 1; // x86 on arm64
#endif #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) if (!bHostInject)
{ {
@ -928,25 +879,6 @@ _FX ULONG_PTR Dll_Ordinal1(
{ {
Ldr_Inject_Init(TRUE); 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);
} }

View File

@ -412,7 +412,7 @@ _FX VOID File_SavePathTree_internal(LIST* Root, const WCHAR* name)
HANDLE hPathsFile; HANDLE hPathsFile;
IO_STATUS_BLOCK IoStatusBlock; 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; return;
WCHAR* Path = (WCHAR *)Dll_Alloc((0x7FFF + 1)*sizeof(WCHAR)); // max nt path WCHAR* Path = (WCHAR *)Dll_Alloc((0x7FFF + 1)*sizeof(WCHAR)); // max nt path

View File

@ -36,7 +36,7 @@ typedef struct _FILE_SNAPSHOT {
WCHAR ID[FILE_MAX_SNAPSHOT_ID]; WCHAR ID[FILE_MAX_SNAPSHOT_ID];
ULONG IDlen; ULONG IDlen;
ULONG ScramKey; ULONG ScramKey;
//WCHAR Name[34]; //WCHAR Name[BOXNAME_COUNT];
struct _FILE_SNAPSHOT* Parent; struct _FILE_SNAPSHOT* Parent;
LIST PathRoot; LIST PathRoot;
} FILE_SNAPSHOT, *PFILE_SNAPSHOT; } FILE_SNAPSHOT, *PFILE_SNAPSHOT;
@ -480,8 +480,8 @@ _FX void File_InitSnapshots(void)
File_LoadPathTree_internal(&Cur_Snapshot->PathRoot, PathFile); File_LoadPathTree_internal(&Cur_Snapshot->PathRoot, PathFile);
} }
//WCHAR SnapshotName[34] = { 0 }; //WCHAR SnapshotName[BOXNAME_COUNT] = { 0 };
//GetPrivateProfileStringW(SnapshotId, L"Name", L"", SnapshotName, 34, SnapshotsIni); //GetPrivateProfileStringW(SnapshotId, L"Name", L"", SnapshotName, BOXNAME_COUNT, SnapshotsIni);
//wcscpy(Cur_Snapshot->Name, SnapshotName); //wcscpy(Cur_Snapshot->Name, SnapshotName);
GetPrivateProfileStringW(SnapshotId, L"Parent", L"", Snapshot, 16, SnapshotsIni); GetPrivateProfileStringW(SnapshotId, L"Parent", L"", Snapshot, 16, SnapshotsIni);

View File

@ -282,22 +282,15 @@ void CALLBACK Ldr_LdrDllNotification(ULONG NotificationReason, PLDR_DLL_NOTIFICA
{ {
ULONG_PTR LdrCookie = 0; ULONG_PTR LdrCookie = 0;
NTSTATUS status = 0; NTSTATUS status = 0;
WCHAR text[4096];
if (NotificationReason == 1) { if (NotificationReason == 1) {
status = __sys_LdrLockLoaderLock(0, NULL, &LdrCookie); status = __sys_LdrLockLoaderLock(0, NULL, &LdrCookie);
Ldr_MyDllCallbackNew(NotificationData->Loaded.BaseDllName->Buffer, (HMODULE)NotificationData->Loaded.DllBase, TRUE); Ldr_MyDllCallbackNew(NotificationData->Loaded.BaseDllName->Buffer, (HMODULE)NotificationData->Loaded.DllBase, TRUE);
__sys_LdrUnlockLoaderLock(0, LdrCookie); __sys_LdrUnlockLoaderLock(0, LdrCookie);
Sbie_snwprintf(text, ARRAYSIZE(text), L"%s (loaded)", NotificationData->Loaded.BaseDllName->Buffer);
} }
else if (NotificationReason == 2) { else if (NotificationReason == 2) {
Ldr_MyDllCallbackNew(NotificationData->Unloaded.BaseDllName->Buffer, (HMODULE)NotificationData->Loaded.DllBase, FALSE); 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]; WCHAR ImageNameW[128];
Sbie_snwprintf(ImageNameW, ARRAYSIZE(ImageNameW), L"%S", ImageName); 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 _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 _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 // 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) _FX void *Ldr_GetProcAddrNew(const WCHAR *DllName, const WCHAR *ProcNameW, char * ProcNameA)
{ {
NTSTATUS status; NTSTATUS status;
void *proc; void *proc = NULL;
// char buffer[768]; // char buffer[768];
// sprintf(buffer,"GetProcAddrNew: DllName = %S, ProcW = %S, ProcA = %s\n",DllName,ProcNameW,ProcNameA); // sprintf(buffer,"GetProcAddrNew: DllName = %S, ProcW = %S, ProcA = %s\n",DllName,ProcNameW,ProcNameA);
// OutputDebugStringA(buffer); // OutputDebugStringA(buffer);
if (Dll_OsBuild < 9600) { if (Dll_OsBuild < 9600) { // Windows 8.0 or earlier
proc = Ldr_GetProcAddr_2(DllName, ProcNameW); proc = Ldr_GetProcAddr_2(DllName, ProcNameW);
if (!proc) { if (!proc) {
ULONG_PTR LdrCookie; 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; HMODULE DllBase;
DllBase = GetModuleHandle(DllName); DllBase = GetModuleHandle(DllName);
if (!DllBase) { if (!DllBase) {

View File

@ -22,6 +22,7 @@
#include "dll.h" #include "dll.h"
#include "core/low/lowdata.h"
#include <stdio.h> #include <stdio.h>
@ -880,6 +881,22 @@ _FX void* Ldr_Inject_Entry(ULONG_PTR *pPtr)
{ {
Ldr_LoadInjectDlls(g_bHostInject); 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; return entrypoint;
} }

View File

@ -1,4 +1,5 @@
// Copyright 2004-2020 Sandboxie Holdings, LLC // Copyright 2004-2020 Sandboxie Holdings, LLC
// Copyright 2023 David Xanatos, xanasoft.com
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -54,11 +55,10 @@
#ifdef BUILD_UTILITY_PASS2 #ifdef BUILD_UTILITY_PASS2
#if MY_ARM64_FLAG #if MY_ARM64_FLAG
LOWLEVEL RCDATA "../low/obj/ARM64/LowLevel.dll" LOWLEVEL64 RCDATA "../low/obj/ARM64/LowLevel.dll"
#elif MY_WIN64_FLAG #elif MY_WIN64_FLAG
LOWLEVEL RCDATA "../low/obj/amd64/LowLevel.dll" LOWLEVEL64 RCDATA "../low/obj/amd64/LowLevel.dll"
#else
LOWLEVEL RCDATA "../low/obj/i386/LowLevel.dll"
#endif // MY_WIN64_FLAG #endif // MY_WIN64_FLAG
LOWLEVEL32 RCDATA "../low/obj/i386/LowLevel.dll"
#endif // BUILD_UTILITY_PASS2 #endif // BUILD_UTILITY_PASS2

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2004-2020 Sandboxie Holdings, LLC * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -48,6 +48,7 @@
typedef struct _MY_TARGETS { typedef struct _MY_TARGETS {
unsigned long long entry; unsigned long long entry;
unsigned long long data; unsigned long long data;
unsigned long long detour;
} MY_TARGETS; } MY_TARGETS;
#ifdef _M_ARM64 #ifdef _M_ARM64
@ -85,7 +86,7 @@ typedef PVOID (*P_VirtualAlloc2)(
SBIEDLL_EXPORT HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess); SBIEDLL_EXPORT HANDLE SbieDll_InjectLow_SendHandle(HANDLE hProcess);
void *SbieDll_InjectLow_CopyCode( 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 #ifdef _M_ARM64
, BOOLEAN use_arm64ec , BOOLEAN use_arm64ec
#endif #endif
@ -129,11 +130,16 @@ ULONG Hook_GetSysCallFunc(ULONG* aCode, void** pHandleStubHijack);
void *m_sbielow_ptr = NULL; void *m_sbielow_ptr = NULL;
ULONG m_sbielow_len = 0;
//adding two offsets variables to replace the "head" and "tail" dependency //adding two offsets variables to replace the "head" and "tail" dependency
ULONG m_sbielow_start_offset = 0; ULONG m_sbielow_start_offset = 0;
ULONG m_sbielow_data_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; ULONG *m_syscall_data = NULL;
@ -149,19 +155,19 @@ P_VirtualAlloc2 __sys_VirtualAlloc2 = NULL;
#endif #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, // lock the SbieLow resource (embedded within the SbieSvc executable,
// see lowlevel.rc) and find the offset to executable code, and length // see lowlevel.rc) and find the offset to executable code, and length
// //
IMAGE_DOS_HEADER *dos_hdr = 0; IMAGE_DOS_HEADER *dos_hdr = 0;
IMAGE_NT_HEADERS *nt_hdrs = 0; IMAGE_NT_HEADERS *nt_hdrs = 0;
IMAGE_SECTION_HEADER *section = 0; IMAGE_SECTION_HEADER *section = 0;
@ -171,8 +177,8 @@ _FX ULONG SbieDll_InjectLow_InitHelper()
ULONG errlvl = 0x11; ULONG errlvl = 0x11;
HRSRC hrsrc = FindResource(Dll_Instance, L"LOWLEVEL", RT_RCDATA); HRSRC hrsrc = FindResource(Dll_Instance, arch_64bit ? L"LOWLEVEL64" : L"LOWLEVEL32", RT_RCDATA);
if (! hrsrc) if (! hrsrc)
return errlvl; return errlvl;
ULONG binsize = SizeofResource(Dll_Instance, hrsrc); 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') { if (dos_hdr->e_magic == 'MZ' || dos_hdr->e_magic == 'ZM') {
nt_hdrs = (IMAGE_NT_HEADERS *)((UCHAR *)dos_hdr + dos_hdr->e_lfanew); nt_hdrs = (IMAGE_NT_HEADERS *)((UCHAR *)dos_hdr + dos_hdr->e_lfanew);
if (nt_hdrs->Signature == IMAGE_NT_SIGNATURE) { // 'PE\0\0' 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 {
return errlvl; 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 #ifdef _M_ARM64
zzzzz = 4; if (arch_64bit)
#else zzzzz = 4; // ARM64 only
if (imageBase != 0) { else
return errlvl;
}
zzzzz = 1;
#endif #endif
if (imageBase != 0) // x64 or x86
return errlvl;
section = IMAGE_FIRST_SECTION(nt_hdrs); section = IMAGE_FIRST_SECTION(nt_hdrs);
if (nt_hdrs->FileHeader.NumberOfSections < 2) return errlvl; if (nt_hdrs->FileHeader.NumberOfSections < 2) return errlvl;
@ -241,13 +236,32 @@ _FX ULONG SbieDll_InjectLow_InitHelper()
targets = (MY_TARGETS *)& bindata[section[zzzzz].PointerToRawData]; targets = (MY_TARGETS *)& bindata[section[zzzzz].PointerToRawData];
m_sbielow_start_offset = (ULONG)(targets->entry - imageBase - section[0].VirtualAddress); if(start_offset) *start_offset = (ULONG)(targets->entry - imageBase - section[0].VirtualAddress);
m_sbielow_data_offset = (ULONG)(targets->data - 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; *sbielow_ptr = bindata + section[0].PointerToRawData; //Old version: head;
m_sbielow_len = section[0].SizeOfRawData; //Old version: (ULONG)(ULONG_PTR)(tail - 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; return errlvl;
// //
@ -403,6 +417,10 @@ _FX ULONG SbieDll_InjectLow_InitSyscalls(BOOLEAN drv_init)
// Get the SbieDll Location // Get the SbieDll Location
// //
/*if (1) {
GetSystemDirectory(sbie_home, 512);
}
else */
if (drv_init) if (drv_init)
{ {
status = SbieApi_GetHomePath(NULL, 0, sbie_home, 512); 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); extra->LdrGetProcAddr_offset = ULONG_DIFF(ptr, extra);
ptr += 28 / sizeof(WCHAR); 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 // 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); extra->NtRaiseHardError_offset = ULONG_DIFF(ptr, extra);
ptr += 20 / sizeof(WCHAR); 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 // 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); 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 // 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 #endif
lowdata.RealNtDeviceIoControlFile = (ULONG64)GetProcAddress((HMODULE)lowdata.ntdll_base, "NtDeviceIoControlFile"); 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"); 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 #endif
lowLevel_size = m_sbielow_len; 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 #ifdef _M_ARM64
, (BOOLEAN)lowdata.flags.is_arm64ec , (BOOLEAN)lowdata.flags.is_arm64ec
#endif #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) { if (!remote_addr) {
errlvl = 0x33; errlvl = 0x33;
goto finish; 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 #ifndef _M_ARM64
#ifdef _WIN64 #ifdef _WIN64
lowdata.flags.long_diff = 1; lowdata.flags.long_diff = 1;
@ -1041,8 +1129,8 @@ _FX void* InjectLow_AllocMemory(HANDLE hProcess, SIZE_T size, BOOLEAN executable
void *remote_addr = NULL; void *remote_addr = NULL;
#ifdef _M_ARM64 #ifdef _M_ARM64
if (use_arm64ec && executable) if (use_arm64ec && executable) {
{
MEM_EXTENDED_PARAMETER Parameter = { 0 }; MEM_EXTENDED_PARAMETER Parameter = { 0 };
Parameter.Type = MemExtendedParameterAttributeFlags; Parameter.Type = MemExtendedParameterAttributeFlags;
Parameter.ULong64 = MEM_EXTENDED_PARAMETER_EC_CODE; 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); remote_addr = __sys_VirtualAlloc2(hProcess, (void*)base_addr, region_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE, &Parameter, 1);
} }
return remote_addr;
} }
else
#endif #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 #ifdef _M_ARM64
, BOOLEAN use_arm64ec , BOOLEAN use_arm64ec
#endif #endif
) { ) {
void* remote_addr;
void* pLdrInitializeThunk = (void*)m_LdrInitializeThunk;
#ifdef _M_ARM64 void* remote_addr = InjectLow_AllocMemory(hProcess, total_size, TRUE
if (use_arm64ec)
pLdrInitializeThunk = (void*)m_LdrInitializeThunkEC;
#endif
remote_addr = InjectLow_AllocMemory(hProcess, lowLevel_size, TRUE
#ifdef _M_ARM64 #ifdef _M_ARM64
, use_arm64ec , use_arm64ec
#endif #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 // 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; SIZE_T len2 = 0;
BOOL vm_ok = WriteProcessMemory( BOOL vm_ok = WriteProcessMemory(
hProcess, remote_addr, m_sbielow_ptr, hProcess, remote_addr, lowLevel_ptr,
len1, &len2); len1, &len2);
if (vm_ok && len1 == len2) { if (vm_ok && len1 == len2) {
// return remote_addr;
// 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;
}
} }
} }
@ -1356,10 +1421,8 @@ _FX void *SbieDll_InjectLow_CopySyscalls(HANDLE hProcess, BOOLEAN is_wow64
data = m_syscall_data; data = m_syscall_data;
SIZE_T region_size = *data; SIZE_T region_size = *data;
remote_addr = InjectLow_AllocMemory(hProcess, region_size remote_addr = InjectLow_AllocMemory(hProcess, region_size , FALSE
, is_wow64 // we copy the detour code into this area, hence executable = TRUE
#ifdef _M_ARM64 #ifdef _M_ARM64
//|| use_arm64ec
, FALSE , FALSE
#endif #endif
); );
@ -1406,10 +1469,7 @@ _FX BOOLEAN SbieDll_InjectLow_CopyData(
ULONG protect; ULONG protect;
vm_ok = VirtualProtectEx(hProcess, remote_addr, m_sbielow_len, 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 PAGE_EXECUTE_READ, &protect);
// we set PAGE_EXECUTE_READ in SbieDll.dll Dll_Ordinal1
PAGE_EXECUTE_READWRITE, &protect);
//PAGE_EXECUTE_READ, &protect);
if (vm_ok) { if (vm_ok) {
return TRUE; return TRUE;
} }

View File

@ -667,7 +667,7 @@ _FX ULONG64 SbieApi_QueryProcessInfoEx(
_FX LONG SbieApi_QueryBoxPath( _FX LONG SbieApi_QueryBoxPath(
const WCHAR *box_name, // WCHAR [34] const WCHAR *box_name, // WCHAR [BOXNAME_COUNT]
WCHAR *out_file_path, WCHAR *out_file_path,
WCHAR *out_key_path, WCHAR *out_key_path,
WCHAR *out_ipc_path, WCHAR *out_ipc_path,
@ -828,7 +828,7 @@ _FX LONG SbieApi_QueryPathList(
_FX LONG SbieApi_EnumProcessEx( _FX LONG SbieApi_EnumProcessEx(
const WCHAR *box_name, // WCHAR [34] const WCHAR *box_name, // WCHAR [BOXNAME_COUNT]
BOOLEAN all_sessions, BOOLEAN all_sessions,
ULONG which_session, // -1 for current session ULONG which_session, // -1 for current session
ULONG *boxed_pids, // ULONG [512] ULONG *boxed_pids, // ULONG [512]
@ -1432,7 +1432,7 @@ _FX ULONG SbieApi_QueryConfNumber(
_FX LONG SbieApi_EnumBoxes( _FX LONG SbieApi_EnumBoxes(
LONG index, // initialize to -1 LONG index, // initialize to -1
WCHAR *box_name) // WCHAR [34] WCHAR *box_name) // WCHAR [BOXNAME_COUNT]
{ {
return SbieApi_EnumBoxesEx(index, box_name, FALSE); return SbieApi_EnumBoxesEx(index, box_name, FALSE);
} }
@ -1445,7 +1445,7 @@ _FX LONG SbieApi_EnumBoxes(
_FX LONG SbieApi_EnumBoxesEx( _FX LONG SbieApi_EnumBoxesEx(
LONG index, // initialize to -1 LONG index, // initialize to -1
WCHAR *box_name, // WCHAR [34] WCHAR *box_name, // WCHAR [BOXNAME_COUNT]
BOOLEAN return_all_sections) BOOLEAN return_all_sections)
{ {
LONG rc; LONG rc;
@ -1738,7 +1738,7 @@ _FX LONG SbieApi_SessionLeader(HANDLE TokenHandle, HANDLE *ProcessId)
_FX LONG SbieApi_IsBoxEnabled( _FX LONG SbieApi_IsBoxEnabled(
const WCHAR *box_name) // WCHAR [34] const WCHAR *box_name) // WCHAR [BOXNAME_COUNT]
{ {
NTSTATUS status; NTSTATUS status;
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS]; __declspec(align(8)) ULONG64 parms[API_NUM_ARGS];

View File

@ -105,10 +105,6 @@ _FX int Trace_Init(void)
OutputDebugString(L"SbieDll injected...\n"); 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]);
}
} }
// //

View File

@ -711,7 +711,7 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
if (pTrapFrame) { if (pTrapFrame) {
ret = pTrapFrame->Rip; ret = pTrapFrame->Rip;
UserStack = pTrapFrame->Rsp; UserStack = pTrapFrame->Rsp;
pTrapFrame->Rsp = pTrapFrame->Rbp; //*pRbp; pTrapFrame->Rsp = pTrapFrame->Rdi; //*pRbp;
pTrapFrame->Rip = pTrapFrame->Rbx; //*pRbx; pTrapFrame->Rip = pTrapFrame->Rbx; //*pRbx;
} }
} }

View File

@ -554,7 +554,7 @@ _FX NTSTATUS Syscall_Api_Invoke32(PROCESS* proc, ULONG64* parms)
if (pTrapFrame) { if (pTrapFrame) {
ret = pTrapFrame->Rip; ret = pTrapFrame->Rip;
UserStack = pTrapFrame->Rsp; UserStack = pTrapFrame->Rsp;
pTrapFrame->Rsp = pTrapFrame->Rbp; //*pRbp; pTrapFrame->Rsp = pTrapFrame->Rdi; //*pRbp;
pTrapFrame->Rip = pTrapFrame->Rbx; //*pRbx; pTrapFrame->Rip = pTrapFrame->Rbx; //*pRbx;
} }
} }

View File

@ -159,11 +159,6 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="init.c" /> <ClCompile Include="init.c" />
<ClCompile Include="inject.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>
<ItemGroup> <ItemGroup>
<ClInclude Include="lowdata.h" /> <ClInclude Include="lowdata.h" />

View File

@ -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 ; 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 ; it under the terms of the GNU General Public License as published by
@ -19,6 +19,8 @@
IMPORT EntrypointC IMPORT EntrypointC
IMPORT DetourFunc
;EXPORT ServiceDataPtr ;EXPORT ServiceDataPtr
EXPORT SystemServiceARM64 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 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 ; cmp x0, #0x00
mov x0, #0x00 ; PathToFile ; bne DetourError
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 ; resume execution or original function
; 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 ldp x0, x1, [sp, #0x00]
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 x2, x3, [sp, #0x10]
ldp x4, x5, [sp, #0x20] ldp x4, x5, [sp, #0x20]
ldp x6, x7, [sp, #0x30] ldp x6, x7, [sp, #0x30]
ldr x8, [x19, 0x68] ; [x19].InjectData.SbieDllOrdinal1 ldr x8, [x19, 0x08] ; [x19].InjectData.RtlFindActCtx
add sp, sp, #0x40 add sp, sp, #0x40
ldp x19, x20, [sp], #0x10 ldp x19, x20, [sp], #0x10
@ -376,34 +301,170 @@ LdrLoadGood
br x8 br x8
RtlFindActivationContextSectionStringError ;DetourError
;
str x0, [sp, #0x38] ; save ntstatus ; add sp, sp, #0x40
; ldp x19, x20, [sp], #0x10
add x8, x19, 0x50 ; [x19].InjectData.SbieDll_Unicode ; ldp fp, lr, [sp], #0x10
str x8, [x19, 0x08] ; [x19].InjectData.LdrLoadDll ;
; ret
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 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 ; Parameters stored by SbieSvc
@ -433,8 +494,9 @@ SbieLowData
DCQ Start ; entry point for the detour DCQ Start ; entry point for the detour
DCQ SbieLowData ; data location DCQ SbieLowData ; data location
DCQ DetourCodeARM64 ; detour code location
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
END END

View File

@ -1,6 +1,6 @@
;------------------------------------------------------------------------ ;------------------------------------------------------------------------
; Copyright 2004-2020 Sandboxie Holdings, LLC ; 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 ; 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 ; 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 ; removed hard coded position dependency
; key symbols are now passed as arguments to EntrypointC ; key symbols are now passed as arguments to EntrypointC
; 64 bit version takes 4 arguments ; 64 bit version takes 4 arguments
; _EntrypointC(SbieLowData,_RtlFindActivationContextSectionString,_SystemService,_RtlFindActivationContextSectionString64) ; _EntrypointC(SbieLowData,_DetourCode,_SystemService)
mov rbx,rcx mov rbx,rcx
add rcx, offset SbieLowData - _001 add rcx, offset SbieLowData - _001
mov rdx,rbx mov rdx,rbx
add rdx, offset _RtlFindActivationContextSectionString64 - _001 add rdx, offset _DetourCode - _001
mov r8,rbx mov r8,rbx
add r8, offset _SystemService - _001 add r8, offset _SystemService - _001
;mov r9,rbx
;add r9, offset _RtlFindActivationContextSectionString - _001
call EntrypointC call EntrypointC
@ -99,21 +97,24 @@ else ; 32-bit
EXTERN _EntrypointC@12 : PROC EXTERN _EntrypointC@12 : PROC
_Start: _Start:
call $+5 call $+5
_001: pop eax _001: pop eax
mov edx,eax mov edx,eax
; removed hard coded position dependency ; removed hard coded position dependency
; key symbols are now passed as arguments to EntrypointC ; key symbols are now passed as arguments to EntrypointC
; 32 bit version takes 3 arguments ; 32 bit version takes 3 arguments
;_EntrypointC(SbieLowData,_RtlFindActivationContextSectionString,_SystemService) ;_EntrypointC(SbieLowData,_DetourCode,_SystemService)
add eax, offset _SystemService - _001 ;old + 96 offset add eax, offset _SystemService - _001 ;old + 96 offset
push eax push eax
mov eax,edx mov eax,edx
add eax, offset _RtlFindActivationContextSectionString - _001; old + 256 offset add eax, offset _DetourCode - _001; old + 256 offset
push eax push eax
mov eax, edx mov eax, edx
add eax, offset SbieLowData - _001 add eax, offset SbieLowData - _001
push eax push eax
call _EntrypointC@12 call _EntrypointC@12
jmp eax ; jump to LdrInitializeThunk trampoline jmp eax ; jump to LdrInitializeThunk trampoline
endif ; 32-bit or 64-bit endif ; 32-bit or 64-bit
@ -126,7 +127,6 @@ endif ; 32-bit or 64-bit
_SystemService: _SystemService:
;----------------------------------------------------------------------------
ifdef _WIN64 ; 64-bit ifdef _WIN64 ; 64-bit
myService Proc myService Proc
db 48h, 0B8h ; rax -> SbieLowData db 48h, 0B8h ; rax -> SbieLowData
@ -141,17 +141,17 @@ myService Proc
; because of x64 calling convention. ; because of x64 calling convention.
; ;
push rbp; target rsp push rdi; target rsp
push rbx; target rip push rbx; target rip
mov r11,[rax + 0e0h] ; SbieLow.RealNtDeviceIoControlFile mov r11,[rax + 0e0h] ; SbieLow.RealNtDeviceIoControlFile
add r11b,0fh add r11b,0fh
mov rbx, r11 ; pass new rip in rbx mov rbx, r11 ; pass new rip in rbx
mov r11, rsp ; restore stack in r11 mov r11, rsp ; restore stack in r11
add r11, 10h add r11, 10h
mov rbp, r11 ; pass stack frame in rbp mov rdi, r11 ; pass stack frame in rbp
API_NUM_ARGS = 8 API_NUM_ARGS = 8
sub rsp, (API_NUM_ARGS + 1 + 2 + 10) * 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+8*8], rdx
mov qword ptr [rsp+9*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 call r10
add rsp, (API_NUM_ARGS + 1 + 2 + 10) * 8 add rsp, (API_NUM_ARGS + 1 + 2 + 10) * 8
pop rbx pop rbx
pop rbp pop rdi
ret ret
myService ENDP myService ENDP
;----------------------------------------------------------------------------
else ; 32-bit else ; 32-bit
@ -297,7 +296,7 @@ else ; 32-bit
push 0 push 0
push [edx+2*8] ; push SbieLow.api_device_handle 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 call eax
; ;
@ -316,160 +315,25 @@ else ; 32-bit
neg ecx neg ecx
mov ecx, [esp+ecx] mov ecx, [esp+ecx]
jmp ecx ; return to caller jmp ecx ; return to caller
endif ; 32-bit or 64-bit endif ; 32-bit or 64-bit
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
; Inject Data Area for our RtlFindActivationContextSectionString ; detour code
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
InjectData struct ; keep in sync with inject.c InjectData struct ; keep in sync with inject.c
dq ? ; 0x00 sbielow_data dq ? ; 0x00
LdrLoadDll dq ? ; 0x08 RtlFindActCtx 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 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 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 mov rax, qword ptr [$-8] ; rax -> inject data area
push rsi ; save rsi, and align stack 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 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 ; call DetourFunc
;
;; 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 mov rcx, rsi
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 rdx, rdx
xor r8, r8 xor r8, r8
inc r8 xor r9, r9
lea r9, [rsi].InjectData.SbieDllOrdinal1 call DetourFunc
call qword ptr [rsi].InjectData.LdrGetProcAddr
test eax, eax ; test eax, eax
jnz RtlFindActivationContextSectionStringError ; jnz DetourError
; ;
; pass control to ordinal 1, which will free the inject ; resume execution or original function
; 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 rcx, qword ptr [rsp+4*8]
mov qword ptr [rsi].InjectData.LdrLoadDll, rax
mov rcx, rsi
mov rdx, qword ptr [rsp+5*8] mov rdx, qword ptr [rsp+5*8]
mov r8, qword ptr [rsp+6*8] mov r8, qword ptr [rsp+6*8]
mov r9, qword ptr [rsp+7*8] mov r9, qword ptr [rsp+7*8]
add rsp, 8*8 add rsp, 8*8
mov rax, qword ptr [rsi].InjectData.RtlFindActCtx
pop rsi 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( ; call DetourFunc
; NTSTATUS ntstatus_message_code, ;
; ULONG number_of_parameters_in_list,
; ULONG mask_of_strings_in_list, push esi
; ULONG_PTR *list_of_pointers_to_parameters, call _DetourFunc@4
; ULONG response_buttons,
; ULONG *out_response) ; test eax, eax
; jnz DetourError
;
; resume execution or original function
; ;
RtlFindActivationContextSectionStringError: mov eax, dword ptr [esi].InjectData.RtlFindActCtx
pop esi
STATUS_DLL_INIT_FAILED = 0C0000142h jmp eax
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 ;DetourError:
inc rdx ;
; 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 ;; Inject Data Area for our RtlFindActivationContextSectionString
mov qword ptr [r9], rax ;;----------------------------------------------------------------------------
;
mov \ ; response_buttons - ERROR_OK ;
qword ptr [rsp+4*8], rdx ;InjectData struct ; keep in sync with inject.c
; dq ? ; 0x00
lea rax, [rsi].InjectData.LdrGetProcAddr ;LdrLoadDll dq ? ; 0x08
mov \ ; out_response ;LdrGetProcAddr dq ? ; 0x10
qword ptr [rsp+5*8], rax ;NtRaiseHardError dq ? ; 0x18
;RtlFindActCtx dq ? ; 0x20
call qword ptr [rsi].InjectData.NtRaiseHardError ;RtlFindActCtx_Protect dd ? ; 0x28
;RtlFindActCtx_Bytes db 20 dup (?) ; 0x2C
mov rax, qword ptr [rsp+7*8] ; restore ntstatus ;KernelDll_Unicode dq 2 dup (?) ; 0x40
add rsp, 8*8 ;SbieDll_Unicode dq 2 dup (?) ; 0x50
pop rsi ;ModuleHandle dq ? ; 0x60
ret ; return to caller with error ;SbieDllOrdinal1 dq ? ; 0x68
;InjectData ends
endif ; 64-bit ;
;
;;----------------------------------------------------------------------------
;; 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 _Start
dq SbieLowData dq SbieLowData
dq _DetourCode
;---------------------------------------------------------------------------- ;----------------------------------------------------------------------------
end end

View File

@ -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; NTSTATUS status = 0;
__declspec(align(8)) UNICODE_STRING64 msgtext; __declspec(align(8)) UNICODE_STRING64 msgtext;
@ -170,9 +170,18 @@ _FX NTSTATUS SbieApi_DebugPrint(SBIELOW_DATA *data, const WCHAR *text)
memzero(parms, sizeof(parms)); memzero(parms, sizeof(parms));
args->func_code = API_LOG_MESSAGE; args->func_code = API_LOG_MESSAGE;
args->session_id.val = -1; args->session_id.val = -1;
args->msgid.val = 1122; args->msgid.val = code;
args->msgtext.val = &msgtext; 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; return status;
} }
@ -196,7 +205,7 @@ _FX NTSTATUS SbieApi_DebugError(SBIELOW_DATA* data, ULONG error)
for(int i=28; i >= 0; i-=4) for(int i=28; i >= 0; i-=4)
*ptr++ = table[(error >> i) & 0xF]; *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(); __debugbreak();
} }
#endif #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 // PrepSyscalls
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -233,11 +275,6 @@ _FX void WaitForDebugger(SBIELOW_DATA *data)
_FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService) _FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
{ {
UCHAR *SystemServiceAsm;
void *RegionBase;
SIZE_T RegionSize;
ULONG OldProtect;
#ifdef _M_ARM64 #ifdef _M_ARM64
if (data->flags.is_arm64ec) { if (data->flags.is_arm64ec) {
@ -248,7 +285,8 @@ _FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
// a replica of the #NtDeviceIoControlFile EC variant // 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 // 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 // get the EcExitThunkPtr which points to
// __os_arm64x_dispatch_call_no_redirect // __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; 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 else
#endif #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 = const LONG OFFSET_ULONG_PTR =
#ifdef _M_ARM64 #ifdef _M_ARM64
@ -295,21 +337,14 @@ _FX void PrepSyscalls(SBIELOW_DATA *data, void * SystemService)
// to include the data area pointer // to include the data area pointer
// //
SystemServiceAsm = (UCHAR *)SystemService; WriteMemorySafe(data, ((UCHAR *)SystemService) + OFFSET_ULONG_PTR, sizeof(ULONG_PTR), &data);
RegionBase = (void *)(SystemServiceAsm + OFFSET_ULONG_PTR);
RegionSize = sizeof(ULONG_PTR);
SBIELOW_CALL(NtProtectVirtualMemory)( //
NtCurrentProcess(), &RegionBase, &RegionSize, // store the SystemService address in pSystemService
PAGE_EXECUTE_READWRITE, &OldProtect); //
*(ULONG_PTR *)(SystemServiceAsm + OFFSET_ULONG_PTR) = (ULONG_PTR)data; ULONG64 SystemServicePtr = (ULONG64)SystemService;
WriteMemorySafe(data, &data->pSystemService, sizeof(ULONG64), &SystemServicePtr);
SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize,
OldProtect, &OldProtect);
data->pSystemService = (ULONG64)SystemServiceAsm;
} }
@ -597,33 +632,29 @@ _FX void DisableCHPE(SBIELOW_DATA* data)
if (!RtlImageOptionsEx) if (!RtlImageOptionsEx)
return; return;
//
// backup bytes for trampoline
//
ULONG DetourSize = 28;
memcpy(data->RtlImageOptionsEx_tramp, RtlImageOptionsEx, DetourSize);
//
// make target writable & create detour
//
void *RegionBase; void *RegionBase;
SIZE_T RegionSize; SIZE_T RegionSize;
ULONG OldProtect; 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)( SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize, NtCurrentProcess(), &RegionBase, &RegionSize,
PAGE_EXECUTE_READWRITE, &OldProtect); PAGE_EXECUTE_READWRITE, &OldProtect);
ULONG* aCode = (ULONG*)RtlImageOptionsEx; ULONG DetourSize = 28;
aCode[0] = 0x580000a7; // ldr x7, 20 - data memcpy(data->RtlImageOptionsEx_tramp, RtlImageOptionsEx, DetourSize);
aCode[1] = 0x58000048; // ldr x8, 8 - MyImageOptionsEx
aCode[2] = 0xD61F0100; // br x8 aCode = (ULONG*)(data->RtlImageOptionsEx_tramp + DetourSize); // 28
*(DWORD64*)&aCode[3] = (DWORD64)MyImageOptionsEx; aCode[0] = 0x58000048; // ldr x8, 8 - Rest of RtlImageOptionsEx
*(DWORD64*)&aCode[5] = (DWORD64)data; aCode[1] = 0xD61F0100; // br x8
*(DWORD64*)&aCode[2] = (DWORD64)RtlImageOptionsEx + DetourSize;
// 44
SBIELOW_CALL(NtProtectVirtualMemory)( SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize, NtCurrentProcess(), &RegionBase, &RegionSize,
@ -633,13 +664,29 @@ _FX void DisableCHPE(SBIELOW_DATA* data)
NtCurrentProcess(), RegionBase, (ULONG)RegionSize); NtCurrentProcess(), RegionBase, (ULONG)RegionSize);
// //
// create simple trampoline // make target writable & create detour
// //
aCode = (ULONG*)(data->RtlImageOptionsEx_tramp + DetourSize); RegionBase = (void*)RtlImageOptionsEx;
aCode[0] = 0x58000048; // ldr x8, 8 - Rest of RtlImageOptionsEx RegionSize = DetourSize;
aCode[1] = 0xD61F0100; // br x8 SBIELOW_CALL(NtProtectVirtualMemory)(
*(DWORD64*)&aCode[2] = (DWORD64)RtlImageOptionsEx + DetourSize; 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 #endif
@ -745,7 +792,7 @@ ULONG_PTR EntrypointC(SBIELOW_DATA *data, void *DetourCode, void *SystemService)
// WaitForDebugger(data); // WaitForDebugger(data);
//wchar_t text[] = { 't','e','s','t',0 }; //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); PrepSyscalls(data, SystemService);
if (!data->flags.bHostInject && !data->flags.bNoSysHooks) if (!data->flags.bHostInject && !data->flags.bNoSysHooks)

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2004-2020 Sandboxie Holdings, LLC * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@
*/ */
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Functions // inject
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include <ntstatus.h> #include <ntstatus.h>
@ -28,12 +28,13 @@ typedef long NTSTATUS;
#include "common/win32_ntddk.h" #include "common/win32_ntddk.h"
#include "common/defines.h" #include "common/defines.h"
#include "lowdata.h" #include "lowdata.h"
#include "core/drv/api_defs.h"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Functions // 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); _FX NTSTATUS SbieApi_DebugError(SBIELOW_DATA* data, ULONG error);
UCHAR *FindDllExport(void *DllBase, const UCHAR *ProcName, ULONG *pErr); UCHAR *FindDllExport(void *DllBase, const UCHAR *ProcName, ULONG *pErr);
@ -45,10 +46,27 @@ static UCHAR *FindDllExport2(
void* Hook_GetFFSTarget(UCHAR* SourceFunc); void* Hook_GetFFSTarget(UCHAR* SourceFunc);
#endif #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) #define SBIELOW_CALL(x) ((P_##x)&data->x##_code)
@ -176,34 +194,135 @@ _FX UCHAR *FindDllExport2(
return proc; 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) { NTSTATUS status;
*FunctionAddress = Hook_GetFFSTarget(*FunctionAddress); UNICODE_STRING* pDllPath;
if (!*FunctionAddress) HANDLE ModuleHandle;
return STATUS_ENTRYPOINT_NOT_FOUND; 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; return status;
} }
#endif
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// InitInject // InitInject
@ -216,7 +335,7 @@ _FX void InitInject(SBIELOW_DATA *data, void *DetourCode)
SYSCALL_DATA* syscall_data; SYSCALL_DATA* syscall_data;
INJECT_DATA *inject; INJECT_DATA *inject;
SBIELOW_EXTRA_DATA *extra; SBIELOW_EXTRA_DATA *extra;
UCHAR *LdrCode, *MyHookCode; UCHAR *HookTarget, *HookCode;
void *RegionBase; void *RegionBase;
SIZE_T RegionSize; SIZE_T RegionSize;
ULONG OldProtect; ULONG OldProtect;
@ -284,67 +403,65 @@ _FX void InitInject(SBIELOW_DATA *data, void *DetourCode)
// and RtlFindActivationContextSectionString // and RtlFindActivationContextSectionString
// //
LdrCode = FindDllExport(ntdll_base, inject->LdrLoadDll = (ULONG_PTR)FindDllExport(ntdll_base,
(UCHAR *)extra + extra->LdrLoadDll_offset, &uError); (UCHAR *)extra + extra->LdrLoadDll_offset, &uError);
if (!LdrCode) { #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); SbieApi_DebugError(data, (0x01 << 4) | uError);
return; 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, inject->LdrGetProcAddr = (ULONG_PTR)FindDllExport(ntdll_base,
(UCHAR *)extra + extra->LdrGetProcAddr_offset, &uError); (UCHAR *)extra + extra->LdrGetProcAddr_offset, &uError);
if (!LdrCode) { #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); SbieApi_DebugError(data, (0x02 << 4) | uError);
return; 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 #ifdef _WIN64
if (data->flags.is_wow64) { if (data->flags.is_wow64) {
LdrCode = FindDllExport(ntdll_base,
(UCHAR*)extra + extra->NtRaiseHardError_offset, &uError); inject->NtProtectVirtualMemory = (ULONG_PTR)FindDllExport(ntdll_base,
if (!LdrCode) { (UCHAR*)extra + extra->NtProtectVirtualMemory_offset, &uError);
if (!inject->NtProtectVirtualMemory) {
SbieApi_DebugError(data, (0x03 << 4) | uError); SbieApi_DebugError(data, (0x03 << 4) | uError);
return; 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 else
#endif #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
//
// inject->NtProtectVirtualMemory = data->NativeNtProtectVirtualMemory;
// 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->NtRaiseHardError = data->NativeNtRaiseHardError; inject->NtRaiseHardError = data->NativeNtRaiseHardError;
inject->NtDeviceIoControlFile = data->NtDeviceIoControlFile;
}
inject->api_device_handle = data->api_device_handle;
#ifdef _M_ARM64 #ifdef _M_ARM64
@ -355,226 +472,168 @@ _FX void InitInject(SBIELOW_DATA *data, void *DetourCode)
// //
if (!data->flags.is_wow64) if (!data->flags.is_wow64)
LdrCode = (UCHAR*)inject->LdrLoadDll; HookTarget = (UCHAR*)inject->LdrLoadDll;
else else
#endif #endif
{ {
LdrCode = FindDllExport(ntdll_base, HookTarget = FindDllExport(ntdll_base,
(UCHAR *)extra + extra->RtlFindActCtx_offset, &uError); (UCHAR *)extra + extra->RtlFindActCtx_offset, &uError);
if (!LdrCode) { if (!HookTarget) {
SbieApi_DebugError(data, (0x04 << 4) | uError); SbieApi_DebugError(data, (0x05 << 4) | uError);
return; return;
} }
} }
inject->RtlFindActCtx = (ULONG_PTR)LdrCode; inject->RtlFindActCtx = (ULONG_PTR)HookTarget;
// //
// prepare unicode strings // prepare unicode strings
// //
inject->KernelDll_Length = (USHORT)extra->KernelDll_length; inject->KernelDll.Length = (USHORT)extra->KernelDll_length;
inject->KernelDll_MaxLen = inject->KernelDll_Length + sizeof(WCHAR); inject->KernelDll.MaxLen = inject->KernelDll.Length + sizeof(WCHAR);
inject->KerneDll_Buf32 = inject->KernelDll.Buf32 =
(ULONG)((ULONG_PTR)extra + extra->KernelDll_offset); (ULONG)((ULONG_PTR)extra + extra->KernelDll_offset);
inject->KerneDll_Buf64 =
(ULONG64)((ULONG_PTR)extra + extra->KernelDll_offset);
#ifdef _WIN64 #ifdef _WIN64
if (data->flags.is_wow64) { inject->KernelDll.Buf64 =
(ULONG64)((ULONG_PTR)extra + extra->KernelDll_offset);
#endif
InitInjectWow64(data); //
return; // sellect the right version of SbieDll.dll
} //
#endif _WIN64
#ifdef _M_ARM64 #ifdef _M_ARM64
if (data->flags.is_arm64ec) { if (data->flags.is_arm64ec) {
inject->SbieDll_Length = (SHORT)extra->Arm64ecSbieDll_length; inject->SbieDll.Length = (SHORT)extra->Arm64ecSbieDll_length;
inject->SbieDll_MaxLen = inject->SbieDll_Length + sizeof(WCHAR); inject->SbieDll.MaxLen = inject->SbieDll.Length + sizeof(WCHAR);
inject->SbieDll_Buf64 = inject->SbieDll.Buf64 =
(ULONG64)((ULONG_PTR)extra + extra->Arm64ecSbieDll_offset); (ULONG64)((ULONG_PTR)extra + extra->Arm64ecSbieDll_offset);
} }
else else
#endif #endif
#ifdef _WIN64
if (data->flags.is_wow64)
{ {
inject->SbieDll_Length = (SHORT)extra->NativeSbieDll_length; inject->SbieDll.Length = (SHORT)extra->Wow64SbieDll_length;
inject->SbieDll_MaxLen = inject->SbieDll_Length + sizeof(WCHAR); inject->SbieDll.MaxLen = inject->SbieDll.Length + sizeof(WCHAR);
inject->SbieDll_Buf32 = inject->SbieDll.Buf32 =
(ULONG)((ULONG_PTR)extra + extra->NativeSbieDll_offset); (ULONG)((ULONG_PTR)extra + extra->Wow64SbieDll_offset);
inject->SbieDll_Buf64 = }
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); (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: // modify our detour code in entry.asm to include a hard coded pointer to the inject data area.
// 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 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 #ifdef _M_ARM64
MyHookCode = (UCHAR *) DetourCode; HookCode = (UCHAR*)DetourCode;
RegionBase = (void *)(MyHookCode - 8); RegionBase = (void*)(HookCode - 8);
RegionSize = sizeof(ULONG_PTR); RegionSize = sizeof(ULONG_PTR);
SBIELOW_CALL(NtProtectVirtualMemory)( SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize, NtCurrentProcess(), &RegionBase, &RegionSize,
PAGE_EXECUTE_READWRITE, &OldProtect); PAGE_EXECUTE_READWRITE, &OldProtect);
*(ULONG_PTR *)(MyHookCode - 8) = (ULONG_PTR)inject; *(ULONG_PTR*)(HookCode - 8) = (ULONG_PTR)inject;
SBIELOW_CALL(NtProtectVirtualMemory)( SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize, NtCurrentProcess(), &RegionBase, &RegionSize,
OldProtect, &OldProtect); OldProtect, &OldProtect);
RegionBase = (void *)&LdrCode[0]; // RtlFindActCtx RegionBase = (void*)&HookTarget[0]; // RtlFindActCtx
RegionSize = 16; RegionSize = 16;
SBIELOW_CALL(NtProtectVirtualMemory)( SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize, NtCurrentProcess(), &RegionBase, &RegionSize,
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect); PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
memcpy(&inject->RtlFindActCtx_Bytes, LdrCode, 16); memcpy(inject->RtlFindActCtx_Bytes, HookTarget, 16);
ULONG* aCode = (ULONG*)LdrCode; ULONG* aCode = (ULONG*)HookTarget;
*aCode++ = 0x58000048; // ldr x8, 8 *aCode++ = 0x58000048; // ldr x8, 8
*aCode++ = 0xD61F0100; // br x8 *aCode++ = 0xD61F0100; // br x8
*(DWORD64*)aCode = (DWORD64)MyHookCode; *(DWORD64*)aCode = (DWORD64)HookCode;
SBIELOW_CALL(NtFlushInstructionCache)( SBIELOW_CALL(NtFlushInstructionCache)(
NtCurrentProcess(), RegionBase, (ULONG)RegionSize); 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;
#else #else
MyHookCode = (UCHAR *)DetourCode; HookCode = (UCHAR*)DetourCode;
RegionBase = (void *)(MyHookCode + 1); RegionBase = (void*)(HookCode - 8);
RegionSize = sizeof(ULONG_PTR); RegionSize = sizeof(ULONG_PTR);
SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize,
PAGE_EXECUTE_READWRITE, &OldProtect);
SBIELOW_CALL(NtProtectVirtualMemory)( *(ULONG_PTR*)(HookCode - 8) = (ULONG_PTR)inject;
NtCurrentProcess(), &RegionBase, &RegionSize,
PAGE_EXECUTE_READWRITE, &OldProtect);
*(ULONG *)(MyHookCode + 1) = (ULONG)(ULONG_PTR)inject; SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize,
OldProtect, &OldProtect);
SBIELOW_CALL(NtProtectVirtualMemory)( RegionBase = (void*)&HookTarget[0]; // RtlFindActCtx
NtCurrentProcess(), &RegionBase, &RegionSize, RegionSize = 12;
OldProtect, &OldProtect); SBIELOW_CALL(NtProtectVirtualMemory)(
NtCurrentProcess(), &RegionBase, &RegionSize,
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
memcpy(inject->RtlFindActCtx_Bytes, HookTarget, 12);
RegionBase = (void *)LdrCode; // RtlFindActCtx HookTarget[0] = 0x48;
RegionSize = 5; HookTarget[1] = 0xb8;
*(ULONG_PTR*)&HookTarget[2] = (ULONG_PTR)HookCode;
SBIELOW_CALL(NtProtectVirtualMemory)( HookTarget[10] = 0xff;
NtCurrentProcess(), &RegionBase, &RegionSize, HookTarget[11] = 0xe0;
PAGE_EXECUTE_READWRITE, &inject->RtlFindActCtx_Protect);
memcpy(&inject->RtlFindActCtx_Bytes, LdrCode, 5);
LdrCode[0] = 0xE9;
*(ULONG *)&LdrCode[1] = (ULONG)(MyHookCode - (LdrCode + 5));
#endif #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

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2004-2020 Sandboxie Holdings, LLC * 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 * 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 * 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 RealNtDeviceIoControlFile; // offset 224
ULONG64 NtDeviceIoControlFile; // for ARM64 // offset 232 ULONG64 NtDeviceIoControlFile; // for ARM64 // offset 232
ULONG64 NativeNtRaiseHardError; // offset 240 ULONG64 NativeNtProtectVirtualMemory; // offset 240
ULONG64 NativeNtRaiseHardError; // offset 248
ULONG64 pSystemService; ULONG64 pSystemService;
ULONG64 DebugData[16];
#ifdef _WIN64 #ifdef _WIN64
SBIELOW_J_TABLE * Sbie64bitJumpTable; SBIELOW_J_TABLE * Sbie64bitJumpTable;
ULONG64 ntdll_wow64_base; ULONG64 ntdll_wow64_base;
ULONG64 ptr_32bit_detour;
#endif #endif
#ifdef _M_ARM64 #ifdef _M_ARM64
@ -142,7 +142,9 @@ typedef struct _SBIELOW_EXTRA_DATA {
ULONG LdrLoadDll_offset; ULONG LdrLoadDll_offset;
ULONG LdrGetProcAddr_offset; ULONG LdrGetProcAddr_offset;
ULONG NtProtectVirtualMemory_offset;
ULONG NtRaiseHardError_offset; ULONG NtRaiseHardError_offset;
ULONG NtDeviceIoControlFile_offset;
ULONG RtlFindActCtx_offset; ULONG RtlFindActCtx_offset;
#ifdef _M_ARM64 #ifdef _M_ARM64
ULONG RtlImageOptionsEx_offset; ULONG RtlImageOptionsEx_offset;
@ -206,51 +208,45 @@ typedef struct _SYSCALL_DATA32 { // win32u.dll
} SYSCALL_DATA32; } 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 // temporary data used by the Detour Code any changed to
// this structure must be synchronized with all 3 versions of the // 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 // in entry_asm.asm and entry_arm.asm
//
// entry_asm.asm, entry_arm.asm and lowlevel_code.c
// //
typedef struct _INJECT_DATA { typedef struct _INJECT_DATA {
ULONG64 sbielow_data; // 0 ULONG64 sbielow_data; // 0
union { ULONG64 RtlFindActCtx; // 8
ULONG64 LdrLoadDll; // 8 ULONG RtlFindActCtx_Protect;
ULONG64 RtlFindActCtx_SavedArg1; // todo: split this UCHAR RtlFindActCtx_Bytes[20];
};
ULONG64 LdrGetProcAddr; // 16
ULONG64 NtRaiseHardError; // 24
ULONG64 RtlFindActCtx; // 32
ULONG RtlFindActCtx_Protect; // 40 ULONG64 LdrLoadDll;
UCHAR RtlFindActCtx_Bytes[20]; // 44 ULONG64 LdrGetProcAddr;
ULONG64 NtProtectVirtualMemory;
ULONG64 NtRaiseHardError;
ULONG64 NtDeviceIoControlFile;
ULONG64 api_device_handle;
USHORT KernelDll_Length; // 64 UNIVERSAL_STRING KernelDll;
USHORT KernelDll_MaxLen; UNIVERSAL_STRING SbieDll;
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
} INJECT_DATA; } INJECT_DATA;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -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

View File

@ -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;
}

View File

@ -30,6 +30,8 @@
extern void Kmd_ScanDll(BOOLEAN silent); extern void Kmd_ScanDll(BOOLEAN silent);
extern BOOL Kmd_FixDacls();
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Defines // Defines
@ -43,7 +45,8 @@ typedef enum _COMMAND {
CMD_STOP, CMD_STOP,
CMD_SCANDLL, CMD_SCANDLL,
CMD_SCANDLL_SILENT, CMD_SCANDLL_SILENT,
CMD_MESSAGE CMD_MESSAGE,
CMD_FIXDACLS
} COMMAND; } COMMAND;
typedef enum _OPTIONS { typedef enum _OPTIONS {
@ -224,6 +227,10 @@ BOOL Parse_Command_Line(
*Command = CMD_MESSAGE; *Command = CMD_MESSAGE;
num_args_needed = 2; num_args_needed = 2;
} else if (_wcsicmp(args[1], L"fixdacls") == 0) {
*Command = CMD_FIXDACLS;
num_args_needed = 0;
} else { } else {
*Command = CMD_ERROR; *Command = CMD_ERROR;
MessageBox(NULL, L"Invalid command", L"KmdUtil", MessageBox(NULL, L"Invalid command", L"KmdUtil",
@ -761,6 +768,16 @@ int __stdcall WinMain(
&Options)) &Options))
return EXIT_FAILURE; 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( ScMgr = OpenSCManager(
NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE); NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
@ -803,9 +820,7 @@ int __stdcall WinMain(
if (Command == CMD_STOP) if (Command == CMD_STOP)
ok = Kmd_Stop_Service(Driver_Name); ok = Kmd_Stop_Service(Driver_Name);
if (Command == CMD_MESSAGE) finish:
ok = Kmd_Show_Message(Driver_Name, Driver_Path);
if (! ok) if (! ok)
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -183,6 +183,20 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <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="KmdUtil.c" />
<ClCompile Include="sbiedrv.c" /> <ClCompile Include="sbiedrv.c" />
<ClCompile Include="scandll.c" /> <ClCompile Include="scandll.c" />

View File

@ -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 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 # %2 = Mozilla Firefox
2191;pop;inf;01 2191;pop;inf;01
SBIE2191 %2 should not be updated while running under Sandboxie. SBIE2191 %2 should not be updated while running under Sandboxie.