深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

admin 2024年6月10日22:59:52评论1 views字数 4313阅读14分22秒阅读模式


      中东一哥,叶海亚将军最近刷屏了,再配上抖音那首《人间半途》的“把酒叹平生,把往事熬成药;一秋风雨敬苍天,从此无年少;我问月亮借华韶,再听秋风诉情长;一段芳华煮清欢,琐碎了平凡”,那容颜、那气质,文质彬彬却又杀气腾腾,温文尔雅又铮铮铁骨,敢跟美帝叫板的硬汉,连我此等俗人都赞叹仰慕不已,那歌词真是绝配了,循环了无数遍。


正    文

说起 PEB和TEB,那真是老生常谈了,光在我的公众号里就出现过若干次,有《windows下的反调试》《识别和分析 shellcode的一些方法》《Soloz的静态恶意代码免杀》《汇编:定位kernel32的基地址》《工具Pe2shc (Pe to Shellcode) 的源码级分析(下)》《对<由一道CTF对10种反调试的探究>一文的学习》《带你认识绕不开的ASLR》,没想到有这么多。

今天值班,再次有时间,将Peb和Teb详细地理了一遍,分享给大家。

一、简单介绍

在 Windows 操作系统中,进程和线程的管理涉及到一系列复杂的数据结构。两个关键的内部数据结构是 PEB(进程环境块,Process Environment Block)和 TEB(线程环境块,Thread Environment Block)。这些数据结构对于操作系统管理进程和线程的状态、资源和环境至关重要。本文将深入探讨 PEB 和 TEB 的定义、结构和用途。

1. 什么是 PEB?

PEB(Process Environment Block)是一个包含进程相关信息的数据结构。每个进程在创建时都会有一个对应的 PEB,它存储了该进程的全局状态和环境信息。

1.1 PEB 的作用

PEB 包含进程的许多重要信息,例如:

  • 环境变量

  • 映像基地址(Image Base Address)

  • 进程启动参数

  • 加载的模块列表

  • 堆的管理信息


1.2 PEB 的结构

在 Windows 操作系统中,PEB 的结构在不同版本之间可能略有不同。以下是一个简化的 PEB 结构示例:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

2. 什么是 TEB?

TEB(Thread Environment Block)是一个包含线程相关信息的数据结构。每个线程在创建时都会有一个对应的 TEB,它存储了该线程的局部状态和环境信息。

2.1 TEB 的作用

TEB 包含线程的许多重要信息,例如:

  • 线程局部存储(TLS)

  • 异常处理链

  • 堆栈基址和栈顶地址

  • 当前线程的环境变量指针

  • 线程ID


2.2 TEB 的结构

TEB 的结构也在不同的 Windows 版本之间有所不同。以下是一个简化的 TEB 结构示例:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

3. PEB 和 TEB 的关系

每个线程都通过其 TEB 关联到进程的 PEB,这样线程可以访问进程级的全局信息。TEB 包含一个指向其所属进程的 PEB 的指针,这使得线程可以方便地获取进程的环境信息。

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

引用《工具Pe2shc (Pe to Shellcode) 的源码级分析(下)》中图示:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

4. 获取 PEB 和 TEB 的方法

在 Windows 上,可以使用多种方法来获取当前进程的 PEB 和当前线程的 TEB。例如,在 64 位系统上,可以通过以下代码获取 PEB 和 TEB:

获取 PEB:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

获取 TEB:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

这些函数使用了特定的 CPU 寄存器来读取 PEB 和 TEB 的基地址。


二、详细了解

以下部分,参考AperOdry一文;

TEB即为线程环境块, 进程中每一条线程都对应着的自己的“TEB”。

TEB的访问方法:

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

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

从图中我们可以看到NtCurrentTeb() 函数所返回的结构体指针即为 fs:[0x18] 的值,里面的值即为TEB的结构体指针,对比数据窗口即可发现

fs:[0]的值即为TEB的起始地址。

(一)TEB结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

1.+0x000 NtTib            : _NT_TIB

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

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

  • ExceptionList:即为指向_EXCEPTION_REGISTRATION_RECORD结构体的链表指针(SEH)

  • StackBase:这里为线程堆栈顶部

  • StackLimit :这里为线程堆栈底部

  • Self:这为_NT_TIB结构体的自引用指针,即为NtCurrentTeb() 函数所读出的TEB结构体指针


2.+0x020 ClientId         : _CLIENT_ID

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

  • 深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

  • 深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

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

(2)UniqueThread: 这个为当前进程的的Tid,可用函数 GetCurrentThreadId() 访问当前结构体成员获取线程标识符:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

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

3.+0x030 ProcessEnvironmentBlock : Ptr32 _PEB

这个即为PEB结构体的指针,所以说一般 fs:[0x30] 即为PEB的起始地址。线程TEB结构体中,每个TEB+0x30(fs:[0x30])中都指向同一个地址(TEB.ProcessEnvironmentBlock)。我们可以用fs:[0x30]来访问PEB的结构体地址。

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

这里我们可以看到 [TEB.ProcessEnvironmentBlock] = =   fs:[0x30],而EP中 EBX寄存器默认为PEB的结构体地址。


(二)PEB的数据结构:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

(1)+0x002 BeingDebugged    : UChar

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

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

看到先是取出PEB的结构体地址,在取出PEB.BeingDebugged  结构体成员然后返回。

(2)+0x008 ImageBaseAddress : Ptr32 Void

这个结构体成员我们也经常用到,也就是自身的 ImageBase ,和PE结构中的 IMAGE_OPTIONAL_HEADER.ImageBase 。

可用函 GetModuleHandle (0) 获取自身模块句柄来访问这个结构体成员:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

这里判断参数是否为0,也就是取自身的模块句柄 (ImaheBase

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

这里也同上,先是取出PEB结构体地址,再取出 ImageBaseAddress 。

(3)+0x00c Ldr              : Ptr32 _PEB_LDR_DATA

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

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

InLoadOrderModuleList、InMemoryOrderModuleList、InInitializationOrderModuleList 这三个结构体成员都是指向LIST_ENTRY

的结构体指针,我们查询下这个数据结构:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

可以看出这是一个双向链表,链表中存放着 _LDR_DATA_TABLE_ENTRY 的结构体信息:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

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

(4)+0x018 ProcessHeap      : Ptr32 Void

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

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

程序正常运行时,ProcessHeap.Flags的值为2 , ProcessHeap. ForceFlags 的值为0,也常用于反调试。

ProcessHeap结构体成员指向的HEAP结构体指针可用函数 GetProcessHeap()获取:

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

(5)+0x068 NtGlobalFlag     : Uint4B

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


三、一个实例

A simple PoC to locate hooked functions within ntdll.dll to further EDR evasion research.

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

源码地址:https://github.com/fin3ss3g0d/HookFinder

这段代码实现了一个简单的 Windows 下的钩子检测程序。它通过读取线程环境块(TEB)和进程环境块(PEB),检查 NTDLL.dll 中的导出函数表(EAT)来检测是否有函数被钩住(hooked)。

  1. 获取 TEB 和 PEB


    深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

RtlGetThreadEnvironmentBlock(): 通过内联汇编获取 TEB(线程环境块)的地址。对于 64 位系统,使用 __readgsqword(0x30),对于 32 位系统,使用 __readfsdword(0x16)

2. 获取图像导出目录

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

GetImageExportDirectory(): 通过解析 DOS 和 NT 头获取图像导出目录(EAT)的地址。

3. 主函数

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

  • wmain(): 获取当前线程的 TEB 和当前进程的 PEB,验证它们的有效性并检查操作系统的主版本号是否为 10。

  • 从 PEB 中获取 NTDLL 模块的基地址,然后获取 NTDLL 的导出地址表(EAT),并调用 HookFinder() 来检测钩子。


4. 钩子检测

深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构


后记:今天是端午节,祝大家端午安康!!

端午节是一个充满文化和历史意义的节日,它在每年的农历五月初五庆祝,纪念古代爱国诗人屈原。通过丰富多彩的传统习俗和活动,不仅纪念了屈原的爱国精神,也表达了人们对健康和平安的美好愿望。无论是在中国还是在世界其他地方,端午节都成为了一个具有深厚文化内涵的节日。

主要习俗

  1. 赛龙舟

    • 龙舟竞赛是端午节最重要的活动之一。龙舟是雕刻成龙形的长船,比赛时,参赛者们划着龙舟在江河湖泊中竞速。赛龙舟不仅是对屈原的纪念,也是一种传统体育活动,吸引了大量观众观看和参与。

  2. 吃粽子

    • 粽子是端午节的传统食物,是用糯米包裹各种馅料(如红豆、红枣、咸蛋黄、猪肉等),用竹叶或苇叶包裹后蒸煮而成。人们通过吃粽子来纪念屈原。

  3. 挂艾草和菖蒲

    • 在端午节期间,人们会在门前挂艾草和菖蒲,认为可以驱邪避害,保持健康。艾草和菖蒲有特殊的香味,据说可以驱赶蚊虫和邪气。

  4. 喝雄黄酒

    • 雄黄酒是一种用雄黄(一种矿物)泡制的酒,古人认为雄黄酒可以驱毒避邪。在端午节,尤其是南方一些地区,人们会饮用雄黄酒或在孩子身上涂抹雄黄,以祈求健康平安。

  5. 佩戴香包

    • 香包是一种用布做的小袋子,里面装有香草或药材,有驱虫和防病的作用。端午节期间,家长会给孩子佩戴香包,寓意驱邪保平安。

原文始发于微信公众号(MicroPest):深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年6月10日22:59:52
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   深入理解 PEB 和 TEB:Windows 操作系统的内部数据结构https://cn-sec.com/archives/2835445.html

发表评论

匿名网友 填写信息