为何遍历Ldr会得到空项?
转自:http://www.0xaa55.com/thread-1385-1-1.html
之前做过ldr遍历的操作,发现第一项竟然是空,也就是大部分元素都是0,下面来揭示一下原理:
经过研究,其实Ldr链表得第一项为头结点,为PEB_LDR_DATA结构,而其他所有项均为LDR_DATA_TABLE_ENTRY结构
Ldr的创建:ldrinit.c -> LdrpInitializeProcess
PEB_LDR_DATA PebLdr
LdrpInitializeProcess 初始化进程时用空项PebLdr创建Ldr
Peb->Ldr = &PebLdr;
InitializeListHead(&PebLdr.InLoadOrderModuleList);
InitializeListHead(&PebLdr.InMemoryOrderModuleList);
InitializeListHead(&PebLdr.InInitializationOrderModuleList);
PebLdr.Length = sizeof(PEB_LDR_DATA);
PebLdr.Initialized = TRUE;
LdrUnloadDll和LdrpLoadDll分别会进行对Ldr这3个链表卸载和增添节点操作,而顺序不同:
Load时如果发现未加载dll则会增加节点,会先添加InMemoryOrderModuleList InLoadOrderModuleList 两个链表增加节点,之后操作InInitializationOrderModuleList,之后调用DllMain初始化
而Unload的时候若发现引用计数为0则会删除节点,会先对InMemoryOrderModuleList InInitializationOrderModuleList 两个链表删除节点,之后调用DllMain清理,最后删除InLoadOrderModuleList节点
#define RemoveEntryList(e) do { PLIST_ENTRY f = (e)->Flink, b = (e)->Blink; f->Blink = b; b->Flink = f; (e)->Flink = (e)->Blink = NULL; } while (0)
可见删除链表操作为将该项后一个节点直接连接到前一个节点,并且将当前节点的首尾指向NULL,因此通过判断Flink=0 可以判断某DLL正在被卸载
正确的遍历Ldr LIST_ENTRY方法:
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
Next = ListHead->Flink;
while (Next != ListHead)//跳过头结点即可
{
Next = Next->Flink;
}
而ldr结构图如下:
typedef struct _PEB_LDR_DATA
{
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
PVOID EntryPointActivationContext;
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
当时我遍历的时候将Head当成LDR_DATA_TABLE_ENTRY,自然数据是不对的~~
为何遍历Ldr会得到空项?的更多相关文章
- Java的poi技术遍历Excel时进行空Cell,空row,判断
/** * 导入信息 */ @Override public List<Object> add(HttpServletRequest request) { // TODO Auto-gen ...
- js中遍历删除数组中的项(项目中遇到的问题解决)
代码如下: for (var key=0;key<$scope.pageContent.messages.length;key++){ if($scope.pageContent.message ...
- checkbox遍历操作, 提交所有选中项的值
<div class="content_list pad_10 hidden" > <h3>修改可配送地区</h3> <input typ ...
- Winform 遍历 ListBox中的所有项
foreach(DataRowView row in listBox.Items ) { MessageBox.Show(row["displayMember"].ToString ...
- PHP数组去空项
$strDelCodes = "A;B;;C;;C;D;;;D;D";$rsArray = array_values (array_unique (array_diff (spli ...
- 先序遍历创建二叉树,对二叉树统计叶子节点个数和统计深度(创建二叉树时#代表空树,序列不能有误)c语言
#include "stdio.h" #include "string.h" #include "malloc.h" #define NUL ...
- C++树的插入和遍历(关于指针的指针,指针的引用的思考)
题目 写一个树的插入和遍历的算法,插入时按照单词的字典顺序排序(左边放比它"小"的单词,右边放比它"大"的单词),对重复插入的单词进行计数. 程序源码 #inc ...
- PEB及LDR链
PEB地址的取得在NT内核系统中fs寄存器指向TEB结构,TEB+0x30处指向PEB结构,PEB+0x0c处指向PEB_LDR_DATA结构,PEB_LDR_DATA+0x1c处存放一些指向动态链接 ...
- 二叉树遍历入门 Lebal:research
解决二叉树遍历的画法 对于二叉树的基本概念,一般学生都知道,但对于二叉树的遍历,在实际运用中可以发现很多问题,这里提供一次性彻底解决这个问题的方法. 二叉树的遍历 二叉树的遍历是指不重复地访问二叉树中 ...
随机推荐
- 命令行运行命令时报错You don't have write permissions for the /Library/***
这是由于要运行这些操作时必须有管理员的权限(比方更新软件),比方更新cocoapods时报错 soindy:SmartThermo soindy$ gem install cocoapods Fetc ...
- 你知道为什么Xcode6中Swift没有智能提示和自己主动补全功能吗 ?
你知道为什么Xcode6中Swift没有智能提示和自己主动补全功能吗 ? 长沙戴维营教育将为你解开这个巨大的谜团大BUG! http://www.ubuntucollege.cn/course/29/ ...
- ARM64调试环境
自从上一次ZCTF做了一道ARM64的逆向题目后,我决定记录下利用qemu搭建ARM64的环境的过程,以后肯定会遇到更多ARM平台下的Reverse和PWN. 一 安装QEMU 我要模拟的是64位的A ...
- linux 命令入门
1 linux 中,一切皆文件. 图片.MP3和视频,它们都是文件. 目录,是一种特殊的文件,其中包含其他文件的信息.磁盘驱动器则是真正的大文件了. 网络连接也是文件,甚至运行中的进程都是文件.这些都 ...
- javascript模式——Prototype模式
GoF权威的解释是,原型模式是一种通过对一个对象的克隆,创建基于这个对象的多种对象的模式. 为了实现这种原型模式,可以直接使用ECMAScript 5 中的方法Object.create.它不紧可以创 ...
- iOS设计模式解析(三)适配器模式
适配器模式:将一个类的借口转换成客户端希望的另一个接口 有一个很直观的图: 例如 :电源适配器(将110V电压转换成220V电压,其中Traget是220V电压,adaptee就是110V电 ...
- C# for 循环 迭代法 穷举法
for()循环. 四要素: 初始条件,循环条件,状态改变,循环体. 执行过程: 初始条件--循环条件--循环体--状态改变--循环条件.... 注意:for的小括号里面分号隔开,for的小括号后不要加 ...
- python基础之语句结束
1 2 3 4 5 if a : if b: # 这里是if b的作用区间 #这里是if a的作用区间 #这里不在if 区间 python 是按缩进来识别代码块的.
- 关于height:100%两三事
对于CSS的height:100%,顾名思义,该元素的高度自动填充为其父元素的高度.但该样式有时候会不起作用,Mark down 一下.>< 首先,看一下以下CSS代码: div { he ...
- 【译】Optimize caching-缓存优化
缓存优化 大部分的网页都包括不常更改的资源,比如CSS文件,图片文件,JavaScript文件等.这些资源通过网络下载需要一定的时间,这就增加了网页加载的总时间.HTTP缓存可以让这些资源通过浏览器以 ...