设为首页 加入收藏

TOP

驱动开发:内核PE结构VA与FOA转换(二)
2023-07-23 13:26:03 】 浏览:68
Tags:内核 结构 FOA 转换
Headers); PIMAGE_FILE_HEADER pFileHeader = &pNtHeaders->FileHeader; DWORD64 dwFOA = 0x84EC00; DWORD64 ImageBase = pNtHeaders->OptionalHeader.ImageBase; DWORD NumberOfSectinsCount = pNtHeaders->FileHeader.NumberOfSections; DbgPrint("镜像基址 = %p | 节表数量 = %d \n", ImageBase, NumberOfSectinsCount); for (int each = 0; each < NumberOfSectinsCount; each++) { DWORD64 PointerRawStart = pSection[each].PointerToRawData; // 文件偏移开始位置 DWORD64 PointerRawEnds = pSection[each].PointerToRawData + pSection[each].SizeOfRawData; // 文件偏移结束位置 // DbgPrint("文件开始偏移 = %p | 文件结束偏移 = %p \n", PointerRawStart, PointerRawEnds); if (dwFOA >= PointerRawStart && dwFOA <= PointerRawEnds) { DWORD64 RVA = pSection[each].VirtualAddress + (dwFOA - pSection[each].PointerToRawData); // 计算出RVA DWORD64 VA = RVA + pNtHeaders->OptionalHeader.ImageBase; // 计算出VA DbgPrint("FOA偏移 [ %p ] --> 对应VA地址 [ %p ] \n", dwFOA, VA); } } ZwUnmapViewOfSection(NtCurrentProcess(), pBaseAddress); ZwClose(hSection); ZwClose(hFile); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }

运行效果如下所示,此处之所以出现两个结果是因为没有及时返回,一般我们取第一个结果就是最准确的;

VA转换为FOA: 将VA内存地址转换为FOA文件偏移,代码与如上基本保持一致。

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com

NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("hello lyshark.com \n");

	NTSTATUS status = STATUS_SUCCESS;
	HANDLE hFile = NULL;
	HANDLE hSection = NULL;
	PVOID pBaseAddress = NULL;
	UNICODE_STRING FileName = { 0 };

	// 初始化字符串
	RtlInitUnicodeString(&FileName, L"\\??\\C:\\Windows\\System32\\ntoskrnl.exe");

	// 内存映射文件
	status = KernelMapFile(FileName, &hFile, &hSection, &pBaseAddress);
	if (!NT_SUCCESS(status))
	{
		return 0;
	}

	// 获取PE头数据集
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;
	PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew);
	PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeaders);
	PIMAGE_FILE_HEADER pFileHeader = &pNtHeaders->FileHeader;

	DWORD64 dwVA = 0x00007FF6D3389200;
	DWORD64 ImageBase = pNtHeaders->OptionalHeader.ImageBase;
	DWORD NumberOfSectinsCount = pNtHeaders->FileHeader.NumberOfSections;
	DbgPrint("镜像基址 = %p | 节表数量 = %d \n", ImageBase, NumberOfSectinsCount);

	for (DWORD each = 0; each < NumberOfSectinsCount; each++)
	{
		DWORD Section_Start = ImageBase + pSection[each].VirtualAddress;                                  // 获取节的开始地址
		DWORD Section_Ends = ImageBase + pSection[each].VirtualAddress + pSection[each].Misc.VirtualSize; // 获取节的结束地址

		DbgPrint("Section开始地址 = %p | Section结束地址 = %p \n", Section_Start, Section_Ends);

		if (dwVA >= Section_Start && dwVA <= Section_Ends)
		{
			DWORD RVA = dwVA - pNtHeaders->OptionalHeader.ImageBase;                                    // 计算RVA
			DWORD FOA = pSection[each].PointerToRawData + (RVA - pSection[each].VirtualAddress);       // 计算FOA
			
			DbgPrint("VA偏移 [ %p ] --> 对应FOA地址 [ %p ] \n", dwVA, FOA);
		}
	}

	ZwUnmapViewOfSection(NtCurrentProcess(), pBaseAddress);
	ZwClose(hSection);
	ZwClose(hFile);

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCC
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇位段/位域 的使用 下一篇c语言,函数的址传递例子

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目