Article de reference

Bloc d'informations sur le thread Win32

Le bloc d'informations de thread ( TIB ) ou bloc d'environnement de thread ( TEB ) est une structure de données Win32 sur x86 qui stocke des informations sur le thread en cours ...

Le bloc d'informations de thread ( TIB ) ou bloc d'environnement de thread ( TEB ) est une structure de données Win32 sur x86 qui stocke des informations sur le thread en cours d'exécution. Il est dérivé d' une structure similaire d' OS/2 et est rétrocompatible avec celle-ci sur les systèmes 32 bits .

Le TIB n'est officiellement pas documenté pour Windows 9x . Le DDK de la série Windows NT (ainsi que l' implémentation MinGW / ReactOS ) inclut une structure documentant la partie indépendante du sous-système. Avant même que le TIB ne soit correctement documenté, de nombreuses applications utilisaient déjà ses champs, qui font de facto partie de l' API . Le premier champ, contenant le cadre SEH , est notamment référencé par le code généré par le compilateur de Microsoft. La partie du TEB spécifique au sous-système Win32 n'est pas documentée, mais Wine inclut une définition du TEB . NT_TIBwinnt.hwinternl.h

Le TIB permet d'obtenir de nombreuses informations sur le processus sans faire appel à l'API Win32. Il peut notamment servir à émuler certaines fonctions GetLastError(). GetVersion()Grâce au pointeur vers le PEB , on accède aux tables d'importation (IAT), aux arguments de démarrage du processus, au nom de l'image, etc. Cet accès se fait via le registre de segment FS sur Windows 32 bits et GS sur Windows 64 bits.

Contenu du TIB sous Windows

Ce tableau est basé sur le travail de Wine sur les composants internes de Microsoft Windows .

FS (pour les systèmes 32 bits) ou GS (pour les systèmes 64 bits) correspond à un TIB (Thread Inventory Block) intégré dans un bloc de données appelé TDB (Thread Data Base). Le TIB contient la chaîne de gestion des exceptions spécifique au thread et un pointeur vers le TLS (Thread Local Storage). Le TLS est différent du stockage local en C.

Informations sur la pile stockées dans le TIB

Un processus doit pouvoir déplacer librement la pile de ses threads à condition de mettre à jour les informations stockées dans la TIB en conséquence. Quelques champs sont essentiels à cet égard : la base de la pile, la limite de la pile, la pile de désallocation et les octets de pile garantis, respectivement stockés aux décalages `<adresse_pile>` 0x8, 0x10` <limite_pile>` 0x1478et `<valeur_pile> 0x1748` sur 64 bits. Différentes fonctions du noyau Windows lisent et écrivent ces valeurs, notamment pour distinguer les débordements de pile des autres défauts de page en lecture/écriture (une lecture ou une écriture sur une page protégée par les limites de la pile dans les octets de pile garantis générera une exception de débordement de pile au lieu d'une violation d'accès). La pile de désallocation est importante car l'API Windows permet de modifier le nombre de pages protégées : la fonction `deallocation` SetThreadStackGuaranteepermet à la fois de lire l'espace courant et de l'étendre. Pour le lire, elle lit le GuaranteedStackByteschamp `<adresse_pile>`, et pour l'étendre, elle utilise `deallocation` pour libérer des pages de pile. Définir les limites de la pile sans définir `<valeur_pile>` DeallocationStackrisque d'entraîner un comportement inattendu SetThreadStackGuarantee. Par exemple, cela écrasera les limites de la pile avec des valeurs incorrectes. Différentes bibliothèques appellent `deallocation` SetThreadStackGuarantee, par exemple le CLR .NET l'utilise pour initialiser la pile de ses threads.

Accès au TIB

Le TIB du thread actuel peut être accédé comme un décalage du registre de segment FS (x86) ou GS (x64).

Il n'est pas courant d'accéder aux champs TIB par un décalage à partir de FS:[0], mais plutôt d'obtenir d'abord un pointeur linéaire autoréférentiel vers celui-ci stocké à FS:[18h]. Ce pointeur peut être utilisé avec l'arithmétique des pointeurs ou être converti en un pointeur de structure .

En utilisant le SDK Microsoft Windows ou un équivalent, un programmeur pourrait utiliser une fonction en ligne définie dans winnt.hnommée NtCurrentTebqui renvoie l'adresse du bloc d'informations du thread actuel sous la forme NT_TIB *.

Les méthodes d'accès alternatives pour les architectures IA-32 sont les suivantes :

// gcc (assembleur en ligne de style AT&T). 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 architecture non prise en charge #endif return pTIB ; }
// gcc (espaces d'adressage nommés, identiques à la version assembleur en ligne sur -O1 ou -ftree-ter). void * getTIB ( void ) { #if defined(__x86_64__) || defined(__amd64__) #ifndef __SEG_GS #error version GCC non prise en charge #endif return * ( void * __seg_gs * ) 0x30 ; #elif defined(__i386__) #ifndef __SEG_FS #error version GCC non prise en charge #endif return * ( void * __seg_fs * ) 0x18 ; #else #error architecture non prise en charge #endif }
// Microsoft C __declspec ( nu ) void * getTIB () { __asm ​​mov EAX , FS : [ 18 h ] __asm ​​ret }
// Utilisation des intrinsèques Microsoft au lieu de l'assembleur en ligne (fonctionne pour les architectures x86 et x64) void * getTIB () { #ifdef _M_IX86 return ( void * ) __readfsdword ( 0x18 ); #elif _M_AMD64 return ( void * ) __readgsqword ( 0x30 ); #else #error architecture non prise en charge #endif }

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index