Skip to content

Commit cee6c0a

Browse files
authored
Merge pull request #148 from GDATAAdvancedAnalytics/fix-vmprotect
Add compatibility for VMProtect 3.6+
2 parents 480dc49 + 1463828 commit cee6c0a

27 files changed

+423
-85
lines changed

3rdparty/ntdll/ntdll.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4535,6 +4535,47 @@ NTSTATUS
45354535
SIZE_T BufferSize,
45364536
PSIZE_T NumberOfBytesWritten
45374537
);
4538+
4539+
typedef
4540+
NTSTATUS
4541+
(NTAPI
4542+
*t_NtOpenFile)(
4543+
_Out_ PHANDLE FileHandle,
4544+
_In_ ACCESS_MASK DesiredAccess,
4545+
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
4546+
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
4547+
_In_ ULONG ShareAccess,
4548+
_In_ ULONG OpenOptions
4549+
);
4550+
4551+
typedef
4552+
NTSTATUS
4553+
(NTAPI
4554+
*t_NtCreateSection)(
4555+
_Out_ PHANDLE SectionHandle,
4556+
_In_ ACCESS_MASK DesiredAccess,
4557+
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
4558+
_In_opt_ PLARGE_INTEGER MaximumSize,
4559+
_In_ ULONG SectionPageProtection,
4560+
_In_ ULONG AllocationAttributes,
4561+
_In_opt_ HANDLE FileHandle
4562+
);
4563+
4564+
typedef
4565+
NTSTATUS
4566+
(NTAPI
4567+
*t_NtMapViewOfSection)(
4568+
_In_ HANDLE SectionHandle,
4569+
_In_ HANDLE ProcessHandle,
4570+
_Inout_ _At_(*BaseAddress, _Readable_bytes_(*ViewSize) _Writable_bytes_(*ViewSize) _Post_readable_byte_size_(*ViewSize)) PVOID* BaseAddress,
4571+
_In_ ULONG_PTR ZeroBits,
4572+
_In_ SIZE_T CommitSize,
4573+
_Inout_opt_ PLARGE_INTEGER SectionOffset,
4574+
_Inout_ PSIZE_T ViewSize,
4575+
_In_ SECTION_INHERIT InheritDisposition,
4576+
_In_ ULONG AllocationType,
4577+
_In_ ULONG Win32Protect
4578+
);
45384579

45394580
// win32k system calls
45404581
// BlockInput

HookLibrary/Export.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ HookedNtUserGetForegroundWindow
3030
HookedNtUserQueryWindow
3131
HookedNtYieldExecution
3232
HookedOutputDebugStringA
33-
HookedNtResumeThread
33+
HookedNtResumeThread
34+
HookedNtOpenFile
35+
HookedNtCreateSection
36+
HookedNtMapViewOfSection

HookLibrary/HookLibrary.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
</Link>
168168
</ItemDefinitionGroup>
169169
<ItemGroup>
170+
<ClCompile Include="..\Scylla\VersionPatch.cpp" />
170171
<ClCompile Include="HookedFunctions.cpp" />
171172
<ClCompile Include="HookHelper.cpp" />
172173
<ClCompile Include="DllMain.cpp" />
@@ -175,6 +176,7 @@
175176
<None Include="Export.def" />
176177
</ItemGroup>
177178
<ItemGroup>
179+
<ClInclude Include="..\Scylla\VersionPatch.h" />
178180
<ClInclude Include="HookedFunctions.h" />
179181
<ClInclude Include="HookHelper.h" />
180182
<ClInclude Include="HookMain.h" />

HookLibrary/HookLibrary.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<ClCompile Include="DllMain.cpp">
2525
<Filter>Source Files</Filter>
2626
</ClCompile>
27+
<ClCompile Include="..\Scylla\VersionPatch.cpp">
28+
<Filter>Source Files</Filter>
29+
</ClCompile>
2730
</ItemGroup>
2831
<ItemGroup>
2932
<None Include="Export.def">
@@ -43,6 +46,9 @@
4346
<ClInclude Include="Tls.h">
4447
<Filter>Header Files</Filter>
4548
</ClInclude>
49+
<ClInclude Include="..\Scylla\VersionPatch.h">
50+
<Filter>Header Files</Filter>
51+
</ClInclude>
4652
</ItemGroup>
4753
<ItemGroup>
4854
<MASM Include="InstrumentationCallbackX86.asm">

HookLibrary/HookMain.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ typedef struct _HOOK_DLL_DATA {
116116
t_NtCreateThread dNtCreateThread;
117117
DWORD NtCreateThreadBackupSize;
118118

119+
t_NtOpenFile dNtOpenFile;
120+
DWORD NtOpenFileBackupSize;
121+
t_NtCreateSection dNtCreateSection;
122+
DWORD NtCreateSectionBackupSize;
123+
t_NtMapViewOfSection dNtMapViewOfSection;
124+
DWORD NtMapViewOfSectionBackupSize;
125+
119126
/////////////////////////////////////////////////////////
120127
t_GetTickCount dGetTickCount;
121128
DWORD GetTickCountBackupSize;

HookLibrary/HookedFunctions.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ HOOK_DLL_DATA HookDllData = { 0 };
88
#include "HookHelper.h"
99
#include "Tls.h"
1010

11+
#include "Scylla/VersionPatch.h"
12+
1113
void FakeCurrentParentProcessId(PSYSTEM_PROCESS_INFORMATION pInfo);
1214
void FakeCurrentOtherOperationCount(PSYSTEM_PROCESS_INFORMATION pInfo);
1315
void 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+
}

HookLibrary/HookedFunctions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,7 @@ VOID NTAPI HookedKiUserExceptionDispatcher();//(PEXCEPTION_RECORD pExcptRec, PCO
6868
HWND NTAPI HookedNtUserFindWindowEx(HWND hWndParent, HWND hWndChildAfter, PUNICODE_STRING lpszClass, PUNICODE_STRING lpszWindow, DWORD dwType);
6969

7070
NTSTATUS NTAPI HookedNtResumeThread(HANDLE ThreadHandle, PULONG PreviousSuspendCount);
71+
72+
NTSTATUS NTAPI HookedNtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions);
73+
NTSTATUS NTAPI HookedNtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle);
74+
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);

0 commit comments

Comments
 (0)