#include <stdio.h> #include <Windows.h>
#pragma comment(lib,"user32.lib") #pragma comment(lib,"Advapi32.lib")
#ifndef NT_SUCCESS #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #endif
#define BYTE_ARRAY_LENGTH 16 #define SystemModuleInformation 11 #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
typedef long(__stdcall *ZWQUERYSYSTEMINFORMATION) ( IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, IN PULONG ReturnLength OPTIONAL );
typedef struct { ULONG Unknow1; ULONG Unknow2; ULONG Unknow3; ULONG Unknow4; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT NameLength; USHORT LoadCount; USHORT ModuleNameOffset; char ImageName[256]; } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct { ULONG Count; SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct { PVOID Address; ULONG64 Length; UCHAR data[256]; } KF_DATA, *PKF_DATA;
HANDLE hDriver = 0; HMODULE hKernel = 0; ULONG64 KernelBase = 0; CHAR NtosFullName[260] = { 0 };
DWORD CTL_CODE_GEN(DWORD lngFunction) { return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED; }
BOOL IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize) { DWORD lDrvRetSize; return DeviceIoControl(hDrvHandle, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, &lDrvRetSize, 0); }
ULONG64 GetKernelBase64(PCHAR NtosName) { ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation; PSYSTEM_MODULE_INFORMATION pSystemModuleInformation; ULONG NeedSize, BufferSize = 0x5000; PVOID pBuffer = NULL; NTSTATUS Result;
ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQuerySystemInformation"); do { pBuffer = malloc(BufferSize); if (pBuffer == NULL) return 0;
Result = ZwQuerySystemInformation(SystemModuleInformation, pBuffer, BufferSize, &NeedSize); if (Result == STATUS_INFO_LENGTH_MISMATCH) { free(pBuffer); BufferSize *= 2; } else if (!NT_SUCCESS(Result)) { free(pBuffer); return 0; } } while (Result == STATUS_INFO_LENGTH_MISMATCH);
pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;
ULONG64 ret = (ULONG64)(pSystemModuleInformation->Module[0].Base);
if (NtosName != NULL) { strcpy(NtosName, pSystemModuleInformation->Module[0].ImageName + pSystemModuleInformation->Module[0].ModuleNameOffset); }
free(pBuffer); return ret; }
BOOL RepairRelocationTable(ULONG64 HandleInFile, ULONG64 BaseInKernel) { PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS64 pNtHeader; PIMAGE_BASE_RELOCATION pRelocTable; ULONG i, dwOldProtect;
pDosHeader = (PIMAGE_DOS_HEADER)HandleInFile; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return FALSE; }
pNtHeader = (PIMAGE_NT_HEADERS64)((ULONG64)HandleInFile + pDosHeader->e_lfanew);
if (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) { pRelocTable = (PIMAGE_BASE_RELOCATION)((ULONG64)HandleInFile + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
do { ULONG numofReloc = (pRelocTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2; SHORT minioffset = 0; PUSHORT pRelocData = (PUSHORT)((ULONG64)pRelocTable + sizeof(IMAGE_BASE_RELOCATION));
for (i = 0; i<numofReloc; i++) { PULONG64 RelocAddress;
if (((*pRelocData) >> 12) == IMAGE_REL_BASED_DIR64) { minioffset = (*pRelocData) & 0xFFF;
RelocAddress = (PULONG64)(HandleInFile + pRelocTable->VirtualAddress + minioffset);
VirtualProtect((PVOID)RelocAddress, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect);
*RelocAddress = *RelocAddress + BaseInKernel - pNtHeader->OptionalHeader.ImageBase; VirtualProtect((PVOID)RelocAddress, 4, dwOldProtect, NULL); } pRelocData++; } pRelocTable = (PIMAGE_BASE_RELOCATION)((ULONG64)pRelocTable + pRelocTable->SizeOfBlock); } while (pRelocTable->VirtualAddress);
return TRUE; } return FALSE; }
BOOL InitEngine(BOOL IsClear) { if (IsClear == TRUE) { KernelBase = GetKernelBase64(NtosFullName); printf("模块基址: %llx | 模块名: %s \n", KernelBase, NtosFullName); if (!KernelBase) { return FALSE; } hKernel = LoadLibraryExA(NtosFullName, 0, DONT_RESOLVE_DLL_REFERENCES);
if (!hKernel) { return FALSE; }
if (!RepairRelocationTable((ULONG64)hKernel, KernelBase)) { return FALSE; } return TRUE; } else { FreeLibrary(hKernel); return TRUE; } }
VOID GetOriginalMachineCode(ULONG64 Address, PUCHAR ba, SIZE_T Length) { ULONG64 OffsetAddress = Address - KernelBase + (ULONG64)hKernel; RtlCopyMemory(ba, (PVOID)OffsetAddress, Length); }
ULONG64 GetSystemRoutineAddress(PCHAR FuncName) { return KernelBase + (ULONG64)GetProcAddress(hKernel, FuncName) - (ULONG64)hKernel; }
VOID GetCurrentMachineCode(ULONG64 Address, PUCHAR ba, SIZE_T Length) { ULONG64 dat[2] = { 0 }; dat[0] = Address; dat[1] = Length; IoControl(hDriver, CTL_CODE_GEN(0x800), dat, 16, ba, Length); }
VOID ClearInlineHook(ULONG64 Address, PUCHAR ba, SIZE_T Length) { KF_DATA dat = { 0 }; dat.Address = (PVOID)Address; dat.Length = Length;
RtlCopyMemory(dat.data, ba, Length); IoControl(hDriver, CTL_CODE_GEN(0x801), &dat, sizeof(KF_DATA), 0, 0); }
VOID PrintBytes(PCHAR DescriptionString, PUCHAR ba, UINT Length) { printf("%s", DescriptionString); for (UINT i = 0; i<Length; i++) { printf("%02x ", ba[i]); } printf("\n"); }
int main(int argc, char *argv[]) { UCHAR OriginalMachineCode[BYTE_ARRAY_LENGTH]; UCHAR CurrentMachineCode[BYTE_ARRAY_LENGTH]; ULONG64 Address = 0;
hDriver = CreateFileA("\\\\.\\WinDDK", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (!InitEngine(TRUE) || hDriver == 0) { return 0; }
CHAR *FunctionList[128] = { "PsLookupProcessByProcessId", "NtCommitEnlistment", "NtCommitComplete", "NtCommitTransaction" };
for (size_t i = 0; i < 4; i++) { RtlZeroMemory(OriginalMachineCode, 0, BYTE_ARRAY_LENGTH); RtlZeroMemory(CurrentMachineCode, 0, BYTE_ARRAY_LENGTH);
Address = GetSystemRoutineAddress(FunctionList[i]);
printf("\n函数地址: %p | 函数名: %s\n", Address, FunctionList[i]); if (Address == 0 || Address < KernelBase) { return 0; }
GetOriginalMachineCode(Address, OriginalMachineCode, BYTE_ARRAY_LENGTH); PrintBytes("原始机器码: ", OriginalMachineCode, BYTE_ARRAY_LENGTH);
GetCurrentMachineCode(Address, CurrentMachineCode, BYTE_ARRAY_LENGTH); PrintBytes("当前机器码: ", CurrentMachineCode, BYTE_ARRAY_LENGTH);
}
InitEngine(FALSE); system("pause");
return 0; }
|