From 11d540dd463101fdeb433186e895857218250a1f Mon Sep 17 00:00:00 2001 From: Artur Alekseev Date: Thu, 16 Nov 2023 01:49:02 +0300 Subject: [PATCH] VPM Heaven's Gate Bypass by miketestz --- HookLibrary/HookHelper.cpp | 244 ++++++++++++++++++++++++++++++++ HookLibrary/HookHelper.h | 3 + HookLibrary/HookLibrary.vcxproj | 1 + HookLibrary/HookedFunctions.cpp | 27 +++- 4 files changed, 274 insertions(+), 1 deletion(-) diff --git a/HookLibrary/HookHelper.cpp b/HookLibrary/HookHelper.cpp index 474bc910..8a9ba91d 100644 --- a/HookLibrary/HookHelper.cpp +++ b/HookLibrary/HookHelper.cpp @@ -708,3 +708,247 @@ bool WriteMemoryToFile(const WCHAR * filename, LPCVOID buffer, DWORD bufferSize, return NT_SUCCESS(status); } + +#ifndef _WIN64 // Windows 7-8.1 do not support x86/WOW64 instrumentation callbacks +LONG CALLBACK VMPSysenterHandler(EXCEPTION_POINTERS* info) +{ + int ExceptionCode = info->ExceptionRecord->ExceptionCode; + ULONG_PTR ExceptionInfo0 = info->ExceptionRecord->ExceptionInformation[0]; + ULONG_PTR ExceptionInfo1 = info->ExceptionRecord->ExceptionInformation[1]; + ULONG_PTR ExceptionAddr = (ULONG_PTR)info->ExceptionRecord->ExceptionAddress; + + if (ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + { + if (ExceptionInfo0 == 0) // Read + if (ExceptionInfo1 == -1) // InAccessible Address + if (!IsBadReadPtr((void*)ExceptionAddr, 2)) + if (*reinterpret_cast(ExceptionAddr) == 0x340F) // sysenter + { + //x32bit syscall_number windows 10 22H2 19045.3324 ~ + enum SYSCALLNAME : ULONG { + NTSETINFORMATIONPROCESS = 0x4F, + NTQUERYINFORMATIONPROCESS = 0xB9, + NTSETINFORMATIONTHREAD = 0x4D, + NTOPENFILE = 0xF4, + NTCREATESECTION = 0x163, + NTMAPVIEWOFSECTION = 0x101, + NTUNMAPVIEWOFSECTION = 0x14, + NTCLOSE = 0x18E, + NTPROTECTVIRTUALMEMORY = 0xCE, + NTQUERYVIRTUALMEMORY = 0x97, + NTQUERYSYSTEMINFORMATION = 0x9D + }; + + + ULONG Syscallnum = info->ContextRecord->Eax; + + PVOID FuncArgs = reinterpret_cast(info->ContextRecord->Esp + 8); + + switch (Syscallnum) + { + case SYSCALLNAME::NTSETINFORMATIONPROCESS: + { + //ProcessWow64Information + + HANDLE ProcessHandle = *reinterpret_cast(FuncArgs); + PROCESSINFOCLASS pclass = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + PVOID informationbuffer = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + ULONG buffersize = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + + if (pclass != ProcessInstrumentationCallback) + info->ContextRecord->Eax = NtSetInformationProcess(ProcessHandle, pclass, informationbuffer, buffersize); + else + { + info->ContextRecord->Eax = 0; + } + + info->ContextRecord->Eip += 2; + + break; + } + case SYSCALLNAME::NTQUERYINFORMATIONPROCESS: + { + + HANDLE ProcessHandle = *reinterpret_cast(FuncArgs); + PROCESSINFOCLASS pclass = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + PVOID informationbuffer = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + ULONG buffersize = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + PULONG returnbuffersize = *reinterpret_cast((ULONG_PTR*)FuncArgs + 4); + + info->ContextRecord->Eax = NtQueryInformationProcess(ProcessHandle, pclass, informationbuffer, buffersize, returnbuffersize); + + info->ContextRecord->Eip += 2; + + break; + } + case SYSCALLNAME::NTSETINFORMATIONTHREAD: + { + + HANDLE ProcessHandle = *reinterpret_cast(FuncArgs); + THREADINFOCLASS tclass = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + PVOID threadinformation = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + ULONG buffersize = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + + info->ContextRecord->Eax = NtSetInformationThread(ProcessHandle, tclass, threadinformation, buffersize); + + info->ContextRecord->Eip += 2; + + break; + } + case SYSCALLNAME::NTOPENFILE: + { + + + PHANDLE PProcessHandle = *reinterpret_cast(FuncArgs); + ACCESS_MASK accessmask = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + POBJECT_ATTRIBUTES attribute = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + PIO_STATUS_BLOCK io_block = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + ULONG shareaccess = *reinterpret_cast((ULONG_PTR*)FuncArgs + 4); + ULONG openoption = *reinterpret_cast((ULONG_PTR*)FuncArgs + 5); + + info->ContextRecord->Eax = NtOpenFile(PProcessHandle, accessmask, attribute, io_block, shareaccess, openoption); + + info->ContextRecord->Eip += 2; + + break; + } + case SYSCALLNAME::NTCREATESECTION: + { + + PHANDLE SectionHandle = *reinterpret_cast(FuncArgs); + ACCESS_MASK accessmask = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + POBJECT_ATTRIBUTES attribute = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + PLARGE_INTEGER largeinteger = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + ULONG shareaccess = *reinterpret_cast((ULONG_PTR*)FuncArgs + 4); + ULONG openoption = *reinterpret_cast((ULONG_PTR*)FuncArgs + 5); + HANDLE filehandle = *reinterpret_cast((ULONG_PTR*)FuncArgs + 6); + + info->ContextRecord->Eax = NtCreateSection( + SectionHandle, + accessmask, + attribute, + largeinteger, + shareaccess, + openoption, + filehandle + ); + + info->ContextRecord->Eip += 2; + + break; + } + case SYSCALLNAME::NTMAPVIEWOFSECTION: + { + HANDLE SectionHandle = *reinterpret_cast(FuncArgs); + HANDLE ProcessHandle = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + PVOID* Baseaddress = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + ULONG_PTR Zerobits = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + SIZE_T commitsize = *reinterpret_cast((ULONG_PTR*)FuncArgs + 4); + PLARGE_INTEGER largeinteger = *reinterpret_cast((ULONG_PTR*)FuncArgs + 5); + PSIZE_T viewsize = *reinterpret_cast((ULONG_PTR*)FuncArgs + 6); + SECTION_INHERIT inhertdispos = *reinterpret_cast((ULONG_PTR*)FuncArgs + 7); + ULONG AllocationType = *reinterpret_cast((ULONG_PTR*)FuncArgs + 8); + ULONG Win32Protect = *reinterpret_cast((ULONG_PTR*)FuncArgs + 9); + + info->ContextRecord->Eax = NtMapViewOfSection( + SectionHandle, + ProcessHandle, + Baseaddress, + Zerobits, + commitsize, + largeinteger, + viewsize, + inhertdispos, + AllocationType, + Win32Protect + ); + + info->ContextRecord->Eip += 2; + + break; + } + case SYSCALLNAME::NTUNMAPVIEWOFSECTION: + { + HANDLE ProcessHandle = *reinterpret_cast(FuncArgs); + PVOID Baseaddress = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + + info->ContextRecord->Eax = NtUnmapViewOfSection(ProcessHandle, Baseaddress); + + info->ContextRecord->Eip += 2; + + break; + } + case SYSCALLNAME::NTCLOSE: + { + HANDLE Handle = *reinterpret_cast(FuncArgs); + info->ContextRecord->Eax = NtClose(Handle); + + info->ContextRecord->Eip += 2; + break; + } + case SYSCALLNAME::NTPROTECTVIRTUALMEMORY: + { + + HANDLE ProcessHandle = *reinterpret_cast(FuncArgs); + PVOID* Baseaddress = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + PSIZE_T RegionSize = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + ULONG NewProt = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + PULONG OldProt = *reinterpret_cast((ULONG_PTR*)FuncArgs + 4); + + info->ContextRecord->Eax = NtProtectVirtualMemory(ProcessHandle, Baseaddress, RegionSize, NewProt, OldProt); + + info->ContextRecord->Eip += 2; + break; + } + case SYSCALLNAME::NTQUERYVIRTUALMEMORY: + { + HANDLE ProcessHandle = *reinterpret_cast(FuncArgs); + PVOID Baseaddress = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + MEMORY_INFORMATION_CLASS meminfoclass = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + PVOID MemoryInformation = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + SIZE_T MemoryInformationLength = *reinterpret_cast((ULONG_PTR*)FuncArgs + 4); + PSIZE_T ReturnLength = *reinterpret_cast((ULONG_PTR*)FuncArgs + 5); + + info->ContextRecord->Eax = NtQueryVirtualMemory( + ProcessHandle, + Baseaddress, + meminfoclass, + MemoryInformation, + MemoryInformationLength, + ReturnLength + ); + + info->ContextRecord->Eip += 2; + break; + } + case SYSCALLNAME::NTQUERYSYSTEMINFORMATION: + { + SYSTEM_INFORMATION_CLASS SysteminformationClass = *reinterpret_cast(FuncArgs); + PVOID SystemInformation = *reinterpret_cast((ULONG_PTR*)FuncArgs + 1); + ULONG SystemInformationLength = *reinterpret_cast((ULONG_PTR*)FuncArgs + 2); + PULONG ReturnLength = *reinterpret_cast((ULONG_PTR*)FuncArgs + 3); + + info->ContextRecord->Eax = NtQuerySystemInformation( + SysteminformationClass, + SystemInformation, + SystemInformationLength, + ReturnLength + ); + + info->ContextRecord->Eip += 2; + break; + } + default: + { + return EXCEPTION_CONTINUE_SEARCH; + } + } + + + return EXCEPTION_CONTINUE_EXECUTION; + } + } + + return EXCEPTION_CONTINUE_SEARCH; +} +#endif diff --git a/HookLibrary/HookHelper.h b/HookLibrary/HookHelper.h index 65e4a816..39b9cc8a 100644 --- a/HookLibrary/HookHelper.h +++ b/HookLibrary/HookHelper.h @@ -48,3 +48,6 @@ bool WriteMalwareToDisk(LPCVOID buffer, DWORD bufferSize, DWORD_PTR imagebase); bool WriteMemoryToFile(const WCHAR * filename, LPCVOID buffer, DWORD bufferSize, DWORD_PTR imagebase); void * GetPEBRemote(HANDLE hProcess); void DumpMalware(DWORD dwProcessId); +#ifndef _WIN64 // Only wow64process +LONG CALLBACK VMPSysenterHandler(EXCEPTION_POINTERS* info); +#endif diff --git a/HookLibrary/HookLibrary.vcxproj b/HookLibrary/HookLibrary.vcxproj index 687e1299..e625634d 100644 --- a/HookLibrary/HookLibrary.vcxproj +++ b/HookLibrary/HookLibrary.vcxproj @@ -149,6 +149,7 @@ Windows Export.def false + kernel32.lib;ntdll.lib;%(AdditionalDependencies) diff --git a/HookLibrary/HookedFunctions.cpp b/HookLibrary/HookedFunctions.cpp index 591f7f70..2752eddf 100644 --- a/HookLibrary/HookedFunctions.cpp +++ b/HookLibrary/HookedFunctions.cpp @@ -230,13 +230,22 @@ NTSTATUS NTAPI HookedNtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFO return STATUS_PORT_NOT_SET; } - +#ifndef _WIN64 // Only wow64process + if ((ProcessInformationClass == ProcessDebugFlags || + ProcessInformationClass == ProcessDebugPort || + ProcessInformationClass == ProcessBasicInformation || + ProcessInformationClass == ProcessBreakOnTermination || + ProcessInformationClass == ProcessHandleTracing || + ProcessInformationClass == ProcessIoCounters || + ProcessInformationClass == ProcessWow64Information) && +#else if ((ProcessInformationClass == ProcessDebugFlags || ProcessInformationClass == ProcessDebugPort || ProcessInformationClass == ProcessBasicInformation || ProcessInformationClass == ProcessBreakOnTermination || ProcessInformationClass == ProcessHandleTracing || ProcessInformationClass == ProcessIoCounters) && +#endif (ProcessHandle == NtCurrentProcess || HandleToULong(NtCurrentTeb()->ClientId.UniqueProcess) == GetProcessIdByProcessHandle(ProcessHandle))) { Status = HookDllData.dNtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength); @@ -290,6 +299,22 @@ NTSTATUS NTAPI HookedNtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFO RESTORE_RETURNLENGTH(); } +#ifndef _WIN64 // Only wow64process + else if (ProcessInformationClass == ProcessWow64Information) + { + BACKUP_RETURNLENGTH(); + static bool vectorinstall = false; + if (vectorinstall == false) + { + AddVectoredExceptionHandler(1, &VMPSysenterHandler); + vectorinstall = true; + } + + *((ULONG_PTR*)ProcessInformation) = 0; + + RESTORE_RETURNLENGTH(); + } +#endif } return Status;