iOS-逆向06-汇编终章OC反汇编

《iOS底层原理文章汇总》

1.OC反汇编

图片.png

objc_msgSend中存在两个参数(id,SEL),id类型实质上是一个结构体指针类型,SEL是一个选择器

x8寄存器中存放的是一个地址0x1021295b0,将x8寄存器中存放的地址值读取8个字节内容存放到x0寄存器中

再将x8寄存器中存放的一个地址0x1021295a0,读取8个字节内容存放到x1寄存器中

将x0,x1的值传入objc_msgSend方法中

(lldb) x 0x1021295b0
0x1021295b0: 98 96 12 02 01 00 00 00 d0 95 12 02 01 00 00 00  ................
0x1021295c0: 08 00 00 00 10 00 00 00 08 00 00 00 00 00 00 00  ................
(lldb) po 0x0102129698
Person

(lldb) x 0x1021295a0
0x1021295a0: 05 3d 2a 8b 01 00 00 00 00 00 00 00 00 00 00 00  .=*.............
0x1021295b0: 98 96 12 02 01 00 00 00 d0 95 12 02 01 00 00 00  ................
(lldb) po (SEL)0x018b2a3d05
"person"

(lldb) register read x0
      x0 = 0x0000000102129698  (void *)0x000001a102129671
(lldb) register read x1
      x1 = 0x000000018b2a3d05  "person"
(lldb)
图片.png

通过objc_msgSend方法分析就能还原方法的调用
进入[Person person]方法后发现,系统的alloc和init在iOS11以后没有走objc_msgSend方法了,
根据系统的版本不同,而会有不同的优化,iOS11.0的系统中alloc不会调用objc_msgSend方法了,而init还会调用objc_msgSend方法,如下是iOS11.0系统真机

iOS-逆向06-汇编终章OC反汇编_第1张图片
image

objc_msgSend方法中没有看到x0赋值,可以推测objc_alloc的返回值又赋值给了x0传入到了objc_msgSend方法,读取x0为init方法,读取x1为Person实例对象,为objc_msgSend的两个参数id self和SEL _cmd

图片.png

最初的版本[[self alloc] init]会有两次消息发送,如iOS9.0
到了iOS11.0只有init会走消息发送
到了iOS13.0都不会走消息发送了

执行完[Person person]方法后,返回值存放在x0,是一个Person实例对象

iOS-逆向06-汇编终章OC反汇编_第2张图片
image

会进入objc_storeStrong函数,OC中用strong修饰的对象都会调用这个函数,main中有个局部变量,相当于有个强引用在引用它Person *person = [Person person],这一句代码相当于让p销毁了,函数调用栈要平衡了

将x0存到x8指向的地址空间,x0为objc_msgSend的返回值&p
x8的值赋值给x0
0赋值给x1

iOS-逆向06-汇编终章OC反汇编_第3张图片
image

(lldb) register read x0
x0 = 0x00000001c4039d60
(lldb) po 0x00000001c4039d60

传入objc_storeStrong方法,x0 = *location = &p;
obj = nil,

即p = nil,
id = prev = *location = person对象
*location = person对象 = obj = nil
objc_release(prev) = objc_release(person对象)回收堆空间
release p
栈平衡时回收栈空间释放p指针变量的地址

iOS-逆向06-汇编终章OC反汇编_第4张图片
image
图片.png

2.通过工具分析OC反汇编

将Product下生成的MachO文件直接拖入Hopper Disassembler v4中


iOS-逆向06-汇编终章OC反汇编_第5张图片
image

双击OBJC_CLASS$_Person得到Person类的地址在1000096c8

image
iOS-逆向06-汇编终章OC反汇编_第6张图片
image

双击Selector,person

iOS-逆向06-汇编终章OC反汇编_第7张图片
image
iOS-逆向06-汇编终章OC反汇编_第8张图片
image
iOS-逆向06-汇编终章OC反汇编_第9张图片
image

MachO中分析汇编代码的时候根据地址能找到字符串,找到字符串后根据类型知道是什么,有类,类的引用,方法的名称,放在不同的位置代表不同的意义,hopper和MachOView都是根据特定的格式读取MachO文件

3.Block的反汇编

I.不引用外部变量的block

iOS-逆向06-汇编终章OC反汇编_第10张图片
image

读取寄存器x0发现此block是一个全局block,全局静态block不引用外部变量,在编译器确定内存分配,存在于MachO文件中的可执行文件常量区


iOS-逆向06-汇编终章OC反汇编_第11张图片
image

Block本质是结构体,isa指针8字节,为全局block、栈区block、堆区block,flags占用4个字节,reserved占用4字节,invoke中的内容是16个字节之后的内容,descriptor是底层问题描述


iOS-逆向06-汇编终章OC反汇编_第12张图片
图片.png
iOS-逆向06-汇编终章OC反汇编_第13张图片
image

通过反汇编工具Hopper查看invoke中的内容,双击全局block,查看block结构

iOS-逆向06-汇编终章OC反汇编_第14张图片
image
图片.png

双击invoke,invoke中的内容都显示出来

iOS-逆向06-汇编终章OC反汇编_第15张图片
图片.png

descriptor在block的上方

iOS-逆向06-汇编终章OC反汇编_第16张图片
图片.png

II.引用外部变量的block

isa指针指向栈block

iOS-逆向06-汇编终章OC反汇编_第17张图片
image

读取invoke,通过dis -s invoke内存地址读取到

iOS-逆向06-汇编终章OC反汇编_第18张图片
image
iOS-逆向06-汇编终章OC反汇编_第19张图片
image

hopper工具分析:双击invoke,双击descriptor查看

iOS-逆向06-汇编终章OC反汇编_第20张图片
image

hopper查看流程图

图片.png

iOS-逆向06-汇编终章OC反汇编_第21张图片
图片.png

流程图如下,if判断可以通过过汇编代码分析,但没有图分析显示分期的

iOS-逆向06-汇编终章OC反汇编_第22张图片
图片.png

查看伪代码:还原main函数

iOS-逆向06-汇编终章OC反汇编_第23张图片
image

你可能感兴趣的:(iOS-逆向06-汇编终章OC反汇编)