Перехват библиотечных функций в linux и bsd



         

Перехват функций не во сне, а наяву - часть 3


       PUSH EBP

       MOV  EBP,ESP

       SUB ESP, byte ptr [EAX]    ; берем XXh из памяти

       INC EAX                           ; на след. машинную команду

       JMP EAX

      

prolog_2: ;// эмулируем

выполнение пролога

типа PUSB EBP/MOV EBP,ESP/PUSH EDI/PUSH ESI

       PUSH EBP

       MOV EBP, ESP

       PUSH EDI

       PUSH ESI

       JMP EAX

Листинг 11 базовый код перехватчика (расположенный в gets), поддерживающий несколько различных прологом

Программа-инсталлятор анализирует пролог перехватываемой функции и, в зависимости от результата, внедряет в ее начало либо call prepare_prolog_1 либо call prepare_prolog_2, где prepare_prolog_x – метка, расположенная внутри thunk-кода, помещенного нами в функцию gets. Команда call занимает 5 байт и потому в аккурат накладывается на команду SUB ESP,XXh так, что XXh оказывается прямо за ее концом. Поэтому, сохранять XXh в теле самого перехватчика не нужно!!! Команда SUB ESP, byte ptr [EAX], вызываемая из thunk-кода эмулирует выполнение SUB ESP,XXh на ура!

Приведенный пример портит регистр EAX и работает только с cdecl и stdcall функциями. Перехват fastcall-функции, передающих аргументы через EAX, по этой схеме невозможен. Однако, оригинальный EAX можно сохранять в стеке и восстанавливать непосредственно перед передачей управления перехваченной функции, но в этом случае JMP EAX придется заменить на RETN, а на верхушку стека предварительно положить адрес для перехода.

Вот, собственно говоря, и все. Скелет перехватчика успешно собран и готов к работе. Остается дописать "боевую начинку". Это может быть и логгер, протоколирующий вызовы, и анти-протектор, блокирующий вызовы некоторых функций (например, удаление файла), и макро-машина, "подсовывающая" функциям клавиатурного ввода готовые данные и… да все что угодно!




Содержание  Назад  Вперед