?? jiurl玩玩win2k進(jìn)程線程篇 teb.htm
字號(hào):
<!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進(jìn)程線程篇 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進(jìn)程線程篇 </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=宋體>
主頁(yè): <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=宋體> 日期: 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> TEB,Thread Environment Block,線程環(huán)境塊。位于用戶地址空間。在比 PEB
所在地址低的地方,比如 0x7FFDF000,0x7FFDE000。每個(gè)線程都有自己的一個(gè) TEB。由于 TEB
在用戶地址空間,所以本進(jìn)程中運(yùn)行在用戶模式下的代碼就可以訪問(wèn) TEB 結(jié)構(gòu)。Win2k Build 2195 中一個(gè)線程的 ETHREAD 結(jié)構(gòu)偏移
+020 處的 *Teb 指向這個(gè)線程的 TEB 結(jié)構(gòu)。在 undocumented.ntinternals.net
(需要注意的是這是個(gè)非官方的站點(diǎn))我們可以找到 TEB 及其相關(guān)結(jié)構(gòu)的定義。從 kd
中也可以找到一些相關(guān)結(jié)構(gòu)的定義。我們首先列出結(jié)構(gòu)的定義,然后對(duì)一些內(nèi)容進(jìn)行說(shuō)明。<BR><BR>// 來(lái)自
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>// 來(lái)自
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>指向結(jié)構(gòu)化異常處理(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>一個(gè)線程,有兩個(gè)自己的堆棧(Stack)。一個(gè)是內(nèi)核模式下的堆棧,一個(gè)是用戶模式下的堆棧。當(dāng)線程在內(nèi)核模式,也就是
ring0 下,執(zhí)行代碼的時(shí)候,使用的是內(nèi)核模式堆棧。當(dāng)線程在用戶模式下,也就是 ring3
下,執(zhí)行代碼的時(shí)候,使用的是用戶模式堆棧。某些只在內(nèi)核模式運(yùn)行的線程沒(méi)有用戶模式堆棧,比如 System
進(jìn)程(PID為8的進(jìn)程)的一些線程。<BR><BR>一個(gè)線程的用戶模式堆棧,位于用戶地址空間。線程 TEB 偏移 +04 處的 StackBase
是該線程用戶模式堆棧的最高地址,也就是開(kāi)始地址,堆棧是向下增長(zhǎng)的。線程 TEB 偏移 +08 處的 StackLimit
是該線程用戶模式堆棧的最低地址(有效部分)。<BR><BR>線程的內(nèi)核模式堆棧的信息在線程 ETHREAD 結(jié)構(gòu)中。<BR><BR><B>FS
段</B><BR><BR>在系統(tǒng)的許多函數(shù)的匯編代碼中我們進(jìn)程可以看到使用 fs 段。對(duì)于 x86 來(lái)說(shuō),分段機(jī)制是默認(rèn),并且必須使用的。Win2k
使用了平坦(Flat)模型,把段設(shè)為整個(gè)4G地址空間,隱藏了分段機(jī)制。不過(guò) fs
段是一個(gè)例外。對(duì)于運(yùn)行在用戶模式下,也就是運(yùn)行在ring3下的程序,fs 段是當(dāng)前線程的 TEB
所在地址空間。對(duì)于運(yùn)行在內(nèi)核模式下,也就是運(yùn)行在ring0下的程序,fs 段是從地址 FFDFF000 開(kāi)始,大小為 0x2000
的那部分地址空間。<BR><BR>下面我們使用 SoftICE 分別觀察在 ring3 執(zhí)行代碼的 FS段 和在 ring0 執(zhí)行代碼的
FS段。<BR><BR>ring3<BR><BR>在ring3執(zhí)行某一時(shí)刻的段寄存器和全局描述符表<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 ,說(shuō)明 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 對(duì)應(yīng)的段描述符,Base=7FFDE000 DPL=3<BR>//
當(dāng)前的線程的 TEB 就在 7FFDE000 開(kāi)始處的 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 <BR><BR>剛才的ring3程序進(jìn)行系統(tǒng)調(diào)用,產(chǎn)生了 int
2e 中斷。當(dāng)轉(zhuǎn)到中斷2e的中斷處理程序時(shí),CPU
以及轉(zhuǎn)換了堆棧段,代碼段。中斷2e的中斷處理程序會(huì)把原來(lái)的fs段選擇符壓棧,將fs段選擇符賦值為30。<BR><BR>這時(shí)的段寄存器和全局描述符表<BR><BR><BR>//
注意 CS 和 SS ,CPL 已經(jīng)是 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 對(duì)應(yīng)的段描述符,Base=FFDFF000 DPL=0<BR>003B Data32 7FFDE000
00000FFF 3 P RW<BR>...<BR><BR>用戶模式下的 FS 段是當(dāng)前線程的 TEB。<BR>內(nèi)核模式下的 FS 段,是
FFDFF000 開(kāi)始的8KB(通常只有4KB映射了物理內(nèi)存)地址空間。它的內(nèi)容是和當(dāng)前線程有關(guān)的一些信息。其中<BR>偏移+00
處的4個(gè)字節(jié)是內(nèi)核模式下 EXCEPTION_REGISTRATION_RECORD *ExceptionList 。<BR>偏移+04
處的4個(gè)字節(jié),偏移+08 處的4個(gè)字節(jié),是和線程內(nèi)核堆棧有關(guān)的信息。<BR>偏移+124 處的4個(gè)字節(jié),是指向當(dāng)前線程的 ETHREAD
結(jié)構(gòu)的指針。<BR>注意 FFDFF000
開(kāi)始的這段地址空間中是當(dāng)前線程的有關(guān)信息,對(duì)于不同的線程,這段地址空間中的內(nèi)容也是不一樣。<BR><BR>為了方便觀察某個(gè)進(jìn)程地址空間中內(nèi)容,我寫(xiě)了一個(gè)叫
<A
href="http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/JiurlProcessMemSee.zip">JiurlProcessMemSee</A>
的程序,可以獲得指定進(jìn)程地址空間中的內(nèi)容。
<P>歡迎交流,歡迎交朋友,<BR>歡迎訪問(wèn) <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
可執(zhí)行文件及源程序</A><BR></P></TD></TR></TBODY></TABLE></DIV></BODY></HTML>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -