0x01.简介
Wrox Press Mac OS X and iOS Internals, To the Apple’s Core (2013).pdf PAGE164有描述:
支持动态库插入(Interposing)功能,是苹果加载器dyld在传统加载器的一个不同的地方。通过向宏DYLD_INSERT_LIBRARIES里写入动态库完整路径。就可以在执行文件加载时将该动态库插入。
dyld源代码部分:
include/mach-o/dyld-interposing.h
#if !defined(_DYLD_INTERPOSING_H_)
#define _DYLD_INTERPOSING_H_
/* Example:
* static
* int
* my_open(const char* path, int flags, mode_t mode)
* {
* int value;
* // do stuff before open (including changing the arguments)
* value = open(path, flags, mode);
* // do stuff after open (including changing the return value(s))
* return value;
* }
* DYLD_INTERPOSE(my_open, open)
*/
#define DYLD_INTERPOSE(_replacment,_replacee) \
__attribute__((used)) static struct{ const void* replacment; const void* replacee; }
_interpose_##_replacee \
__attribute__ ((section (“__DATA,__interpose”))) = { (const void*)(unsigned
long)&_replacment, (const void*)(unsigned long)&_replacee };
#endif
Interposing就是说注入的动态库会创建一个叫做__interpose的数据段,里面放好原始函数的地址,以及替换函数的地址,dyld在加载时对跳转地址进行替换。(这段是看雪上找的)
0x02.来实践
又到了小白照猫画虎的时间了
先在Xcode里面创建一个普通的view app工程
左下角(左边的第二个左下角)点击加号,创建framework库
然后在insert文件夹下添加InsertClass类,如图写一个load类,打印一条log信息
这里环节结束之后先点击运行,设备选择越狱的air2,这样就会生成相应的insert.framework了。
把生成的framework上传到air2的/var/root目录下
切换到设备里,先ps -A | grep "/var"找一下应用
使用DYLD_INSERT_LIBRARIES命令把上传的insert库插入到执行的app里
这里就向宏DYLD_INSERT_LIBRARIES里写入动态库完整路径,在执行文件加载时将该动态库插入。
这里打印出来log,说明在执行文件加载的时候动态库是插入成功了的
0x03.冥想
当我做完这一顿照猫画虎按图索骥的工作之后,我砸壳下来拖入烂苹果查看LC_LOAD_DYLIB section,因为动态库注入的原理应该是添加一个LC_LOAD_DYLIB section(???),但是并没有发现增加的有LC_LOAD_DYLIB section。我当时就很疑惑,log是打印成功的,说明动态库插入是实现了的。但是并没有多出一个LC_LOAD_DYLIB section的原因,据我个人看法,DYLD_INSERT_LIBRARIES插入动态库只是在可执行文件加载的时候临时添加桩区依赖等等来让可执行文件执行插入的方法,并没有真正打包进可执行文件,所以自然是不能在原本的可执行文件中找到增加的库了(如何打包进可执行文件)。想来我是把概念搞混淆了。