【发布时间】:2018-05-19 14:24:49
【问题描述】:
我正在尝试编写一个LD_PRELOADable 库,以防止进程从该变量中删除自身(以确保子代继承它)。
到目前为止,我成功地包装了 putenv、setenv 和 clearenv,但 execve 给我带来了问题。
到目前为止我的代码:
int (*real_execve)(const char *filename, char *const argv[], char *const envp[]);
int execve(const char *filename, char *const argv[], char *const envp[]){
real_execve = dlsym(RTLD_NEXT,"execve");
char *path = getenv("LD_PRELOAD");
fprintf(stderr, "INTERCEPTED execve, env:\n");
int i;
for(i=0;envp[i]!=NULL;i++);
char *nenvp[i+1];
nenvp[i]=NULL;
for(i=0;envp[i]!=NULL;i++){
char *string = envp[i];
char *buf = malloc((strlen(string)+1)*sizeof(char));
strcpy(buf,string);
char *name = strtok(buf,"=");
char *value = strtok(NULL,"=");
if(0==strcmp(name,"LD_PRELOAD")){
fprintf(stderr," FIXING '%s'\n",string);
char * nstring = malloc((strlen(name)+strlen(path)+strlen(value)+3)*sizeof(char));
strcpy(nstring,name);
strcat(nstring,"=");
strcat(nstring,path);
strcat(nstring,":");
strcat(nstring,value);
nenvp[i]=nstring;
fprintf(stderr," TO '%s'\n",nenvp[i]);
free(string);
}else{
nenvp[i]=envp[i];
fprintf(stderr," LEFT '%s'\n",nenvp[i]);
}
free(buf);
}
fprintf(stderr, " CALLING %s\n", filename);
return real_execve(filename,argv,nenvp);
}
我遇到了 2 个问题:
-
它记录如下内容:
FIXING 'LD_PRELOAD=/usr/$LIB/libstdc++.so.6 /usr/$LIB/libgcc_s.so.1 /usr/$LIB/libxcb.so.1' TO 'LD_PRELOAD=/usr/$LIB/libstdc++.so.6 /usr/$LIB/libgcc_s.so.1 /usr/$LIB/libxcb.so.1:/usr/$LIB/libstdc++.so.6 /usr/$LIB/libgcc_s.so.1 /usr/$LIB/libxcb.so.1'而不是预期的自我路径前置,所以我想我以某种方式搞砸了 strtok。
-
我遇到了很多这样的错误:
Error in 'sh': munmap_chunk(): invalid pointer: 0x00007fff3888af4a这听起来像是我释放了太多,但我找不到罪魁祸首。
我希望这听起来不太像“嘿,帮我解决这个问题”的帖子,但我在这里有点碰壁,非常感谢任何帮助。
【问题讨论】:
-
您需要(重新)阅读
strtok的文档。如果你用相同的字符串和分隔符调用它两次,你会得到相同的结果。第二次和后续调用必须将 NULL 作为其第一个参数。 -
显然完全扫了一眼。非常感谢你,我会解决这个问题,然后编辑我的问题以反映第二个问题,或者如果它消失了就关闭它(如果你将你的评论改写为答案,我很乐意支持/接受它)。
-
确定后,在应用该修复程序后,它现在会复制
value中的值,而不是在其前面添加path。也仍然收到munmap_chunk错误 -
可能不相关,但请记住
execve应该是异步信号安全的,因此您不能真正从中调用非异步安全函数(malloc、strtok、 ETC。)。法律职能列表见manpage。 -
@nonchip 这就是我通常所做的,因为
alloca和mmap不能保证在所有 Unix 风格上都是异步安全的 (signal-safety(7))。
标签: c environment-variables ld-preload execve