Шприц для bsd или функции на игле

         

Введение - часть 2


Рисунок 2 функция dladdr в действительности реализована в libc.so (впрочем, в старых версиях это было не так), где она называется _dl_addr

Проблема в том, что dladdr находится в библиотеке libdl.x.so, которой может и не быть в памяти конкретно взятого процесса, а если она там есть, то хрен знает по какому адресу загружена. Некоторые хакеры утверждают, что в thunk-коде можно использовать только прямые вызовы ядра через интерфейс INT 80h, а все остальные функции недоступны. На самом деле это не так! Как показывает дизассемблер, dladdr это всего лишь "обертка" вокруг _dl_addr, реализованной в libc.so.x, а она-то доступна наверняка! Вот только на базовый адрес загрузки закладываться ни в коем случае нельзя и вызов должен быть относительным.

Простейшая подпрограмма генерации относительного вызова выглядит так:

unsigned char buf_code[]={0xE8, 0x0, 0x0, 0x0,0x0}; // call 00000h

call_r(char *lib_name, char *from, char *to, int delta)

{

       unsigned char *base, *from, *to;

      

       base = dlopen(lib_name,RTLD_NOW); if (!base) return -1;

       from = dlsym(base,from); if (!from) return -1;

       to   = dlsym(base,to); if (!to) return -1;

      

       *((unsigned int*)&buf_code[1]) = to - from - sizeof(buf_code) - delta;

       return 666;

}

Листинг 1 подпрограмма генерирует относительный вызов и помещает его в глобальный буфер buf_code, lib_name – имя хакаемой библиотеки, from – имя функции, из которой будет осуществляться вызов (например, gets), to – имя функции, которую нужно вызывать (например, write), delta – смещение инструкции call от начала thunk-кода

Функция call_r вызывается из программы-инсталлятора (например, нашей mem.c) и генерирует относительный вызов call по адресу from на адрес to. Она может использоваться для вызова любых функций, а не только _dl_addr.

Модернизируем программу mem.c и отпатчим функцию gets так, чтобы она выводила символ "*" на экран.


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