Трассировка доступа к таблице страниц процесса Linux

Я пишу, чтобы узнать о возможности отслеживания доступа к таблице страниц (с точки зрения «индекса» каждого доступа к таблице страниц) обычного пользовательского приложения Linux. По сути, то, что я делаю, — это воссоздание уязвимости, упомянутой в этой исследовательской статье (https://www.ieee-security.org/TC/SP2015/papers-archived/6949a640.pdf). В частности, необходимо регистрировать доступ к странице данных для использования и вывода секретов программы.

Я понимаю, что в системе Linux, 64-битной архитектуре x86 размер таблицы страниц составляет 4 КБ. И я использовал pin (https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool), чтобы регистрировать трассировку адресов для всех обращений к виртуальной памяти. Итак, могу ли я просто вычислить «индекс» каждого доступа к таблице страниц данных с помощью следующего правила преобразования?

index = address >> 15 

С 4KB = 2 ^ 15. Это правильно? Заранее благодарим вас за любые предложения или комментарии.

Кроме того, я думаю, что хочу отметить одну вещь: концептуально мне не нужен «точный» идентификатор каждого идентификатора таблицы страниц данных, а просто число («индекс»), чтобы различать доступ к различным страницам данных. Это должно обеспечить концептуально идентичный объем информации по сравнению с их атаками.


person lllllllllllll    schedule 05.05.2020    source источник
comment
Что такое индекс доступа к таблице страниц? Является ли это индексом строки в таблице, которая используется для преобразования адресов? Обратите внимание, что x86 и x86_64 имеют несколько уровней таблиц страниц. Таким образом, при трансляции одного адреса осуществляется доступ к нескольким таблицам, поэтому непонятно, что представляет собой ваш индекс.   -  person Tsyvarev    schedule 05.05.2020
comment
Что такое pin? Что вы имеете в виду под индексом? Чего вы точно пытаетесь достичь? Вы пишете модуль ядра? Вы работаете с пользовательской программой? Просьба уточнить. Сказать, что индекс таблицы страниц сам по себе не имеет большого значения, поскольку в Linux есть несколько уровней таблиц страниц, и каждый адрес соответствует индексу в каждом из них.   -  person Marco Bonelli    schedule 05.05.2020
comment
@Tsyvarev Извините за путаницу, которую это вызвало .. Я обновил свой вопрос, добавив дополнительную информацию и ссылки. Не могли бы вы взглянуть и посмотреть, имеет ли это больше смысла на этот раз? Благодарю вас!   -  person lllllllllllll    schedule 05.05.2020
comment
@МаркоБонелли. Благодарю вас! Я обновил свой вопрос с дополнительной информацией. Не могли бы вы посмотреть и понять, имеет ли это смысл? Благодарю вас!   -  person lllllllllllll    schedule 05.05.2020
comment
Самый простой способ сделать это — настроить qemu для записи обращений к памяти.   -  person stark    schedule 05.05.2020
comment
Имейте в виду, что pin выполняет доступ к памяти сам по себе и может изменить место, где программа выделяет память.   -  person nitzanms    schedule 06.05.2020


Ответы (1)


Итак, вам действительно не нужен «индекс», а просто какой-то уникальный идентификатор, чтобы различать разные страницы в виртуальном адресе процесса.

В таком случае вы можете просто сделать address >> PAGE_SHIFT. В x86 со страницами размером 4 КБ PAGE_SHIFT это 12, поэтому вы можете сделать:

page_id = address >> 12

Тогда, если address1 и address2 соответствуют одной и той же странице, page_id будет одинаковым для обоих адресов.

В качестве альтернативы, чтобы добиться того же результата, вы можете сделать address & PAGE_MASK, где PAGE_MASK — это просто 0xfffffffffffff000 (то есть ~((1UL << PAGE_SHIFT) - 1)).

person Marco Bonelli    schedule 05.05.2020
comment
Фантастика. Это именно то, что я ищу. Большое спасибо! - person lllllllllllll; 05.05.2020