自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

可怕!CPU暗藏了這些未公開的指令!

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

大家好,我是軒轅。

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

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

很久以來,我都在思考一個問題:

CPU有沒有未公開的指令?

或者說:

CPU有沒有隱藏的指令?

為什么會有這個問題?

平常我們談論網(wǎng)絡安全問題的時候,大多數(shù)時候都是在軟件層面。談應用程序的漏洞、后端服務的漏洞、第三方開源組件的漏洞乃至操作系統(tǒng)的漏洞。

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

要是CPU隱藏有某些不為人知的指令,這是一件非??膳碌氖虑椤?/p>

如果某一天,某些國家或者某些團體組織出于某種需要,利用這些隱藏的指令來發(fā)動攻擊,后果不堪設想。

雖然想到過這個問題,但我一直沒有付諸實踐去認真的研究。

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

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

這份PDF深度研究了x86架構CPU中隱藏的指令,原報告因為是英文,看起來有些晦澀,這篇文章,我嘗試用大家易懂的語言來給大家分享一下這篇非常有意思的干貨。

有些人會問:真的會有隱藏指令的存在嗎,CPU的指令集不是都寫在指令手冊里了嗎?

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

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

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

指令手冊沒告訴你。

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

指令集的搜索空間

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

如果指令長度是固定的,比如JVM那樣的虛擬機,那問題好辦,直接遍歷就行了。

但問題難就難在,x86架構CPU的指令集屬于復雜指令集CISC,它的指令不是固定長度的。

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

90  nop

CC int 3

C3 ret

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

8B C8  mov ecx,eax

6A 20 push 20h

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

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

機器碼:2e 67 f0 48 818480 23df067e 89abcdef

一個字節(jié)、兩個字節(jié),甚至三個四個遍歷都還能接受,4個字節(jié)最多也就42億多種組合,對于計算機來說,也還能接受。

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

指令搜索算法

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

該算法的指導思想在于:快速跳過指令中無關緊要的字節(jié)。

怎么理解這句話?

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

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

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

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

(PS:本文來自公眾號:編程技術宇宙)

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

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

又該怎么理解這句話?

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

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

在這個指導思想下,我們來看一個例子:

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

我們從兩個字節(jié)的指令開始遍歷:

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

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

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

那么在這個基礎上,長度增加1位,以指令長度為3的指令來繼續(xù)上面的探索過程:從最后一位開始+1做起。

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

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

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

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

如何判定指令長度

現(xiàn)在來解答前面遺留的一個問題。

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

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

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

所以如何知道長度有沒有變化呢?報告中用到了一個非常巧妙的方法。

假設我們要評估下面這一串數(shù)據(jù),前面開頭到底多少個字節(jié)是一條完整指令。

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

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

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

到底是什么情況,我們不知道,讓我們用程序來嘗試推導出來。

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

記?。寒擟PU發(fā)現(xiàn)指令位于不可執(zhí)行的頁面中時,它會拋異常!

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

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

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

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

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

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

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

四個:

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

指令可以執(zhí)行了!雖然也拋了異常(因為天知道這是個什么指令,會拋什么異常),但頁錯誤的地址不再是第二個頁面的地址了!

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

挖掘隱藏指令

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

以一臺Intel Core i7的CPU為目標,來挖一挖:

挖掘成果,收獲頗豐:

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

然后是AMD Athon的CPU:

挖掘成果:

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

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

還有的就是毫無記錄,只有Intel/AMD自己人知道了,誰知道它們用這些指令是來干嘛的?

軟件即便是開源都能爆出各種各樣的問題,何況是黑盒一樣的硬件。

CPU作為計算機中的基石,它要是出了問題,那可是大問題。

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

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

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

最后,歡迎大家加入我的知識星球,新一輪的學習活動就快要開始了。

責任編輯:武曉燕 來源: 編程技術宇宙
相關推薦

2009-07-06 18:01:04

Windows CE未公開函數(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

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

2017-11-09 15:29:21

CPU溫度常識

2021-03-08 10:58:03

漏洞Microsoft E微軟

2021-11-10 15:37:49

Go源碼指令

2019-03-18 15:56:56

IntelAMDCPU

2024-09-12 12:44:36

AI訓練

2020-07-10 13:58:18

Windows 7微軟軟件

2023-02-02 14:16:39

GPT-4微軟

2018-03-29 22:50:50

2010-07-19 15:49:22

求職陷阱

2020-11-09 07:25:20

函數(shù) JavaScript數(shù)據(jù)
點贊
收藏

51CTO技術棧公眾號