Как обнаружить файловые действия выполняемого дочернего процесса в Linux на C?

#c #linux #file-io #child-process

#c #linux #file-io #дочерний процесс

Вопрос:

У меня есть моя программа, которая является другим процессом exec (не моим, считайте это черным ящиком). Есть ли способ обнаружить операции, такие как open() и close() , для этого дочернего процесса?

Особенно меня интересует поиск всех вновь созданных файлов или существующих файлов, которые открываются с намерением быть созданными ( O_CREAT флаг для open() ).

Комментарии:

1. Возможно , вам захочется взглянуть на man ptrace это . Или, чтобы перехватывать вызовы open() , выполняемые программой напрямую, вы могли бы написать функцию замены open() , которая регистрирует каждый вызов, а затем вызывает «реальный» open() , помещает оболочку в библиотеку и использует LS_PRELOAD для загрузки этой библиотеки перед программой.

2. @alk: хорошие идеи, но это LD_PRELOAD вместо LS_PRELOAD .

3. Да, конечно, это LD_PRELOAD . Извините за опечатку.

Ответ №1:

Рабочий подход заключается в переопределении open() внутри моей собственной разделяемой библиотеки и предварительной загрузке ее внутри exec() процесса редактирования через LD_PRELOAD переменную среды. Спасибо @alk за подход.

Код для переопределения open() выглядит следующим образом:

 #include <fcntl.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <sys/types.h>

extern "C" {

int open(const char *pathname, int flags, ...) {
  bool has_mode = false;
  mode_t mode = 0;
  if (flags amp; O_CREAT) {
    va_list ap;
    va_start(ap, flags);
    mode = va_arg(ap, mode_t);
    has_mode = true;
    va_end(ap);
  }

  using Fn = int (*)(const char * pathname, int flags, ...);
  Fn new_open = reinterpret_cast<Fn>(dlsym(RTLD_NEXT, "open"));

  // Do something useful.

  if (has_mode) {
    return new_open(pathname, flags, mode);
  } else {
    return new_open(pathname, flags);
  }
}

}  // extern "C"
 

Единственная проблема заключается в том , что у fcntl.h него может быть какое — то вызывающее объявление для функции open() . Вам нужен этот файл, чтобы получить определение O_CREAT . Другой способ — включить файл с определением напрямую: в моем случае это файл asm-generic/fcntl.h .