xcode反汇编调试iOS模拟器程序(五)调试objc_msgSend函数

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

反汇编调试objective-c,遇到最多的就是objc_msgSend这函数了,本节主要讲讲它的实现以及调试过程的一些技巧。

以UIWebView为例子,看看它在loadRequest时做了什么。

首先必须明白,原始代码中调用

[cpp]  view plain copy
  1. [uiWebViewInstance loadRequest:request]  
的实质是调用了
[cpp]  view plain copy
  1. objc_msgSend(uiWebViewInstance, "loadRequest:"的selector, request)  

编写一个用到UIWebView的demo,主要功能是打开一个网页。

在main函数加断点,触发后,在命令行输入:

[plain]  view plain copy
  1. b -[UIWebView loadRequest:]  
然后continue,直到触发断点,如下图:


用step over跑到第17行,或直接在那加个断点continue到那。旁边的注释已经显示,call的是存储了objc_msgSend这个函数的偏移地址的代码位置。

17行的前三行,可以看出其动作是往栈上传参数,这三个参数原本是放在edx,ecx,eax的,所以如果参数不多,也可以不用esp为基址来查参数。

在当前的命令行输入

[plain]  view plain copy
  1. register read  
来查看各寄存器的值。lldb会把当前值的意义也输出来。但gdb不会,gdb对应的命令是
[plain]  view plain copy
  1. info registers  

结果如下图:


从ecx的内容可以看出,要call的selector的名字同样是loadRequest:,后面会验证。

接着,step into,可以看到:

那里只有一个跳转命令,继续step into,跳到objc_msgSend真正的地址,看到下图所示的代码:


简单点说,这些代码做了这些事:

1. 先判断传来的对象是否nil,是的话,把返回值(esp+4)置0就返回了,不是就进行下一步。即使是void型的函数,也是被当做有返回值的,只是没用。

2. 查找这个method有没有被cache,有就jmpl到cache了的IMP地址;没有就以selector代表的字符串从这个类的method list里找出method来(第13到20行的循环),cache后再jmpl。如果找不到method就抛出异常然后程序崩溃了。

一个小技巧是,如果想省去点好多次step over来跳过查找的步骤,可以在两个jmpl *%eax的地方加断点,然后run到那里(图中的第31行和38行)。如果传来的对象不是nil,最后都会到这来。此时eax里保存的是函数的地址,即objective-c运行时库定义的IMP(指向函数的指针),jump过去就能到目标函数里了。

另外,在调试反汇编时,step over和step into不要用快捷键,要用调试工具栏上的按钮。不知道为什么按快捷键都等于run了……

接着,在jmpl处step into,就到真实的函数了:


证实了刚才ecx是传了selector名字。


在lldb中搜索

[plain]  view plain copy
  1. image lookup -r -s objc_msgSend  
可以看到:
[plain]  view plain copy
  1. 13 symbols match the regular expression 'objc_msgSend' in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/usr/lib/libobjc.A.dylib:  
  2.         Address: libobjc.A.dylib[0x0001708c] (libobjc.A.dylib.__TEXT.__text + 90252)  
  3.         Summary: libobjc.A.dylib`objc_msgSend        Address: libobjc.A.dylib[0x00017104] (libobjc.A.dylib.__TEXT.__text + 90372)  
  4.         Summary: libobjc.A.dylib`objc_msgSendSuper        Address: libobjc.A.dylib[0x0001716c] (libobjc.A.dylib.__TEXT.__text + 90476)  
  5.         Summary: libobjc.A.dylib`objc_msgSendSuper2        Address: libobjc.A.dylib[0x00017468] (libobjc.A.dylib.__TEXT.__text + 91240)  
  6.         Summary: libobjc.A.dylib`objc_msgSendSuper2_debug        Address: libobjc.A.dylib[0x00017338] (libobjc.A.dylib.__TEXT.__text + 90936)  
  7.         Summary: libobjc.A.dylib`objc_msgSendSuper2_stret        Address: libobjc.A.dylib[0x00017478] (libobjc.A.dylib.__TEXT.__text + 91256)  
  8.         Summary: libobjc.A.dylib`objc_msgSendSuper2_stret_debug        Address: libobjc.A.dylib[0x000172c8] (libobjc.A.dylib.__TEXT.__text + 90824)  
  9.         Summary: libobjc.A.dylib`objc_msgSendSuper_stret        Address: libobjc.A.dylib[0x00017460] (libobjc.A.dylib.__TEXT.__text + 91232)  
  10.         Summary: libobjc.A.dylib`objc_msgSend_debug        Address: libobjc.A.dylib[0x000171dc] (libobjc.A.dylib.__TEXT.__text + 90588)  
  11.         Summary: libobjc.A.dylib`objc_msgSend_fpret        Address: libobjc.A.dylib[0x00017480] (libobjc.A.dylib.__TEXT.__text + 91264)  
  12.         Summary: libobjc.A.dylib`objc_msgSend_fpret_debug        Address: libobjc.A.dylib[0x00017488] (libobjc.A.dylib.__TEXT.__text + 91272)  
  13.         Summary: libobjc.A.dylib`objc_msgSend_noarg        Address: libobjc.A.dylib[0x00017254] (libobjc.A.dylib.__TEXT.__text + 90708)  
  14.         Summary: libobjc.A.dylib`objc_msgSend_stret        Address: libobjc.A.dylib[0x00017470] (libobjc.A.dylib.__TEXT.__text + 91248)  
  15.         Summary: libobjc.A.dylib`objc_msgSend_stret_debug  
objc_msgSend会有好多个版本:

objc_msgSend是普通调用,返回值为void、id、指针、int等32bit能表示的数据的objective-c函数会用到它。

objc_msgSend_stret在返回值为结构体时用到,stret表示structure return。值得一提的是,C++类也算是结构体哦。

objc_msgSend_fpret在返回值为浮点数时用到,fpret表示floating point return

带Super的表示调用父类的函数。


如上节所说,在obj_msgSend的第一行加自动断点 p (char*)*(SEL*)($esp+8) 就会打印多到你不想看的selector名字。注意这个地方不能去po对象,因为po的实质是调用对象的description,这个会再调用obj_msgSend,无限递归就挂了。


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

反汇编调试objc_msgSend函数 这是一篇很无聊的文章,对开发移动App的人来说没什么卵用。本文仅仅是对@hursing的[xcode反汇编调试iOS模拟器程序调试objc_msgSend函数] 阅读详情

相关推荐

iOS应用逆向工程实战:从Mach-O文件结构到代码逻辑还原

在软件开发和安全分析领域,理解程序的底层运行机制是深入掌握技术的关键。二进制文件分析作为这一过程的基础,揭示了源代码编译后的最终形态及其执行原理。通过解析可执行文件格式,可以洞察程序的内存布局、依赖关系和指令逻辑,这对于性能优化、漏洞挖掘和竞品研究具有重要价值。在移动生态中,iOS应用的Mach-O格式是此类分析的典型对象。本文聚焦于Mach-O文件结构,详细拆解其文件头、加载命令与数据区,并介绍如何利用静态分析工具(如Hopper Disassembler)与动态调试技术(结合LLDB与Frida)进行实

weixin_30919571的博客 405

IOS Xcode调试常用命令和断点整理

主要介绍了IOS Xcode调试常用命令和断点整理的相关资料,这里对IOS Xcode调试常用命令进行了总结,需要的朋友可以参考下

iOS应用逆向工程:静态分析与动态调试的完整实战指南

在软件安全与逆向工程领域,静态分析与动态调试是两大核心技术支柱。静态分析通过对二进制文件、代码结构和资源进行离线审查,如同研究建筑蓝图,旨在理解程序的整体架构与逻辑。动态调试则让程序在受控环境中运行,实时监控其内存状态、函数调用与数据流,以揭示运行时行为与隐藏逻辑。这两种方法各有局限,静态分析难以处理混淆代码与运行时特性,动态调试则不易把握程序全貌。因此,将二者结合,形成“动静结合”的分析范式,对于深入理解应用机制、进行安全评估、性能优化或漏洞挖掘具有极高的技术价值。尤其在iOS应用开发与安全研究场景中,面

Hi, Sun 167

Xcode】undefined symbols错误总结

今天在使用ZBar的时候,报了很多undefined symbols错误。特意总结一下这类错误。 1、framework缺失 这类错误一般是因为库文件没导入引起的。在导入CoreMedia.framework之后,错误消失。怎样快速找到缺失的库,这里面是有规律的。 前两个字母CM正是CoreMedia的缩写。还有类似的比如: _CV是缺失CoreVideo _CA是缺失CoreAnn

SoulHao的专栏 9597

[Xcode]编译时objc_msgSend错误的解决办法

之前开发的代码中需要强制使用一些苹果的私有API,用了objc_msgSend方法进行调用,最近使用最新版本的Xcode进行编译时一致无法通过,后来通过度娘解决了这个问题,在此记录一下,修改方法也很简单,将ENABLE_STRICT_OBJC_MSGSEND的属性值设置为NO就OK,至少目前还没发现程序有什么问题。参考地址http://www.ruanman.net/swift/learn/104

李大仁博客 1589

iOS msgSend消息发送流程

objc_msgSendiOS中调用方法其实就是在给对象发送某条消息。消息的发送在编译的时候编译器就会把方法转 换为objc_msgSend这个函数objc_msgSend有俩个隐式的参数,消息的接收者和消息的方法 名。objc_msgSend这个函数就能够通过这俩个隐式的参数去找到方法具体的实现。如果消息的接 收者是实例对象,isa就指向类对象,后再通过第二个参数方法名,去类对象里面找对应的方法实 现。如果消息的接收者是类对象,isa就指向元类,就会去元类里面找对应的方法实现。 通过 clang

wywinstonwy的专栏 2802

xcode反汇编调试iOS模拟器程序

http://blog.csdn.net/hursing/article/details/8697654 (前两节也许你会看得没劲,可直接先看第四节 (四)自动断点应用之NSNotificationCenter http://blog.csdn.net/hursing/article/details/8752235) iOS模拟器程序的实质就是Mac OS X程序,只不过它需要以模

forlong401的专栏--有问题上:http://www.androidren.com 6324

分享&交流&调查 xcode反汇编调试iOS模拟器程序

http://bbs.csdn.net/topics/390425281 xcode反汇编调试iOS模拟器程序 (一)查看反汇编http://blog.csdn.net/hursing/article/details/8697654 (二)看懂反汇编http://blog.csdn.net/hursing/article/details/8700964 (三)查看Objective-C函数

forlong401的专栏--有问题上:http://www.androidren.com 800

iOS逆向工程实战:class-dump与IDA Pro避坑指南与高阶技巧

在软件安全与移动应用分析领域,逆向工程是理解程序内部逻辑、进行安全评估与漏洞挖掘的核心技术。其基本原理是通过静态与动态分析,解析二进制可执行文件的结构与指令,还原其设计意图与数据流。这项技术的核心价值在于赋能安全研究、竞品分析、漏洞修复与恶意软件检测。在iOS生态中,逆向工程常聚焦于应用安全评估、隐私合规审查与越狱社区研究。class-dump和IDA Pro是iOS逆向工程中不可或缺的静态分析工具链,前者用于快速提取Objective-C运行时信息,后者提供深度的交互式反汇编与反编译环境。然而,在实际工程

weixin_34323858的博客 379

iOS应用请求加密算法逆向分析:从Frida Hook到签名还原实战

在移动应用安全领域,API请求的加密与签名校验是保障数据传输安全的核心机制,其原理通常基于密码学哈希函数(如HMAC-SHA256)与对称加密算法(如AES)。理解这套机制的技术价值在于,它不仅是评估应用自身安全性的关键,也为开发者设计健壮的通信协议、安全研究员挖掘潜在漏洞提供了基础。典型的应用场景包括社交、金融等涉及敏感数据交互的App,它们通过在客户端对请求参数进行排序、拼接并混合时间戳、随机数等元素,再使用密钥生成签名,以防止数据篡改与重放攻击。本文以某iOS社交应用为例,详细演示了如何利用Frida

weixin_30423977的博客 390

iOS逆向工程学习路径:从环境搭建到算法还原的完整指南

逆向工程是理解软件内部工作原理、进行安全分析和漏洞挖掘的关键技术。其核心原理在于通过静态与动态分析,解析二进制程序的逻辑与行为。这项技术在移动安全、协议分析、软件调试等领域具有重要价值。对于iOS平台,掌握逆向工程意味着能够深入分析应用逻辑、研究系统机制。具体应用场景包括分析网络通信协议、研究UI实现原理、检测安全漏洞等。本文基于**Frida动态注入**和**ARM64汇编**等关键技术,系统梳理了从环境搭建、工具使用到实战分析的学习路径,旨在帮助开发者建立完整的iOS逆向知识体系。

weixin_30608503的博客 457

iOS应用深度加固实战:从源码混淆到运行时保护的完整方案

在移动应用开发领域,代码保护与安全加固是保障核心知识产权和业务逻辑的关键环节。其基本原理是通过混淆、加密等技术手段,增加代码的逆向工程难度,从而提升应用的整体安全性。这项技术的核心价值在于,它能有效防止核心算法、支付流程等敏感逻辑被轻易分析或篡改,尤其适用于金融、游戏等高价值业务场景。在iOS生态中,针对Mach-O二进制文件的保护,常涉及ast混淆、控制流扁平化、字符串加密等具体技术。例如,通过集成PPiOS-Rename等工具进行源码层符号混淆,或结合梆梆加固等商业方案进行二进制加固,能构建从静态分析到

weixin_30784501的博客 341

iOS马甲包过审实战:二进制加固技术深度解析与应用

iOS应用开发与安全领域,代码混淆和二进制加固是提升应用安全性与应对平台审核的关键技术。代码混淆通过改变类名、方法名等符号信息,增加逆向分析的难度,属于基础防护手段。而二进制加固则深入到编译后的机器码层面,通过控制流扁平化、指令替换、虚拟化等技术,从根本上改变程序的逻辑结构和指令序列,能有效对抗自动化相似度分析工具,技术价值更高。这些技术广泛应用于保护核心算法、防止逆向工程,以及在特定场景下满足合规要求。本文聚焦于iOS马甲包过审这一具体应用场景,深入探讨如何利用LLVM-Obfuscator等工具实施二

weixin_30457551的博客 316

6、iOS底层分析 - 消息发送(objc_msgeSend)分析

调试分析 OC中的方法到底是怎么调用的呢?之前查资料知道oc的方法调用是通过消息发送的形式进行调用,那就来结合源码探究一下 LGPerson *person = [[LGPerson alloc] init]; Class pClass = [LGPerson class]; [person sayNB]; 汇编查看流程(注意使用真机调试) Debug -...

shengdaVolleyball的博客 627

objc_msgSend消息传递学习笔记 – 消息转发

该文是 objc_msgSend消息传递学习笔记 – 对象方法消息传递流程 的基础上继续探究源码,请先阅读上文。   消息转发机制(message forwarding)   Objective-C 在调用对象方法的时候,是通过消息传递机制来查询且执行方法。如果想令该类能够理解并执行方法,必须以程序代码实现出对应方法。但是,在编译期间向类发送了无法解读的消息并不会报错,因为在 runtim...

weixin_34041003的博客 251

Xcode12 踩坑之 objc_msgSend

Xcode12 问题 objc_msgSend运行时方法报错,提示No matching function for call to 'objc_msgSend',google 了下,有人反馈是Xcode12的bug。Enable Strict Checking of objc_msgSend Calls 配置设为NO 无效。 xcversion 安装多版本Xcode xcversion gem install xcode-install xcversion list xcversion install 11

woashizhangsi的专栏 2027

objc_msgSend底层探索(下)

上一篇里面,我从OC层面来探索了objc_msgSend如何进行消息的发送,对普通开发者来说也是比较容易理解的,那很多人都知道,Runtime是由C或者C++以及汇编语言写的一套底层的API。

pablum1113的博客 881
上一篇: xcode反汇编调试iOS模拟器程序(四)自动断点应用之NSNotificationCenter
下一篇: xcode反汇编调试iOS模拟器程序(六)函数出入口处的处理与局部变量
NJP
NJP
博客等级 码龄14年 48粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值