【发布时间】:2011-05-16 07:39:51
【问题描述】:
我正在执行一个程序,比如 A 来自另一个程序,首先是 fork,然后是 execve()。现在的问题是我希望 A 使用我通常通过使用 LD_PRELOAD 来完成的库。如何在 execve() 中执行此操作。
谢谢
【问题讨论】:
我正在执行一个程序,比如 A 来自另一个程序,首先是 fork,然后是 execve()。现在的问题是我希望 A 使用我通常通过使用 LD_PRELOAD 来完成的库。如何在 execve() 中执行此操作。
谢谢
【问题讨论】:
您可以在 envp execve 的参数中传递 LD_PRELOAD:
被执行的程序,名为“run”:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
printf("%s\n",getenv("LD_PRELOAD"));
}
执行 execve 的程序,名为“ex”:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
char *const args[] = {"./run",NULL};
char *const envs[] = {"LD_PRELOAD=caca",NULL};
execve("./run",args,envs);
}
运行它:
root@pinkpony:~# ./ex
ERROR: ld.so: object 'caca' from LD_PRELOAD cannot be preloaded: ignored.
caca
编辑: 显示的错误被抛出,因为“caca”库无法预加载以运行,所以它可以工作。 (为了清楚起见,我跳过了 fork() 部分,但用法相同)
编辑: 做类似的事情:
LD_PRELOAD=caca ./ex
如果您没有通过 envp execve() 的参数传递它,则在 execve()-ing 运行时不会自动预加载 caca lib
【讨论】:
如果您只想将 LD_PRELOAD 用于程序 A(而不是其父程序),您可以通过 shell 加载它;将要执行的程序的名称传递给 shell,并将 LD_PRELOAD 添加到环境中。
【讨论】:
更新
在阅读了问题中添加的信息后,我猜您可能必须指定完整路径,或者也设置 LD_LIBRARY_PATH?因为加载器正在承认预加载是有序的这一事实。
否则,我可以想象会有一个安全限制(尽管它必须与从登录 shell 调用运行相关联,这似乎很难检测到)。尽管如此,您可能希望尝试以 root 身份运行(使用sudo -E 来保留您的环境)
从this earlier question 看来,这种行为是默认行为
LD_PRELOAD affects new child even after unsetenv("LD_PRELOAD")
你测试了吗?
【讨论】: