본문 바로가기

High Level Technique/Reversing

Process Environment Block (PEB)

Process Environment Block (PEB)


Process Environmnet Block (이하 PEB)는 프로세스 정보를 담고 있는 구조체 입니다.


PEB는 TEB.ProcessEnvrionmentBlock 멤버가 PEB 구조체의 주소입니다. TEB 구조체는 FS Segment 셀렉터가 가리키는 세그먼트 메모리의 시작 주소에 위치하고 ProcessEnvrionmentBlock 멤버는 TEB 구조체의 시작부터 30 Offset 만큼 떨어져 있습니다.


FS:[30] = TEB.ProcessEnvironmentBlock = address of PEB


어셈코드로 하면 mov eax, DWORD PTR FS:[30]이거나 mov eax, DWORD PTR FS:[18] mov eax, DWORD PTR DS:[EAX+30] 이 됩니다.



PEB 구조체는 아래와 같이 정의되어 있습니다.




WinDBG로 PEB 내용을 살펴보면 아래와 같습니다.

0:000> dt_PEB

ntdll!_PEB

   +0x000 InheritedAddressSpace : UChar

   +0x001 ReadImageFileExecOptions : UChar

   +0x002 BeingDebugged    : UChar

   +0x003 BitField         : UChar

   +0x003 ImageUsesLargePages : Pos 0, 1 Bit

   +0x003 IsProtectedProcess : Pos 1, 1 Bit

   +0x003 IsImageDynamicallyRelocated : Pos 2, 1 Bit

   +0x003 SkipPatchingUser32Forwarders : Pos 3, 1 Bit

   +0x003 IsPackagedProcess : Pos 4, 1 Bit

   +0x003 IsAppContainer   : Pos 5, 1 Bit

   +0x003 IsProtectedProcessLight : Pos 6, 1 Bit

   +0x003 SpareBits        : Pos 7, 1 Bit

   +0x004 Padding0         : [4] UChar

   +0x008 Mutant           : Ptr64 Void

   +0x010 ImageBaseAddress : Ptr64 Void

   +0x018 Ldr              : Ptr64 _PEB_LDR_DATA

   +0x020 ProcessParameters : Ptr64 _RTL_USER_PROCESS_PARAMETERS

   +0x028 SubSystemData    : Ptr64 Void

   +0x030 ProcessHeap      : Ptr64 Void

   +0x038 FastPebLock      : Ptr64 _RTL_CRITICAL_SECTION

   +0x040 AtlThunkSListPtr : Ptr64 Void

   +0x048 IFEOKey          : Ptr64 Void

   +0x050 CrossProcessFlags : Uint4B

   +0x050 ProcessInJob     : Pos 0, 1 Bit

   +0x050 ProcessInitializing : Pos 1, 1 Bit

   +0x050 ProcessUsingVEH  : Pos 2, 1 Bit

   +0x050 ProcessUsingVCH  : Pos 3, 1 Bit

   +0x050 ProcessUsingFTH  : Pos 4, 1 Bit

   +0x050 ReservedBits0    : Pos 5, 27 Bits

   +0x054 Padding1         : [4] UChar

   +0x058 KernelCallbackTable : Ptr64 Void

   +0x058 UserSharedInfoPtr : Ptr64 Void

   +0x060 SystemReserved   : [1] Uint4B

   +0x064 AtlThunkSListPtr32 : Uint4B

   +0x068 ApiSetMap        : Ptr64 Void

   +0x070 TlsExpansionCounter : Uint4B

   +0x074 Padding2         : [4] UChar

   +0x078 TlsBitmap        : Ptr64 Void

   +0x080 TlsBitmapBits    : [2] Uint4B

   +0x088 ReadOnlySharedMemoryBase : Ptr64 Void

   +0x090 SparePvoid0      : Ptr64 Void

   +0x098 ReadOnlyStaticServerData : Ptr64 Ptr64 Void

   +0x0a0 AnsiCodePageData : Ptr64 Void

   +0x0a8 OemCodePageData  : Ptr64 Void

   +0x0b0 UnicodeCaseTableData : Ptr64 Void

   +0x0b8 NumberOfProcessors : Uint4B

   +0x0bc NtGlobalFlag     : Uint4B

   +0x0c0 CriticalSectionTimeout : _LARGE_INTEGER

   +0x0c8 HeapSegmentReserve : Uint8B

   +0x0d0 HeapSegmentCommit : Uint8B

   +0x0d8 HeapDeCommitTotalFreeThreshold : Uint8B

   +0x0e0 HeapDeCommitFreeBlockThreshold : Uint8B

   +0x0e8 NumberOfHeaps    : Uint4B

   +0x0ec MaximumNumberOfHeaps : Uint4B

   +0x0f0 ProcessHeaps     : Ptr64 Ptr64 Void

   +0x0f8 GdiSharedHandleTable : Ptr64 Void

   +0x100 ProcessStarterHelper : Ptr64 Void

   +0x108 GdiDCAttributeList : Uint4B

   +0x10c Padding3         : [4] UChar

   +0x110 LoaderLock       : Ptr64 _RTL_CRITICAL_SECTION

   +0x118 OSMajorVersion   : Uint4B

   +0x11c OSMinorVersion   : Uint4B

   +0x120 OSBuildNumber    : Uint2B

   +0x122 OSCSDVersion     : Uint2B

   +0x124 OSPlatformId     : Uint4B

   +0x128 ImageSubsystem   : Uint4B

   +0x12c ImageSubsystemMajorVersion : Uint4B

   +0x130 ImageSubsystemMinorVersion : Uint4B

   +0x134 Padding4         : [4] UChar

   +0x138 ActiveProcessAffinityMask : Uint8B

   +0x140 GdiHandleBuffer  : [60] Uint4B

   +0x230 PostProcessInitRoutine : Ptr64     void 

   +0x238 TlsExpansionBitmap : Ptr64 Void

   +0x240 TlsExpansionBitmapBits : [32] Uint4B

   +0x2c0 SessionId        : Uint4B

   +0x2c4 Padding5         : [4] UChar

   +0x2c8 AppCompatFlags   : _ULARGE_INTEGER

   +0x2d0 AppCompatFlagsUser : _ULARGE_INTEGER

   +0x2d8 pShimData        : Ptr64 Void

   +0x2e0 AppCompatInfo    : Ptr64 Void

   +0x2e8 CSDVersion       : _UNICODE_STRING

   +0x2f8 ActivationContextData : Ptr64 _ACTIVATION_CONTEXT_DATA

   +0x300 ProcessAssemblyStorageMap : Ptr64 _ASSEMBLY_STORAGE_MAP

   +0x308 SystemDefaultActivationContextData : Ptr64 _ACTIVATION_CONTEXT_DATA

   +0x310 SystemAssemblyStorageMap : Ptr64 _ASSEMBLY_STORAGE_MAP

   +0x318 MinimumStackCommit : Uint8B

   +0x320 FlsCallback      : Ptr64 _FLS_CALLBACK_INFO

   +0x328 FlsListHead      : _LIST_ENTRY

   +0x338 FlsBitmap        : Ptr64 Void

   +0x340 FlsBitmapBits    : [4] Uint4B

   +0x350 FlsHighIndex     : Uint4B

   +0x358 WerRegistrationData : Ptr64 Void

   +0x360 WerShipAssertPtr : Ptr64 Void

   +0x368 pUnused          : Ptr64 Void

   +0x370 pImageHeaderHash : Ptr64 Void

   +0x378 TracingFlags     : Uint4B

   +0x378 HeapTracingEnabled : Pos 0, 1 Bit

   +0x378 CritSecTracingEnabled : Pos 1, 1 Bit

   +0x378 LibLoaderTracingEnabled : Pos 2, 1 Bit

   +0x378 SpareTracingBits : Pos 3, 29 Bits

   +0x37c Padding6         : [4] UChar

   +0x380 CsrServerReadOnlySharedMemoryBase : Uint8B

   +0x388 TppWorkerpListLock : Uint8B

   +0x390 TppWorkerpList   : _LIST_ENTRY

   +0x3a0 WaitOnAddressHashTable : [128] Ptr64 Void



PEB.BeingDebugged

kernel32에 IsDebuggerPresent() API가 존재하는데, 일반 응용프로그램 개발에는 잘 사용되지 않습니다.
이 API는 프로세스가 디버깅을 당하는지 판단해서 결과를 리턴하는데, 이때 참조하는 정보가 PEB.BeingDebugged 멤버 입니다.
디버깅 중이면 1, 아니면 0을 반환합니다.

Windows 7에서는 kernelbase.dll에 있습니다. 마찬가지로 windows 10에서도 kernelbase.dll에 존재합니다.



32비트에서는 FS:[18]의 TEB 주소를 구한 후 DS:[TEB+30]의 TEB.ProcessEnvironmnetBlock 멤버를 통해서 PEB 구조체에 접근합니다.

결국에는 FS:[30]과 같습니다. 


위 그림은 64비트 환경에서의 IsDebuggerPresent() 입니다. gs:[60]의 값을 가져옵니다.



64비트에서는 값을 확인할 수가 없었습니다. 주소가 나타나면 해당 위치로 이동해서 값을 확인해보면 디버깅중인지 아닌지가 판단이 되는데 값을 확인하지 못하니 확인할 방법이 없습니다.


Set New Origin Here 을 이용해서 값을 가져와서 확인해보니 값이 나타났습니다. (정확한 값인지는 잘 모르겠네요.)



PEB.ImageBaseAddress


PEB.ImageBaseAddress 멤버는 프로세스의 ImageBase를 표시합니다.





PEB.Ldr


PEB.Ldr 멤버는 _PEB_LDR_DATA 구조체의 포인터 입니다. WinDBG로 확인한 _PEB_LDR_DATA 구조체의 모습은 아래와 같습니다.


Ldr 멤버가 중요한 이유는 프로세ㅡ에 로딩된 모듈의 로딩 베이스 주소를 직접 구할 수 있는 방법을 제공합니다. _LIST_ENTRY 타입의 멤버가 3개가 존재합니다.

_LIST_ENTRY는 더블 링크드 리스트로 이루어진 구조체 입니다.


프로세스에 로딩된 DLL 모듈마다 _LDR_DATA_TABLE_ENTRY 구조체가 하나씩 생성되고 이 구조체들은 _LIST_ENTRY 더블 링크드 리스트로 연결됩니다.




PEB.ProcessHeap, PEB.NtGlobalFlag


안티디버깅 기법에 사용되고, 프로세스가 디버깅 중이면 ProcessHeap과 NtGlobalFlag 멤버는 특정 값을 가지게 됩니다.

'High Level Technique > Reversing' 카테고리의 다른 글

IA32 Instruction  (1) 2016.08.04
Structured Exception Handler (SEH)  (0) 2016.08.04
Thread Environment Block (TEB)  (0) 2016.08.02
Thread Local Storage CallBack (TLS)  (0) 2016.08.01
DLL Injection in kernel 6  (0) 2016.07.27