Как интерпретировать доступ к регистру сегментов на x86-64? - PullRequest
8 голосов
/ 21 октября 2011

С помощью этой функции:

mov    1069833(%rip),%rax        # 0x2b5c1bf9ef90 <_fini+3250648>
add    %fs:0x0,%rax
retq

Как мне интерпретировать вторую инструкцию и узнать, что было добавлено в RAX?

Ответы [ 2 ]

8 голосов
/ 21 октября 2011

Этот код:

mov    1069833(%rip),%rax        # 0x2b5c1bf9ef90 <_fini+3250648>
add    %fs:0x0,%rax
retq

возвращает адрес локальной переменной потока.%fs:0x0 - это адрес TCB (блока управления потоком), а 1069833(%rip) - это смещение оттуда к переменной, которая известна, поскольку переменная находится либо в программе, либо в некоторой динамической библиотеке, загруженной во время загрузки программы (библиотекам, загружаемым во время выполнения через dlopen(), необходим другой код

3 голосов
/ 21 октября 2011

Я не уверен, что их называли сегмент зарегистрировать со времен старых сегментированных архитектур. Я считаю, что правильный термин - это селектор (но я могу ошибаться).

Тем не менее, я думаю, что вам просто нужно набрать первое четырехзначное слово (64 бита) в области fs.

Бит %fs:0x0 означает содержимое памяти в fs:0. Поскольку вы использовали общий add (а не addl, например), я думаю, что он будет принимать ширину данных от цели %rax.

С точки зрения получения фактического значения это зависит от того, находитесь ли вы в унаследованном или длинном режиме.

В устаревшем режиме вам нужно получить значение fs и найти его в GDT (или, возможно, LDT), чтобы получить базовый адрес.

В длинном режиме вам нужно будет посмотреть соответствующие регистры конкретной модели. Если вы на этом этапе, к сожалению, вы вышли за пределы моего уровня знаний.

...