首页 > 代码库 > Win7 内核重载 1 ——内核版PELoader
Win7 内核重载 1 ——内核版PELoader
重载重点,其实就是自己实现一个山寨版的Windows PELoader ,重载其实就是将一个模块自己重新加载一份到别的内存,运行它。
所谓内核重载,则是将内核文件即:ntkrnlpa.exe 自己加载一份到内存,并运行它,这样的好处可以避免一切HOOK,如SSDT ,InLineHook 等等,原理就是HOOK继续
HOOK主原来内核,但是实际上Windows走的是我们自己的内核。
废话不多说,开始干起来,首先查找内核模块,遍历内核模块的方式很多种,这里我使用的是通过LDR链表:
// 查找内核模块 PLDR_DATA_TABLE_ENTRY SearchDriver(PDRIVER_OBJECT pDriverObject, wchar_t *strDriverName) { LDR_DATA_TABLE_ENTRY *pDataTableEntry, *pTempDataTableEntry; PLIST_ENTRY pList; UNICODE_STRING usModuleName; RtlInitUnicodeString(&usModuleName, strDriverName); pDataTableEntry = (LDR_DATA_TABLE_ENTRY*)pDriverObject->DriverSection; if (!pDataTableEntry) { return 0; } pList = pDataTableEntry->InLoadOrderLinks.Flink; while (pList != &pDataTableEntry->InLoadOrderLinks) { pTempDataTableEntry = (LDR_DATA_TABLE_ENTRY *)pList; if (0 == RtlCompareUnicodeString(&pTempDataTableEntry->BaseDllName, &usModuleName, FALSE)) { return pTempDataTableEntry; } pList = pList->Flink; } return 0; }找到内核模块,就开始读文件到内存~
NTSTATUS ReadFileToMemory(LPWSTR lpFileName, PVOID* lpVirtualPoint, PVOID pOriImage) { NTSTATUS Status; HANDLE hFile; OBJECT_ATTRIBUTES ObjAttr; UNICODE_STRING usFileName; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER FileOffset; PVOID pVirtualAddress; ULONG uIndex; ULONG uSizeOfSection; ULONG uSectionAddress; IMAGE_DOS_HEADER ImageDosHeader; IMAGE_NT_HEADERS ImageNtHeader; PIMAGE_SECTION_HEADER pImageSectionHeader; RtlInitUnicodeString(&usFileName, lpFileName); InitializeObjectAttributes( &ObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwCreateFile( &hFile, FILE_ALL_ACCESS, &ObjAttr, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); if (!NT_SUCCESS(Status)) { DbgPrint("ZwCreateFile faild\n"); return Status; } FileOffset.QuadPart = 0; Status = ZwReadFile( hFile, NULL, NULL, NULL, &IoStatusBlock, &ImageDosHeader, sizeof(IMAGE_DOS_HEADER), &FileOffset, NULL); if (!NT_SUCCESS(Status)) { DbgPrint("ZwReadFile ImageDosHeader faild\n"); ZwClose(hFile); return Status; } FileOffset.QuadPart = ImageDosHeader.e_lfanew; Status = ZwReadFile( hFile, NULL, NULL, NULL, &IoStatusBlock, &ImageNtHeader, sizeof(IMAGE_NT_HEADERS), &FileOffset, NULL); if (!NT_SUCCESS(Status)) { DbgPrint("ZwReadFile ImageNtHeader faild\n"); ZwClose(hFile); return Status; } // 读节段 pImageSectionHeader = (PIMAGE_SECTION_HEADER)ExAllocatePool(NonPagedPool, sizeof(IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections); if (NULL == pImageSectionHeader) { DbgPrint("ExAllocatePool pImageSectionHeader faild\n"); ZwClose(hFile); return STATUS_UNSUCCESSFUL; } FileOffset.QuadPart += sizeof(IMAGE_NT_HEADERS); Status = ZwReadFile( hFile, NULL, NULL, NULL, &IoStatusBlock, pImageSectionHeader, sizeof(IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections, &FileOffset, NULL); if (!NT_SUCCESS(Status)) { DbgPrint("ZwReadFile pImageSectionHeader faild\n"); ExFreePool(pImageSectionHeader); ZwClose(hFile); return Status; } // 复制内存 pVirtualAddress = ExAllocatePool(NonPagedPool, ImageNtHeader.OptionalHeader.SizeOfImage); if (NULL == pVirtualAddress) { DbgPrint("ExAllocatePool pVirtualAddress faild\n"); ExFreePool(pImageSectionHeader); ZwClose(hFile); return STATUS_UNSUCCESSFUL; } RtlZeroMemory(pVirtualAddress, ImageNtHeader.OptionalHeader.SizeOfImage); RtlCopyMemory(pVirtualAddress, &ImageDosHeader, sizeof(IMAGE_DOS_HEADER)); RtlCopyMemory( (PVOID)((ULONG)pVirtualAddress + ImageDosHeader.e_lfanew), &ImageNtHeader, sizeof(IMAGE_NT_HEADERS)); RtlCopyMemory( (PVOID)((ULONG)pVirtualAddress + ImageDosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)), pImageSectionHeader, sizeof(IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections); for (uIndex = 0; uIndex < ImageNtHeader.FileHeader.NumberOfSections; uIndex++) { uSectionAddress = pImageSectionHeader[uIndex].VirtualAddress; if (pImageSectionHeader[uIndex].Misc.VirtualSize > pImageSectionHeader[uIndex].SizeOfRawData) uSizeOfSection = pImageSectionHeader[uIndex].Misc.VirtualSize; else uSizeOfSection = pImageSectionHeader[uIndex].SizeOfRawData; FileOffset.QuadPart = pImageSectionHeader[uIndex].PointerToRawData; Status = ZwReadFile( hFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)((ULONG)pVirtualAddress + uSectionAddress), uSizeOfSection, &FileOffset, NULL); if (!NT_SUCCESS(Status)) { DbgPrint("ZwReadFile ImageSectionHeader faild\n"); ExFreePool(pImageSectionHeader); ExFreePool(pVirtualAddress); ZwClose(hFile); return Status; } } FixRelocTable(pVirtualAddress, pOriImage); DbgPrint("OK\n"); ExFreePool(pImageSectionHeader); *lpVirtualPoint = pVirtualAddress; ZwClose(hFile); return Status; }
接下来这步也是最关键一步,就是修复重定位表:
void FixRelocTable(PVOID pNewImage, PVOID pOriImage) { PIMAGE_DOS_HEADER pImageDosHeader; PIMAGE_NT_HEADERS pImageNtHeadaers; IMAGE_DATA_DIRECTORY ImageDataDirectory; PIMAGE_BASE_RELOCATION pImageBaseRelocation; ULONG uRelocTableSize; ULONG uCount; ULONG uIndex; USHORT *pwOffsetAddress; USHORT uTypeValue; ULONG uRelocOffset; ULONG uRelocAddress; pImageDosHeader = (PIMAGE_DOS_HEADER)pNewImage; pImageNtHeadaers = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew + (ULONG)pNewImage); uRelocOffset = (ULONG)pOriImage - pImageNtHeadaers->OptionalHeader.ImageBase; ImageDataDirectory = pImageNtHeadaers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)(ImageDataDirectory.VirtualAddress + (ULONG)pNewImage); uRelocTableSize = ImageDataDirectory.Size; while (uRelocTableSize) { uCount = (pImageBaseRelocation->SizeOfBlock - sizeof(ULONG)* 2) / sizeof(USHORT); pwOffsetAddress = pImageBaseRelocation->TypeOffset; for (uIndex = 0; uIndex < uCount; uIndex++) { uTypeValue = http://www.mamicode.com/pwOffsetAddress[uIndex];>通过上面步骤,我们成功的将内核文件完全复制了一遍。
之后就是如何让相关黑科技走我们的内核了,明天再继续!
Win7 内核重载 1 ——内核版PELoader
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。