引入vad.h
头文件,并写入如下代码,此处的eprocess_offset_VadRoot
以及eprocess_offset_VadCount
则是上方得出的相对于EPROCESS
结构的偏移值,每个系统都不一样,版本不同偏移值会不同 。
#include "vad.h"#include <ntifs.h>// 定义VAD相对于EProcess头部偏移值#define eprocess_offset_VadRoot 0x658#define eprocess_offset_VadCount 0x668VOID EnumVad(PMMVAD Root, PALL_VADS pBuffer, ULONG nCnt){ if (!Root || !pBuffer || !nCnt) {return; } __try {if (nCnt > pBuffer->nCnt){// 得到起始页与结束页ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;endptr = endptr << 32;ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;startptr = startptr << 32;// 得到根节点pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;// 起始页: startingVpn * 0x1000pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;// 结束页: EndVpn * 0x1000 + 0xfffpBuffer->VadInfos[pBuffer->nCnt].endVpn = ((endptr | Root->Core.EndingVpn) << PAGE_SHIFT) + 0xfff;// VAD标志 928 = Mapped1049088 = Private....pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;// 验证节点可读性if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea)){if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4))){pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);}}pBuffer->nCnt++;}if (MmIsAddressValid(Root->Core.VadNode.Left)){// 递归枚举左子树EnumVad((PMMVAD)Root->Core.VadNode.Left, pBuffer, nCnt);}if (MmIsAddressValid(Root->Core.VadNode.Right)){// 递归枚举右子树EnumVad((PMMVAD)Root->Core.VadNode.Right, pBuffer, nCnt);} } __except (1) { }}BOOLEAN EnumProcessVad(ULONG Pid, PALL_VADS pBuffer, ULONG nCnt){ PEPROCESS Peprocess = 0; PRTL_AVL_TREE Table = NULL; PMMVAD Root = NULL; // 通过进程PID得到进程EProcess if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)Pid, &Peprocess))) {// 与偏移相加得到VAD头节点Table = (PRTL_AVL_TREE)((UCHAR*)Peprocess + eprocess_offset_VadRoot);if (!MmIsAddressValid(Table) || !eprocess_offset_VadRoot){return FALSE;}__try{// 取出头节点Root = (PMMVAD)Table->Root;if (nCnt > pBuffer->nCnt){// 得到起始页与结束页ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;endptr = endptr << 32;ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;startptr = startptr << 32;pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;// 起始页: startingVpn * 0x1000pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;// 结束页: EndVpn * 0x1000 + 0xfffpBuffer->VadInfos[pBuffer->nCnt].endVpn = (endptr | Root->Core.EndingVpn) << PAGE_SHIFT;pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea)){if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4))){pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);}}pBuffer->nCnt++;}// 枚举左子树if (Table->Root->Left){EnumVad((MMVAD*)Table->Root->Left, pBuffer, nCnt);}// 枚举右子树if (Table->Root->Right){EnumVad((MMVAD*)Table->Root->Right, pBuffer, nCnt);}}__finally{ObDereferenceObject(Peprocess);} } else {return FALSE; } return TRUE;}VOID UnDriver(PDRIVER_OBJECT driver){ DbgPrint(("Uninstall Driver Is OK \n"));}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){ DbgPrint(("hello lyshark \n")); typedef struct {ULONG nPid;ULONG nSize;PALL_VADS pBuffer; }VADProcess; __try {VADProcess vad = { 0 };vad.nPid = 4520;// 默认有1000个线程vad.nSize = sizeof(VAD_INFO) * 0x5000 + sizeof(ULONG);// 分配临时空间vad.pBuffer = (PALL_VADS)ExAllocatePool(PagedPool, vad.nSize);// 根据传入长度得到枚举数量ULONG nCount = (vad.nSize - sizeof(ULONG)) / sizeof(VAD_INFO);// 枚举VADEnumProcessVad(vad.nPid, vad.pBuffer, nCount);// 输出VADfor (size_t i = 0; i < vad.pBuffer->nCnt; i++){DbgPrint("StartVPN = %p | ", vad.pBuffer->VadInfos[i].startVpn);DbgPrint("EndVPN = %p | ", vad.pBuffer->VadInfos[i].endVpn);DbgPrint("PVAD = %p | ", vad.pBuffer->VadInfos[i].pVad);DbgPrint("Flags = %d | ", vad.pBuffer->VadInfos[i].flags);DbgPrint("pFileObject = %p \n", vad.pBuffer->VadInfos[i].pFileObject);} } __except (1) { } Driver->DriverUnload = UnDriver; return STATUS_SUCCESS;}
经验总结扩展阅读
- [Android开发学iOS系列] 快速上手UIKit
- [Android开发学iOS系列] ViewController
- 驱动开发:内核中实现Dump进程转储
- GitHub 供应链安全已支持 Dart 开发者生态
- 驱动开发:内核R3与R0内存映射拷贝
- [Android开发学iOS系列] iOS写UI的几种方式
- AgileBoot - 基于SpringBoot + Vue3的前后端快速开发脚手架
- 驱动开发:内核通过PEB得到进程参数
- 市场开发战略是什么?
- 完 golang开发:go并发的建议