為什么我要寫這篇文章呢?第一,是對這一周實習中使用到的技巧進行總結與回顧;第二,是想把這一周對于反編譯這一小眾的技能分享出去。(其實只是周末比較無聊而已哈哈)
好的,首先簡單的介紹一下,本人目前正在讀研,假期閑得蛋疼所以在北京找了一家規模還不錯的公司實習,主要是想學一點平時很少接觸的技能,希望找工作的時候能成為加分項。(其實主要還是用來裝逼的)
廢話少說,進入正題 ->_<-。
1.怎么反編譯?
首先介紹一個反編譯神器 - Android Crack Tool,不開玩笑的說,這個工具幾乎可以完成反編譯的所有任務,吊炸天的棒??
牛逼不?全都是可視化操作,先把apk文件拖進去,然后反編譯apk,之后會生成一個如下所示的文件夾:
里面有 res 和 asset 的全部資源文件 (樣式文件有什么用?反正我覺得沒什么卵用...)
接下來就是關鍵了! 把apk文件的后綴改成.zip,然后解壓,會得到一個 dex 文件,然后在拖進可視化工具中,選擇 DEX2JAR 執行,之后呢會生成一個.jar后綴的文件,然后選擇 JDGUI 再執行。這時會彈出一個JDGUI的代碼查看界面,這里面就是項目源碼了。 開心伐???
這個時候呢理論上應該激動地跳起來,但是先穩一手...我賭五毛錢你會看得頭昏眼花 ?? 因為估計關鍵部分的代碼都被混淆了..你以為別人公司的代碼這么容易就被你看穿了嗎???
2.閱讀反編譯源碼技巧
說到這里不得不申明一下,為什么公司會讓我去搞反編譯。原因很簡單,只是想單純的向競爭公司學習學習,順便呢研究研究對手有沒有在搞什么黑科技(絕不是抄襲嘿嘿:smirk:)
在剛拿到競品源碼的時候,我是比較懵逼的。作為一個從來沒有看過大公司代碼結構的戰五渣來說,一上來就是以這樣一種形式去研究別人公司的代碼,對我來說是一個很不錯的挑戰吧。
如果知道程序的入口,可以從入口開始,一層層地深入去看。對于Android程序而言,在手機或模擬器上運行一下app,然后根據跳轉和處理的事件來查看對應的邏輯代碼,這是一種比較理想的方式吧。
這樣對于整個代碼也會有一個宏觀的認識。
然而在閱讀代碼的過程中,可能會讓你崩潰。因為很多地方的代碼都被混淆了,比如下圖所示的樣子:
又或者是這種:
崩潰不?絕望不?遇到這種被混淆的方法,也只能說放棄,從別的地方著手吧。
但是呢,通過我一周以來的探路發現,有的時候其實也并不需要去解讀某些方法的具體實現過程,也許你足夠機智,可以大概猜到這個方法他想干嘛。就像第二張圖里面的那些類似注釋一樣的代碼塊,
雖然這些完全沒有邏輯,但是里面偶爾會夾雜著某些方法名,然后你就可以發揮你的想象,去猜想他在干嘛!
不得不說的一點就是,如果以后你想提高代碼的安全程度,不想讓別人反編譯然后解讀你的代碼,我強烈建議多使用反射機制...這是我這周以來的強烈感受!因為在使用反射的地方,你根本就猜不到他是調用了哪個方法!氣死我了。
反編譯后的代碼為什么難以解讀?主要是:
代碼會被混淆,就像剛才看到的那樣,會讓你崩潰。
變量名會改變,比如說方法中的變量名會變成 param1,param2..
if 和 while,for 循環的邏輯會改變!! 媽蛋啊,這些邏輯改變了還看個毛啊!? 還好,百度可以搜到一些常見的變化規則....
如果你也是為了破解和偵察敵方公司的代碼而反編譯的話,無從下手或者處于崩潰邊緣,可以試著從手機中 data/user/0/files 中的文件入手,
因為可能一些比較關鍵的本地數據或文件都存放在這個文件夾下,一旦找到一些看似“黑科技”的文件,請務必在全局代碼中去搜索哪里使用了該文件,
這可能會點燃你的希望 。
但是呢前提是得使用root過的手機哦 ~
找到sdk目錄下的adb 然后在終端中執行 ./adb shell ,你就可以掌控你的手機了!
cp 手機文件 PC路徑 將files里面的文件考到電腦上,然后認真研究一番。
除此之外,還有一個心得,除了利用這個Android Crack Tool 來閱讀jar里面的反編譯代碼之外,還可以將jar包放進Android Studio 或者 IDEA 的Librabry里面,然后add Library ,其實這也是工具自帶的反編譯功能。為什么要這樣呢? 因為有些代碼(特別是混淆代碼)在不同工具中會有不一樣的顯示哦!~
3.自己的理解
通過這一周對于競品的研究,我深深地體會到這些公司的不容易。一方面要保證代碼質量必須要高,另一方面還要想方設法為自己的代碼“加密”。
確實對于互聯網時代而言,技術壁壘和安全性是多么的重要。你的技術再牛逼,如果安全程度不高的話也是浮云吧~
所以我總結一下如何提高app的安全性吧,就一些自己的理解。
(1)多用一些語言的高級用法,比如java反射機制, 讓你的代碼不是那么一目了然。因為很多碼農只是為了以實現功能為目的去寫程序的話,有很大概率不會用上像反射這種高級的用法,甚至連聽都沒聽說過...
確實,如果某段方法被混淆了,并且還是用了反射,那么的確會讓解讀你代碼的人很絕望。
(2)將一些重要的數據或方法封裝在一些罕見的格式中。比如就像我研究的競品代碼,我認為他們在安全性上確實是下了一番功夫的。
首先他們將一些數據封裝在一些.obj后綴的文件里面,并且無論用什么方法去讀里面的內容,都會是亂碼。
后來發現,者使用了一種叫做Kryo的序列化方式,類似以Json,但是卻非常隱蔽并且安全。因為一想要反序列化的話,必須register 注冊那些用到的javaBean,少了一個也不行!
然而,里面用到的反射也是根據從obj文件中讀取到的數據進行反射的,讓我真是大開眼界! 原來還可以這么玩兒啊...
(3)利用 .SO 動態鏈接庫文件去封裝一些方法。 因為在研究競品代碼時,我發現有一些obj文件我根本就找不到在哪里調用的。后來組長提醒我,可能和這些SO文件有關。
然后我就找啊找..最后發現確實調用了SO文件里面的方法,而且這些SO文件里面的方法還很關鍵。(因為我不知道SO文件里面的方法有沒有可能去讀或者去找手機里面的文件,
如果真的可以,那這也太吊了吧...)
反編譯并不是什么違法的事情,就對于個人而言只是一種學習的手段,向別人的代碼借鑒和學習。畢竟多一門技術也并不是什么壞事,說不定什么時候就真正派上用場了呢~
一周的競品研究雖說沒有什么突破性的研究成果,但是確實讓我一個反編譯小白學到了很多一身受用東西。我也是抱著去公司學習和研究一些自己平時很少接觸但很有用的東西的這么一個心態,
而不是一味的去寫業務邏輯代碼,研究一些有技術難度的東西挺好的。這一周下來,組長每次問我最多的一句話就是:“研究的怎么樣了?崩潰了沒有?”。
還好,反編譯這種技術要的就是思維靈活,剛好我的腦洞比較大,找到了很多突破口,讓競品的研究有了些進展,不至于被噴哈哈。
第一次寫類似博客的東西,技術性偏少吧...對技術博客的套路還沒摸清楚門路...希望下次能寫出高技術含量的東西,而不是這種旅游日記哈哈。