因为最近需要搞一个遍历所有动态库的功能
比如在 ELF 中可以通过 .got.plt
表的第二项拿到 link_map
的地址, 进而可以遍历所有的 so.
在 osx 中如果可以取到 dyld_all_image_infos
内容就可以遍历所有的 image, 这个结构体的地址存放在 dyld:Section64(__DATA, __all_image_info)
, 按理说如果可以拿到 dyld 的加载地址就可以, 但是我阅读了 xnu 和 dyld 的部分源码和很多参考资料, 好像没有把 dyld 的地址像ELF那样写到某个位置, 都是通过 task_info+TASK_DYLD_INFO
取得, 实在无奈只能过来求助, 感谢.
第二个是link_map?不是说是libc的版本ID么?还有在full relro的情况下got2还有没有保存link_map?
最后一个问题是那个_dl_runtime_resolve()的第二个参数index到底是怎么标记的?该怎么偏移才能指向后面的段啊,(有测试过都传入了0x28,0x10等等,不符合.rel.plt的下标啊)
xiaoxiao:
不是说是libc的版本ID么
你是看了程序员自我修养那本书吧. 有些没有讲到.
我写了几篇文章
PWN之ELF符号动态解析过程.md
linux进程动态so注入.md
通过解析runtime的elf程序进行注入
https://github.com/jmpews/evilELF
通过最近的研究, 自己对这个问题回答下吧, 关于这个对runtime的macho解析有几种方法.
1. task_info
2. vm_region 这个原理就是内核有个表记录了所有虚拟内存映射 用户层访问不到, 可以参考下面
http://stackoverflow.com/questions/10301542/getting-process-base-address-in-mac-osx
3. 部分暴力内存搜索, 根据虚拟内存页和xnu的aslr特点, 可以限定内存搜索范围, 其实和上面有些类似
https://github.com/jmpews/evilMACHO/tree/master/dumpRuntimeMacho
1 个赞
感谢,那个书上介绍的确实不全,验证过确实是link_map_obj了。
问下重定位时的地址问题,我在这边怎么构造都跳不到我自己要解析的函数地址 。
已知我构造的f_relplt, f_dynsym, f_dynstr三个数据的地址,那么f_relplt中的r_info和f_dynsym中的st_name两个下标怎么计算呢?
这里是我的计算方式:
r_info = ((f_dymsymAddr - dymsymAddr)/0x10 << 0x8) | 0x7
st_name = f_dynstrAddr - dynstrAddr
(f_xxxAddr为伪造的数据地址,dynstrAddr等等为程序原段地址)
你是希望在 _dl_fixup
时进行劫持么?
如果你想要在这个过程中劫持确实需要伪造 ElfW(Rel)
也就是你说的 f_relplt
, 首先这段代码在 http://code.metager.de/source/xref/gnu/glibc/elf/dl-runtime.c#45
, 我看的 glibc-2.23
.
具体的实现我也没看到我只能说可能出现问题的点,1. f_relplt 只在第一次延迟加载该符号时才会使用 .plt -> .got.plt -> .plt -> _dl_runtime_resolve -> _dl_fixup
是这么个调用流程 2. f_relplt 的结构体, 低8位表示重定位入口类型为, 高24位表示在 .dynsym
中的下标, 你这么算没啥问题感觉, 建议你到 gdb 里看下.
弄了半天,最后提示symbol lookup error……不弄了。
你有fully RELRO保护下dl_resolve劫持的资料没?
这种保护下所有重定位在程序刚加载时就完成了,只能修改栈中的link_map,但这个链表的地址怎么找呢?
大佬有没有时间帮我看个exp啊,里面有段爆破got低位最后指向syscall获得shell的代码不明白。求大佬留个邮箱什么的交流交流
jmpews
2017 年3 月 15 日 08:28
11
不一样的,我说的是full RELRO保护的情况下,got都不含link_map和dl_resolve指针,查过一些资料,都说只能从栈入手来还原出这两个指针
jmpews
2017 年3 月 20 日 06:24
16
恩 你这个是一个原型 有很多细节的问题, 比如从什么地址开始搜索?搜索范围是多少?怎么判断搜索的字符串不是偶然的?还有就是你现在是这个是对自身而言,对于其他 task
还需要搜索到程序的 load_address
.
在上面我列举了几个方法,写了一个demo,但是感觉文件架构没写好.
最近重写了另外一个 rtspy-(runtime spy) , 可以参考下
哦, 你说其他进程
只搜索目标进程 PROT_READ | PROT_EXEC 的内存, 可不可以实现?
jmpews
2017 年3 月 20 日 07:47
18
你说的和这个有点类似 但是还是有那个问题 就是搜索起始位置和搜索范围 否则的话搜搜范围太大了
Rozbo
(rozbo)
2019 年3 月 14 日 02:15
19
翻山越岭来给zz评论,太牛批了。。先有zz后有天, zz赛过活神仙。
@jmpews 大佬您好,我有两个问题想请教一下。
1)请问Mach-O 架构下是不是没有relro保护技术呢?我查了很多资料,clang编译器
对’-z’ 选项不支持,导致我clang编译用户空间的程序用不了FULL RELRO保护。版本信息如下:
$ clang -v
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ ld -v
@(#)PROGRAM:ld PROJECT:ld64-409.12
BUILD 17:47:51 Sep 25 2018
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em arm64e arm64_32
LTO support using: LLVM version 10.0.0, (clang-1000.11.45.5) (static support for 21, runtime is 21)
TAPI support using: Apple TAPI version 10.0.0 (tapi-1000.11.8.2)
2)Mach-O 文件在运行时确实也是lazy binding的,那la_symbol_ptr段只能是可写的么,有没有想类似partial/full relro这种编译时保护开关,将这些字段设为只读。
如果有时间恳请您回答一下,谢谢 :)
同没找到, 但是不知道是否符合你的需求. read_only_relocs