DICHook/DICHook_OpenSource/DDKCommon.cpp

610 lines
15 KiB
C++

#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);
}