Комментарии 14
>x32
>x86
вы уже определитесь
по теме: а где сейчас используются такие хардакорные хаки, кроме всяких руткитов?
для отладки же можно более просто и платформонезависимо подменять юзерспейсовую функцию либцы через LD_PRELOAD? это не работает для каких-то случаев?
>x86
вы уже определитесь
по теме: а где сейчас используются такие хардакорные хаки, кроме всяких руткитов?
для отладки же можно более просто и платформонезависимо подменять юзерспейсовую функцию либцы через LD_PRELOAD? это не работает для каких-то случаев?
в x86-64 есть две функции обработчика прерываний первый способ, позволяет получить адрес обработчика, который сделан для совместимости с х32, второй сопособ позволяет получить адрес для х64 обработчика.
Стоит рассматривать это как спортивно/академический интерес, как вариант руткит.
Ну вы перехватите обращение резолвера к /etc/hosts через LD_PRELOAD, тогда поговорим.
Если бинарник статически слинкован
Для перехвата функций внутри любого юзерспейсовского процесса вполне достаточно хорошего знания ELF.
В конце концов, так работает сам загрузчик (ld.so). LD_PRELOAD тут не панацея, ибо перехватывает ВСЕ обращения из всех модулей процесса к некоторой функции.
Другой вопрос — когда дело касается хуков сторонней программы.
В конце концов, так работает сам загрузчик (ld.so). LD_PRELOAD тут не панацея, ибо перехватывает ВСЕ обращения из всех модулей процесса к некоторой функции.
Другой вопрос — когда дело касается хуков сторонней программы.
Хм, уже полгода использую аналогичный метод в одном большом проекте :)
Если кому интересно, на Linux ARM найти таблицу вызовов можно так:
unsigned long **FindSysCallTable(void)
{
unsigned long **sctable;
unsigned long ptr;
extern unsigned long loops_per_jiffy;
sctable = NULL;
for (ptr = (unsigned long)&elf_check_arch;
ptr < (unsigned long)&loops_per_jiffy;
ptr += sizeof(void *)
)
{
unsigned long *p = (unsigned long*)ptr;
if (p[__NR_close] == (unsigned long) sys_close)
{
sctable = (unsigned long**)p;
return &sctable[0];
}
}
return NULL;
}
Далее просто заменяем нужный вызов, не беспокоясь о защите памяти, т.к. её нет.
Конечно все это есть не очень гуд и следует стараться обходится без таких вот хаков…
Если кому интересно, на Linux ARM найти таблицу вызовов можно так:
unsigned long **FindSysCallTable(void)
{
unsigned long **sctable;
unsigned long ptr;
extern unsigned long loops_per_jiffy;
sctable = NULL;
for (ptr = (unsigned long)&elf_check_arch;
ptr < (unsigned long)&loops_per_jiffy;
ptr += sizeof(void *)
)
{
unsigned long *p = (unsigned long*)ptr;
if (p[__NR_close] == (unsigned long) sys_close)
{
sctable = (unsigned long**)p;
return &sctable[0];
}
}
return NULL;
}
Далее просто заменяем нужный вызов, не беспокоясь о защите памяти, т.к. её нет.
Конечно все это есть не очень гуд и следует стараться обходится без таких вот хаков…
ptrace(2) и не нужно никаких модулей ядра.
Черт. Ни черта не понятно (
мдауж. 9 лет все наступали на грабли под windows, а теперь и под никсами стали на них наступать.
Уже везде 100 раз было сказано, что сброс WP бита — это опасное действие, которое может натварить очень много плохих дел. И если надо писать в защищенные участки памяти под ядром, то лучше использовать другой механизм: По виртуальному адресу страницы получить физические страницы. Для полученных физических страниц выделить виртуальную память без защиты. т.е. на одну и туже физическую страницу памяти будет ссылаться 2 страницы виртуальной памяти, но одна из них будет не защищена.
Уже везде 100 раз было сказано, что сброс WP бита — это опасное действие, которое может натварить очень много плохих дел. И если надо писать в защищенные участки памяти под ядром, то лучше использовать другой механизм: По виртуальному адресу страницы получить физические страницы. Для полученных физических страниц выделить виртуальную память без защиты. т.е. на одну и туже физическую страницу памяти будет ссылаться 2 страницы виртуальной памяти, но одна из них будет не защищена.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Перехват системных вызовов в linux под x86-64