xcode反汇编调试iOS模拟器程序(三)查看Objective-C函数与参数

简介: 在Objective-C函数的入口处(第一行)加断点,可用esp指针来探查参数。 以esp为基址,往后的偏移分别是: 0:函数执行完毕后的返回地址(不是返回值的地址哦) 4:对象实例的指针,即self指针 8:selector,实际是一个...

在Objective-C函数的入口处(第一行)加断点,可用esp指针来探查参数。

以esp为基址,往后的偏移分别是:

0:函数执行完毕后的返回地址(不是返回值的地址哦)

4:对象实例的指针,即self指针

8:selector,实际是一个char数组型的字符串,即char*

12:(如果有)第一个参数

…(前一个参数的基址+前一个参数所占的字节数):(如果有)第n个参数


由此,要调试这样一个函数

- (void)para1:(id)p1 para2:(CGRect)p2 para3:(CGPoint)p3 para4:(id)p4
{
    NSLog(@"para1:(id)p1 para2:(CGRect)p2 para3:(CGPoint)p3 para4:(id)p4");
}

- (void)viewDidLoad
{
    [self para1:[UIApplication sharedApplication] para2:CGRectMake(10, 20, 30, 40) para3:CGPointMake(50, 60) para4:self];

时,断点后可在gdb这样调试:

po *(id*)($esp+4)                  // 得到对象实例的描述。执行越过函数头部后,应为 po *(id*)($ebp+8),以下类同

p (char*)*(SEL*)($esp+8)     // 得到selector的名字

po *(id*)($esp+12)               // 得到p1的description

p *(CGRect*)($esp+16)       // 得到p2的各个成员值,输出结果为:“(CGRect) $1 = origin=(x=10, y=20) size=(width=30, height=40)”

p *(CGPoint*)($esp+32)   // 因为一个CGRect结构体占16字节(4个float),所以是“+32”,即“+16+16”, 得到p3的各个成员值,输出结果为:“(CGPoint) $4 = (x=50, y=60)”

po *(id*)($esp+40)       // 因为一个CGPoint结构体占8字节(2个float),所以是“+40”,即“+32+8”、得到p4的description

(gdb) po *(id*)($esp+4) 
<ViewController: 0x757f8c0>
(gdb) p (char*)*(SEL*)($esp+8) 
$1 = 0xf37b "para1:para2:para3:para4:"
(gdb) po *(id*)($esp+12) 
<UIApplication: 0x9250000>
(gdb) p *(CGRect*)($esp+16) 
$2 = {
  origin = {
    x = 10, 
    y = 20
  }, 
  size = {
    width = 30, 
    height = 40
  }
}
(gdb) p *(CGPoint*)($esp+32)
$3 = {
  x = 50, 
  y = 60
}
(gdb) po *(id*)($esp+40) 
<ViewController: 0x757f8c0>

注意:由于在第一行,push了ebp,会导致esp被修改,而第二行又立刻把esp的值赋给ebp,所以在执行经过函数的这些头部后,可以用ebp类似地访问,不过参数的偏移都需要+4。

下面是如何查看浮点型参数。

浮点型参数会通过SSE寄存器来传递,可以在gdb中这样查看:

p $xmm0

(lldb不能用上面的命令,暂没去研究用什么替代)

例如调试上例中的

CGRectMake(10, 20, 30, 40)

编译器会把参数反序送入xmm寄存器组,即40传入xmm0,30传入xmm1……

在CGRectMake加断点,执行到下图中的位置时输入命令


命令结果如下:
(gdb) p $xmm0
$1 = {
  v4_float = {0, 0, 0, 40}, 
  v2_double = {0, 5.4811317061554153e-315}, 
  v16_int8 = {0 <repeats 12 times>, 66, 32, 0, 0}, 
  v8_int16 = {0, 0, 0, 0, 0, 0, 16928, 0}, 
  v4_int32 = {0, 0, 0, 1109393408}, 
  v2_int64 = {0, 1109393408}, 
  uint128 = 35467839930368
}
因为SSE寄存器是128位的,gdb并不知道哪些bit是有意义的,所以列出了一些猜测的结果。

我们传入的是CGFloat,即float,故v4_float = {0, 0, 0, 40} 是有意义的。

当传入的是double型,则v2_double有意义。


转载请注明出处:http://blog.csdn.net/hursing

xcode反汇编调试iOS模拟器程序
(一)查看反汇编
(二)看懂反汇编
(三)查看Objective-C函数与参数
(四)自动断点应用之NSNotificationCenter
(五)调试objc_msgSend函数
(六)函数出入口处的处理与局部变量
(七)Debug与Release的区别

(八)反汇编自己的代码来掌握规则

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
Web App开发 JavaScript iOS开发
Xcode9用Safari调试模拟器JS代码显示“无可检查的应用程序”的原因
Xcode9用Safari调试模拟器JS代码显示“无可检查的应用程序”的原因
1135 0
|
6月前
|
C语言
【汇编语言实战】基础知识+函数的引用(求1+2+..+N)+OllyDBG的使用
【汇编语言实战】基础知识+函数的引用(求1+2+..+N)+OllyDBG的使用
39 1
|
6月前
|
编译器 API C语言
在x86架构汇编语言中函数参数传递的三种约定
在x86架构汇编语言中函数参数传递的三种约定
183 2
|
6月前
|
Windows
86/88汇编代码的运行调试
86/88汇编代码的运行调试
41 0
|
6月前
|
前端开发 rax Linux
汇编语言与x64函数参数传递
汇编语言与x64函数参数传递
204 0
|
搜索推荐 iOS开发 芯片
记录一次Xcode 模拟器项目编译问题
记录一次Xcode 模拟器项目编译问题
记录一次Xcode 模拟器项目编译问题
|
存储
汇编语言与微机原理-变量的调试与分析
汇编语言与微机原理-变量的调试与分析
159 0
汇编语言与微机原理-变量的调试与分析
|
开发工具 Perl
Xcode12 适配模拟器问题总结
Xcode12运行模拟器会报以下错误
212 0
iOS开发:Xcode自带的模拟器常用快捷键的使用
在iOS开发过程中,为了方便起见在测试程序的效果的时候,开发者会使用Xcode自带模拟器进行操作,而且Xcode自带的手机模拟器包含了苹果的所有最新的手机型号尺寸,这样也方便了开发者测试不同机型,但是在电脑Xcode上面的模拟器操作和真机操作还是有很大的不便,如果不知道常用的快捷键,操作起来也不方便,那么本篇博文就来分享一下Xcode自带模拟器的快捷键操作集合,分享给有需要的人。
589 0
iOS开发:Xcode自带的模拟器常用快捷键的使用
|
iOS开发
Xcode清理模拟器文件
在"XCode->Preferences->Components->Simulators"安装的模拟器组件,没有提供删除方式,而且容量比较大
222 0