从猫蛇之战看内核戏CPU

格友 | 格蠹老雷

小时候曾亲眼见证过猫和蛇的激烈对抗,面对昂首吐信的毒蛇,小猫毫不慌张,挥舞前爪,冷静沉着,伺机进攻,表现得胆大而细心。

在网络上搜索一番,可以发现许多猫蛇对战的精彩图片,看来猫蛇之战是许多人热衷观看的“精彩节目”。

从猫蛇之战看内核戏CPU (图片来源于搜索引擎

再展示一张更清晰的图片。

从猫蛇之战看内核戏CPU (图片来源于搜索引擎)

之所以联想到猫蛇之战,是因为今天在“格友会讲”群里,一位同行提出了一个非常有深度的问题。

(以下内容仅适合技术爱好者,其他读者请绕行)

简单来说,问题是调试器是如何访问到那些本不该访问的内存区域的。

看到这个问题,我立刻意识到这位同行是有真本事的,因为普通程序员是不会提出这种问题的。

要理解这个问题,需要具备一些底层知识。

首先,需要理解保护模式的概念。今天的CPU运行在所谓的保护模式下,软件访问的内存空间是虚拟的。这个虚拟空间的内容是有等级划分的,分为平民区和富人区,分为道路和深坑。因此,访问内存时必须小心翼翼,有些地方可以访问,有些地方一旦访问可能引发严重问题,如程序崩溃甚至系统“死亡”。

大多数应用程序崩溃和系统蓝屏都是因为访问了不该访问的地方。

其次,需要对调试器有较深的了解,知道在调试器中可以大胆地访问任何地方,不必那么小心。

例如,在普通程序中,如果访问空地址,可能导致程序崩溃(处理不当的话,程序会被系统终止)。但在调试器中,执行“dd 0”不会有问题,调试器会显示一连串的问号,表示不可访问,内容不存在。

6: kd> dd 0

00000000`00000000 ???????? ???????? ???????? ????????

00000000`00000010 ???????? ???????? ???????? ????????

00000000`00000020 ???????? ???????? ???????? ????????

00000000`00000030 ???????? ???????? ???????? ????????

00000000`00000040 ???????? ???????? ???????? ????????

00000000`00000050 ???????? ???????? ???????? ????????

00000000`00000060 ???????? ???????? ???????? ????????

00000000`00000070 ???????? ???????? ???????? ????????

塔猫ChatPPT 塔猫ChatPPT

塔猫官网提供AI一键生成 PPT的智能工具,帮助您快速制作出专业的PPT。塔猫ChatPPT让您的PPT制作更加简单高效。

塔猫ChatPPT 42 查看详情 塔猫ChatPPT

那么,为什么普通程序一碰就爆炸,而调试器访问却安然无恙呢?

坦白说,第一次在脑海中出现这个问题时,我也困惑了一阵子。直到后来发现内核中有一个神秘机制。这个机制是跨操作系统的,Windows中有,Linux也有,而且都使用相同的名字,称为Probe。

令人惊讶的是,连函数名都很相似,例如Windows(NT内核)中的两个函数是:

6: kd> x nt!probe*

fffff800`06581d70 nt!ProbeForWrite (void)

fffff800`06518ad0 nt!ProbeForRead ()

而Linux内核中的两个函数是:

root@gedu-VirtualBox:/home/gedu/labs/linux-source-4.8.0# sudo cat /proc/kallsyms | grep “bprobe_ke”

ffffffff811a5f00 W probe_kernel_read

ffffffff811a5fc0 W probe_kernel_write

搜索一下KDB/KGDB的源代码,可以看到许多地方调用了上述两个函数:

从猫蛇之战看内核戏CPU 简而言之,内核中封装了两个特殊的函数,供包括调试器在内的一些特殊客户端使用。

接下来要问的是,probe函数内部是如何实现的呢?相关的源代码如下。

从猫蛇之战看内核戏CPU(更完整的请见https://elixir.bootlin.com/linux/v4.8/source/mm/maccess.c#L23 )

关键在于在__copy操作前后分别有:

pagefault_disable();

pagefault_enable();

也就是说,先禁用pagefault,访问完成后再启用。这有点像是在戏耍蛇之前,先把它的毒牙包起来。

进一步挖掘,在当前的Linux内核实现中,维护了一个计数器:pagefault_disabled。

从猫蛇之战看内核戏CPU(https://www.php.cn/link/0ac18d27cc2284445bc249e8a83462fe)

在处理页面错误的do_page_fault函数中,会检查这个标志,如果发现禁止条件,则忽略这次访问错误。

讲到这里,问题只解答了一半,要继续深入探讨的话,还有一些细节,今天时间有点晚了,改天再继续。

以上就是从猫蛇之战看内核戏CPU的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/238910.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月4日 00:38:15
下一篇 2025年11月4日 00:42:22

相关推荐

发表回复

登录后才能评论
关注微信