遍历vad二叉树来遍历进程里的模块

/*
 遍历vad二叉树来遍历进程里的模块
*/

#include <ntifs.h>

typedef struct _MMADDRESS_NODE
{
	ULONG64 u1;
	struct _MMADDRESS_NODE* LeftChild;
	struct _MMADDRESS_NODE* RightChild;
	ULONG64 StartingVpn;
	ULONG64 EndingVpn;
}MMADDRESS_NODE, *PMMADDRESS_NODE;
typedef struct _EX_FAST_REF
{
	union
	{
		PVOID Object;
		ULONG_PTR RefCnt : 3;
		ULONG_PTR Value;
	};
} EX_FAST_REF, *PEX_FAST_REF;
struct _SEGMENT
{
	struct _CONTROL_AREA* ControlArea;
	ULONG TotalNumberOfPtes;
	ULONG SegmentFlags;
	ULONG64 NumberOfCommittedPages;
	ULONG64 SizeOfSegment;
	union
	{
		struct _MMEXTEND_INFO* ExtendInfo;
		void* BasedAddress;
	};
	ULONG64 SegmentLock;
	ULONG64 u1;
	ULONG64 u2;
	struct _MMPTE* PrototypePte;
	ULONGLONG ThePtes[0x1];
};
//控制区
struct _CONTROL_AREA
{
	struct _SEGMENT* Segment;
	struct _LIST_ENTRY DereferenceList;
	unsigned __int64 NumberOfSectionReferences;
	unsigned __int64 NumberOfPfnReferences;
	unsigned __int64 NumberOfMappedViews;
	unsigned __int64 NumberOfUserReferences;
	ULONG  u;
	ULONG FlushInProgressCount;
	struct _EX_FAST_REF FilePointer;

	/*ULONG ControlAreaLock;
	ULONG ModifiedWriteCount;
	ULONG StartingFrame;
	ULONG64 WaitingForDeletion;
	ULONG64 u2; //0x10字节
	ULONG64 LockedPages;
	_LIST_ENTRY ViewList;*/
};
struct _SUBSECTION
{
	struct _CONTROL_AREA* ControlArea;
	struct _MMPTE* SubsectionBase;
	struct _SUBSECTION* NextSubsection;
	ULONG PtesInSubsection;
	ULONG UnusedPtes;
	struct _MM_AVL_TABLE* GlobalPerSessionHead;
	ULONG u;
	ULONG StartingSector;
	ULONG NumberOfFullSectors;
};
typedef struct _MMVAD
{
	ULONG64 u1;
	struct _MMVAD* LeftChild;
	struct _MMVAD* RightChild;
	ULONG64 StartingVpn;
	ULONG64 EndingVpn;
	ULONG64 u;
	ULONG64 PushLock;
	ULONG64 u5;
	ULONG64 u2;
	struct _SUBSECTION* Subsection;
	struct _MSUBSECTION* MappedSubsection;
	struct _MMPTE* FirstPrototypePte;
	struct _MMPTE* LastContiguousPte;
	struct _LIST_ENTRY ViewLinks;
	struct _EPROCESS* VadsProcess;
}MMVAD;
typedef struct   tag_MM_AVL_TABLE
{
	struct _MMADDRESS_NODE BalancedRoot;
	ULONG64 DepthOfTree;
	ULONG64 Unused;
	ULONG64 NumberGenericTableElements;
	void* NodeHint;
	void* NodeFreeHint;
}MM_AVL_TABLE, *PMMAVL_TABLE;

long TotalNum = 0;

VOID EnumVad(MMVAD* Root)
{
	POBJECT_NAME_INFORMATION  Str = (POBJECT_NAME_INFORMATION)ExAllocatePool(PagedPool, 500);
	ULONG RetLen = 0;//接收

	//DbgBreakPoint();

	//申请内存失败或者节点为null都退出
	if (!Str || !Root)
		return;

	RtlZeroMemory(Str, 500);
	//KdPrint(("-> %p\n", Root->Subsection->ControlArea->FilePointer.Value));
	__try
	{
		if (MmIsAddressValid(Root->Subsection) &&
			MmIsAddressValid(Root->Subsection->ControlArea) &&
			MmIsAddressValid((PVOID)Root->Subsection->ControlArea->FilePointer.Value)
			)
		{
			//清除低4位就是FILE_OBJECT
			PFILE_OBJECT pFileObj = (PFILE_OBJECT)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);
			if (MmIsAddressValid(pFileObj))
			{
				//获取模块名称
				NTSTATUS Status = ObQueryNameString(pFileObj, Str, 500, &RetLen);
				if (NT_SUCCESS(Status))
				{
					//KdPrint(("基址:%p 大小:%p  ",
					//	Root->Subsection->ControlArea->Segment->BasedAddress,
					//	Root->Subsection->ControlArea->Segment->SizeOfSegment));
					KdPrint(("模块:%ws\n\n", Str->Name.Buffer));
					TotalNum++;
				}
				else
				{
					KdPrint(("获取模块名称失败 %08X\n", Status));
				}

			}
		}
	}
	__except (1)
	{
		//KdPrint(("地址无效!\n"));
	}
	ExFreePool(Str);
	__try
	{
		if (MmIsAddressValid(Root->LeftChild))
			EnumVad(Root->LeftChild);

		if (MmIsAddressValid(Root->RightChild))
			EnumVad(Root->RightChild);
	}
	__except (1)
	{
		KdPrint(("异常!!"));
		return;
	}

}
BOOLEAN EnumProcessModule(ULONG Pid)
{
	PEPROCESS Peprocess = 0;
	if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)Pid, &Peprocess)))
	{
		//挂靠到目标进程
		KeAttachProcess(Peprocess);

		PMMAVL_TABLE Table = (PMMAVL_TABLE)((UCHAR*)Peprocess + 0x448);
		KdPrint(("%p", Table->BalancedRoot.RightChild));

		if (Table->BalancedRoot.LeftChild)
			EnumVad((MMVAD*)Table->BalancedRoot.LeftChild);

		if (Table->BalancedRoot.RightChild)
			EnumVad((MMVAD*)Table->BalancedRoot.RightChild);

		//解除挂靠
		KeDetachProcess();

		KdPrint(("总模块数量为%ld", TotalNum));
	}
	else
	{
		KdPrint(("PsLookupProcessByProcessId failed"));
		return FALSE;
	}

	return TRUE;
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值