PEB的深入学习
前言
纯属是之前乱弄shellcode编写的时候看见的PEB,然后当时做了笔记。不是很熟悉PEB这个,打算在了解一下。
PEB是什么
进程环境块(PEB)是 Windows NT操作系统内部使用的数据结构,用以存储每个进程的运行时数据。[1] Microsoft的MSDN文档中仅公开了PEB的少数几个域,该结构“在未来的Windows版本中可能会修改”。[2]PEB包含的数据结构适用于整个进程,如全局上下文,启动参数,程序image装载器的数据结构,程序image的基地址,进程级互斥同步访问对象等。[1]
PEB与kernel mode EPROCESS数据结构密切相关。也是逐进程数据结构,在客户-服务器运行时子系统(CSRSS)进程地址空间被管理。但是,类似于CSRSS数据结构,PEB自身并不是内核模式数据结构。它驻留在所关联的进程的用户态内存空间中。这是因为它被设计为被操作系统的用户态的程序所使用,如NTDLL,在内核态之外执行,如程序映象的加载器与堆管理器。[3]
WinDbg中,卸载PEB内容的命令是!peb,命令参数是PEB在进程地址空间的地址,它实际上是通过!process命令获取,将显示来自于EPROCESS数据结构的信息,其中一个域是PEB地址。[3]
准备工具
windbg
od
vs
实验过程
用汇编写一段寻找PEB地址的指令,然后编译逐渐调试。
global _start
section .text
_start:
mov eax,[fs:0x30] ;EAX=PEB
mov eax,[eax+0xc] ;EAX=PEB->Ldr
mov esi,[eax+0x14] ;ESI=PEB->Ldr.InMemOrder (Ldr.InMemOrder地址赋到ESI寄存器)
lodsd ;ESI内存地址指向的值写入到EAX EAX=Second module (进入链表:Flink : Ptr32 _LIST_ENTR)->进入Ldr.InMemOrder链表的的一个元素位地址
xchg eax,esi ;EAX和ESI交换值 EAX=ESI,ESI=EAX (EAX=Ldr.InMemOrder->链表第一元素位的地址,然后从EAX和ESI互相切换值)
lodsd ;EAX=Third(Kernel32)
mov ebx,[eax+0x10] ;EBX=Kernel32基地址
mov edx,[ebx+0x3c] ;EDX = DOS->e_lfanew (DOS头偏移地址)
add edx,ebx ;PE头地址获取
mov edx,[edx+0x78] ;IMAGE_EXPORT_DIRECTORY
add edx,ebx ;EDX = Export table
mov esi, [edx + 0x20] ; ESI = Offset namestable
add esi, ebx ; ESI = Names table
xor ecx, ecx ; EXC = 0
yasm和golink编译成exe
yasm.win32.exe -f win32 -o test.obj test.asm
Golink /ni /entry _start shell.obj
然后拖入windbg调,自动解析PEB!peb
- InheritedAddressSpace: 继承的地址空间
- ReadImageFileExecOptions: 读取文件镜像执行选项
- BeingDebugged: 是否在被调试
- ImageBaseAddress: 镜像基本的地址
- Ldr: (到PEB_LDR_DATA结构的指针,提供被加载模块的信息。)包含kernel32 与ntdll的基地址
- SubSystemData: 子系统数据
- ProcessHeap: 进程堆栈首地址
- ProcessParameters: 进程参数地址
- CurrentDirectory: 当前目录
- WindowTitle: 窗口标题
- ImageFile: 镜像我呢见
- CommandLine: 命令行
- DllPath: DLL路径
- Environment: 环境
手动解析PEBdt _PEB @$peb
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
+0x003 BitField : 0 ''
+0x003 ImageUsesLargePages : 0y0
+0x003 IsProtectedProcess : 0y0
+0x003 IsImageDynamicallyRelocated : 0y0
+0x003 SkipPatchingUser32Forwarders : 0y0
+0x003 IsPackagedProcess : 0y0
+0x003 IsAppContainer : 0y0
+0x003 IsProtectedProcessLight : 0y0
+0x003 IsLongPathAwareProcess : 0y0
+0x004 Mutant : 0xffffffff Void
+0x008 ImageBaseAddress : 0x00400000 Void
+0x00c Ldr : 0x7750dca0 _PEB_LDR_DATA
+0x010 ProcessParameters : 0x004b1d38 _RTL_USER_PROCESS_PARAMETERS
+0x014 SubSystemData : (null)
+0x018 ProcessHeap : 0x004b0000 Void
+0x01c FastPebLock : 0x7750da60 _RTL_CRITICAL_SECTION
+0x020 AtlThunkSListPtr : (null)
+0x024 IFEOKey : (null)
+0x028 CrossProcessFlags : 3
+0x028 ProcessInJob : 0y1
+0x028 ProcessInitializing : 0y1
+0x028 ProcessUsingVEH : 0y0
+0x028 ProcessUsingVCH : 0y0
+0x028 ProcessUsingFTH : 0y0
+0x028 ProcessPreviouslyThrottled : 0y0
+0x028 ProcessCurrentlyThrottled : 0y0
+0x028 ProcessImagesHotPatched : 0y0
+0x028 ReservedBits0 : 0y000000000000000000000000 (0)
+0x02c KernelCallbackTable : (null)
+0x02c UserSharedInfoPtr : (null)
+0x030 SystemReserved : 0
+0x034 AtlThunkSListPtr32 : (null)
+0x038 ApiSetMap : 0x00040000 Void
+0x03c TlsExpansionCounter : 0
+0x040 TlsBitmap : 0x7750dc50 Void
+0x044 TlsBitmapBits : [2] 0x10001
+0x04c ReadOnlySharedMemoryBase : 0x7fe40000 Void
+0x050 SharedData : (null)
+0x054 ReadOnlyStaticServerData : 0x7fe40750 -> (null)
+0x058 AnsiCodePageData : 0x7ffa0000 Void
+0x05c OemCodePageData : 0x7ffa0000 Void
+0x060 UnicodeCaseTableData : 0x7ffd0028 Void
+0x064 NumberOfProcessors : 0xc
+0x068 NtGlobalFlag : 0x70
+0x070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
+0x078 HeapSegmentReserve : 0x100000
+0x07c HeapSegmentCommit : 0x2000
+0x080 HeapDeCommitTotalFreeThreshold : 0x10000
+0x084 HeapDeCommitFreeBlockThreshold : 0x1000
+0x088 NumberOfHeaps : 1
+0x08c MaximumNumberOfHeaps : 0x10
+0x090 ProcessHeaps : 0x7750c760 -> 0x004b0000 Void
+0x094 GdiSharedHandleTable : (null)
+0x098 ProcessStarterHelper : (null)
+0x09c GdiDCAttributeList : 0
+0x0a0 LoaderLock : 0x7750b3d0 _RTL_CRITICAL_SECTION
+0x0a4 OSMajorVersion : 0xa
+0x0a8 OSMinorVersion : 0
+0x0ac OSBuildNumber : 0x47bb
+0x0ae OSCSDVersion : 0
+0x0b0 OSPlatformId : 2
+0x0b4 ImageSubsystem : 2
+0x0b8 ImageSubsystemMajorVersion : 4
+0x0bc ImageSubsystemMinorVersion : 0
+0x0c0 ActiveProcessAffinityMask : 0xfff
+0x0c4 GdiHandleBuffer : [34] 0
+0x14c PostProcessInitRoutine : (null)
+0x150 TlsExpansionBitmap : 0x7750dc38 Void
+0x154 TlsExpansionBitmapBits : [32] 1
+0x1d4 SessionId : 1
+0x1d8 AppCompatFlags : _ULARGE_INTEGER 0x0
+0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER 0x0
+0x1e8 pShimData : 0x001b0000 Void
+0x1ec AppCompatInfo : (null)
+0x1f0 CSDVersion : _UNICODE_STRING ""
+0x1f8 ActivationContextData : (null)
+0x1fc ProcessAssemblyStorageMap : (null)
+0x200 SystemDefaultActivationContextData : 0x001a0000 _ACTIVATION_CONTEXT_DATA
+0x204 SystemAssemblyStorageMap : (null)
+0x208 MinimumStackCommit : 0
+0x20c SparePointers : [4] (null)
+0x21c SpareUlongs : [5] 0
+0x230 WerRegistrationData : (null)
+0x234 WerShipAssertPtr : (null)
+0x238 pUnused : (null)
+0x23c pImageHeaderHash : (null)
+0x240 TracingFlags : 0
+0x240 HeapTracingEnabled : 0y0
+0x240 CritSecTracingEnabled : 0y0
+0x240 LibLoaderTracingEnabled : 0y0
+0x240 SpareTracingBits : 0y00000000000000000000000000000 (0)
+0x248 CsrServerReadOnlySharedMemoryBase : 0x00007df4`2f970000
+0x250 TppWorkerpListLock : 0
+0x254 TppWorkerpList : _LIST_ENTRY [ 0x276254 - 0x276254 ]
+0x25c WaitOnAddressHashTable : [128] (null)
+0x45c TelemetryCoverageHeader : (null)
+0x460 CloudFileFlags : 0x60
+0x464 CloudFileDiagFlags : 0
+0x468 PlaceholderCompatibilityMode : 1 ''
+0x469 PlaceholderCompatibilityModeReserved : [7] ""
+0x470 LeapSecondData : 0x7ff90000 _LEAP_SECOND_DATA
+0x474 LeapSecondFlags : 0
+0x474 SixtySecondEnabled : 0y0
+0x474 Reserved : 0y0000000000000000000000000000000 (0)
+0x478 NtGlobalFlag2 : 0
这里比较重要的是Ldr,(PEB_LDR_DATA结构的指针,提供被加载模块的信息。)
Ldr分析
+0x000 Length : 0x30
+0x004 Initialized : 0x1 ''
+0x008 SsHandle : (null)
+0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x4b3720 - 0x4b3d30 ] //按加载顺序
+0x014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x4b3728 - 0x4b3d38 ] //按内存顺序
+0x01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x4b3628 - 0x4b3d40 ] //按初始化顺序
+0x024 EntryInProgress : (null)
+0x028 ShutdownInProgress : 0 ''
+0x02c ShutdownThreadId : (null)
InLoadOrderModuleList、InMemoryOrderModuleList、InMemoryOrderModuleList这三个是双向链表
(其实三个都一样,顺序不同而已)
对应的格式为 LIST_ENTRY
0:000> dt _LIST_ENTRY
ntdll!_LIST_ENTRY
+0x000 Flink : Ptr32 _LIST_ENTRY
+0x004 Blink : Ptr32 _LIST_ENTRY
LDR_DATA_TABLE_ENTRY structure,双向循环链表吧,从一个方向开始,不停的循环,就回到初始位了,就相当于遍历了一次
结构如下
0:000> dt _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x008 InMemoryOrderLinks : _LIST_ENTRY
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x018 DllBase : Ptr32 Void
+0x01c EntryPoint : Ptr32 Void
+0x020 SizeOfImage : Uint4B
+0x024 FullDllName : _UNICODE_STRING
+0x02c BaseDllName : _UNICODE_STRING
+0x034 FlagGroup : [4] UChar
+0x034 Flags : Uint4B
+0x034 PackagedBinary : Pos 0, 1 Bit
+0x034 MarkedForRemoval : Pos 1, 1 Bit
+0x034 ImageDll : Pos 2, 1 Bit
+0x034 LoadNotificationsSent : Pos 3, 1 Bit
+0x034 TelemetryEntryProcessed : Pos 4, 1 Bit
+0x034 ProcessStaticImport : Pos 5, 1 Bit
+0x034 InLegacyLists : Pos 6, 1 Bit
+0x034 InIndexes : Pos 7, 1 Bit
+0x034 ShimDll : Pos 8, 1 Bit
+0x034 InExceptionTable : Pos 9, 1 Bit
+0x034 ReservedFlags1 : Pos 10, 2 Bits
+0x034 LoadInProgress : Pos 12, 1 Bit
+0x034 LoadConfigProcessed : Pos 13, 1 Bit
+0x034 EntryProcessed : Pos 14, 1 Bit
+0x034 ProtectDelayLoad : Pos 15, 1 Bit
+0x034 ReservedFlags3 : Pos 16, 2 Bits
+0x034 DontCallForThreads : Pos 18, 1 Bit
+0x034 ProcessAttachCalled : Pos 19, 1 Bit
+0x034 ProcessAttachFailed : Pos 20, 1 Bit
+0x034 CorDeferredValidate : Pos 21, 1 Bit
+0x034 CorImage : Pos 22, 1 Bit
+0x034 DontRelocate : Pos 23, 1 Bit
+0x034 CorILOnly : Pos 24, 1 Bit
+0x034 ChpeImage : Pos 25, 1 Bit
+0x034 ReservedFlags5 : Pos 26, 2 Bits
+0x034 Redirected : Pos 28, 1 Bit
+0x034 ReservedFlags6 : Pos 29, 2 Bits
+0x034 CompatDatabaseProcessed : Pos 31, 1 Bit
+0x038 ObsoleteLoadCount : Uint2B
+0x03a TlsIndex : Uint2B
+0x03c HashLinks : _LIST_ENTRY
+0x044 TimeDateStamp : Uint4B
+0x048 EntryPointActivationContext : Ptr32 _ACTIVATION_CONTEXT
+0x04c Lock : Ptr32 Void
+0x050 DdagNode : Ptr32 _LDR_DDAG_NODE
+0x054 NodeModuleLink : _LIST_ENTRY
+0x05c LoadContext : Ptr32 _LDRP_LOAD_CONTEXT
+0x060 ParentDllBase : Ptr32 Void
+0x064 SwitchBackContext : Ptr32 Void
+0x068 BaseAddressIndexNode : _RTL_BALANCED_NODE
+0x074 MappingInfoIndexNode : _RTL_BALANCED_NODE
+0x080 OriginalBase : Uint4B
+0x088 LoadTime : _LARGE_INTEGER
+0x090 BaseNameHashValue : Uint4B
+0x094 LoadReason : _LDR_DLL_LOAD_REASON
+0x098 ImplicitPathOptions : Uint4B
+0x09c ReferenceCount : Uint4B
+0x0a0 DependentLoadFlags : Uint4B
+0x0a4 SigningLevel : UChar
跟上面的汇编一样找InMemoryOrderModuleList来遍历0x4b3728 - 0x4b3d38
这个地址范围里存着对应的内存顺序载入过程
0:000> dt 0x4b3728 _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x4b3620 - 0x7750dcb4 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x400000 - 0x401000 ]
+0x018 DllBase : 0x00002000 Void
+0x01c EntryPoint : 0x00620060 Void
+0x020 SizeOfImage : 0x4b21fc
+0x024 FullDllName : _UNICODE_STRING "test.exe"
+0x02c BaseDllName : _UNICODE_STRING "--- memory read error at address 0x0000ffff ---"
+0x034 FlagGroup : [4] "P???"
+0x034 Flags : 0x7750db50
+0x034 PackagedBinary : 0y0
+0x034 MarkedForRemoval : 0y0
+0x034 ImageDll : 0y0
+0x034 LoadNotificationsSent : 0y0
+0x034 TelemetryEntryProcessed : 0y1
+0x034 ProcessStaticImport : 0y0
+0x034 InLegacyLists : 0y1
+0x034 InIndexes : 0y0
+0x034 ShimDll : 0y1
+0x034 InExceptionTable : 0y1
+0x034 ReservedFlags1 : 0y10
+0x034 LoadInProgress : 0y1
+0x034 LoadConfigProcessed : 0y0
+0x034 EntryProcessed : 0y1
+0x034 ProtectDelayLoad : 0y1
+0x034 ReservedFlags3 : 0y00
+0x034 DontCallForThreads : 0y0
+0x034 ProcessAttachCalled : 0y0
+0x034 ProcessAttachFailed : 0y1
+0x034 CorDeferredValidate : 0y0
+0x034 CorImage : 0y1
+0x034 DontRelocate : 0y0
+0x034 CorILOnly : 0y1
+0x034 ChpeImage : 0y1
+0x034 ReservedFlags5 : 0y01
+0x034 Redirected : 0y1
+0x034 ReservedFlags6 : 0y11
+0x034 CompatDatabaseProcessed : 0y0
+0x038 ObsoleteLoadCount : 0xdb50
+0x03a TlsIndex : 0x7750
+0x03c HashLinks : _LIST_ENTRY [ 0x6032501a - 0x0 ]
+0x044 TimeDateStamp : 0
+0x048 EntryPointActivationContext : 0x004b37e0 _ACTIVATION_CONTEXT
+0x04c Lock : 0x004b37e0 Void
+0x050 DdagNode : 0x004b37e0 _LDR_DDAG_NODE
+0x054 NodeModuleLink : _LIST_ENTRY [ 0x19fa64 - 0x0 ]
+0x05c LoadContext : 0x773f1124 _LDRP_LOAD_CONTEXT
+0x060 ParentDllBase : (null)
+0x064 SwitchBackContext : 0x004b3d98 Void
+0x068 BaseAddressIndexNode : _RTL_BALANCED_NODE
+0x074 MappingInfoIndexNode : _RTL_BALANCED_NODE
+0x080 OriginalBase : 0xf9727ce2
+0x088 LoadTime : _LARGE_INTEGER 0x00000004`33df1536
+0x090 BaseNameHashValue : 0
+0x094 LoadReason : 2 ( LoadReasonDynamicForwarderDependency )
+0x098 ImplicitPathOptions : 0
+0x09c ReferenceCount : 0
+0x0a0 DependentLoadFlags : 0xabababab
+0x0a4 SigningLevel : 0xab ''
然后通过不断遍历链表元素里的InLoadOrderLinks,最后找到kernel32.dll
0:000> dt 0x4b3728 _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x4b3620 - 0x7750dcb4 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x400000 - 0x401000 ]
+0x018 DllBase : 0x00002000 Void
+0x01c EntryPoint : 0x00620060 Void
+0x020 SizeOfImage : 0x4b21fc
+0x024 FullDllName : _UNICODE_STRING "test.exe"
+0x02c BaseDllName : _UNICODE_STRING "--- memory read error at address 0x0000ffff ---"
+0x034 FlagGroup : [4] "P???"
+0x034 Flags : 0x7750db50
+0x034 PackagedBinary : 0y0
+0x034 MarkedForRemoval : 0y0
+0x034 ImageDll : 0y0
+0x034 LoadNotificationsSent : 0y0
+0x034 TelemetryEntryProcessed : 0y1
+0x034 ProcessStaticImport : 0y0
+0x034 InLegacyLists : 0y1
+0x034 InIndexes : 0y0
+0x034 ShimDll : 0y1
+0x034 InExceptionTable : 0y1
+0x034 ReservedFlags1 : 0y10
+0x034 LoadInProgress : 0y1
+0x034 LoadConfigProcessed : 0y0
+0x034 EntryProcessed : 0y1
+0x034 ProtectDelayLoad : 0y1
+0x034 ReservedFlags3 : 0y00
+0x034 DontCallForThreads : 0y0
+0x034 ProcessAttachCalled : 0y0
+0x034 ProcessAttachFailed : 0y1
+0x034 CorDeferredValidate : 0y0
+0x034 CorImage : 0y1
+0x034 DontRelocate : 0y0
+0x034 CorILOnly : 0y1
+0x034 ChpeImage : 0y1
+0x034 ReservedFlags5 : 0y01
+0x034 Redirected : 0y1
+0x034 ReservedFlags6 : 0y11
+0x034 CompatDatabaseProcessed : 0y0
+0x038 ObsoleteLoadCount : 0xdb50
+0x03a TlsIndex : 0x7750
+0x03c HashLinks : _LIST_ENTRY [ 0x6032501a - 0x0 ]
+0x044 TimeDateStamp : 0
+0x048 EntryPointActivationContext : 0x004b37e0 _ACTIVATION_CONTEXT
+0x04c Lock : 0x004b37e0 Void
+0x050 DdagNode : 0x004b37e0 _LDR_DDAG_NODE
+0x054 NodeModuleLink : _LIST_ENTRY [ 0x19fa64 - 0x0 ]
+0x05c LoadContext : 0x773f1124 _LDRP_LOAD_CONTEXT
+0x060 ParentDllBase : (null)
+0x064 SwitchBackContext : 0x004b3d98 Void
+0x068 BaseAddressIndexNode : _RTL_BALANCED_NODE
+0x074 MappingInfoIndexNode : _RTL_BALANCED_NODE
+0x080 OriginalBase : 0xf9727ce2
+0x088 LoadTime : _LARGE_INTEGER 0x00000004`33df1536
+0x090 BaseNameHashValue : 0
+0x094 LoadReason : 2 ( LoadReasonDynamicForwarderDependency )
+0x098 ImplicitPathOptions : 0
+0x09c ReferenceCount : 0
+0x0a0 DependentLoadFlags : 0xabababab
+0x0a4 SigningLevel : 0xab ''
0:000> dt 0x4b3620 _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x4b3b08 - 0x4b3728 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x4b3ed0 - 0x7750dcbc ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x773f0000 - 0x0 ]
+0x018 DllBase : 0x0019a000 Void
+0x01c EntryPoint : 0x003c003a Void
+0x020 SizeOfImage : 0x4b34f8
+0x024 FullDllName : _UNICODE_STRING "ntdll.dll"
+0x02c BaseDllName : _UNICODE_STRING "--- memory read error at address 0x0000ffff ---"
+0x034 FlagGroup : [4] "@???"
+0x034 Flags : 0x7750db40
+0x034 PackagedBinary : 0y0
+0x034 MarkedForRemoval : 0y0
+0x034 ImageDll : 0y0
+0x034 LoadNotificationsSent : 0y0
+0x034 TelemetryEntryProcessed : 0y0
+0x034 ProcessStaticImport : 0y0
+0x034 InLegacyLists : 0y1
+0x034 InIndexes : 0y0
+0x034 ShimDll : 0y1
+0x034 InExceptionTable : 0y1
+0x034 ReservedFlags1 : 0y10
+0x034 LoadInProgress : 0y1
+0x034 LoadConfigProcessed : 0y0
+0x034 EntryProcessed : 0y1
+0x034 ProtectDelayLoad : 0y1
+0x034 ReservedFlags3 : 0y00
+0x034 DontCallForThreads : 0y0
+0x034 ProcessAttachCalled : 0y0
+0x034 ProcessAttachFailed : 0y1
+0x034 CorDeferredValidate : 0y0
+0x034 CorImage : 0y1
+0x034 DontRelocate : 0y0
+0x034 CorILOnly : 0y1
+0x034 ChpeImage : 0y1
+0x034 ReservedFlags5 : 0y01
+0x034 Redirected : 0y1
+0x034 ReservedFlags6 : 0y11
+0x034 CompatDatabaseProcessed : 0y0
+0x038 ObsoleteLoadCount : 0xdb40
+0x03a TlsIndex : 0x7750
+0x03c HashLinks : _LIST_ENTRY [ 0x1e699fab - 0x0 ]
+0x044 TimeDateStamp : 0
+0x048 EntryPointActivationContext : 0x004b36d8 _ACTIVATION_CONTEXT
+0x04c Lock : 0x004b36d8 Void
+0x050 DdagNode : 0x004b36d8 _LDR_DDAG_NODE
+0x054 NodeModuleLink : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x05c LoadContext : (null)
+0x060 ParentDllBase : 0x004b3f28 Void
+0x064 SwitchBackContext : (null)
+0x068 BaseAddressIndexNode : _RTL_BALANCED_NODE
+0x074 MappingInfoIndexNode : _RTL_BALANCED_NODE
+0x080 OriginalBase : 0xf9727ce2
+0x088 LoadTime : _LARGE_INTEGER 0xf46857d4
+0x090 BaseNameHashValue : 0
+0x094 LoadReason : 2 ( LoadReasonDynamicForwarderDependency )
+0x098 ImplicitPathOptions : 0x800
+0x09c ReferenceCount : 0
+0x0a0 DependentLoadFlags : 0xabababab
+0x0a4 SigningLevel : 0xab ''
0:000> dt 0x4b3b08 _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x4b3ec8 - 0x4b3620 ]
+0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x4b3d40 - 0x4b3ed0 ]
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x75f50000 - 0x75f65f70 ]
+0x018 DllBase : 0x000e0000 Void
+0x01c EntryPoint : 0x00420040 Void
+0x020 SizeOfImage : 0x4b3c08
+0x024 FullDllName : _UNICODE_STRING "KERNEL32.DLL"
+0x02c BaseDllName : _UNICODE_STRING "--- memory read error at address 0x0000ffff ---"
+0x034 FlagGroup : [4] "0???"
+0x034 Flags : 0x7750db30
+0x034 PackagedBinary : 0y0
+0x034 MarkedForRemoval : 0y0
+0x034 ImageDll : 0y0
+0x034 LoadNotificationsSent : 0y0
+0x034 TelemetryEntryProcessed : 0y1
+0x034 ProcessStaticImport : 0y1
+0x034 InLegacyLists : 0y0
+0x034 InIndexes : 0y0
+0x034 ShimDll : 0y1
+0x034 InExceptionTable : 0y1
+0x034 ReservedFlags1 : 0y10
+0x034 LoadInProgress : 0y1
+0x034 LoadConfigProcessed : 0y0
+0x034 EntryProcessed : 0y1
+0x034 ProtectDelayLoad : 0y1
+0x034 ReservedFlags3 : 0y00
+0x034 DontCallForThreads : 0y0
+0x034 ProcessAttachCalled : 0y0
+0x034 ProcessAttachFailed : 0y1
+0x034 CorDeferredValidate : 0y0
+0x034 CorImage : 0y1
+0x034 DontRelocate : 0y0
+0x034 CorILOnly : 0y1
+0x034 ChpeImage : 0y1
+0x034 ReservedFlags5 : 0y01
+0x034 Redirected : 0y1
+0x034 ReservedFlags6 : 0y11
+0x034 CompatDatabaseProcessed : 0y0
+0x038 ObsoleteLoadCount : 0xdb30
+0x03a TlsIndex : 0x7750
+0x03c HashLinks : _LIST_ENTRY [ 0x59b71f87 - 0x0 ]
+0x044 TimeDateStamp : 0
+0x048 EntryPointActivationContext : 0x004b3bc0 _ACTIVATION_CONTEXT
+0x04c Lock : 0x004b3bc0 Void
+0x050 DdagNode : 0x004b3bc0 _LDR_DDAG_NODE
+0x054 NodeModuleLink : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x05c LoadContext : 0x773f1194 _LDRP_LOAD_CONTEXT
+0x060 ParentDllBase : 0x004b3788 Void
+0x064 SwitchBackContext : 0x004b3680 Void
+0x068 BaseAddressIndexNode : _RTL_BALANCED_NODE
+0x074 MappingInfoIndexNode : _RTL_BALANCED_NODE
+0x080 OriginalBase : 0xf9727ce2
+0x088 LoadTime : _LARGE_INTEGER 0x00000004`536cd652
+0x090 BaseNameHashValue : 0x4000
+0x094 LoadReason : 2 ( LoadReasonDynamicForwarderDependency )
+0x098 ImplicitPathOptions : 0
+0x09c ReferenceCount : 0
+0x0a0 DependentLoadFlags : 0xabababab
+0x0a4 SigningLevel : 0xab ''
对面上面的汇编
mov eax,[fs:0x30] ;EAX=PEB
mov eax,[eax+0xc] ;EAX=PEB->Ldr
mov esi,[eax+0x14] ;ESI=PEB->Ldr.InMemOrder (Ldr.InMemOrder地址赋到ESI寄存器)
lodsd ;ESI内存地址指向的值写入到EAX EAX=Second module (进入链表:Flink : Ptr32 _LIST_ENTR)->进入Ldr.InMemOrder链表的的一个元素位地址
xchg eax,esi ;EAX和ESI交换值 EAX=ESI,ESI=EAX (EAX=Ldr.InMemOrder->链表第一元素位的地址,然后从EAX和ESI互相切换值)
lodsd ;EAX=Third(Kernel32)
mov ebx,[eax+0x10] ;EBX=Kernel32基地址
最后对应的0x10链表首地址放的即为kernel32.dll的基址
+0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x75f50000 - 0x75f65f70 ]
其实可以简写成别的(lodsd看起来容易把人搞混)
mov eax, fs:[0x30] //得到PEB地址,其实这里还有个TEB的概念,但是只用到这一次,为了防止混乱,就不再解释了
mov eax, [eax + 0xc]//指向PEB_LDR_DATA结构的首地址
mov eax, [eax + 0x1c]//一个双向链表的地址
mov eax, [eax]//得到第二个条目kernelBase的链表
mov eax, [eax]//得到第三个条目kernel32链表(win10)
mov eax, [eax + 0x8] //kernel32.dll地址
对应0x8链表里的kernel32.dll基址
在内存里的过程
可以使用OD进行验证,od拖入test.exe。然后在堆栈窗口ctrl+G输入fs:[0]
跳到所在位置
执行mov eax,fs[0x30]
后
执行mov eax, [eax + 0xc]
得到LDR地址
(得到PEB地址后,在内存窗口ctrl+G输入PEB的地址,选择”长型”->”地址”)
执行lodsd ;ESI内存地址指向的值写入到EAX EAX=Second module (进入链表:Flink : Ptr32 _LIST_ENTR)->进入Ldr.InMemOrder链表的的一个元素位地址
得到链表里的第一个Flink的地址
(数据窗口选择刚刚的InMemoryOrderModuleList地址,选择”数据窗口跟随”)
继续执行
xchg eax,esi ;EAX和ESI交换值 EAX=ESI,ESI=EAX (EAX=Ldr.InMemOrder->链表第一元素位的地址,然后从EAX和ESI互相切换值)
lodsd ;EAX=Third(Kernel32)
如何用C实现?
1.直接用汇编返回对PEB地址然后根据微软给的数据结构解析即可
2.直接用给出的数据结构来解析 (好像可以这么写)
第一种方法
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
int main()
{
DWORD PPEB;
DWORD LLDR;
DWORD dllbase;
DWORD initlist;
DWORD virtualaddress;
PCHAR dllname;
char *kernel32dllname = "KERNEL32.dll";
PIMAGE_DOS_HEADER dosheader;
PIMAGE_NT_HEADERS ntheader;
PIMAGE_EXPORT_DIRECTORY exportdirectory;
__asm {
mov eax, fs:[0x30];EAX = PEB
mov PPEB,eax
}
LLDR = *(PDWORD)(PPEB + 0xc); //LDR
printf("PEB Address:0x%x\n", PPEB);
initlist=*(PDWORD)(LLDR+0x1c); //LDR->InInitializationOrderModuleList
CHAR szGetProcAddr[]="GetProcAddress";
CHAR szLoadLib[]="LoadLibraryA";
for (;dllbase = *(PDWORD)(initlist + 0x8);initlist = *(PDWORD)initlist) { //遍历InMemoryOrderLinks链表
dosheader = (PIMAGE_DOS_HEADER)dllbase; //DOS头部
ntheader = (PIMAGE_NT_HEADERS)(dllbase+dosheader->e_lfanew); //PE头部
virtualaddress = ntheader->OptionalHeader.DataDirectory[0].VirtualAddress; //EXPORT_DIRECTORY
exportdirectory = (PIMAGE_EXPORT_DIRECTORY)(dllbase + virtualaddress); //导出表
dllname = (PCHAR)(dllbase + exportdirectory->Name); //DLL Name
if (!strcmp(dllname, kernel32dllname)) {
printf("%s Address:0x%x\n", kernel32dllname, dllbase);
}
}
system("pause");
return 0;
}
之后就是从kernel32.dll的PE里导出loadlibraryA和GetProcAddress函数的地址。
(下次在写)
参考链接
https://www.jb51.net/article/171962.htm
https://zhuanlan.zhihu.com/p/109079902
https://www.cnblogs.com/lsgxeva/p/10794735.html
https://xz.aliyun.com/t/2108
https://zh.wikipedia.org/wiki/%E8%BF%9B%E7%A8%8B%E7%8E%AF%E5%A2%83%E5%9D%97
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
文章标题:PEB的深入学习
本文作者:九世
发布时间:2021-02-22, 14:26:52
最后更新:2021-02-22, 20:04:03
原始链接:http://jiushill.github.io/posts/165f8274.html版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。