iOS-逆向15-HOOK原理《下》

《iOS底层原理文章汇总》
上一篇文章《iOS-逆向14-HOOK原理》介绍了符号绑定的过程,本文继续介绍Hook原理

image

1.fishhook如何通过符号找到非懒加载符号表中绑定的地址进行修改的呢,如何通过NSLog,一步一步找到对应的符号表中的地址???

fishhook修改懒加载符号表中符号绑定的地址,通过NSLog字符串告诉fishhook要修改的符号,fishhook通过字符串能找到符号表
首先知道要找的是Lazy Symbol Pointers中的符号NSLog,排在Lazy Symbol Pointers中的第一位,Indirect Symbols中的排序和Lazy Symbol Pointers中的排序一样


image

image

间接符号表Indirect Symbols和总表Symbols有关系,间接符号表中的00000F6(246)指明了符号NSLog在symbol中的角标


图片.png

image

String Table中的起始值0000D810+偏移值000000D8=0000D8E8,找到字符串常量,有一个下划线,指向_NSLog,由.隔开,前面一个是自定义的函数my_NSLog
图片.png

fishhook的查找流程:

I.通过NSLog符号在String table中查找字符串,从而找到NSLog在Symbols中的偏移值000000D8
image
II.此时通过Symbols中Data->000000D8找到NSLog在Symbols中的偏移值Offset为#246,从而找到在间接符号表Indirect Symbols中符号_NSLog的Data->000000F6(246)
image
III.找到_NSLog在Indirect Symbols中是第几个符号,在Lazy Symbols Pointers中就是第几个
image
IV.找到Lazy Symbols Pointers中的NSLog里面Data的值,修改Data进行符号重绑定
image

符号查找流程图

fishhook符号查找流程图

此过程在fishhook的github地址也有说明

image

2.符号:去符号和恢复符号,App中的符号已经被去掉了再上架,App被编译了,内存中可以通过地址访问,符号在MachO文件中占用体积大小,完全可以去除这些符号减少包的体积大小,一方面优化包的大小,一方面为了安全防破解。

I.符号的种类

间接符号必须保留
App:会去掉所有全局(给外界调用)符号,本地(static修饰)符号
动态库:全局符号要保留,供外部调用

II.Xcode默认去符号在Xcode->Build Settings->Strip Style

Strip Style有三个选项
All Symbols:全部符号去掉
Non-Global Symbols:全局符号以外的符号都去掉
Debugging Symbols:去掉调试符号


image

Deployment Postprocessing:为No只会在打包阶段去符号,为YES在编译阶段就去符号了


image

图片.png

查看MachO文件,Lazy Symbols Pointers中的间接符号不变,全局符号和本地符号都被去掉了
图片.png

image

image

若将Deployment Postprocessing:改为No只会在打包阶段去符号,则本地符号和全局符号还在


图片.png

去符号后,Xcode中的断点没生效


image

因为去符号了,断点没生效,NSLog不是全局符号和本地符号.
属于间接符号,为什么没有断住呢?这个断点并不是符号断点。

要想断住,下符号断点


图片.png

image

不知道函数名称的情况下,如何进行逆向分析呢?

I.动态调试时,使用OC调用方法objc_msgSend(),读取x0和x1获取self和_cmd

此时断点已经跳入NSLog中
如何将断点跳入objc_msgSend中呢
可以添加地址断点:
偏移地址+ASLR
实际地址0x10468de1c-ASLR0x0000000104688000 = 偏移地址0x5e1c

地址断点可以下为0x5elc+ASLR,即断住了objc_msgSend前面一句代码,若直接断符号objc_msgSend,代码中存在太多objc_msgSend不容易分辨跳出,容易乱套

image

0x0000000100895elc = ASLR0x0000000100890000+0x5e1c


image

II.恢复符号表:如果没有符号名称,在断点调试的时候比较麻烦,怎么去恢复这个符号呢?

全局符号和本地符号


图片.png

选择Strip Style模式为Debugging Symbols,去掉调试符号
查看MackO文件中的全局符号和本地符号


image

image

图片.png

选择Strip Style模式为Non-Global Symbols,去掉所有非全局符号即去掉所有本地符号


image

选择Strip Style模式为All Symbols,去掉所有全局符号和本地符号,只保留间接符号


image

符号表里面已经没有符号了,怎么恢复符号呢?类名列表,方法名列表,方法类型依然存在于MachO文件中,这些是去不掉的,去掉后无法找到方法,凭什么通过字符串找到类NSClassFromString(@"ViewController"),存在classname类名,methodtype方法签名,methodname方法名称


图片.png

类名


图片.png

方法签名
图片.png

方法名


image

通过类名,方法签名,方法名可以创造出符号表,去符号是为了减少包的体积和MachO文件的大小
通过工具restore-symbol恢复符号./restore-symbol symbolDemo -o symbolDemo2 生成恢复了符号的symbolDemo2,通过MachView查看
image

图片.png

image

恢复建立在运行时基础上,动态派发的能恢复,动态派发的必定保留了类名,方法名,方法签名以及类名方法名IMP之间的关系,c函数就恢复不了了,静态的恢复不了了,swift动态派发的可以恢复,静态调用的和函数一样不能恢复,swift相对来说比动态语言更加安全
逆向时,恢复了符号的二进制MachO文件,重新替换老的MachO文件,重新签名,重新安装,重新运行,打断点时就能看到方法名称了

III.初探反Hook防护

1.利用fishhook做防护

破解Hook第三方的用OC MethodSwizzle方法,里面使用的是系统的函数和方法,若本地App利用fishhook将系统的MethodSwizzle方法hook了,外部想要Hook动态注入,就无法进行篡改了,达到了防护的目的

framework的load方法加载更快
注入的代码会在framwork的加载之后,主工程代码之前,防护的代码卸载

I.场景:外面hook按钮1,自己做防护,自己的hook内部要用

新建工程,创建一个framework,导入fishhook代码到framework中


image

image

图片.png

图片.png

显示包内容,拷贝出AntiHook到代码文件夹


image

A.新建一个工程HookDemo,去重签上面的App->AntiHook,试着去Hook它,看看是否还能成功
重签过程

1.appSign.sh脚本拷贝到根目录文件夹
2.重新打包AntiHook为.ipa文件,ip -ry WeChata.ipa Payload/,删掉Payload文件夹


图片.png

图片.png

3.运行拿到p12文件
4.添加脚本(过程已在前文详细描述过),运行成功


image

点击按钮1,调用按钮1,点击按钮2调用按钮2
image

B.再次进行framework的动态注入,看是否能改变按钮的调用

1.新建CloudHook动态库framework
2.添加Inject类

image

3.修改appSign.sh脚本,添加CloudHook动态注入库路径,拖入yololib可执行文件,重新运行
image

image

4.点击重签的App中的按钮,发现并没有打印HOOK成功!!!,起到了反防护的目的
图片.png

C.若本工程中要使用method_exchangeImplementations方法,则需要将fishhook捕获的exchangeP暴露出来给外界使用
1.暴露函数指针方法CF_EXPORT void (*exchangeP)(Method _Nonnull m1, Method _Nonnull m2)
图片.png

2.头文件暴露#import <HookMgr/AntiHook.h>
image

3.HookMgr动态库public文件中暴露AntiHook.h
image

本工程的Hook很顺利,能顺利使用exchangeP函数指针执行method_exchangeImplementations方法进行方法交换
图片.png

将编译好的AntiHook包替换到HookDemo工程中,再次运行
AntiHook中的防护已生效,检测到了Hook,按钮1调用没有被拦截,本类中的按钮2调用被本类中的exchangeP拦截到
image

IV.此种防护方式很容易被破解,通过hopper查看framework可执行文件

图片.png

1.一旦把framework中的防护代码改了,就防护不了了,比如将字符串少写一个字母,就防护不了了
通过字符串常量很容易定位到防护代码,定位到后可以修改,将字符串常量修改了,就不会去hook这个函数了,一旦不会去修改了,就找不到了,就hook不到了,method_exchangeImplementations此字符串没法做混淆,必须要用此字符串才能使用fishhook,如果想要把字符串隐藏能用运算符,不能直接用变量
靠时间进行防护
2.靠运行时间,只要比防护代码执行的时间早,防护就没用了,可以通过对fishhook中的源码必要的系统函数进行符号断点断住或hook或将hook方法所在的load方法进行hook掉,将防护的代码不执行,就破解了防护

问:能用方法交换,方法交换方法(method_exchangeImplementations)嘛?
因为方法交换exchange是函数,它不是方法,只能用fishhook交换方法交换方法(method_exchangeImplementations)。

这一种初探反防护的方式很容易被破解,很明显的防护手段很容易被攻克掉,介绍另外一种逆向工具Monkey

V.Monkey

根据官方文档进行安装

Xcode12会遇到一个安装错误xcode 12 Types.xcspec not found

执行如下命令再次安装即可

sudo ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/PrivatePlugIns/IDEOSXSupportCore.ideplugin/Contents/Resources /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications

在.zshrc中配置环境变量THEOS配置环境变量,配置成功后在终端执行nic.pl

#逆向相关的配置
export THEOS=/opt/theos
#写入环境变量
export PATH=/opt/MonkeyDev/bin:$THEOS/bin:$PATH
图片.png

安装成功后出现如下图标


image

Monkey进行重签名和代码注入

1.将微信8.0.2的ipa包放到TargetApp目录下,运行程序


图片.png

image

2.代码注入,将前文运行的antihook.ipa包放入TargetApp目录下
I.Logos目录下的MonkeyDemoDylib.xm选择为Objective-C++ Source源码,方便进行编辑
II.hook目标App中的点击事件,运行


图片.png
%hook ViewController
- (void)btnClick1:(id)sender {
    NSLog(@"大哥!哥么干掉你了!!!");
}
%end
image

点击按钮1,和按钮2,logos语法hook成功生效,检测到了MonkeyDemo在hook之后,但MonkeyDemo仍旧将btnClick1干掉了,防护没有防住


image

3.防护没有防住的原因,可能Monkey中进行hook的不是method_exchangeImplementations方法,是getImp和setImp方法,在防护的framework中继续hook防护getImp和setImp方法,看是否能防住Monkey中的hook


image

重新编译,将AntiHook包拖入到MonkeyDemo中,运行,检测到了3次Hook,分别是method_exchangeImplementations,method_setImplementation,method_getImplementation


image

再次点击按钮1,成功防住了Monkey的Hook,说明Monkey中的Hook用的是method_setImplementation和method_getImplementation方法
image

Monkey中通过libsubstrate.dylib进行Hook,写的logos语句均被此动态库读取,解析logos语句,logos语句对runtime代码进行了简化

%hook ViewController
- (void)btnClick1:(id)sender {
    NSLog(@"大哥!哥么干掉你了!!!");
}
%end

MonkeyDemoDylib.mm解析.xm文件中的logos语句,最后被libsubstrate.dylib动态库读取进行hook


图片.png

image

Monkey中的寻找回家的路,将AntiHook改为没有任何防护,再次替换TargetApp中的AntiHook包,重新运行,此时可以Hook到btnClick1,之前OC层面的methodSwizzle和exchangeMethod时,无法回到原来的代码或回到原来的代码时,要单独保存原来的代码,而用Monkey直接用%orig调用


image

image

图片.png

找回回家的路,执行原来的代码,%orig;相当于setImp后,执行getImp,编译期就已经有了,在MonkeyDemoDylib.mm文件中,被libsubstrate.dylib动态库读取进行hook


image

图片.png

Framework注入的代码会先执行,依赖于dyld源码中的哪一部分逻辑?

Dyld加载主程序的时候先加载insertDylid动态库,再是Framework动态库,再调用main函数,再实例化主程序------->objc中执行load方法------>c++构造方法,load顺序和ImageList有关,ImageList和链接顺序有关,insertDylid一个一个链接后,再链接系统的,再在ImageList中一个一个add添加后,执行load的时候,拿ImageList中的load循环执行,load方法看ImageList的顺序。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,431评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,637评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,555评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,900评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,629评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,976评论 1 328
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,976评论 3 448
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,139评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,686评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,411评论 3 358
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,641评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,129评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,820评论 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,233评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,567评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,362评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,604评论 2 380

推荐阅读更多精彩内容