⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jiurl玩玩win2k进程线程篇 teb.htm

📁 关于win2000核心编程的文章
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0066)http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/PsTeb.htm -->
<HTML><HEAD><TITLE>JIURL玩玩Win2k进程线程篇 TEB</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<STYLE type=text/css>.title {
	FONT-FAMILY: "黑体", Arial, sans-serif; FONT-SIZE: 21px; FONT-WEIGHT: bold; LINE-HEIGHT: 48px; TEXT-DECORATION: none
}
.author {
	FONT-FAMILY: "宋体"; FONT-SIZE: 12px; LINE-HEIGHT: 16px
}
.content {
	FONT-SIZE: 14px; LINE-HEIGHT: 20px
}
</STYLE>

<META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
<BODY bgColor=#f7f7f7 topMargin=5>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=29 width="96%">
  <TBODY>
  <TR>
    <TD class=title height=41 width="100%">
      <P align=center><FONT face=宋体>JIURL玩玩Win2k进程线程篇 </FONT><FONT 
      face=宋体>TEB</FONT></P></TD></TR></CENTER>
  <TR>
    <TD class=author height=9 width="100%">
      <P align=center><FONT face=宋体>作者: <A 
      href="mailto:jiurl@mail.china.com">JIURL</A> </FONT></P></TD></TR>
  <TR>
    <TD class=author height=6 width="100%">
      <P align=center><FONT 
      face=宋体>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      主页: <A href="http://jiurl.yeah.net/">http://jiurl.yeah.net/</A> 
    </FONT></P></TD></TR>
  <TR>
    <TD class=author height=2 width="100%">
      <P align=center><FONT face=宋体>&nbsp;&nbsp;&nbsp; 日期: 2003-7-30</FONT> 
    </P></TD></TR></TBODY></TABLE></DIV>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=1 width="96%">
  <TBODY>
  <TR>
    <TD height=1 width="100%">
      <HR color=#396da5 SIZE=3>
    </TD></TR></TBODY></TABLE></CENTER></DIV>
<DIV align=center>
<TABLE border=0 cellPadding=0 cellSpacing=0 class=content height=4097 
width="96%">
  <TBODY>
  <TR>
    <TD height=1929 vAlign=top width="131%">
      <P>&nbsp;&nbsp;&nbsp; TEB,Thread Environment Block,线程环境块。位于用户地址空间。在比 PEB 
      所在地址低的地方,比如 0x7FFDF000,0x7FFDE000。每个线程都有自己的一个 TEB。由于 TEB 
      在用户地址空间,所以本进程中运行在用户模式下的代码就可以访问 TEB 结构。Win2k Build 2195 中一个线程的 ETHREAD 结构偏移 
      +020 处的 *Teb 指向这个线程的 TEB 结构。在 undocumented.ntinternals.net 
      (需要注意的是这是个非官方的站点)我们可以找到 TEB 及其相关结构的定义。从 kd 
      中也可以找到一些相关结构的定义。我们首先列出结构的定义,然后对一些内容进行说明。<BR><BR>// 来自 
      undocumented.ntinternals.net<BR>typedef struct _TEB {<BR>NT_TIB 
      Tib;<BR>PVOID EnvironmentPointer;<BR>CLIENT_ID Cid;<BR>PVOID 
      ActiveRpcInfo;<BR>PVOID ThreadLocalStoragePointer;<BR>PPEB Peb;<BR>ULONG 
      LastErrorValue;<BR>ULONG CountOfOwnedCriticalSections;<BR>PVOID 
      CsrClientThread;<BR>PVOID Win32ThreadInfo;<BR>ULONG 
      Win32ClientInfo[0x1F];<BR>PVOID WOW32Reserved;<BR>ULONG 
      CurrentLocale;<BR>ULONG FpSoftwareStatusRegister;<BR>PVOID 
      SystemReserved1[0x36];<BR>PVOID Spare1;<BR>ULONG ExceptionCode;<BR>ULONG 
      SpareBytes1[0x28];<BR>PVOID SystemReserved2[0xA];<BR>ULONG 
      GdiRgn;<BR>ULONG GdiPen;<BR>ULONG GdiBrush;<BR>CLIENT_ID 
      RealClientId;<BR>PVOID GdiCachedProcessHandle;<BR>ULONG 
      GdiClientPID;<BR>ULONG GdiClientTID;<BR>PVOID 
      GdiThreadLocaleInfo;<BR>PVOID UserReserved[5];<BR>PVOID 
      GlDispatchTable[0x118];<BR>ULONG GlReserved1[0x1A];<BR>PVOID 
      GlReserved2;<BR>PVOID GlSectionInfo;<BR>PVOID GlSection;<BR>PVOID 
      GlTable;<BR>PVOID GlCurrentRC;<BR>PVOID GlContext;<BR>NTSTATUS 
      LastStatusValue;<BR>UNICODE_STRING StaticUnicodeString;<BR>WCHAR 
      StaticUnicodeBuffer[0x105];<BR>PVOID DeallocationStack;<BR>PVOID 
      TlsSlots[0x40];<BR>LIST_ENTRY TlsLinks;<BR>PVOID Vdm;<BR>PVOID 
      ReservedForNtRpc;<BR>PVOID DbgSsReserved[0x2];<BR>ULONG 
      HardErrorDisabled;<BR>PVOID Instrumentation[0x10];<BR>PVOID 
      WinSockData;<BR>ULONG GdiBatchCount;<BR>ULONG Spare2;<BR>ULONG 
      Spare3;<BR>ULONG Spare4;<BR>PVOID ReservedForOle;<BR>ULONG 
      WaitingOnLoaderLock;<BR>PVOID StackCommit;<BR>PVOID 
      StackCommitMax;<BR>PVOID StackReserved;<BR>} TEB, *PTEB;<BR><BR>// 来自 
      kd<BR>struct _NT_TIB (sizeof=28)<BR>+00 struct 
      _EXCEPTION_REGISTRATION_RECORD *ExceptionList<BR>+04 void 
      *StackBase<BR>+08 void *StackLimit<BR>+0c void *SubSystemTib<BR>+10 void 
      *FiberData<BR>+10 uint32 Version<BR>+14 void *ArbitraryUserPointer<BR>+18 
      struct _NT_TIB *Self<BR><BR>struct _CLIENT_ID (sizeof=8)<BR>+0 void 
      *UniqueProcess<BR>+4 void *UniqueThread<BR><BR>struct 
      _EXCEPTION_REGISTRATION_RECORD (sizeof=8)<BR>+0 struct 
      _EXCEPTION_REGISTRATION_RECORD *Next<BR>+4 function *Handler<BR><BR>struct 
      _UNICODE_STRING (sizeof=8)<BR>+0 uint16 Length<BR>+2 uint16 
      MaximumLength<BR>+4 uint16 *Buffer<BR><BR><B>异常处理链</B><BR><BR>struct 
      _TEB<BR>struct _NT_TIB (sizeof=28)<BR>+00 struct 
      _EXCEPTION_REGISTRATION_RECORD 
      *ExceptionList<BR><BR>指向结构化异常处理(SEH)链的指针。<BR><BR><B>线程用户模式下的堆栈</B><BR><BR>struct 
      _TEB<BR>struct _NT_TIB (sizeof=28)<BR>+04 void *StackBase<BR>+08 void 
      *StackLimit<BR><BR>一个线程,有两个自己的堆栈(Stack)。一个是内核模式下的堆栈,一个是用户模式下的堆栈。当线程在内核模式,也就是 
      ring0 下,执行代码的时候,使用的是内核模式堆栈。当线程在用户模式下,也就是 ring3 
      下,执行代码的时候,使用的是用户模式堆栈。某些只在内核模式运行的线程没有用户模式堆栈,比如 System 
      进程(PID为8的进程)的一些线程。<BR><BR>一个线程的用户模式堆栈,位于用户地址空间。线程 TEB 偏移 +04 处的 StackBase 
      是该线程用户模式堆栈的最高地址,也就是开始地址,堆栈是向下增长的。线程 TEB 偏移 +08 处的 StackLimit 
      是该线程用户模式堆栈的最低地址(有效部分)。<BR><BR>线程的内核模式堆栈的信息在线程 ETHREAD 结构中。<BR><BR><B>FS 
      段</B><BR><BR>在系统的许多函数的汇编代码中我们进程可以看到使用 fs 段。对于 x86 来说,分段机制是默认,并且必须使用的。Win2k 
      使用了平坦(Flat)模型,把段设为整个4G地址空间,隐藏了分段机制。不过 fs 
      段是一个例外。对于运行在用户模式下,也就是运行在ring3下的程序,fs 段是当前线程的 TEB 
      所在地址空间。对于运行在内核模式下,也就是运行在ring0下的程序,fs 段是从地址 FFDFF000 开始,大小为 0x2000 
      的那部分地址空间。<BR><BR>下面我们使用 SoftICE 分别观察在 ring3 执行代码的 FS段 和在 ring0 执行代码的 
      FS段。<BR><BR>ring3<BR><BR>在ring3执行某一时刻的段寄存器和全局描述符表<BR><BR>:r 
      -d<BR>CS:EIP=001B:00401919 SS:ESP=0023:0012FE20<BR>EAX=00000001 
      EBX=7FFDF000 ECX=0012FFB0 EDX=00040000<BR>ESI=0012FE20 EDI=0012FF80 
      EBP=0012FF80 EFL=00000246<BR>DS=0023 ES=0023 FS=0038 GS=0000<BR><BR>注意 CS 
      为 1B ,说明 CPL 为 ring3。注意 FS 段选择符。<BR><BR>:gdt<BR>Sel. Type Base Limit DPL 
      Attributes<BR>GDTbase=80036000 Limit=03FF<BR>0008 Code32 00000000 FFFFFFFF 
      0 P RE<BR>0010 Data32 00000000 FFFFFFFF 0 P RW<BR>001B Code32 00000000 
      FFFFFFFF 3 P RE<BR>0023 Data32 00000000 FFFFFFFF 3 P RW<BR>0028 TSS32 
      801F4000 000020AB 0 P B<BR>0030 Data32 FFDFF000 00001FFF 0 P RW<BR>003B 
      Data32 7FFDE000 00000FFF 3 P RW<BR>// FS 对应的段描述符,Base=7FFDE000 DPL=3<BR>// 
      当前的线程的 TEB 就在 7FFDE000 开始处的 4KB 地址空间中。<BR>0043 Data16 00000400 0000FFFF 3 
      P RW<BR>0048 Reserved 00000000 00000000 0 NP<BR>0050 TSS32 80470040 
      00000068 0 P<BR>...<BR><BR><BR>ring0&nbsp;<BR><BR>刚才的ring3程序进行系统调用,产生了 int 
      2e 中断。当转到中断2e的中断处理程序时,CPU 
      以及转换了堆栈段,代码段。中断2e的中断处理程序会把原来的fs段选择符压栈,将fs段选择符赋值为30。<BR><BR>这时的段寄存器和全局描述符表<BR><BR><BR>// 
      注意 CS 和 SS ,CPL 已经是 ring0 了。注意 FS 值为30。<BR>:r -d<BR>CS:EIP=0008:804615DD 
      SS:ESP=0010:EF0B5DB4<BR>EAX=00000038 EBX=00000030 ECX=80002000 
      EDX=0012FD9C<BR>ESI=00000000 EDI=0012FF80 EBP=0012FDF8 
      EFL=00000002<BR>DS=0023 ES=0023 FS=0030 GS=0000<BR><BR>:gdt<BR>Sel. Type 
      Base Limit DPL Attributes<BR>GDTbase=80036000 Limit=03FF<BR>0008 Code32 
      00000000 FFFFFFFF 0 P RE<BR>0010 Data32 00000000 FFFFFFFF 0 P RW<BR>001B 
      Code32 00000000 FFFFFFFF 3 P RE<BR>0023 Data32 00000000 FFFFFFFF 3 P 
      RW<BR>0028 TSS32 801F4000 000020AB 0 P B<BR>0030 Data32 FFDFF000 00001FFF 
      0 P RW<BR>// FS 对应的段描述符,Base=FFDFF000 DPL=0<BR>003B Data32 7FFDE000 
      00000FFF 3 P RW<BR>...<BR><BR>用户模式下的 FS 段是当前线程的 TEB。<BR>内核模式下的 FS 段,是 
      FFDFF000 开始的8KB(通常只有4KB映射了物理内存)地址空间。它的内容是和当前线程有关的一些信息。其中<BR>偏移+00 
      处的4个字节是内核模式下 EXCEPTION_REGISTRATION_RECORD *ExceptionList 。<BR>偏移+04 
      处的4个字节,偏移+08 处的4个字节,是和线程内核堆栈有关的信息。<BR>偏移+124 处的4个字节,是指向当前线程的 ETHREAD 
      结构的指针。<BR>注意 FFDFF000 
      开始的这段地址空间中是当前线程的有关信息,对于不同的线程,这段地址空间中的内容也是不一样。<BR><BR>为了方便观察某个进程地址空间中内容,我写了一个叫 
      <A 
      href="http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/JiurlProcessMemSee.zip">JiurlProcessMemSee</A> 
      的程序,可以获得指定进程地址空间中的内容。 
      <P>欢迎交流,欢迎交朋友,<BR>欢迎访问 <A 
      href="http://jiurl.yeah.net/">http://jiurl.yeah.net/</A> <A 
      href="http://jiurl.cosoft.org.cn/forum">http://jiurl.cosoft.org.cn/forum</A> 

      <P>  
      <P><A 
      href="http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/JiurlProcessMemSee.zip">下载 
      JiurlProcessMemSee 
可执行文件及源程序</A><BR></P></TD></TR></TBODY></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -