加入收藏 | 设为首页 | 会员中心 | 我要投稿 唐山站长网 (https://www.0315zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

在Linux上的命令使用情况

发布时间:2021-02-16 13:42:40 所属栏目:外闻 来源:互联网
导读:演示到这里的时候,我们成功的从汇编的视角,看到了一些我们想要的东西。 首先看看当前的 ip 是 0x100000f9f, 我们汇编中使用的jlable此时已经被计算,变成了新的目标地址(0x100000fa7)。我们知道,新的 ip 是通过当前 ip 加偏移算出来的, jmp的指令长度是5

演示到这里的时候,我们成功的从汇编的视角,看到了一些我们想要的东西。

首先看看当前的 ip 是 0x100000f9f, 我们汇编中使用的jlable此时已经被计算,变成了新的目标地址(0x100000fa7)。我们知道,新的 ip 是通过当前 ip 加偏移算出来的, jmp的指令长度是5,前面我们已经解释过了。所以我们可以知道下面的关系:

 

消息转发机制这部分动态方法解析,备援接收者,消息重定向应该是很多面试官都喜欢问的环节 : ) ,我想大家肯定是比较熟悉这部分内容,这里就不再赘述了。

trampline函数的实现

接下来的内容,我们简单介绍下,从汇编的视角出发,如何实现一个trampline函数,完成c函数级别的函数转发。以x86指令集为例,其他类型原理也相似。

从汇编的角度来看,函数的跳转,最直接的方式就是插入jmp指令。x86指令集中,每条指令都有自己的指令长度,比如说jmp指令, 长度为5,其中包含一个字节的指令码,4个字节的相对偏移量。假定我们手头有两个函数A和B, 如果想让B的调用转发到A上去, 毫无疑问,jmp指令是可以帮上忙的。接着我们要解决的问题是如何计算出这两个函数的相对偏移量。这个问题我们可以这样考虑, 但cpu碰到jmp的时候,它的执行动作为ip = ip + 5 + 相对偏移量。

为了更加直接的解释这个问题,我们看看下面的额汇编函数(不熟悉汇编的同学不用担心, 这个函数没有干任何事情,只是做一个跳转)。

你也可以跟我一起来做,先写一个jump_test.s,定义了一个什么事情都没做的函数。

先看看汇编代码文件:(jump_test.s)翻译成C函数的话,就是void jump_test(){ return ; }。

 

这个函数内部是用汇编写的,针对不同的硬件系统提供了相应的实现代码。不同的版本实现应该是存在差异, 包括函数名称和实现(我查阅的版本是 objc4-208)。

objc_msgSend首先第一件事就是检测消息发送对象self是否为空,如果为空,直接返回,啥事不做。这也就是为什么对象为nil时,发送消息不会崩溃的原因。做完这些检测之后,会通过self->isa->cache去缓存里查找selector对应的Method, (cache里面存放的是Method ),查找到的话直接调用Method->method_imp。没有找到的话进入下一个处理流程,调用一个名为class_lookupMethodAndLoadCache的函数。

这个函数的定义如下所示:

 

MP 是一个函数指针,它是最终方法调用是的执行指令入口。

objc_method可以说是非常关键了,它也是OC语言可以在运行期进行method swizzling 的设计基石, 通过objc_method 把函数地址,函数签名以及函数名称打包做个关联, 在 真正执行类方法的时候,通过selector名称,查找对应的IMP。同样,我们也可以通过在运行期替换某个selector 名称与之对应的IMP来完成一些特殊的需求。

消息发送机制

这三个概念明确了之后,我们继续聊下消息发送机制。我们知道当向某个对象发送消息的时候,有一个关键函数叫objc_msgSend, 这个函数里到底干了些什么事情, 我们简单聊一聊。


(编辑:唐山站长网)

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

    热点阅读