El Bloque de Información de Hilo ( TIB ) o Bloque de Entorno de Hilo ( TEB ) es una estructura de datos en Win32 para x86 que almacena información sobre el hilo que se está ejecutando actualmente. Deriva de una estructura similar en OS/2 y es compatible con versiones anteriores en sistemas de 32 bits con ella . [ 1 ]
El TIB no está documentado oficialmente para Windows 9x . El DDK de la serie Windows NT (así como la implementación de MinGW / ReactOS ) incluye una estructura que documenta la parte independiente del subsistema. Incluso antes de que el TIB estuviera documentado de manera efectiva, muchas aplicaciones ya habían comenzado a usar sus campos, que son efectivamente parte de la API . El primer campo que contiene el marco SEH , en particular, es referenciado por el código producido por el propio compilador de Microsoft. [ 1 ] La parte del TEB específica del subsistema Win32 no está documentada, pero Wine incluye una definición de TEB en . [ 2 ]NT_TIBwinnt.hwinternl.h
El TIB permite obtener mucha información sobre el proceso sin necesidad de llamar a la API de Win32. Algunos ejemplos incluyen la emulación de GetLastError(), GetVersion(). Mediante el puntero al PEB se puede acceder a las tablas de importación (IAT), los argumentos de inicio del proceso, el nombre de la imagen, etc. Se accede a él desde el registro de segmento FS en Windows de 32 bits y GS en Windows de 64 bits.
Contenido del TIB en Windows
Esta tabla se basa en el trabajo de Wine sobre los componentes internos de Microsoft Windows . [ 2 ]
FS (para 32 bits) o GS (para 64 bits) se asigna a un TIB que está integrado en un bloque de datos conocido como TDB (base de datos de subprocesos). El TIB contiene la cadena de manejo de excepciones específica del subproceso y un puntero al TLS (almacenamiento local de subprocesos). El almacenamiento local de subprocesos no es lo mismo que el almacenamiento local de C.
Información de la pila almacenada en el TIB
Un proceso debería poder mover libremente la pila de sus subprocesos siempre que actualice la información almacenada en el TIB de forma adecuada. Algunos campos son clave para este asunto: base de la pila, límite de la pila, pila de desasignación y bytes de pila garantizados, almacenados respectivamente en los desplazamientos 0x8, 0x10, 0x1478y 0x1748en 64 bits. Diferentes funciones del kernel de Windows leen y escriben estos valores, especialmente para distinguir los desbordamientos de pila de otros fallos de página de lectura/escritura (una lectura o escritura en una página protegida entre los límites de la pila en bytes de pila garantizados generará una excepción de desbordamiento de pila en lugar de una violación de acceso). La pila de desasignación es importante porque la API de Windows permite cambiar la cantidad de páginas protegidas: la función SetThreadStackGuaranteepermite tanto leer el espacio actual como aumentarlo. Para leerlo, lee el GuaranteedStackBytescampo y para aumentarlo, utiliza tiene que liberar páginas de la pila. Establecer límites de pila sin establecer DeallocationStackprobablemente causará un comportamiento extraño en SetThreadStackGuarantee. Por ejemplo, sobrescribirá los límites de la pila con valores incorrectos. Diferentes bibliotecas llaman a SetThreadStackGuarantee, por ejemplo, el CLR de .NET lo utiliza para configurar la pila de sus subprocesos.
Acceso al TIB
Se puede acceder al TIB del hilo actual como un desplazamiento del registro de segmento FS (x86) o GS (x64).
No es común acceder a los campos TIB mediante un desplazamiento desde FS:[0], sino que primero se obtiene un puntero autorreferencial lineal a él almacenado en FS:[18h]. Ese puntero se puede usar con aritmética de punteros o se puede convertir a un puntero de estructura .
Usando Microsoft Windows SDK o similar, un programador podría usar una función en línea definida en winnt.hllamada NtCurrentTebque devuelve la dirección del bloque de información de subproceso actual como NT_TIB *. [ 5 ]
Los métodos de acceso alternativos para las arquitecturas IA-32 son los siguientes:
// gcc (ensamblador en línea estilo 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 arquitectura no compatible #endif return pTIB ; }// gcc (espacios de direcciones con nombre, igual que la versión de ensamblador en línea en -O1 o -ftree-ter). void * getTIB ( void ) { #if defined(__x86_64__) || defined(__amd64__) #ifndef __SEG_GS #error versión de GCC no compatible #endif return * ( void * __seg_gs * ) 0x30 ; #elif defined(__i386__) #ifndef __SEG_FS #error versión de GCC no compatible #endif return * ( void * __seg_fs * ) 0x18 ; #else #error arquitectura no compatible #endif }// Microsoft C __declspec ( desnudo ) void * getTIB () { __asm mov EAX , FS : [ 18 h ] __asm ret }// Usando funciones intrínsecas de Microsoft en lugar de ensamblado en línea (funciona tanto para arquitecturas X86 como X64) void * getTIB () { #ifdef _M_IX86 return ( void * ) __readfsdword ( 0x18 ); #elif _M_AMD64 return ( void * ) __readgsqword ( 0x30 ); #else #error arquitectura no compatible #endif }Referencias
- 1 2 Pietrek, Matt (mayo de 1996). "Under The Hood" . Microsoft Systems Journal . Archivado del original el 14 de junio de 2009. Recuperado el 7 de julio de 2010 .
- 1 2 3 4 "wine winternl.h: typedef struct _TEB" . GitHub . wine-mirror. 29 de octubre de 2019.
- ↑ "Un vistazo más de cerca a la página de Stack Guard" . 3 de febrero de 2022.
- ↑ Chapell, Geoff. "TEB" .
- ↑ "Función NtCurrentTeb" . Microsoft Docs . Consultado el 20 de noviembre de 2019 .
Lecturas adicionales
- Pietrek, Matt (marzo de 1996). Secretos de programación de Windows 95 (pdf) . IDG. págs. 136-138 . ISBN 978-1-56884-318-6. Consultado el 17 de julio de 2010 .
Enlaces externos
- Diseño TEB en NTinternals.net
- Manejo estructurado de excepciones y TIB
- Descripción de las primeras ranuras del TIB
- Descripción de TEB, campo por campo
- Definiciones de TEB para varias versiones de Windows
- Arquitectura de Windows NT
- Interfaces de programación de aplicaciones de Microsoft
- Hilos (informática)