fishhook 原理探究(简述fish的基本原理及应用)
cac55 2024-09-29 09:30 44 浏览 0 评论
前言
今天要和大家分享的是 Facebook 提供的一个动态修改链接 mach-O 文件的工具 fishhook。它利用 MachO 文件加载原理,通过修改懒加载和非懒加载两个表的指针达到 C 函数 HOOK 的目的。
这个工具本身代码才两百多行,如果你对 MachO 有一定的了解推荐读者阅读其源码.本文将从 fishhook 的使用切入,带着大家探索其原理。废话不多说,我们上代码。
fishhook简单使用
它所提供的接口
拿到 fishhook 之后你会发现,它真的非常简单,这家伙只有两个文件 “fishhook.h” 和 “fishhook.c”。它提供的接口仅有一个结构体和两个函数:
rebinding 结构体用来确定你要 HOOK 的函数和要交换的函数地址。
struct
rebinding {
constchar
*name;
//需要HOOK的函数名称,C字符串
void
*replacement;
//新函数的地址
void
**replaced;
//原始函数地址的指针!
};
注意replaced:在使用该结构体时,由于函数内部要修改外部指针变量所保存的值,所以这里是指针的指针(二级指针)。
rebind_symbols 和 rebind_symbols_image 函数用来 HOOK 的两个方法。只不过后者是指定某个镜像文件的时候使用。所以一般我们直接使用前者。
镜像文件:比如 NSLog 函数是在 Fundation 框架中,那么 Fundation 在内存中就是一个镜像文件。
int
rebind_symbols(
struct
rebinding rebindings[],
size_t
rebindings_nel);
int
rebind_symbols_image(
void
*header,
intptr_t
slide,
struct
rebinding rebindings[],
size_t
rebindings_nel);
多说无益,玩一下最重要!
HOOK一下NSLog
我们新建一个 SingleView 的项目。在 ViewDidLoad 中对系统的 NSLog 函数进行 HOOK 。
//函数指针
staticvoid
(*sys_nslog)(
NSString
* format,...);
//定义一个新的函数。HOOK成功后NSLog调用时,会来到这里
void
myNSLog(
NSString
* format,...){
format = [format stringByAppendingString:@
"\n上钩了!\n\n"
];
sys_nslog(format);
//调用系统的NSLog,HOOK成功后sys_nslog指针保存的是Fundation中NSLog的地址
}
- (
void
)viewDidLoad {
[
super
viewDidLoad];
//准备rebinding结构体
struct
rebinding nslog;
nslog.name =
"NSLog"
;
//需要HOOK的函数名称
nslog.replacement = myNSLog;
//新函数的地址
nslog.replaced = (
void
*)&sys_nslog;
//原始函数指针
//准备数组,将一个或多个 rebinding 结构体放进去。
struct
rebinding rebs[
1
] = {nslog};
/**
arg1: 存放rebinding 结构体的数组
arg2: 数组的长度
*/
rebind_symbols(rebs,
1
);
}
-(
void
)touchesBegan:(
NSSet
<
UITouch
*> *)touches withEvent:(
UIEvent
*)
event
{
NSLog
(@
"点击了屏幕!"
);
}
运行之后,可以发现 NSLog 的函数调用已经被 HOOK 成功了!几行代码轻松搞定,看起来很厉害的样子。(PS:但是剧情如果这样发展,太过简单了。我预感,马上会有一个转折...) 接下来迫不及待的,我们 HOOK 一下自定义的函数,结果你会发现怎么都 HOOK 不到。姿势和 HOOK 系统的 NSLog 一样(代码我就不贴了,不信你自己去 ~~浪费时间~~ 尝试)。那为什么系统函数能 HOOK 成功,自定义的却 HOOK 不到呢?so~,往下看...
fishHook原理分析
MachO
首先我们要了解一个东西。我们写好的代码,生成的 iOS 程序其实是一个可执行文件。这个文件格式是 MachO 格式,所以一般我们称其为 MachO 文件。在刚才的 APP 包里面,它长这样:
这个文件里面包含的就是数据和指令。比如你定义的类、方法、全局变量、方法实现等等。我们为什么要讨论 MachO?因为结合上面的疑问我们思考一个问题:自定义函数和系统函数,在文件位置上有什么区别?
- 自定义函数在本 MachO 文件中,在运行时刻进入内存,自定义函数在本镜像文件中。
- 系统函数在系统框架中,在运行时刻进入内存,系统函数在系统的动态库中,比如 NSLog 在 Fundation 这个镜像文件中。
那既然如此我们就可以得到这样的结论:自定义的函数,在编译时刻,编译器就可以确定函数的实现地址(在 MachO 文件中的偏移地址)。但是系统函数是没办法知道的。那么在 CPU 执行我们的代码的时候,我们是如何告诉 CPU ,我们需要调用系统函数。以及如何知道系统函数的地址的呢?这里就要提到 PIC 技术了。
PIC(Position Independ code)技术
PIC翻译过来就是位置独立代码。
说人话:比如当你的程序要调用一个 MachO 外部函数的时候,编译器是没办法知道该函数的地址的。所以它在 MachO 文件里面生成一个列表,列表里面放指针。让当前的系统函数调用指向这个列表里面对应的指针。等到我们的 MachO 文件加载进入内存时,再将系统函数的真实地址,一个一个的赋值给列表中的指针。
- 那么这个列表,我们称为符号表。
- 这里面的指针,我们称为符号。
- 给里面的指针赋值的过程,我们称为符号绑定。
那么说到这里,我想很多童鞋已经猜到了。fishhook 之所以 HOOK 不了自定义的函数,就是因为自定义的函数没有通过符号寻找地址这个过程。而系统函数是通过符号去绑定实现地址的。fishhook 就是利用这一点,去修改了系统函数的符号达到 HOOK 的目的。其实我们通过fishhook 的函数名称就不难看出来 rebind_symbols 符号重绑定。
这篇文章到这里其实已经差不多了。不过理论总归是理论,很多人总想眼见为实的探索。如果你想探索,那么你准备酒,我准备 肉 MachOView,我们往下走...
fishHook原理探索
观察符号绑定和重绑定过程
MachO 文件内部存有代码和数据,代码放在 _TEXT 段(代码段)中,数据放在 _DATA 段(数据段)中。数据段除了全局变量、常量、自定义类还有很多东西,比如我们刚才提到的符号表。接下来,我们要借助一个图形化工具,去分析我们的 MachO 文件。这个工具就是 MachOView ,它长这样:
分析MachO文件
我们将刚才的 MachO 文件放入到 MachOView 里面分析一下。可以看到下图。
找到符号偏移地址
在这里面我们就可以清晰的看到符号表在文件中长啥样了。并且最重要的是能够看出符号在文件中的偏移位置。
有了这个偏移值,我们可以在项目运行的时候,通过LLDB,观察的符号的绑定和重绑定过程。
动态调试
1、来到我们原来的代码,在这几行打上断点并运行。
2、第一次断点触发时,我们利用 LLDB 查看符号中的值。
首先查看 MachO 文件的地址:通过 image list指令,查看所有镜像文件( MachO 文件)的地址。
然后通过 memory read指令读取内存。因为符号是指针,所以读取8个字节的数据。
但是这里面存放的到底是不是 NSLog 的真实地址呢?我们如何查看。
我们可以利用 dis-s查看反汇编。由于 iOS 的小端模式,所以读数据从右往左读。比如:图中数据 d0 ea e10201000000那么读取出来的地址是 0x0102e1ead0
然后我们通过汇编发现,这里并不是 NSLog 的地址。如果是,这里会显示 Fundation 框架中的 NSLog 函数(等下会看到现象)。其原因是因为 NSLog 是懒加载符号,此时是第一次调用,还没有绑定符号。此时如果跟汇编,我们最终会看到 dyld_stub_binder 函数的调用。所以,我们过掉断点。
3、来到第二个断点处
我们重复上面的步骤,查看符号的内存数据,然后取出里面的值,通过 dis 反汇编查看。你会发现此刻已经绑定了符号。可以清晰的看到里面是 NSLog 的实现地址了。(这个过程就是符号绑定!)
接下来,我们来看看 rebind_symbols 之后,我们的符号表里面保存的地址变成了啥?
4、来到第三个断点处(第42行)
我们重复上面的步骤,查看符号的内存数据,然后取出里面的值,通过 dis 反汇编查看。你会发现此刻符号内的数据已经替换成了自定义的函数地址了。(符号重绑定成功!)
经过一系列动态调试,我们可以观察到符号绑定和重绑定的全部过程。但是,fishhook 是怎么通过我们传给它的一个字符就找到了我们 NSLog 的符号的呢?我们往下看...
通过符号找到字符串
我们还是来到 MachOView 里面,注意,我们数一下,NSLog 这个符号,在懒加载符号表里面是第几个?很明显第一个。
所以,与懒加载表对应的另外一张表就出来了。indirect Symbols。懒加载表里面 NSLog 是第一个,那么它在 indirect Symbols 表里面也就是第一个。
接下来,将 indirect Symbols 里面对应的 Data 值换算成为10进制。
0x81 的十进制是 129 .为什么要转换这个数据,因为它又是另外一个列表的角标。
这个列表就是 Symbols ,我们查看一下。
那么到了 Symbols 里面就接近我们最终的字符常量了。注意在 Symbols 里面有 String Table 的 Index 值。这里是 0xC9。这就说明,在 String Table 里面,偏移 0xC9 的地址就是我们NSLog字符。
我们来到 String Table 里面查看一下。我们通过起始位置加上偏移便可以定位到 NSLog 字符了。
函数名称在字符表里面都是5F也就是 _ 开始 然后00也就是 . 结束! 这也就是为什么你给 fishhook 一个系统函数名称,它能够帮你顺利 HOOK 到系统函数的原理了。通过上面一顿分析,我相信官方的图你也能看懂了。官方是以 close 函数为例:
后记
刚才我们通过动态调试加 MachOView 的分析梳理了整个符号绑定以及重绑定的过程。这个过程也是 fishhook 能够 HOOK 系统函数的原理。了解了其原理接下来你可以分析一下它的源码了。Facebook那帮家伙是怎么通过代码实现刚才的过程?好在 fishhook 的源码并不多,但是如果你不了解 MachO 的相关 API ,这百来行代码也会让你怀疑人生。
还有一个问题,fishhook 这个工具我们可以用它来干啥?我例举个实际的运用场景:比如最近抖音团队分享的二进制重排启动优化。在这个优化的过程中,我们如何定位到启动时所有的OC 方法?我想你已经猜到了,通过 objc_msgSend 函数的 HOOK 。
原文作者:逻辑iOS技术号(Hank)
公众号:
相关推荐
- 无力吐槽的自动续费(你被自动续费困扰过吗?)
-
今天因为工作需要,需要在百度文库上下载一篇文章。没办法,确实需要也有必要,只能老老实实的按要求买了个VIP。过去在百度文库上有过类似经历,当时为了写论文买了一个月的VIP,后面也没有太注意,直到第二个...
- 百度文库推出“文源计划”创作者可一键认领文档
-
11月7日,百度文库发布了旨在保护创作者权益的“文源计划”。所谓“文源计划”,即为每一篇文档找到源头,让创作者享受更多的权益。据百度文库总经理李小婉介绍,文源计划分为三部分,分别是版权认证、版权扶持和...
- 有开放大学学号的同学,百度文库高校版可以用了。
-
还在网上找百度文库的下载方式,只要从身边的朋友在读开放大学的,那他(她)的学号就可以登陆到国家开放大学图书馆,还使用百度文库高校版来下载。与百度文库稍有不同,但足够使用了。现转国图链接如下:htt...
- 搜索资源方法推荐(搜索资源的方法)
-
今天msgbox就要教大家如何又快又准的搜到各类资源,第一点,排除干扰百度搜索出来啊经常前排展示它的产品以及百度文库,如何去除呢?很简单,后面输入空格减号百度文库,比如你搜高等数学百度文库很多,只要后...
- 一行代码搞定百度文库VIP功能(2021百度文库vip账号密码共享)
-
百度文库作为大家常用查资料找文档的平台,大多数文档我们都可以直接在百度文库找到,然而百度文库也有让人头痛的时候。好不容易找到一篇合适的文档,当你准备复制的时候他却提示你需要开通VIP才能复制~~~下载...
- 百度文库文档批量上传工具用户说明书
-
百度文库文档批量上传工具用户说明书1、软件主要功能1、批量上传文档到百度文库,支持上传到收费、VIP专享、优享以及共享。2、支持自动分类和自动获取标签3、支持多用户切换,一个账户传满可以切换到...
- 百度文库现在都看不到文档是否上传成功,要凉了吗?
-
打开知识店铺,百度文库文档里显示都是下载这一按键,上传的文档也看不到是否成功?咋情况,要取消了吗?没通过审核的也不让你删除,是几个意思,想通吃吗?现在百度上传文档也很费劲,有时弄了半天的资料上传审核过...
- 微信推广引流108式:利用百度文库长期分享软文引流
-
百度文库相对于百度知道、百度百科来说,操作上没那么多条条框框,规则上也相对好把握些。做一条百度知道所花费的精力一般都会比做一条百度文库的要多些,老马个人操作下来觉得百度文库更好把握。但见仁见智吧,今天...
- 职场“避雷”指南 百度文库推出标准化劳动合同范本
-
轰轰烈烈的毕业季结束了,众多应届生在经过了“职场海选”后,已正式成为职场生力军的一员。这一阶段,除了熟悉业务,签订劳动合同、了解职场福利也迅速被提上日程。而随着国人法律意识的增强,百度文库内《劳动合同...
- 《百度文库》:素材精选宝库(百度文库官网首页)
-
《百度文库》:独特功能助力选择高质量素材在当今信息爆炸的时代,如何高效地获取并利用有价值的素材成为了许多人面临的挑战。而《百度文库》作为百度公司推出的一款在线文档分享平台,凭借其丰富的资源、强大的功能...
- 深度整合和开放AI能力 百度文库和网盘推出内容操作系统「沧舟OS」
-
【TechWeb】4月25日消息,Create2025百度AI开发者大会上,百度文库和百度网盘推出全球首个内容操作系统——沧舟OS。基于沧舟OS,百度文库APP全新上线「GenFlow超能搭子」...
- 女子发现大二作业被百度文库要求付费下载,律师:平台侵权,应赔偿
-
近日,28岁的黎女士在百度百科搜索家乡的小地名时,发现了自己在大二完成的课题作业。她继续搜索,发现多个平台收录了该文,比如豆丁网和文档之家等,有的还设置了付费或积分下载。2月15日,九派新闻记者以用户...
- 2016杀入百度文库的新捷径,只有少数人才知道的喔
-
百度的产品在SEO优化中的分量真不用多说,其实很多人都像我一样一直在找捷径。但是我经常发现很多人都是在用死方法。比如发贴吧发帖而不知道去申请一个吧主,知道自问自答而不知道去申请一个合作资格。口碑和贴吧...
- 百度文库付费文档搜索方法(百度文库付费文档搜索方法有哪些)
-
一直以来,百度文库中无论是个人中心还是个人主页,都没有像淘宝一样的店内搜索功能,连最近新开的知识店铺也没有设计店内搜索功能,这无论是对上传用户还是下载用户都不方便,上传用户想要搜索自己的文档无法办到...
- 供读者免费使用!泰达图书馆机构版百度文库新年上新啦
-
在泰达图书馆读者使用百度文库数字资源不需要VIP,免-费-用!惊不惊喜?快来了解一下吧……新年伊始,为满足区域企业、高校、科研院所以及居民群众在教学、科研及学习过程中,对各类文献资源的需求,泰达图书馆...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 如何绘制折线图 (52)
- javaabstract (48)
- 新浪微博头像 (53)
- grub4dos (66)
- s扫描器 (51)
- httpfile dll (48)
- ps实例教程 (55)
- taskmgr (51)
- s spline (61)
- vnc远程控制 (47)
- 数据丢失 (47)
- wbem (57)
- flac文件 (72)
- 网页制作基础教程 (53)
- 镜像文件刻录 (61)
- ug5 0软件免费下载 (78)
- debian下载 (53)
- ubuntu10 04 (60)
- web qq登录 (59)
- 笔记本变成无线路由 (52)
- flash player 11 4 (50)
- 右键菜单清理 (78)
- cuteftp 注册码 (57)
- ospf协议 (53)
- ms17 010 下载 (60)