Win32 trådinformationsblok - Win32 Thread Information Block
I databehandling er Win32 Thread Information Block (TIB) en datastruktur i Win32 på x86, der gemmer oplysninger om den aktuelt kørende tråd . Det er også kendt som Thread Environment Block (TEB) til Win32. Det nedstammer fra og er bagudkompatibelt på 32-bit-systemer med en lignende struktur i OS / 2 .
TIB er officielt udokumenteret til Windows 9x. Windows NT-serien DDK (såvel som MinGW / ReactOS-implementeringen) inkluderer en struktur NT_TIB i winnt.h, der dokumenterer delsystemets uafhængige del. Selv før TIB blev effektivt dokumenteret, er mange applikationer allerede begyndt at bruge dens felter, at de effektivt er en del af API'et . Især det første felt, der indeholder SEH-rammen, henvises direkte til koden produceret af Microsofts egen kompilator. Den Win32-undersystemspecifikke del af TEB er udokumenteret, men Wine inkluderer en TEB-definition i winternl.h.
TIB kan bruges til at få en masse information om processen uden at ringe til Win32 API. Eksempler inkluderer emulering af GetLastError (), GetVersion (). Via markøren til PEB kan man få adgang til importtabellerne (IAT), procesopstartsargumenter, billednavne osv. Det tilgås fra FS-segmentregistret på 32-bit Windows og GS på 64-bit Windows.
Indholdet af TIB på Windows
Denne tabel er baseret på Wines arbejde med Microsoft Windows internals.
Bytes / Type |
offset (32-bit, FS) | offset (64-bit, GS) | Windows-versioner | Beskrivelse |
---|---|---|---|---|
markør | FS: [0x00] | GS: [0x00] | Win9x og NT | Nuværende struktureret undtagelse (SEH) ramme
Bemærk: 64-bit versionen af Windows bruger stakafvikling udført i kernetilstand i stedet. |
markør | FS: [0x04] | GS: [0x08] | Win9x og NT | Stakbase / bunden af stakken (høj adresse) |
markør | FS: [0x08] | GS: [0x10] | Win9x og NT | Stakbegrænsning / Loft af stak (lav adresse) |
markør | FS: [0x0C] | GS: [0x18] | NT | SubSystemTib |
markør | FS: [0x10] | GS: [0x20] | NT | Fiberdata |
markør | FS: [0x14] | GS: [0x28] | Win9x og NT | Vilkårlig dataport |
markør | FS: [0x18] | GS: [0x30] | Win9x og NT | Lineær adresse for TEB |
Slut på NT-subsystemuafhængig del nedenfor er Win32- afhængige | ||||
markør | FS: [0x1C] | GS: [0x38] | NT | Miljøpeger |
markør | FS: [0x20] | GS: [0x40] | NT | Proces-id (i nogle Windows-distributioner bruges dette felt som 'DebugContext') |
markør | FS: [0x24] | GS: [0x48] | NT | Nuværende tråd-ID |
markør | FS: [0x28] | GS: [0x50] | NT | Aktivt RPC-håndtag |
markør | FS: [0x2C] | GS: [0x58] | Win9x og NT | Lineær adresse på tråd-lokal lagring matrix |
markør | FS: [0x30] | GS: [0x60] | NT | Lineær adresse til Process Environment Block (PEB) |
4 | FS: [0x34] | GS: [0x68] | NT | Sidste fejlnummer |
4 | FS: [0x38] | GS: [0x6C] | NT | Optælling af ejede kritiske sektioner |
markør | FS: [0x3C] | GS: [0x70] | NT | Adresse på CSR-klienttråd |
markør | FS: [0x40] | GS: [0x78] | NT | Win32 trådinformation |
124 | FS: [0x44] | GS: [0x80] | NT, vin | Win32-klientinformation (NT), private32 private data (vin), 0x60 = LastError (Win95 & 98), 0x74 = LastError (WinME) |
markør | FS: [0xC0] | GS: [0x100] | NT | Reserveret til Wow64. Indeholder en markør til FastSysCall i Wow64. |
4 | FS: [0xC4] | GS: [0x108] | NT | Nuværende landestandard |
4 | FS: [0xC8] | GS: [0x10C] | NT | FP Software Status Register |
216 | FS: [0xCC] | GS: [0x110] | NT, vin | Reserveret til OS (NT), kernel32 private data (vin) heri: FS: [0x124] 4 NT Pointer to KTHREAD (ETHREAD) struktur |
4 | FS: [0x1A4] | GS: [0x2C0] | NT | Undtagelseskode |
18 | FS: [0x1A8] | GS: [0x2C8] | NT | Aktiveringskontekststak |
24 | FS: [0x1BC] | GS: [0x2E8] | NT, vin | Spare bytes (NT), ntdll private data (vin) |
40 | FS: [0x1D4] | GS: [0x300] | NT, vin | Reserveret til OS (NT), ntdll private data (Vin) |
1248 | FS: [0x1FC] | GS: [0x350] | NT, vin | GDI TEB Batch (OS), vm86 private data (vin) |
4 | FS: [0x6DC] | GS: [0x838] | NT | GDI-region |
4 | FS: [0x6E0] | GS: [0x840] | NT | GDI-pen |
4 | FS: [0x6E4] | GS: [0x848] | NT | GDI børste |
4 | FS: [0x6E8] | GS: [0x850] | NT | Ægte proces-id |
4 | FS: [0x6EC] | GS: [0x858] | NT | Ægte tråd-ID |
4 | FS: [0x6F0] | GS: [0x860] | NT | GDI cachelagret proceshåndtag |
4 | FS: [0x6F4] | GS: [0x868] | NT | GDI-klientproces-id (PID) |
4 | FS: [0x6F8] | GS: [0x86C] | NT | GDI-klienttråd-id (TID) |
4 | FS: [0x6FC] | GS: [0x870] | NT | Oplysninger om GDI-trådsprog |
20 | FS: [0x700] | GS: [0x878] | NT | Reserveret til brugerapplikation |
1248 | FS: [0x714] | GS: [0x890] | NT | Reserveret til GL (Se vinreferencer for interner) |
4 | FS: [0xBF4] | GS: [0x1250] | NT | Sidste statusværdi |
532 | FS: [0xBF8] | GS: [0x1258] | NT | Statisk UNICODE_STRING-buffer |
markør | FS: [0xE0C] | GS: [0x1478] | NT | Også kendt som DeallocationStack, etablerer den den virkelige startadresse for stakbufferen, deraf den virkelige stakgrænse: den er et par sider mindre end stabelbegrænsningsfeltet (som skjuler de beskyttelsessider, der bruges til at opdage stakoverløb). |
markør [] | FS: [0xE10] | GS: [0x1480] | NT | TLS-slots, 4/8 bytes pr. Slot, 64 slots |
8 | FS: [0xF10] | GS: [0x1680] | NT | TLS-links (LIST_ENTRY-struktur) |
4 | FS: [0xF18] | GS: [0x1690] | NT | VDM |
4 | FS: [0xF1C] | GS: [0x1698] | NT | Reserveret til RPC |
4 | FS: [0xF28] | GS: [0x16B0] | NT | Trådfejltilstand (RtlSetThreadErrorMode) |
4 | FS: [0xF78] | GS: [0x1748] | NT | Garanteret stakbyte |
Dette er ikke den fulde tabel; se vinreferencer for alle felter indtil FS: [0xfb4] / GS: [17c8]. Nyere Windows-versioner udvider størrelsen af TIB yderligere op til 0x1000 / 0x1838 i Windows 10. Nogle af de tilføjede felter fjernes, hvilket fører til modstridende definitioner. |
FS (til 32-bit) eller GS (til 64-bit) kort til en TIB, der er indlejret i en datablok kendt som TDB (tråddatabase). TIB indeholder den trådspecifikke undtagelseshåndteringskæde og markør til TLS (lokal lokal lagring.) Den lokale trådlagring er ikke den samme som lokal lokal C.
Stakoplysninger, der er gemt i TIB
En proces skal være fri til at flytte stakken af sine tråde, så længe den opdaterer de oplysninger, der er gemt i TIB i overensstemmelse hermed. Et par felter er nøglen til denne sag: stakbase, stakbegrænsning, deallocation-stak og garanterede stakbyte, der henholdsvis er lagret ved forskydninger 0x8, 0x10, 0x1478 og 0x1748 i 64 bit. Forskellige Windows-kernefunktioner læser og skriver disse værdier, specielt for at skelne stakoverløb fra andre læse- / skrivesidefejl (en læsning eller skrivning til en side, der er beskyttet blandt stakgrænserne i garanterede stakbyte, genererer en stakoverløbsundtagelse i stedet for en adgang krænkelse). Deallocation-stakken er vigtig, fordi Windows API giver mulighed for at ændre antallet af beskyttede sider: funktionen SetThreadStackGuarantee giver både mulighed for at læse det aktuelle rum og udvide det. For at læse det læser det GuaranteedStackBytes-feltet, og for at dyrke det bruger det ikke-forpligtende stak-sider. Indstilling af stakgrænser uden indstilling af DeallocationStack vil sandsynligvis medføre ulige adfærd i SetThreadStackGuarantee. For eksempel overskriver den stabelgrænserne til forkerte værdier. Forskellige biblioteker kalder SetThreadStackGuarantee, for eksempel bruger .NET CLR det til at oprette stakken af deres tråde.
Adgang til TIB
TIB af den nuværende tråd kan tilgås som en forskydning af segmentet register FS (x86) eller GS (x64).
Det er ikke almindeligt at få adgang til TIB-felterne ved en forskydning fra FS:[0]
, men først at få en lineær selvhenvisende markør til den gemt på FS:[18h]
. Denne markør kan bruges med markøraritmetik eller kastes til en struct- markør .
Ved hjælp af Microsoft Windows SDK eller lignende kunne en programmør bruge en integreret funktion defineret i winnt.h
navngivet, NtCurrentTeb
som returnerer adressen på den aktuelle trådinformationsblok som NT_TIB *
.
Alternative metoder til adgang for IA-32- arkitekturer er som følger:
// gcc (AT&T-style inline assembly).
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
#error unsupported architecture
#endif
return pTIB;
}
// gcc (named address spaces, same as the inline assembly version on -O1 or -ftree-ter).
void *getTIB(void) {
#if defined(__x86_64__) || defined(__amd64__)
#ifndef __SEG_GS
#error unsupported GCC version
#endif
return *(void *__seg_gs *) 0x30;
#elif defined(__i386__)
#ifndef __SEG_FS
#error unsupported GCC version
#endif
return *(void *__seg_fs *) 0x18;
#else
#error unsupported architecture
#endif
}
// Microsoft C
__declspec(naked)
void *getTIB() {
__asm mov EAX, FS:[18h]
__asm ret
}
// Using Microsoft's intrinsics instead of inline assembly (works for both X86 and X64 architectures)
void *getTIB() {
#ifdef _M_IX86
return (void *)__readfsdword(0x18);
#elif _M_AMD64
return (void *)__readgsqword(0x30);
#else
#error unsupported architecture
#endif
}
Se også
Referencer
Yderligere læsning
- Pietrek, Matt (marts 1996). Windows 95 programmeringshemmeligheder (pdf) . IDG. s. 136–138 . ISBN 978-1-56884-318-6 . Hentet 17.07.2010 .