stringtranslate.com

Bloque de información del hilo Win32

El bloque de información de subprocesos ( TIB ) o el bloque de entorno de subprocesos ( TEB ) es una estructura de datos en Win32 en x86 que almacena información sobre el subproceso que se está ejecutando actualmente . Desciende de, y es compatible con versiones anteriores, sistemas de 32 bits con una estructura similar en OS/2 . [1]

El TIB no está oficialmente documentado para Windows 9x . El DDK de la serie Windows NT (así como la implementación MinGW / ReactOS ) incluye una estructura que documenta la parte independiente del subsistema. Incluso antes de que TIB se documentara efectivamente, muchas aplicaciones ya habían comenzado a usar sus campos que efectivamente forman parte de la API . El primer campo que contiene el marco SEH , en particular, está directamente 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 se puede utilizar para obtener mucha información sobre el proceso sin llamar a la API Win32. Los ejemplos incluyen emular GetLastError(), GetVersion(). A través del puntero al PEB se puede obtener acceso a las tablas de importación (IAT), argumentos de inicio del proceso, nombre de la imagen, etc. Se accede desde el registro del 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 en 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 del subproceso). El almacenamiento local del subproceso no es lo mismo que el almacenamiento local de C.

Información de pila almacenada en el TIB

Un proceso debería tener libertad para mover la pila de sus subprocesos siempre que actualice la información almacenada en el TIB en consecuencia. Algunos campos son clave para este asunto: base de pila, límite de pila, pila de desasignación y bytes de pila garantizados, almacenados respectivamente en desplazamientos 0x8, 0x10y 0x1478en 0x174864 bits. Diferentes funciones del kernel de Windows leen y escriben estos valores, especialmente para distinguir los desbordamientos de pila de otros fallos de lectura/escritura de páginas (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 un acceso). violación). 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 hacerlo crecer, utiliza las páginas de la pila que deben descomprimir. Establecer límites de pila sin configurar DeallocationStackprobablemente provocará un comportamiento extraño en archivos SetThreadStackGuarantee. Por ejemplo, sobrescribirá los límites de la pila con valores incorrectos. Diferentes bibliotecas llaman a SetThreadStackGuarantee, por ejemplo, .NET CLR lo usa para configurar la pila de sus subprocesos.

Accediendo 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 obtener primero un puntero lineal de autorreferencia almacenado en FS:[18h]. Ese puntero se puede usar con aritmética de punteros o convertirse en un puntero de estructura .

Usando el SDK de Microsoft Windows o similar, un programador podría usar una función en línea definida en winnt.hnombrado NtCurrentTebque devuelve la dirección del bloque de información del subproceso actual como NT_TIB *. [4]

Los métodos alternativos de acceso para las arquitecturas IA-32 son los siguientes:

// gcc (ensamblaje en línea estilo AT&T). vacío * getTIB ( vacío ) { registro vacío * pTIB ; #si está definido(__x86_64__) || definido(__amd64__) __asm__ ( "movq %%gs:0x30, %0" : "=r" ( pTIB )); #elif definido(__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 ensamblada en línea en -O1 o -ftree-ter). vacío * getTIB ( vacío ) { #si está definido (__x86_64__) || definido(__amd64__) #ifndef __SEG_GS #error versión GCC no compatible #endif return * ( void * __seg_gs * ) 0x30 ; #elif definido(__i386__) #ifndef __SEG_FS #error versión 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 los elementos intrínsecos de Microsoft en lugar del ensamblaje en línea (funciona para arquitecturas X86 y X64) void * getTIB () { #ifdef _M_IX86 return ( void * ) __readfsdword ( 0x18 ); #elif _M_AMD64 return ( void * ) __readgsqword ( 0x30 ); #else #error arquitectura no compatible #endif }        

Ver también

Referencias

  1. ^ ab Pietrek, Matt (mayo de 1996). "Bajo el capó". Revista de sistemas de Microsoft . Archivado desde el original el 14 de junio de 2009 . Consultado el 7 de julio de 2010 .
  2. ^ abcd "wine winternl.h: estructura typedef _TEB". GitHub . espejo de vino. 29 de octubre de 2019.
  3. ^ Capilla, Geoff. "TEB".
  4. ^ "Función NtCurrentTeb". Documentos de Microsoft . Consultado el 20 de noviembre de 2019 .

Otras lecturas

enlaces externos