[科普]通过VAD枚举进程模块
众所周知,进程模块的信息分别存在于PEB和VAD里。枚举PEB的文章很多,我就不赘述了。枚举VAD的文章很少,而且代码写得乱七八糟,于是决定写篇文章科普一下。由于VAD并不是微软公开的结构,所以不同系统的变化比较大,在我看来基本分为三个阶段:WINXP、WIN2K3~WIN8、WIN8.1~WIN10(目前版本是16299)。不过,所谓变化,都是形变神不变,这里以XP系统举例,因为XP系统的VAD结构最简单,方便理解。VAD入口是EPROCESS->VadRoot。在XP下,WINDBG显示VadRoot的类型为PVOID,实际上它是MMVAD结构体的指针:/*lkd> dt_mmvad
nt!_MMVAD
+0x000 StartingVpn : Uint4B
+0x004 EndingVpn : Uint4B
+0x008 Parent : Ptr32 _MMVAD
+0x00c LeftChild : Ptr32 _MMVAD
+0x010 RightChild : Ptr32 _MMVAD
+0x014 u : __unnamed
+0x018 ControlArea : Ptr32 _CONTROL_AREA
+0x01c FirstPrototypePte : Ptr32 _MMPTE
+0x020 LastContiguousPte : Ptr32 _MMPTE
+0x024 u2 : __unnamed*/
typedef struct _MMVAD2600
{
ULONG StartingVpn;
ULONG EndingVpn;
struct _MMVAD2600 *Parent;
struct _MMVAD2600 *LeftChild;
struct _MMVAD2600 *RightChild;
void *u;
PCONTROL_AREA2600 ControlArea;
}MMVAD2600, *PMMVAD2600;VAD结构本身并没有模块名称和模块地址,它们存储在ControlArea的下级结构里:/*lkd> dt_CONTROL_AREA
nt!_CONTROL_AREA
+0x000 Segment : Ptr32 _SEGMENT
+0x004 DereferenceList: _LIST_ENTRY
+0x00c NumberOfSectionReferences : Uint4B
+0x010 NumberOfPfnReferences : Uint4B
+0x014 NumberOfMappedViews : Uint4B
+0x018 NumberOfSubsections : Uint2B
+0x01a FlushInProgressCount : Uint2B
+0x01c NumberOfUserReferences : Uint4B
+0x020 u : __unnamed
+0x024 FilePointer : Ptr32 _FILE_OBJECT <---这里是模块对应文件的文件对象
+0x028 WaitingForDeletion : Ptr32 _EVENT_COUNTER
+0x02c ModifiedWriteCount : Uint2B
+0x02e NumberOfSystemCacheViews : Uint2B*/
typedef struct _CONTROL_AREA2600
{
PSEGMENT2600 Segment;
UCHAR WhoCare;
PFILE_OBJECT FilePointer;
}CONTROL_AREA2600, *PCONTROL_AREA2600;/*lkd> dt_segment
nt!_SEGMENT
+0x000 ControlArea : Ptr32 _CONTROL_AREA
+0x004 TotalNumberOfPtes : Uint4B
+0x008 NonExtendedPtes: Uint4B
+0x00c WritableUserReferences : Uint4B
+0x010 SizeOfSegment : Uint8B
+0x018 SegmentPteTemplate : _MMPTE
+0x020 NumberOfCommittedPages : Uint4B
+0x024 ExtendInfo : Ptr32 _MMEXTEND_INFO
+0x028 SystemImageBase: Ptr32 Void
+0x02c BasedAddress : Ptr32 Void <---这里是模块地址
+0x030 u1 : __unnamed
+0x034 u2 : __unnamed
+0x038 PrototypePte : Ptr32 _MMPTE
+0x040 ThePtes : _MMPTE*/
typedef struct _SEGMENT2600
{
UCHAR WhoCare;
PVOID BasedAddress;
}SEGMENT2600, *PSEGMENT2600;VAD并不是简单的数组或链表结构,而是树结构。这棵树具体怎么样我就不多说了,反正你知道,它有“左孩子”和“右孩子”,得到第一个VAD结构体之后,顺着两个“孩子”走下去,直到“孩子”的地址为0或非法即可。枚举代码如下:**** Hidden Message *****接下来是干货内容,关于在WIN7、WIN8和WIN10上枚举VAD需要注意的地方。**** Hidden Message ***** 非常感谢分享! 本帖最后由 CleanLove 于 2017-10-31 18:12 编辑
谢谢TA科普 膜拜一下.
非常感谢分享! 实力UCHAR WhoCare; 感觉很厉害 厉害 非常感谢分享! 其实这货我也打算发一份嘞,被捷足先登了,哈哈 谢谢分享 看看,万一用到了呢 干货来了 好久没有写驱动了,谢谢分享,~! 学习一下! 感谢分享 感谢大大分享! 来学习一下 学习学习 好东西感谢分享,收藏了 谢谢楼主共享 参观参观 谢谢楼主 感谢分享! 谢谢楼主 感谢科普 来看看win10的干货. 谢谢楼主分享 非常感谢分享! 学习一下 非常感谢,好东西 学习学习学习