@@ -8,6 +8,8 @@ HOOK_DLL_DATA HookDllData = { 0 };
88#include " HookHelper.h"
99#include " Tls.h"
1010
11+ #include " Scylla/VersionPatch.h"
12+
1113void FakeCurrentParentProcessId (PSYSTEM_PROCESS_INFORMATION pInfo);
1214void FakeCurrentOtherOperationCount (PSYSTEM_PROCESS_INFORMATION pInfo);
1315void FilterHandleInfo (PSYSTEM_HANDLE_INFORMATION pHandleInfo, PULONG pReturnLengthAdjust);
@@ -1143,3 +1145,107 @@ NTSTATUS NTAPI HookedNtResumeThread(HANDLE ThreadHandle, PULONG PreviousSuspendC
11431145 return HookDllData.dNtResumeThread (ThreadHandle, PreviousSuspendCount);
11441146 }
11451147}
1148+
1149+ HANDLE hNtdllFile = INVALID_HANDLE_VALUE;
1150+ HANDLE hNtdllSection = INVALID_HANDLE_VALUE;
1151+
1152+ NTSTATUS NTAPI HookedNtOpenFile (PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions)
1153+ {
1154+ NTSTATUS status = HookDllData.dNtOpenFile (FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, ShareAccess, OpenOptions);
1155+
1156+ if (NT_SUCCESS (status))
1157+ {
1158+ UNICODE_STRING usNtdll;
1159+ RtlInitUnicodeString (&usNtdll, L" \\ ntdll.dll" );
1160+ if (RtlUnicodeStringContains (ObjectAttributes->ObjectName , &usNtdll, TRUE ))
1161+ {
1162+ hNtdllFile = *FileHandle;
1163+ }
1164+ }
1165+
1166+ return status;
1167+ }
1168+
1169+ NTSTATUS NTAPI HookedNtCreateSection (PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle)
1170+ {
1171+ if (AllocationAttributes == SEC_IMAGE_NO_EXECUTE && RtlNtMajorVersion () <= 6 && (RtlNtMajorVersion () < 6 || RtlNtMinorVersion () < 2 ))
1172+ {
1173+ // Fix for VMProtect. It attempts to use SEC_IMAGE_NO_EXECUTE on OSes that don't support it.
1174+ AllocationAttributes = SEC_IMAGE;
1175+ }
1176+ NTSTATUS status = HookDllData.dNtCreateSection (SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle);
1177+
1178+ if (NT_SUCCESS (status) && hNtdllFile != INVALID_HANDLE_VALUE && FileHandle == hNtdllFile)
1179+ {
1180+ hNtdllFile = INVALID_HANDLE_VALUE;
1181+ hNtdllSection = *SectionHandle;
1182+ }
1183+
1184+ return status;
1185+ }
1186+
1187+ void DestroyMappedNtApi (const char *szProcName, PVOID hRealNtdll, PVOID pMapping)
1188+ {
1189+ PVOID ProcedureAddress;
1190+ ANSI_STRING ProcedureName;
1191+ RtlInitAnsiString (&ProcedureName, (PSTR)szProcName);
1192+ if (NT_SUCCESS (LdrGetProcedureAddress (hRealNtdll, &ProcedureName, 0 , &ProcedureAddress)))
1193+ {
1194+ SIZE_T delta = (ULONG_PTR)ProcedureAddress - (ULONG_PTR)hRealNtdll;
1195+ PUCHAR pMappedApi = (PUCHAR)pMapping + delta;
1196+
1197+ #ifdef _WIN64
1198+ if (*(PDWORD)pMappedApi != 0xB8D18B4C ) // mov r10,rcx; mov eax, callNr
1199+ return ;
1200+
1201+ PVOID ProtAddress = pMappedApi;
1202+ SIZE_T RegionSize = 5 ;
1203+ ULONG OldProtect;
1204+ if (NT_SUCCESS (NtProtectVirtualMemory (NtCurrentProcess, &ProtAddress, &RegionSize, PAGE_READWRITE, &OldProtect)))
1205+ {
1206+ *(PWORD)pMappedApi = 0x0B0F ; // UD2
1207+ *(PWORD)(pMappedApi + 3 ) = 0x0B0F ; // UD2
1208+ NtProtectVirtualMemory (NtCurrentProcess, &ProtAddress, &RegionSize, OldProtect, &OldProtect);
1209+ }
1210+ #else
1211+ if (*pMappedApi != 0xB8 ) // mov eax, callNr
1212+ return ;
1213+
1214+ PVOID ProtAddress = pMappedApi;
1215+ SIZE_T RegionSize = 2 ;
1216+ ULONG OldProtect;
1217+ if (NT_SUCCESS (NtProtectVirtualMemory (NtCurrentProcess, &ProtAddress, &RegionSize, PAGE_READWRITE, &OldProtect)))
1218+ {
1219+ *(PWORD)pMappedApi = 0x0B0F ; // UD2
1220+ NtProtectVirtualMemory (NtCurrentProcess, &ProtAddress, &RegionSize, OldProtect, &OldProtect);
1221+ }
1222+ #endif
1223+ }
1224+ }
1225+
1226+ NTSTATUS NTAPI HookedNtMapViewOfSection (HANDLE SectionHandle, HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Win32Protect)
1227+ {
1228+ NTSTATUS status = HookDllData.dNtMapViewOfSection (SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect);
1229+
1230+ if (NT_SUCCESS (status) && ProcessHandle == NtCurrentProcess && hNtdllSection != INVALID_HANDLE_VALUE && SectionHandle == hNtdllSection)
1231+ {
1232+ hNtdllSection = INVALID_HANDLE_VALUE;
1233+ ApplyNtdllVersionPatch (ProcessHandle, *BaseAddress);
1234+
1235+ // Prevent syscall numbers from being extracted from API code.
1236+ PVOID hRealNtdll;
1237+ UNICODE_STRING usNtdll;
1238+ RtlInitUnicodeString (&usNtdll, L" ntdll.dll" );
1239+ if (NT_SUCCESS (LdrGetDllHandle (NULL , NULL , &usNtdll, &hRealNtdll)))
1240+ {
1241+ DestroyMappedNtApi (" NtSetInformationProcess" , hRealNtdll, *BaseAddress); // If VMProtect can syscall this, it will unset the instrumentation callback.
1242+ DestroyMappedNtApi (" NtQueryInformationProcess" , hRealNtdll, *BaseAddress);
1243+ DestroyMappedNtApi (" NtSetInformationThread" , hRealNtdll, *BaseAddress);
1244+ DestroyMappedNtApi (" NtQueryInformationThread" , hRealNtdll, *BaseAddress);
1245+ DestroyMappedNtApi (" NtQuerySystemInformation" , hRealNtdll, *BaseAddress);
1246+ DestroyMappedNtApi (" NtQueryVirtualMemory" , hRealNtdll, *BaseAddress);
1247+ }
1248+ }
1249+
1250+ return status;
1251+ }
0 commit comments