x86重载内核[源码在最后]

本文介绍了X86内核重载的原理与实现过程,包括修改PE文件、驱动编程、修复重定向表和IAT表、内核内存申请、SSDT函数替换以及hook KiFastCallEntry。适合驱动编程新手学习,提供了源码地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

X86重载内核

测试系统:WinXp, 环境:vs2017

一、内核重载简述

涉及PE文件,驱动程序编写, 对X86内核的了解
内核重载其实就是让所有的SSDT函数全部走自己写入的一块新内核

内核重载不是什么高端技术,但对于学习驱动编程的新手而言,还是有学习参考价值的

二、实现步骤(部分代码)

1.打开内核文件存为buffer,拉伸PE,修重定向表,IAT表

​
NTSTATUS LoadNtkrnlpa() 
{
	NTSTATUS						status = STATUS_SUCCESS;
	HANDLE							hFile = NULL;
	OBJECT_ATTRIBUTES				objAttr;
	IO_STATUS_BLOCK					ioBlock;
	UNICODE_STRING					FileName;
	FILE_STANDARD_INFORMATION		FileInfo;
	LARGE_INTEGER					Lageint; // 读取位置offset

	RtlInitUnicodeString(&FileName, FILEPATH);
	InitializeObjectAttributes(&objAttr, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL);

	status = ZwOpenFile(&hFile, FILE_ALL_ACCESS, &objAttr, &ioBlock, 0, FILE_NON_DIRECTORY_FILE);
	if (!NT_SUCCESS(status))
	{
		DbgPrint("ZwOpenFile Failed!, status:%d\n", status);
		return STATUS_UNSUCCESSFUL;
	}

	status = ZwQueryInformationFile(hFile, &ioBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
	if (!NT_SUCCESS(status))
	{
		ZwClose(hFile);
		DbgPrint("ZwQueryInformationFile Failed!\n");
		return STATUS_UNSUCCESSFUL;
	}
	FileSize = FileInfo.EndOfFile.LowPart;
	pFileBuffer = ExAllocatePool(NonPagedPool, FileSize);

	Lageint.QuadPart = 0;
	status = ZwReadFile(hFile, NULL, NULL, NULL, &ioBlock, pFileBuffer, FileSize, &Lageint, NULL);
	if (!NT_SUCCESS(status))
	{
		ZwClose(hFile);
		DbgPrint("ZwReadFile Failed!\n");
		return STATUS_UNSUCCESSFUL;
	}

	ZwClose(hFile);
	// 读取PE信息
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
	{
		ExFreePool(pFileBuffer);
		pFileBuffer = NULL;
		DbgPrint("Read PE File Failed\n");
		return STATUS_UNSUCCESSFUL;
	}

	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		ExFreePool(pFileBuffer);
		pFileBuffer = NULL;
		DbgPrint("Read PE File Failed\n");
		return STATUS_UNSUCCESSFUL;
	}

	pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
	pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
	pReloactionDirectory = (PIMAGE_BASE_RELOCATION)((DWORD)pDosHeader + RVA_TO_FOA(pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress));
	pIATDirectory = (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + RVA_TO_FOA(pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress));
	
	return status;
}

(1)修重定向表

​
NTSTATUS FixRelocTable(DWORD OrignalImageBase)
{
	if (pReloactionDirectory == NULL) return STATUS_UNSUCCESSFUL;

	// 修复重定位表
	DWORD AddItem = OrignalImageBase - pOptionalHeader->ImageBase;
	// pOptionalHeader->ImageBase = NewImageBase;

	PIMAGE_BASE_RELOCATION pTempRelocationDir = pReloactionDirectory;
	UINT Count = 0;

	do
	{
		DWORD ChunkNum = (pTempRelocationDir->SizeOfBlock - 0x8) / 0x2;

		for (UINT i = 0; i < ChunkNum; i++)
		{
			PWORD pItem = (PWORD)(((DWORD)pTempRelocationDir + 0x8) + 0x2 * i);
			DWORD Type = (*pItem) >> 12;
			if (Type == 3)
			{
				PDWORD pFixAddress = (PDWORD)((DWORD)pDosHeader + RVA_TO_FOA(pTempRelocationDir->VirtualAddress + (*pItem & 0x0FFF)));
				*pFixAddress += AddItem;
			}
		}

		pTempRelocationDir = (PIMAGE_BASE_RELOCATION)((DWORD)pTempRelocationDir + pTempRelocationDir->SizeOfBlock);
		Count++;
	} while (pTempRelocationDir->VirtualAddress != 0 && pTempRelocationDir->SizeOfBlock != 0);

	// DbgPrint("FixBlockCount:%d\n", Count);
	return STATUS_SUCCESS;
}

(2)修IAT表

​
NTSTATUS FixIATTable()
{
	PIMAGE_THUNK_DATA pTemIATDir = pIATDirectory;
	ULONG CopySize = 0;

	while (pTemIATDir->u1.Function != 0)
	{
		CopySize += 4;
		pTemIATDir++;
	}

	PULONG pCurrentIATDir = OrignImage + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
	RtlCopyMemory(pIATDirectory, pCurrentIATDir, CopySize);
	
	return STATUS_SUCCESS;
}

2.内核层申请一块内存贴入buffer

​
NTSTATUS CopyFileBufferToImageBuffer(_In_ LPVOID pFilebuffer_, _Out_ LPVOID* pImageBuffer_)
{
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFilebuffer_;
	PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFilebuffer_ + pDosHeader->e_lfanew);

	PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 0x4);
	PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
	PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);

	DWORD AlignImageSize = Align(pOptionalHeader->SizeOfImage, pOptionalHeader->SectionAlignment);
	*pImageBuffer_ = ExAllocatePool(NonPagedPool, AlignImageSize);
	memset(*pImageBuffer_, 0, AlignImageSize);
	memcpy(*pImageBuffer_, pFilebuffer_, pOptionalHeader->SizeOfHeaders);

	PIMAGE_SECTION_HEADER TempSectionHeader = pSectionHeader;

	for (int i = 0; i < pFileHeader->NumberOfSections; i++)
	{
		memcpy((LPVOID)((DWORD)*pImageBuffer_ + TempSectionHeader->VirtualAddress), (LPVOID)((DWORD)pDosHeader + TempSectionHeader->PointerToRawData), TempSectionHeader->SizeOfRawData);
		TempSectionHeader++;
	}

	return STATUS_SUCCESS;
}

3.修复ssdt中函数地址为新内核函数地址

4.创建山寨系统服务表

​
NTSTATUS SetNewSSDT(DWORD NewImageBase)
{

	pNewKeServiceDescriptorTable = (PKSERVICE_TABLE_DESCRIPTOR)((DWORD)KeServiceDescriptorTable - OrignImage + NewImageBase);

	// 函数表
	pNewKeServiceDescriptorTable->ntoskrnl.ServiceTableBase = (PULONG)((DWORD)KeServiceDescriptorTable->ntoskrnl.ServiceTableBase - OrignImage + NewImageBase);
	
	// 函数个数
	pNewKeServiceDescriptorTable->ntoskrnl.NumberOfService = KeServiceDescriptorTable->ntoskrnl.NumberOfService;

	// 调用次数
	// pNewKeServiceDescriptorTable->ntoskrnl.ServiceCounterTableBase = (PULONG)((DWORD)KeServiceDescriptorTable->ntoskrnl.ServiceCounterTableBase - OrignImage + NewImageBase);

	// 参数表
	pNewKeServiceDescriptorTable->ntoskrnl.ParamTableBase = (PULONG)((DWORD)KeServiceDescriptorTable->ntoskrnl.ParamTableBase - OrignImage + NewImageBase);

	 PageProtectOff();

	// 修复函数地址表 ,其实重定位表修复那里就修好了
	for (ULONG i = 0; i < pNewKeServiceDescriptorTable->ntoskrnl.NumberOfService; i++)
	{
		pNewKeServiceDescriptorTable->ntoskrnl.ServiceTableBase[i] += (-OrignImage + NewImageBase);

	}
	 PageProtectOn();

	return STATUS_SUCCESS;
}

5.hook KiFastCallEntry

​
NTSTATUS HookKiFastCallEntry()
{
	ULONG	HookAddr = 0;
	ULONG	uKiFastCallEntry = 0;
	// 找到KiFastCallEntry函数首地址, 在特殊模组寄存器的0x176号寄存器中
	__asm
	{
		push ecx;
		push eax;
		push edx;
		mov ecx, 0x176; // 设置编号
		rdmsr; ;// 读取到edx:eax
		mov uKiFastCallEntry, eax;// 保存到变量
		pop edx;
		pop eax;
		pop ecx;
	}

	for (ULONG i = 0; i < 0x1FF; ++i)
	{
		if (RtlCompareMemory((UCHAR*)uKiFastCallEntry + i, OriginalCode, 5) == 5)
		{
			HookAddr = uKiFastCallEntry + i;
			break;
		}
	}
	if (HookAddr == 0)
	{
		DbgPrint("Not Find 2be1c1e902 bytes");
		return STATUS_UNSUCCESSFUL;
	}

	PDWORD JmpAddr = (PDWORD)HookProc;

	PageProtectOff();
	DWORD32 X = (HookAddr + 5) - ((DWORD32)&OriginalCode[5] + 5);
	OriginalCode[5] = '\xE9';
	*(DWORD32*)(OriginalCode + 5 + 1) = X;
	pOrigianlCmd = (PORIGINALCOMD)(CHAR*)OriginalCode;
	BackAddr = HookAddr + 5;

	memset(NewCode, 0, 64);
	NewCode[0] = '\xE9';
	X = (DWORD32)JmpAddr - (HookAddr + 5);
	*(DWORD32*)(NewCode + 1) = (DWORD32)X;
	int Numnop = 5 - 5;
	for (int i = 0; i < Numnop; i++)
	{
		NewCode[5 + i] = '\x90';
	}

	RtlMoveMemory(HookAddr, NewCode, 5);

	PageProtectOn();

	return STATUS_SUCCESS;
}

三、代码测试截图

在这里插入图片描述

四、总结(源码地址)

​​

github地址
https://github.com/DeadpoolWilson12/kernelReload_

(3dmem) zrt@zrt:~$ sudo dmesg | grep ch34x [23948.109110] usbcore: registered new interface driver ch34x [23948.109121] usbserial: USB Serial support registered for ch34x [23948.109134] ch34x 1-8.4:1.0: ch34x converter detected [23948.109168] Modules linked in: ch34x(OE+) usbserial snd_usb_audio snd_usbmidi_lib snd_ump mc pcspkr ccm rfcomm nvidia_uvm(PO) mvfgvirtualserial(OE) cmlframegrabber(OE) cmac xofframegrabber(OE) algif_hash algif_skcipher af_alg cxpframegrabber(OE) bnep gevframegrabber(OE) gevfilter(OE) intel_rapl_msr intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common intel_tcc_cooling x86_pkg_temp_thermal intel_powerclamp coretemp nvidia_drm(PO) nvidia_modeset(PO) nvidia(PO) snd_sof_pci_intel_tgl snd_sof_intel_hda_common soundwire_intel snd_sof_intel_hda_mlink soundwire_cadence snd_sof_intel_hda snd_sof_pci snd_sof_xtensa_dsp snd_sof binfmt_misc kvm_intel snd_sof_utils snd_soc_hdac_hda rtw89_8851be snd_hda_ext_core snd_soc_acpi_intel_match rtw89_8851b snd_soc_acpi snd_hda_codec_realtek soundwire_generic_allocation nls_iso8859_1 snd_hda_codec_generic soundwire_bus rtw89_pci snd_hda_codec_hdmi kvm snd_soc_core snd_compress irqbypass ac97_bus rtw89_core snd_pcm_dmaengine crct10dif_pclmul btusb polyval_clmulni [23948.109280] ch34x_attach+0x1a6/0x3d0 [ch34x] [23948.109304] ? __pfx_ch34x_init+0x10/0x10 [ch34x] [23948.109305] ch34x_init+0x23/0xff0 [ch34x] [23948.109762] usb 1-8.4: ch34x converter now attached to ttyUSB0 [23951.195800] usb 1-8.4: usbfs: interface 0 claimed by ch34x while 'brltty' sets config #1 [23951.196419] ch34x ttyUSB0: ch34x converter now disconnected from ttyUSB0 [23951.196427] ch34x 1-8.4:1.0: device disconnected [24071.682644] ch34x 1-8.4:1.0: ch34x converter detected [24071.683064] usb 1-8.4: ch34x converter now attached to ttyUSB0 [24072.212788] usb 1-8.4: usbfs: interface 0 claimed by ch34x while 'brltty' sets config #1 [24072.213372] ch34x ttyUSB0: ch34x converter now disconnected from ttyUSB0 [24072.213389] ch34x 1-8.4:1.0: device disconnected [24137.264924] ch34x 1-8.4:1.0: ch34x converter detected [24137.265809] usb 1-8.4: ch34x converter now attached to ttyUSB0 [24137.798412] usb 1-8.4: usbfs: interface 0 claimed by ch34x while 'brltty' sets config #1 [24137.798977] ch34x ttyUSB0: ch34x converter now disconnected from ttyUSB0 [24137.798985] ch34x 1-8.4:1.0: device disconnected [24143.229930] ch34x 1-8.4:1.0: ch34x converter detected [24143.230327] usb 1-8.4: ch34x converter now attached to ttyUSB0 [24143.756662] usb 1-8.4: usbfs: interface 0 claimed by ch34x while 'brltty' sets config #1 [24143.757207] ch34x ttyUSB0: ch34x converter now disconnected from ttyUSB0 [24143.757215] ch34x 1-8.4:1.0: device disconnected
最新发布
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值