偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

可怕!CPU暗藏了這些未公開(kāi)的指令!

商務(wù)辦公
平常我們談?wù)摼W(wǎng)絡(luò)安全問(wèn)題的時(shí)候,大多數(shù)時(shí)候都是在軟件層面。談應(yīng)用程序的漏洞、后端服務(wù)的漏洞、第三方開(kāi)源組件的漏洞乃至操作系統(tǒng)的漏洞。

大家好,我是軒轅。

我們知道,我們平時(shí)編程寫的高級(jí)語(yǔ)言,是經(jīng)過(guò)編譯器編譯以后,變成了CPU可以執(zhí)行的機(jī)器指令:

而CPU能支持的指令,都在它的指令集里面了。

很久以來(lái),我都在思考一個(gè)問(wèn)題:

CPU有沒(méi)有未公開(kāi)的指令?

或者說(shuō):

CPU有沒(méi)有隱藏的指令?

為什么會(huì)有這個(gè)問(wèn)題?

平常我們談?wù)摼W(wǎng)絡(luò)安全問(wèn)題的時(shí)候,大多數(shù)時(shí)候都是在軟件層面。談應(yīng)用程序的漏洞、后端服務(wù)的漏洞、第三方開(kāi)源組件的漏洞乃至操作系統(tǒng)的漏洞。

但很少有機(jī)會(huì)去觸及硬件,前幾年爆發(fā)的熔斷和幽靈系列漏洞,就告訴我們,CPU也不是可信任的。

要是CPU隱藏有某些不為人知的指令,這是一件非常可怕的事情。

如果某一天,某些國(guó)家或者某些團(tuán)體組織出于某種需要,利用這些隱藏的指令來(lái)發(fā)動(dòng)攻擊,后果不堪設(shè)想。

雖然想到過(guò)這個(gè)問(wèn)題,但我一直沒(méi)有付諸實(shí)踐去認(rèn)真的研究。

直到前段時(shí)間,極客時(shí)間的一位老師分享了一份PDF給我,解答了我的疑惑。

這份PDF內(nèi)容是2017年頂級(jí)黑客大會(huì)Black Hat上的一篇報(bào)告:《us-17-Domas-Breaking-The-x86-ISA》,作者是大神:@xoreaxeaxeax,熟悉匯編的同學(xué)知道這名字是什么意思嗎?

這份PDF深度研究了x86架構(gòu)CPU中隱藏的指令,原報(bào)告因?yàn)槭怯⑽模雌饋?lái)有些晦澀,這篇文章,我嘗試用大家易懂的語(yǔ)言來(lái)給大家分享一下這篇非常有意思的干貨。

有些人會(huì)問(wèn):真的會(huì)有隱藏指令的存在嗎,CPU的指令集不是都寫在指令手冊(cè)里了嗎?

我們以單字節(jié)指令為例,單字節(jié)的范圍是0x00-0XFF,總共256種組合,Intel的指令手冊(cè)中是這樣介紹單字節(jié)指令的:

橫向?yàn)閱巫止?jié)的高四位,縱向?yàn)閱巫止?jié)的低四位,順著表格定位,可以找到每一個(gè)單字節(jié)指令的定義。比如我們常見(jiàn)的nop指令的機(jī)器碼是0x90,就是行為9,列為0的那一格。

但是不知道你發(fā)現(xiàn)沒(méi)有,這張表格中還有些單元格是空的,比如0xF1,那CPU拿到一個(gè)為0xF1的指令,會(huì)怎么執(zhí)行呢?

指令手冊(cè)沒(méi)告訴你。

這篇報(bào)告的主要內(nèi)容就是告訴你,如何去尋找這些隱藏的指令。

指令集的搜索空間

想要找到隱藏的指令,得先明確一個(gè)問(wèn)題:一條指令到底有多長(zhǎng),換句話說(shuō),有幾個(gè)字節(jié),我們應(yīng)該在什么樣的一個(gè)范圍內(nèi)去尋找隱藏指令。

如果指令長(zhǎng)度是固定的,比如JVM那樣的虛擬機(jī),那問(wèn)題好辦,直接遍歷就行了。

但問(wèn)題難就難在,x86架構(gòu)CPU的指令集屬于復(fù)雜指令集CISC,它的指令不是固定長(zhǎng)度的。

有單字節(jié)指令,比如:

90  nop

CC int 3

C3 ret

也有雙字節(jié)指令,比如:

8B C8  mov ecx,eax

6A 20 push 20h

還有三四節(jié)、四字節(jié)、五字節(jié)···最長(zhǎng)能有十幾個(gè)字節(jié),比如這條指令:

指令:lock add qword cs:[eax + 4 * eax + 07e06df23h], 0efcdab89h

機(jī)器碼:2e 67 f0 48 818480 23df067e 89abcdef

一個(gè)字節(jié)、兩個(gè)字節(jié),甚至三個(gè)四個(gè)遍歷都還能接受,4個(gè)字節(jié)最多也就42億多種組合,對(duì)于計(jì)算機(jī)來(lái)說(shuō),也還能接受。

但越往后,容量是呈指數(shù)型增長(zhǎng),這種情況再去遍歷,顯然是不現(xiàn)實(shí)的。

指令搜索算法

這份報(bào)告中提出了一種深度優(yōu)先的搜索算法:

該算法的指導(dǎo)思想在于:快速跳過(guò)指令中無(wú)關(guān)緊要的字節(jié)。

怎么理解這句話?

比如壓棧的指令push,下面幾條雖然字節(jié)序列不同,但變化的只是數(shù)據(jù),其實(shí)都是壓棧指令,對(duì)于這類指令,就沒(méi)必要花費(fèi)時(shí)間去遍歷:

  • 68 6F 72 6C 64 push 646C726Fh
  • 68 6F 2C 20 77 push 77202C6Fh
  • 68 68 65 6C 6C push 6C6C6568h

第一個(gè)字節(jié)68就是關(guān)鍵字節(jié),后面的四個(gè)字節(jié)都是壓入棧中的數(shù)據(jù),就屬于無(wú)關(guān)緊要的字節(jié)。

如果能識(shí)別出這類,快速跳過(guò),將能夠大面積減少需要遍歷的搜索空間。

(PS:本文來(lái)自公眾號(hào):編程技術(shù)宇宙)

上面只是一個(gè)例子,如何能夠系統(tǒng)化的過(guò)濾掉這類指令呢?報(bào)告中提出了一個(gè)方案:

觀察指令中的有意義的字節(jié),它們對(duì)指令的長(zhǎng)度和異常表現(xiàn)會(huì)產(chǎn)生沖擊。

又該怎么理解這句話?

還是上面那個(gè)例子,當(dāng)嘗試修改第一個(gè)字節(jié)68的時(shí)候,這一段二進(jìn)制序列可能就完全變成了別的指令,甚至指令長(zhǎng)度都會(huì)發(fā)生變化(比如把68改成90,那就變成了一個(gè)字節(jié)的nop指令),那么就認(rèn)為這第一個(gè)字節(jié)是一個(gè)有意義的字節(jié),修改了它會(huì)對(duì)指令的長(zhǎng)度產(chǎn)生重要影響。

反之,如果修改后面字節(jié)的數(shù)據(jù),會(huì)發(fā)現(xiàn)這仍然是一條5個(gè)字節(jié)的壓棧指令,長(zhǎng)度沒(méi)變化,也沒(méi)有其他異常行為表現(xiàn)與之前不同,那么就認(rèn)為后面幾個(gè)字節(jié)是無(wú)關(guān)緊要的字節(jié)。

在這個(gè)指導(dǎo)思想下,我們來(lái)看一個(gè)例子:

從下面這一段數(shù)據(jù)開(kāi)始出發(fā):

我們從兩個(gè)字節(jié)的指令開(kāi)始遍歷:

把最后那個(gè)字節(jié)的內(nèi)容+1,嘗試去執(zhí)行它:

發(fā)現(xiàn)指令長(zhǎng)度沒(méi)有變化(具體怎么判斷指令長(zhǎng)度變沒(méi)變,下一節(jié)會(huì)重點(diǎn)討論),那就繼續(xù)+1,再次嘗試執(zhí)行它:

一直這樣加下去,直到發(fā)現(xiàn)加到4的時(shí)候,指令長(zhǎng)度發(fā)生了變化,長(zhǎng)度超過(guò)了2(但具體是多少還不知道,后文會(huì)解釋):

那么在這個(gè)基礎(chǔ)上,長(zhǎng)度增加1位,以指令長(zhǎng)度為3的指令來(lái)繼續(xù)上面的探索過(guò)程:從最后一位開(kāi)始+1做起。

隨著分析的深入,梳理一下指令搜索的路徑圖:

當(dāng)某一條的最后一個(gè)字節(jié)遍歷至FF時(shí),開(kāi)始往回走(就像遞歸,不能一直往下,總有回去的時(shí)候):

往回走一個(gè)字節(jié),將其+1,繼續(xù)再來(lái):

按照這個(gè)思路,整個(gè)要搜索的指令空間壓縮到可以接受遍歷的程度:

如何判定指令長(zhǎng)度

現(xiàn)在來(lái)解答前面遺留的一個(gè)問(wèn)題。

上面這個(gè)算法能夠工作的一個(gè)重要前提是:

我們得知道,給末尾字節(jié)+1后,有沒(méi)有影響指令的長(zhǎng)度。

要判斷某個(gè)字節(jié)是不是關(guān)鍵字節(jié),就得知道這個(gè)字節(jié)的內(nèi)容變化,會(huì)不會(huì)影響到指令長(zhǎng)度,所以如果無(wú)法判斷長(zhǎng)度有沒(méi)有變化,那上面的算法就無(wú)從談起了。

所以如何知道長(zhǎng)度有沒(méi)有變化呢?報(bào)告中用到了一個(gè)非常巧妙的方法。

假設(shè)我們要評(píng)估下面這一串?dāng)?shù)據(jù),前面開(kāi)頭到底多少個(gè)字節(jié)是一條完整指令。

可能第一個(gè)字節(jié)0F就是一條指令。

也可能前面兩個(gè)字節(jié)0F 6A是一條指令。

還可能前面五個(gè)字節(jié)0F 6A 60 6A 79 6D是一條指令。

到底是什么情況,我們不知道,讓我們用程序來(lái)嘗試推導(dǎo)出來(lái)。

準(zhǔn)備兩個(gè)連續(xù)的內(nèi)存頁(yè)面,前面一個(gè)擁有可執(zhí)行的權(quán)限,后面一個(gè)不能執(zhí)行。

記?。寒?dāng)CPU發(fā)現(xiàn)指令位于不可執(zhí)行的頁(yè)面中時(shí),它會(huì)拋異常!

現(xiàn)在,在內(nèi)存中這樣放置上面的數(shù)據(jù)流:第一個(gè)字節(jié)放在第一個(gè)頁(yè)面的末尾位置,后面在字節(jié)放在第二個(gè)不可執(zhí)行的頁(yè)面上。

然后JMP到這條指令的地址,嘗試去執(zhí)行它,CPU中的譯碼器開(kāi)始譯碼:

譯碼器譯碼發(fā)現(xiàn)是0F,不是單字節(jié)指令,還需要繼續(xù)分析后面的字節(jié),繼續(xù)取第二個(gè)字節(jié):

但注意,第二個(gè)字節(jié)是位于不可執(zhí)行的頁(yè)面,CPU檢查發(fā)現(xiàn)后會(huì)拋出頁(yè)錯(cuò)誤異常:

如果我們發(fā)現(xiàn)CPU拋了異常,并且異常的地址指向了第二個(gè)頁(yè)面的地址,那么我們可以斷定:這條指令的長(zhǎng)度肯定不止一個(gè)字節(jié)。

既然不止一個(gè)字節(jié),那就往前挪一下,放兩個(gè)字節(jié)在可執(zhí)行頁(yè)面,從第三個(gè)字節(jié)開(kāi)始放在不可執(zhí)行頁(yè)面,繼續(xù)這個(gè)過(guò)程。

繼續(xù)上面這個(gè)過(guò)程,放三個(gè)字節(jié)在可執(zhí)行頁(yè)面:

四個(gè):

當(dāng)放了四個(gè)字節(jié)在可執(zhí)行頁(yè)面之后,事情發(fā)生了變化:

指令可以執(zhí)行了!雖然也拋了異常(因?yàn)樘熘肋@是個(gè)什么指令,會(huì)拋什么異常),但頁(yè)錯(cuò)誤的地址不再是第二個(gè)頁(yè)面的地址了!

有了這個(gè)信號(hào),我們就知道,前面4個(gè)字節(jié)是一條完整的指令:

挖掘隱藏指令

現(xiàn)在核心算法和判斷指令長(zhǎng)度的方法都介紹完了,可以正式來(lái)開(kāi)挖,挖出那些隱藏的指令了!

以一臺(tái)Intel Core i7的CPU為目標(biāo),來(lái)挖一挖:

挖掘成果,收獲頗豐:

這些都是Intel指令集手冊(cè)中未交待,但CPU卻能執(zhí)行的指令。

然后是AMD Athon的CPU:

挖掘成果:

那這些隱藏的指令是做什么的呢?

有些已經(jīng)被逆向工程分析了。

還有的就是毫無(wú)記錄,只有Intel/AMD自己人知道了,誰(shuí)知道它們用這些指令是來(lái)干嘛的?

軟件即便是開(kāi)源都能爆出各種各樣的問(wèn)題,何況是黑盒一樣的硬件。

CPU作為計(jì)算機(jī)中的基石,它要是出了問(wèn)題,那可是大問(wèn)題。

我不是陰謀論,害人之心不可有,但防人之心不可無(wú)。

看完這些,我對(duì)國(guó)產(chǎn)、安全、自主可控這幾個(gè)字的理解又加深了一層。

各位朋友,你對(duì)這些隱藏指令怎么看?歡迎評(píng)論區(qū)分享你的觀點(diǎn)。

最后,歡迎大家加入我的知識(shí)星球,新一輪的學(xué)習(xí)活動(dòng)就快要開(kāi)始了。

責(zé)任編輯:武曉燕 來(lái)源: 編程技術(shù)宇宙
相關(guān)推薦

2009-07-06 18:01:04

Windows CE未公開(kāi)函數(shù)

2010-07-26 16:26:56

MS SQL Serv

2010-07-23 15:52:52

MS SQL Serv

2025-01-20 15:22:55

2025-06-03 08:28:00

2015-05-22 11:33:08

2018-07-12 05:33:30

2019-11-20 15:40:48

CPU軟件處理器

2021-10-29 11:45:26

Python代碼Python 3.

2022-08-15 10:47:01

IP屬地互聯(lián)網(wǎng)

2023-06-13 15:55:54

2021-03-08 10:58:03

漏洞Microsoft E微軟

2010-07-19 15:49:22

求職陷阱

2024-09-12 12:44:36

AI訓(xùn)練

2018-03-29 22:50:50

2017-11-09 15:29:21

CPU溫度常識(shí)

2023-02-02 14:16:39

GPT-4微軟

2020-07-10 13:58:18

Windows 7微軟軟件

2021-11-10 15:37:49

Go源碼指令

2019-03-18 15:56:56

IntelAMDCPU
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)