mach_override和鱼钩之间的技术差异?

ash*_*tch 5 macos mach-o ios

今天我第一次遇到了鱼钩库https://github.com/facebook/fishhook,它可用于动态重新绑定Mach-O二进制文件中的符号(他们说是针对iOS,但我想这些代码也适用于OS X).

到目前为止,我只知道并使用了mach_override https://github.com/rentzsch/mach_override,它旨在实现类似的目标(即将一个函数的一个实现替换为另一个),但是将函数开头的汇编语句重写为跳到不同的位置.

鱼钩方法看起来更简单,但由于它"只"重写符号表,我有直觉感觉它不像mach_override方法那样通用.

当一个项目优先于另一个项目时(即一种方法不起作用,但另一种方法不起作用的情况),有人可以提供一些关于情况的一些硬技术事实吗?

Tec*_*eks 10

这两种方法使用不同的方法:

A)鱼钩工作,正如您所说,符号表中的符号.这意味着,如果符号由dylib或框架导出,并且您可以修改导入表,则可以将其重定向到您的实现.

B)mach_override使用OS X(和iOS)的Mach VM API来修补已经加载的函数 - 即已经在内存中.它通过二进制修补函数实现的开头跳转到另一个地址(您的实现)然后跳回来.

Fishhook更稳定,因为它是(i)更容易实现的操作,并且(ii)一旦dyld加载过程并且符号被链接就无缝.但是,它不适用于未由可执行文件直接加载的符号.换句话说,如果要修补printf(3),例如,它只能用于从可执行文件调用printf,而不能用于从libSystem或其他库调用.然而,Mach_override并不是那么稳定,因为它依赖于某些可以被覆盖的函数序言 - 大约90%的时间,但不是100%.

虽然yiding对于正在读取的iOS页面是正确的,但在某些情况下可以解决这个问题(如果修补可执行文件也可以修补LC_SEGMENT和section命令),并且可以使用mach VM apis取消保护页面(仅当设备被越狱时).