- 注册时间
- 2021-4-16
- 最后登录
- 2023-11-9
- 在线时间
- 3 小时
编程入门
- 龙马币
- 52
|
x64的内核重载源码,参照x86写的 望大牛们指点。
ReX64.h
- #pragma once
- #include <ntifs.h>
- #include <ntimage.h>
- #include <intrin.h>
-
- PVOID pNewBuffer = nullptr;
- typedef struct _SYSTEM_SERVICE_TABLE //SSDT结构
- {
- PVOID serviceTableBase;
- PVOID serviceCounterTableBase;
- ULONGLONG numberofServices;
- PVOID paramTableBase;
- }SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
-
- typedef struct _BaseAddr_Size
- {
- DWORD_PTR mMoudleBaseAddress;
- DWORD_PTR mMoudleSizeOf;
- }BaseAddr_Size, *PBaseAddr_Size;
- #pragma once
- #include <ntifs.h>
- #include <ntimage.h>
- #include <intrin.h>
-
- PVOID pNewBuffer = nullptr;
- typedef struct _SYSTEM_SERVICE_TABLE //SSDT结构
- {
- PVOID serviceTableBase;
- PVOID serviceCounterTableBase;
- ULONGLONG numberofServices;
- PVOID paramTableBase;
- }SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
-
- typedef struct _BaseAddr_Size
- {
- DWORD_PTR mMoudleBaseAddress;
- DWORD_PTR mMoudleSizeOf;
- }BaseAddr_Size, *PBaseAddr_Size;
-
- typedef struct _PE
- {
- IMAGE_DOS_HEADER DosHeader;
- IMAGE_NT_HEADERS32 NtHeaders;
- IMAGE_SECTION_HEADER SectionHeader;
- }PE, *pPE;
-
- typedef struct _LDR_DATA_TABLE_ENTRY
- {
- struct _LIST_ENTRY InLoadOrderLinks; //0x0
- struct _LIST_ENTRY InMemoryOrderLinks; //0x8
- struct _LIST_ENTRY InInitializationOrderLinks; //0x10
- VOID* DllBase; //0x18
- VOID* EntryPoint; //0x1c
- ULONG SizeOfImage; //0x20
- struct _UNICODE_STRING FullDllName; //0x24
- struct _UNICODE_STRING BaseDllName; //0x2c
- ULONG Flags; //0x34
- USHORT LoadCount; //0x38
- USHORT TlsIndex; //0x3a
- union
- {
- struct _LIST_ENTRY HashLinks; //0x3c
- struct
- {
- VOID* SectionPointer; //0x3c
- ULONG CheckSum; //0x40
- }u;
- };
- union
- {
- ULONG TimeDateStamp; //0x44
- VOID* LoadedImports; //0x44
- };
- VOID* EntryPointActivationContext; //0x48
- VOID* PatchInformation; //0x4c
- }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;//0x50 bytes (sizeof)
-
- EXTERN_C{
- VOID UnLoad(PDRIVER_OBJECT pDriver);
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg);
- }
- NTSTATUS GetKernelImageBase_1(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING szMoudeName, OUT PBaseAddr_Size mBeseAddrOfSize);
- PVOID GetNewKernelBuffer_1(IN PUNICODE_STRING pStrKernelPathName);
- VOID RepirRelocTable(IN DWORD_PTR uNewModule, IN DWORD_PTR uOldModule);
- NTSTATUS RepirSSDT(IN PDRIVER_OBJECT pDriver, IN ULONG64 pNewKernelBuffer, IN ULONG64 uOldModule);
- NTSTATUS GetSSDT(IN PDRIVER_OBJECT pdriver, OUT PVOID* addr); //通过链表找到ssdt
- ReX64.cpp
- [mw_shl_code=cpp,true]#pragma once
- #include "ReX64Knrl.h"
-
-
- #pragma warning (disable:4310)
- VOID UnLoad(PDRIVER_OBJECT pDriver)
- {
- UNREFERENCED_PARAMETER(pDriver);
- if (pNewBuffer) ExFreePool(pNewBuffer);
- }
-
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
- {
- UNREFERENCED_PARAMETER(pReg);
- pDriver->DriverUnload = UnLoad;
- DbgBreakPoint();
- NTSTATUS status = STATUS_UNSUCCESSFUL;
- UNICODE_STRING szMoudleName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
- BaseAddr_Size sz = { 0 };
- status= GetKernelImageBase_1(pDriver, &szMoudleName, &sz);
- if (NT_SUCCESS(status))
- {
- DbgPrintEx(77, 0, "GetKernelImageBase_1 sucess!\n");
- }
- else
- {
- DbgPrintEx(77, 0, "GetKernelImageBase_1 Faild!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- UNICODE_STRING szFileName = RTL_CONSTANT_STRING(L"\\??\\C:\\Windows\\system32\\ntoskrnl.exe");//ntdll.dll //\\??\\C:\\WINDOWS\\system32\\ntkrnlpa.exe
- PVOID pNewKernelBuffer = GetNewKernelBuffer_1(&szFileName);
- if (!MmIsAddressValid(pNewKernelBuffer))
- {
- DbgPrintEx(77, 0, "pNewKernelBuffer is faild");
- return STATUS_UNSUCCESSFUL;
- }
- DbgPrintEx(77, 0, "pNewKernelBuffer is: %llx", pNewKernelBuffer);
- //基址重定位
- RepirRelocTable((DWORD_PTR)pNewKernelBuffer, sz.mMoudleBaseAddress);
-
- //系统服务表重定位
- status = RepirSSDT(pDriver, (ULONG64)pNewKernelBuffer, sz.mMoudleBaseAddress);
- if (NT_SUCCESS(status))
- {
- DbgPrintEx(77, 0, "RepirSSDT sucess!\n");
- }
- else
- {
- DbgPrintEx(77, 0, "RepirSSDT Faild!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- //>>>>>>>> 插入HOOK 代码
-
- return STATUS_SUCCESS;
- }
-
- //[获取当前内核模块基址_1]
- NTSTATUS GetKernelImageBase_1(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING szMoudeName, OUT PBaseAddr_Size mBeseAddrOfSize)
- {
- PLIST_ENTRY pCurrObject = (PLIST_ENTRY)pDriver->DriverSection;
- PLIST_ENTRY pNextObject = pCurrObject->Flink;
- PLDR_DATA_TABLE_ENTRY szTemp = nullptr;
- while (pCurrObject != pNextObject)
- {
- szTemp = (PLDR_DATA_TABLE_ENTRY)pNextObject;
- if (RtlCompareUnicodeString(&szTemp->BaseDllName, szMoudeName, TRUE) == NULL)
- {
- mBeseAddrOfSize->mMoudleBaseAddress = (DWORD_PTR)(szTemp->DllBase);
- mBeseAddrOfSize->mMoudleSizeOf = szTemp->SizeOfImage;
- DbgPrintEx(77, 0, "DllBase:0x%llX SizeOfImage:0x%X BaseDllName:%wZ FullDllName:%wZ ", szTemp->DllBase, szTemp->SizeOfImage, szTemp->BaseDllName, szTemp->FullDllName);
- return STATUS_SUCCESS;
- }
- pNextObject = pNextObject->Flink;
- }
- return STATUS_UNSUCCESSFUL;
- }
-
- // [1、获取新的内核模块虚拟缓存]
- PVOID GetNewKernelBuffer_1(IN PUNICODE_STRING pStrKernelPathName)
- {
- PE pe = { 0 };
- HANDLE hFile = NULL;
- OBJECT_ATTRIBUTES objectAttributes = { 0 };
- IO_STATUS_BLOCK ioStatusBlock = { 0 };
- InitializeObjectAttributes(&objectAttributes, pStrKernelPathName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
- NTSTATUS ntStatus = ZwCreateFile(&hFile, GENERIC_READ, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE, NULL, 0);
- if (!NT_SUCCESS(ntStatus))
- {
- KdPrint(("ZwCreateFile错误:%x\n", ntStatus));
- return NULL;
- }
- LARGE_INTEGER fileOffset = { 0 };
- fileOffset.QuadPart = 0;
- //读取DOS头
- ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, &pe.DosHeader, sizeof(IMAGE_DOS_HEADER), &fileOffset, NULL);
- if (!NT_SUCCESS(ntStatus))
- {
- KdPrint(("ZwReadFile错误:%x\n", ntStatus));
- goto exit;
- }
- fileOffset.QuadPart += pe.DosHeader.e_lfanew;
- //读取NT头
- ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, &pe.NtHeaders, sizeof(IMAGE_NT_HEADERS), &fileOffset, NULL);
- if (!NT_SUCCESS(ntStatus))
- {
- KdPrint(("ZwReadFile错误:%x\n", ntStatus));
- goto exit;
- }
-
- pNewBuffer = ExAllocatePool(NonPagedPool, pe.NtHeaders.OptionalHeader.SizeOfImage);
- if (pNewBuffer == NULL)
- {
- KdPrint(("pNewBuffer错误\n"));
- goto exit;
- }
- PVOID pTempBuffer = pNewBuffer;
- RtlCopyMemory(pTempBuffer, &pe.DosHeader, sizeof(IMAGE_DOS_HEADER));
- pTempBuffer = (PVOID)((DWORD_PTR)pTempBuffer + pe.DosHeader.e_lfanew);
- RtlCopyMemory(pTempBuffer, &pe.NtHeaders, sizeof(IMAGE_NT_HEADERS));
- fileOffset.QuadPart += sizeof(IMAGE_NT_HEADERS);
- pTempBuffer = (PVOID)((DWORD_PTR)pTempBuffer + sizeof(IMAGE_NT_HEADERS));
- //读取节表
- ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, pTempBuffer, (sizeof(IMAGE_SECTION_HEADER) * pe.NtHeaders.FileHeader.NumberOfSections), &fileOffset, NULL);
- if (!NT_SUCCESS(ntStatus))
- {
- KdPrint(("ZwReadFile错误:%x\n", ntStatus));
- pNewBuffer = nullptr;
- goto exit;
- }
- PIMAGE_SECTION_HEADER pTempSectionHeader = (PIMAGE_SECTION_HEADER)pTempBuffer;
-
- //读取节内容
- for (ULONG32 uCount = 0; uCount < pe.NtHeaders.FileHeader.NumberOfSections; uCount++)
- {
- pTempBuffer = (PVOID)((DWORD_PTR)pNewBuffer + pTempSectionHeader->VirtualAddress);
- fileOffset.QuadPart = pTempSectionHeader->PointerToRawData;
- ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, pTempBuffer, pTempSectionHeader->SizeOfRawData, &fileOffset, NULL);
- if (!NT_SUCCESS(ntStatus))
- {
- KdPrint(("ZwReadFile错误:%x\n", ntStatus));
- pNewBuffer = nullptr;
- goto exit;
- }
- pTempSectionHeader++;
- }
- exit:
- if (hFile) ZwClose(hFile);
- //if (pNewBuffer) ExFreePool(pNewBuffer);
- return pNewBuffer;
- }
-
- //修复重定位表
- VOID RepirRelocTable(IN DWORD_PTR uNewModule,IN DWORD_PTR uOldModule)
- {
- UNREFERENCED_PARAMETER(uOldModule);
- PIMAGE_DOS_HEADER pDosHeader = NULL;
- PIMAGE_NT_HEADERS pNtHeaders = NULL;
- PIMAGE_BASE_RELOCATION pRelocation = NULL;
- PIMAGE_DATA_DIRECTORY pData = NULL;
-
- pDosHeader = (PIMAGE_DOS_HEADER)uNewModule;
- pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDosHeader + pDosHeader->e_lfanew);
- pData = pNtHeaders->OptionalHeader.DataDirectory;
- //定位重定位表
- pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)uNewModule + pData[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
- //由于新的内核里面的全局变量地址都是用的老的 所以要加上它们之间的偏移量 就等于我们新的内核全局变量地址
- DWORD_PTR uOffset = uNewModule - pNtHeaders->OptionalHeader.ImageBase; //需要改正的偏移
- while (pRelocation->VirtualAddress != 0 && pRelocation->SizeOfBlock != 0 && pRelocation->VirtualAddress != 01)
- {
- LONG32 uNumOfRelocs = (pRelocation->SizeOfBlock - 8) / 2; //取得重定位数量
- PUSHORT pUShort = (PUSHORT)((DWORD_PTR)pRelocation + 8);
- for (DWORD_PTR uCount = 0; uCount < uNumOfRelocs; uCount++, pUShort++)
- {
- if (((*pUShort) >> 12) == IMAGE_REL_BASED_DIR64)
- {
- PULONG64 pUlong32 = (PULONG64)(((*pUShort) & 0x0FFF) + pRelocation->VirtualAddress + uNewModule);
- *pUlong32 += uOffset; //改好数据写入目的地址
- }
- }
- pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)pRelocation + pRelocation->SizeOfBlock);
- }
- }
-
- //修复新的系统服务表
- NTSTATUS RepirSSDT(IN PDRIVER_OBJECT pDriver, IN ULONG64 pNewKernelBuffer, IN ULONG64 uOldModule)
- {
- ULONG64 g_uOffset = pNewKernelBuffer - uOldModule;
- PVOID szAddr = nullptr;
- NTSTATUS status = GetSSDT(pDriver, &szAddr);
- if (!NT_SUCCESS(status))
- {
- DbgPrintEx(77, 0, "GetSSDT Faile!\n");
- return STATUS_UNSUCCESSFUL;
- }
- PSYSTEM_SERVICE_TABLE m_pOldSSDT = { 0 };
- m_pOldSSDT = (PSYSTEM_SERVICE_TABLE)szAddr;
- PSYSTEM_SERVICE_TABLE m_pNewSSDT = (PSYSTEM_SERVICE_TABLE)((ULONGLONG)m_pOldSSDT + g_uOffset);
- m_pNewSSDT->numberofServices = m_pOldSSDT->numberofServices;
- ULONG64 m_uOffset = (ULONG64)m_pOldSSDT->serviceTableBase - uOldModule;
- m_pNewSSDT->serviceTableBase = (PULONG32)(pNewKernelBuffer + m_uOffset);
-
- m_uOffset = ((ULONGLONG)m_pOldSSDT->serviceCounterTableBase - uOldModule);
- m_pNewSSDT->serviceCounterTableBase = (PULONG32)(pNewKernelBuffer + m_uOffset);
- m_uOffset = ((ULONGLONG)m_pOldSSDT->paramTableBase - uOldModule);
- m_pNewSSDT->paramTableBase = (PCHAR)(pNewKernelBuffer + m_uOffset);
- RtlCopyMemory((PULONGLONG)m_pNewSSDT->paramTableBase, (PULONGLONG)m_pOldSSDT->paramTableBase, (ULONG64)m_pNewSSDT->numberofServices);//复制参数
- m_uOffset = (ULONG64)m_pNewSSDT->serviceTableBase - pNewKernelBuffer;
- //计算ssdt表中函数地址 注:win10 ssdt表中函数地址为:高28位为偏移 低4位为参数个数-4 不足4个参数时为零
- for (ULONG32 uCount = 0; uCount < m_pNewSSDT->numberofServices; uCount++)
- {
- ((PULONG32)(UCHAR*)(m_pNewSSDT->serviceTableBase))[uCount] = (ULONG32)((((PULONG32)(UCHAR*)(m_pNewSSDT->serviceTableBase))[uCount] - m_uOffset) << 4) + (((CHAR)((UCHAR*)(m_pNewSSDT->paramTableBase))[uCount]) >> 2);
- }
- return STATUS_SUCCESS;
- }
-
- NTSTATUS GetSSDT(IN PDRIVER_OBJECT pdriver, OUT PVOID* addr) //通过链表找到ssdt
- {
- PLDR_DATA_TABLE_ENTRY entry = (PLDR_DATA_TABLE_ENTRY)pdriver->DriverSection;
- PLDR_DATA_TABLE_ENTRY head = entry;
- UNICODE_STRING temp = { 0 };
- RtlInitUnicodeString(&temp, L"ntoskrnl.exe");
- PCHAR start = NULL;
- ULONG size = 0;
- do
- { //通过链表找到ntoskrnl.exe 内核文件。
- if (RtlCompareUnicodeString(&temp, &entry->BaseDllName, TRUE) == NULL)
- {
- //DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "%wZ\n", &entry->BaseDllName);
- start = (PCHAR)entry->DllBase;
- size = entry->SizeOfImage;
- break;
- }
- entry = (PLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink;
- } while (entry != head);
- for (ULONG i = 0; i < size; i++)
- {
- if (MmIsAddressValid(start))
- {
- if (*start == (CHAR)0x4c && *(CHAR*)(start + 1) == (CHAR)0x8d && *(CHAR*)(start + 2) == (CHAR)0x15) //注:必需强制转换字符串类型
- {
- start += 7;
- if (MmIsAddressValid(start))
- {
- if (*start == (CHAR)0x4c && *(CHAR*)(start + 1) == (CHAR)0x8d && *(CHAR*)(start + 2) == (CHAR)0x1d)
- {
- *(PULONGLONG)addr = *(PULONG)(start - 4) + (ULONGLONG)start;
- return STATUS_SUCCESS;
- }
- }
- }
- }
- if (MmIsAddressValid(start))
- {
- start++;
- }
- }
- return STATUS_UNSUCCESSFUL;
- }
复制代码 |
|