TEB和PEB

TEB和PEBTEB ThreadEnviro 线程环境块 线程环境块中存放着进程中所有线程的各种信息 TEB 的访问方法 ntdll NtCurrentTeb 函数用来返回当前线程的 TEB 结构体指针 NtCurrentTeb 函数所返回的结构体指针即为 fs 0x18 的值 里面的值即为 TEB 的结构体指针 fs 0 的值即为 TEB 的起始地址 nt TEB

TEB(Thread Environment Block,线程环境块)

线程环境块中存放着进程中所有线程的各种信息

TEB的访问方法

ntdll.NtCurrentTeb() 函数用来返回当前线程的TEB结构体指针

NtCurrentTeb() 函数所返回的结构体指针即为 fs:[0x18] 的值,里面的值即为TEB的结构体指针,fs:[0]的值即为TEB的起始地址

nt!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB +0x034 LastErrorValue : Uint4B +0x038 CountOfOwnedCriticalSections : Uint4B +0x03c CsrClientThread : Ptr32 Void +0x040 Win32ThreadInfo : Ptr32 Void +0x044 User32Reserved : [26] Uint4B +0x0ac UserReserved : [5] Uint4B +0x0c0 WOW32Reserved : Ptr32 Void +0x0c4 CurrentLocale : Uint4B +0x0c8 FpSoftwareStatusRegister : Uint4B +0x0cc SystemReserved1 : [54] Ptr32 Void +0x1a4 ExceptionCode : Int4B +0x1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK +0x1bc SpareBytes1 : [24] UChar +0x1d4 GdiTebBatch : _GDI_TEB_BATCH +0x6b4 RealClientId : _CLIENT_ID +0x6bc GdiCachedProcessHandle : Ptr32 Void +0x6c0 GdiClientPID : Uint4B +0x6c4 GdiClientTID : Uint4B +0x6c8 GdiThreadLocalInfo : Ptr32 Void +0x6cc Win32ClientInfo : [62] Uint4B +0x7c4 glDispatchTable : [233] Ptr32 Void +0xb68 glReserved1 : [29] Uint4B +0xbdc glReserved2 : Ptr32 Void +0xbe0 glSectionInfo : Ptr32 Void +0xbe4 glSection : Ptr32 Void +0xbe8 glTable : Ptr32 Void +0xbec glCurrentRC : Ptr32 Void +0xbf0 glContext : Ptr32 Void +0xbf4 LastStatusValue : Uint4B +0xbf8 StaticUnicodeString : _UNICODE_STRING +0xc00 StaticUnicodeBuffer : [261] Uint2B +0xe0c DeallocationStack : Ptr32 Void +0xe10 TlsSlots : [64] Ptr32 Void +0xf10 TlsLinks : _LIST_ENTRY +0xf18 Vdm : Ptr32 Void +0xf1c ReservedForNtRpc : Ptr32 Void +0xf20 DbgSsReserved : [2] Ptr32 Void +0xf28 HardErrorsAreDisabled : Uint4B +0xf2c Instrumentation : [16] Ptr32 Void +0xf6c WinSockData : Ptr32 Void +0xf70 GdiBatchCount : Uint4B +0xf74 InDbgPrint : UChar +0xf75 FreeStackOnTermination : UChar +0xf76 HasFiberData : UChar +0xf77 IdealProcessor : UChar +0xf78 Spare3 : Uint4B +0xf7c ReservedForPerf : Ptr32 Void +0xf80 ReservedForOle : Ptr32 Void +0xf84 WaitingOnLoaderLock : Uint4B +0xf88 Wx86Thread : _Wx86ThreadState +0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void +0xf98 ImpersonationLocale : Uint4B +0xf9c IsImpersonating : Uint4B +0xfa0 NlsCache : Ptr32 Void +0xfa4 pShimData : Ptr32 Void +0xfa8 HeapVirtualAffinity : Uint4B +0xfac CurrentTransactionHandle : Ptr32 Void +0xfb0 ActiveFrame : Ptr32 _TEB_ACTIVE_FRAME +0xfb4 SafeThunkCall : UChar +0xfb5 BooleanSpare : [3] UChar

详细的介绍常用的结构体成员及作用

1

+0x000 NtTib            : _NT_TIB

TEB的结构体的第一个成员NtTib即为我们常说的TIB   TIB(Thread Information Block,线程信息块)

typedef struct _NT_TIB //sizeof 1ch { 00h struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; 04h PVOID StackBase; 08h PVOID StackLimit; 0ch PVOID SubSystemTib; union { PVOID FiberData; 10h DWORD Version; }; 14h PVOID ArbitraryUserPointer; 18h struct _NT_TIB *Self; }NT_TIB;
  • ExceptionList:即为指向_EXCEPTION_REGISTRATION_RECORD结构体的链表指针(SEH)
  • StackBase:这里为线程堆栈顶部
  • StackLimit :这里为线程堆栈底部
  • Self:这为_NT_TIB结构体的自引用指针,即为NtCurrentTeb() 函数所读出的TEB结构体指针

2

+0x020 ClientId         : _CLIENT_ID

nt!_CLIENT_ID +0x000 UniqueProcess : Ptr64 Void +0x008 UniqueThread : Ptr64 Void

UniqueProcess:这个为当前进程的的Pid,可用函数 GetCurrentProcessId() 访问当前结构体成员获取进程标识符:

可以看到TEB+0x20即为 UniqueProcess 的成员变量。
  • UniqueThread: 这个为当前进程的的Tid,可用函数 GetCurrentThreadId() 访问当前结构体成员获取线程标识符:

可以看到TEB+0x20即为 UniqueThread 的成员变量。

3

+0x030 ProcessEnvironmentBlock : Ptr32 _PEB

这个即为PEB结构体的指针,所以说一般 fs:[0x30] 即为PEB的起始地址。

什么是PEB?

线程TEB结构体中,每个TEB+0x30(fs:[0x30])中都指向同一个地址(TEB.ProcessEnvironmentBlock)So。我们可以用fs:[0x30]来访问PEB的结构体地址

这里我们可以看到 [TEB.ProcessEnvironmentBlock] = =   fs:[0x30],而EP中 EBX寄存器默认为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

+0x002 BeingDebugged    : UChar

这个结构体成员大家应该都懂,表示当前进程是否处于调试状态,也就是函数 IsDebuggerPresent() 所访问的结构体成员.

这里我看可以看到先是取出PEB的结构体地址,在取出PEB.BeingDebugged  结构体成员然后返回

+0x008 ImageBaseAddress : Ptr32 Void

这个结构体成员我们也经常用到,也就是自身的 ImageBase ,和PE结构中的 IMAGE_OPTIONAL_HEADER.ImageBase 。
可用函 GetModuleHandle (0) 获取自身模块句柄来访问这个结构体成员:

+0x00c Ldr              : Ptr32 _PEB_LDR_DATA

这个结构体成员就很复杂了,它是指向 _PEB_LDR_DATA 的结构体指针,当DLL加载到进程,可从 PEB.Ldr 中获取该模块的基址和其他信息:

ntdll!_PEB_LDR_DATA +0x000 Length //结构体大小 +0x004 Initialized //进程是否初始化完成 +0x008 SsHandle +0x00c InLoadOrderModuleList : _LIST_ENTRY +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01c InInitializationOrderModuleList : _LIST_ENTRY +0x024 EntryInProgress +0x028 ShutdownInProgress +0x02c ShutdownThreadId

InLoadOrderModuleList、InMemoryOrderModuleList、InInitializationOrderModuleList 这三个结构体成员都是指向LIST_ENTRY的结构体指针,我们查询下这个数据结构:

nt!_LIST_ENTRY +0x000 Flink : Ptr64 _LIST_ENTRY +0x008 Blink : Ptr64 _LIST_ENTRY 

可以看出这是一个双向链表,每条链表都指向名为 LDR_DATA_TABLE_ENTRY 的结构体指针:

nt!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY +0x010 InMemoryOrderLinks : _LIST_ENTRY +0x020 InInitializationOrderLinks : _LIST_ENTRY +0x030 DllBase : Ptr64 Void +0x038 EntryPoint : Ptr64 Void +0x040 SizeOfImage : Uint4B +0x048 FullDllName : _UNICODE_STRING +0x058 BaseDllName : _UNICODE_STRING +0x068 FlagGroup : [4] UChar +0x068 Flags : Uint4B +0x068 PackagedBinary : Pos 0, 1 Bit +0x068 MarkedForRemoval : Pos 1, 1 Bit +0x068 ImageDll : Pos 2, 1 Bit +0x068 LoadNotificationsSent : Pos 3, 1 Bit +0x068 TelemetryEntryProcessed : Pos 4, 1 Bit +0x068 ProcessStaticImport : Pos 5, 1 Bit +0x068 InLegacyLists : Pos 6, 1 Bit +0x068 InIndexes : Pos 7, 1 Bit +0x068 ShimDll : Pos 8, 1 Bit +0x068 InExceptionTable : Pos 9, 1 Bit +0x068 ReservedFlags1 : Pos 10, 2 Bits +0x068 LoadInProgress : Pos 12, 1 Bit +0x068 LoadConfigProcessed : Pos 13, 1 Bit +0x068 EntryProcessed : Pos 14, 1 Bit +0x068 ProtectDelayLoad : Pos 15, 1 Bit +0x068 ReservedFlags3 : Pos 16, 2 Bits +0x068 DontCallForThreads : Pos 18, 1 Bit +0x068 ProcessAttachCalled : Pos 19, 1 Bit +0x068 ProcessAttachFailed : Pos 20, 1 Bit +0x068 CorDeferredValidate : Pos 21, 1 Bit +0x068 CorImage : Pos 22, 1 Bit +0x068 DontRelocate : Pos 23, 1 Bit +0x068 CorILOnly : Pos 24, 1 Bit +0x068 ChpeImage : Pos 25, 1 Bit +0x068 ReservedFlags5 : Pos 26, 2 Bits +0x068 Redirected : Pos 28, 1 Bit +0x068 ReservedFlags6 : Pos 29, 2 Bits +0x068 CompatDatabaseProcessed : Pos 31, 1 Bit +0x06c ObsoleteLoadCount : Uint2B +0x06e TlsIndex : Uint2B +0x070 HashLinks : _LIST_ENTRY +0x080 TimeDateStamp : Uint4B +0x088 EntryPointActivationContext : Ptr64 _ACTIVATION_CONTEXT +0x090 Lock : Ptr64 Void +0x098 DdagNode : Ptr64 _LDR_DDAG_NODE +0x0a0 NodeModuleLink : _LIST_ENTRY +0x0b0 LoadContext : Ptr64 _LDRP_LOAD_CONTEXT +0x0b8 ParentDllBase : Ptr64 Void +0x0c0 SwitchBackContext : Ptr64 Void +0x0c8 BaseAddressIndexNode : _RTL_BALANCED_NODE +0x0e0 MappingInfoIndexNode : _RTL_BALANCED_NODE +0x0f8 OriginalBase : Uint8B +0x100 LoadTime : _LARGE_INTEGER +0x108 BaseNameHashValue : Uint4B +0x10c LoadReason : _LDR_DLL_LOAD_REASON +0x110 ImplicitPathOptions : Uint4B +0x114 ReferenceCount : Uint4B +0x118 DependentLoadFlags : Uint4B +0x11c SigningLevel : UChar 

每个进程中的DLL加载进来都有与之对于的 _LDR_DATA_TABLE_ENTRY 结构体,这些结构相互链接就形成了双向链表

+0x018 ProcessHeap      : Ptr32 Void

这个结构体成员就是进程堆的句柄,也就是指向结构体HEAP的指针,我们查询下结构体成员:

nt!_HEAP +0x000 Segment : _HEAP_SEGMENT +0x000 Entry : _HEAP_ENTRY +0x010 SegmentSignature : Uint4B +0x014 SegmentFlags : Uint4B +0x018 SegmentListEntry : _LIST_ENTRY +0x028 Heap : Ptr64 _HEAP +0x030 BaseAddress : Ptr64 Void +0x038 NumberOfPages : Uint4B +0x040 FirstEntry : Ptr64 _HEAP_ENTRY +0x048 LastValidEntry : Ptr64 _HEAP_ENTRY +0x050 NumberOfUnCommittedPages : Uint4B +0x054 NumberOfUnCommittedRanges : Uint4B +0x058 SegmentAllocatorBackTraceIndex : Uint2B +0x05a Reserved : Uint2B +0x060 UCRSegmentList : _LIST_ENTRY +0x070 Flags : Uint4B +0x074 ForceFlags : Uint4B +0x078 CompatibilityFlags : Uint4B +0x07c EncodeFlagMask : Uint4B +0x080 Encoding : _HEAP_ENTRY +0x090 Interceptor : Uint4B +0x094 VirtualMemoryThreshold : Uint4B +0x098 Signature : Uint4B +0x0a0 SegmentReserve : Uint8B +0x0a8 SegmentCommit : Uint8B +0x0b0 DeCommitFreeBlockThreshold : Uint8B +0x0b8 DeCommitTotalFreeThreshold : Uint8B +0x0c0 TotalFreeSize : Uint8B +0x0c8 MaximumAllocationSize : Uint8B +0x0d0 ProcessHeapsListIndex : Uint2B +0x0d2 HeaderValidateLength : Uint2B +0x0d8 HeaderValidateCopy : Ptr64 Void +0x0e0 NextAvailableTagIndex : Uint2B +0x0e2 MaximumTagIndex : Uint2B +0x0e8 TagEntries : Ptr64 _HEAP_TAG_ENTRY +0x0f0 UCRList : _LIST_ENTRY +0x100 AlignRound : Uint8B +0x108 AlignMask : Uint8B +0x110 VirtualAllocdBlocks : _LIST_ENTRY +0x120 SegmentList : _LIST_ENTRY +0x130 AllocatorBackTraceIndex : Uint2B +0x134 NonDedicatedListLength : Uint4B +0x138 BlocksIndex : Ptr64 Void +0x140 UCRIndex : Ptr64 Void +0x148 PseudoTagEntries : Ptr64 _HEAP_PSEUDO_TAG_ENTRY +0x150 FreeLists : _LIST_ENTRY +0x160 LockVariable : Ptr64 _HEAP_LOCK +0x168 CommitRoutine : Ptr64 long +0x170 StackTraceInitVar : _RTL_RUN_ONCE +0x178 CommitLimitData : _RTL_HEAP_MEMORY_LIMIT_DATA +0x198 FrontEndHeap : Ptr64 Void +0x1a0 FrontHeapLockCount : Uint2B +0x1a2 FrontEndHeapType : UChar +0x1a3 RequestedFrontEndHeapType : UChar +0x1a8 FrontEndHeapUsageData : Ptr64 Wchar +0x1b0 FrontEndHeapMaximumIndex : Uint2B +0x1b2 FrontEndHeapStatusBitmap : [129] UChar +0x238 Counters : _HEAP_COUNTERS +0x2b0 TuningParameters : _HEAP_TUNING_PARAMETERS 

程序正常运行时,ProcessHeap.Flags的值为2 , ProcessHeap. ForceFlags 的值为0,也常用于反调试。
ProcessHeap结构体成员指向的HEAP结构体指针可用函数 GetProcessHeap()获取:

+0x068 NtGlobalFlag     : Uint4B

再调试状态时,PEB.NtGlobalFlag 的值为0x70 ,这个值我也不清楚 只记得几个Flages的值进行 OR(位或) 的结果

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/211132.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午11:08
下一篇 2026年3月18日 下午11:08


相关推荐

  • 静态方法和非静态方法区别?

    静态方法和非静态方法区别?静态方法 static 类方法 和非静态方法 实例方法 的区别 方法我们主要分为三种 1 构造方法 2 非静态方法 普通方法 实例方法 3 静态方法 类方法 对于 1 补充一下 构造方法分为无参构造方法和有参构造方法 另外这两个方法 涉及到了方法重载 小伙伴可以自己去了解方法重载 方法重写 方法重构区别 当然我其他文章也会写相关的介绍 对于 2 静态方法 是使用 static 关键字修

    2026年3月20日
    2
  • Pycharm安装matplotlib

    Pycharm安装matplotlib在终端中通过pip3安装matplotlib后,发现pycharm中引入会报错,查了一下发现可以在Pycharm中安装matplotlib来解决:1.打开Preferences,找到ProjectInterpreter,点“+”添加2.在输入框中输入matplotlib进行搜索,然后选中要安装的包并点击下方的installpackage3.此时如果发现安装特别慢,可以…

    2022年6月16日
    30
  • AI编程:探索ClaudeCode + Claude4/Kimi K2/Qwen3 Coder的全面玩法分析

    AI编程:探索ClaudeCode + Claude4/Kimi K2/Qwen3 Coder的全面玩法分析

    2026年3月16日
    2
  • WPF教程(二) WPF vs WinForms

    在前面的章节,我们讨论了WPF是什么,还涉及了一点点WinForms。在本章节,我将尝试比较两者,尽管它们服务的目的一样,却存在很多的区别。如果你以前从来没有接触过WinForms,或者WPF是你学习的第一种GUI框架,请跳过这一章节。但是如果你有兴趣的话,不妨尝试一读。先说说两者最重要的区别。WinForms只是标准窗体控件顶部的一层(如文本框),而WPF从零开始,几乎在所有场景下都不依赖于

    2022年4月9日
    46
  • vue自定义组件封装_vue组件的双向绑定实现

    vue自定义组件封装_vue组件的双向绑定实现vue组件封装,vueelementui组件封装,vue图片上传,elementui图片上传

    2026年2月20日
    8
  • Android-json解析(三):原生JSONObject+JSONArray的解析、遍历及生成等

    Android-json解析(三):原生JSONObject+JSONArray的解析、遍历及生成等一、JSONObject和JSONArray的数据表示形式JSONObject的数据是用{}来表示的,例如:{"id":"123",

    2022年7月13日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号