我搜索了互聯網,但沒有找到具體的答案,爲什麼反編譯器無法生成原始源代碼。我力求得到滿意的答覆。有人寫道,它類似於停止問題,但力量告訴如何。那麼創建一個完美的反編譯器的理論和技術限制是什麼。爲什麼反編譯器不能生成原始代碼理論上
0
A
回答
4
很簡單,它是一個多對一的問題。例如,在C:
b++;
和
b+=1;
和
b = b + 1;
可能都得到一次編譯器和優化完成編譯到相同的一組操作。它對事物進行重新排序,放棄無效操作,並重寫整段代碼。到它完成時,它不知道你寫了什麼,只是一個很好的想法,你想要在原始CPU(或vCPU)級別發生。
它甚至足夠聰明刪除不需要的變量:
{
a=5;
b=func();
c=a+b;
d=func2(c);
}
## gets rewritten as:
REGISTERA=func()
REGISTERA+=5
return(func2(REGISTERA))
3
對於初學者來說,編譯程序時從不保存變量名。 ...所以最好它可以可能確實會在整個重新構建的程序中使用無意義的變量名稱。編譯通常是單向轉換 - 就像單向散列函數。就像散列一樣,也可以生成其他可以哈希到相同值的其他東西,但反編譯程序與原始程序完全相同的可能性非常小。
2
編譯器扔出去的信息;並非源代碼中的所有信息都在編譯代碼中。例如在編譯Java中,你不能區分參數化和非參數化的泛型類型,因爲這些信息只被編譯器使用;一些註釋僅在編譯時使用,不包含在編譯後的輸出中。這並不意味着你無法通過反編譯獲得某種源代碼;它只是不匹配,也不會像實際的源代碼那樣提供信息。
1
源代碼和編譯代碼之間通常不存在1對1的對應關係。如果基本上無限數量的可能源會導致相同的目標代碼(給定無限變量名稱長度等),反編譯器如何猜測要吐出哪一個?
相關問題
- 1. 爲Android編譯反應原生地理編碼器時出錯
- 2. 爲什麼這段代碼不能用MS編譯器編譯?
- 3. 爲什麼代碼不能編譯
- 4. 編譯器爲自動裝箱生成什麼代碼?
- 5. 爲什麼編譯器生成這個代碼?
- 6. 爲什麼此代碼會生成編譯器錯誤C2227?
- 7. 反彙編原始x64機器代碼
- 8. 爲什麼編譯成中間代碼?
- 9. 將一個文件「反編譯」爲原始二進制代碼
- 10. 原生代碼Typescript編譯器
- 11. 爲什麼Clang ++不能在Windows上編譯代碼<header>?
- 12. 爲什麼Google地圖地理編碼器不能初始化?
- 13. 編譯器代碼生成器驗證
- 14. 反射器和編譯器生成的代碼
- 15. 爲什麼這個反彙編代碼不能在C#中編譯?
- 16. 爲什麼不編譯這個代碼?
- 17. 爲什麼不編譯這個代碼?
- 18. 這段代碼爲什麼不編譯?
- 19. 爲什麼不編譯這個代碼?
- 20. 爲什麼不編譯這段代碼?
- 21. 陣列代碼 - 爲什麼不編譯?
- 22. 編譯時代碼生成
- 23. Haskell編譯器的代碼生成
- 24. javax.annotation.processing.AbstractProcessor:編譯器生成的代碼
- 25. Swift編譯器 - 代碼生成
- 26. 編譯器代碼生成比較
- 27. 我需要編寫什麼代碼才能生成此代碼?
- 28. clang在Coliru中編譯此代碼段,但不在編譯器資源管理器中編譯。爲什麼?
- 29. 如何反彙編原始MIPS代碼?
- 30. 如何反彙編原始x86代碼?
什麼,評論和所有?那麼可能已經完成的所有優化,只需再次撤消它們呢?爲什麼我不能通過將蛋放入冷凍箱幾分鐘而從煮雞蛋中得到生雞蛋? – asawyer
@asawyer:喜歡這個比喻。 – Gerrat