调试器WoA(内核调试器微软指令程序)「能调试内核的调试器」

对于任何新生事物的出现,最好的迎接方式就是学习它
而学习又分为3个层次:远观、近玩和内窥
远观,即远远地看几眼,这是一种最粗浅的学习,只能了解它的轮廓
近玩,即靠近它,用一用、试一试,这是一种中等程度的学习,可以明白它的各种特性
内窥,即把它拆开,弄清它的内部结构、工作原理,这是最深层次的学习,可以学习到它的精髓,甚至最后你自己可以造一个同样的东西
WoA 虽然早在2012年就已经问世(如果把 Surface RT 看作是第一代 WoA 的话),但直到最近两年才逐步得到大家的关注,这里边主要的原因还是由于软件兼容的问题,即传统 x86 PC 上的软件无法在 Windows RT 环境下运行
而随着苹果成功把 MacBook 从 x86 转移到Arm 后,高通、英伟达等很多巨头也积极研发 Arm PC
微软也宣称,Windows 11可以运行 Arm 上,并且支持所有现存的 x86 应用程序(应用程序无需做任何修改)
无论如何,WoA 已经成为一个大家绕不开的话题,甚至有很多人认为,2024年将是 Arm PC 开始高速发展的一年
那么 WoA 是怎样做到支持现存的 x86 应用程序的呢?WoA 有哪些不为人知的秘密?面对 WoA,我们还有哪些工作要做呢?要回答这些问题,最好的方法就是我开始说的“内窥”——借助调试器,我们可以进入到 WoA 内部一探究竟
格蠹科技创始人兼 CEO 张银奎老师几天前(2024年1月13号)举办了一场关于“在调试器下看WoA”的线上直播,给大家详细介绍了 WoA 的来龙去脉,并且分享了几个在调试器下看 WoA 的例子
xtajit前面我们提到,WoA 是怎样做到支持所有现存的 x86 应用程序的?打开一个x86 应用程序(直播时,张老师运行了Windows的经典程序——扫雷游戏 WinMine.exe),通过调试,我们发现系统加载了一个名叫 xtajit 的 dll
微软并没有多少介绍 xtajit 的官方文档,但由其名称可以推出,它是一个即时翻译器(x86 to arm just in time),即在运行时把原先 x86 的指令翻译成 Arm 指令,这样原先的 x86 程序就能原封不动地在 Arm 上运行
这种即时翻译的机制其实非常常见,当年在安腾64机器上运行 x86 程序时,采用的就是这种机制
那么这种即时翻译的效率会怎样呢?答案是丝毫没有影响
首先系统并不会在一开始就把所有的指令进行翻译,只在需要用到时才翻译
其次,系统会把那些翻译过的很多程序公用的指令缓存起来,再次用到时直接拿来就可以了,不需要再翻译一遍
下图是一个运行时的架构图,WinMine 和 WinCMD 表示两个传统的32位 x86 程序,带木纹背景的方块表示它们公用的指令
了解 WoA 内核要深入了解 WoA 内核,同样需要用到调试器
这时,WoA 做为被调试的目标机器,需要另一台机器(可以是 Arm 或者 x86)运行 WinDBG 程序,两台机器之间通过串口相连
通过调试内核,我们可以更深层次地了解到二进制翻译的信息
通过观察,我们看到系统在运行 x86 程序时,的确把一些 x86 dll 翻译成 Arm 指令的文件并且缓存到一个叫 \Windows\XtaCache 的目录下
不过,当张老师试图打开那个目录时,系统提示没有权限,这说明微软并不想暴露过多的二进制翻译的实现细节
如果不通过内核调试,我们根本无法获取这些信息
Hal.dllHal.dll 是 Windows 的一个硬件提取层模块,用于解决硬件的复杂性带来的兼容性问题
这个文件原先有100K左右,但是从 Windows 10开始,它变得很小,只有18K 不到,只剩下一个空壳了,那么它原先实现的功能到哪儿去了呢?通过调试,我们发现,现在微软已经把 Hal 层和内核编译在一起了
这其实跟 Linux 非常相似,Linux 就是把内核层和抽象层编译在一起的,不跨文件,因为跨文件会引起很多麻烦
如今微软的这个改动,到底是抄袭了 Linux,还是他们自己悟出了其中的道理,我们就不得而知了
开发 Arm 驱动和固件虽然传统 x86 的应用可以无缝地运行在 WoA 上,但是驱动程序却不能,因为驱动运行在内核层
为了使 WoA 真正落地应用,我们还有很多的适配工作要做
另外,Arm 本身的固件代码(UEFI 代码)也存在一些问题,比如对 ACPI 的支持不完善,无法自由安装通用操作系统
所有这些都需要我们去开发或完善,而驱动和固件的开发更是离不开调试器
关于 UEFI 编程,这里补充一句,张老师打算在2024年春天推出一期专门关于 UEFI 编程的培训,详细信息,请参考我的另一篇文章
调试器WoA(内核调试器微软指令程序)
(图片来源网络,侵删)

联系我们

在线咨询:点击这里给我发消息