Win32 trådinformationsblok - Win32 Thread Information Block

I databehandling er Win32 Thread Information Block (TIB) en datastruktur i Win32 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

eksterne links