子进程的LD_PRELOAD
一个指定LD_PRELOAD的进程创建的子进程是否受LD_PRELOAD的影响?
1.
fork()后在子进程中执行函数。
main.c
#include <unistd.h>
#include <stdio.h>
extern char** environ;
void foo();
int main()
{
for(char **current = environ; *current; current++) {
puts(*current);
}
if(0 == fork()){
foo();
}else{
sleep(1);
}
return 0;
}
foo.c
#include <stdio.h>
void foo()
{
printf("real foo\n");
}
wfoo.c
#include <stdio.h>
void foo()
{
printf("wrap foo\n");
}
将以上代码编译成执行文件和动态库
gcc -fPIC -shared foo.c -o libfoo.so
gcc -fPIC -shared wfoo.c -o libwfoo.so
gcc main.c -L./ -lfoo
执行LD_PRELOAD=./libwfoo.so ./a.out
,其输出如下
[root@localhost ~]# LD_LIBRARY_PATH=./ LD_PRELOAD=./libwfoo.so ./a.out
LD_PRELOAD=./libwfoo.so
....
其他环境变量
...
wrap foo
也就是说fork()后的子进程其函数地址是和父进程一样的。
先执行了
export LD_LIBRARY_PATH=./
仔细想了一想,fork()创建子进程,子进程仍使用父进程的代码段,这和LD_PRELOAD并没有关系。
2.
创建子进程后执行exec簇函数
exec.c
#include <unistd.h>
int main()
{
if(0 == fork()){
execl("./a.out", "./a.out", NULL);
}
return 0;
}
gcc exec.c -o exec
[root@localhost ~]# LD_PRELOAD=./libwfoo.so ./exec
LD_PRELOAD=./libwfoo.so
....
其他环境变量
...
wrap foo
如果将excel()
替换为excele()
,则情况发生变化
[root@localhost ~]# ./exec
./a.out: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
这意味着LD_LIBRARY_PATH环境变量失效了。
仔细阅读man 3 exec
后,恍然大悟。exec函数簇可分为两类,一类将当前进程的char** environ
指向的环境变量传递给新程序镜像,如execl()
,另一类则只使用函数参数指定的环境变量,如execle()
。
综上,当使用execle()
这类函数时,如果没有手动将当前进程的环境变量通过参数传递下去,那么就会使得LD_PRELOAD失效,无法实现函数拦截的功能了。
3.
使用system()创建的子进程同样继承环境变量
exec.c
#include <unistd.h>
int main()
{
if(0 == fork()){
system("./a.out");
}
return 0;
}
gcc exec.c -o exec
[root@localhost ~]# LD_LIBRARY_PATH=./ LD_PRELOAD=./libwfoo.so ./exec
LD_PRELOAD=./libwfoo.so
....
其他环境变量
...
wrap foo
4.
结合以上情况,只有在特意指定子进程环境变量的情况(使用execle()
等函数),原先指定的环境变量才会失效,否则环境变量都会传递到子进程。
子进程的LD_PRELOAD的更多相关文章
- UNIX下的LD_PRELOAD环境变量
UNIX下的LD_PRELOAD环境变量 也许这个话题并不新鲜,因为LD_PRELOAD所产生的问题由来已久.不过,在这里,我还是想讨论一下这个环境变量.因为这个环境变量所带来的安全问题非常严重,值得 ...
- [forward]警惕UNIX下的LD_PRELOAD环境变量
From: https://blog.csdn.net/haoel/article/details/1602108 警惕UNIX下的LD_PRELOAD环境变量 前言 也许这个话题并不新鲜,因为LD_ ...
- LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir
这次TCTF中一道题,给出了一个PHP一句话木马,设置了open_basedir,disable_functions包含所有执行系统命令的函数,然后目标是运行根目录下的/readflag,目标很明确, ...
- Node.js:进程、子进程与cluster多核处理模块
1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...
- MapReduce剖析笔记之七:Child子进程处理Map和Reduce任务的主要流程
在上一节我们分析了TaskTracker如何对JobTracker分配过来的任务进行初始化,并创建各类JVM启动所需的信息,最终创建JVM的整个过程,本节我们继续来看,JVM启动后,执行的是Child ...
- PHP CLI编程基础知识积累(进程、子进程、线程)
.note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...
- 记一次WinForm程序中主进程打开子进程并传递参数的操作过程(进程间传递参数)
目标:想在WinForm程序之间传递参数.以便子进程作出相应的处理. 一种错误的方法 父进程的主程序: ProcessStartInfo psi = new ProcessStartInfo(); p ...
- Android5.1.1源码 - zygote fork出的子进程如何权限降级
前言 所有Android应用进程都是zygote fork出来的,新fork出来的应用进程还保持着root权限,这显然是不被允许的,所以这个fork出来的子进程的权限需要被降级,本文说的就是Andro ...
- fork()创建子进程
fork()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回值是子进程的pid) 在fork()的调用处,整个父 ...
随机推荐
- Codeforces 839D Winter is here - 暴力 - 容斥原理
Winter is here at the North and the White Walkers are close. John Snow has an army consisting of n s ...
- Linux 踢掉其他终端用户
输入W查看信息 root@HAN:~# w 09:02:36 up 8 days, 20:10, 1 user, load average: 0.00, 0.00, 0.00 USER TTY FRO ...
- javacpp, javacv: 封装了FFmpeg、OpenCV等计算机视觉编程人员常用库的接口
jvavacpp: 一个java调用jni的库,支持安卓. javacv: 封装了FFmpeg.OpenCV等计算机视觉编程人员常用库的接口,可以通过其中的Utility类方便的在包 ...
- [web前端] react router4.0 登录后返回之前浏览页面(回到来源页)
本文链接:https://blog.csdn.net/zeroyulong/article/details/81911704困扰了好久的问题,最终还是在官方文档上找到了答案(看英文文档真心难受啊~~) ...
- checkbox与label内的文字垂直居中的解决方案
<label style="float:left;margin-top:5px;margin-left:10px;cursor:pointer"><input t ...
- Oralce 如何将查询结果中的0转成空的
我们遇到过大多的情况的需求是查询结果中空转为0,这个可以通过oracle的NVL()函数就可以搞定. 之前做报表客户有个需求,查询出结果为0 要转成空的,不显示0 那么在oracle有没有现成函数能搞 ...
- (8)Flask微电影项目会员中心其他页面搭建
会员中心修改密码.评论.登录日志和收藏电影4个页面的内容. 一.修改密码页面: {% extends "home/home.html" %} {% block css %} < ...
- NPOI导出EXCEL样式
public void Export(DataRequest<ExportModel> request, DataResponse<dynamic> response) { t ...
- pytorch保证每次运行使用的随机数都相同的方法
其实在代码的开头添加下面几句话即可: # 保证训练时获取的随机数都是一样的 init_seed = torch.manual_seed(init_seed) torch.cuda.manual_see ...
- 自定义Func方法支持out,ref参数
默认的Func不支持Out,ref类型的参数,所以需要自定义个delegate func来满足需求.具体代码如下 public delegate TResult FuncEX<T1, T2, T ...