Peb(Process Environment Block)简单学习及分析
文章目录
- 1. PEB结构初探
- 2. Peb应用程序代码
参考资料:
Google peb site:pediy.com
PEB结构——枚举用户模块列表
修改已加载DLL的模块名和路径
PEB结构初探
windows系统中通过各种结构来管理各个对象,关于进程线程的PEB、TEB、EPROCESS等,这几个结构的关系如下图
而PEB(Process Environment Block)——进程环境块使用较多,并且我们可以找到很多关于PEB的资料并且用处也很大,它包含了映像加载器、堆管理器和其他的windows系统DLL所需要的信息,因为它们需要在用户模式下修改PEB中的信息,所以必须位于用户空间。PEB存放进程信息,每个进程都有自己的 PEB 信息。准确的 PEB 地址应从系统的 EPROCESS 结构的 1b0H 偏移处获得,但由于 EPROCESS在进程的核心内存区,所以程序不能直接访问。但是由上面的关系图可以发现TEB也指向PEB结构同时位于用户空间并且可以很方便的获得,可以通过CPU的FS寄存器来访问TEB,一般存储在[FS:0],在TEB结构偏移30H处可以获得PEB位置
1 2 3 4 5 |
__asm { mov eax,fs:[0x30] mov PEB,eax } |
除此之外还可以通过以下方式获得PEB结构
- 在内核中我们可以先PsGetCurrentProcess得到当前进程的EPROCESS,然后通过它的成员域PEB访问到当前进程
- 在内核中,我们可以通过KPRCB获得当前线程的ETHREAD,然后通过它的成员域来访问当TEB,然后再通过TEB的成员域来访问PEB
##PEB结构体
###_PEB
上图是PEB结构各个元素关系图,可以对PEB结构有个初步认识同时也可以看到这个结构较为复杂成员较多。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
MSDN文档中结构体不是很详细,所以PEB结构现在也属于一个未公开结构体。 32位系统 typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; 标识当前进程是否被调试,在反调试 BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved4[104]; PVOID Reserved5[52]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved6[128]; PVOID Reserved7[1]; ULONG SessionId; } PEB, *PPEB; 64位系统 typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[21]; PPEB_LDR_DATA LoaderData; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved3[520]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved4[136]; ULONG SessionId; } PEB; 根据reactos来的结构定义 typedef struct _PEB { +0x000 BOOLEAN InheritedAddressSpace; +0x001 BOOLEAN ReadImageFileExecOptions; +0x002 BOOLEAN BeingDebugged; 标志当前进程是否被调试 +0x003 BOOLEAN Spare; +0x004 HANDLE Mutant; +0x008 PVOID ImageBaseAddress; 进程的映像基地址,exe 0x400000,dll 0x1000000 +0x00c PPEB_LDR_DATA LoaderData; 由PE Loader填充,包含很多pe中包含的信息,用来枚举用户加载的模块 +0x010 PRTL_USER_PROCESS_PARAMETERS ProcessParameters; 指向 RTL_USER_PROCESS_PARAMETERS 的指针,RTL_USER_PROCESS_PARAMETERS 中是一些进程的参数。 +0x014 PVOID SubSystemData; PVOID ProcessHeap; 指向进程堆首地址,每个程序新建时默认堆使用 PVOID FastPebLock; 存放的是PEBLOCKROUTINE这个例程函数需要用到的参数。 PPEBLOCKROUTINE FastPebLockRoutine; PEB加锁/解锁回调例程 PPEBLOCKROUTINE FastPebUnlockRoutine; ULONG EnvironmentUpdateCount; 进程的环境变量更改的次数 PPVOID KernelCallbackTable; 从内核“回调”用户空间的函数 PVOID EventLogSection; PVOID EventLog; PPEB_FREE_BLOCK FreeList; ULONG TlsExpansionCounter; PVOID TlsBitmap; 域代表TLS位图 ULONG TlsBitmapBits[0x2]; PVOID ReadOnlySharedMemoryBase; PVOID ReadOnlySharedMemoryHeap; PPVOID ReadOnlyStaticServerData; PVOID AnsiCodePageData; PVOID OemCodePageData; PVOID UnicodeCaseTableData; ULONG NumberOfProcessors; ULONG NtGlobalFlag; BYTE Spare2[0x4]; LARGE_INTEGER CriticalSectionTimeout; ULONG HeapSegmentReserve; ULONG HeapSegmentCommit; ULONG HeapDeCommitTotalFreeThreshold; ULONG HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; PPVOID *ProcessHeaps; PVOID GdiSharedHandleTable; PVOID ProcessStarterHelper; PVOID GdiDCAttributeList; PVOID LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; ULONG OSBuildNumber; ULONG OSPlatformId; ULONG ImageSubSystem; ULONG ImageSubSystemMajorVersion; ULONG ImageSubSystemMinorVersion; ULONG GdiHandleBuffer[0x22]; ULONG PostProcessInitRoutine; ULONG TlsExpansionBitmap; BYTE TlsExpansionBitmapBits[0x80]; ULONG SessionId; } PEB, *PPEB; |
由上面结构体中可以发现PEB结构成员众多且还属于未公开结构体,但是微软也公开了一些结构。其中PPEB_LDR_DATA是本篇主要讨论的
###PPEB_LDR_DATA
msdn.aspx)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
typedef struct _PEB_LDR_DATA { BYTE Reserved1[8]; PVOID Reserved2[3]; LIST_ENTRY InMemoryOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA; ReactOS 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 _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY; 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——->PEB_LDR_DATA———>LDR_MODULE的过程,LDR_MODULE中容纳的是进程中各个dll的信息最后通过LIST_ENTRY形成双向链表将各个dll信息连接起来。我们就可以通过上面的方式找到各个dll模块然后将信息打印出来,形成自己的模块遍历程序。
同时我们也可以通过修改或则删除某些dll模块信息达到隐藏dll目的。
Peb应用程序代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
//AboutPeb.h #ifndef _ABOUT_PEB_ #define _ABOUT_PEB_ #include |
——————————————-代码—————————————————-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
// AboutPeb.cpp : 定义控制台应用程序的入口点。 // #include "StdAfx.h" #include "AboutPeb.h" #include |