Разработка динамических сайтов
SEO услуги
Управление контекстной рекламой

Вход на хостинг

Имя пользователя:*

Пароль пользователя:*

IT-новости

20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла

Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......

подробнее

30.07.2015 Ищем уникальный контент для сайта

Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......

подробнее

11.05.2015 Распространённые ошибки разработчиков сайтов

Не секрет, что в сети Интернет насчитывается миллионы сайтов, и каждый день появляются тысячси новых......

подробнее

Перехват системных вызовов в операционной системе Linux


Часть 2

Владимир Мешков

Общая методика перехвата

Рассмотрим сначала теоретически, как осуществляется перехват методом прямого доступа к адресному пространству ядра, а затем приступим к практической реализации.

Прямой доступ к адресному пространству ядра обеспечивает файл устройства /dev/kmem. В этом файле отображено все доступное виртуальное адресное пространство, включая раздел подкачки (swap-область). Для работы с файлом kmem используются стандартные системные функции – open(), read(), write(). Открыв стандартным способом /dev/kmem, мы можем обратиться к любому адресу в системе, задав его как смещение в этом файле. Данный метод был разработан Сильвио Чезаре (Silvio Cesare) (см. статью «Runtime kernel kmem patching», Silvio Cesare, http://www.sans.org/rr/threats/rootkits.php).

Вспомним кратко механизм функционирования системных вызовов в ОС Linux (см. мою статью «Перехват системных вызовов в ОС Linux». – Журнал «Системный администратор». – 2003 г. №3(4). с.40-44).

Обращение к системной функции осуществляется посредством загрузки параметров функции в регистры процессора и последующим вызовом программного прерывания int $0x80. Обработчик этого прерывания, функция system_call, помещает параметры вызова в стек, извлекает из таблицы sys_call_table адрес вызываемой системной функции и передает управление по этому адресу.

Имея полный доступ к адресному пространству ядра, мы можем получить все содержимое таблицы системных вызовов, т.е. адреса всех системных функций. Изменив адрес любого системного вызова, мы, тем самым, осуществим его перехват. Но для этого необходимо знать адрес таблицы, или, другими словами, смещение в файле /dev/kmem, по которому эта таблица расположена.

Чтобы определить адрес таблицы sys_call_table, предварительно необходимо вычислить адрес функции system_call. Поскольку данная функция является обработчиком прерывания, давайте рассмотрим, как обрабатываются прерывания в защищенном режиме.

В реальном режиме процессор при регистрации прерывания обращается к таблице векторов прерываний, находящейся всегда в самом начале памяти и содержащей двухсловные адреса программ обработки прерываний. В защищенном режиме аналогом таблицы векторов прерываний является таблица дескрипторов прерываний (IDT, Interrupt Descriptor Table), располагающаяся в операционной системе защищенного режима. Для того чтобы процессор мог обратиться к этой таблице, ее адрес следует загрузить в регистр IDTR (Interrupt Descriptor Table Register, регистр таблицы дескрипторов прерываний). Таблица IDT содержит дескрипторы обработчиков прерываний, в которые, в частности, входят их адреса. Эти дескрипторы называются шлюзами (вентилями). Процессор, зарегистрировав прерывание, по его номеру извлекает из IDT шлюз, определяет адрес обработчика и передает ему управление.

Для вычисления адреса функции system_call из таблицы IDT необходимо извлечь шлюз прерывания int $0x80, а из него – адрес соответствующего обработчика, т.е. адрес функции system_call. В функции system_call обращение к таблице sys_call_table выполняет команда call <адрес таблицы>(,%eax,4) (см. файл arch/i386/kernel/entry.S). Найдя опкод (сигнатуру) этой команды в файле /dev/kmem, мы найдем и адрес таблицы системных вызовов.

Для определения опкода воспользуемся отладчиком gdb. Загрузим отладчик:

gdb -q /usr/src/linux/vmlinux

Дизассемблируем функцию system_call:

disass system_call

В ответ на экран будет выведен ассемблерный листинг. В этом листинге ищем строку типа:

0xc010904d <system_call+45>: call *0xc0200520(,%eax,4)

Это и есть обращение к таблице sys_call_table. Значение 0xc0200520 – адрес таблицы (скорее всего, у вас числа будут другими). Получим опкод этой команды:

x/xw (system_call+45)

Результат:

0xc010904d <system_call+45>: 0x208514ff

Мы нашли опкод команды обращения к таблице sys_call_table. Он равен xffx14x85. Следующие за ним 4 байта – это адрес таблицы. Убедиться в этом можно, введя команду:

x/xw (system_call+45+3)


Предыдущая страницаОглавлениеСледующая страница
 
[001] [002] [003] [004] [005] [006] [007] [008] [009] [010] [011] [012] [013] [014] [015] [016] [017] [018] [019] [020]
[021] [022] [023] [024] [025] [026] [027] [028] [029] [030] [031] [032] [033] [034] [035] [036] [037] [038] [039] [040]
[041] [042] [043] [044] [045] [046] [047] [048] [049] [050] [051] [052] [053] [054] [055] [056] [057] [058] [059] [060]
[061] [062] [063] [064] [065] [066] [067] [068] [069] [070] [071] [072] [073] [074] [075] [076] [077] [078] [079] [080]
[081] [082] [083] [084] [085] [086] [087] [088] [089] [090] [091] [092] [093] [094] [095] [096] [097] [098] [099] [100]
[101] [102] [103] [104] [105] [106] [107] [108] [109] [110] [111] [112] [113] [114] [115] [116] [117] [118] [119] [120]
[121] [122] [123] [124] [125] [126] [127] [128] [129] [130] [131] [132] [133] [134] [135] [136] [137] [138] [139] [140]
[141] [142] [143] [144] [145] [146] [147] [148] [149] [150]

+7 (831) 413-63-27
ООО Дельта-Технология ©2007 - 2023 год
Нижний Новгород, ул. Дальняя, 17А.
Rambler's Top100