Вопрос

Помимо трюка LD_PRELOAD и модулей ядра Linux , которые заменяют определенный системный вызов на предоставленный вами , есть ли какая - либо возможность перехватить системный вызов ( например , open ) , чтобы он сначала прошел через вашу функцию , прежде чем достигнет фактического open ?

Это было полезно?

Решение

если вам действительно нужно решение, вас может заинтересовать руткит DR, который выполняет именно это, http://www.immunityinc.com/downloads/linux_rootkit_source.tbz2 статья об этом находится здесь http://www.theregister.co.uk/2008/09/04/linux_rootkit_released/

Другие советы

Почему вы не можете / не хотите использовать Трюк с LD_PRELOAD?

Пример кода здесь:

/*
 * File: soft_atimes.c
 * Author: D.J. Capelis
 *
 * Compile:
 * gcc -fPIC -c -o soft_atimes.o soft_atimes.c
 * gcc -shared -o soft_atimes.so soft_atimes.o -ldl
 *
 * Use:
 * LD_PRELOAD="./soft_atimes.so" command
 *
 * Copyright 2007 Regents of the University of California
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>

extern int errorno;

int (*_open)(const char * pathname, int flags, ...);
int (*_open64)(const char * pathname, int flags, ...);

int open(const char * pathname, int flags, mode_t mode)
{
    _open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
    if(flags & O_CREAT)
        return _open(pathname, flags | O_NOATIME, mode);
    else
        return _open(pathname, flags | O_NOATIME, 0);
}

int open64(const char * pathname, int flags, mode_t mode)
{
    _open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
    if(flags & O_CREAT)
        return _open64(pathname, flags | O_NOATIME, mode);
    else
        return _open64(pathname, flags | O_NOATIME, 0);
}

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

Предполагая, что вы не можете модифицировать программу и не можете (или не хотите) модифицировать ядро, подход LD_PRELOAD является лучшим, предполагая, что ваше приложение достаточно стандартное и на самом деле не является тем, которое злонамеренно пытается обойти ваш перехват.(В этом случае вам понадобится один из других методов.)

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

На случай, если вы не в курсе, Valgrind в основном используется для поиска утечек памяти и других ошибок, связанных с памятью.Но лежащая в основе технология - это, по сути, эмулятор x86.Он эмулирует вашу программу и перехватывает вызовы malloc / free и т.д.Хорошо то, что вам не нужно перекомпилировать, чтобы использовать его.

У Valgrind есть функция, которую они называют Обертывание функций, который используется для управления перехватом функций.См. раздел 3.2 настоящего руководства. Руководство по Valgrind за подробностями.Вы можете настроить перенос функций для любой функции, которая вам нравится.Как только вызов перехвачен, затем вызывается альтернативная функция, которую вы предоставляете.

Некоторые приложения могут заставить strace / ptrace не запускаться, поэтому единственный реальный вариант, который у меня был, - это использование systemtap

Systemtap может перехватывать кучу системных вызовов, если это необходимо, из-за соответствия шаблону.Systemtap - это не C, а отдельный язык.В базовом режиме systemtap должен помешать вам делать глупости, но он также может работать в "экспертном режиме", который позволяет разработчику использовать C, если это требуется.

Это не требует от вас исправления вашего ядра (или, по крайней мере, не должно), и как только модуль скомпилирован, вы можете скопировать его из окна тестирования / разработки и вставить (через insmod) в производственную систему.

Мне еще предстоит найти приложение Linux, которое нашло бы способ обойти systemtap / избежать попадания в него.

Если ты просто хочешь Смотреть что откроется, вы хотите посмотреть на функцию ptrace() или исходный код утилиты strace командной строки.Если ты действительно этого хочешь перехватывать вызов, чтобы, возможно, заставить его делать что-то еще, я думаю, что перечисленные вами параметры - LD_PRELOAD или модуль ядра - это ваши единственные варианты.

У меня нет синтаксиса, чтобы сделать это изящно с помощью LKM, но в этой статье представлен хороший обзор того, что вам нужно было бы сделать: http://www.linuxjournal.com/article/4378

Вы также могли бы просто исправить функцию sys_open.Он начинается со строки 1084 файла /open.c начиная с linux-2.6.26.

Вы также можете узнать, не можете ли вы использовать inotify, systemtap или SELinux для ведения всего этого журнала за вас без необходимости создавать новую систему.

Если вы просто хотите сделать это в целях отладки, загляните в strace, который встроен поверх системного вызова ptrace (2), который позволяет вам подключать код при выполнении системного вызова.Смотрите часть PTRACE_SYSCALL справочной страницы.

Похоже, вам нужна проверка.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top