From 6595d2756b48cdeac3fc4f9a4b0253768e72e918 Mon Sep 17 00:00:00 2001 From: CSlime <41416733+CS1ime@users.noreply.github.com> Date: Tue, 19 Oct 2021 19:44:12 +0800 Subject: [PATCH] qwq pwp --- DICHook_OpenSource.sln | 51 ++ DICHook_OpenSource/DDKCommon.cpp | 609 ++++++++++++++++ DICHook_OpenSource/DDKCommon.h | 101 +++ DICHook_OpenSource/DICHook_OpenSource.inf | 32 + DICHook_OpenSource/DICHook_OpenSource.vcxproj | 181 +++++ .../DICHook_OpenSource.vcxproj.filters | 68 ++ .../DICHook_OpenSource.vcxproj.user | 6 + DICHook_OpenSource/HwidHook.cpp | 681 ++++++++++++++++++ DICHook_OpenSource/HwidHook.h | 26 + DICHook_OpenSource/KernelAsm.asm | 270 +++++++ DICHook_OpenSource/KernelAsm.h | 172 +++++ DICHook_OpenSource/MyMemoryIo64.cpp | 131 ++++ DICHook_OpenSource/MyMemoryIo64.h | 156 ++++ DICHook_OpenSource/MyPEB.h | 139 ++++ DICHook_OpenSource/NtFunctionDefine.h | 248 +++++++ DICHook_OpenSource/main.cpp | 65 ++ DICHook_OpenSource/vtstruct.h | 605 ++++++++++++++++ 17 files changed, 3541 insertions(+) create mode 100644 DICHook_OpenSource.sln create mode 100644 DICHook_OpenSource/DDKCommon.cpp create mode 100644 DICHook_OpenSource/DDKCommon.h create mode 100644 DICHook_OpenSource/DICHook_OpenSource.inf create mode 100644 DICHook_OpenSource/DICHook_OpenSource.vcxproj create mode 100644 DICHook_OpenSource/DICHook_OpenSource.vcxproj.filters create mode 100644 DICHook_OpenSource/DICHook_OpenSource.vcxproj.user create mode 100644 DICHook_OpenSource/HwidHook.cpp create mode 100644 DICHook_OpenSource/HwidHook.h create mode 100644 DICHook_OpenSource/KernelAsm.asm create mode 100644 DICHook_OpenSource/KernelAsm.h create mode 100644 DICHook_OpenSource/MyMemoryIo64.cpp create mode 100644 DICHook_OpenSource/MyMemoryIo64.h create mode 100644 DICHook_OpenSource/MyPEB.h create mode 100644 DICHook_OpenSource/NtFunctionDefine.h create mode 100644 DICHook_OpenSource/main.cpp create mode 100644 DICHook_OpenSource/vtstruct.h diff --git a/DICHook_OpenSource.sln b/DICHook_OpenSource.sln new file mode 100644 index 0000000..e37b156 --- /dev/null +++ b/DICHook_OpenSource.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31515.178 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DICHook_OpenSource", "DICHook_OpenSource\DICHook_OpenSource.vcxproj", "{788C82FC-D258-4C61-A8DA-C12DC560FCAD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|ARM.ActiveCfg = Debug|ARM + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|ARM.Build.0 = Debug|ARM + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|ARM.Deploy.0 = Debug|ARM + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|ARM64.Build.0 = Debug|ARM64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|x64.ActiveCfg = Debug|x64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|x64.Build.0 = Debug|x64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|x64.Deploy.0 = Debug|x64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|x86.ActiveCfg = Debug|Win32 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|x86.Build.0 = Debug|Win32 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Debug|x86.Deploy.0 = Debug|Win32 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|ARM.ActiveCfg = Release|ARM + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|ARM.Build.0 = Release|ARM + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|ARM.Deploy.0 = Release|ARM + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|ARM64.ActiveCfg = Release|ARM64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|ARM64.Build.0 = Release|ARM64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|ARM64.Deploy.0 = Release|ARM64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|x64.ActiveCfg = Release|x64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|x64.Build.0 = Release|x64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|x64.Deploy.0 = Release|x64 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|x86.ActiveCfg = Release|Win32 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|x86.Build.0 = Release|Win32 + {788C82FC-D258-4C61-A8DA-C12DC560FCAD}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0F5EA8A1-6BCE-462A-87DA-DD9CA15E4D26} + EndGlobalSection +EndGlobal diff --git a/DICHook_OpenSource/DDKCommon.cpp b/DICHook_OpenSource/DDKCommon.cpp new file mode 100644 index 0000000..d98b115 --- /dev/null +++ b/DICHook_OpenSource/DDKCommon.cpp @@ -0,0 +1,609 @@ +#include "DDKCommon.h" +#include "MyMemoryIo64.h" +#pragma comment(lib,"oldnames.lib") + +typedef struct _SBYTEINFO_3 { + UCHAR RawByte; + UCHAR Hi : 1; //Hi 4 bit is ?? + UCHAR Lo : 1; //Lo 4 bit is ?? + UCHAR All : 1; + UCHAR No : 1; +}SBYTEINFO_3, *PSBYTEINFO_3; +typedef struct _SBYTEINFO_2 { + UCHAR RawByte; + BOOLEAN All; +}SBYTEINFO_2, *PSBYTEINFO_2; + +void AnsiToUnicode(LPCSTR AnsiStr, LPWSTR UnicodeStrBuffer, ULONG MaxLenth) { + int len = strlen(AnsiStr); + if (len > MaxLenth)len = MaxLenth; + UnicodeStrBuffer[len] = 0; + for (int i = 0; i < len; ++i) { + UnicodeStrBuffer[i] = AnsiStr[i]; + } + return; +} +void UnicodeToAnsi(LPCWSTR UnicodeStr, LPSTR AnsiStrBuffer, ULONG MaxLenth) { + int len = wcslen(UnicodeStr); + if (len > MaxLenth)len = MaxLenth; + + AnsiStrBuffer[len] = 0; + for (int i = 0; i < len; ++i) { + AnsiStrBuffer[i] = UnicodeStr[i]; + } + return; +} + +static ULONG64 g_per = 0; +static BOOL g_first = TRUE; +ULONG64 GetRealTime() { + if (g_first) { + g_first = FALSE; + + ULONG64 fir, sec; + fir = AsmRdtsc(); + Sleep(50); + sec = AsmRdtsc(); + + g_per = (sec - fir) / 50; + + } + + return AsmRdtsc() / g_per; +} +static ULONG64 g_per_micro = 0; +static BOOL g_first_micro = TRUE; +ULONG64 GetRealMicroTime() { + if (g_first_micro) { + g_first_micro = FALSE; + + ULONG64 fir, sec; + fir = AsmRdtsc(); + Sleep(50); + sec = AsmRdtsc(); + + g_per_micro = (sec - fir) / 50000; + + } + + return AsmRdtsc() / g_per_micro; +} +VOID Sleep(LONG Millsecond) { + LARGE_INTEGER t; + t.QuadPart = Millsecond; + //µ¥Î»:100ÄÉÃë + t.QuadPart *= -10 * 1000; + KeDelayExecutionThread(KernelMode, FALSE, &t); + return; +} +VOID ForceSleep(LONG Millsecond) { + KeStallExecutionProcessor(Millsecond * 1000); +} + +LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch) +{ + int iLen; + LPCWSTR end; + + if (!lpszStr || !lpszSearch || !*lpszSearch) + return NULL; + + iLen = wcslen(lpszSearch); + end = lpszStr + wcslen(lpszStr); + + while (lpszStr + iLen <= end) + { + if (!wcsnicmp(lpszStr, lpszSearch, iLen)) + return (LPWSTR)lpszStr; + lpszStr++; + } + return NULL; +} +LPWSTR WINAPI StrStrNIW(LPCWSTR lpszStr, LPCWSTR lpszSearch, SIZE_T max_chars) +{ + int iLen; + LPCWSTR end; + + if (!lpszStr || !lpszSearch || !*lpszSearch || !max_chars) + return NULL; + + iLen = wcslen(lpszSearch); + end = lpszStr + max_chars; + + while (lpszStr + iLen <= end) + { + if (!wcsnicmp(lpszStr, lpszSearch, iLen)) + return (LPWSTR)lpszStr; + lpszStr++; + } + return NULL; +} +LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch) +{ + int iLen; + LPCSTR end; + + if (!lpszStr || !lpszSearch || !*lpszSearch) + return NULL; + + iLen = strlen(lpszSearch); + end = lpszStr + strlen(lpszStr); + + while (lpszStr + iLen <= end) + { + if (!strnicmp(lpszStr, lpszSearch, iLen)) + return (LPSTR)lpszStr; + lpszStr++; + } + return NULL; +} +LPSTR WINAPI StrStrNIA(LPCSTR lpszStr, LPCSTR lpszSearch, SIZE_T max_chars) +{ + int iLen; + LPCSTR end; + + if (!lpszStr || !lpszSearch || !*lpszSearch || !max_chars) + return NULL; + + iLen = strlen(lpszSearch); + end = lpszStr + max_chars; + + while (lpszStr + iLen <= end) + { + if (!strnicmp(lpszStr, lpszSearch, iLen)) + return (LPSTR)lpszStr; + lpszStr++; + } + return NULL; +} + +UCHAR CharToByte(UCHAR c) { + if (c >= '0' && c <= '9') return(c - 48); + else if (c >= 'A' && c <= 'F')return(c - 55); + else if (c >= 'a' && c <= 'f')return(c - 87); + return 0; +} +#define STRTOBYTE(h) (CharToByte(h[0]) * 0x10 + CharToByte(h[1])) +UCHAR StrToByte(const char* hex) { + return CharToByte(hex[0]) * 0x10 + CharToByte(hex[1]); +} +ULONG __strlen__(LPCSTR str) { + register ULONG len = 0; + while (*str++)++len; + return len; +} +#define CHECKCHARVALID(v) ((v >= '0' && v <= '9') || (v >= 'A' && v <= 'F') || (v >= 'a' && v <= 'f') || v == '?') +ULONG CheckForSignureCode(LPCSTR scode) { + ULONG len = __strlen__(scode); + LPCSTR str = scode; + if (len % 2)return FALSE; + str = scode; + ULONG Type = 1; + for (int i = 0; i < len; i += 2) { + if (!CHECKCHARVALID(scode[i]) || !CHECKCHARVALID(scode[i + 1]))return 0; + if (scode[i] == '?' && scode[i + 1] != '?') { + return 3; + } + if (scode[i + 1] == '?' && scode[i] != '?') { + return 3; + } + if (scode[i] == '?' && scode[i + 1] == '?')Type = 2; + } + return Type; +} + +#define HI4BIT(v) (v>>4) +#define LO4BIT(v) (v&0x0f) + +BOOLEAN __forceinline CompareByte_3(UCHAR byte, PSBYTEINFO_3 sbyte) { + if (sbyte->No)return byte == sbyte->RawByte; + if (sbyte->All) return TRUE; + if (sbyte->Hi) { + return sbyte->RawByte == LO4BIT(byte); + } + if (sbyte->Lo) { + return sbyte->RawByte == HI4BIT(byte); + } + return FALSE; +} +VOID __forceinline convert_scode_sbyte_3(LPCSTR SignatureCode, PSBYTEINFO_3 rawbyte) { + ULONG len = __strlen__(SignatureCode) / 2; + memset(rawbyte, 0, len * sizeof(SBYTEINFO_3)); + for (int i = 0; i < len; i++) { + LPCSTR scode = SignatureCode + i * 2; + if (scode[0] == '?' && scode[1] == '?') { + rawbyte[i].All = TRUE; + continue; + } + if (scode[0] == '?') { + rawbyte[i].Hi = TRUE; + rawbyte[i].RawByte = CharToByte(scode[1]); + continue; + } + if (scode[1] == '?') { + rawbyte[i].Lo = TRUE; + rawbyte[i].RawByte = CharToByte(scode[0]); + continue; + } + rawbyte[i].RawByte = STRTOBYTE(scode); + rawbyte[i].No = TRUE; + } +} +VOID __forceinline convert_scode_sbyte_2(LPCSTR SignatureCode, PSBYTEINFO_2 rawbyte) { + ULONG len = __strlen__(SignatureCode) / 2; + memset(rawbyte, 0, len * sizeof(SBYTEINFO_2)); + for (int i = 0; i < len; i++) { + LPCSTR scode = SignatureCode + i * 2; + if (scode[0] == '?') { + rawbyte[i].All = TRUE; + continue; + } + rawbyte[i].RawByte = STRTOBYTE(scode); + } +} +INT64 FindSignatureCode_3_nocheck(const PUCHAR Memory, UINT64 MemoryLenth, LPCSTR SignatureCode, UINT64 Pos) { + ULONG len = __strlen__(SignatureCode) / 2; + if (len > 100) + return -1; + SBYTEINFO_3 rawbyte[100]; + memset(rawbyte, 0, sizeof(rawbyte)); + + convert_scode_sbyte_3(SignatureCode, rawbyte); + + register PSBYTEINFO_3 sbyte = rawbyte; + UINT64 opos = 0; + register UINT64 cmppos = 0; + register BOOLEAN Hit = FALSE; + for (UINT64 i = Pos; i < MemoryLenth; ++i) { + if (CompareByte_3(Memory[i], sbyte)) { + if (!Hit) { + opos = i; + Hit = TRUE; + } + ++sbyte; + if (++cmppos == len) { + return i - (len - 1); + } + } + else { + if (Hit) { + if (Hit)i = opos; + Hit = FALSE; + cmppos = 0; + sbyte = rawbyte; + } + } + + } + return -1; +} +INT64 FindSignatureCode_2_nocheck(const PUCHAR Memory, UINT64 MemoryLenth, LPCSTR SignatureCode, UINT64 Pos) { + ULONG len = __strlen__(SignatureCode) / 2; + ULONG PoolSize = len * sizeof(SBYTEINFO_2); + + if (len > 100) + return -1; + SBYTEINFO_2 rawbyte[100]; + memset(rawbyte, 0, sizeof(rawbyte)); + + convert_scode_sbyte_2(SignatureCode, rawbyte); + + register PSBYTEINFO_2 sbyte = rawbyte; + UINT64 opos = 0; + register UINT64 cmppos = 0; + register BOOLEAN Hit = FALSE; + for (register UINT64 i = Pos; i < MemoryLenth; ++i) { + if (sbyte->All || (Memory[i] == sbyte->RawByte)) { + if (!Hit) { + opos = i; + Hit = TRUE; + } + ++sbyte; + if (++cmppos == len) { + return i - (len - 1); + } + } + else { + if (Hit) { + i = opos; + Hit = FALSE; + cmppos = 0; + sbyte = rawbyte; + } + } + } + return -1; +} +INT64 FindSignatureCode_nocheck(LPCVOID Memory, UINT64 MemoryLenth, LPCSTR SignatureCode, UINT64 Pos) { + CHAR realPattern[300]; + RtlZeroMemory(realPattern, sizeof(realPattern)); + int len = strlen(SignatureCode); + int j = 0; + for (int i = 0; i < len; i++) { + if (SignatureCode[i] != ' ') { + realPattern[j++] = SignatureCode[i]; + if (j > 299) + break; + } + } + + ULONG type = CheckForSignureCode(realPattern); + if (!type)return -1; + if (type == 3)return FindSignatureCode_3_nocheck((const PUCHAR)Memory, MemoryLenth, realPattern, Pos); + if (type == 2 || type == 1) return FindSignatureCode_2_nocheck((const PUCHAR)Memory, MemoryLenth, realPattern, Pos); + + return -1; +} + +ULONG64 ScanSection(LPCSTR SectionName, LPCSTR Pattern) { + PIMAGE_NT_HEADERS pHdr; + PIMAGE_SECTION_HEADER pFirstSec; + PIMAGE_SECTION_HEADER pSec; + PUCHAR ntosBase; + + ntosBase = (PUCHAR)KGetNtoskrnl(); + + if (!ntosBase) + return NULL; + IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)ntosBase; + pHdr = (IMAGE_NT_HEADERS*)(ntosBase + idh->e_lfanew); + pFirstSec = IMAGE_FIRST_SECTION(pHdr); + for (pSec = pFirstSec; pSec < pFirstSec + pHdr->FileHeader.NumberOfSections; pSec++) + { + CHAR Name[9]; + RtlZeroMemory(&Name, 9); + memcpy(Name, pSec->Name, 8); + if (!strcmp(SectionName, Name)) + { + PUCHAR pFound = NULL; + INT64 pos = FindSignatureCode_nocheck(ntosBase + pSec->VirtualAddress, pSec->Misc.VirtualSize, Pattern, 0); + if (pos != -1) + { + return (ULONG64)(pos + ntosBase + pSec->VirtualAddress); + } + + } + } + return NULL; +} +ULONG64 ScanSection_Image(LPCVOID hImage, LPCSTR SectionName, LPCSTR Pattern) { + PIMAGE_NT_HEADERS pHdr; + PIMAGE_SECTION_HEADER pFirstSec; + PIMAGE_SECTION_HEADER pSec; + PUCHAR ntosBase; + + ntosBase = (PUCHAR)hImage; + + if (!ntosBase) + return NULL; + IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)ntosBase; + pHdr = (IMAGE_NT_HEADERS*)(ntosBase + idh->e_lfanew); + pFirstSec = IMAGE_FIRST_SECTION(pHdr); + for (pSec = pFirstSec; pSec < pFirstSec + pHdr->FileHeader.NumberOfSections; pSec++) + { + CHAR Name[9]; + RtlZeroMemory(&Name, 9); + memcpy(Name, pSec->Name, 8); + if (!strcmp(SectionName, Name)) + { + PUCHAR pFound = NULL; + INT64 pos = FindSignatureCode_nocheck(ntosBase + pSec->VirtualAddress, pSec->Misc.VirtualSize, Pattern, 0); + if (pos != -1) + { + return (ULONG64)(pos + ntosBase + pSec->VirtualAddress); + } + + } + } + return NULL; +} +PVOID KGetDriverImageBase2(PCHAR name) { + PVOID addr = 0; + + ULONG size = 0; + NTSTATUS status = ZwQuerySystemInformation(SystemModuleInformation, 0, 0, &size); + if (STATUS_INFO_LENGTH_MISMATCH != status) { + return addr; + } + + PSYSTEM_MODULE_INFORMATION modules = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(NonPagedPoolNx, size, POOL_TAG); + if (!modules) { + return addr; + } + + if (!NT_SUCCESS(status = ZwQuerySystemInformation(SystemModuleInformation, modules, size, 0))) { + return addr; + } + int name_len = strlen(name); + for (ULONG i = 0; i < modules->NumberOfModules; ++i) { + SYSTEM_MODULE m = modules->Modules[i]; + UCHAR buf[256 + 1]; + RtlZeroMemory(buf, sizeof(buf)); + memcpy(buf, m.FullPathName, 256); + if (StrStrIA((LPCSTR)buf, name)) { + addr = m.ImageBase; + break; + } + } + + ExFreePoolWithTag(modules, POOL_TAG); + return addr; +} +ULONG KGetDriverImageSize2(PCHAR name) { + ULONG addr = 0; + + ULONG size = 0; + NTSTATUS status = ZwQuerySystemInformation(SystemModuleInformation, 0, 0, &size); + if (STATUS_INFO_LENGTH_MISMATCH != status) { + return addr; + } + + PSYSTEM_MODULE_INFORMATION modules = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(NonPagedPoolNx, size, POOL_TAG); + if (!modules) { + return addr; + } + + if (!NT_SUCCESS(status = ZwQuerySystemInformation(SystemModuleInformation, modules, size, 0))) { + return addr; + } + + for (ULONG i = 0; i < modules->NumberOfModules; ++i) { + SYSTEM_MODULE m = modules->Modules[i]; + UCHAR buf[256 + 1]; + RtlZeroMemory(buf, sizeof(buf)); + memcpy(buf, m.FullPathName, 256); + if (StrStrIA((LPCSTR)buf, name)) { + addr = m.ImageSize; + break; + } + } + + ExFreePoolWithTag(modules, POOL_TAG); + return addr; +} +PVOID KGetDriverImageBase(LPCWSTR DriverName) { + CHAR str[300]; + UnicodeToAnsi(DriverName, str, 300); + return KGetDriverImageBase2(str); +} +ULONG KGetDriverImageSize(LPCWSTR DriverName) { + CHAR str[300]; + UnicodeToAnsi(DriverName, str, 300); + return KGetDriverImageSize2(str); +} +ULONG64 KGetProcessCr3(PEPROCESS Process) { + return *(PULONG64)(((PUCHAR)Process) + 0x28); +} +ULONG g_cachedBuildNumber = 0; +ULONG KGetBuildNumber() { + if (g_cachedBuildNumber) + return g_cachedBuildNumber; + RTL_OSVERSIONINFOW ow; + if (!NT_SUCCESS(RtlGetVersion(&ow))) { + return 0; + } + g_cachedBuildNumber = ow.dwBuildNumber; + return ow.dwBuildNumber; +} + +PVOID g_NtoskrnlBase = 0; +PVOID g_HaldllBase = 0; + +PVOID KGetNtoskrnl() { + if (g_NtoskrnlBase) { + return g_NtoskrnlBase; + } + g_NtoskrnlBase = KGetDriverImageBase2("ntoskrnl.exe"); + return g_NtoskrnlBase; +} +PVOID KGetProcAddress(PVOID ModuleHandle, LPCSTR ProcName) { + IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)ModuleHandle; + IMAGE_NT_HEADERS64 *inh = (IMAGE_NT_HEADERS64 *)(idh->e_lfanew + (PUCHAR)idh); + IMAGE_EXPORT_DIRECTORY *ied = (IMAGE_EXPORT_DIRECTORY *)((PUCHAR)ModuleHandle + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); + + for (int i = 0; i < ied->NumberOfNames; i++) { + WORD index = ((WORD *)((PUCHAR)ModuleHandle + ied->AddressOfNameOrdinals))[i]; + ULONG NameRVA = ((ULONG *)((PUCHAR)ModuleHandle + ied->AddressOfNames))[i]; + PCSTR Name = (PCSTR)(((ULONG64)ModuleHandle) + NameRVA); + + if (!strcmp(Name, ProcName)) { + ULONG FunRVA = ((ULONG *)((PUCHAR)ModuleHandle + ied->AddressOfFunctions))[index]; + PUCHAR FunAddress = ((PUCHAR)ModuleHandle + FunRVA); + + BOOLEAN IsBoundImport = FALSE; + ULONG BoundImportNameLenth = 0; + for (ULONG i = 0; i < 50; i++) { + PUCHAR pAddr = FunAddress + i; + UCHAR c = *pAddr; + if (c == '.' && i > 0) { + IsBoundImport = TRUE; + BoundImportNameLenth = i; + break; + } + else { + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))) { + break; + } + } + } + if (IsBoundImport) { + UCHAR BoundImportModuleName[160]; + RtlZeroMemory(BoundImportModuleName, sizeof(BoundImportModuleName)); + memcpy(BoundImportModuleName, FunAddress, BoundImportNameLenth); + + LPCSTR BoundImportFunctionName = (LPCSTR)(FunAddress + BoundImportNameLenth + 1); + ULONG64 base = (ULONG64)KGetDriverImageBase2((PCHAR)BoundImportModuleName); + if (base) { + return KGetProcAddress((PVOID)base, BoundImportFunctionName); + } + + + } + + return FunAddress; + } + + } + + return NULL; +} + +PVOID64 KGetPteBase_Signature() { + DWORD64 Ntoskrnl = (DWORD64)KGetNtoskrnl(); + DWORD64 Fun = (DWORD64)KGetProcAddress((PVOID)Ntoskrnl, "MmGetVirtualForPhysical"); + DWORD64 pos = FindSignatureCode_nocheck((LPCVOID)Fun, 0x200, "48BA????????????????48C1E219", 0); + if (pos == -1)return NULL; + return *(PVOID64 *)(pos + Fun + 2); +} +PVOID64 KGetPteBase() { + ULONG BuildNumber = KGetBuildNumber(); + ULONG64 pte_base = 0; + if (BuildNumber < 14316) { + //win10 + pte_base = 0xFFFFF68000000000; + } + else { + ULONG64 cr3_mask = ~(ULONG64)0xFFF; + ULONG64 cr3 = __readcr3() & cr3_mask; + PHYSICAL_ADDRESS phy; + phy.QuadPart = cr3; + ULONG64 vir = (ULONG64)MmGetVirtualForPhysical(phy); + if (vir) { + for (int i = 0; i < 0x200; i++) { + HardwarePteX64 v; + v.all = *(ULONG64*)(vir + i * 8); + if ((v.page_frame_number << 12) == cr3) { + ULONG64 addon = (ULONG64)i << 39; + pte_base = 0xFFFF000000000000 | addon; + break; + } + } + } + else { + pte_base = (ULONG64)KGetPteBase_Signature(); + } + + + } + return (PVOID64)pte_base; + +} +BOOL KIsAddressValid(PVOID Address) { + return MmiGetPhysicalAddress(Address) != 0; +} +VOID KRaiseIrqlToDpcOrHigh(PIRQL_STATE state) { + state->old_irql = __readcr8(); + if (state->old_irql < DISPATCH_LEVEL) { + __writecr8(DISPATCH_LEVEL); + } +} +VOID KLowerIrqlToState(PIRQL_STATE state) { + if (state->old_irql < DISPATCH_LEVEL) { + __writecr8(state->old_irql); + } +} + +ULONG64 KGetRspBase() { + return __readgsqword(0x1A8); +} + diff --git a/DICHook_OpenSource/DDKCommon.h b/DICHook_OpenSource/DDKCommon.h new file mode 100644 index 0000000..e58174a --- /dev/null +++ b/DICHook_OpenSource/DDKCommon.h @@ -0,0 +1,101 @@ +#pragma once +#ifndef __DDKCOMMON_INCLUDED_ + +#pragma comment(lib,"oldnames.lib") +#pragma comment(linker,"/INCREMENTAL:NO") + +#include "ntifs.h" +#include "ntimage.h" +#include "MyPEB.h" +#include "NtFunctionDefine.h" +#include "KernelAsm.h" +#include "MyMemoryIo64.h" + +//#define print DbgPrint +#define print + +#define WIN10 (10240) +#define WIN10_1507 (10240) +#define WIN10_1511 (10586) +#define WIN10_1607 (14393) +#define WIN10_1703 (15063) +#define WIN10_1709 (16299) +#define WIN10_1803 (17134) +#define WIN10_1809 (17763) +#define WIN10_1903 (18362) +#define WIN10_1909 (18363) +#define WIN10_2004 (19041) +#define WIN10_21H1 (19043) + +#define POOL_TAG 'enoN' + +typedef struct _XINPUT_GAMEPAD +{ + WORD wButtons; + BYTE bLeftTrigger; + BYTE bRightTrigger; + SHORT sThumbLX; + SHORT sThumbLY; + SHORT sThumbRX; + SHORT sThumbRY; +} XINPUT_GAMEPAD, * PXINPUT_GAMEPAD; + +typedef struct _XINPUT_STATE +{ + DWORD dwPacketNumber; + XINPUT_GAMEPAD Gamepad; +} XINPUT_STATE, * PXINPUT_STATE; + +typedef struct _KBuffer { + PVOID Address; + ULONG Size; +}KBuffer, * PKBuffer; + +#ifdef __cplusplus +extern "C"{ +#endif + +LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch); +LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch); + +VOID Sleep(LONG Millsecond); +ULONG64 GetRealTime(); +ULONG64 GetRealMicroTime(); +LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch); +LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch); +LPWSTR WINAPI StrStrNIW(LPCWSTR lpszStr, LPCWSTR lpszSearch, SIZE_T max_chars); +LPSTR WINAPI StrStrNIA(LPCSTR lpszStr, LPCSTR lpszSearch, SIZE_T max_chars); + +INT64 FindSignatureCode_nocheck(LPCVOID Memory, UINT64 MemoryLenth, LPCSTR SignatureCode, UINT64 Pos); + +ULONG64 ScanSection(LPCSTR SectionName, LPCSTR Pattern); +ULONG64 ScanSection_Image(LPCVOID hImage, LPCSTR SectionName, LPCSTR Pattern); +ULONG64 KGetProcessCr3(PEPROCESS Process); + +PVOID KGetDriverImageBase(LPCWSTR DriverName); +PVOID KGetDriverImageBase2(PCHAR name); +ULONG KGetDriverImageSize(LPCWSTR DriverName); + +PVOID KGetProcAddress(PVOID ModuleHandle, LPCSTR ProcName); +ULONG KGetBuildNumber(); +PVOID KGetNtoskrnl(); + +PVOID64 KGetPteBase(); + +typedef struct _IRQL_STATE { + ULONG old_irql; +}IRQL_STATE, * PIRQL_STATE; + +VOID KRaiseIrqlToDpcOrHigh(PIRQL_STATE state); +VOID KLowerIrqlToState(PIRQL_STATE state); + +ULONG64 KGetRspBase(); + +#ifdef __cplusplus +} +#endif + +#endif // !__DDKCOMMON_INCLUDED_ + + + diff --git a/DICHook_OpenSource/DICHook_OpenSource.inf b/DICHook_OpenSource/DICHook_OpenSource.inf new file mode 100644 index 0000000..737a03f --- /dev/null +++ b/DICHook_OpenSource/DICHook_OpenSource.inf @@ -0,0 +1,32 @@ +; +; DICHook_OpenSource.inf +; + +[Version] +Signature="$WINDOWS NT$" +Class=System +ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} +Provider=%ManufacturerName% +DriverVer= +CatalogFile=DICHook_OpenSource.cat + +[DestinationDirs] +DefaultDestDir = 12 + + +[SourceDisksNames] +1 = %DiskName%,,,"" + +[SourceDisksFiles] + + +[Manufacturer] +%ManufacturerName%=Standard,NT$ARCH$ + +[Standard.NT$ARCH$] + + +[Strings] +ManufacturerName="" ;TODO: Replace with your manufacturer name +ClassName="" +DiskName="DICHook_OpenSource Source Disk" diff --git a/DICHook_OpenSource/DICHook_OpenSource.vcxproj b/DICHook_OpenSource/DICHook_OpenSource.vcxproj new file mode 100644 index 0000000..7266a9b --- /dev/null +++ b/DICHook_OpenSource/DICHook_OpenSource.vcxproj @@ -0,0 +1,181 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + {788C82FC-D258-4C61-A8DA-C12DC560FCAD} + {dd38f7fc-d7bd-488b-9242-7d8754cde80d} + v4.5 + 12.0 + Debug + Win32 + DICHook_OpenSource + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows7 + true + WindowsKernelModeDriver10.0 + Driver + WDM + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + false + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + TurnOffAllWarnings + + + + + false + false + false + Fast + + + false + oldnames.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DICHook_OpenSource/DICHook_OpenSource.vcxproj.filters b/DICHook_OpenSource/DICHook_OpenSource.vcxproj.filters new file mode 100644 index 0000000..72902bc --- /dev/null +++ b/DICHook_OpenSource/DICHook_OpenSource.vcxproj.filters @@ -0,0 +1,68 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/DICHook_OpenSource/DICHook_OpenSource.vcxproj.user b/DICHook_OpenSource/DICHook_OpenSource.vcxproj.user new file mode 100644 index 0000000..4400702 --- /dev/null +++ b/DICHook_OpenSource/DICHook_OpenSource.vcxproj.user @@ -0,0 +1,6 @@ + + + + Off + + \ No newline at end of file diff --git a/DICHook_OpenSource/HwidHook.cpp b/DICHook_OpenSource/HwidHook.cpp new file mode 100644 index 0000000..95f2659 --- /dev/null +++ b/DICHook_OpenSource/HwidHook.cpp @@ -0,0 +1,681 @@ +#include "DDKCommon.h" +#include "HwidHook.h" +#include "ntddndis.h" +#include "kernelasm.h" +#include "ntifs.h" +#include "NtFunctionDefine.h" +#include "MyPEB.h" + +#define printf + +typedef struct _HOOK_DEVICE_IO_CONTEXT { + PVOID JmpPage; + PVOID Object; + ULONG64 iosb; + ULONG IoControlCode; + ULONG64 InputBuffer; + ULONG InputBufferLength; + ULONG64 OutputBuffer; + ULONG OutputBufferLength; +}HOOK_DEVICE_IO_CONTEXT; +typedef struct _HOOK_NTQUERY_CONTEXT { + PVOID JmpPage; + ULONG FsInformationClass; + ULONG64 FsInformation; + ULONG Length; +}HOOK_NTQUERY_CONTEXT; + +typedef BOOL(*fnIoCtlPostCallback)(HOOK_DEVICE_IO_CONTEXT *); +fnIoCtlPostCallback g_IoCtlPostCallback = 0; + +typedef void(*fndiccabk)(ULONG64, ULONG64, ULONG64, ULONG64, ULONG64); +typedef void(*fnntqcabk)(ULONG64, ULONG64, ULONG64); +typedef VOID(*fnExtraCallback)(VOID); +fndiccabk dicpostcabk = 0; +fndiccabk dicprecabk = 0; +fnntqcabk ntqcabk = 0; +fnExtraCallback pcabk = 0; + +#include "vtstruct.h" + +ULONG64 Search_FsInformation = 0; +ULONG Search_Length = 0; +ULONG64 Search_Object = 0; + +ULONG64 pRetCodePage = 0; +ULONG64 pNtQueryRetCodePage = 0; + +ULONG64 NtDeviceIoControlFileRet = 0; +ULONG64 NtFsControlFileRet = 0; +ULONG64 NtQueryVolumeInformationFileRet = 0; + +ULONG RspOffset = 0; +ULONG RspOffset_NtQuery = 0; + +ULONG NtDevice_Offset_Object = 0; + +ULONG NtQuery_StackSize = 0; +LONG NtQuery_Offset_FsInformation = 0; +LONG NtQuery_Offset_Length = 0; + +ULONG64 MyAllocEx() { + return 0; +} +VOID TestDeviceIoControl() { + HANDLE FileHandle = 0; + UNICODE_STRING name; + RtlInitUnicodeString(&name, L"\\??\\C:"); + + OBJECT_ATTRIBUTES oa; + InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, 0, 0); + IO_STATUS_BLOCK iosb; + RtlZeroMemory(&iosb, sizeof(IO_STATUS_BLOCK)); + NTSTATUS stats = ZwCreateFile(&FileHandle, FILE_GENERIC_READ, &oa, &iosb, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, 0, 0); + RtlZeroMemory(&iosb, sizeof(IO_STATUS_BLOCK)); + + PFILE_OBJECT obj = 0; + OBJECT_HANDLE_INFORMATION objhandle = { 0 }; + RtlZeroMemory(&objhandle, sizeof(objhandle)); + stats = ObReferenceObjectByHandle(FileHandle, 0, *IoFileObjectType, KernelMode, (PVOID *)&obj, &objhandle); + if (!NT_SUCCESS(stats)) { + ZwClose(FileHandle); + KeBugCheck(0x56009); + } + ObDereferenceObject(obj); + Search_Object = (ULONG64)obj; + typedef NTSTATUS + (*NTAPI fnNtDeviceIoControlFile)( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG IoControlCode, + _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength + ); + fnNtDeviceIoControlFile pNtDeviceIoControlFile = (fnNtDeviceIoControlFile)KGetProcAddress(KGetNtoskrnl(), "NtDeviceIoControlFile"); + UCHAR Input[4] = { 0 }; + UCHAR Output[4] = { 0 }; + ULONG64 Magic[2]; + Magic[0] = 0x1122334455667788; + Magic[1] = 0x8877665544772299; + pNtDeviceIoControlFile(FileHandle, 0, 0, 0, &iosb, IOCTL_NDIS_QUERY_GLOBAL_STATS, Input, 4, Output, 4); + + ZwClose(FileHandle); +} +VOID TestNtQueryVolumeInformationFile() { + HANDLE FileHandle = 0; + UNICODE_STRING name; + RtlInitUnicodeString(&name, L"\\??\\C:"); + + OBJECT_ATTRIBUTES oa; + InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, 0, 0); + IO_STATUS_BLOCK iosb; + RtlZeroMemory(&iosb, sizeof(IO_STATUS_BLOCK)); + + NTSTATUS stats = ZwCreateFile(&FileHandle, FILE_GENERIC_READ, &oa, &iosb, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, 0, 0); + RtlZeroMemory(&iosb, sizeof(IO_STATUS_BLOCK)); + FILE_FS_OBJECTID_INFORMATION *pinfo = (FILE_FS_OBJECTID_INFORMATION *)ExAllocatePoolWithTag(NonPagedPoolNx, 0x2000, POOL_TAG); + RtlZeroMemory(pinfo, sizeof(FILE_FS_OBJECTID_INFORMATION)); + + ULONG64 Mark[2]; + Mark[0] = 0xCC22334455666688; + Mark[1] = 0xAA77665544333399; + + Search_FsInformation = (ULONG64)pinfo; + Search_Length = 0x1238; + NtQueryVolumeInformationFile(FileHandle, &iosb, pinfo, 0x1238, FileFsObjectIdInformation); + ExFreePoolWithTag(pinfo, POOL_TAG); + ZwClose(FileHandle); +} + +ULONG64 GetIopDispatchAllocateIrp() { + ULONG BuildNumber = KGetBuildNumber(); + if (BuildNumber >= 15063) { + //8B 05 ?? ?? ?? ?? 44 8A C2 + ULONG64 pos = ScanSection(".text", "8B05????????448AC2"); + if (pos) { + return *(LONG *)(pos + 2) + pos + 6; + } + else { + pos = ScanSection(".text", "8B05????????440FB6C2"); + if (pos) { + return *(LONG *)(pos + 2) + pos + 6; + } + } + } + return 0; +} +BOOL InitStackSize() { + ULONG64 ntos = (ULONG64)KGetNtoskrnl(); + + ULONG64 pNtQueryVolumeInformationFile = (ULONG64)KGetProcAddress((PVOID)ntos, "NtQueryVolumeInformationFile"); + + //63 ?? 24 ?? ?? 00 00 + ULONG64 pos = FindSignatureCode_nocheck((LPCVOID)pNtQueryVolumeInformationFile, 0x200, "63??24????0000", 0); + if (pos == -1)return FALSE; + NtQuery_StackSize = *(ULONG *)(pos + pNtQueryVolumeInformationFile + 3) - 0x28; + + + + return TRUE; +} + +namespace DispatchControl { + BOOLEAN enable_ntq = TRUE; + BOOLEAN enable = FALSE; + BOOLEAN Inited = FALSE; +} +VOID DispatchCallback(ULONG64 pRsp) { + static const unsigned char shellcode[] = "\x48\xB9\x00\x00\x00\x00\x00\x10\x00\x00\x51\x48\xB9\x00\x00\x00\x00\x00\x10\x00\x00\x50\xC7\x04\x24\x00\x00\x00\x10\xC7\x44\x24\x04\x00\x00\x00\x10\xC3" + ; + KIRQL irql = AsmReadCr8() & 0xFF; + if (irql >= DISPATCH_LEVEL)return; + ULONG64 RFlag = AsmGetRFlags(); + if (RFlag & 0x10000) { + return; + } + int Pid = (int)PsGetProcessId(PsGetCurrentThreadProcess()); + if ((int)Pid != 4) { + if (pcabk) { + pcabk(); + + } + } + ULONG64 Low = 0, High = 0; + IoGetStackLimits(&Low, &High); + if (DispatchControl::Inited == FALSE) { + if (RspOffset == 0 || DispatchControl::enable_ntq ? RspOffset_NtQuery == 0 : false) { + PULONG64 Rsp = (PULONG64)pRsp; + for (int i = 0; (ULONG64)Rsp < High - 8; Rsp++, i++) { + if (RspOffset == 0) { + if (Rsp[0] == 0x1122334455667788) { + if (Rsp[1] == 0x8877665544772299) { + //DbgBreakPoint(); + ULONG64 OLRSP = (ULONG64)Rsp; + for (int j = 0; OLRSP > pRsp && j < 0x1000; OLRSP -= 8, j += 8) { + if (*(ULONG64*)OLRSP == NtDeviceIoControlFileRet) { + RspOffset = OLRSP - pRsp; + //printf("[112233] RspOffset %x\n", RspOffset); + ULONG64 OOLRSP = OLRSP; + for (int p = 0; OOLRSP > pRsp && p < 0x1000; OOLRSP -= 8, p += 8) { + //search arg offset + if (NtDevice_Offset_Object) + break; + if (NtDevice_Offset_Object == 0) { + if (*(ULONG64*)OOLRSP == Search_Object) { + NtDevice_Offset_Object = OOLRSP - pRsp; + continue; + } + } + + } + break; + } + } + } + } + if (RspOffset)break; + } + if (RspOffset_NtQuery == 0 && DispatchControl::enable_ntq) { + if (Rsp[0] == 0xCC22334455666688) { + if (Rsp[1] == 0xAA77665544333399) { + ULONG64 OLRSP = (ULONG64)Rsp; + for (int j = 0; OLRSP > pRsp && j < 0x800; OLRSP -= 8, j += 8) { + if (*(ULONG64*)OLRSP == NtQueryVolumeInformationFileRet) { + RspOffset_NtQuery = OLRSP - pRsp; + ULONG64 OOLRSP = OLRSP; + for (int p = 0; OOLRSP > pRsp && p < 0x800; OOLRSP -= 8, p += 8) { + //search arg offset + if (NtQuery_Offset_FsInformation && NtQuery_Offset_Length) + break; + if (NtQuery_Offset_FsInformation == 0) { + if (*(ULONG64*)OOLRSP == Search_FsInformation) { + NtQuery_Offset_FsInformation = OOLRSP - pRsp; + continue; + } + } + if (NtQuery_Offset_Length == 0) { + if (*(ULONG*)OOLRSP == Search_Length) { + NtQuery_Offset_Length = OOLRSP - pRsp; + continue; + } + } + + } + if (NtQuery_Offset_Length == 0) { + KeBugCheck(0x33221); + } + if (NtQuery_Offset_FsInformation == 0) { + KeBugCheck(0x33222); + } + break; + } + } + printf("[112233] RspOffset_NtQuery:%x\n", RspOffset_NtQuery); + printf("[112233] FsInformation:%x Length:%x\n", NtQuery_Offset_FsInformation, NtQuery_Offset_Length); + } + } + if (RspOffset_NtQuery)break; + } + + } + //printf("[112233] RspOffset:%x RspOffset_Ntquery:%x\n", RspOffset, RspOffset_NtQuery); + } + } + + if (RspOffset) { + if (High - pRsp > RspOffset) { + if (*(ULONG64 *)(pRsp + RspOffset) == NtDeviceIoControlFileRet || *(ULONG64*)(pRsp + RspOffset) == NtFsControlFileRet) { + ULONG64 LRSP = (ULONG64)(pRsp + RspOffset); + + ULONG64 Object = *(ULONG64 *)(pRsp + NtDevice_Offset_Object); + ULONG64 iosb = *(ULONG64*)(LRSP + 8 + 0x90); + ULONG ControlCode = *(ULONG *)(LRSP + 8 + 0x98); + ULONG64 InputBuffer = *(ULONG64 *)(LRSP + 8 + 0xA0); + ULONG InputBufferLength = *(ULONG *)(LRSP + 8 + 0xA8); + ULONG64 OutputBuffer = *(ULONG64 *)(LRSP + 8 + 0xB0); + ULONG OutputBufferLength = *(ULONG *)(LRSP + 8 + 0xB8); + + HOOK_DEVICE_IO_CONTEXT lContext; + RtlZeroMemory(&lContext, sizeof(lContext)); + lContext.iosb = iosb; + lContext.InputBuffer = InputBuffer; + lContext.InputBufferLength = InputBufferLength; + lContext.OutputBuffer = OutputBuffer; + lContext.OutputBufferLength = OutputBufferLength; + lContext.IoControlCode = ControlCode; + lContext.Object = (PVOID)Object; + + if (g_IoCtlPostCallback(&lContext)) { + HOOK_DEVICE_IO_CONTEXT *Context = (HOOK_DEVICE_IO_CONTEXT *)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(lContext), POOL_TAG); + RtlZeroMemory(Context, sizeof(HOOK_DEVICE_IO_CONTEXT)); + memcpy(Context, &lContext, sizeof(lContext)); + PUCHAR JmpPage = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, sizeof(shellcode)+1, POOL_TAG); + memcpy(JmpPage, shellcode, sizeof(shellcode)); + ULONG offset = 0; + *(ULONG64 *)(JmpPage + 0x2 + offset) = *(ULONG64 *)(LRSP + 0x70); + *(ULONG64 *)(JmpPage + 0xd + offset) = (ULONG64)Context; + LARGE_INTEGER Addr; + Addr.QuadPart = pRetCodePage; + *(ULONG *)(JmpPage + 0x19 + offset) = Addr.LowPart; + *(ULONG *)(JmpPage + 0x21 + offset) = Addr.HighPart; + + Context->JmpPage = JmpPage; + *(ULONG64 *)(LRSP + 0x70) = (ULONG64)JmpPage; + } + + return; + } + } + } + if (RspOffset_NtQuery && DispatchControl::enable_ntq) { + if (High - pRsp > RspOffset_NtQuery) { + if (*(ULONG64 *)(pRsp + RspOffset_NtQuery) == NtQueryVolumeInformationFileRet) { + ULONG64 LRSP = (ULONG64)(pRsp + RspOffset_NtQuery); + ULONG FsInfomationClass = *(ULONG *)(LRSP + 8 + NtQuery_StackSize + 0x28); + ULONG64 FsInformation = *(ULONG64 *)(pRsp + NtQuery_Offset_FsInformation); + ULONG Length = *(ULONG *)(pRsp + NtQuery_Offset_Length); + + printf("[112233] NtQ Class %d FsInfomation %p Length %x\n", FsInfomationClass, FsInformation, Length); + + HOOK_NTQUERY_CONTEXT* Context = (HOOK_NTQUERY_CONTEXT*)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(HOOK_NTQUERY_CONTEXT), POOL_TAG); + RtlZeroMemory(Context, sizeof(HOOK_NTQUERY_CONTEXT)); + + Context->FsInformation = FsInformation; + Context->FsInformationClass = FsInfomationClass; + Context->Length = Length; + + PUCHAR JmpPage = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, sizeof(shellcode)+1, POOL_TAG); + memcpy(JmpPage, shellcode, sizeof(shellcode)); + ULONG offset = 0; + *(ULONG64 *)(JmpPage + 0x2 + offset) = *(ULONG64 *)(LRSP + 8 + NtQuery_StackSize); + *(ULONG64 *)(JmpPage + 0xd + offset) = (ULONG64)Context; + LARGE_INTEGER Addr; + Addr.QuadPart = pNtQueryRetCodePage; + *(ULONG *)(JmpPage + 0x19 + offset) = Addr.LowPart; + *(ULONG *)(JmpPage + 0x21 + offset) = Addr.HighPart; + + Context->JmpPage = JmpPage; + + *(ULONG64 *)(LRSP + 8 + NtQuery_StackSize) = (ULONG64)JmpPage; + } + } + } + + + return; +} + +BOOLEAN g_hooked = FALSE; + +VOID InstallHook(fnIoCtlPostCallback PostCallback, PVOID PreCallback, PVOID NtQueryPre) { + if (g_hooked == TRUE) { + return; + } + + static unsigned char shellcode[] = "\x50\x53\x51\x52\x56\x57\x55\x41\x50\x41\x51\x41\x52\x41\x53\x41\x54\x41\x55\x41\x56\x41\x57\x9C\x48\x8D\x8C\x24\x80\x00\x00\x00\x48\xB8\x00\x00\x00\x00\x00\x01\x00\x00\x48\x35\xFF\xFF\xFF\x7F\x48\x93\xE8\x30\x00\x00\x00\xFF\xD3\xE8\x3E\x00\x00\x00\x9D\x41\x5F\x41\x5E\x41\x5D\x41\x5C\x41\x5B\x41\x5A\x41\x59\x41\x58\x5D\x5F\x5E\x5A\x59\x5B\x58\x50\xC7\x04\x24\x00\x00\x00\x10\xC7\x44\x24\x04\x00\x00\x00\x10\xC3\x4C\x8D\x5C\x24\x08\x48\x83\xE4\xF0\x41\x53\x41\x53\x48\x83\xEC\x30\x41\xFF\x63\xF8\x41\x5B\x48\x83\xC4\x38\x5C\x41\xFF\xE3" + ; + static unsigned char shellcode2[] = "\x50\x53\x51\x52\x56\x57\x55\x41\x50\x41\x51\x41\x52\x41\x53\x41\x54\x41\x55\x41\x56\x41\x57\x9C\x48\xB8\x00\x00\x00\x00\x00\x01\x00\x00\x48\x35\xFF\xFF\xFF\x7F\x48\x93\xE8\x20\x00\x00\x00\xFF\xD3\xE8\x2E\x00\x00\x00\x9D\x41\x5F\x41\x5E\x41\x5D\x41\x5C\x41\x5B\x41\x5A\x41\x59\x41\x58\x5D\x5F\x5E\x5A\x59\x5B\x58\xC3\x4C\x8D\x5C\x24\x08\x48\x83\xE4\xF0\x41\x53\x41\x53\x48\x83\xEC\x30\x41\xFF\x63\xF8\x41\x5B\x48\x83\xC4\x38\x5C\x41\xFF\xE3" + ; + static unsigned char shellcode3[] = "\x50\x53\x51\x52\x56\x57\x55\x41\x50\x41\x51\x41\x52\x41\x53\x41\x54\x41\x55\x41\x56\x41\x57\x9C\x48\x89\xC2\x48\xB8\x00\x00\x00\x00\x01\x00\x00\x00\x48\x35\xFF\xFF\xFF\x7F\x48\x93\xE8\x20\x00\x00\x00\xFF\xD3\xE8\x2E\x00\x00\x00\x9D\x41\x5F\x41\x5E\x41\x5D\x41\x5C\x41\x5B\x41\x5A\x41\x59\x41\x58\x5D\x5F\x5E\x5A\x59\x5B\x58\xC3\x4C\x8D\x5C\x24\x08\x48\x83\xE4\xF0\x41\x53\x41\x53\x48\x83\xEC\x30\x41\xFF\x63\xF8\x41\x5B\x48\x83\xC4\x38\x5C\x41\xFF\xE3" + ; + static unsigned char shellcode4[] = "\x53\x51\x52\x56\x57\x55\x41\x50\x41\x51\x41\x52\x41\x53\x41\x54\x41\x55\x41\x56\x41\x57\x9C\x48\x89\xC2\x48\xB8\x00\x00\x00\x00\x01\x00\x00\x00\x48\x35\xFF\xFF\xFF\x7F\x48\x93\xE8\x1F\x00\x00\x00\xFF\xD3\xE8\x2D\x00\x00\x00\x9D\x41\x5F\x41\x5E\x41\x5D\x41\x5C\x41\x5B\x41\x5A\x41\x59\x41\x58\x5D\x5F\x5E\x5A\x59\x5B\xC3\x4C\x8D\x5C\x24\x08\x48\x83\xE4\xF0\x41\x53\x41\x53\x48\x83\xEC\x30\x41\xFF\x63\xF8\x41\x5B\x48\x83\xC4\x38\x5C\x41\xFF\xE3" + ; + + if (!InitStackSize())KeBugCheck(0x897877); + ULONG BuildNumber = KGetBuildNumber(); + ULONG64 ntos = (ULONG64)KGetNtoskrnl(); + ULONG offset = 0; + + ULONG64 ViPacketLookaside = 0; + //ViPacketLookaside + //48 8B F9 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 33 C9 + //48 8D 0D ?? ?? ?? ?? 66 89 74 24 ?? 41 B9 00 02 00 00 C7 44 24 ?? 49 72 70 74 + //48 8B D3 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? F0 FF 0D + ULONG64 pos = ScanSection("PAGEVRFY", "488BF9488D0D????????E8????????33C9"); + if (pos) { + ViPacketLookaside = *(LONG*)(pos + 6) + pos + 10; + } + else { + pos = ScanSection("PAGEVRFY", "48 8D 0D ?? ?? ?? ?? 66 89 74 24 ?? 41 B9 00 02 00 00 C7 44 24 ?? 49 72 70 74"); + if (pos) { + ViPacketLookaside = *(LONG*)(pos + 3) + pos + 7; + } + else { + pos = ScanSection("PAGEVRFY", "48 8B D3 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? F0 FF 0D"); + if (pos) { + ViPacketLookaside = *(LONG*)(pos + 6) + pos + 10; + } + } + } + if (!ViPacketLookaside) { + KeBugCheck(0x957778); + } + //DbgPrint("[112233] ViPacketLookaside %p\n", ViPacketLookaside); + //48 8D 0D ?? ?? ?? ?? C7 05 ?? ?? ?? ?? 01 00 00 00 E8 + + if (*(ULONG64 *)(ViPacketLookaside + 0x30) == 0) { + pos = ScanSection("PAGEVRFY", "488D0D????????C705????????01000000E8"); + if (!pos) { + pos = ScanSection("PAGE", "488D0D????????C705????????01000000E8"); + if (!pos)KeBugCheck(0x957776); + } + ULONG64 VfInitVerifierComponents = *(LONG *)(pos + 3) + pos + 7; + typedef ULONG64(*fnVfInitVerifierComponents)(ULONG64, ULONG64, ULONG64); + fnVfInitVerifierComponents v = (fnVfInitVerifierComponents)VfInitVerifierComponents; + v(0, 0, 0); + } + ULONG64 VfIoDisabled = 0; + if (BuildNumber < 10240) { + //win7 8B 05 ?? ?? ?? ?? 33 FF 49 8B F1 + pos = ScanSection("PAGEVRFY", "8B05????????33FF498BF1"); + if (!pos) KeBugCheck(0x6765544); + VfIoDisabled = *(LONG *)(pos + 2) + pos + 6; + } + else { + //8B 05 ?? ?? ?? ?? 40 FE C5 + pos = ScanSection("PAGEVRFY", "8B05????????40FEC5"); + if (!pos) KeBugCheck(0x6765544); + VfIoDisabled = *(LONG *)(pos + 2) + pos + 6; + } + ULONG64 IovAllocateIrp = 0; + ULONG64 pIoAllocateIrp = 0; + ULONG64 IopDispatchAllocateIrp = 0; + if (BuildNumber < 10240) { + //48 8D 05 ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 89 05 + pos = ScanSection("PAGEVRFY", "488D05????????488D15????????488905"); + if (!pos) KeBugCheck(0x6725544); + IovAllocateIrp = *(LONG *)(pos + 3) + pos + 7; + pIoAllocateIrp = *(LONG *)(pos + 17) + pos + 21; + *(ULONG64 *)(pIoAllocateIrp) = IovAllocateIrp; + + } + else if (BuildNumber >= 10240 && BuildNumber <= 14393) { + //48 8D 05 ?? ?? ?? ?? 48 87 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? 48 87 0D ?? ?? ?? ?? 48 8D 05 + pos = ScanSection(".text", "488D05????????488705????????488D0D????????48870D????????488D05"); + if (!pos) KeBugCheck(0x6725544); + IovAllocateIrp = *(LONG *)(pos + 3) + pos + 7; + pIoAllocateIrp = *(LONG *)(pos + 10) + pos + 14; + + *(ULONG64 *)(pIoAllocateIrp) = IovAllocateIrp; + } + else if (BuildNumber >= 15063) { + //87 05 ?? ?? ?? ?? 87 0D + pos = ScanSection(".text", "8705????????870D"); + if (!pos) KeBugCheck(0x6725544); + IopDispatchAllocateIrp = *(LONG *)(pos + 2) + pos + 6; + //if (!IopDispatchAllocateIrp)return; + *(int *)(IopDispatchAllocateIrp) = 1; + } + + ULONG bn = KGetBuildNumber(); + + //E8 ?? ?? ?? ?? 48 8B D8 48 89 84 24 ?? ?? ?? ?? 48 85 C0 + + //E8 ?? ?? ?? ?? 48 83 C4 + ULONG64 pNtDeviceIoControlFile = (ULONG64)KGetProcAddress((PVOID)ntos, "NtDeviceIoControlFile"); + pos = FindSignatureCode_nocheck((LPCVOID)pNtDeviceIoControlFile, 0x200, "E8????????4883C4", 0); + if (pos == -1)KeBugCheck(0x89997); + NtDeviceIoControlFileRet = pos + pNtDeviceIoControlFile + 5; + + ULONG64 pNtFsControlFile = (ULONG64)KGetProcAddress((PVOID)ntos, "NtFsControlFile"); + pos = FindSignatureCode_nocheck((LPCVOID)pNtFsControlFile, 0x200, "E8????????4883C4", 0); + if (pos == -1)KeBugCheck(0x89998); + NtFsControlFileRet = pos + pNtFsControlFile + 5; + //printf("[112233] NtDeviceIoControlFileRet %p\n", NtDeviceIoControlFileRet); + //printf("[112233] NtFsControlFileRet %p\n", NtFsControlFileRet); + //DbgPrint("[112233] IoCreateFileRet:%p\n", IoCreateFileRet); + //45 33 C9 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? ?? 8B ?? E8 ?? ?? ?? ?? + //DbgPrint("[112233] IopCreateFileRet:%p\n", IopCreateFileRet); + //DbgBreakPoint(); + ULONG64 pNtQueryVolumeInformationFile = (ULONG64)KGetProcAddress((PVOID)ntos, "NtQueryVolumeInformationFile"); + if (BuildNumber < WIN10_1507) { + //4C E8 ?? ?? ?? ?? 48 + pos = FindSignatureCode_nocheck((LPCVOID)pNtQueryVolumeInformationFile, 0x1000, "4CE8????????48", 0); + if (pos == -1)KeBugCheck(0x89967); + NtQueryVolumeInformationFileRet = pos + pNtQueryVolumeInformationFile + 6; + } + else if (BuildNumber >= WIN10_1507 && BuildNumber <= WIN10_1607) { + //4C ?? ?? ?? FF 15 ?? ?? ?? ?? ?? ?? ?? 48 + pos = FindSignatureCode_nocheck((LPCVOID)pNtQueryVolumeInformationFile, 0x1000, "4C??????FF15??????????????48", 0); + if (pos == -1)KeBugCheck(0x89967); + NtQueryVolumeInformationFileRet = pos + pNtQueryVolumeInformationFile + 10; + } + else if (BuildNumber >= WIN10_1703) { + //4C ?? 8B ?? E8 ?? ?? ?? ?? ?? 89 + //4C ?? 8B ?? E8 ?? ?? ?? ?? ?? 8B ?? 48 89 44 24 + //4C E8 ?? ?? ?? ?? ?? 8B ?? 48 89 44 24 + //4C ?? 8B ?? E8 ?? ?? ?? ?? 48 89 44 24 + + pos = FindSignatureCode_nocheck((LPCVOID)pNtQueryVolumeInformationFile, 0x1000, "4C ?? 8B ?? E8 ?? ?? ?? ?? ?? 89", 0); + if (pos != -1) { + NtQueryVolumeInformationFileRet = pos + pNtQueryVolumeInformationFile + 9; + } + else { + pos = FindSignatureCode_nocheck((LPCVOID)pNtQueryVolumeInformationFile, 0x600, "4C ?? 8B ?? E8 ?? ?? ?? ?? ?? 8B ?? 48 89 44 24", 0); + if (pos != -1) { + NtQueryVolumeInformationFileRet = pos + pNtQueryVolumeInformationFile + 9; + } + else { + pos = FindSignatureCode_nocheck((LPCVOID)pNtQueryVolumeInformationFile, 0x800, "4C E8 ?? ?? ?? ?? ?? 8B ?? 48 89 44 24", 0); + if (pos != -1) { + NtQueryVolumeInformationFileRet = pos + pNtQueryVolumeInformationFile + 6; + } + else { + KeBugCheck(0x89967); + } + } + + } + } + //DbgPrint("[112233] NtQueryVolumeInformationFile %p\n", pNtQueryVolumeInformationFile); + //DbgPrint("[112233] NtQueryVolumeInformationFileRet %p\n", NtQueryVolumeInformationFileRet); + + if (!NtQueryVolumeInformationFileRet) + KeBugCheck(0x89967); + if (BuildNumber < 10240) { + *(ULONG64*)(pIoAllocateIrp) = IovAllocateIrp; + } + else if (BuildNumber >= 10240 && BuildNumber <= 14393) { + *(ULONG64*)(pIoAllocateIrp) = IovAllocateIrp; + } + else if (BuildNumber >= 15063) { + *(int*)(IopDispatchAllocateIrp) = 1; + } + + KIRQL irql = KeRaiseIrqlToDpcLevel(); + + pRetCodePage = (ULONG64)ExAllocatePool(NonPagedPool, 0x500); + memcpy((PVOID)pRetCodePage, shellcode2, sizeof(shellcode2)); + *(ULONG64*)(pRetCodePage + 0x1A) = ((ULONG64)PreCallback) ^ 0x7fffffff; + + pNtQueryRetCodePage = (ULONG64)ExAllocatePool(NonPagedPool, 0x500); + memcpy((PVOID)pNtQueryRetCodePage, shellcode3, sizeof(shellcode3)); + *(ULONG64*)(pNtQueryRetCodePage + 0x1D) = ((ULONG64)NtQueryPre) ^ 0x7fffffff; + g_IoCtlPostCallback = PostCallback; + + + PUCHAR pcode = (PUCHAR)ExAllocatePool(NonPagedPool, 0x500); + memcpy(pcode, shellcode, sizeof(shellcode)); + *(ULONG64 *)(pcode + 0x22 + offset) = ((ULONG64)DispatchCallback) ^ 0x7fffffff; + ULONG64 pfn = *(ULONG64*)(ViPacketLookaside + 0x30); + ULONG64 Origin = pfn; + if (MmiGetPhysicalAddress((PVOID)pfn)) { + if (*(ULONG64*)pfn == *(ULONG64*)shellcode) { + LARGE_INTEGER new_addr; + new_addr.LowPart = *(ULONG*)(pfn + 0x5A + offset); + new_addr.HighPart = *(ULONG*)(pfn + 0x62 + offset); + Origin = new_addr.QuadPart; + } + } + + LARGE_INTEGER Addr; + Addr.QuadPart = (ULONG64)MyAllocEx; + *(ULONG *)(pcode + 0x5A + offset) = Addr.LowPart; + *(ULONG *)(pcode + 0x62 + offset) = Addr.HighPart; + InterlockedExchange64((volatile LONG64*)(ViPacketLookaside + 0x30), (LONG64)pcode); + + *(DWORD*)(pcode + sizeof(shellcode)) = 0xDEADBEEF; + + *(int*)(VfIoDisabled) = 0; + + KeLowerIrql(irql); + //*(int *)(IopDispatchAllocateIrp) = 1; + TestDeviceIoControl(); + TestNtQueryVolumeInformationFile(); + + + DispatchControl::Inited = TRUE; +} +BOOL FnDICPostCallback(HOOK_DEVICE_IO_CONTEXT *Context) { + + if (Context) { + PFILE_OBJECT FileObject = (PFILE_OBJECT)Context->Object; + if (dicpostcabk) { + dicpostcabk(Context->IoControlCode, Context->InputBuffer, Context->InputBufferLength, Context->OutputBuffer, Context->OutputBufferLength); + } + return TRUE; + } + return FALSE; +} +VOID FnDICPreCallback(HOOK_DEVICE_IO_CONTEXT *aContext){ + if (aContext) { + HOOK_DEVICE_IO_CONTEXT Context = *aContext; + ExFreePoolWithTag(Context.JmpPage, POOL_TAG); + ExFreePoolWithTag(aContext, POOL_TAG); + if (dicprecabk) { + dicprecabk(Context.IoControlCode, Context.InputBuffer, Context.InputBufferLength, Context.OutputBuffer, Context.OutputBufferLength); + } + } +} +VOID FnNtQueryPreCallback(HOOK_NTQUERY_CONTEXT *aContext) { + if (aContext) { + HOOK_NTQUERY_CONTEXT Context = *aContext; + ExFreePoolWithTag(Context.JmpPage, POOL_TAG); + ExFreePoolWithTag(aContext, POOL_TAG); + + if (ntqcabk) { + ntqcabk(Context.FsInformationClass, Context.FsInformation, Context.Length); + } + } +} + +BOOL DICPostCallback(HOOK_DEVICE_IO_CONTEXT* Context) { + //ÌáÉýirqlÖÁ2,¹Ø±Õsmap + IRQL_STATE state; + KRaiseIrqlToDpcOrHigh(&state); + Cr4 cr4; + cr4.all = __readcr4(); + bool smap = cr4.fields.smap == 1; + if (smap) { + cr4.fields.smap = 0; + __writecr4(cr4.all); + } + BOOL ret = FnDICPostCallback(Context); + if (smap) { + cr4.fields.smap = 1; + __writecr4(cr4.all); + } + KLowerIrqlToState(&state); + return ret; +} +VOID DICPreCallback(HOOK_DEVICE_IO_CONTEXT* aContext) { + //ÌáÉýirqlÖÁ2,¹Ø±Õsmap + IRQL_STATE state; + KRaiseIrqlToDpcOrHigh(&state); + Cr4 cr4; + cr4.all = __readcr4(); + bool smap = cr4.fields.smap == 1; + if (smap) { + cr4.fields.smap = 0; + __writecr4(cr4.all); + } + FnDICPreCallback(aContext); + if (smap) { + cr4.fields.smap = 1; + __writecr4(cr4.all); + } + KLowerIrqlToState(&state); +} +VOID NtQueryPreCallback(HOOK_NTQUERY_CONTEXT* aContext) { + //ÌáÉýirqlÖÁ2,¹Ø±Õsmap + IRQL_STATE state; + KRaiseIrqlToDpcOrHigh(&state); + Cr4 cr4; + cr4.all = __readcr4(); + bool smap = cr4.fields.smap == 1; + if (smap) { + cr4.fields.smap = 0; + __writecr4(cr4.all); + } + FnNtQueryPreCallback(aContext); + if (smap) { + cr4.fields.smap = 1; + __writecr4(cr4.all); + } + KLowerIrqlToState(&state); +} + +VOID setpcabk(PVOID fun) { + pcabk = (fnExtraCallback)fun; + InstallHook(DICPostCallback, DICPreCallback, NtQueryPreCallback); +} +VOID setdicpostcabk(PVOID func) { + dicpostcabk = (fndiccabk)func; + InstallHook(DICPostCallback, DICPreCallback, NtQueryPreCallback); +} +VOID setdicprecabk(PVOID func) { + dicprecabk = (fndiccabk)func; + InstallHook(DICPostCallback, DICPreCallback, NtQueryPreCallback); +} +VOID setntqcabk(PVOID func) { + ntqcabk = (fnntqcabk)func; +} + +VOID setntqhookstats(BOOL stats) { + DispatchControl::enable_ntq = stats; +} \ No newline at end of file diff --git a/DICHook_OpenSource/HwidHook.h b/DICHook_OpenSource/HwidHook.h new file mode 100644 index 0000000..8ccb566 --- /dev/null +++ b/DICHook_OpenSource/HwidHook.h @@ -0,0 +1,26 @@ +#pragma once + +#ifndef _SPOOFER_INCLUDED_ +#define _SPOOFER_INCLUDED_ + +#include "ntifs.h" +#include "DDKCommon.h" + +#ifdef __cplusplus +extern "C" { +#endif + +VOID setpcabk(PVOID fun); +VOID setdicpostcabk(PVOID func); +VOID setdicprecabk(PVOID func); +VOID setntqcabk(PVOID func); +VOID setntqhookstats(BOOL stats); + +#ifdef __cplusplus +} +#endif + +#endif // !_SPOOFER_INCLUDED_ + + + diff --git a/DICHook_OpenSource/KernelAsm.asm b/DICHook_OpenSource/KernelAsm.asm new file mode 100644 index 0000000..50cd015 --- /dev/null +++ b/DICHook_OpenSource/KernelAsm.asm @@ -0,0 +1,270 @@ + + .code + +_text SEGMENT + +ReadSsQ PROC + +db 36h,48h, 08bh, 01h +ret + +ReadSsQ ENDP + +AsmInt2F PROC + +int 2Fh +ret + +AsmInt2F ENDP + +AsmIntE1 PROC + +int 0E1h +ret + +AsmIntE1 ENDP + +AsmRdtsc PROC + +rdtsc +and rax,0FFFFFFFFh +and rdx,0FFFFFFFFh +rol rdx,32 +or rax,rdx +ret + +AsmRdtsc ENDP + +AsmGetRFlags PROC + +pushfq +pop rax +ret + +AsmGetRFlags ENDP + +AsmGetRSP PROC + +mov rax,rsp +add rax,8 +ret + +AsmGetRSP ENDP + +AsmReadCr0 PROC +mov rax,cr0 +ret +AsmReadCr0 ENDP + +AsmReadCr2 PROC +mov rax,cr2 +ret +AsmReadCr2 ENDP + +AsmReadCr3 PROC +mov rax,cr3 +ret +AsmReadCr3 ENDP + +AsmReadCr4 PROC +mov rax,cr4 +ret +AsmReadCr4 ENDP + +AsmReadCr8 PROC +mov rax,cr8 +ret +AsmReadCr8 ENDP + +AsmReadMsr PROC + +and rcx,0FFFFFFFFh +rdmsr +and rax,0FFFFFFFFh +and rdx,0FFFFFFFFh +rol rdx,32 +or rax,rdx +ret + +AsmReadMsr ENDP + +AsmWriteMsr PROC + +and rcx,0FFFFFFFFh +mov eax,edx +shr rdx,32 +wrmsr +ret + +AsmWriteMsr ENDP + +AsmReadGs PROC + +mov rax,gs:[rcx] +ret + +AsmReadGs ENDP + +AsmWriteCr4 PROC +mov cr4,rcx +ret +AsmWriteCr4 ENDP + +AsmWriteCr0 PROC +mov cr0,rcx +ret +AsmWriteCr0 ENDP + +AsmWriteCr8 PROC +mov cr8,rcx +ret +AsmWriteCr8 ENDP + +AsmCpuid PROC +;rcx=eax rdx=ecx r8=pcpuidret + +push rbx +push r11 + +mov r11,r8 + +mov eax,ecx +mov ecx,edx +cpuid +mov dword ptr[r11],eax +mov dword ptr[r11+4],ebx +mov dword ptr[r11+8],ecx +mov dword ptr[r11+12],edx + +pop r11 +pop rbx +ret + +AsmCpuid ENDP + +AsmGetLDTR PROC + sldt ax + ret +AsmGetLDTR ENDP + +AsmGetEs PROC + +xor rax,rax +mov ax,es +ret + +AsmGetEs ENDP + +AsmGetCs PROC + +xor rax,rax +mov ax,cs +ret + +AsmGetCs ENDP + +AsmGetDs PROC + +xor rax,rax +mov ax,ds +ret + +AsmGetDs ENDP + +AsmGetFs PROC + +xor rax,rax +mov ax,fs +ret + +AsmGetFs ENDP + +AsmGetGs PROC + +xor rax,rax +mov ax,gs +ret + +AsmGetGs ENDP + +AsmGetSs PROC + +xor rax,rax +mov ax,ss +ret + +AsmGetSs ENDP + +AsmGetTr PROC +xor rax,rax +str rax +ret +AsmGetTr ENDP + +AsmGetIdtBase PROC +sub rsp,10h +sidt qword ptr[rsp] +mov rax,qword ptr[rsp+2] +add rsp,10h +ret +AsmGetIdtBase ENDP + +AsmGetIdtLimit PROC +sub rsp,10h +sidt qword ptr[rsp] +xor rax,rax +mov ax,word ptr[rsp] +add rsp,10h +ret +AsmGetIdtLimit ENDP + +AsmGetGdtBase PROC +sub rsp,10h +sgdt qword ptr[rsp] +mov rax,qword ptr[rsp+2] +add rsp,10h +ret +AsmGetGdtBase ENDP + +AsmGetGdtLimit PROC +sub rsp,10h +sgdt qword ptr[rsp] +xor rax,rax +mov ax,word ptr[rsp] +add rsp,10h +ret +AsmGetGdtLimit ENDP + +AsmGetDr7 PROC + +xor rax,rax +mov rax,dr7 +ret + +AsmGetDr7 ENDP + +AsmSti Proc +sti +ret +AsmSti Endp + +AsmCli Proc +cli +ret +AsmCli Endp + +AsmLoadAccessRightsByte PROC + lar rax, rcx + ret +AsmLoadAccessRightsByte ENDP + +AsmInvpcid Proc + + invpcid rcx,oword ptr[rdx] + ret + +AsmInvpcid Endp + +_text ENDS + + END diff --git a/DICHook_OpenSource/KernelAsm.h b/DICHook_OpenSource/KernelAsm.h new file mode 100644 index 0000000..29ddf38 --- /dev/null +++ b/DICHook_OpenSource/KernelAsm.h @@ -0,0 +1,172 @@ +#pragma once + +#ifndef _KernelAsm_INCLUDED_ +#define _KernelAsm_INCLUDED_ +#include "ntifs.h" + +#undef KernelAsm_EXTERN +#define KernelAsm_EXTERN extern + +#ifdef __cplusplus + +#undef KernelAsm_EXTERN +#define KernelAsm_EXTERN extern "C" + +#endif // __cplusplus + +typedef struct _CpuidRet { + ULONG EAX; + ULONG EBX; + ULONG ECX; + ULONG EDX; +}CpuidRet; + +typedef struct +{ + unsigned PE : 1; + unsigned MP : 1; + unsigned EM : 1; + unsigned TS : 1; + unsigned ET : 1; + unsigned NE : 1; + unsigned Reserved_1 : 10; + unsigned WP : 1; + unsigned Reserved_2 : 1; + unsigned AM : 1; + unsigned Reserved_3 : 10; + unsigned NW : 1; + unsigned CD : 1; + unsigned PG : 1; + unsigned Reserved_64 : 32; +}_CR0; + +typedef struct +{ + unsigned VME : 1; + unsigned PVI : 1; + unsigned TSD : 1; + unsigned DE : 1; + unsigned PSE : 1; + unsigned PAE : 1; + unsigned MCE : 1; + unsigned PGE : 1; + unsigned PCE : 1; + unsigned OSFXSR : 1; + unsigned PSXMMEXCPT : 1; + unsigned UNKONOWN_1 : 1; //These are zero + unsigned UNKONOWN_2 : 1; //These are zero + unsigned VMXE : 1; //It's zero in normal + unsigned Reserved : 18; //These are zero + unsigned Reserved_64 : 32; +}_CR4; + +typedef struct +{ + unsigned CF : 1; + unsigned Unknown_1 : 1; //Always 1 + unsigned PF : 1; + unsigned Unknown_2 : 1; //Always 0 + unsigned AF : 1; + unsigned Unknown_3 : 1; //Always 0 + unsigned ZF : 1; + unsigned SF : 1; + unsigned TF : 1; + unsigned IF : 1; + unsigned DF : 1; + unsigned OF : 1; + unsigned TOPL : 2; + unsigned NT : 1; + unsigned Unknown_4 : 1; + unsigned RF : 1; + unsigned VM : 1; + unsigned AC : 1; + unsigned VIF : 1; + unsigned VIP : 1; + unsigned ID : 1; + unsigned Reserved : 10; //Always 0 + unsigned Reserved_64 : 32; //Always 0 +}_EFLAGS; + +typedef struct +{ + unsigned SSE3 : 1; + unsigned PCLMULQDQ : 1; + unsigned DTES64 : 1; + unsigned MONITOR : 1; + unsigned DS_CPL : 1; + unsigned VMX : 1; + unsigned SMX : 1; + unsigned EIST : 1; + unsigned TM2 : 1; + unsigned SSSE3 : 1; + unsigned Reserved : 22; + unsigned Reserved_64 : 32; +}_CPUID_ECX; + +typedef struct _IA32_FEATURE_CONTROL_MSR +{ + unsigned Lock : 1; // Bit 0 is the lock bit - cannot be modified once lock is set + unsigned EnableVmxonSMX : 1; // Undefined + unsigned EnableVmxon : 1; // Bit 2. If this bit is clear, VMXON causes a general protection exception + unsigned Reserved2 : 29; // Undefined + unsigned Reserved3 : 32; // Undefined + +} IA32_FEATURE_CONTROL_MSR; + +KernelAsm_EXTERN ULONG64 ReadSsQ(PULONG64); +KernelAsm_EXTERN VOID AsmInt2F(); +KernelAsm_EXTERN VOID AsmIntE1(); +KernelAsm_EXTERN ULONG64 AsmRdtsc(); +KernelAsm_EXTERN ULONG64 AsmGetRFlags(); +KernelAsm_EXTERN ULONG64 AsmGetRSP(); +KernelAsm_EXTERN ULONG64 AsmReadCr0(); +KernelAsm_EXTERN ULONG64 AsmReadCr2(); +KernelAsm_EXTERN ULONG64 AsmReadCr3(); +KernelAsm_EXTERN ULONG64 AsmReadCr4(); +KernelAsm_EXTERN ULONG64 AsmReadCr8(); +KernelAsm_EXTERN ULONG64 AsmReadMsr(ULONG Msr); +KernelAsm_EXTERN ULONG64 AsmWriteMsr(ULONG Msr, ULONG64 value); +KernelAsm_EXTERN ULONG64 AsmReadGs(ULONG offset); +KernelAsm_EXTERN VOID AsmWriteCr0(ULONG64 Cr0); +KernelAsm_EXTERN VOID AsmWriteCr4(ULONG64 Cr4); +KernelAsm_EXTERN VOID AsmWriteCr8(ULONG64 Cr8); +KernelAsm_EXTERN VOID AsmCpuid(ULONG Eax, ULONG Ecx, CpuidRet* ret); +KernelAsm_EXTERN ULONG64 AsmGetEs(); +KernelAsm_EXTERN ULONG64 AsmGetCs(); +KernelAsm_EXTERN ULONG64 AsmGetDs(); +KernelAsm_EXTERN ULONG64 AsmGetFs(); +KernelAsm_EXTERN ULONG64 AsmGetGs(); +KernelAsm_EXTERN ULONG64 AsmGetSs(); +KernelAsm_EXTERN ULONG64 AsmGetTr(); +KernelAsm_EXTERN USHORT AsmGetLDTR(); +KernelAsm_EXTERN ULONG64 AsmGetIdtBase(); +KernelAsm_EXTERN UINT16 AsmGetIdtLimit(); +KernelAsm_EXTERN ULONG64 AsmGetGdtBase(); +KernelAsm_EXTERN UINT16 AsmGetGdtLimit(); +KernelAsm_EXTERN ULONG64 AsmGetDr7(); +KernelAsm_EXTERN ULONG64 AsmLoadAccessRightsByte(ULONG64 segment_selector); +typedef struct _INVPCID_CTX { + ULONG64 PCID : 12; + ULONG64 Reserved : 52; + ULONG64 LinearAddress; +}INVPCID_CTX, * PINVPCID_CTX; +KernelAsm_EXTERN VOID AsmInvpcid(ULONG64 type, PINVPCID_CTX pDesc); +KernelAsm_EXTERN VOID AsmSti(); +KernelAsm_EXTERN VOID AsmCli(); + +#define AsmGetCr0 AsmReadCr0 +#define AsmGetCr3 AsmReadCr3 +#define AsmGetCr4 AsmReadCr4 +#define AsmGetCr8 AsmReadCr8 + +#define AsmReadES AsmGetEs +#define AsmReadCS AsmGetCs +#define AsmReadDS AsmGetDs +#define AsmReadFS AsmGetFs +#define AsmReadGS AsmGetGs +#define AsmReadSS AsmGetSs +#define AsmReadTR AsmGetTr +#define AsmReadLDTR AsmGetLDTR + +#endif // !_KernelAsm_INCLUDED_ + diff --git a/DICHook_OpenSource/MyMemoryIo64.cpp b/DICHook_OpenSource/MyMemoryIo64.cpp new file mode 100644 index 0000000..8e241b4 --- /dev/null +++ b/DICHook_OpenSource/MyMemoryIo64.cpp @@ -0,0 +1,131 @@ +#include "MyMemoryIo64.h" + +DWORD64 g_PteBase = NULL; +DWORD64 g_PdeBase = NULL; +DWORD64 g_PpeBase = NULL; +DWORD64 g_PxeBase = NULL; + +union VirtualAddress { + ULONG64 all; + struct { + ULONG64 offset : 12; + ULONG64 pte_index : 9; + ULONG64 pde_index : 9; + ULONG64 ppe_index : 9; + ULONG64 pxe_index : 9; + ULONG64 head : 16; + }; +}; + +DWORD64 MmiGetPteAddress(PVOID64 Address) { + return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 12) << 3) + g_PteBase); +} +DWORD64 MmiGetPdeAddress(PVOID64 Address) { + return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 21) << 3) + g_PdeBase); +} +DWORD64 MmiGetPpeAddress(PVOID64 Address) { + return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 30) << 3) + g_PpeBase); +} +DWORD64 MmiGetPxeAddress(PVOID64 Address) { + return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 39) << 3) + g_PxeBase); +} + +bool g_invpcid_enable = 0; +bool g_clfsh_enable = 0; +BOOLEAN Mmi_Init() { + if (g_PteBase) + return TRUE; + g_PteBase = (DWORD64)KGetPteBase(); + if (g_PteBase == 0) { + KeBugCheck(0x8787878); + return FALSE; + } + g_PdeBase = MmiGetPteAddress((PVOID)g_PteBase); + g_PpeBase = MmiGetPteAddress((PVOID)g_PdeBase); + g_PxeBase = MmiGetPteAddress((PVOID)g_PpeBase); + + CpuidRet cpuid_ret; + memset(&cpuid_ret, 0, sizeof(cpuid_ret)); + AsmCpuid(7, 0, &cpuid_ret); + g_invpcid_enable = cpuid_ret.EBX & 0x400; + AsmCpuid(1, 0, &cpuid_ret); + g_clfsh_enable = cpuid_ret.EDX & 0x80000; + return TRUE; +} +VOID MmiClearPteBase() { + g_PteBase = 0; + g_PdeBase = 0; + g_PpeBase = 0; + g_PxeBase = 0; +} +VOID MmiFlushTLB(PVOID LinearAddress) { + /*if (g_invpcid_enable) { + BOOL i_enable = AsmGetRFlags() & 0x200; + if (i_enable) + _disable(); + CR4 cr4; + cr4.all = __readcr4(); + if (cr4.PCIDE) { + INVPCID_CTX ctx; + ctx.LinearAddress = (ULONG64)LinearAddress; + ctx.PCID = __readcr3() & 0xFFF; + if (ctx.PCID != 0) { + AsmInvpcid(0, &ctx); + return; + } + } + if (i_enable) + _enable(); + + }*/ + /*if (g_clfsh_enable) { + _mm_mfence(); + _mm_clflush(LinearAddress); + } + else*/ + __invlpg(LinearAddress); + +} +ULONG64 MmiGetPhysicalAddress(PVOID va) { + HardwarePteX64 PageEntry[3] = { 0 }; + HardwarePteX64 page; + + PULONG64 p_pxe = (PULONG64)MmiGetPxeAddress(va); + page.all = *p_pxe; + if (page.valid == 0) + return 0; + if (page.large_page) { + ULONG64 off = (ULONG64)va & 0x7FFFFFFFFF; + ULONG64 PhyAdd = page.page_frame_number << 12; + PhyAdd += off; + return PhyAdd; + } + PULONG64 p_ppe = (PULONG64)MmiGetPpeAddress(va); + page.all = *p_ppe; + if (page.valid == 0) + return 0; + if (page.large_page) { + ULONG64 off = (ULONG64)va & 0x3FFFFFFF; + ULONG64 PhyAdd = page.page_frame_number << 12; + PhyAdd += off; + return PhyAdd; + } + PULONG64 p_pde = (PULONG64)MmiGetPdeAddress(va); + page.all = *p_pde; + if (page.valid == 0) + return 0; + if (page.large_page) { + ULONG64 off = (ULONG64)va & 0x1FFFFF; + ULONG64 PhyAdd = page.page_frame_number << 12; + PhyAdd += off; + return PhyAdd; + } + PULONG64 p_pte = (PULONG64)MmiGetPteAddress(va); + page.all = *p_pte; + if (page.valid == 0) + return 0; + ULONG64 off = (ULONG64)va & 0xFFF; + ULONG64 PhyAdd = page.page_frame_number << 12; + PhyAdd += off; + return PhyAdd; +} diff --git a/DICHook_OpenSource/MyMemoryIo64.h b/DICHook_OpenSource/MyMemoryIo64.h new file mode 100644 index 0000000..0caadb0 --- /dev/null +++ b/DICHook_OpenSource/MyMemoryIo64.h @@ -0,0 +1,156 @@ +#pragma once + +#ifndef __MyMempryIO64___Included___ +#define __MyMempryIO64___Included___ +#include "ntifs.h" +#include "windef.h" +#include "ntimage.h" +#include "intrin.h" +#include "DDKCommon.h" + + +struct HardwarePteX64 { + union + { + ULONG64 all; + struct { + ULONG64 valid : 1; //!< [0] + ULONG64 write : 1; //!< [1] + ULONG64 owner : 1; //!< [2] + ULONG64 write_through : 1; //!< [3] PWT + ULONG64 cache_disable : 1; //!< [4] PCD + ULONG64 accessed : 1; //!< [5] + ULONG64 dirty : 1; //!< [6] + ULONG64 large_page : 1; //!< [7] PAT + ULONG64 global : 1; //!< [8] + ULONG64 copy_on_write : 1; //!< [9] + ULONG64 prototype : 1; //!< [10] + ULONG64 reserved0 : 1; //!< [11] + ULONG64 page_frame_number : 36; //!< [12:47] + ULONG64 reserved1 : 4; //!< [48:51] + ULONG64 software_ws_index : 11; //!< [52:62] + ULONG64 no_execute : 1; //!< [63] + }; + }; + +}; +struct CR4 { + union { + ULONG64 all; + struct { + ULONG64 VME : 1; + ULONG64 PVI : 1; + ULONG64 TSD : 1; + ULONG64 DE : 1; + ULONG64 PSE : 1; + ULONG64 PAE : 1; + ULONG64 MCE : 1; + ULONG64 PGE : 1; + ULONG64 PCE : 1; + ULONG64 OSFXSR : 1; + ULONG64 OSXMMEXCPT : 1; + ULONG64 UMIP : 1; + ULONG64 LA57 : 1; + ULONG64 VMXE : 1; + ULONG64 SMXE : 1; + ULONG64 Reversed1 : 1; + ULONG64 FSGSBASE : 1; + ULONG64 PCIDE : 1; + ULONG64 OSXSAVE : 1; + ULONG64 Reversed2 : 1; + ULONG64 SMEP : 1; + ULONG64 SMAP : 1; + ULONG64 PKE : 1; + }; + }; +}; + +typedef struct _MyVirtualAddress { + union { + struct { + ULONG64 offset : 12; + ULONG64 pte_index : 9; + ULONG64 pde_index : 9; + ULONG64 ppe_index : 9; + ULONG64 pxe_index : 9; + }; + ULONG64 VirtualAddress; + }; +}MyVirtualAddress, *PMyVirtualAddress; + +typedef struct _MyPageTableEntry { + union { + struct { + ULONG64 Present : 1; + ULONG64 Writable : 1; + ULONG64 UserAccessible : 1; + ULONG64 WriteThrough : 1; + ULONG64 DisableCache : 1; + ULONG64 Accessd : 1; + ULONG64 Dirty : 1; + ULONG64 HugePage : 1; + ULONG64 Global : 1; + ULONG64 Available1 : 3; + ULONG64 PhysicalAddress : 40; + ULONG64 Available2 : 11; + ULONG64 NoExecute : 1; + }; + ULONG64 Value; + }; +}MyPageTableEntry, *PMyPageTableEntry; + +#define MmiInvaildAddressValue ((PVOID64)~0) + +#define MmiEntryToAddress(v) (((ULONG64)v)&0x000FFFFFFFFFF000) +#define MmiEntryFlag_Present ((ULONG64)0x0000000000000001) +#define MmiEntryFlag_Write ((ULONG64)0x0000000000000002) +#define MmiEntryFlag_UserAccessible ((ULONG64)0x0000000000000004) +#define MmiEntryFlag_WriteThrough ((ULONG64)0x0000000000000008) +#define MmiEntryFlag_DisableCache ((ULONG64)0x0000000000000010) +#define MmiEntryFlag_Accessed ((ULONG64)0x0000000000000020) +#define MmiEntryFlag_Dirty ((ULONG64)0x0000000000000040) +#define MmiEntryFlag_HugePage ((ULONG64)0x0000000000000080) +#define MmiEntryFlag_Global ((ULONG64)0x0000000000000100) +#define MmiEntryFlag_NoExecute ((ULONG64)0x8000000000000000) + +#define MmiEntryFlag_EntryPage (MmiEntryFlag_Present | MmiEntryFlag_Write | MmiEntryFlag_Accessed | MmiEntryFlag_Dirty) +#define MmiEntryFlag_ReadOnlyPage (MmiEntryFlag_Present | MmiEntryFlag_Accessed | MmiEntryFlag_Dirty) + +#define MmiCheckFlag(e,f) (e&f) + +#define MmiMakeVirtualAddressHigh16(pxe) ((pxe&0x100)?((ULONG64)0xFFFF000000000000):((ULONG64)0x0000000000000000)) +#define MmiMakeVirtualAddress_PXE(pxe) (MmiMakeVirtualAddressHigh16(pxe)|(((ULONG64)pxe)<<39)) +#define MmiMakeVirtualAddress_PPE(pxe,ppe) (MmiMakeVirtualAddressHigh16(pxe)|(((ULONG64)pxe)<<39)|(((ULONG64)ppe)<<30)) +#define MmiMakeVirtualAddress_PDE(pxe,ppe,pde) (MmiMakeVirtualAddressHigh16(pxe)|(((ULONG64)pxe)<<39)|(((ULONG64)ppe)<<30)|(((ULONG64)pde)<<21)) +#define MmiMakeVirtualAddress_PTE(pxe,ppe,pde,pte) (MmiMakeVirtualAddressHigh16(pxe)|(((ULONG64)pxe)<<39)|(((ULONG64)ppe)<<30)|(((ULONG64)pde)<<21)|(((ULONG64)pte)<<12)) +#define MmiMakeVirtualAddress(pxe,ppe,pde,pte,o) (MmiMakeVirtualAddressHigh16(pxe)|(((ULONG64)pxe)<<39)|(((ULONG64)ppe)<<30)|(((ULONG64)pde)<<21)|(((ULONG64)pte)<<12)|((ULONG64)o)) + + +#define MmiVA_GetPXEIndex(v) ((((ULONG64)v)&((ULONG64)0x0000FF8000000000))>>39) +#define MmiVA_GetPPEIndex(v) ((((ULONG64)v)&((ULONG64)0x0000007FC0000000))>>30) +#define MmiVA_GetPDEIndex(v) ((((ULONG64)v)&((ULONG64)0x000000003FE00000))>>21) +#define MmiVA_GetPTEIndex(v) ((((ULONG64)v)&((ULONG64)0x00000000001FF000))>>12) +#define MmiVA_GetOFFSET(v) (((ULONG64)v)&((ULONG64)0x0000000000000FFF)) + +#define MmiGetPhysicalPFN(p) (((ULONG64)(p)&0x0000FFFFFFFFF000)>>12) +#define MmiGetCr3() (MmiEntryToAddress(__readcr3())) + +#ifdef __cplusplus +extern "C" { +#endif + +BOOLEAN Mmi_Init(); +VOID MmiClearPteBase(); +DWORD64 MmiGetPteAddress(PVOID64 Address); +DWORD64 MmiGetPdeAddress(PVOID64 Address); +DWORD64 MmiGetPpeAddress(PVOID64 Address); +DWORD64 MmiGetPxeAddress(PVOID64 Address); +VOID MmiFlushTLB(PVOID LinearAddress); +DWORD64 MmiGetPhysicalAddress(PVOID VirtualAddress); + +ULONG64 MmiGetPhysicalAddress(PVOID va); +#ifdef __cplusplus +} +#endif + +#endif // !__MempryIO___Included___ diff --git a/DICHook_OpenSource/MyPEB.h b/DICHook_OpenSource/MyPEB.h new file mode 100644 index 0000000..1c22c98 --- /dev/null +++ b/DICHook_OpenSource/MyPEB.h @@ -0,0 +1,139 @@ +#pragma once + +#ifndef __MYPEB_INCLUDED__ +#define __MYPEB_INCLUDED__ + +#include "ntifs.h" +#include "windef.h" + +typedef struct _MYUNICODE_STRING32 +{ + USHORT Length; + USHORT MaximumLength; + ULONG Buffer; +} MYUNICODE_STRING32, *PMYUNICODE_STRING32; + +typedef struct _MYPEB32 +{ + UCHAR InheritedAddressSpace; + UCHAR ReadImageFileExecOptions; + UCHAR BeingDebugged; + UCHAR BitField; + ULONG Mutant; + ULONG ImageBaseAddress; + ULONG Ldr; + ULONG ProcessParameters; + ULONG SubSystemData; + ULONG ProcessHeap; + ULONG FastPebLock; + ULONG AtlThunkSListPtr; + ULONG IFEOKey; + ULONG CrossProcessFlags; + ULONG UserSharedInfoPtr; + ULONG SystemReserved; + ULONG AtlThunkSListPtr32; + ULONG ApiSetMap; +} MYPEB32, *PMYPEB32; + +typedef struct _PEB_LDR_DATA32 +{ + ULONG Length; + BOOLEAN Initialized; + ULONG SsHandle; + LIST_ENTRY32 InLoadOrderModuleList; + LIST_ENTRY32 InMemoryOrderModuleList; + LIST_ENTRY32 InInitializationOrderModuleList; + ULONG EntryInProgress; +} PEB_LDR_DATA32, *PPEB_LDR_DATA32; + +typedef struct _LDR_DATA_TABLE_ENTRY32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderModuleList; + LIST_ENTRY32 InInitializationOrderModuleList; + ULONG DllBase; + ULONG EntryPoint; + ULONG SizeOfImage; + MYUNICODE_STRING32 FullDllName; + MYUNICODE_STRING32 BaseDllName; + ULONG Flags; + USHORT LoadCount; + USHORT TlsIndex; + union + { + LIST_ENTRY32 HashLinks; + ULONG SectionPointer; + }; + ULONG CheckSum; + union + { + ULONG TimeDateStamp; + ULONG LoadedImports; + }; + ULONG EntryPointActivationContext; + ULONG PatchInformation; +} LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32; + +typedef struct _PEB_LDR_DATA +{ + DWORD Length; + UCHAR Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID EntryInProgress; +}PEB_LDR_DATA, *PPEB_LDR_DATA; + +typedef struct _LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + PVOID DllBase; + PVOID EntryPoint; + DWORD SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + DWORD Flags; + WORD LoadCount; + WORD TlsIndex; + LIST_ENTRY HashLinks; + PVOID SectionPointer; + DWORD CheckSum; + DWORD TimeDateStamp; + PVOID LoadedImports; + PVOID EntryPointActivationContext; + PVOID PatchInformation; +}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; + +typedef struct _MYPEB +{ + UCHAR InheritedAddressSpace; + UCHAR ReadImageFileExecOptions; + UCHAR BeingDebugged; + UCHAR SpareBool; + PVOID Mutant; + PVOID ImageBaseAddress; + PPEB_LDR_DATA Ldr; +}MYPEB, *PMYPEB; + +#ifdef __cplusplus +extern "C"{ +#endif + +NTKERNELAPI PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process); +NTKERNELAPI PPEB NTAPI PsGetProcessWow64Process(PEPROCESS Process); + +#ifdef __cplusplus +} +#endif + + + + + +#endif // !__MYPEB_INCLUDED + + + diff --git a/DICHook_OpenSource/NtFunctionDefine.h b/DICHook_OpenSource/NtFunctionDefine.h new file mode 100644 index 0000000..5e3c8e3 --- /dev/null +++ b/DICHook_OpenSource/NtFunctionDefine.h @@ -0,0 +1,248 @@ +#pragma once +#ifndef _EXPORTS__INDLC +#define _EXPORTS__INDLC + +#include "ntifs.h" +typedef enum _SYSTEM_INFORMATION_CLASS { + SystemBasicInformation, + SystemProcessorInformation, + SystemPerformanceInformation, + SystemTimeOfDayInformation, + SystemNotImplemented1, + SystemProcessesAndThreadsInformation, + SystemCallCounts, + SystemConfigurationInformation, + SystemProcessorTimes, + SystemGlobalFlag, + SystemNotImplemented2, + SystemModuleInformation, + SystemLockInformation, + SystemNotImplemented3, + SystemNotImplemented4, + SystemNotImplemented5, + SystemHandleInformation, + SystemObjectInformation, + SystemPagefileInformation, + SystemInstructionEmulationCounts, + SystemInvalidInfoClass1, + SystemCacheInformation, + SystemPoolTagInformation, + SystemProcessorStatistics, + SystemDpcInformation, + SystemNotImplemented6, + SystemLoadImage, + SystemUnloadImage, + SystemTimeAdjustment, + SystemNotImplemented7, + SystemNotImplemented8, + SystemNotImplemented9, + SystemCrashDumpInformation, + SystemExceptionInformation, + SystemCrashDumpStateInformation, + SystemKernelDebuggerInformation, + SystemContextSwitchInformation, + SystemRegistryQuotaInformation, + SystemLoadAndCallImage, + SystemPrioritySeparation, + SystemNotImplemented10, + SystemNotImplemented11, + SystemInvalidInfoClass2, + SystemInvalidInfoClass3, + SystemTimeZoneInformation, + SystemLookasideInformation, + SystemSetTimeSlipEvent, + SystemCreateSession, + SystemDeleteSession, + SystemInvalidInfoClass4, + SystemRangeStartInformation, + SystemVerifierInformation, + SystemAddVerifier, + SystemSessionProcessesInformation +} SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS; + +typedef struct _SYSTEM_HANDLE_INFORMATION { + USHORT ProcessId; + USHORT CreatorBackTraceIndex; + UCHAR ObjectTypeNumber; + UCHAR Flags; + USHORT Handle; + PVOID Object; + ACCESS_MASK GrantedAccess; +} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; +typedef struct _SYSTEM_HANDLE_INFORMATION_EX { + ULONG NumberOfHandles; + SYSTEM_HANDLE_INFORMATION Information[1]; +} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX; + +typedef struct _SYSTEM_THREAD_INFORMATION { + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + KPRIORITY Priority; + KPRIORITY BasePriority; + ULONG ContextSwitchCount; + LONG State; + LONG WaitReason; +} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION; +typedef struct _SYSTEM_PROCESS_INFORMATION { + ULONG NextEntryDelta; + ULONG ThreadCount; + ULONG Reserved1[6]; + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ProcessName; + KPRIORITY BasePriority; + ULONG ProcessId; + ULONG InheritedFromProcessId; + ULONG HandleCount; + ULONG Reserved2[2]; + VM_COUNTERS VmCounters; + IO_COUNTERS IoCounters; + SYSTEM_THREAD_INFORMATION Threads[1]; +} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; +typedef struct _SYSTEM_MODULE { + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[MAXIMUM_FILENAME_LENGTH]; +} SYSTEM_MODULE, * PSYSTEM_MODULE; + +typedef struct _SYSTEM_MODULE_INFORMATION { + ULONG NumberOfModules; + SYSTEM_MODULE Modules[1]; +} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION; + +typedef struct _SYSTEM_BIGPOOL_ENTRY +{ + union { + PVOID VirtualAddress; + ULONG_PTR NonPaged : 1; + }; + ULONG_PTR SizeInBytes; + union { + UCHAR Tag[4]; + ULONG TagUlong; + }; +} SYSTEM_BIGPOOL_ENTRY, *PSYSTEM_BIGPOOL_ENTRY; + +typedef struct _SYSTEM_BIGPOOL_INFORMATION { + ULONG Count; + SYSTEM_BIGPOOL_ENTRY AllocatedInfo[ANYSIZE_ARRAY]; +} SYSTEM_BIGPOOL_INFORMATION, *PSYSTEM_BIGPOOL_INFORMATION; + +/*typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { + DWORD BeginAddress; + DWORD EndAddress; + union { + DWORD UnwindInfoAddress; + DWORD UnwindData; + } DUMMYUNIONNAME; +} RUNTIME_FUNCTION, * PRUNTIME_FUNCTION, _IMAGE_RUNTIME_FUNCTION_ENTRY, * _PIMAGE_RUNTIME_FUNCTION_ENTRY;*/ +typedef enum _MYOBJECT_INFORMATION_CLASS +{ + myObjectBasicInformation = 0, + myObjectNameInformation, + myObjectTypeInformation, + myObjectTypesInformation, + myObjectHandleFlagInformation, + myObjectSessionInformation, + myMaxObjectInfoClass +} MYOBJECT_INFORMATION_CLASS, * PMYOBJECT_INFORMATION_CLASS; +typedef struct _MYOBJECT_HANDLE_ATTRIBUTE_INFORMATION +{ + BOOLEAN Inherit; + BOOLEAN ProtectFromClose; +} MYOBJECT_HANDLE_ATTRIBUTE_INFORMATION, * PMYOBJECT_HANDLE_ATTRIBUTE_INFORMATION; + +typedef struct _MYOBJECT_TYPE_INFORMATION +{ + UNICODE_STRING TypeName; + ULONG TotalNumberOfObjects; + ULONG TotalNumberOfHandles; + ULONG TotalPagedPoolUsage; + ULONG TotalNonPagedPoolUsage; + ULONG TotalNamePoolUsage; + ULONG TotalHandleTableUsage; + ULONG HighWaterNumberOfObjects; + ULONG HighWaterNumberOfHandles; + ULONG HighWaterPagedPoolUsage; + ULONG HighWaterNonPagedPoolUsage; + ULONG HighWaterNamePoolUsage; + ULONG HighWaterHandleTableUsage; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ULONG ValidAccessMask; + BOOLEAN SecurityRequired; + BOOLEAN MaintainHandleCount; + ULONG PoolType; + ULONG DefaultPagedPoolCharge; + ULONG DefaultNonPagedPoolCharge; +} MYOBJECT_TYPE_INFORMATION, * PMYOBJECT_TYPE_INFORMATION; + +typedef struct _MYOBJECT_NAME_INFORMATION +{ + UNICODE_STRING Name; +} MYOBJECT_NAME_INFORMATION, * PMYOBJECT_NAME_INFORMATION; + + +#ifdef __cplusplus +extern "C" { +#endif + +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySystemInformation( + IN SYSTEM_INFORMATION_CLASS SystemInformationClass, + OUT PVOID SystemInformation, + IN ULONG SystemInformationLength, + OUT PULONG ReturnLength OPTIONAL +); +NTKERNELAPI NTSTATUS ObReferenceObjectByName(__in PUNICODE_STRING ObjectName, + __in ULONG Attributes, + __in_opt PACCESS_STATE AccessState, + __in_opt ACCESS_MASK DesiredAccess, + __in POBJECT_TYPE ObjectType, + __in KPROCESSOR_MODE AccessMode, + __inout_opt PVOID ParseContext, + __out PVOID * Object +); +extern POBJECT_TYPE *IoDriverObjectType; + +NTKERNELAPI +UCHAR* PsGetProcessImageFileName(__in PEPROCESS Process); +NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(IN PEPROCESS Process); +NTKERNELAPI +PVOID +PsGetProcessSectionBaseAddress( + __in PEPROCESS Process +); +PEJOB NTAPI PsGetProcessJob(PEPROCESS Process); +PEPROCESS NTAPI PsGetCurrentThreadProcess(VOID); +POBJECT_TYPE NTAPI ObGetObjectType(IN PVOID pObject); +NTSTATUS NTAPI ZwQueryInformationProcess( + _In_ HANDLE ProcessHandle, + _In_ PROCESSINFOCLASS ProcessInformationClass, + _Out_ PVOID ProcessInformation, + _In_ ULONG ProcessInformationLength, + _Out_opt_ PULONG ReturnLength +); + +#ifdef __cplusplus +} +#endif + +#endif // !_EXPORTS__INDLC + + + diff --git a/DICHook_OpenSource/main.cpp b/DICHook_OpenSource/main.cpp new file mode 100644 index 0000000..8a5572b --- /dev/null +++ b/DICHook_OpenSource/main.cpp @@ -0,0 +1,65 @@ +#include "DDKCommon.h" +#include "MyMemoryIo64.h" +#include "HwidHook.h" +#include + +VOID NtDeviceIoControlFileCallback(ULONG64 IoControlCode, ULONG64 InputBuffer, ULONG64 InputBufferLength, ULONG64 OutputBuffer, ULONG64 OutputBufferLength) { + //´Ëʱirql == 2 ! + // + //ÐÞ¸ÄÎïÀíMacµØÖ·Àý×Ó + if (IoControlCode == IOCTL_NDIS_QUERY_GLOBAL_STATS && + InputBufferLength >= 4 && MmiGetPhysicalAddress((PVOID)InputBuffer) && MmiGetPhysicalAddress((PVOID)(InputBuffer + 4 - 1)) && + OutputBufferLength >= 6 && MmiGetPhysicalAddress((PVOID)OutputBuffer) && MmiGetPhysicalAddress((PVOID)(OutputBuffer + 6 - 1))) { + DWORD Code = *(DWORD*)(InputBuffer); + switch (Code) { + case OID_802_3_PERMANENT_ADDRESS: + case OID_802_3_CURRENT_ADDRESS: + case OID_802_5_PERMANENT_ADDRESS: + case OID_802_5_CURRENT_ADDRESS: + { + PUCHAR pMac = (PUCHAR)OutputBuffer; + pMac[0] = 0x00; pMac[1] = 0x11; pMac[2] = 0x22; pMac[3] = 0x33; pMac[4] = 0x44; pMac[5] = 0x55; + break; + } + default: + break; + } + } +} +VOID NtQueryVolumeInformationFileCallback(ULONG64 FsInformationClass, ULONG64 FsInformation, ULONG64 Length) { + //´Ëʱirql == 2 ! + // + //Ð޸ķÖÇøÐòÁкÅÀý×Ó + switch (FsInformationClass) + { + case FileFsVolumeInformation: + { + if (Length >= sizeof(FILE_FS_VOLUME_INFORMATION) && + MmiGetPhysicalAddress((PVOID)FsInformation) && + MmiGetPhysicalAddress((PVOID)(FsInformation + sizeof(FILE_FS_VOLUME_INFORMATION) - 1))) { + + PFILE_FS_VOLUME_INFORMATION pinfo = (PFILE_FS_VOLUME_INFORMATION)FsInformation; + pinfo->VolumeSerialNumber = 0; + } + break; + } + default: + break; + } +} +extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT drv, PUNICODE_STRING reg_path) { + Mmi_Init(); + GetRealTime();//³õʼ»¯GetRealTime + + //ÉèÖÃÊÇ·ñÆôÓà NtQueryVolumeInformationFile Hook,TRUEΪ¿ªÆô,FALSEΪ¹Ø±Õ + //×¢Òâ,win10 1507 - win10 1709²»Ö§³ÖNtQueryVolumeInformationFile Hook,ÒòΪÎÞ·¨´Ó¶ÑÕ»ÖлñÈ¡µ½²ÎÊý + //NtQueryVolumeInformationFile Hook ÍêÃÀ¼æÈÝwin7ÒÔ¼°win10 1803¼°ÒÔÉÏ°æ±¾ + setntqhookstats(FALSE); + + //ÉèÖÃNtDeviceIoControlFile HookµÄCallback,win7,win10ȫϵͳ¼æÈÝ + setdicprecabk(NtDeviceIoControlFileCallback); + + //ÉèÖÃNtQueryVolumeInformationFile HookµÄCallback + setntqcabk(NtQueryVolumeInformationFileCallback); + return STATUS_SUCCESS; +} diff --git a/DICHook_OpenSource/vtstruct.h b/DICHook_OpenSource/vtstruct.h new file mode 100644 index 0000000..ce4d8f0 --- /dev/null +++ b/DICHook_OpenSource/vtstruct.h @@ -0,0 +1,605 @@ +#pragma once + + +#ifndef _VTSTRUCT__INCLUDED__ +#define _VTSTRUCT__INCLUDED__ + +#include "ntifs.h" + +enum class Msr : unsigned long { + kIa32ApicBase = 0x01B, + + kIa32FeatureControl = 0x03A, + + kIa32SysenterCs = 0x174, + kIa32SysenterEsp = 0x175, + kIa32SysenterEip = 0x176, + + kIa32Debugctl = 0x1D9, + + kIa32MtrrCap = 0xFE, + kIa32MtrrDefType = 0x2FF, + kIa32MtrrPhysBaseN = 0x200, + kIa32MtrrPhysMaskN = 0x201, + kIa32MtrrFix64k00000 = 0x250, + kIa32MtrrFix16k80000 = 0x258, + kIa32MtrrFix16kA0000 = 0x259, + kIa32MtrrFix4kC0000 = 0x268, + kIa32MtrrFix4kC8000 = 0x269, + kIa32MtrrFix4kD0000 = 0x26A, + kIa32MtrrFix4kD8000 = 0x26B, + kIa32MtrrFix4kE0000 = 0x26C, + kIa32MtrrFix4kE8000 = 0x26D, + kIa32MtrrFix4kF0000 = 0x26E, + kIa32MtrrFix4kF8000 = 0x26F, + + kIa32VmxBasic = 0x480, + kIa32VmxPinbasedCtls = 0x481, + kIa32VmxProcBasedCtls = 0x482, + kIa32VmxExitCtls = 0x483, + kIa32VmxEntryCtls = 0x484, + kIa32VmxMisc = 0x485, + kIa32VmxCr0Fixed0 = 0x486, + kIa32VmxCr0Fixed1 = 0x487, + kIa32VmxCr4Fixed0 = 0x488, + kIa32VmxCr4Fixed1 = 0x489, + kIa32VmxVmcsEnum = 0x48A, + kIa32VmxProcBasedCtls2 = 0x48B, + kIa32VmxEptVpidCap = 0x48C, + kIa32VmxTruePinbasedCtls = 0x48D, + kIa32VmxTrueProcBasedCtls = 0x48E, + kIa32VmxTrueExitCtls = 0x48F, + kIa32VmxTrueEntryCtls = 0x490, + kIa32VmxVmfunc = 0x491, + + kIa32Efer = 0xC0000080, + kIa32Star = 0xC0000081, + kIa32Lstar = 0xC0000082, + + kIa32Fmask = 0xC0000084, + + kIa32FsBase = 0xC0000100, + kIa32GsBase = 0xC0000101, + kIa32KernelGsBase = 0xC0000102, + kIa32TscAux = 0xC0000103, +}; +enum class VmcsField : unsigned __int32 { + // 16-Bit Control Field + kVirtualProcessorId = 0x00000000, + kPostedInterruptNotification = 0x00000002, + kEptpIndex = 0x00000004, + // 16-Bit Guest-State Fields + kGuestEsSelector = 0x00000800, + kGuestCsSelector = 0x00000802, + kGuestSsSelector = 0x00000804, + kGuestDsSelector = 0x00000806, + kGuestFsSelector = 0x00000808, + kGuestGsSelector = 0x0000080a, + kGuestLdtrSelector = 0x0000080c, + kGuestTrSelector = 0x0000080e, + kGuestInterruptStatus = 0x00000810, + kPmlIndex = 0x00000812, + // 16-Bit Host-State Fields + kHostEsSelector = 0x00000c00, + kHostCsSelector = 0x00000c02, + kHostSsSelector = 0x00000c04, + kHostDsSelector = 0x00000c06, + kHostFsSelector = 0x00000c08, + kHostGsSelector = 0x00000c0a, + kHostTrSelector = 0x00000c0c, + // 64-Bit Control Fields + kIoBitmapA = 0x00002000, + kIoBitmapAHigh = 0x00002001, + kIoBitmapB = 0x00002002, + kIoBitmapBHigh = 0x00002003, + kMsrBitmap = 0x00002004, + kMsrBitmapHigh = 0x00002005, + kVmExitMsrStoreAddr = 0x00002006, + kVmExitMsrStoreAddrHigh = 0x00002007, + kVmExitMsrLoadAddr = 0x00002008, + kVmExitMsrLoadAddrHigh = 0x00002009, + kVmEntryMsrLoadAddr = 0x0000200a, + kVmEntryMsrLoadAddrHigh = 0x0000200b, + kExecutiveVmcsPointer = 0x0000200c, + kExecutiveVmcsPointerHigh = 0x0000200d, + kTscOffset = 0x00002010, + kTscOffsetHigh = 0x00002011, + kVirtualApicPageAddr = 0x00002012, + kVirtualApicPageAddrHigh = 0x00002013, + kApicAccessAddr = 0x00002014, + kApicAccessAddrHigh = 0x00002015, + kEptPointer = 0x0000201a, + kEptPointerHigh = 0x0000201b, + kEoiExitBitmap0 = 0x0000201c, + kEoiExitBitmap0High = 0x0000201d, + kEoiExitBitmap1 = 0x0000201e, + kEoiExitBitmap1High = 0x0000201f, + kEoiExitBitmap2 = 0x00002020, + kEoiExitBitmap2High = 0x00002021, + kEoiExitBitmap3 = 0x00002022, + kEoiExitBitmap3High = 0x00002023, + kEptpListAddress = 0x00002024, + kEptpListAddressHigh = 0x00002025, + kVmreadBitmapAddress = 0x00002026, + kVmreadBitmapAddressHigh = 0x00002027, + kVmwriteBitmapAddress = 0x00002028, + kVmwriteBitmapAddressHigh = 0x00002029, + kVirtualizationExceptionInfoAddress = 0x0000202a, + kVirtualizationExceptionInfoAddressHigh = 0x0000202b, + kXssExitingBitmap = 0x0000202c, + kXssExitingBitmapHigh = 0x0000202d, + kEnclsExitingBitmap = 0x0000202e, + kEnclsExitingBitmapHigh = 0x0000202f, + kTscMultiplier = 0x00002032, + kTscMultiplierHigh = 0x00002033, + // 64-Bit Read-Only Data Field + kGuestPhysicalAddress = 0x00002400, + kGuestPhysicalAddressHigh = 0x00002401, + // 64-Bit Guest-State Fields + kVmcsLinkPointer = 0x00002800, + kVmcsLinkPointerHigh = 0x00002801, + kGuestIa32Debugctl = 0x00002802, + kGuestIa32DebugctlHigh = 0x00002803, + kGuestIa32Pat = 0x00002804, + kGuestIa32PatHigh = 0x00002805, + kGuestIa32Efer = 0x00002806, + kGuestIa32EferHigh = 0x00002807, + kGuestIa32PerfGlobalCtrl = 0x00002808, + kGuestIa32PerfGlobalCtrlHigh = 0x00002809, + kGuestPdptr0 = 0x0000280a, + kGuestPdptr0High = 0x0000280b, + kGuestPdptr1 = 0x0000280c, + kGuestPdptr1High = 0x0000280d, + kGuestPdptr2 = 0x0000280e, + kGuestPdptr2High = 0x0000280f, + kGuestPdptr3 = 0x00002810, + kGuestPdptr3High = 0x00002811, + kGuestIa32Bndcfgs = 0x00002812, + kGuestIa32BndcfgsHigh = 0x00002813, + // 64-Bit Host-State Fields + kHostIa32Pat = 0x00002c00, + kHostIa32PatHigh = 0x00002c01, + kHostIa32Efer = 0x00002c02, + kHostIa32EferHigh = 0x00002c03, + kHostIa32PerfGlobalCtrl = 0x00002c04, + kHostIa32PerfGlobalCtrlHigh = 0x00002c05, + // 32-Bit Control Fields + kPinBasedVmExecControl = 0x00004000, + kCpuBasedVmExecControl = 0x00004002, + kExceptionBitmap = 0x00004004, + kPageFaultErrorCodeMask = 0x00004006, + kPageFaultErrorCodeMatch = 0x00004008, + kCr3TargetCount = 0x0000400a, + kVmExitControls = 0x0000400c, + kVmExitMsrStoreCount = 0x0000400e, + kVmExitMsrLoadCount = 0x00004010, + kVmEntryControls = 0x00004012, + kVmEntryMsrLoadCount = 0x00004014, + kVmEntryIntrInfoField = 0x00004016, + kVmEntryExceptionErrorCode = 0x00004018, + kVmEntryInstructionLen = 0x0000401a, + kTprThreshold = 0x0000401c, + kSecondaryVmExecControl = 0x0000401e, + kPleGap = 0x00004020, + kPleWindow = 0x00004022, + // 32-Bit Read-Only Data Fields + kVmInstructionError = 0x00004400, // See: VM-Instruction Error Numbers + kVmExitReason = 0x00004402, + kVmExitIntrInfo = 0x00004404, + kVmExitIntrErrorCode = 0x00004406, + kIdtVectoringInfoField = 0x00004408, + kIdtVectoringErrorCode = 0x0000440a, + kVmExitInstructionLen = 0x0000440c, + kVmxInstructionInfo = 0x0000440e, + // 32-Bit Guest-State Fields + kGuestEsLimit = 0x00004800, + kGuestCsLimit = 0x00004802, + kGuestSsLimit = 0x00004804, + kGuestDsLimit = 0x00004806, + kGuestFsLimit = 0x00004808, + kGuestGsLimit = 0x0000480a, + kGuestLdtrLimit = 0x0000480c, + kGuestTrLimit = 0x0000480e, + kGuestGdtrLimit = 0x00004810, + kGuestIdtrLimit = 0x00004812, + kGuestEsArBytes = 0x00004814, + kGuestCsArBytes = 0x00004816, + kGuestSsArBytes = 0x00004818, + kGuestDsArBytes = 0x0000481a, + kGuestFsArBytes = 0x0000481c, + kGuestGsArBytes = 0x0000481e, + kGuestLdtrArBytes = 0x00004820, + kGuestTrArBytes = 0x00004822, + kGuestInterruptibilityInfo = 0x00004824, + kGuestActivityState = 0x00004826, + kGuestSmbase = 0x00004828, + kGuestSysenterCs = 0x0000482a, + kVmxPreemptionTimerValue = 0x0000482e, + // 32-Bit Host-State Field + kHostIa32SysenterCs = 0x00004c00, + // Natural-Width Control Fields + kCr0GuestHostMask = 0x00006000, + kCr4GuestHostMask = 0x00006002, + kCr0ReadShadow = 0x00006004, + kCr4ReadShadow = 0x00006006, + kCr3TargetValue0 = 0x00006008, + kCr3TargetValue1 = 0x0000600a, + kCr3TargetValue2 = 0x0000600c, + kCr3TargetValue3 = 0x0000600e, + // Natural-Width Read-Only Data Fields + kExitQualification = 0x00006400, + kIoRcx = 0x00006402, + kIoRsi = 0x00006404, + kIoRdi = 0x00006406, + kIoRip = 0x00006408, + kGuestLinearAddress = 0x0000640a, + // Natural-Width Guest-State Fields + kGuestCr0 = 0x00006800, + kGuestCr3 = 0x00006802, + kGuestCr4 = 0x00006804, + kGuestEsBase = 0x00006806, + kGuestCsBase = 0x00006808, + kGuestSsBase = 0x0000680a, + kGuestDsBase = 0x0000680c, + kGuestFsBase = 0x0000680e, + kGuestGsBase = 0x00006810, + kGuestLdtrBase = 0x00006812, + kGuestTrBase = 0x00006814, + kGuestGdtrBase = 0x00006816, + kGuestIdtrBase = 0x00006818, + kGuestDr7 = 0x0000681a, + kGuestRsp = 0x0000681c, + kGuestRip = 0x0000681e, + kGuestRflags = 0x00006820, + kGuestPendingDbgExceptions = 0x00006822, + kGuestSysenterEsp = 0x00006824, + kGuestSysenterEip = 0x00006826, + // Natural-Width Host-State Fields + kHostCr0 = 0x00006c00, + kHostCr3 = 0x00006c02, + kHostCr4 = 0x00006c04, + kHostFsBase = 0x00006c06, + kHostGsBase = 0x00006c08, + kHostTrBase = 0x00006c0a, + kHostGdtrBase = 0x00006c0c, + kHostIdtrBase = 0x00006c0e, + kHostIa32SysenterEsp = 0x00006c10, + kHostIa32SysenterEip = 0x00006c12, + kHostRsp = 0x00006c14, + kHostRip = 0x00006c16 +}; +enum class InvVpidType : ULONG_PTR { + kIndividualAddressInvalidation = 0, + kSingleContextInvalidation = 1, + kAllContextInvalidation = 2, + kSingleContextInvalidationExceptGlobal = 3, +}; +struct InvVpidDescriptor { + USHORT vpid; + USHORT reserved1; + ULONG32 reserved2; + ULONG64 linear_address; +}; +enum class InvEptType : ULONG_PTR { + kSingleContextInvalidation = 1, + kGlobalInvalidation = 2, +}; +union EptPointer { + ULONG64 all; + struct { + ULONG64 memory_type : 3; //!< [0:2] + ULONG64 page_walk_length : 3; //!< [3:5] + ULONG64 enable_accessed_and_dirty_flags : 1; //!< [6] + ULONG64 reserved1 : 5; //!< [7:11] + ULONG64 pml4_address : 36; //!< [12:48-1] + ULONG64 reserved2 : 16; //!< [48:63] + } fields; +}; +struct InvEptDescriptor { + EptPointer ept_pointer; + ULONG64 reserved1; +}; + +union Ia32VmxBasicMsr { + unsigned __int64 all; + struct { + unsigned revision_identifier : 31; //!< [0:30] + unsigned reserved1 : 1; //!< [31] + unsigned region_size : 12; //!< [32:43] + unsigned region_clear : 1; //!< [44] + unsigned reserved2 : 3; //!< [45:47] + unsigned supported_ia64 : 1; //!< [48] + unsigned supported_dual_moniter : 1; //!< [49] + unsigned memory_type : 4; //!< [50:53] + unsigned vm_exit_report : 1; //!< [54] + unsigned vmx_capability_hint : 1; //!< [55] + unsigned reserved3 : 8; //!< [56:63] + } fields; +}; + +union VmxVmEntryControls { + unsigned int all; + struct { + unsigned reserved1 : 2; //!< [0:1] + unsigned load_debug_controls : 1; //!< [2] + unsigned reserved2 : 6; //!< [3:8] + unsigned ia32e_mode_guest : 1; //!< [9] + unsigned entry_to_smm : 1; //!< [10] + unsigned deactivate_dual_monitor_treatment : 1; //!< [11] + unsigned reserved3 : 1; //!< [12] + unsigned load_ia32_perf_global_ctrl : 1; //!< [13] + unsigned load_ia32_pat : 1; //!< [14] + unsigned load_ia32_efer : 1; //!< [15] + unsigned load_ia32_bndcfgs : 1; //!< [16] + unsigned conceal_vmentries_from_intel_pt : 1; //!< [17] + } fields; +}; +union VmxVmExitControls { + unsigned int all; + struct { + unsigned reserved1 : 2; //!< [0:1] + unsigned save_debug_controls : 1; //!< [2] + unsigned reserved2 : 6; //!< [3:8] + unsigned host_address_space_size : 1; //!< [9] + unsigned reserved3 : 2; //!< [10:11] + unsigned load_ia32_perf_global_ctrl : 1; //!< [12] + unsigned reserved4 : 2; //!< [13:14] + unsigned acknowledge_interrupt_on_exit : 1; //!< [15] + unsigned reserved5 : 2; //!< [16:17] + unsigned save_ia32_pat : 1; //!< [18] + unsigned load_ia32_pat : 1; //!< [19] + unsigned save_ia32_efer : 1; //!< [20] + unsigned load_ia32_efer : 1; //!< [21] + unsigned save_vmx_preemption_timer_value : 1; //!< [22] + unsigned clear_ia32_bndcfgs : 1; //!< [23] + unsigned conceal_vmexits_from_intel_pt : 1; //!< [24] + } fields; +}; + +union VmxPinBasedControls { + unsigned int all; + struct { + unsigned external_interrupt_exiting : 1; //!< [0] + unsigned reserved1 : 2; //!< [1:2] + unsigned nmi_exiting : 1; //!< [3] + unsigned reserved2 : 1; //!< [4] + unsigned virtual_nmis : 1; //!< [5] + unsigned activate_vmx_peemption_timer : 1; //!< [6] + unsigned process_posted_interrupts : 1; //!< [7] + } fields; +}; +union VmxProcessorBasedControls { + unsigned int all; + struct { + unsigned reserved1 : 2; //!< [0:1] + unsigned interrupt_window_exiting : 1; //!< [2] + unsigned use_tsc_offseting : 1; //!< [3] + unsigned reserved2 : 3; //!< [4:6] + unsigned hlt_exiting : 1; //!< [7] + unsigned reserved3 : 1; //!< [8] + unsigned invlpg_exiting : 1; //!< [9] + unsigned mwait_exiting : 1; //!< [10] + unsigned rdpmc_exiting : 1; //!< [11] + unsigned rdtsc_exiting : 1; //!< [12] + unsigned reserved4 : 2; //!< [13:14] + unsigned cr3_load_exiting : 1; //!< [15] + unsigned cr3_store_exiting : 1; //!< [16] + unsigned reserved5 : 2; //!< [17:18] + unsigned cr8_load_exiting : 1; //!< [19] + unsigned cr8_store_exiting : 1; //!< [20] + unsigned use_tpr_shadow : 1; //!< [21] + unsigned nmi_window_exiting : 1; //!< [22] + unsigned mov_dr_exiting : 1; //!< [23] + unsigned unconditional_io_exiting : 1; //!< [24] + unsigned use_io_bitmaps : 1; //!< [25] + unsigned reserved6 : 1; //!< [26] + unsigned monitor_trap_flag : 1; //!< [27] + unsigned use_msr_bitmaps : 1; //!< [28] + unsigned monitor_exiting : 1; //!< [29] + unsigned pause_exiting : 1; //!< [30] + unsigned activate_secondary_control : 1; //!< [31] + } fields; +}; +/// See: Definitions of Secondary Processor-Based VM-Execution Controls +union VmxSecondaryProcessorBasedControls { + unsigned int all; + struct { + unsigned virtualize_apic_accesses : 1; //!< [0] + unsigned enable_ept : 1; //!< [1] + unsigned descriptor_table_exiting : 1; //!< [2] + unsigned enable_rdtscp : 1; //!< [3] + unsigned virtualize_x2apic_mode : 1; //!< [4] + unsigned enable_vpid : 1; //!< [5] + unsigned wbinvd_exiting : 1; //!< [6] + unsigned unrestricted_guest : 1; //!< [7] + unsigned apic_register_virtualization : 1; //!< [8] + unsigned virtual_interrupt_delivery : 1; //!< [9] + unsigned pause_loop_exiting : 1; //!< [10] + unsigned rdrand_exiting : 1; //!< [11] + unsigned enable_invpcid : 1; //!< [12] + unsigned enable_vm_functions : 1; //!< [13] + unsigned vmcs_shadowing : 1; //!< [14] + unsigned reserved1 : 1; //!< [15] + unsigned rdseed_exiting : 1; //!< [16] + unsigned reserved2 : 1; //!< [17] + unsigned ept_violation_ve : 1; //!< [18] + unsigned reserved3 : 1; //!< [19] + unsigned enable_xsaves_xstors : 1; //!< [20] + unsigned reserved4 : 1; //!< [21] + unsigned mode_based_execute_control_for_ept : 1; //!< [22] + unsigned reserved5 : 2; //!< [23:24] + unsigned use_tsc_scaling : 1; //!< [25] + } fields; +}; +/// See: Guest Register State +union VmxRegmentDescriptorAccessRight { + unsigned int all; + struct { + unsigned type : 4; //!< [0:3] + unsigned system : 1; //!< [4] + unsigned dpl : 2; //!< [5:6] + unsigned present : 1; //!< [7] + unsigned reserved1 : 4; //!< [8:11] + unsigned avl : 1; //!< [12] + unsigned l : 1; //!< [13] Reserved (except for CS) 64-bit mode + unsigned db : 1; //!< [14] + unsigned gran : 1; //!< [15] + unsigned unusable : 1; //!< [16] Segment unusable + unsigned reserved2 : 15; //!< [17:31] + } fields; +}; + +union Cr0 { + ULONG_PTR all; + struct { + unsigned pe : 1; //!< [0] Protected Mode Enabled + unsigned mp : 1; //!< [1] Monitor Coprocessor FLAG + unsigned em : 1; //!< [2] Emulate FLAG + unsigned ts : 1; //!< [3] Task Switched FLAG + unsigned et : 1; //!< [4] Extension Type FLAG + unsigned ne : 1; //!< [5] Numeric Error + unsigned reserved1 : 10; //!< [6:15] + unsigned wp : 1; //!< [16] Write Protect + unsigned reserved2 : 1; //!< [17] + unsigned am : 1; //!< [18] Alignment Mask + unsigned reserved3 : 10; //!< [19:28] + unsigned nw : 1; //!< [29] Not Write-Through + unsigned cd : 1; //!< [30] Cache Disable + unsigned pg : 1; //!< [31] Paging Enabled + } fields; +}; +static_assert(sizeof(Cr0) == sizeof(void*), "Size check"); + +/// See: CONTROL REGISTERS +union Cr4 { + ULONG_PTR all; + struct { + unsigned vme : 1; //!< [0] Virtual Mode Extensions + unsigned pvi : 1; //!< [1] Protected-Mode Virtual Interrupts + unsigned tsd : 1; //!< [2] Time Stamp Disable + unsigned de : 1; //!< [3] Debugging Extensions + unsigned pse : 1; //!< [4] Page Size Extensions + unsigned pae : 1; //!< [5] Physical Address Extension + unsigned mce : 1; //!< [6] Machine-Check Enable + unsigned pge : 1; //!< [7] Page Global Enable + unsigned pce : 1; //!< [8] Performance-Monitoring Counter Enable + unsigned osfxsr : 1; //!< [9] OS Support for FXSAVE/FXRSTOR + unsigned osxmmexcpt : 1; //!< [10] OS Support for Unmasked SIMD Exceptions + unsigned reserved1 : 2; //!< [11:12] + unsigned vmxe : 1; //!< [13] Virtual Machine Extensions Enabled + unsigned smxe : 1; //!< [14] SMX-Enable Bit + unsigned reserved2 : 2; //!< [15:16] + unsigned pcide : 1; //!< [17] PCID Enable + unsigned osxsave : 1; //!< [18] XSAVE and Processor Extended States-Enable + unsigned reserved3 : 1; //!< [19] + unsigned smep : 1; //!< [20] Supervisor Mode Execution Protection Enable + unsigned smap : 1; //!< [21] Supervisor Mode Access Protection Enable + } fields; +}; +static_assert(sizeof(Cr4) == sizeof(void*), "Size check"); + +/// Represents a stack layout after PUSHAQ +union GpRegistersX64 { + ULONG_PTR all[16]; + struct { + ULONG_PTR r15; + ULONG_PTR r14; + ULONG_PTR r13; + ULONG_PTR r12; + ULONG_PTR r11; + ULONG_PTR r10; + ULONG_PTR r9; + ULONG_PTR r8; + ULONG_PTR di; + ULONG_PTR si; + ULONG_PTR bp; + ULONG_PTR sp; + ULONG_PTR bx; + ULONG_PTR dx; + ULONG_PTR cx; + ULONG_PTR ax; + }; +}; + +/// Represents a stack layout after PUSHAD +struct GpRegistersX86 { + ULONG_PTR di; + ULONG_PTR si; + ULONG_PTR bp; + ULONG_PTR sp; + ULONG_PTR bx; + ULONG_PTR dx; + ULONG_PTR cx; + ULONG_PTR ax; +}; + +/// Represents a stack layout after PUSHAx +#if defined(_AMD64_) +using GpRegisters = GpRegistersX64; +#else +using GpRegisters = GpRegistersX86; +#endif +struct KtrapFrameX86 { + ULONG reserved1[26]; + ULONG ip; //!< Called EIP in _KTRAP_FRAME + ULONG reserved2[2]; + ULONG sp; //!< Called HardwareEsp in _KTRAP_FRAME + ULONG reserved3[5]; +}; +static_assert(sizeof(KtrapFrameX86) == 0x8c, "structure size mismatch"); +#if !defined(__clang__) +static_assert(FIELD_OFFSET(KtrapFrameX86, ip) == 0x68, "structure size mismatch"); +static_assert(FIELD_OFFSET(KtrapFrameX86, sp) == 0x74, "structure size mismatch"); +#endif + +/// nt!_KTRAP_FRAME on x64 +struct KtrapFrameX64 { + ULONG64 reserved1[45]; + ULONG64 ip; //!< Called EIP in _KTRAP_FRAME + ULONG64 reserved2[2]; + ULONG64 sp; //!< Called Rsp in _KTRAP_FRAME + ULONG64 reserved3; +}; +static_assert(sizeof(KtrapFrameX64) == 0x190, "structure size mismatch"); +#if !defined(__clang__) +static_assert(FIELD_OFFSET(KtrapFrameX64, ip) == 0x168, "structure size mismatch"); +static_assert(FIELD_OFFSET(KtrapFrameX64, sp) == 0x180, "structure size mismatch"); +#endif + +/// See: Stack Usage on Transfers to Interrupt and Exception-Handling Routines +struct MachineFrame { + ULONG_PTR ip; + ULONG_PTR cs; + ULONG_PTR flags; + ULONG_PTR sp; + ULONG_PTR ss; +}; + +#if defined(_AMD64_) +using KtrapFrame = KtrapFrameX64; +#else +using KtrapFrame = KtrapFrameX86; +#endif +struct VmmInitialStack { + GpRegisters gp_regs; + KtrapFrame trap_frame; + //ProcessorData* processor_data; +}; +union MovCrQualification { + ULONG_PTR all; + struct { + ULONG_PTR control_register : 4; //!< [0:3] + ULONG_PTR access_type : 2; //!< [4:5] + ULONG_PTR lmsw_operand_type : 1; //!< [6] + ULONG_PTR reserved1 : 1; //!< [7] + ULONG_PTR gp_register : 4; //!< [8:11] + ULONG_PTR reserved2 : 4; //!< [12:15] + ULONG_PTR lmsw_source_data : 16; //!< [16:31] + ULONG_PTR reserved3 : 32; //!< [32:63] + } fields; +}; + +#endif // !_VTSTRUCT__INCLUDED__ + +/// See: BASIC VMX INFORMATION +