我正在尝试编写一个LD_PRELOAD函数库,以防止进程从该变量中移除自身(确保子进程继承它)。
到目前为止,我成功地包装了putenvsetenvclearenv,但是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);
}

我遇到两个问题:
它记录了如下内容:
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
对我来说,这听起来可能是我释放太多了,但我找不到罪魁祸首。
我希望这听起来不像是一个“嘿,帮我修好这个”的帖子,但我有点撞到墙了,任何帮助都会非常感谢。

最佳答案

直接向前:
创建一个新的指针数组,其大小必须能容纳新的env/var/s
strdup()从旧数组到新数组所需的所有元素。
根据需要添加新内容。
确保数组中的最后一个指针是NULL
将新指针数组传递给原始的execve()
不要修改甚至(尝试)旧环境的条目。

关于c - 筛选执行环境的正确方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50426311/

10-10 08:28