芯片IC單片機解密百科

十年專注單片機解密

芯片破解指令識別和避免反匯編中遇到的花指令

工作中需要花費大量時間和精力去分析花指令,成為困擾逆向工程師以及安全響應人員的一件事。花指令就是一串沒有任何實際意義的指令。除了浪費時間之外,我發現有的人也會對他們發現的花指令感到震驚、興奮。這是因為他們在一個本來不能執行代碼的內存中發現了可執行代碼,也就相當於發現了一個漏洞利用程序或高級惡意軟件樣本。

 

在這篇文章中,我將通過介紹花指令產生的原因以及其我將討論如何識別花指令。 BBIN导航將重點關注x86反匯編,在其他的平台上也是類似的情況。


問題的產生


人們在分析匯編代碼的過程中,由於芯片破解反匯編器將花指令反匯編成有效的指令,所以很多人就默認假設所有匯編代碼都是實際的代碼指令,這就是很多人所犯的第一個錯誤。由於X86平台的指令是密集編碼的,所以很多指令都是一個字節編碼的。乍一看,幾乎所有數據的反匯編代碼都可能產生有效的x86代碼。

 

例如,我生成了一個16kb的隨機數據文件,並對其進行了反匯編。 這產生了6,455個有效的32位x86指令,隻有239個字節無法識別的數據。這意味著反匯編程序無法解析成有效指令的數據。可以看到超過98%的隨機數據可以被反匯編成有效的指令。


讓BBIN导航看看這個隨機數據的第一部分反匯編,BBIN导航可以看到許多指令和一個字節無法識別的數據。

 

 

這個片段中的第一列數據是數據偏移量。第二列顯示組成指令的字節,第三列顯示這些字節的反匯編表示。對於除高亮行(偏移量0x16)之外的所有行,反匯編顯示一個有效的指令。


偏移量0x16表示可能看起來像一條指令的內容,但符號“db”隻是匯編表示法來聲明一個字節。反匯編器表示在這個位置是字節0xF6,它不能將其識別為指令的一部分。x86指令集是編碼密集,以至於每個字節值都可能是下一個指令的潛在開始。


在這種情況下,0xF6可能是一個指令的有效開始,取決於它後麵的字節,但這種情況下的其與後麵的字節0x4E並不構成有效的操作數。在隨機數據的16kb中,274個無法識別的字節隻有27個不同的值。在這27個值中,唯一一個與常用英文字符範圍重疊的是字母“b”(0x62)。

 

在這篇文章中,BBIN导航將堅持使用32位反匯編,因為它的流暢度更高,但在16位和64位英特爾匯編中也會出現同樣的問題。 當先前提供的隨機數據被拆分為16位代碼時,它產生了96%的有效指令,而拆分為64位則產生了95%的有效指令。

 

你可能會想如何用大麵積的零來表示著這段內存空間中沒有代碼存在,這該多麽美妙。高級反匯編可能會智能地識別大量的零代碼,並跳過反匯編,但它們還是將大量的零反匯編為有效的x86指令。 這裏有幾個反匯編零字節來說明這一點:


 

英文文本的問題更為嚴重。我生成了一個包含隨機文本(lorem ipsum)的60kb文件,並對其進行了反匯編,生成了23,170條指令,並且沒有無法識別的數據。所以,100%的隨機文本被反匯編成有效的指令。 下麵的片段顯示了標準Lorem ipsum反匯編的前三個單詞(“Lorem ipsum dolor”):


所以,BBIN导航在看反匯編代碼時,不僅要看對應序列能否被反匯編成功,還是要看其是否是有效的指令。


解決方法


盡管編寫更好的啟發式的腳本用來過濾掉花指令是可行的,但是目前BBIN导航最好的武器依舊是是人類的大腦。對於一個經驗豐富的逆向工程師來說,在本文中到目前為止所看到的代碼片段有很多東西,他們是學習判斷你所看到的代碼是否是花指令的關鍵。