为何遍历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
解决二叉树遍历的画法 对于二叉树的基本概念,一般学生都知道,但对于二叉树的遍历,在实际运用中可以发现很多问题,这里提供一次性彻底解决这个问题的方法. 二叉树的遍历 二叉树的遍历是指不重复地访问二叉树中 ...
随机推荐
- HttpContext详解【转】
HttpContext 类:封装有关个别 HTTP 请求的所有 HTTP 特定的信息. 在处理请求执行链的各个阶段中,会有一个对象在各个对象之间进行传递,也即会保存请求的上下文信息,这个对象就是Htt ...
- C#软件winform程序安装包制作及卸载程序制作
使用vs2010 winform程序开发的软件的人比较多,程序的开发是为了在不同的人不同的机器使用,为了使不同的机器能使用该软件就需要在制作程序安装包,安装包里必须包含该软件运行所选的所有环境,下面就 ...
- Android中view的事件
view:top.left.right.bottom,相对于parent的位置参数,获取通过get*()来获取.width=right-left.height=bottom-top.x=left+tr ...
- 读书笔记-实用单元测试(英文版) Pragmatic Unit Testing in C# with NUnit
读书笔记-实用单元测试(英文版) Pragmatic Unit Testing in C# with NUnit Author: Andrew Hunt ,David Thomas with Matt ...
- Swift和Objective-C的差异性
1:Type Swift提供了类型推断,不需要人工的去注释变量的类型信息,编译器会通过变量的值来推断类型.例如,编译器可以自动将该变量设置为字符串: // 自动推断,不显示 var name1 = & ...
- input file 样式以及获取选择文件方法集合
样式一(http://www.cnblogs.com/jason-liu-blogs/archive/2013/06/13/3133377.html) <style> a{display: ...
- C指针--通过二级指针往回拉数据
现在有这种需求,在main函数中建立一个二叉树的root结点的指针,在tree_create函数中malloc或者new一个二叉树结点,然后在main函数中能正常的访问这个新建的结点. 注:这里的tr ...
- Javascript中undefined,NaN等特殊比较
以下内容转自: http://blog.csdn.net/hongweigg/article/details/38090093 1.问题:在Javascript中,typeof(undefined) ...
- 用SQL将查询出来的多列的值拼接成一个字符串【转载】
MySQL中: [sql] view plaincopyprint? -- 单列拼接,先查出一行,再加上逗号,接着拼接 查出的下一行 select group_concat(E.SUPPORT) fr ...
- 基于jQuery的前端如何做到无伤迁移
首先,解释一下我个人对前端无伤迁移的理解,即移动端和PC端使用同一套代码,或者说原本在PC端运行得很完美的代码,只要修改少许,就可以在移动端完美运行. 当然,大部分的公司会专门为移动端设计了一套,同时 ...