Друзья! Функция NtCurrentTeb () недокументирована, возвращает через раз неправильный адрес с тукруры TEB, это структура блока окружения потока (или как она там расшифроваывается), тоже недокументированная. Вот код: Код (Text): #include <windows.h> #include <stdio.h> using namespace std; int main() { SetConsoleCP (1251); SetConsoleOutputCP (1251); printf ("%x\n", (unsigned int) NtCurrentTeb()); getchar (); return (0) ; } После чего приаттачиваемся OllyDbg к процессу и наблюдаем в регистре fs совсем другое значение. Типичные значения: программно получаю 0X7ffdf000, а в отладчике 7ffde000 (с различными варицацями: 0X7ffdd000), что делать? Спасибо, кто откликнется.
Щас посмотрел реализацию NtCurrentTeb(), оказывается, вся-то реализация и заключается в: PUSH EBP MOV EBP,ESP PUSH EBX SUB ESP,10 MOV EBX,DWORD PTR FS:[18] MOV DWORD PTR SS:[EBP-8],EBX MOV EAX,DWORD PTR SS:[EBP-8] ADD ESP,10 POP EBX LEAVE RETN Вот и всё, и этот код выполняется в главном модуле, а не где-то в dll-ках. Вот я жирным выделил нахождение непосредственно адреса TEB, ну да, всё правильно. Немного смущает, зачем они берут fs:[18], а не fs:[0], там ведь одно и то же, ну да это их дела. То есть, получается NtCurrentTeb() железно не врёт. Но почему тогда врёт регистр fs? А ещё я заметил, что эта ложь наблюдается только при присоединении к потоку, а если сразу процесс запуситить в отладчике, то не наблюдается.
amvoz Адрес TEB и значение в fs — абсолютно разные вещи. Адрес TEB и должен колебаться где-то в районе 0x7ffde000, а fs содержит селектор сегмента (0x3b), база которого находится по адресу TEB. Кроме того, у каждого потока свой TEB, соответственно вручную получаете адрес одного TEB'а, а после аттача OllyDbg смотрите адрес другого. fs:[0] даже близко не содержит адрес TEB, он содержит указатель на продолжение связного списка SEH с адресами обработчиков исключений. Естесственно по fs:[18] и fs:[0] абсолютно разные значения. Он не врёт. Опять таки. Адреса TEB разных потоков видите.
у вас слишком мнго информации, поэтому я буду переспрашивать дозировано Очень интересно. ПРименим формальную логику тык скыть: 1) Вначале структуры TEB лежит структура TIB? Лежит. 2) Следовательно, адреса TEB и TIB равны 3) Дословно: "На Intel Win32 платформе, регистр FS всегда указывает на текущий TIB." (Взял у Мэта Питрека, здесь: http://www.wasm.ru/article.php?article=Win32SEHPietrek1) 4) Значит вывод: "На Intel Win32 платформе, регистр FS всегда указывает на текущий TEB" 5) Следовательно утверждение о том, что "Адрес TEB и значение в fs — абсолютно разные вещи" неверно Просто скажите мне в каком из пунктов я неправ и это будет эффективнее, чемя щас буду узнавать, что такое селектор сегмента. Извините.
amvoz В том месте, где буквально понимаете слово "указывает" в приведенной цитате. В данном случае под "указывает" понимается то, что я написал касательно селектора и базы сегмента. Собственно, Вы, вероятно, и сами в курсе, что регистр fs имеет длину в 16 бит (надеюсь, мне по этому поводу сейчас никто не начнёт рассказывать про теневую часть), а значит не может содержать указатели вида 0x7ffde000. Если же хотите знать больше, то всё-таки придётся почитать про механизм сегментации в защищённом режиме и селекторы сегментов в частности.
amvoz Аттач отладчика к процессу происходит путем создания доп.потока, который вызывает DbgBreakpoint, на котором и происходит останов отладчика - соотв-но и fs:0 в момент останова указывает на TEB этого доп.потока, а не твоего основного. Глянь в View\Memory и увидишь рядом две строчки data block - of main thread это адрес TEB твоего основного потока, а второй of thread ??? - дополнительного, на котором в данный момент осуществлен останов и соотв-но fs:0 указывает именно на его TEB Ну, и не путай загрузку дворда, лежащего по адресу fs:[0], с самим линейным адресом fs:0, который в чистом виде просто так не получишь, поэтому и "придумали" хранить адрес TEB в нем самом по смещению fs:[18]