之前学习断链的时候了解到了LDR,最近考试周刚过比较闲,就整理了一下当时学习过程中的笔记,很基础的文章。
在windows中,每一个模块(exe,dll)对应了一个LDR_MODULE,这个模块是让系统认识到每个模块的存在,在获取模块基址,获取api地址用的很多,进而可以用来隐藏模块,编写外壳程序等……
关于结构LDR_MODULE的定义:
typedef struct _LDR_MODULE
{
LIST_ENTRY InLoadOrderModuleList; //按加载模块顺序构成的模块链表
LIST_ENTRY InMemoryOrderModuleList; //按内存顺序的模块链表
LIST_ENTRY InInitializationOrderModuleList; //按初始化顺序的模块链表
PVOID BaseAddress; //模块的基地址
PVOID EntryPoint; //模块的入口
ULONG SizeOfImage; //模块镜像大小
UNICODE_STRING FullDllName; //路径名
UNICODE_STRING BaseDllName; //模块名
ULONG Flags;
SHORT LoadCount; //引用计数
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
而后来我在查看PEB_LDR_DATA结构的时候:
typedef struct _PEB_LDR_DATA
{
ULONG Length;
BOOLEAN Initialized;
HANDLE SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
也发现了这三个链表InLoadOrderModuleList, InMemoryOrderModuleList, InInitializationOrderModuleList
那么这三个链表存在于两个结构中,到底有和对应的关系呢?
编写了一个程序helloworld.exe,windbg载入:
0:000> !peb
PEB at 7efde000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: Yes
ImageBaseAddress: 01000000
..........
0:000> dt _PEB 7efde000
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
+0x003 BitField : 0x8 ''
+0x003 ImageUsesLargePages : 0y0
+0x003 IsProtectedProcess : 0y0
+0x003 IsLegacyProcess : 0y0
+0x003 IsImageDynamicallyRelocated : 0y1
+0x003 SkipPatchingUser32Forwarders : 0y0
+0x003 SpareBits : 0y000
+0x004 Mutant : 0xffffffff Void
+0x008 ImageBaseAddress : 0x01000000 Void
+0x00c Ldr : 0x77d90200 _PEB_LDR_DATA
+0x010 ProcessParameters : 0x00421918 _RTL_USER_PROCESS_PARAMETERS
..................
0:000> dt _PEB_LDR_DATA 0x77d90200
ntdll!_PEB_LDR_DATA
+0x000 Length : 0x30
+0x004 Initialized : 0x1 ''
+0x008 SsHandle : (null)
+0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x593510 - 0x5941a8 ]
+0x014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x593518 - 0x5941b0 ]
+0x01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x5935b0 - 0x5941b8 ]
+0x024 EntryInProgress : (null)
+0x028 ShutdownInProgress : 0 ''
+0x02c ShutdownThreadId : (null)
0:000> dt _LDR_DATA_TABLE_ENTRY 0X593510
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x5935a0 - 0x77d9020c ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x5935a8 - 0x77d90214 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 DllBase : 0x01360000 Void
+0x01c EntryPoint : 0x0137110e Void
+0x020 SizeOfImage : 0x1c000
+0x024 FullDllName : _UNICODE_STRING "F:\helloworld.exe"
+0x02c BaseDllName : _UNICODE_STRING "helloworld.exe"
+0x034 Flags : 0x4000
+0x038 LoadCount : 0xffff
+0x03a TlsIndex : 0
+0x03c HashLinks : _LIST_ENTRY [ 0x77d948a0 - 0x77d948a0 ]
+0x03c SectionPointer : 0x77d948a0 Void
+0x040 CheckSum : 0x77d948a0
+0x044 TimeDateStamp : 0x548284c9
+0x044 LoadedImports : 0x548284c9 Void
+0x048 EntryPointActivationContext : (null)
+0x04c PatchInformation : (null)
+0x050 ForwarderLinks : _LIST_ENTRY [ 0x593560 - 0x593560 ]
+0x058 ServiceTagLinks : _LIST_ENTRY [ 0x593568 - 0x593568 ]
+0x060 StaticLinks : _LIST_ENTRY [ 0x594288 - 0x594260 ]
+0x068 ContextInformation : 0x77ccc984 Void
+0x06c OriginalBase : 0
+0x070 LoadTime : _LARGE_INTEGER 0x0
可以看到windbg中的_LDR_DATA_TABLE_ENTRY就是对应着LDR_MODULE结构,三个链表InLoadOrderModuleList, InMemoryOrderModuleList, InInitializationOrderModuleList都分别对应着各自的LDR_MODULE结构
用图来表示如下
由该图可知,三个链表结构被PEB_LDR_DATA和LDR_MODULE结构共用
那么这三个链表InLoadOrderModuleList, InMemoryOrderModuleList, InInitializationOrderModuleList又都有什么区别呢?
用上面那个测试程序:
对InLoadOrderModuleList 加载模块顺序构成的模块链表进行调试
//针对0x593510链表的flink进行遍历
+0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x593510 - 0x5941a8 ]
..................
0:000> dt _LIST_ENTRY 0X593510
ntdll!_LIST_ENTRY
[ 0x5935a0 - 0x77d9020c ]
+0x000 Flink : 0x005935a0 _LIST_ENTRY [ 0x593920 - 0x593510 ]
+0x004 Blink : 0x77d9020c _LIST_ENTRY [ 0x593510 - 0x5941a8 ]
0:000> dt _LIST_ENTRY 0X5935a0
ntdll!_LIST_ENTRY
[ 0x593920 - 0x593510 ]
+0x000 Flink : 0x00593920 _LIST_ENTRY [ 0x593a38 - 0x5935a0 ]
+0x004 Blink : 0x00593510 _LIST_ENTRY [ 0x5935a0 - 0x77d9020c ]
0:000> dt _LIST_ENTRY 0X593920
ntdll!_LIST_ENTRY
[ 0x593a38 - 0x5935a0 ]
+0x000 Flink : 0x00593a38 _LIST_ENTRY [ 0x5941a8 - 0x593920 ]
+0x004 Blink : 0x005935a0 _LI