Я пытаюсь перехватить execve()
через execl()
. Вот мой вызов-обертка (построен как разделяемая библиотека — libexec.so
).
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
static int (*real_exec)(const char*, char *const [], char *const []) = 0;
static void __attribute__((constructor))init(void) {
real_exec = (int (*)(const char*, char *const [], char *const []))dlsym(RTLD_NEXT, "execve");
}
int execve(const char* arg, char *const argv[], char *const envp[]) {
printf ("In wrapped execve\n");
return (*real_exec)(arg, argv, envp);
}
и вот моя программа, которая выполняется.
//run.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int pid;
pid = fork();
if (pid == 0) {
execl("/usr/bin/date", "date", NULL);
} else {
wait (NULL);
}
return 0;
}
Насколько я знаю, все остальные вызовы exec*
являются оболочкой над системным вызовом execve()
. Я также проверил вышеприведенную программу, запустив ее с помощью strace.
> strace -f -e execve ./run
execve("./run", ["./run"], 0x7ffcefad6a28 /* 61 vars */) = 0
strace: Process 1491914 attached
[pid 1491914] execve("/usr/bin/date", ["date"], 0x7fff28393cc8 /* 61 vars */) = 0
Tuesday 16 February 2021 12:52:16 PM UTC
[pid 1491914] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1491914, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++
Но когда я запускаю программу следующим образом,
> LD_PRELOAD=/home/user/libexec.so ./run
звонок не перехватывается. то есть я не вижу, чтобы In wrapped execve\n
печаталось. Что мне здесь не хватает? Если вместо этого я прямо вызову execve()
в run.c
, это сработает.
Во-вторых, LD_PRELOAD
тоже следует за дочерними процессами? Перехватываются ли звонки детей и потомков?
AFAIK, all other exec* calls are wrapper over execve() system call. I also validated the program above by running with strace.
- не обязательно. Библиотечные функции могут вызывать системный вызов, используяsyscall
напрямую, без вызова его функции-оболочки из библиотеки. Иstrace
показывает вам фактические системные вызовы, а не вызванные библиотечные функции. - person qrdl   schedule 16.02.2021execl()
->syscall(<number for execve>, ...)
вместоexecl()
->execve()
->syscall(<number for execve>, ...)
? - person quasarguru   schedule 16.02.2021LD_PRELOAD=yourlib.so
с помощьюputenv()
перед вызовомexec()
- person qrdl   schedule 16.02.2021