加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

深入iOS系统底层之程序中的汇编代码

发布时间:2019-05-29 13:06:49 所属栏目:业界 来源:欧阳大哥2013
导读:合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。--(老子道德经 ) 对于一个闭源系统来说如果想研究某些逻辑的内部实现就需要对汇编语言进行掌握和了解、对于某些需要高性能实现的逻辑来说用汇编语言实现可能是最好的选择、对于某些逻辑来说可能只
副标题[/!--empirenews.page--]

合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。--(老子·道德经 )

对于一个闭源系统来说如果想研究某些逻辑的内部实现就需要对汇编语言进行掌握和了解、对于某些需要高性能实现的逻辑来说用汇编语言实现可能是最好的选择、对于某些逻辑来说可能只能用汇编来实现。以最后一个能力来说:当我们要实现一个HOOK所有OC方法调用的逻辑时,因为HOOK的方法不能破坏原有函数的参数栈,而且还需要在适当的时候调用原始的函数而不关注原始函数的入参时就只能选择用汇编语言来实现。

查看程序的汇编代码

其实更多的时候我们不要求去编写一段汇编代码或者机器指令,而是如果能够读懂简单的汇编代码就能窥探一些系统底层的实现逻辑和原理。当然市面上也有很多的反汇编的工具软件能够将汇编代码转化为高级语言的伪代码,缺点就是这些工具大多是静态分析工具以及反汇编出来的代码不一定完全正确,有时候我们可能更加希望在运行时去调试或者分析一些问题,这样能够阅读汇编代码的话效果会更好一些。

查看汇编代码的三种方法

Xcode提供了三种查看程序汇编代码的方式:

  1. 在程序运行时的断点处可以通过Debug菜单->Debug Workflow->Always Show Disassembly来切换汇编代码模式和高级语言模式。
  2. 通过快捷键 alt + command + 可以对某个系统函数或者第三方库函数或者类的方法设置符号断点,这样当程序出现相应的函数或者方法调用时就会切换到汇编代码模式。你可以通过这种方式来阅读和了解函数或者方法的实现。
  3. 如果你想查看某个高级语言文件生成的伪汇编代码时,你需要在对应的文件处通过Product菜单->Perform Action->Assemble "xxxxx" 来查看这个文件生成的伪汇编代码。当你在模拟器模式下所看到的就是x64系统下的汇编代码,当你在设备模式下时所看到的就是arm系统下的汇编代码。

clang命令的简单介绍

通过上述的第三种方式查看生成的汇编代码的方式其实是通过clang命令完成的。clang是一个C/C++/Objective-C语言的编译器,它包含了预处理、语法分析、优化、代码生成、汇编装配、链接等功能。我们通过菜单来进行的构建程序的操作其实内部实现都是借助clang来完成的。你可以在命令终端中键入man clang来查看这个命令的所有参数和使用介绍,你还可以在Xcode工程中使用command + 9快捷键就可以看到你每次构建工程的详细流程,这里面有对程序使用clang命令的进行编译和链接的具体实践。

深入iOS系统底层之程序中的汇编代码

可以看出无论是源代码编译还是程序链接都是用clang命令来实现的,不要被命令中大量的编译链接选项所吓倒,其实这些参数都是我们在可视化的工程的Build Settings里面设置的

要想了解完整的编译选项的设置和意义可以参考:pewpewthespells.com/blog/builds…

我们只介绍clang命令的几个主要的参数选项:

  1. clang [-arch ] [-x ] [-L<库路径>] [-I<头文件路径>] [-F<框架头文件路径>] [-isysroot 系统SDK路径] [-fobjc-arc | -fno-objc-arc] [-lxxx] [-framework XXX] [-Xlinker option] [-Xlinker value] [-E 源代码文件] [-rewrite-objc 源代码文件] [-c 源代码文件] [-S 源代码文件] [-filelist LinkFileList文件] [-o 输出文件] 

1.常规参数

  •  -arch : 生成的代码的体系结构,四选一。
  •  -x
  •  -I<头文件路径>: 指定#import或者#include .h文件的搜索路径。
  •  -L<库路径>: 指定链接时的动态库或者静态库文件的搜索路径。这个选项用在链接阶段。
  •  -F<框架头文件路径>: 指定#import一个框架库时的头文件搜索路径。
  •  -isysroot 系统SDK路径: 指定程序使用的系统框架SDK的路径。比如: -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.1.sdk 表明使用真机版的iOS12.1版本的SDK来编译或者链接当前程序。
  •  -fobjc-arc | -fno-objc-arc: 表明当前程序是使用arc编译还是mrc来编译。
  •  -lxxx: 只在链接时使用,表明将名字为libxxx的库链接到程序中来。
  •  -framework XXX: 只在链接时使用,表明将名字为XXX的framework库链接到程序中来。
  •  -Xlinker option -Xlinker value: 设置链接的选项,这里必须要成对出现,其意义表示: option = value。

2.预处理

-E 源代码文件 -o 输出文件: 对源代码进行预处理。也就是将所有#include和#import的头文件展开、将所有宏定义展开、将所有枚举值转化为常量值的处理。你可以借助**Product菜单->Perform Action->Preprocess "xxxxx"**来查看一个源代码文件的预处理结果。

3.生成C++代码

-rewrite-objc 源代码文件: 将OC代码转化为对应的C++语言实现。并在源代码文件的当前目录下生成一个对应的后缀为.cpp的C++代码。你可以通过这种方法来详细了解arc的实现原理、block的实现以及调用原理、各种OC关键字的实现逻辑原理、OC类属性和方法的实现逻辑、类方法的定义以及runtime的机制等等逻辑。因此用这个参数可以帮助我们窥探很多iOS系统的秘密。在使用这个命令时可能会遇到一个常见的错误:

  1. In file included from xxxx.m:9: 
  2. xxxx.h:9:29: fatal error: module 'UIKit' not found 
  3. #pragma clang module import UIKit /* clang -E: implicit import for #import <uikit uikit.h=""> */ 
  4.                      ~~~~~~~^~~~~ 
  5. 1 warning and 1 error generated.</uikit> 

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读