PEB, TEB, EPROCESS, KPROCESS, ETHREAD, KTHREAD 윈도우



1. 서론


PEB, TEB 에 대해서 알아보자.


PEB Process Environment Block 의 약자이고
TEB Thread Environment Block 의 약자이다.

프로세스가 생성되면 해당 프로세스의 정보를 가지고 있는 EPROCESS 라는 구조체가 커널 메모리(MSDN의 표현을 빌리자면 System Address Space) 에 생성된다. 모든 프로세스는 각자의 EPROCESS 구조체를 하나씩 가지고 자신이 사용하는 쓰레드의 개수만큼 ETHREAD 구조체를 가진다. ETHREAD 구조체 역시 커널 메모리에 생성된다.

EPROCESSETHREAD 구조체는 커널메모리에서만 접근 가능하기 때문에 이러한 정보가 커널 메모리에만 존재한다고 가정하면 단지 PROCESS ID 값, 혹은 THREAD ID 값을 얻으려고 해도 커널 구조체에 접근해야 한다. 또한 빈번하게 갱신되는 프로세스의 정보도 위와 같은 구조에서는 커널 메모리에 접근해야지만 수정이 가능하기때문에 유저 메모리에 (Process Memory Space) PEB, TEB 와 같은 구조체를 만들어 둔다면 프로세스의 정보를 보다 효율적으로 관리할 수 있다.

EPROCESS ETHREAD 내부에는 각각 PCB, TCB란 이름의 KPROCESSKTHREAD 라는 구조체가 존재한다.
운영체제 수업에서 들을 수 있었던 Process Control BlockThread Control Block 윈도우 구현체다.

KPROCESS 는 NULL 동기화 객체와 관련된 디스패처 객체 헤더, 가상 메모리의 CR3 레지스터 값, 프로세스에 속해 있는 스레드 리스트 헤더, CPU에 대한 종속성(Affinity), 프로세스 우선순위, 프로세스에서 생성되는 스레드의 기본 실행 시간 값 등과 같은 정보를 가지고 있다.

ETHREAD - KTHREAD 관계는 는 EPROCESS - KPROCESS 관계와 비슷하다. 
KTHREAD 는 스레드 종료 동기화 객체, TEB(Thread Environment Block) 포인터, 스레드 우선순위, 스케줄러에 의해 실행을 준비하고 있는 스레드 리스트, 퀀텀 값등의 정보를 가지고 있다.

 자세한 내용은 http://youmin3.egloos.com/1650047 를 참고하도록 하자.
2. 본론


아래는 WinDBG에서 확인한 구조체이다. 순서대로 PEB, EPROCESS, KPROCESS, TEB, ETHREAD, KTHREAD 이다.

kd> dt _PEB
nt!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 SpareBool        : UChar
   +0x004 Mutant           : Ptr32 Void
   +0x008 ImageBaseAddress : Ptr32 Void
   +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
   +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : Ptr32 Void
   +0x018 ProcessHeap      : Ptr32 Void
   +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION
   +0x020 FastPebLockRoutine : Ptr32 Void
   +0x024 FastPebUnlockRoutine : Ptr32 Void
   +0x028 EnvironmentUpdateCount : Uint4B
   +0x02c KernelCallbackTable : Ptr32 Void
   +0x030 SystemReserved   : [1] Uint4B
   +0x034 AtlThunkSListPtr32 : Uint4B
   +0x038 FreeList         : Ptr32 _PEB_FREE_BLOCK
   +0x03c TlsExpansionCounter : Uint4B
   +0x040 TlsBitmap        : Ptr32 Void
   +0x044 TlsBitmapBits    : [2] Uint4B
   +0x04c ReadOnlySharedMemoryBase : Ptr32 Void
   +0x050 ReadOnlySharedMemoryHeap : Ptr32 Void
   +0x054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void
   +0x058 AnsiCodePageData : Ptr32 Void
   +0x05c OemCodePageData  : Ptr32 Void
   +0x060 UnicodeCaseTableData : Ptr32 Void
   +0x064 NumberOfProcessors : Uint4B
   +0x068 NtGlobalFlag     : Uint4B
   +0x070 CriticalSectionTimeout : _LARGE_INTEGER
   +0x078 HeapSegmentReserve : Uint4B
   +0x07c HeapSegmentCommit : Uint4B
   +0x080 HeapDeCommitTotalFreeThreshold : Uint4B
   +0x084 HeapDeCommitFreeBlockThreshold : Uint4B
   +0x088 NumberOfHeaps    : Uint4B
   +0x08c MaximumNumberOfHeaps : Uint4B
   +0x090 ProcessHeaps     : Ptr32 Ptr32 Void
   +0x094 GdiSharedHandleTable : Ptr32 Void
   +0x098 ProcessStarterHelper : Ptr32 Void
   +0x09c GdiDCAttributeList : Uint4B
   +0x0a0 LoaderLock       : Ptr32 Void
   +0x0a4 OSMajorVersion   : Uint4B
   +0x0a8 OSMinorVersion   : Uint4B
   +0x0ac OSBuildNumber    : Uint2B
   +0x0ae OSCSDVersion     : Uint2B
   +0x0b0 OSPlatformId     : Uint4B
   +0x0b4 ImageSubsystem   : Uint4B
   +0x0b8 ImageSubsystemMajorVersion : Uint4B
   +0x0bc ImageSubsystemMinorVersion : Uint4B
   +0x0c0 ImageProcessAffinityMask : Uint4B
   +0x0c4 GdiHandleBuffer  : [34] Uint4B
   +0x14c PostProcessInitRoutine : Ptr32     void 
   +0x150 TlsExpansionBitmap : Ptr32 Void
   +0x154 TlsExpansionBitmapBits : [32] Uint4B
   +0x1d4 SessionId        : Uint4B
   +0x1d8 AppCompatFlags   : _ULARGE_INTEGER
   +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER
   +0x1e8 pShimData        : Ptr32 Void
   +0x1ec AppCompatInfo    : Ptr32 Void
   +0x1f0 CSDVersion       : _UNICODE_STRING
   +0x1f8 ActivationContextData : Ptr32 Void
   +0x1fc ProcessAssemblyStorageMap : Ptr32 Void
   +0x200 SystemDefaultActivationContextData : Ptr32 Void
   +0x204 SystemAssemblyStorageMap : Ptr32 Void
   +0x208 MinimumStackCommit : Uint4B




nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : Ptr32 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY
   +0x090 QuotaUsage       : [3] Uint4B
   +0x09c QuotaPeak        : [3] Uint4B
   +0x0a8 CommitCharge     : Uint4B
   +0x0ac PeakVirtualSize  : Uint4B
   +0x0b0 VirtualSize      : Uint4B
   +0x0b4 SessionProcessLinks : _LIST_ENTRY
   +0x0bc DebugPort        : Ptr32 Void
   +0x0c0 ExceptionPort    : Ptr32 Void
   +0x0c4 ObjectTable      : Ptr32 _HANDLE_TABLE
   +0x0c8 Token            : _EX_FAST_REF
   +0x0cc WorkingSetLock   : _FAST_MUTEX
   +0x0ec WorkingSetPage   : Uint4B
   +0x0f0 AddressCreationLock : _FAST_MUTEX
   +0x110 HyperSpaceLock   : Uint4B
   +0x114 ForkInProgress   : Ptr32 _ETHREAD
   +0x118 HardwareTrigger  : Uint4B
   +0x11c VadRoot          : Ptr32 Void
   +0x120 VadHint          : Ptr32 Void
   +0x124 CloneRoot        : Ptr32 Void
   +0x128 NumberOfPrivatePages : Uint4B
   +0x12c NumberOfLockedPages : Uint4B
   +0x130 Win32Process     : Ptr32 Void
   +0x134 Job              : Ptr32 _EJOB
   +0x138 SectionObject    : Ptr32 Void
   +0x13c SectionBaseAddress : Ptr32 Void
   +0x140 QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
   +0x144 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
   +0x148 Win32WindowStation : Ptr32 Void
   +0x14c InheritedFromUniqueProcessId : Ptr32 Void
   +0x150 LdtInformation   : Ptr32 Void
   +0x154 VadFreeHint      : Ptr32 Void
   +0x158 VdmObjects       : Ptr32 Void
   +0x15c DeviceMap        : Ptr32 Void
   +0x160 PhysicalVadList  : _LIST_ENTRY
   +0x168 PageDirectoryPte : _HARDWARE_PTE
   +0x168 Filler           : Uint8B
   +0x170 Session          : Ptr32 Void
   +0x174 ImageFileName    : [16] UChar
   +0x184 JobLinks         : _LIST_ENTRY
   +0x18c LockedPagesList  : Ptr32 Void
   +0x190 ThreadListHead   : _LIST_ENTRY
   +0x198 SecurityPort     : Ptr32 Void
   +0x19c PaeTop           : Ptr32 Void
   +0x1a0 ActiveThreads    : Uint4B
   +0x1a4 GrantedAccess    : Uint4B
   +0x1a8 DefaultHardErrorProcessing : Uint4B
   +0x1ac LastThreadExitStatus : Int4B
   +0x1b0 Peb              : Ptr32 _PEB
   +0x1b4 PrefetchTrace    : _EX_FAST_REF
   +0x1b8 ReadOperationCount : _LARGE_INTEGER
   +0x1c0 WriteOperationCount : _LARGE_INTEGER
   +0x1c8 OtherOperationCount : _LARGE_INTEGER
   +0x1d0 ReadTransferCount : _LARGE_INTEGER
   +0x1d8 WriteTransferCount : _LARGE_INTEGER
   +0x1e0 OtherTransferCount : _LARGE_INTEGER
   +0x1e8 CommitChargeLimit : Uint4B
   +0x1ec CommitChargePeak : Uint4B
   +0x1f0 AweInfo          : Ptr32 Void
   +0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x1f8 Vm               : _MMSUPPORT
   +0x238 LastFaultCount   : Uint4B
   +0x23c ModifiedPageCount : Uint4B
   +0x240 NumberOfVads     : Uint4B
   +0x244 JobStatus        : Uint4B
   +0x248 Flags            : Uint4B
   +0x248 CreateReported   : Pos 0, 1 Bit
   +0x248 NoDebugInherit   : Pos 1, 1 Bit
   +0x248 ProcessExiting   : Pos 2, 1 Bit
   +0x248 ProcessDelete    : Pos 3, 1 Bit
   +0x248 Wow64SplitPages  : Pos 4, 1 Bit
   +0x248 VmDeleted        : Pos 5, 1 Bit
   +0x248 OutswapEnabled   : Pos 6, 1 Bit
   +0x248 Outswapped       : Pos 7, 1 Bit
   +0x248 ForkFailed       : Pos 8, 1 Bit
   +0x248 HasPhysicalVad   : Pos 9, 1 Bit
   +0x248 AddressSpaceInitialized : Pos 10, 2 Bits
   +0x248 SetTimerResolution : Pos 12, 1 Bit
   +0x248 BreakOnTermination : Pos 13, 1 Bit
   +0x248 SessionCreationUnderway : Pos 14, 1 Bit
   +0x248 WriteWatch       : Pos 15, 1 Bit
   +0x248 ProcessInSession : Pos 16, 1 Bit
   +0x248 OverrideAddressSpace : Pos 17, 1 Bit
   +0x248 HasAddressSpace  : Pos 18, 1 Bit
   +0x248 LaunchPrefetched : Pos 19, 1 Bit
   +0x248 InjectInpageErrors : Pos 20, 1 Bit
   +0x248 VmTopDown        : Pos 21, 1 Bit
   +0x248 Unused3          : Pos 22, 1 Bit
   +0x248 Unused4          : Pos 23, 1 Bit
   +0x248 VdmAllowed       : Pos 24, 1 Bit
   +0x248 Unused           : Pos 25, 5 Bits
   +0x248 Unused1          : Pos 30, 1 Bit
   +0x248 Unused2          : Pos 31, 1 Bit
   +0x24c ExitStatus       : Int4B
   +0x250 NextPageColor    : Uint2B
   +0x252 SubSystemMinorVersion : UChar
   +0x253 SubSystemMajorVersion : UChar
   +0x252 SubSystemVersion : Uint2B
   +0x254 PriorityClass    : UChar
   +0x255 WorkingSetAcquiredUnsafe : UChar
   +0x258 Cookie           : Uint4B




kd> dt _KPROCESS
nt!_KPROCESS
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 ProfileListHead  : _LIST_ENTRY
   +0x018 DirectoryTableBase : [2] Uint4B
   +0x020 LdtDescriptor    : _KGDTENTRY
   +0x028 Int21Descriptor  : _KIDTENTRY
   +0x030 IopmOffset       : Uint2B
   +0x032 Iopl             : UChar
   +0x033 Unused           : UChar
   +0x034 ActiveProcessors : Uint4B
   +0x038 KernelTime       : Uint4B
   +0x03c UserTime         : Uint4B
   +0x040 ReadyListHead    : _LIST_ENTRY
   +0x048 SwapListEntry    : _SINGLE_LIST_ENTRY
   +0x04c VdmTrapcHandler  : Ptr32 Void
   +0x050 ThreadListHead   : _LIST_ENTRY
   +0x058 ProcessLock      : Uint4B
   +0x05c Affinity         : Uint4B
   +0x060 StackCount       : Uint2B
   +0x062 BasePriority     : Char
   +0x063 ThreadQuantum    : Char
   +0x064 AutoAlignment    : UChar
   +0x065 State            : UChar
   +0x066 ThreadSeed       : UChar
   +0x067 DisableBoost     : UChar
   +0x068 PowerState       : UChar
   +0x069 DisableQuantum   : UChar
   +0x06a IdealNode        : UChar
   +0x06b Flags            : _KEXECUTE_OPTIONS
   +0x06b ExecuteOptions   : UChar




kd> dt -a -b _TEB
nt!_TEB
   +0x000 NtTib            : _NT_TIB
      +0x000 ExceptionList    : Ptr32 
      +0x004 StackBase        : Ptr32 
      +0x008 StackLimit       : Ptr32 
      +0x00c SubSystemTib     : Ptr32 
      +0x010 FiberData        : Ptr32 
      +0x010 Version          : Uint4B
      +0x014 ArbitraryUserPointer : Ptr32 
      +0x018 Self             : Ptr32 
   +0x01c EnvironmentPointer : Ptr32 
   +0x020 ClientId         : _CLIENT_ID
      +0x000 UniqueProcess    : Ptr32  
     +0x004 UniqueThread     : Ptr32  
   +0x028 ActiveRpcHandle  : Ptr32 
   +0x02c ThreadLocalStoragePointer : Ptr32 
   +0x030 ProcessEnvironmentBlock : Ptr32 
   +0x034 LastErrorValue   : Uint4B
   +0x038 CountOfOwnedCriticalSections : Uint4B
   +0x03c CsrClientThread  : Ptr32 
   +0x040 Win32ThreadInfo  : Ptr32 
   +0x044 User32Reserved   : Uint4B
   +0x0ac UserReserved     : Uint4B
   +0x0c0 WOW32Reserved    : Ptr32 
   +0x0c4 CurrentLocale    : Uint4B
   +0x0c8 FpSoftwareStatusRegister : Uint4B
   +0x0cc SystemReserved1  : Ptr32 
   +0x1a4 ExceptionCode    : Int4B
   +0x1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK
      +0x000 Flags            : Uint4B
      +0x004 NextCookieSequenceNumber : Uint4B
      +0x008 ActiveFrame      : Ptr32 
      +0x00c FrameListCache   : _LIST_ENTRY
         +0x000 Flink            : Ptr32 
         +0x004 Blink            : Ptr32 
   +0x1bc SpareBytes1      : UChar
   +0x1d4 GdiTebBatch      : _GDI_TEB_BATCH
      +0x000 Offset           : Uint4B
      +0x004 HDC              : Uint4B
      +0x008 Buffer           : Uint4B
   +0x6b4 RealClientId     : _CLIENT_ID
      +0x000 UniqueProcess    : Ptr32 
      +0x004 UniqueThread     : Ptr32 
   +0x6bc GdiCachedProcessHandle : Ptr32 
   +0x6c0 GdiClientPID     : Uint4B
   +0x6c4 GdiClientTID     : Uint4B
   +0x6c8 GdiThreadLocalInfo : Ptr32 
   +0x6cc Win32ClientInfo  : Uint4B
   +0x7c4 glDispatchTable  : Ptr32 
   +0xb68 glReserved1      : Uint4B
   +0xbdc glReserved2      : Ptr32 
   +0xbe0 glSectionInfo    : Ptr32 
   +0xbe4 glSection        : Ptr32 
   +0xbe8 glTable          : Ptr32 
   +0xbec glCurrentRC      : Ptr32 
   +0xbf0 glContext        : Ptr32 
   +0xbf4 LastStatusValue  : Uint4B
   +0xbf8 StaticUnicodeString : _UNICODE_STRING
      +0x000 Length           : Uint2B
      +0x002 MaximumLength    : Uint2B
      +0x004 Buffer           : Ptr32 
   +0xc00 StaticUnicodeBuffer : Uint2B
   +0xe0c DeallocationStack : Ptr32 
   +0xe10 TlsSlots         : Ptr32 
   +0xf10 TlsLinks         : _LIST_ENTRY
      +0x000 Flink            : Ptr32 
      +0x004 Blink            : Ptr32 
   +0xf18 Vdm              : Ptr32 
   +0xf1c ReservedForNtRpc : Ptr32 
   +0xf20 DbgSsReserved    : Ptr32 
   +0xf28 HardErrorsAreDisabled : Uint4B
   +0xf2c Instrumentation  : Ptr32 
   +0xf6c WinSockData      : Ptr32 
   +0xf70 GdiBatchCount    : Uint4B
   +0xf74 InDbgPrint       : UChar
   +0xf75 FreeStackOnTermination : UChar
   +0xf76 HasFiberData     : UChar
   +0xf77 IdealProcessor   : UChar
   +0xf78 Spare3           : Uint4B
   +0xf7c ReservedForPerf  : Ptr32 
   +0xf80 ReservedForOle   : Ptr32 
   +0xf84 WaitingOnLoaderLock : Uint4B
   +0xf88 Wx86Thread       : _Wx86ThreadState
      +0x000 CallBx86Eip      : Ptr32 
      +0x004 DeallocationCpu  : Ptr32 
      +0x008 UseKnownWx86Dll  : UChar
      +0x009 OleStubInvoked   : Char
   +0xf94 TlsExpansionSlots : Ptr32 
   +0xf98 ImpersonationLocale : Uint4B
   +0xf9c IsImpersonating  : Uint4B
   +0xfa0 NlsCache         : Ptr32 
   +0xfa4 pShimData        : Ptr32 
   +0xfa8 HeapVirtualAffinity : Uint4B
   +0xfac CurrentTransactionHandle : Ptr32 
   +0xfb0 ActiveFrame      : Ptr32 
   +0xfb4 SafeThunkCall    : UChar
   +0xfb5 BooleanSpare     : UChar




kd> dt _ETHREAD
nt!_ETHREAD
   +0x000 Tcb              : _KTHREAD
   +0x1c0 CreateTime       : _LARGE_INTEGER
   +0x1c0 NestedFaultCount : Pos 0, 2 Bits
   +0x1c0 ApcNeeded        : Pos 2, 1 Bit
   +0x1c8 ExitTime         : _LARGE_INTEGER
   +0x1c8 LpcReplyChain    : _LIST_ENTRY
   +0x1c8 KeyedWaitChain   : _LIST_ENTRY
   +0x1d0 ExitStatus       : Int4B
   +0x1d0 OfsChain         : Ptr32 Void
   +0x1d4 PostBlockList    : _LIST_ENTRY
   +0x1dc TerminationPort  : Ptr32 _TERMINATION_PORT
   +0x1dc ReaperLink       : Ptr32 _ETHREAD
   +0x1dc KeyedWaitValue   : Ptr32 Void
   +0x1e0 ActiveTimerListLock : Uint4B
   +0x1e4 ActiveTimerListHead : _LIST_ENTRY
   +0x1ec Cid              : _CLIENT_ID
   +0x1f4 LpcReplySemaphore : _KSEMAPHORE
   +0x1f4 KeyedWaitSemaphore : _KSEMAPHORE
   +0x208 LpcReplyMessage  : Ptr32 Void
   +0x208 LpcWaitingOnPort : Ptr32 Void
   +0x20c ImpersonationInfo : Ptr32 _PS_IMPERSONATION_INFORMATION
   +0x210 IrpList          : _LIST_ENTRY
   +0x218 TopLevelIrp      : Uint4B
   +0x21c DeviceToVerify   : Ptr32 _DEVICE_OBJECT
   +0x220 ThreadsProcess   : Ptr32 _EPROCESS
   +0x224 StartAddress     : Ptr32 Void
   +0x228 Win32StartAddress : Ptr32 Void
   +0x228 LpcReceivedMessageId : Uint4B
   +0x22c ThreadListEntry  : _LIST_ENTRY
   +0x234 RundownProtect   : _EX_RUNDOWN_REF
   +0x238 ThreadLock       : _EX_PUSH_LOCK
   +0x23c LpcReplyMessageId : Uint4B
   +0x240 ReadClusterSize  : Uint4B
   +0x244 GrantedAccess    : Uint4B
   +0x248 CrossThreadFlags : Uint4B
   +0x248 Terminated       : Pos 0, 1 Bit
   +0x248 DeadThread       : Pos 1, 1 Bit
   +0x248 HideFromDebugger : Pos 2, 1 Bit
   +0x248 ActiveImpersonationInfo : Pos 3, 1 Bit
   +0x248 SystemThread     : Pos 4, 1 Bit
   +0x248 HardErrorsAreDisabled : Pos 5, 1 Bit
   +0x248 BreakOnTermination : Pos 6, 1 Bit
   +0x248 SkipCreationMsg  : Pos 7, 1 Bit
   +0x248 SkipTerminationMsg : Pos 8, 1 Bit
   +0x24c SameThreadPassiveFlags : Uint4B
   +0x24c ActiveExWorker   : Pos 0, 1 Bit
   +0x24c ExWorkerCanWaitUser : Pos 1, 1 Bit
   +0x24c MemoryMaker      : Pos 2, 1 Bit
   +0x250 SameThreadApcFlags : Uint4B
   +0x250 LpcReceivedMsgIdValid : Pos 0, 1 Bit
   +0x250 LpcExitThreadCalled : Pos 1, 1 Bit
   +0x250 AddressSpaceOwner : Pos 2, 1 Bit
   +0x254 ForwardClusterOnly : UChar
   +0x255 DisablePageFaultClustering : UChar



kd> dt _KTHREAD
nt!_KTHREAD
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 MutantListHead   : _LIST_ENTRY
   +0x018 InitialStack     : Ptr32 Void
   +0x01c StackLimit       : Ptr32 Void
   +0x020 Teb              : Ptr32 Void
   +0x024 TlsArray         : Ptr32 Void
   +0x028 KernelStack      : Ptr32 Void
   +0x02c DebugActive      : UChar
   +0x02d State            : UChar
   +0x02e Alerted          : [2] UChar
   +0x030 Iopl             : UChar
   +0x031 NpxState         : UChar
   +0x032 Saturation       : Char
   +0x033 Priority         : Char
   +0x034 ApcState         : _KAPC_STATE
   +0x04c ContextSwitches  : Uint4B
   +0x050 IdleSwapBlock    : UChar
   +0x051 VdmSafe          : UChar
   +0x052 Spare0           : [2] UChar
   +0x054 WaitStatus       : Int4B
   +0x058 WaitIrql         : UChar
   +0x059 WaitMode         : Char
   +0x05a WaitNext         : UChar
   +0x05b WaitReason       : UChar
   +0x05c WaitBlockList    : Ptr32 _KWAIT_BLOCK
   +0x060 WaitListEntry    : _LIST_ENTRY
   +0x060 SwapListEntry    : _SINGLE_LIST_ENTRY
   +0x068 WaitTime         : Uint4B
   +0x06c BasePriority     : Char
   +0x06d DecrementCount   : UChar
   +0x06e PriorityDecrement : Char
   +0x06f Quantum          : Char
   +0x070 WaitBlock        : [4] _KWAIT_BLOCK
   +0x0d0 LegoData         : Ptr32 Void
   +0x0d4 KernelApcDisable : Uint4B
   +0x0d8 UserAffinity     : Uint4B
   +0x0dc SystemAffinityActive : UChar
   +0x0dd PowerState       : UChar
   +0x0de NpxIrql          : UChar
   +0x0df InitialNode      : UChar
   +0x0e0 ServiceTable     : Ptr32 Void
   +0x0e4 Queue            : Ptr32 _KQUEUE
   +0x0e8 ApcQueueLock     : Uint4B
   +0x0f0 Timer            : _KTIMER
   +0x118 QueueListEntry   : _LIST_ENTRY
   +0x120 SoftAffinity     : Uint4B
   +0x124 Affinity         : Uint4B
   +0x128 Preempted        : UChar
   +0x129 ProcessReadyQueue : UChar
   +0x12a KernelStackResident : UChar
   +0x12b NextProcessor    : UChar
   +0x12c CallbackStack    : Ptr32 Void
   +0x130 Win32Thread      : Ptr32 Void
   +0x134 TrapFrame        : Ptr32 _KTRAP_FRAME
   +0x138 ApcStatePointer  : [2] Ptr32 _KAPC_STATE
   +0x140 PreviousMode     : Char
   +0x141 EnableStackSwap  : UChar
   +0x142 LargeStack       : UChar
   +0x143 ResourceIndex    : UChar
   +0x144 KernelTime       : Uint4B
   +0x148 UserTime         : Uint4B
   +0x14c SavedApcState    : _KAPC_STATE
   +0x164 Alertable        : UChar
   +0x165 ApcStateIndex    : UChar
   +0x166 ApcQueueable     : UChar
   +0x167 AutoAlignment    : UChar
   +0x168 StackBase        : Ptr32 Void
   +0x16c SuspendApc       : _KAPC
   +0x19c SuspendSemaphore : _KSEMAPHORE
   +0x1b0 ThreadListEntry  : _LIST_ENTRY
   +0x1b8 FreezeCount      : Char
   +0x1b9 SuspendCount     : Char
   +0x1ba IdealProcessor   : UChar
   +0x1bb DisableBoost     : UChar



3. 결론


필드가 너무 많아서 자세히 조사하긴 어렵다. 간단하게 내가 알고 있는것만 짚고 넘어가자. (위에서 진한 굵기로 되어있는 부분)

PEB 부터 보면,  PEB 내부에는 Ldr 이라는 이름의 _PEB_LDR_DATA 구조체가 존재하는데, 이 구조체는 프로세스가 로드하는 DLL 목록을 연결 리스트 형태로 가지고 있다. 구조체를 한번 보자.

kd> dt _PEB_LDR_DATA
nt!_PEB_LDR_DATA
   +0x000 Length           : Uint4B
   +0x004 Initialized      : UChar
   +0x008 SsHandle         : Ptr32 Void
   +0x00c InLoadOrderModuleList : _LIST_ENTRY
  +0x014 InMemoryOrderModuleList : _LIST_ENTRY
  +0x01c InInitializationOrderModuleList : _LIST_ENTRY
   +0x024 EntryInProgress  : Ptr32 Void

이름이 의미하는바 그대로 로드 순서대로 링크, 메모리 위치 순서대로 링크, 초기화 순서대로 링크리스트다.
자세한 내용은
http://jz.pe.kr/24 를 참고.

이제 EPROCESS 와 KPROCESS 를 알아보자. EPROCESS 내부에는 Pcb 라는 이름의 KPROCESS 구조체와 Peb 라는 이름의 _PEB 구조체가 존재한다. 위에서도 말했듯이 KPROCESS 는 프로세스의 커널 스케쥴링과 동기화 등등을 담당하는 구조체다. 많은 필드가 있으나, 자세한 내용은 http://www.google.com 을 참고하자.

TEB 구조체로 넘어가자. TEB 프로세스의 가상 메모리(Ring3)에서 접근 가능한 구조체이며 많은 정보를 포함하고 있다.
NtTib 라는 이름의 _NT_TIB 구조체와 0x020의 _CLIENT_ID 그 중 하나이다.

TIB 는 경우는 Thread Information Block의 약자로서 Windows 95까지는 TIB 라는 이름으로, Windows NT 부터는 확장되어 TEB라는 이름으로 불리게 되었다고 한다. 

"The Windows 95 code calls it a Thread Information Block (TIB). In Windows NT, it's called the Thread Environment Block (TEB)"

Matt Pietrek, "Under The Hood" 발췌
자세한 내용은 MSJ 1996년 5월 호를 참조하길 바란다. http://www.microsoft.com/msj/archive/S2CE.aspx

특이한점은, _NT_TIB 구조체의 0x018의 Self 라는 이름의 포인터인데, 이는 다시 자기 자신을 가르키고 있다.
이에 대해서는 아래에서 다시 알아보자.

kd> dt _NT_TIB
nt!_NT_TIB
   +0x000 ExceptionList    : Ptr32 _EXCEPTION_REGISTRATION_RECORD
   +0x004 StackBase        : Ptr32 Void
   +0x008 StackLimit       : Ptr32 Void
   +0x00c SubSystemTib     : Ptr32 Void
   +0x010 FiberData        : Ptr32 Void
   +0x010 Version          : Uint4B
   +0x014 ArbitraryUserPointer : Ptr32 Void
   +0x018 Self             : Ptr32 _NT_TIB

그리고 아래의 0x020에 위치한 _CLIENT_ID 는 UniqueProcess 와 UniqueThread 라는 멤버가 존재하는데 이는 각각 현재 프로세스와 스레드의 ID 값이다.

kd> dt -a -b _TEB
nt!_TEB
   +0x000 NtTib            : _NT_TIB
      +0x000 ExceptionList    : Ptr32 
      +0x004 StackBase        : Ptr32 
      +0x008 StackLimit       : Ptr32 
      +0x00c SubSystemTib     : Ptr32 
      +0x010 FiberData        : Ptr32 
      +0x010 Version          : Uint4B
      +0x014 ArbitraryUserPointer : Ptr32 
      +0x018 Self             : Ptr32 
   +0x01c EnvironmentPointer : Ptr32 
   +0x020 ClientId         : _CLIENT_ID
      +0x000 UniqueProcess    : Ptr32 
      +0x004 UniqueThread     : Ptr32 
   ... 이하생략


이를 확인해 보기 위해 Process ID와 Thread ID를 얻기 위해 사용하는 Kernel32.dll 의 
GetCurrentProcessIDGetCurrentThreadID 를 디스어셈블 해보자.


0:001> uf kernel32!GetCurrentProcessID
kernel32!GetCurrentProcessId:
7c7d99c0 64a118000000    mov     eax,dword ptr fs:[00000018h]
7c7d99c6 8b4020          mov     eax,dword ptr [eax+20h]
7c7d99c9 c3              ret


0:001> uf kernel32!GetCurrentThreadID
kernel32!GetCurrentThreadId:
7c7d97d0 64a118000000    mov     eax,dword ptr fs:[00000018h]
7c7d97d6 8b4024          mov     eax,dword ptr [eax+24h]
7c7d97d9 c3              ret


FS:[0x18]이 뭘까? 이에 대한 답도 "Under The Hood" 에 있었다.

"However, in all Intel-based Win32 implementations (even the forgotten stepchild, Win32s), the FS register points to the TIB. "


FS:[0]이 TIB를 가리키므로, FS:[18]은 TIB의 0x18즉, Self 다. 즉 다시 TIB를 가리킨다. (-_-;) 

이에 대해서는 vBDream님의 의견이 가장 설득력 있는것 같다. 미래에 FS:[0] 이 TIB(=TEB) 가 아닌 다른 그 무엇으로 바뀌어도, 해당하는 구조체의 0x18 만 다시 TEB를 가리키게 한다면 위에서 보는 바와 같이 fs:[00000018h] 를 사용하는 API들의 코드를 변경하지 않고도 호환성 있게 사용 가능하기 위해서 이렇게 설정 해 놓았다는 의견이다.


그럼 다시 GetCurrentProcess(Thread)ID 로 돌아와서, EAX로 FS:[0x18]을 옮기고, 그 다음 리턴할 EAX 값에 [EAX+0x20] 혹은 [EAX+0x24]를 옮긴다. FS:[0x18]은 TEB 이고, 그 TEB 값에서 +0x20, +0x24 한 값은 _CLIENT_ID 필드의 UniqueProcessUniqueThread 값, 즉 Process와 Thread의 ID 값 이다.

한번 확인 해보자.

아래는 Notepad 에 WinDbg를 붙여 !TEB를 통해 Process ID와 Thread ID 값을 구해본 것이다.

0:001> !teb
TEB at 7ffde000
    ExceptionList:        00adffe4
    StackBase:            00ae0000
    StackLimit:           00adf000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7ffde000
    EnvironmentPointer:   00000000
   ClientId:             0000081c . 00000c40
    RpcHandle:            00000000
    Tls Storage:          00000000
    PEB Address:          7ffd7000
    LastErrorValue:       0
    LastStatusValue:      0
    Count Owned Locks:    0
    HardErrorMode:        0

0:001> dt ntdll!_CLIENT_ID 7ffde000+0x20 -r1
   +0x000 UniqueProcess    : 0x0000081c 
   +0x004 UniqueThread     : 0x00000c40 


프로세스 ID 값은 0x81C, 쓰레드 ID 값은 0xC40으로 나왔다. 실제로 그러한지 ProcExp를 통해 확인해보자.



2076과 3136, 16진수로 바꾸면 각각 81C, C40에 해당하는 값이다.


이상으로 PEB, TEB 등에 대해서 알아보는 시간을 마쳤고 다음 포스팅에서는 프로세스와 핸들에 대해서 알아보도록 하겠다.






핑백

  • 복군 : Memory Management : Translating Logical Address to Linear Address 2011-06-16 16:29:19 #

    ... 있다. TEB 는 유저 모드에서 사용하는 스레드 정보 저장 구조체다. ( TEB 에 대해서 알고 싶다면 다음을 링크를 참고하라. PEB, TEB, EPROCESS, KPROCESS, ETHREAD, KTHREAD ) 그렇다면, FS 가 TEB 를 가리키므로 현재 0x7ffdc000에 TEB 가 있다는 말이 된다. 한번 확인 해 보자. ... more

덧글

댓글 입력 영역


시계

라운드 시계

위키피디아