macho是否可以不通过task_info获取到dyldImageLoadAddress?

因为最近需要搞一个遍历所有动态库的功能

比如在 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的下标啊)

@ch4r0n :new_moon_with_face:来来来,顺便解决下我的问题

:smiling_imp:

你是看了程序员自我修养那本书吧. 有些没有讲到.

我写了几篇文章

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的代码不明白。求大佬留个邮箱什么的交流交流:smile:

weibo: http://www.weibo.com/winter1ife
mail: jmpews@gmail.com

这个链表的地址怎么找 我在上面文章写了哇 linux进程动态so注入:问题3

恩 好 我看看

已发到邮箱:ok_hand:

不一样的,我说的是full RELRO保护的情况下,got都不含link_map和dl_resolve指针,查过一些资料,都说只能从栈入手来还原出这两个指针

恩 你这个是一个原型 有很多细节的问题, 比如从什么地址开始搜索?搜索范围是多少?怎么判断搜索的字符串不是偶然的?还有就是你现在是这个是对自身而言,对于其他 task 还需要搜索到程序的 load_address.

在上面我列举了几个方法,写了一个demo,但是感觉文件架构没写好.

最近重写了另外一个 rtspy-(runtime spy), 可以参考下

哦, 你说其他进程
只搜索目标进程 PROT_READ | PROT_EXEC 的内存, 可不可以实现?

你说的和这个有点类似 但是还是有那个问题 就是搜索起始位置和搜索范围 否则的话搜搜范围太大了

翻山越岭来给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