我知道從二進製到源代碼(例如C ++)的逆向工程通常被認為是困難的或不可能的,但是有沒有計算機科學家實際上“數學上”證明了不可能(或有可能)將(任何)二進制逆向工程為源代碼?反向工程是一個非常棘手的難題,還是那裡的二進製文件根本無法通過手工還是通過反編譯器進行反向?
注意:我知道答案可能是“這取決於平台和編程語言” “因此,我將假定使用的語言是C ++,因為通常認為它是無法反轉的。
我知道從二進製到源代碼(例如C ++)的逆向工程通常被認為是困難的或不可能的,但是有沒有計算機科學家實際上“數學上”證明了不可能(或有可能)將(任何)二進制逆向工程為源代碼?反向工程是一個非常棘手的難題,還是那裡的二進製文件根本無法通過手工還是通過反編譯器進行反向?
注意:我知道答案可能是“這取決於平台和編程語言” “因此,我將假定使用的語言是C ++,因為通常認為它是無法反轉的。
實際上,答案有些微妙。
根據 Barak等人,不可能混淆程序。這意味著您將始終洩漏足夠的信息以使攻擊者重建程序的藍圖。
另一方面,也無法構建一個程序來自動對任何給定的程序進行反向工程輸入(它來自大米定理,因為它過去是在程序中可以找到的非平凡屬性上建立的混淆)。
因此,最後,不可能進行完美的混淆,但完全沒有自動化。這意味著人類(和直覺)是並將繼續是本科學的關鍵。
似乎不同的答案對應於對該問題的不同解釋。 C ++編譯器從源代碼創建二進製文件。 C ++反編譯器將從二進製文件創建源代碼。
通常不可能重新創建 源(例如,註釋,宏定義和局部變量名通常不存在形式,所以我們剩下的就是嘗試創建功能上等效的 一些 源。
一種簡單的方法這樣做將是逐條指令分解可執行二進製文件,為每條機器指令創建C ++等效代碼。從字面上看,這樣做是可以的,但是結果對於人類來說是完全不可用的。
隨著源語言變得越來越複雜,自動將其轉換為有用,易讀,慣用的形式變得更加困難。參見Chen等人的最新論文,標題為“一種精巧的反編譯器,以生成具有高可讀性的C代碼”。描述了反編譯的目標和挑戰。
正如其他人所說,您始終可以編寫模擬機器代碼的C代碼。但是,這並不總是有用的。通常,您不僅要學習如何運行程序的知識,還想了解如何以有用的方式對其進行修改。
研究人員仍在努力弄清混淆的哪些定義是有用的。 這張著名的論文說,你不能一直隱藏所有的秘密。他們將“秘密”定義為通過反復運行程序並分析輸出無法獲得的任何東西。 最近的論文演示了一種方法,該方法使人們無法辨別原始的等效源代碼。他們的技術是“最好的”混淆,因為它隱藏了任何可以隱藏的秘密。
第一個成功的混淆之一是針對點函數的,輸出“是當您輸入密碼時。您可以通過編碼密碼的MD5哈希來混淆該程序(就像Unix登錄功能一樣)。您可以運行該程序,但不能破解密碼。
某些時候,軟件靜態分析的某些方面在形式上是很難的。例如,請參閱本文及其參考文獻。
我不知道有任何專門研究使程序難以以某種可預測的方式修改行為的研究。那會很有趣。
如果任何二進製文件表示任意二進制數據文件,則答案是肯定的,這是不可能的。為了證明這一點,只需考慮一個文件只有一個字節的情況。
如果將其限制為C / C ++,那麼當然可以將其反轉。但是,由於機器代碼和源代碼之間沒有1:1的關係,因此不可能將其恢復為原始源代碼。根據優化情況,即使在語義上是相同的,該源看起來也可能與原始源完全不同。
是的,任何運行的應用程序都必須具有一些邏輯或代碼才能執行。如果機器(旋轉完成)可以跟隨它;人類也可以(理論上如此,它有可能扭轉一切)。現實顯然取決於情況,例如,可能存在安全限制,以防止攻擊者獲得對系統內存或文件系統(例如某些嵌入式設備)上的可執行文件的訪問。
這取決於逆向工程的定義和目的。
如果聰明的人腦沒有時間限制,那麼實際上聰明的人腦就能理解愚蠢的計算機能夠執行的一切。
我所知道的唯一能夠以某種方式回答您的問題(衡量程序的可理解性以及程序轉換的保密性和安全性保證)的研究方向就是混淆研究。這個領域有一些有趣的作品。例如,這裡,您可以找到該研究領域的一些有趣的摘要。
我試圖給出關於倒車的想法,而不是答案,因為我自己希望自己能找到它,而且我很確定這裡的任何專家都可以說我認為是cr腳的,但是我謹此慷慨解囊。
程序的“逆向工程”而不是將二進制代碼逆向轉換為源代碼,而是驗證程序是否具有某些屬性 。 em>(我們可以想像在源代碼中可以輕鬆觀察到某些屬性,但在二進制代碼中不容易觀察到),那麼“混淆”是為了防止程序進行這種算法驗證。
在理想的(即理論上)世界中,一些非常籠統的結果斷言了幾件事。首先,是萊斯定理(如先前@perror所述)和 Landi更具建設性的結果。 W斷言不存在通用驗證程序,這意味著我們無法編寫驗證程序V,因此當我們為V提供任意程序P和非平凡屬性p時(平凡屬性是所有程序中都存在的一個平凡屬性) ,例如所有PE文件中都存在魔術字節MZ是不重要的屬性),V可以回答P是否具有p。因此,這意味著存在完美的混淆,答案是“不”,這是因為我們永遠不需要如此強大的驗證程序(為所有程序提供確定性答案),對於某些有用的程序類,我們僅需要驗證程序即可。
第二, Barak等(前面也曾提到過@perror)斷言某種矛盾的結果:有些類別的程序無法混淆,即無論它們是什麼被混淆,這很容易編寫驗證器來回答這些程序具有給定的屬性p(或不具有)。實際上,這裡沒有矛盾,因為賴斯定理適用於“所有程序”的上下文,而巴拉克等人的結果適用於“若干程序”的上下文,實際上我們有:
第三, Wee的結果。 H說,如果給定名為 point functions 的特殊程序,我們總是可以隱藏(即混淆)某些屬性。同樣,這並不意味著一般情況下可能會產生混淆,因為此結果適用於“多個程序”的上下文。
第四, Garg的結果。 S et al說,我們可以對任何程序進行混淆,以使從混淆後的程序計算出的任何屬性都是“瑣碎的”。因此,這意味著存在完美的混淆器,如果存在,則與 Barak等人?的結果相矛盾,顯然不是,因為兩個結果實際上使用了瑣碎性的兩個不同定義,第一個屬性如果在所有具有相同語義的程序中都存在,則它是微不足道的(因此,此定義比第二個屬性中的定義要弱)。
在現實世界中,我經驗很少我不能給出任何有用的想法。但是我懷疑遊戲混淆器與反混淆器會以某些非常聰明的方式發展,並且我們仍然有很多空白需要解決(作為混淆器或反混淆器)。
可以對任何二進製文件進行反向工程,而與使用哪種語言/編譯器無關,但這取決於進行該工作的反向工程人員(或)開發完成該工作的工具的開發人員的知識。
您可以對任何東西進行反向工程。只要您掌握了資源(時間,金錢和技能)。當您購買汽車,程序,計算機,超級秘密芯片時。您可以獲得操作它所需的一切。
鑑於此,您可以弄清楚它是如何工作的,然後對它進行反向工程。