各個編程語言的發明者是否能夠隨便反編譯各自的已編譯的二進位文件?

例如:C,Java,OC等等的語言發明者, 是否能輕鬆的將別人使用這種語言編譯的二進位文件反編譯成代碼。


設計語言和實現該語言的編譯器是兩碼事。

當某個語言主流的編譯器還是該語言設計者實現的的時候,或許這些設計者們還能很輕易的認出生成的代碼的模式。但這通常是源於他們調試、修bug的需要,不得不掌握這樣的技能。

逐漸發展起來之後該語言的編譯器就不一定是語言設計者自己實現的,像C就不是了。這個時候語言設計者也未必能輕易認出生成的代碼對應怎樣的源碼。反而是編譯器實現者和專門做逆向工程/研究的人會更熟手。

另外就是有些優化編譯器生成的代碼是會損失信息的。再怎麼樣也很難高保真恢復到原本源碼的狀態。注釋、變數名之類的常常會損失掉。類型有時候也會損失掉。


反Assembly/Bytecode主要是看Pattern見的多不多。

C++這種大型(坑)語言不行,商業編譯器太多,而且即便是C++他爹,可能都不戰後端久矣。Lua和Python一人能單挑前後端的,還是有反彙編能力的,起碼Debug後端的時候,就已經見過了很多的Pattern。


取決於編譯出來的目標代碼是什麼樣子

比如Java和C#,他們編譯出來的是中間代碼,而這些中間代碼是和原始語言有完美對應關係的。那這種就可以完美的反編譯

但比如C++或者C,他們編譯出來是原生代碼(也就是機器碼)。這種東西因為編譯時候一般都有優化的原因,編譯後的代碼結構和順序都可能被完全打亂。那麼這些基本就不可能反編譯回原始代碼。


1、代碼中的很多信息沒有到二進位碼中去,例如變數名等,因此信息是不足以完全恢復代碼的

2、語言的發明者不會從語言定義到二進位代碼生成從頭到位發明一遍,有些語言僅僅發明語法,和一個到較低層語言的轉換器即可

3、二進位代碼本身就在不同的cpu平台上千差萬別


舉個例子你就明白了:

有一個家政公司,有總經理,行政主管,財務人員,家政人員。

總經理負責接活,並下髮指令:明天需要兩個家政人員去某小區某棟某單元某號做清潔兩個小時,做完後收150塊錢;

行政主管把這個指令具體化:家政人員A,B,去某小區某棟某單元某號做清潔,時間是明天上午九點到十一點,財務人員C,十點半到達那裡,收費150元。

在這個例子裡面,總經理要保證他指令的清晰性和無歧義,因此公司需要制訂指令的規範,這就是你所說的語言發明者要做的事情,比如:家政2財務1小區壹棟貳單元三時間2——這是java語言格式,壹小區貳棟三單元2家政1財務2時間——這就是C語言格式等等,至於如何設計一門好的編程語言,可以去看看《編譯原理》這本書。

而行政主管則是相當於編譯器的角色,他負責將總經理下達的任務,轉換成具體的可執行的語言(二進位代碼),並分配資源,在這個過程中,有可能會有一些優化或者變化的過程,比如這收150塊錢,有可能是要財務人員提前半個小時過去收,也有可能就要家政人員A順便帶回來;

家政人員和財務人員,則相當於機器里的CPU等部件,執行二進位代碼並返回結果。

回到你的問題,理論上來講,如果你對某一門語言和編譯這門語言的某個編譯器非常的熟悉,那麼是可以把這個編譯器生成的二進位代碼反編譯的,但這只是理論上的情況,並不能完全精確,以上面的例子來說,你看到有兩個家政人員做了兩個小時衛生,收了150塊錢走了,你會以為總經理說的是家政人員代收服務費,但總經理說的卻只是「做完後收150元錢」。


什麼語言都能讀文件,然後把文件再寫成另一種形式的文件。


如果你懂物理熵的概念,你就不會問這個問題,一個有序的東西變無序很簡單,一個無序的東西變有序很難


假設源碼為8+2,編譯出來結果為10,誰能根據結果10推算出是8+2來的,而不是7+3,或5+5?


c# java相對容易點,,它們編譯生成的是中間文件....cpp那種就,,,


推薦閱讀:

編譯原理學了有什麼用?
從編譯原理上講,未來可能會出現既友好又高性能的高級語言嗎?
不學習編譯原理對於CS專業的學生有多大的損失?
C++ 中的左值、右值、左值引用、右值引用、引用分別是什麼,有哪些關係?

TAG:編程語言 | 科技 | 編譯原理 | 反編譯 |