2013-06-04 60 views
-2

我最近一直在研究一些Android應用程序,並且稍微感到沮喪,因爲我的應用程序可能被反向設計。我確實隱瞞了我的代碼,但這隻能走得太遠,才華橫溢的開發人員可以輕鬆避開晦澀難懂的事情。爲什麼Java應用程序/ applet可以反編譯?

無論如何,我的問題是,爲什麼Java應用程序可以反編譯? Java設計的哪一部分允許其應用程序被反編譯?

我的理解是,Java應用程序的部署JIT編譯,所以它們被用於高效的目的之前,他們只是編譯,這是正確的?我很想知道原因,

謝謝!

+6

這不是理由。任何編譯語言都可以反編譯。如果A + B = C,C-B = A。 – Simon

+2

如果Java類*無法反編譯,那麼VM *如何運行它? (即使編譯爲ML的代碼也必須由CPU理解*)。請注意,模糊處理與編譯不同:模糊處理旨在爲人類(即標識符/代碼重新編譯)設置反編譯的編譯輸出*不那麼友好。機器不關心 - 也不會有人真的想看到*如何完成某件事情。 – user2246674

+0

那麼爲什麼不能爲iOS應用程序做同樣的事情呢? – rusty009

回答

3

無論如何,我的問題是,爲什麼Java應用程序可以反編譯?

任何應用程序,在任何語言,可以被反編譯。對於編程編程語言中具有一定編程經驗的人來說,這應該是顯而易見的。

甲編譯器採用的字節,並創建一組不同的字節表示同一指令集。反編譯器需要字節並創建一組不同的字節來表示相同的指令集。區別僅在於那些字節是什麼。編譯器需要(相對)人類可讀的字節,並創建(相對)機器可讀的字節。反編譯器做相反的事情。

如何以及一個給定的反編譯器可以做自己的工作,不過,依賴於編程語言和反編譯器本身的實現。

在像C語言的情況下,編譯器生成用於CPU的機器指令。這些可以很容易地反編譯成彙編語言,因爲彙編指令與機器指令以1:1非常接近的方式進行映射。一個足夠複雜的反編譯器可以發出C作爲輸出,但可能不是C,這是很自然的寫法。更重要的是,除非編譯的C代碼具有調試符號,否則反編譯的輸出將主要使用反編譯器生成的函數和變量名稱,在這種情況下,反編譯器可能會使用這些名稱。

Java這樣的語言在概念上沒有明顯的不同。雖然Java或Dalvik字節碼是針對虛擬機而不是CPU,但基本方法是相同的。混淆有助於確保生成的字節碼中存在最小數量的人類可讀符號,從而減少反編譯結果的易讀性。此外,VM字節碼到語言語句的映射往往比機器代碼到C語句的映射要近得多,這使得編寫一個反編譯器更容易,使您更接近Java語法(例如,smali/baksmali)。例如,解釋反編譯的機器代碼的困難程度導致建議將許可證管理邏輯通過NDK移動到本機代碼中。但是,這並不是說C編譯器的結果根本無法反編譯。

+1

這是一件很有意思的事情,那就是爲了使本機運行的代碼無法反編譯和理解,幾乎沒有什麼可以完成的。如果你真的不希望某人能夠理解應用程序背後的邏輯,唯一要做的就是不要分發該代碼(在服務器上運行它並使用RESTful API或其他)。即使硬件也不能抵抗反編譯(反向工程),因爲總會有人有足夠的智能去完成產品,並弄清楚它是如何構建的。實際上,這是低效的。 – LucienK

+0

@Dazedy:「如果你真的不想讓別人能夠理解應用程序背後的邏輯,唯一要做的就是不要分發這些代碼」 - 同意了。數據也是如此:如果您不希望用戶訪問「您的」數據,請不要將其放在設備上。 – CommonsWare

+0

安全/數據泄露的主要原因之一是信息被置於不安全的環境中。 IE:無論您將多少個密碼放在筆記本電腦上,如果晚上離開門廊,都有可能會有人接受。由於事物相互關聯的方式,信息更加難以小心。 – LucienK

相關問題