Блок информации о потоке Win32
![]() | Эту статью необходимо обновить . ( декабрь 2013 г. ) |
Блок информации о потоке ( TIB ) или блок среды потока ( TEB ) — это структура данных в Win32 на x86 , которая хранит информацию о текущем выполняющемся потоке . и обратно совместим с 32-битными системами Он произошел от аналогичной структуры OS/2 . [1]
TIB официально не документирован для Windows 9x . DDK Windows NT серии / а также реализация MinGW ( ReactOS ) включает структуру NT_TIB
в winnt.h
который документирует независимую часть подсистемы. Еще до того, как TIB был эффективно задокументирован, многие приложения уже начали использовать его поля, которые фактически являются частью API . В частности, на первое поле, содержащее кадр SEH , напрямую ссылается код, созданный собственным компилятором Microsoft. [1] Часть TEB, специфичная для подсистемы Win32, недокументирована, но Wine включает определение TEB в winternl.h
. [2]
TIB можно использовать для получения большого количества информации о процессе без вызова Win32 API. Примеры включают эмуляцию GetLastError()
, GetVersion()
. Через указатель на PEB можно получить доступ к таблицам импорта (IAT), аргументам запуска процесса, имени образа и т. д. Доступ к нему осуществляется из регистра сегмента FS в 32-битной Windows и GS в 64-битной Windows.
Содержимое TIB в Windows
[ редактировать ]Эта таблица основана на Wine работе над внутренними компонентами Microsoft Windows . [2]
Байт/ Тип | смещение (32-битное, ФС) | смещение (64-бит, GS) | Версии Windows | Описание |
---|---|---|---|---|
указатель | ФС:[0x00] | ГС:[0x00] | Вин9х и НТ | Текущий кадр структурированной обработки исключений (SEH) Примечание. В 64-разрядной версии Windows вместо этого используется раскрутка стека , выполняемая в режиме ядра . |
указатель | ФС:[0x04] | ГС:[0x08] | Вин9х и НТ | База стека /нижняя часть стека (верхний адрес) |
указатель | ФС:[0x08] | ГС:[0x10] | Вин9х и НТ | Предел стека/потолок стека (нижний адрес) |
указатель | ФС:[0x0C] | ГС:[0x18] | НТ | SubSystemTib |
указатель | ФС:[0x10] | ГС:[0x20] | НТ | Данные о оптоволокне |
указатель | ФС:[0x14] | ГС:[0x28] | Вин9х и НТ | Произвольный слот данных |
указатель | ФС:[0x18] | ГС:[0x30] | Вин9х и НТ | Линейный адрес ТЭБ |
Конец независимой части подсистемы NT ; ниже Win32 зависят от | ||||
указатель | ФС:[0x1C] | ГС:[0x38] | НТ | Указатель среды |
указатель | ФС:[0x20] | ГС:[0x40] | НТ | Идентификатор процесса (в некоторых дистрибутивах Windows это поле используется как DebugContext ) |
указатель | ФС:[0x24] | ГС:[0x48] | НТ | Текущий идентификатор потока |
указатель | ФС:[0x28] | ГС:[0x50] | НТ | Активный дескриптор RPC |
указатель | ФС:[0x2C] | ГС:[0x58] | Вин9х и НТ | Линейный адрес локальной памяти потока массива |
указатель | ФС:[0x30] | ГС:[0x60] | НТ | Линейный адрес блока технологической среды (PEB) |
4 | ФС:[0x34] | ГС:[0x68] | НТ | Последний номер ошибки |
4 | ФС:[0x38] | ГС:[0x6C] | НТ | Количество принадлежащих критических секций |
указатель | ФС:[0x3C] | ГС:[0x70] | НТ | Адрес клиентского потока CSR |
указатель | ФС:[0x40] | ГС:[0x78] | НТ | Информация о потоке Win32 |
124 | ФС:[0x44] | ГС:[0x80] | Северная Каролина, Вино | Информация о клиенте Win32 (NT), личные данные пользователя32 (Wine), 0x60 = LastError (Win95 и 98), 0x74 = LastError (WinME) |
указатель | ФС:[0xC0] | ГС:[0x100] | НТ | Зарезервировано для Wow64. Содержит указатель на FastSysCall в Вау64. |
4 | ФС:[0xC4] | ГС:[0x108] | НТ | Текущая локаль |
4 | ФС:[0xC8] | ГС:[0x10C] | НТ | Регистр состояния программного обеспечения FP |
216 | ФС:[0xCC] | ГС:[0x110] | Северная Каролина, Вино | Зарезервировано для ОС (NT), личных данных kernel32 (Wine) здесь: FS:[0x124] 4 NT Указатель на KTHREAD ( ETHREAD ) структура |
4 | ФС:[0x1A4] | ГС:[0x2C0] | НТ | Код исключения |
18 | ФС:[0x1A8] | ГС:[0x2C8] | НТ | Стек контекста активации |
24 | ФС:[0x1BC] | ГС:[0x2E8] | Северная Каролина, Вино | Запасные байты (NT), частные данные ntdll (Wine) |
40 | ФС:[0x1D4] | ГС:[0x300] | Северная Каролина, Вино | Зарезервировано для ОС (NT), личных данных ntdll (Wine) |
1248 | ФС:[0x1FC] | ГС:[0x350] | Северная Каролина, Вино | GDI TEB Batch (ОС), личные данные vm86 (Wine) |
4 | ФС:[0x6DC] | ГС:[0x838] | НТ | Регион GDI |
4 | ФС:[0x6E0] | ГС:[0x840] | НТ | Ручка GDI |
4 | ФС:[0x6E4] | ГС:[0x848] | НТ | Кисть GDI |
4 | ФС:[0x6E8] | ГС:[0x850] | НТ | Реальный идентификатор процесса |
4 | ФС:[0x6EC] | ГС:[0x858] | НТ | Реальный идентификатор потока |
4 | ФС:[0x6F0] | ГС:[0x860] | НТ | Дескриптор кэшированного процесса GDI |
4 | ФС:[0x6F4] | ГС:[0x868] | НТ | Идентификатор процесса клиента GDI (PID) |
4 | ФС:[0x6F8] | ГС:[0x86C] | НТ | Идентификатор потока клиента GDI (TID) |
4 | ФС:[0x6FC] | ГС:[0x870] | НТ | Информация о локали потока GDI |
20 | ФС:[0x700] | ГС:[0x878] | НТ | Зарезервировано для пользовательского приложения |
1248 | ФС:[0x714] | ГС:[0x890] | НТ | Зарезервировано для GL (внутренние части см. в ссылке на вино) [2] |
4 | ФС:[0xBF4] | ГС:[0x1250] | НТ | Последнее значение статуса |
532 | ФС:[0xBF8] | ГС:[0x1258] | НТ | Статический UNICODE_STRING буфер |
указатель | ФС:[0xE0C] | ГС:[0x1478] | НТ | Также известен как DeallocationStack , он устанавливает реальный начальный адрес буфера стека, следовательно, реальный предел стека: он на несколько страниц меньше, чем поле предела стека (которое скрывает защитные страницы, используемые для обнаружения переполнения стека). |
указатель[] | ФС:[0xE10] | ГС:[0x1480] | НТ | Слоты TLS, 4/8 байт на слот, 64 слота |
8 | ФС:[0xF10] | ГС:[0x1680] | НТ | TLS-ссылки ( LIST_ENTRY структура) |
4 | ФС:[0xF18] | ГС:[0x1690] | НТ | ВДМ |
4 | ФС:[0xF1C] | ГС:[0x1698] | НТ | Зарезервировано для RPC |
4 | ФС:[0xF28] | ГС:[0x16B0] | НТ | Режим ошибки потока ( RtlSetThreadErrorMode ) |
4 | ФС:[0xF78] | ГС:[0x1748] | НТ | Гарантированные байты стека |
Это не полная таблица; см. Wine Ref для всех полей до FS:[0xfb4] / GS:[17c8]. [2] В более новых версиях Windows размер TIB еще больше увеличен до 0x1000/0x1838 в Windows 10. Некоторые из добавленных полей удалены, что приводит к противоречивым определениям. [3] |
FS (для 32-разрядной версии) или GS (для 64-разрядной версии) отображается в TIB, который встроен в блок данных, известный как TDB (база данных потока). TIB содержит цепочку обработки исключений, специфичную для потока, и указатель на TLS (локальное хранилище потока). Локальное хранилище потока — это не то же самое, что локальное хранилище C.
Информация стека хранится в TIB
[ редактировать ]Процесс должен иметь возможность свободно перемещать стек своих потоков, пока он соответствующим образом обновляет информацию, хранящуюся в TIB. Несколько полей являются ключевыми в этом вопросе: база стека, предел стека, стек освобождения и гарантированные байты стека, которые соответственно хранятся по смещениям. 0x8
, 0x10
, 0x1478
и 0x1748
в 64 битах. Windows Различные функции ядра читают и записывают эти значения, в частности, чтобы отличить переполнение стека от других ошибок чтения/записи страницы (чтение или запись на страницу, защищенную пределами стека в гарантированных байтах стека, вместо доступа будет генерировать исключение переполнения стека). нарушение). Стек освобождения важен, поскольку Windows API позволяет изменять количество защищенных страниц: функция SetThreadStackGuarantee
позволяет как читать текущее пространство, так и увеличивать его. Чтобы прочитать его, он читает GuaranteedStackBytes
поле, и для его увеличения он использует страницы стека must uncommit. Установка ограничений стека без настройки DeallocationStack
вероятно, вызовет странное поведение в SetThreadStackGuarantee
. Например, он перезапишет ограничения стека на неверные значения. Различные библиотеки называют SetThreadStackGuarantee
, например, .NET CLR использует его для настройки стека своих потоков.
Доступ к TIB
[ редактировать ]Доступ к TIB текущего потока можно получить как смещение регистра сегмента FS (x86) или GS (x64).
Доступ к полям TIB по смещению от FS:[0]
, а сначала получить на него линейный самоссылающийся указатель, хранящийся по адресу FS:[18h]
. Этот указатель можно использовать с арифметикой указателей или привести к структуры указателю .
Используя Microsoft Windows SDK или аналогичный, программист может использовать встроенную функцию, определенную в winnt.h
названный NtCurrentTeb
который возвращает адрес текущего блока информации о потоке как NT_TIB *
. [4]
Альтернативные методы доступа для IA-32 архитектур :
// 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}
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Jump up to: а б Пьетрек, Мэтт (май 1996 г.). «Под капотом» . Системный журнал Microsoft . Архивировано из оригинала 14 июня 2009 г. Проверено 7 июля 2010 г.
- ^ Jump up to: а б с д "wine Winternl.h: typedef struct _TEB" . Гитхаб . вино-зеркало. 29 октября 2019 г.
- ^ Чапелл, Джефф. «ТЭБ» .
- ^ «Функция NtCurrentTeb» . Документы Майкрософт . Проверено 20 ноября 2019 г.
Дальнейшее чтение
[ редактировать ]- Пьетрек, Мэтт (март 1996 г.). Секреты программирования для Windows 95 (pdf) . ИДГ. стр. 136–138 . ISBN 978-1-56884-318-6 . Проверено 17 июля 2010 г.