Win32 trådinformationsblock
Inom datorer är Win32 Thread Information Block (TIB) en datastruktur i Win32 på x86 som lagrar information om den aktuella tråden . Det är också känt som trådmiljöblocket (TEB) för Win32. Den härstammar från och är bakåtkompatibel på 32-bitarssystem med en liknande struktur i OS/2 .
TIB är officiellt odokumenterad för Windows 9x. Windows NT-seriens DDK (liksom MinGW/ReactOS-implementeringen) inkluderar en struct NT_TIB i winnt.h som dokumenterar den delsystemoberoende delen. Redan innan TIB dokumenterades effektivt har många applikationer redan börjat använda dess fält att de faktiskt är en del av API: et . Det första fältet som innehåller SEH-ramen, i synnerhet, refereras direkt av koden som produceras av Microsofts egen kompilator. Den Win32-delsystemspecifika delen av TEB är odokumenterad, men Wine inkluderar en TEB-definition i winternl.h.
TIB kan användas för att få mycket information om processen utan att anropa Win32 API. Exempel inkluderar emulering av GetLastError(), GetVersion(). Genom pekaren till PEB kan man få tillgång till importtabellerna (IAT), processstartargument, bildnamn etc. Den nås från FS segmentregistret på 32-bitars Windows och GS på 64-bitars Windows.
Innehållet i TIB på Windows
Den här tabellen är baserad på Wines arbete med Microsoft Windows interna delar.
Byte/ typ |
offset (32-bitars, FS) | offset (64-bitars, GS) | Windows-versioner | Beskrivning |
---|---|---|---|---|
pekare | FS:[0x00] | GS:[0x00] | Win9x och NT | Current Structured Exception Handling (SEH) ram Obs: 64-bitarsversionen av Windows använder stack-avveckling i kärnläge istället. |
pekare | FS:[0x04] | GS:[0x08] | Win9x och NT | Stack Base / Botten av stapel (hög adress) |
pekare | FS:[0x08] | GS:[0x10] | Win9x och NT | Stapelgräns / tak för stapel (låg adress) |
pekare | FS:[0x0C] | GS:[0x18] | NT | SubSystemTib |
pekare | FS:[0x10] | GS:[0x20] | NT | Fiberdata |
pekare | FS:[0x14] | GS:[0x28] | Win9x och NT | Godtycklig dataplats |
pekare | FS:[0x18] | GS:[0x30] | Win9x och NT | Linjär adress för TEB |
Slutet av NT delsystem oberoende del; nedan är Win32 -beroende | ||||
pekare | FS:[0x1C] | GS:[0x38] | NT | Miljöpekare |
pekare | FS:[0x20] | GS:[0x40] | NT | Process ID (i vissa Windows-distributioner används detta fält som 'DebugContext') |
pekare | FS:[0x24] | GS:[0x48] | NT | Aktuellt tråd-ID |
pekare | FS:[0x28] | GS:[0x50] | NT | Aktivt RPC-handtag |
pekare | FS:[0x2C] | GS:[0x58] | Win9x och NT | Linjär adress för den trådlokala lagringsmatrisen |
pekare | FS:[0x30] | GS:[0x60] | NT | Linjär adress för Process Environment Block (PEB) |
4 | FS:[0x34] | GS:[0x68] | NT | Senaste felnummer |
4 | FS:[0x38] | GS:[0x6C] | NT | Antal ägda kritiska sektioner |
pekare | FS:[0x3C] | GS:[0x70] | NT | Adress till CSR Client Thread |
pekare | FS:[0x40] | GS:[0x78] | NT | Win32 trådinformation |
124 | FS:[0x44] | GS:[0x80] | NT, vin | Win32-klientinformation (NT), user32 privata data (Wine), 0x60 = LastError (Win95&98), 0x74 = LastError (WinME) |
pekare | FS:[0xC0] | GS:[0x100] | NT | Reserverad för Wow64. Innehåller en pekare till FastSysCall i Wow64. |
4 | FS:[0xC4] | GS:[0x108] | NT | Aktuell plats |
4 | FS:[0xC8] | GS:[0x10C] | NT | FP Software Status Register |
216 | FS:[0xCC] | GS:[0x110] | NT, vin |
Reserverad för OS (NT), kernel32 privata data (Wine) häri: FS:[0x124] 4 NT Pekare till KTHREAD (ETHREAD) struktur |
4 | FS:[0x1A4] | GS:[0x2C0] | NT | Undantagskod |
18 | FS:[0x1A8] | GS:[0x2C8] | NT | Aktiveringskontextstack |
24 | FS:[0x1BC] | GS:[0x2E8] | NT, vin | Reservbyte (NT), ntdll privata data (vin) |
40 | FS:[0x1D4] | GS:[0x300] | NT, vin | Reserverad för OS (NT), ntdll privata data (vin) |
1248 | FS:[0x1FC] | GS:[0x350] | NT, vin | GDI TEB Batch (OS), vm86 privata data (vin) |
4 | FS:[0x6DC] | GS:[0x838] | NT | GDI-regionen |
4 | FS:[0x6E0] | GS:[0x840] | NT | GDI Penna |
4 | FS:[0x6E4] | GS:[0x848] | NT | GDI-borste |
4 | FS:[0x6E8] | GS:[0x850] | NT | Verkligt process-ID |
4 | FS:[0x6EC] | GS:[0x858] | NT | Riktigt tråd-ID |
4 | FS:[0x6F0] | GS:[0x860] | NT | GDI-cachad processhandtag |
4 | FS:[0x6F4] | GS:[0x868] | NT | GDI-klientprocess-ID (PID) |
4 | FS:[0x6F8] | GS:[0x86C] | NT | GDI klienttråds-ID (TID) |
4 | FS:[0x6FC] | GS:[0x870] | NT | GDI-trådens språkinformation |
20 | FS:[0x700] | GS:[0x878] | NT | Reserverad för användarapplikation |
1248 | FS:[0x714] | GS:[0x890] | NT | Reserverad för GL (se vinreferens för interna delar) |
4 | FS:[0xBF4] | GS:[0x1250] | NT | Senaste statusvärde |
532 | FS:[0xBF8] | GS:[0x1258] | NT | Statisk UNICODE_STRING-buffert |
pekare | FS:[0xE0C] | GS:[0x1478] | NT | Även känd som DeallocationStack, fastställer den den verkliga startadressen för stackbufferten, därav den verkliga stackgränsen: den är några sidor mindre än stacklimitfältet (som döljer skyddssidorna som används för att upptäcka stackoverflows). |
pekare[] | FS:[0xE10] | GS:[0x1480] | NT | TLS-platser, 4/8 byte per plats, 64 platser |
8 | FS:[0xF10] | GS:[0x1680] | NT | TLS-länkar (LIST_ENTRY-struktur) |
4 | FS:[0xF18] | GS:[0x1690] | NT | VDM |
4 | FS:[0xF1C] | GS:[0x1698] | NT | Reserverad för RPC |
4 | FS:[0xF28] | GS:[0x16B0] | NT | Trådfelsläge (RtlSetThreadErrorMode) |
4 | FS:[0xF78] | GS:[0x1748] | NT | Garanterad stackbyte |
Detta är inte hela tabellen; se vinreferens för alla fält fram till FS:[0xfb4] / GS:[17c8]. Nyare Windows-versioner utökar storleken på TIB ytterligare, upp till 0x1000/0x1838 i Windows 10. Vissa av de bifogade fälten tas bort, vilket leder till motstridiga definitioner. |
FS (för 32-bitars) eller GS (för 64-bitars) mappar till en TIB som är inbäddad i ett datablock känt som TDB (tråddatabas). TIB innehåller den trådspecifika undantagshanteringskedjan och pekaren till TLS (tråd lokal lagring.) Trådens lokala lagring är inte samma som C lokal lagring.
Stapla information lagrad i TIB
En process bör vara fri att flytta stapeln av sina trådar så länge den uppdaterar informationen som lagras i TIB i enlighet därmed. Några fält är nyckeln till denna fråga: stackbas, stackgräns, avallokeringsstack och garanterade stackbytes, respektive lagrade med offset 0x8, 0x10, 0x1478 och 0x1748 i 64 bitar. Olika Windows-kärnfunktioner läser och skriver dessa värden, speciellt för att skilja stackoverflows från andra läs-/skrivsidafel (en läs eller skriv till en sida skyddad bland stackgränserna i garanterade stackbytes kommer att generera ett stack-overflow-undantag istället för en åtkomst överträdelse). Avallokeringsstacken är viktig eftersom Windows API tillåter att ändra antalet skyddade sidor: funktionen SetThreadStackGuarantee tillåter både att läsa det aktuella utrymmet och att växa det. För att kunna läsa den läser den fältet GuaranteedStackBytes, och för att växa måste den avbryta stacksidor. Att ställa in stackgränser utan att ställa in DeallocationStack kommer förmodligen att orsaka udda beteende i SetThreadStackGuarantee. Till exempel kommer den att skriva över stackgränserna till felaktiga värden. Olika bibliotek kallar SetThreadStackGuarantee, till exempel använder .NET CLR det för att sätta upp stacken av sina trådar.
Tillgång till TIB
TIB för den aktuella tråden kan nås som en offset av segmentregistret FS (x86) eller GS (x64).
Det är inte vanligt att komma åt TIB-fälten med en offset från FS:[0]
, utan att först få en linjär självrefererande pekare till den lagrad på FS:[18h]
. Den pekaren kan användas med pekarearitmetik eller gjutas till en strukturpekare .
Med hjälp av Microsoft Windows SDK eller liknande kan en programmerare använda en inline-funktion definierad i winnt.h
med namnet NtCurrentTeb
som returnerar adressen för det aktuella trådinformationsblocket som NT_TIB *
.
Alternativa metoder för åtkomst för IA-32- arkitekturer är följande:
// gcc (inline-sammansättning i AT&T-stil). void * getTIB ( void ) { register void * pTIB ; #if defined(__x86_64__) || defined(__amd64__) __asm__ ( "movq %%gs:0x30, %0" : "=r" ( pTIB )); #elif defined(__i386__) __asm__ ( "movl %%fs:0x18, %0" : "=r" ( pTIB )); #else #fel arkitektur som inte stöds #endif returnera pTIB ; }
// gcc (namngivna adressutrymmen, samma som inline-sammansättningsversionen på -O1 eller -ftree-ter). void * getTIB ( void ) { #if defined(__x86_64__) || defined(__amd64__) #ifndef __SEG_GS #fel stöds inte GCC-version #endif return * ( void * __seg_gs * ) 0x30 ; #elif definierad(__i386__) #ifndef __SEG_FS #fel stöds inte GCC-version #endif return * ( void * __seg_fs * ) 0x18 ; #annat #fel arkitektur som inte stöds #endif }
// Microsoft C __declspec ( naken ) void * getTIB ( ) { __asm mov EAX , FS : [ 18 h ] __asm ret }
// Använda Microsofts inneboende i stället för inline-sammansättning (fungerar för både X86- och X64-arkitekturer) void * getTIB () { #ifdef _M_IX86 return ( void * ) __readfsdword ( 0x18 ); #elif _M_AMD64 return ( void * ) __readgsqword ( 0x30 ); #annat #fel arkitektur som inte stöds #endif }
Se även
Vidare läsning
-
Pietrek, Matt (mars 1996). Windows 95-programmeringshemligheter (pdf) . IDG. s. 136–138 . ISBN 978-1-56884-318-6 . Hämtad 2010-07-17 .
{{ citera bok }}
: CS1 underhåll: url-status ( länk )