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



         

/Dev/mem - часть 2


Для нейтрализации побочных эффектов обычно функцию вызывают с инвалидными аргументами, чтобы она завершилась без выполнения, однако, это грязный трюк, на который ведутся далеко не все функции. В частности, gets упорно ожидает ввода с клавиатуры даже если в качестве указателя ей передать нуль. Если память, принадлежащая функции, доступна на чтение (а в linux/BSD она доступна), нам достаточно просто прочитать несколько байт от начала функции — это гарантированно загрузит принадлежащую ей страницу в физическую память. Собственно говоря, для поиска перехватываемой функции в /dev/mem нам все равно потребуется ее сигнатура, так что без чтения здесь не обойтись.

Весь вопрос в том, как определить адрес функции? Существует по меньшей мере два пути: получить указатель средствами языка Си или вызывать dlsym. В обоих случаях результаты будут различны, что следующая программа и подтверждает:

#include <dlfcn.h>

int a; unsigned char *x;

x = (unsigned char*) gets;

printf("\nx = gets:%08Xh",x);

for(a=0;a<0x60;a++) printf("%02X ",x[a],(a%0x10)?"":printf("\n%08Xh:",(a+x)));

x = dlopen("libc.so.6",RTLD_NOW);

printf("\n\nbase libc.so.6:%08Xh",x);

for(a=0;a<0x60;a++) printf("%02X ",x[a],(a%0x10)?"":printf("\n%08Xh:",(a+x)));

x= dlsym(x,"gets");

printf("\n\nglsym(,\"gets\"):%08Xh",x);

for(a=0;a<0x60;a++) printf("%02X ",x[a],(a%0x10)?"":printf("\n%08Xh:",(a+x)));

printf("\n");

Листинг 3 программа get_addr.c, определяющая адрес функции gets

Компилируем ("gcc get_addr.c -o get_addr -ldl") и запускаем полученный файл на выполнение (ключ -ldl подключает библиотеку dl, экспортирующую функции dlopen и dlsym). На мыщъхином компьютере результат выглядит так:

x = gets:08048364h

08048364h:FF 25 A8 98 04 08 68 08 00 00 00 E9 D0 FF FF FF




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