您现在的位置是:首页 > 抖音知识 > CPU暗藏的未公开指令

CPU暗藏的未公开指令

抖音知识作者:gezhong日期:2023-11-21点击:434

摘要:探讨CPU中的未公开指令,以及如何寻找和分析这些隐藏的指令。

原视频链接>>

视频内容

      CPU暗藏了这些未公开的指令。今天跟大家分享一篇非常有意思的干货。我们知道我们平时编程写的高级语言是经过编译器编译后变成了CPU可以执行的机器指令,而CPU能够支持的指令都在他的指令集里面了。很久以来我都在思考一个问题,CPU有没有未公开的指令,或者说CPU有没有隐藏的指令。为什么会有这个问题呢?平常我们在讨论网络安全问题的时候,大多数时候都是在软件层面谈应用程序的漏洞,后端服务的漏洞,第三方开源组件的漏洞,乃至操作系统的漏洞,但是却很少有机会去触及硬件。前几年爆发的熔断和幽灵系列漏洞就告诉我们,CPU也不是可以信任的。要是CPU隐藏有某些不为人知的指令,这是一件非常可怕的事情。如果某一天,某些国家或者某些团体组织出于某种需要,利用这些隐藏的指令来发动攻击,后果不堪设想。虽然有想到过这个问题,但我一直没有机会去付出时间去研究,直到前段时间极客时间的一位老师分享了一份pdf给我解答了我的疑惑。这份pdf是2017年顶级黑客大会black hand上的一篇报告。这份pdf深度研究了x86架构中的CPU隐藏的指令。原报告因为是英文看起来有些晦涩,这个视频呢我尝试用大家容易懂的语言来跟大家分享一下。这篇非常有意思的干货。有些人可能会问真的会有隐藏指令的存在吗?CPU的指令集不是都写在指令手册里面的吗?确实是这样,我们以单字节指令为例,单词也的范围是0x00到0xff,总共256种组合。英特尔的指令手册中是这样介绍单字节指令的横向为单字节的高四位,纵向为单次节的第四位,顺着表格定位就可以得到每一个单字节指令的定义。比如我们常见的nop指令的机器码是0x90,就是行为九列为零的那一个。但是不知道你有没有发现在这张表格中有些单元格是空的,比如0xf1,那CPU拿到一个为0xf1的指令以后他会怎么处理呢?在指岷手册中没有告诉你。这篇报告的主要内容就是告诉你如何去寻找这样隐藏的指令。想要找到隐藏的指令得先明确一个问题,一条指令到底有多长,换句话说有几个字节,我们应该在什么样的一个范围内去寻找隐藏指令。如果指定长度是固定的,比如说是像JVM那样的虚拟机,那么你就好办,直接便利就好了。但问题难就难,在x86架构的CPU的指令集是属于复杂指令集CISC,它的指令不是固定长度的,有单子机的指令,有双字节的指令,还有三字节是字节,五字节最少能有十几个字节。比如这条指令一个字节,两个字节甚至三四个字节去编辑都还能接受,就算是四个字节最多也就42亿多种组合,对于计算机来说还能接受,但是越往后容量是增值出现的增长,这种情况下再去便利可能就是不现实了。在这份报告中提出了一种深度优先搜索算法,该算法的一个指导思想在于快速跳过殖民中无关紧要的直接,怎么理解这句话呢,比如压榨的指令push,下面这几条指令虽然自己序列不同,但变化的只是数据部分,实际上他们都是压战指令,就没有必要花费时间去便利了。第一个字节六八就是关键字节,后面的四个字节都是压入栈中的数据,就属于无关紧要的字节。如果能够识别出这一类快速跳过将能够大面积的减少需要便利的一个搜索空间。上面只是一个例子,如何能够系统化的过滤掉帧率指令的报告中提出了一个方案,这个方案就是观察指令中的有意义的字节,他们对指令的长度和异常表现会产生冲击。又该怎么理解这句话,还是上面的例子,当尝试修改第一个自己六八的时候这一段二进制序列可能就完全变成了别的指令,甚至指令长度都会发生变化,比如把第一个字节六八变成九零那就变成了一个字节的lop指令,那么就认为这第一个字节是一个有意义的字节,许可了它会对指令的长度产生重要的影响,反之如果我们修改后面字节的数据会发现这仍然是一条五个字节的压榨指令,长度没有变化也没有其他异常行为表现与之前有所不同,那么就认为这后面几个字节是无关紧要的。直接在这个指导思想下我们来看一个例子,从下面这一段数据开始出发我们从两个世界的指令开始便利把最后那个字节的内容加一尝试去执行它如果我们发现指令长度没有变化那就继续加一再次尝试执行大具体怎么判断指令长度变没变后面会重点讨论现在第二个字节变成了零二一直这样加下去直到发现加到四的时候指令长度发生了变化长度超过了当前指令的长度二但具体是多少人还不知道那么在这个基础上长度增加了一位变成了三那接下来就以指令长度为三的指令来继续上面的一个探索过程从最后一位开始加一做起随着分析的深入梳理一下指令搜索的路径图按照这个思路整个要搜索的这个空间压缩到可以接受便利的冲突好了现在我们来解答前面已有的一个问题上面的这个算法能够工作的一个重要的前提是我们得知道给末尾自己加一后有没有影响指令的长度要判断某个字节是不是关键字节就得知道这个字节的内容变化会不会影响到指定长度所以如果无法判断指定长度有没有变化那上面的这个算法就无从谈起了那么如何知道长度有没有变化呢报告中用了一个非常巧妙的办法假设我们要评估下面这一串数据前面开头到底多少个字节是一条完整的指令因为有可能第一个字节零f就是一条指令也有可能前面两个字节零f6a是一条指令还有可能前面五个字节零f6a606a79这是一个指定那到底是哪一种情况呢我们不知道我们尝试用程序来推导出来我们准备两个连续的内存页面前面一个拥有可执行的权限后面一个呢不能执行记住当CPU发现指定位于不可执行的页面中时它会抛异常现在在内存中放置上面的数据流第一个字节放在第一个页面的末尾位置后面的字体放在第二个不可执行的页面上想这样然后让我们的程序跳转到这条指令的地址尝试去执行它CPU中的译码器开始一码译码器经过一马发现是零零f不适当自己的资历所以还需要继续分析后面的字节继续取第二个字节但注意第二个字节是位于不可执行的页面上CPU检查发现后会发出夜收物异常如果我们发现CPU抛了异常并且异常的地址指向了第二个页面的地址那么我们就可以断定这条指令的长度肯定不止一个字节既然不止一个字节那就往前挪一下放两个字节在可执行页面从第三个字节开始放在不可执行的页面继续来这个过程继续上面的过程放三个字节在可执行的页面当我们发现放了四个职业在可执行页面以后事情发生了变化这条指令可以执行的虽然也抛异常但是呢页错误的例子不再是第二个页面的地址了有了这个信号我们就知道前面四个字节是一条完整的制定现在核心算法和判断指令长度的方法都介绍完了就可以正式来开挖挖出那些隐藏的指令了以一台英特尔酷睿i7的CPU为例来挖一挖这是作者的挖掘成果可以看到发现了很多未知的指令这些都是英特尔指令集手册中没有记录但是CPU确认执行的指令再来看AMD的处理器同样有发现不少的隐藏指令那这些隐藏指令是做什么用的呢有些已经被逆向工程给分析了还有的就是毫无记录只有英特尔AMD自己的人知道谁知道他们是用这些指令来干嘛软件即便是开源都能爆出各种各样的问题不光是像黑客一样的硬件CPU作为积分解机时他有个问题max大屏看完这些我对国产安全自主可控这几个字的理解又加深了一层各位朋友你对这些隐藏指令怎么看欢迎评论区分享你的观点哦

上一篇