本篇发表我的TEB 和 PEB的一些见解,我把它图形化了,更形象便于理解。
首先对于TIB TEB PEB的概念我引用一下别人的blog了,以下内容取自看雪:

TEB(Thread Environment Block,线程环境块):系统在此TEB中保存频繁使用的线程相关的数据。位于用户地址空间。进程中的每个线程都有自己的一个TEB。一个进程的所有TEB都以堆栈的方式,存放在从0x7FFDE000(WinXP,当然,不同的系统可能位于不同的地址)开始的线性内存中,每4KB为一个完整的TEB,不过该内存区域是向下扩展的。在用户模式下,当前线程的TEB位于独立的4KB段,可通过CPU的FS寄存器来访问该段,一般存储在[FS:0]。在用户态下WinDbg中可用命令$thread取得TEB地址。
 
PEB(Process Environment Block,进程环境块)存放进程信息,每个进程都有自己的PEB信息。位于用户地址空间。在Win XP下,进程环境块的地址对于每个进程来说是固定的,在0x7FFDF000处,这是用户地址空间,所以程序能够直接访问。

首先,来借助于windbg工具来观察 TEB 结构。

0:000:x86> dt ntdll32!_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 ActivationContextStackPointer : Ptr32 _ACTIVATION_CONTEXT_STACK
   +0x1ac SpareBytes       : [36] UChar
   +0x1d0 TxFsContext      : Uint4B
   +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] Wchar
   +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 HardErrorMode    : Uint4B
   +0xf2c Instrumentation  : [9] Ptr32 Void
   +0xf50 ActivityId       : _GUID
   +0xf60 SubProcessTag    : Ptr32 Void
   +0xf64 EtwLocalData     : Ptr32 Void
   +0xf68 EtwTraceData     : Ptr32 Void
   +0xf6c WinSockData      : Ptr32 Void
   +0xf70 GdiBatchCount    : Uint4B
   +0xf74 CurrentIdealProcessor : _PROCESSOR_NUMBER
   +0xf74 IdealProcessorValue : Uint4B
   +0xf74 ReservedPad0     : UChar
   +0xf75 ReservedPad1     : UChar
   +0xf76 ReservedPad2     : UChar
   +0xf77 IdealProcessor   : UChar
   +0xf78 GuaranteedStackBytes : Uint4B
   +0xf7c ReservedForPerf  : Ptr32 Void
   +0xf80 ReservedForOle   : Ptr32 Void
   +0xf84 WaitingOnLoaderLock : Uint4B
   +0xf88 SavedPriorityState : Ptr32 Void
   +0xf8c SoftPatchPtr1    : Uint4B
   +0xf90 ThreadPoolData   : Ptr32 Void
   +0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void
   +0xf98 MuiGeneration    : 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 FlsData          : Ptr32 Void
   +0xfb8 PreferredLanguages : Ptr32 Void
   +0xfbc UserPrefLanguages : Ptr32 Void
   +0xfc0 MergedPrefLanguages : Ptr32 Void
   +0xfc4 MuiImpersonation : Uint4B
   +0xfc8 CrossTebFlags    : Uint2B
   +0xfc8 SpareCrossTebBits : Pos 0, 16 Bits
   +0xfca SameTebFlags     : Uint2B
   +0xfca SafeThunkCall    : Pos 0, 1 Bit
   +0xfca InDebugPrint     : Pos 1, 1 Bit
   +0xfca HasFiberData     : Pos 2, 1 Bit
   +0xfca SkipThreadAttach : Pos 3, 1 Bit
   +0xfca WerInShipAssertCode : Pos 4, 1 Bit
   +0xfca RanProcessInit   : Pos 5, 1 Bit
   +0xfca ClonedThread     : Pos 6, 1 Bit
   +0xfca SuppressDebugMsg : Pos 7, 1 Bit
   +0xfca DisableUserStackWalk : Pos 8, 1 Bit
   +0xfca RtlExceptionAttached : Pos 9, 1 Bit
   +0xfca InitialThread    : Pos 10, 1 Bit
   +0xfca SpareSameTebBits : Pos 11, 5 Bits
   +0xfcc TxnScopeEnterCallback : Ptr32 Void
   +0xfd0 TxnScopeExitCallback : Ptr32 Void
   +0xfd4 TxnScopeContext  : Ptr32 Void
   +0xfd8 LockCount        : Uint4B
   +0xfdc SpareUlong0      : Uint4B
   +0xfe0 ResourceRetValue : Ptr32 Void

这是一个完整的TEB结构,我这里也有一份pteb.h的头文件

typedef struct _NT_TEB
{
   NT_TIB Tib;                         // 00h
   PVOID EnvironmentPointer;           // 1Ch
   CLIENT_ID Cid;                      // 20h
   PVOID ActiveRpcInfo;                // 28h
   PVOID ThreadLocalStoragePointer;    // 2Ch
   PPEB Peb;                           // 30h
   ULONG LastErrorValue;               // 34h
   ULONG CountOfOwnedCriticalSections; // 38h
   PVOID CsrClientThread;              // 3Ch
   PVOID Win32ThreadInfo;              // 40h
   ULONG Win32ClientInfo[0x1F];        // 44h
   PVOID WOW32Reserved;                // C0h
   ULONG CurrentLocale;                // C4h
   ULONG FpSoftwareStatusRegister;     // C8h
   PVOID SystemReserved1[0x36];        // CCh
   PVOID Spare1;                       // 1A4h
   LONG ExceptionCode;                 // 1A8h
   ULONG SpareBytes1[0x28];            // 1ACh
   PVOID SystemReserved2[0xA];         // 1D4h
   GDI_TEB_BATCH GdiTebBatch;          // 1FCh
   ULONG gdiRgn;                       // 6DCh
   ULONG gdiPen;                       // 6E0h
   ULONG gdiBrush;                     // 6E4h
   CLIENT_ID RealClientId;             // 6E8h
   PVOID GdiCachedProcessHandle;       // 6F0h
   ULONG GdiClientPID;                 // 6F4h
   ULONG GdiClientTID;                 // 6F8h
   PVOID GdiThreadLocaleInfo;          // 6FCh
   PVOID UserReserved[5];              // 700h
   PVOID glDispatchTable[0x118];       // 714h
   ULONG glReserved1[0x1A];            // B74h
   PVOID glReserved2;                  // BDCh
   PVOID glSectionInfo;                // BE0h
   PVOID glSection;                    // BE4h
   PVOID glTable;                      // BE8h
   PVOID glCurrentRC;                  // BECh
   PVOID glContext;                    // BF0h
   NTSTATUS LastStatusValue;           // BF4h
   UNICODE_STRING StaticUnicodeString; // BF8h
   WCHAR StaticUnicodeBuffer[0x105];   // C00h
   PVOID DeallocationStack;            // E0Ch
   PVOID TlsSlots[0x40];               // E10h
   LIST_ENTRY TlsLinks;                // F10h
   PVOID Vdm;                          // F18h
   PVOID ReservedForNtRpc;             // F1Ch
   PVOID DbgSsReserved[0x2];           // F20h
   ULONG HardErrorDisabled;            // F28h
   PVOID Instrumentation[0x10];        // F2Ch
   PVOID WinSockData;                  // F6Ch
   ULONG GdiBatchCount;                // F70h
   ULONG Spare2;                       // F74h
   ULONG Spare3;                       // F78h
   ULONG Spare4;                       // F7Ch
   PVOID ReservedForOle;               // F80h
   ULONG WaitingOnLoaderLock;          // F84h

PVOID StackCommit;                  // F88h
   PVOID StackCommitMax;               // F8Ch
   PVOID StackReserve;                 // F90h

PVOID MessageQueue;                 // ???
} NT_TEB, *PNT_TEB;

看到没有  :

+0x030 ProcessEnvironmentBlock : Ptr32 _PEB

PPEB Peb;                           // 30h

TEB偏移的0x30地址就是PEB的地址,下面来看看PEB的结构:

typedef struct _PEB
{
   UCHAR InheritedAddressSpace;                     // 00h
   UCHAR ReadImageFileExecOptions;                  // 01h
   UCHAR BeingDebugged;                             // 02h
   UCHAR Spare;                                     // 03h
   PVOID Mutant;                                    // 04h
   PVOID ImageBaseAddress;                          // 08h
   PPEB_LDR_DATA Ldr;                               // 0Ch
   PRTL_USER_PROCESS_PARAMETERS ProcessParameters;  // 10h
   PVOID SubSystemData;                             // 14h
   PVOID ProcessHeap;                               // 18h
   PVOID FastPebLock;                               // 1Ch
   PPEBLOCKROUTINE FastPebLockRoutine;              // 20h
   PPEBLOCKROUTINE FastPebUnlockRoutine;            // 24h
   ULONG EnvironmentUpdateCount;                    // 28h
   PVOID* KernelCallbackTable;                      // 2Ch
   PVOID EventLogSection;                           // 30h
   PVOID EventLog;                                  // 34h
   PPEB_FREE_BLOCK FreeList;                        // 38h
   ULONG TlsExpansionCounter;                       // 3Ch
   PVOID TlsBitmap;                                 // 40h
   ULONG TlsBitmapBits[0x2];                        // 44h
   PVOID ReadOnlySharedMemoryBase;                  // 4Ch
   PVOID ReadOnlySharedMemoryHeap;                  // 50h
   PVOID* ReadOnlyStaticServerData;                 // 54h
   PVOID AnsiCodePageData;                          // 58h
   PVOID OemCodePageData;                           // 5Ch
   PVOID UnicodeCaseTableData;                      // 60h
   ULONG NumberOfProcessors;                        // 64h
   ULONG NtGlobalFlag;                              // 68h
   UCHAR Spare2[0x4];                               // 6Ch
   LARGE_INTEGER CriticalSectionTimeout;            // 70h
   ULONG HeapSegmentReserve;                        // 78h
   ULONG HeapSegmentCommit;                         // 7Ch
   ULONG HeapDeCommitTotalFreeThreshold;            // 80h
   ULONG HeapDeCommitFreeBlockThreshold;            // 84h
   ULONG NumberOfHeaps;                             // 88h
   ULONG MaximumNumberOfHeaps;                      // 8Ch
   PVOID** ProcessHeaps;                            // 90h
   PVOID GdiSharedHandleTable;                      // 94h
   PVOID ProcessStarterHelper;                      // 98h
   PVOID GdiDCAttributeList;                        // 9Ch
   PVOID LoaderLock;                                // A0h
   ULONG OSMajorVersion;                            // A4h
   ULONG OSMinorVersion;                            // A8h
   ULONG OSBuildNumber;                             // ACh
   ULONG OSPlatformId;                              // B0h
   ULONG ImageSubSystem;                            // B4h
   ULONG ImageSubSystemMajorVersion;                // B8h
   ULONG ImageSubSystemMinorVersion;                // C0h
   ULONG GdiHandleBuffer[0x22];                     // C4h

PVOID ProcessWindowStation;                      // ???
} PEB, *PPEB;

PVOID ImageBaseAddress;                          // 08h
//偏移08h的地址就是程序的基址,往上看,

UCHAR BeingDebugged;                             // 02h,这里就表示程序是否是在被调试模式了。

接下来,咱们就用ollydbg来调试看看这些数据了,记住,并没有那么神秘的。


我这里写一个小程序里面就调用一个函数GetModuleHandle,咱们要做的就是跟进这个函数去看看

这个就是这个函数的执行体了,咱们要关心的就是7C80B764这个地址的一句:

mov eax,dword ptr fs:[18]

fs:[0]寄存器里面存的就是指向TEB的地址,看看是什么地址啊,


看到没eax指向的就是TEB的地址,接着执行,teb地址偏移30由上面的头文件就可以看出是peb的地址了,


此时可以确定peb的地址就是0x7FFDE000了

由上面的PEB结构

PVOID ImageBaseAddress;                          // 08h
再偏移08h就是基址了

UCHAR BeingDebugged;                             // 02h

偏移2字节就是表示是否被调试跟踪了


偏移2处就是01了 ,呵呵 ,表示被调试跟踪了,偏移8是00400000,这就是基址了,可以证明了

如果自己用代码可以这么测试了:

mov     eax, fs:[30h]               ;指向 PEB

movzx   eax, byte ptr [eax + 2h]
or      al, al
jz      _Fine

如果等于0就是ok得了否则就被跟踪了。

//-----------------------------------------------------------------------------------------------------------------------------------------------------------

以上某些描述有些偏颇,以下是个人见解:

1、fs:[0]寄存器里面存的就是指向_NT_TIB.ExceptionList 指针

2、在Win XP下,进程环境块的地址对于每个进程来说并不固定,我在windows server2003 sp2和winxp sp2上测试过,其它版本上没有测试过

3、fs:[0x18] 地址指向线程环境块_TEB

上面两幅图诠释了内部结构:

1、取PEB地址指针有两种手段:

手段一、FS:[0x18]+0x30

手段二、FS:[0x30]

2、TIB结构实际被包含在TEB的首部

3、FS:[0]存放的是指向TIB结构的Exception List成员的指针

4、PEB首地址加上偏移0xC的位置存放的指向PEB_LDR_DATA的指针

5、PEB_LDR_DATA结构尾部实际上存放的是LIST_ENTRY的数组

6、InLoadOrderModuleList的FLINK存放的是指向LDR_MODULE的指针

7、LDR_MODULE结构的首部存放的是LIST_ENTRY结构的数组

基于以上实现遍历当前进程所有加载的模块:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int __cdecl _tmain(int argc, _TCHAR **argv, _TCHAR **envp)
{
void *pebAddr = NULL;
void *ldrAddr = NULL;
void *fLink = NULL;
void *p = NULL;
void *baseAddr = NULL;
void *dllName = NULL;
void *fullDllName = NULL;
void *entryPoint = NULL;
void *imageOfSize = NULL;
void *isDebuged = NULL;
__asm
{
mov eax,fs:[0x18]   ;取TEB首地址
add eax,0x30        ;PEB地址的指针
mov eax,[eax]       ;取PEB首地址
mov pebAddr,eax
}
ldrAddr = *(( void ** )(( BYTE* )pebAddr+0xC));
isDebuged = *(( void ** )(( BYTE* )pebAddr+0x02));
printf("当前程序%s被调试\n",((WORD)isDebuged) & 0x1?"正在":"没有");
printf("\n--------------------------按加载顺序遍历双向循环链表----------------------------\n\n");
fLink = *(( void ** )(( BYTE* )ldrAddr+0xC));//按加载顺序遍历双向循环链表
p = fLink;
printf(TEXT("\tPEB ADDRESS = \t0x%08X\n"),pebAddr);
printf(TEXT("\tLDR ADDRESS = \t0x%08X\n"),ldrAddr);
printf(TEXT("----------------------------------------------------\n"));
do
{
baseAddr = *(( void ** )(( BYTE* )p+0x18));
dllName = *(( void ** )(( BYTE* )p+0x30));
fullDllName = *(( void ** )(( BYTE* )p+0x28));
entryPoint = *(( void ** )(( BYTE* )p+0x1C));
imageOfSize = *(( void ** )(( BYTE* )p+0x20));
wprintf(L"\tModuleName:%s\n",dllName);
printf(TEXT("\t\tBase Address:0x%08X\n"),baseAddr);
wprintf(L"\t\tFull Module Name:%s\n",fullDllName);
printf(TEXT("\t\tentryPoint:0x%08X\n"),entryPoint);
printf(TEXT("\t\timageOfSize:0x%08X\n"),imageOfSize);
p = *( void ** )p;
} while (p!=fLink);
return (0);
}

FS TIB TEB PEB相关推荐

  1. 反调试/反汇编技术、TEB/PEB部分说明

    反调试技术 WindowsAPI ISDebuggerPresent 查询PEB进程环境块中的ISDebugged标志 CheckRemoteDebuggerPresent 类似于IsDebugger ...

  2. TEB,PEB,LDR结构

    首先查看TEB结构 TEB结构中第一个成员为TIB结构,从偏移量可以看出从0x00到0x1C之间的内容均为TIB结构的成员,为了方便理解,我将TIB结构在TEB中展开来查看 ntdll!_TEB+0x ...

  3. php滑动teb效果,PEB和TEB资料整合

    一.概念 TEB(Thread Environment Block,线程环境块)系统在此TEB中保存频繁使用的线程相关的数据.位于用户地址空间,在比 PEB 所在地址低的地方.进程中的每个线程都有自己 ...

  4. Thread Environment Block(TEB)

    TEB简介 TEB(Thread Environment Block,线程环境块)指线程环境块,该结构体包含进程中运行线程的各种信息,进程中的每个线程都对应着一个TEB结构体.不同OS中TEB结构体的 ...

  5. 通过PEB获取模块基址

    TEB偏移0x30处,即FS:[0x30]地址处保存着一个指针,指向PEB,PEB结构的偏移0xC处保存着另外一个指针ldr,该指针执行PEB_LDR_DATA PEB结构 typedef struc ...

  6. Windows 中 FS 段寄存器

    代码运行在RING0(系统地址空间)和RING3(用户地址空间)时,FS段寄存器分别指向GDT(全局描述符表)中不同段:在RING3下,FS段值是0x3B(这是WindowsXP下值:在Windows ...

  7. 利用FS寄存器获取KERNEL32.DLL基址算法的证明

    FS寄存器指向当前活动线程的TEB结构(线程结构) 偏移  说明 000  指向SEH链指针 004  线程堆栈顶部 008  线程堆栈底部 00C  SubSystemTib 010  FiberD ...

  8. mov eax,dword ptr fs:[0] 指令

    FS寄存器指向当前活动线程的TEB结构(线程结构) 偏移 说明 000 指向SEH链指针 004 线程堆栈顶部 008 线程堆栈底部 00C SubSystemTib 010 FiberData 01 ...

  9. 利用FS寄存器获取KERNEL32.DLL基址算法的证明(ZZ)

    转自:http://blog.csdn.net/int2e/archive/2008/01/09/2032732.aspx FS寄存器指向当前活动线程的TEB结构(线程结构) 偏移  说明 000  ...

最新文章

  1. matlab入门学习2
  2. sap内表 table_LINE
  3. 服务器维护 测试化验加工费,测试化验加工费.PPT
  4. Image:介绍一些跟图片有关的控件,如图片展示特效,图片生产,图片保护等
  5. tomcat路径配置详解
  6. jsencrypt代码分析——openssl的rsa加密解密在js的实现
  7. 计算机四级网络工程师考点速查,计算机四级《网络工程师》考点习题
  8. 梅州市2021普通高考成绩查询,梅州高考成绩查询入口
  9. css3-伪元素与伪类
  10. Codeforces 448 D. Multiplication Table
  11. 苹果CMSv10新手入门安装必看教程
  12. 微信朋友圈点赞生成器
  13. 超级右键-Mac右键扩展工具
  14. img和文字都居中对齐
  15. 【开发环境】Ubuntu 安装 Visual Studio Code 开发环境 ( 下载 Visual Studio Code 安装器 | Ubuntu 安装 deb 包 )
  16. python过去电脑网关不可用怎么办_电脑默认网关不可用怎么解决 Win7系统默认网关不可用终极解决方法...
  17. Android、iPhone和Java三个平台一致的加密方法
  18. 垃圾回收之G1收集过程
  19. R绘制股票走势图及年份成交量图
  20. 安装RHEL7.5超详细教程

热门文章

  1. python快速读取大数据
  2. python3网络请求_使用Python3和请求发送XMLHttpRequest并获取响应
  3. 《Spring实战》读书笔记_装配bean
  4. 电影TS、TC、BD版和HD版
  5. 公司最实用的软件——综合办公管理系统
  6. php domdocument soap,在PHP中使用SoapClient从WSDL获取元素
  7. beego框架 golang web项目-个人博客系统
  8. 网刻(批量部署瘦客户端)
  9. kotlin教程4:函数进阶
  10. 2023年淘宝天猫京东618活动时间安排和活动攻略