PEB結構----枚舉用戶模塊列表(圖)

PEB結構----枚舉用戶模塊列表(圖)

本文在主主要以上述兩篇文章爲基礎,對PEB的結構進行了詳細的分析,重點是在揭示PEB結構中的list—entry的應用,而且以C語言Code進行實證。

  本文主要分爲四個部分,第一部分說明PEB地址如何得到;第二部分說明PEB的框架結構;第三部對PEB中的List-Entry結構進行了詳細剖析,第四部分給出了枚舉用戶模塊列表的代碼。 windows

  -------------------------------------------------------------------------------------------------------------- 框架

  第一部分:PEB地址的取得 ui

  1.1原理:FS段寄存器指向當前的TEB結構,在TEB偏移0x30處是PEB指針,經過這個指針便可取得PEB的地址。 指針

  1.2實現方法: code

  __asm orm

  { it

  mov eax,fs:[0x30] io

  mov PEB,eax asm

  } ast

  --------------------------------------------------------------------------------------------------------------

  第二部分:PEB的框架結構

  在PEB中的0x0c處爲一指針,指向PEB_LDR_DATA結構,

  在PEB_LDR_DATA的0x0c,0x14,0x1c中爲三個LIST_ENTRY,

  在struct _LDR_MODULE的0x00,0x08和0x10處是三個對應的同名稱的LIST_ENTRY,

  PEB_LDR_DATA和struct _LDR_MODULE就是經過這三個LIST_ENTRY對應鏈接起來的。

  2.1 struct _PEB結構:

  typedef struct _PEB { // Size: 0x1D8

  /*000*/ UCHAR InheritedAddressSpace;

  /*001*/ UCHAR ReadImageFileExecOptions;

  /*002*/ UCHAR BeingDebugged;

  /*003*/ UCHAR SpareBool; // Allocation size

  /*004*/ HANDLE Mutant;

  /*008*/ HINSTANCE ImageBaseAddress; // Instance

  /*00C*/ VOID *DllList;

  /*010*/ PPROCESS_PARAMETERS *ProcessParameters;

  /*014*/ ULONG SubSystemData;

  /*018*/ HANDLE DefaultHeap;

  /*01C*/ KSPIN_LOCK FastPebLock;

  /*020*/ ULONG FastPebLockRoutine;

  /*024*/ ULONG FastPebUnlockRoutine;

  /*028*/ ULONG EnvironmentUpdateCount;

  /*02C*/ ULONG KernelCallbackTable;

  /*030*/ LARGE_INTEGER SystemReserved;

  /*038*/ ULONG FreeList;

  /*03C*/ ULONG TlsExpansionCounter;

  /*040*/ ULONG TlsBitmap;

  /*044*/ LARGE_INTEGER TlsBitmapBits;

  /*04C*/ ULONG ReadOnlySharedMemoryBase;

  /*050*/ ULONG ReadOnlySharedMemoryHeap;

  /*054*/ ULONG ReadOnlyStaticServerData;

  /*058*/ ULONG AnsiCodePageData;

  /*05C*/ ULONG OemCodePageData;

  /*060*/ ULONG UnicodeCaseTableData;

  /*064*/ ULONG NumberOfProcessors;

  /*068*/ LARGE_INTEGER NtGlobalFlag; // Address of a local copy

  /*070*/ LARGE_INTEGER CriticalSectionTimeout;

  /*078*/ ULONG HeapSegmentReserve;

  /*07C*/ ULONG HeapSegmentCommit;

  /*080*/ ULONG HeapDeCommitTotalFreeThreshold;

  /*084*/ ULONG HeapDeCommitFreeBlockThreshold;

  /*088*/ ULONG NumberOfHeaps;

  /*08C*/ ULONG MaximumNumberOfHeaps;

  /*090*/ ULONG ProcessHeaps;

  /*094*/ ULONG GdiSharedHandleTable;

  /*098*/ ULONG ProcessStarterHelper;

  /*09C*/ ULONG GdiDCAttributeList;

  /*0A0*/ KSPIN_LOCK LoaderLock;

  /*0A4*/ ULONG OSMajorVersion;

  /*0A8*/ ULONG OSMinorVersion;

  /*0AC*/ USHORT OSBuildNumber;

  /*0AE*/ USHORT OSCSDVersion;

  /*0B0*/ ULONG OSPlatformId;

  /*0B4*/ ULONG ImageSubsystem;

  /*0B8*/ ULONG ImageSubsystemMajorVersion;

  /*0BC*/ ULONG ImageSubsystemMinorVersion;

  /*0C0*/ ULONG ImageProcessAffinityMask;

  /*0C4*/ ULONG GdiHandleBuffer[0x22];

  /*14C*/ ULONG PostProcessInitRoutine;

  /*150*/ ULONG TlsExpansionBitmap;

  /*154*/ UCHAR TlsExpansionBitmapBits[0x80];

  /*1D4*/ ULONG SessionId;

  } PEB, *PPEB;

  2.2 PEB_LDR_DATA結構

  typedef struct _PEB_LDR_DATA

  {

  ULONG Length; // +0x00

  BOOLEAN Initialized; // +0x04

  PVOID SsHandle; // +0x08

  LIST_ENTRY InLoadOrderModuleList; // +0x0c

  LIST_ENTRY InMemoryOrderModuleList; // +0x14

  LIST_ENTRY InInitializationOrderModuleList;// +0x1c

  } PEB_LDR_DATA,*PPEB_LDR_DATA; // +0x24

  2.3 struct _LDR_MODULE結構

  -typedef struct _LDR_MODULE

  -{

  - LIST_ENTRY InLoadOrderModuleList; +0x00

  - LIST_ENTRY InMemoryOrderModuleList; +0x08

  - LIST_ENTRY InInitializationOrderModuleList; +0x10

  - void* BaseAddress; +0x18

  - void* EntryPoint; +0x1c

  - ULONG SizeOfImage;

  - UNICODE_STRING FullDllName;

  - UNICODE_STRING BaseDllName;

  - ULONG Flags;

  - SHORT LoadCount;

  - SHORT TlsIndex;

  - HANDLE SectionHandle;

  - ULONG CheckSum;

  - ULONG TimeDateStamp;

  -} LDR_MODULE, *PLDR_MODULE;

  --------------------------------------------------------------------------------------------------------------

  第三部分:List-Entry連接

  PEB_LDR_DATA結構的最後三項跟struct _LDR_MODULE結構的前三項是同樣的List-Entry連接,

  InLoadOrderModuleList,InMemoryOrderModuleList,和InInitializationOrderModuleList,

  可是這兩個結構是怎樣連接起來的呢?

  其實,着兩個結果中的三個List-Entry是共用的,以下圖所示:



  --------------------------------------------------------------------------------------------------------------

  第四部分:代碼實現:

  4.1程枚舉用戶模塊列表時,能夠經過如下步驟實現:

  a. 從fs:[30h]獲取PEB地址

  b. 從PEB[0x0c]獲取Ldr地址

  c. 從Ldr[0x0c]獲取InLoadOrderModuleList.Flink\

  InMemoryOrderModuleList\InInitializationOrderModuleList

  d. 從InLoadOrderModuleList.Flink\

  InMemoryOrderModuleList.Flink\InInitializationOrderModuleList.Flink開始前向遍歷循環鏈表

  e. 顯示LDR_MODULE結構的BaseAddress、FullDllName成員。

  4.2如下爲取得InLoadOrderModuleList列表的code

  #include "stdafx.h"

  #include "windows.h"

  #include "winsvc.h"

  int _tmain(int argc, _TCHAR* argv[])

  {

  void *PEB = NULL,

  *Ldr = NULL,

  *Flink = NULL,

  *p = NULL,

  *BaseAddress = NULL,

  *FullDllName = NULL;

  __asm

  {

  mov eax,fs:[0x30]

  mov PEB,eax

  }

  Ldr = *( ( void ** )( ( unsigned char * )PEB+0x0c ) );

  Flink = *( ( void ** )( ( unsigned char * )Ldr+ 0x0c ) );

  p = Flink;

  do

  {

  BaseAddress = *( ( void ** )( ( unsigned char * )p+ 0x18 ) );

  FullDllName = *( ( void ** )( ( unsigned char * )p+ 0x28 ) );

  wprintf(L"FullDllName is %s\n",FullDllName);

  printf("BaseAddress is %x\n",BaseAddress);

  p = *( ( void ** )p);

  }

  while ( Flink != p );

  return 0;

  }

  4.3如下爲取得InMemoryOrderModuleList列表的code

  #include "stdafx.h"

  #include "windows.h"

  #include "winsvc.h"

  int _tmain(int argc, _TCHAR* argv[])

  {

  void *PEB = NULL,

  *Ldr = NULL,

  *Flink = NULL,

  *p = NULL,

  *BaseAddress = NULL,

  *FullDllName = NULL;

  __asm

  {

  mov eax,fs:[0x30]

  mov PEB,eax

  }

  Ldr = *( ( void ** )( ( unsigned char * )PEB+0x0c ) );

  Flink = *( ( void ** )( ( unsigned char * )Ldr+ 0x14 ) );

  p = Flink;

  do

  {

  BaseAddress = *( ( void ** )( ( unsigned char * )p+ 0x10 ) );

  FullDllName = *( ( void ** )( ( unsigned char * )p+ 0x20 ) );

  wprintf(L"FullDllName is %s\n",FullDllName);

  printf("BaseAddress is %x\n",BaseAddress);

  p = *( ( void ** )p);

  }

  while ( Flink != p );

  return 0;

  }

  4.4如下爲取得InInitializationOrderModuleList列表的code

  #include "stdafx.h"

  #include "windows.h"

  #include "winsvc.h"

  int _tmain(int argc, _TCHAR* argv[])

  {

  void *PEB = NULL,

  *Ldr = NULL,

  *Flink = NULL,

  *p = NULL,

  *BaseAddress = NULL,

  *FullDllName = NULL;

  __asm

  {

  mov eax,fs:[0x30]

  mov PEB,eax

  }

  Ldr = *( ( void ** )( ( unsigned char * )PEB+0x0c ) );

  Flink = *( ( void ** )( ( unsigned char * )Ldr+ 0x1c ) );

  p = Flink;

  do

  {

  BaseAddress = *( ( void ** )( ( unsigned char * )p+ 0x08 ) );

  FullDllName = *( ( void ** )( ( unsigned char * )p+ 0x18) );

  wprintf(L"FullDllName is %s\n",FullDllName);

  printf("BaseAddress is %x\n",BaseAddress);

  p = *( ( void ** )p);

  }

  while ( Flink != p );

  return 0;

  }

相關文章
相關標籤/搜索