我能够捕获所有低级函数,例如open(),fopen()等,并使用dlsym(RTLD_NEXT,“ ...”)调用原始函数,但是我无法使用posix_spawnp做到这一点(),因为我的可执行文件崩溃了。为什么会这样以及如何捕获此功能?
很抱歉延迟。这是我在运行Linux的某些嵌入式设备上尝试的代码:
int posix_spawnp(pid_t * pid, const char * file, const posix_spawn_file_actions_t * file_actions, const posix_spawnattr_t * attrp, char * const argv[], char * const envp[])
{
orig_fopen_t orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
FILE * fp = orig_fopen("/tmp/DiagnosticsAgent.log", "a");
fprintf(fp, "*** posix_spawnp(..., {");
int i;
for (i = 0; argv[i] != 0; ++ i)
fprintf(fp, "%s, ", argv[i]);
fprintf(fp, "}, ...)\n");
fclose(fp);
void * handle = dlopen("libpthread.so.0", RTLD_LAZY);
orig_posix_spawnp_t orig_posix_spawnp = (orig_posix_spawnp_t)dlsym(handle, "posix_spawnp");
return orig_posix_spawnp(pid, file, file_actions, attrp, argv, envp);
}
答案 0 :(得分:0)
我的linux / glibc可以正常工作。这是一个工作示例:
#!/bin/sh -eu
cat > main.c <<EOF
#include <spawn.h>
#include <sys/wait.h>
int main(int C, char **V)
{
pid_t pid;
if(0!=posix_spawnp(&pid,V[1],NULL,NULL,V+1,NULL))
return 1;
wait(0);
}
EOF
gcc main.c
cat > libspawn.c <<EOF
#define _GNU_SOURCE
#include <spawn.h>
#include <dlfcn.h>
#include <stdio.h>
typedef int spawnp_signature(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[]);
spawnp_signature posix_spwanp;
int posix_spawnp(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[])
{
fprintf(stderr, "OVERRIDE\n");
spawnp_signature *real = dlsym(RTLD_NEXT,__func__);
return real(pid,file,file_actions,attrp,argv,envp);
}
EOF
gcc -shared -fpic -o libspawn.so libspawn.c -ldl
./a.out echo hello world
LD_PRELOAD=$PWD/libspawn.so ./a.out echo hello world
第二个输出将按预期方式打印OVERRIDE
一词。
编辑:
使您的示例可编译后,它也对我有用。也许某些未经检查的调用在您的计算机上失败了,或者您忘记了链接dl
库。
#!/bin/sh -eu
cat > main.c <<EOF
#include <spawn.h>
#include <sys/wait.h>
int main(int C, char **V)
{
pid_t pid;
if(0!=posix_spawnp(&pid,V[1],NULL,NULL,V+1,NULL))
return 1;
wait(0);
}
EOF
gcc main.c
cat > libspawn.c <<EOF
#define _GNU_SOURCE
#include <spawn.h>
#include <dlfcn.h>
#include <stdio.h>
typedef int spawnp_signature(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[]);
spawnp_signature posix_spwanp;
int posix_spawnp(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[])
{
fprintf(stderr, "OVERRIDE\n");
spawnp_signature *real = dlsym(RTLD_NEXT,__func__);
return real(pid,file,file_actions,attrp,argv,envp);
}
EOF
cat >libspawn.c <<EOF
#define _GNU_SOURCE
#include <spawn.h>
#include <dlfcn.h>
#include <stdio.h>
typedef int (*orig_posix_spawnp_t)(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[]);
typedef FILE *(*orig_fopen_t)(char const*, char const*);
int posix_spawnp(pid_t * pid, const char * file, const posix_spawn_file_actions_t * file_actions, const posix_spawnattr_t * attrp, char * const argv[], char * const envp[])
{
orig_fopen_t orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
FILE * fp = orig_fopen("/tmp/DiagnosticsAgent.log", "a");
fprintf(fp, "*** posix_spawnp(..., {");
int i;
for (i = 0; argv[i] != 0; ++ i)
fprintf(fp, "%s, ", argv[i]);
fprintf(fp, "}, ...)\n");
fclose(fp);
void * handle = dlopen("libpthread.so.0", RTLD_LAZY);
if(!handle) { perror(0); return -1; }
orig_posix_spawnp_t orig_posix_spawnp = (orig_posix_spawnp_t)dlsym(handle, "posix_spawnp");
fprintf(stderr,"OVERRIDE\t");
return orig_posix_spawnp(pid, file, file_actions, attrp, argv, envp);
}
EOF
gcc -shared -fpic -o libspawn.so libspawn.c -ldl
./a.out echo hello world
LD_PRELOAD=$PWD/libspawn.so ./a.out echo hello world