Android 反編譯

平常不太會(huì)用得到,但是一旦真的需要用到的了鸽粉,而你卻不會(huì)的話斜脂,那就非常頭疼了。別人可以反編譯程序触机,我們對程序進(jìn)行一定程度的保護(hù)帚戳,因此代碼混淆也是我們必須要掌握的一項(xiàng)技術(shù)。

Android程序打完包之后得到的是一個(gè)APK文件儡首,這個(gè)文件直接安裝到任何Android手機(jī)上片任,我們反編譯其實(shí)也就是對這個(gè)APK文件進(jìn)行反編譯。Android的反編譯主要兩個(gè)部分蔬胯,一個(gè)是對代碼的反編譯对供,一個(gè)是對資源的反編譯。

反編譯代碼
要想將APK文件中的代碼反編譯出來氛濒,我們需要用到以下兩款工具:

dex2jar 這個(gè)工具用于將dex文件轉(zhuǎn)換成jar文件
下載地址:http://sourceforge.net/projects/dex2jar/files/
jd-gui 這個(gè)工具用于將jar文件轉(zhuǎn)換成java代碼
下載地址:http://jd.benow.ca/

解壓dex2jar壓縮包后产场,你會(huì)發(fā)現(xiàn)有很多個(gè)文件,如下圖所示:


image.png

其中我們要用到的是d2j-dex2jar.bat這個(gè)文件舞竿,當(dāng)然如果你是linux或mac系統(tǒng)的話就要用d2j-dex2jar.sh這個(gè)文件京景。
然后我們將app-release.apk文件也進(jìn)行解壓,如果不知道怎么直接解壓的可以先將文件重命名成app-release.zip骗奖,然后用解壓軟件打開确徙。解壓之后你會(huì)發(fā)現(xiàn)里面有一個(gè)classes.dex文件醒串,如下圖所示:


image.png

這個(gè)classes.dex文件就是存放所有java代碼的地方了,我們將它拷貝到dex2jar解壓后的目錄下米愿,并在cmd中也進(jìn)入到同樣的目錄厦凤,然后執(zhí)行:

d2j-dex2jar classes.dex

執(zhí)行結(jié)果如下圖所示:


image.png

雖然報(bào)了錯(cuò)誤,但我們已經(jīng)轉(zhuǎn)換成功了∮叮現(xiàn)在觀察dex2jar目錄较鼓,你會(huì)發(fā)現(xiàn)多了一個(gè)文件,如下圖所示:


image.png

可以看到违柏,classes-dex2jar.jar這個(gè)文件就是我們借助工具之后成功轉(zhuǎn)換出來的jar文件了博烂。但是對于我們而言,jar文件也不是可讀的漱竖,因此這里還需要再借助一下jd-gui這個(gè)工具來將jar文件轉(zhuǎn)換成java代碼禽篱。
下面就很簡單了,使用jd-gui工具打開classes-dex2jar.jar這個(gè)文件馍惹,結(jié)果如下圖所示:
image.png

我們的代碼反編譯工作已經(jīng)成功了躺率,MainActivity中的代碼非常清晰,基本已經(jīng)做到了90%以上的還原工作万矾。但是如果想要做到100%的代碼還原還是非常有難度的悼吱,因?yàn)橄駍etContentView()方法傳入的參數(shù),其實(shí)就是一個(gè)資源的id值而已良狈,那么這里反編譯也就只能將相應(yīng)的id值進(jìn)行還原后添,而無法變成像R.layout.activity_main這樣直觀的代碼展示。
另外薪丁,除了MainActivity之外遇西,還有很多其它的代碼也被反編譯出來了,因?yàn)楫?dāng)前項(xiàng)目有引用support-v4和androidx的包严嗜,這些引用的library也會(huì)作為代碼的一部分被打包到classes.dex文件當(dāng)中粱檀,因此反編譯的時(shí)候這些代碼也會(huì)一起被還原。
好的阻问,學(xué)完了反編譯代碼梧税,接下來我們看一下如何反編譯資源。

反編譯資源

其實(shí)細(xì)心的朋友可能已經(jīng)觀察到了称近,剛才app-release.apk的解壓目錄當(dāng)中不是已經(jīng)有資源文件了嗎,有AndroidManifest.xml文件哮塞,也有res目錄刨秆。進(jìn)入res目錄當(dāng)中,內(nèi)容如下圖所示:

image.png

這不是所有資源文件都在這里了么忆畅?其實(shí)這些資源文件都是在打包的時(shí)候被編譯過了衡未,我們直接打開的話是看不到明文的,不信的話我們打開AndroidManifest.xml文件來瞧一瞧,內(nèi)容如下圖所示:
image.png

直接對APK包進(jìn)行解壓是無法得到它的原始資源文件的缓醋,因此我們還需要對資源進(jìn)行反編譯才行如失。
要想將APK文件中的資源反編譯出來,又要用到另外一個(gè)工具了:
apktool 這個(gè)工具用于最大幅度地還原APK文件中的9-patch圖片送粱、布局褪贵、字符串等等一系列的資源。
下載地址:https://ibotpeaches.github.io/Apktool/install/

接下來的工作就很簡單了抗俄,我們將app-release.apk拷貝到和這兩個(gè)文件同樣的目錄當(dāng)中脆丁,然后cmd也進(jìn)入到這個(gè)目錄下,并在cmd中執(zhí)行如下命令:
apktool d app-release.apk
其中d是decode的意思动雹,表示我們要對app-release.apk這個(gè)文件進(jìn)行解碼槽卫。那除了這個(gè)基本用法之外,我們還可以再加上一些附加參數(shù)來控制decode的更多行為:

  • -f 如果目標(biāo)文件夾已存在胰蝠,則強(qiáng)制刪除現(xiàn)有文件夾(默認(rèn)如果目標(biāo)文件夾已存在歼培,則解碼失敗)茸塞。
  • -o 指定解碼目標(biāo)文件夾的名稱(默認(rèn)使用APK文件的名字來命名目標(biāo)文件夾)躲庄。
  • -s 不反編譯dex文件,也就是說classes.dex文件會(huì)被保留(默認(rèn)會(huì)將dex文件解碼成smali文件)
  • -r 不反編譯資源文件翔横,也就是說resources.arsc文件會(huì)被保留(默認(rèn)會(huì)將resources.arsc解碼成具體的資源文件)读跷。
    apktool d -f app-release.apk -o app


    image.png

    這就說明反編譯資源已經(jīng)成功了。
    現(xiàn)在你會(huì)發(fā)現(xiàn)在當(dāng)前目錄下多了一個(gè)app文件夾禾唁,這個(gè)文件夾中存放的就是反編譯的結(jié)果了效览。我們可以打開AndroidManifest.xml來瞧一瞧,如下圖所示:


    image.png

    這樣就完全能看得懂了吧
image.png

其中荡短,original文件夾下存放的是未經(jīng)反編譯過丐枉、原始的AndroidManifest.xml文件,res文件夾下存放的是反編譯出來的所有資源掘托,smali文件夾下存放的是反編譯出來的所有代碼瘦锹,AndroidManifest.xml則是經(jīng)過反編譯還原后的manifest文件。這里值得一提的是smali文件夾闪盔,如果你進(jìn)入到這個(gè)文件夾中你會(huì)發(fā)現(xiàn)它的目錄結(jié)構(gòu)和我們源碼中src的目錄結(jié)構(gòu)是幾乎一樣的弯院,主要的區(qū)別就是所有的java文件都變成了smali文件。smali文件其實(shí)也是真正的源代碼泪掀,只不過它的語法和java完全不同听绳,它有點(diǎn)類似于匯編的語法,是Android虛擬機(jī)所使用的寄存器語言异赫,語法結(jié)構(gòu)大概如下所示:


image.png

看上去有點(diǎn)暈頭轉(zhuǎn)向是嗎椅挣?如果你一旦能夠看得懂smali文件的話头岔,那么你就可以做很恐怖的事情了——你可以隨意修改應(yīng)用程序內(nèi)的邏輯,將其進(jìn)行破解鼠证!
也已經(jīng)可以對程序的邏輯做一定程度的修改了峡竣。比如說當(dāng)我們點(diǎn)擊按鈕時(shí)會(huì)彈出Hello World這樣一句Toast,邏輯是寫在MainActivity按鈕點(diǎn)擊事件的匿名類當(dāng)中的量九,因此這段代碼反編譯之后一定就會(huì)在MainActivity$1.smali這個(gè)文件當(dāng)中适掰,讓我們打開瞧一瞧,部分代碼如下所示:


image.png

雖說多數(shù)的代碼我是看不懂的娩鹉,但其中第47行實(shí)在太明顯了攻谁,Toast顯示的內(nèi)容不就是在這里定義的么,那么如果我們想把a(bǔ)pp-release程序hack掉弯予,就可以將這段字符串給改掉戚宦,比如說我把它改成Your app is been hacked。
關(guān)于smali的語法锈嫩,網(wǎng)上的資料也非常多受楼,如果你對這門技術(shù)十分感興趣的話可以直接上網(wǎng)去搜,這里我只是簡單介紹一下呼寸,就不再深入講解相關(guān)知識了艳汽。
改了一處代碼后我們再來改一處資源吧,比如這里想要把a(bǔ)pp-release的應(yīng)用圖標(biāo)給換掉对雪,那么首先我們要準(zhǔn)備好一張新的圖片河狐,如下圖所示:


ic_launcher.png(彩虹圈)

然后從AndroidManifest.xml文件中可以看出,應(yīng)用圖標(biāo)使用的是ic_launcher.png這張圖片瑟捣,我們將上面彩虹圈這張圖片命名成ic_launcher.png馋艺,然后拷貝到所有以res/mipmap(貼圖)開頭的文件夾當(dāng)中完成替換操作。如下圖所示:


image.png

ic_launcher_foreground:這是Android 8.0的版本開始的前景圖(我們先按照目錄下的結(jié)構(gòu)弄)迈套,后面專門介紹APP圖標(biāo)適配
在做了兩處改動(dòng)之后捐祠,我們現(xiàn)在來把反編譯后的app-release文件夾重新打包成APK,其實(shí)非常簡單桑李,只需要在cmd中執(zhí)行如下命令:

  • apktool b app -o new_app.apk
    其中b是build的意思踱蛀,表示我們要將app文件夾打包成APK文件,-o用于指定新生成的APK文件名贵白,這里新的文件叫作new_app.apk率拒。執(zhí)行結(jié)果如下圖所示:


    image.png

現(xiàn)在你會(huì)發(fā)現(xiàn)在同級目錄下面生成了一個(gè)新的APK文件:


image.png

不過不要高興得太早了,目前這個(gè)new_app.apk還是不能安裝的禁荒,因?yàn)樗€沒有進(jìn)行簽名俏橘。那么如果這是別人的程序的話,我們從哪兒能拿到它原來的簽名文件呢圈浇?很顯然寥掐,這是根本沒有辦法拿到的,因此我們只能拿自己的簽名文件來對這個(gè)APK文件重新進(jìn)行簽名磷蜀,但同時(shí)也表明我們重新打包出來的軟件就是個(gè)十足的盜版軟件召耘。這里大家學(xué)學(xué)技術(shù)就好了,希望不要有任何人去做什么壞事情褐隆。
那么這里我就用一個(gè)之前生成好的簽名文件了污它,使用Android Studio或者Eclipse都可以非常簡單地生成一個(gè)簽名文件。

有了簽名文件之后在cmd中執(zhí)行簽名命令就可以進(jìn)行簽名了庶弃,命令格式如下:

  • jarsigner -verbose -keystore [您的私鑰存放路徑] -signedjar [簽名后文件存放路徑] [未簽名的文件路徑] [您的證書名稱]
  • 其中jarsigner命令文件是存放在jdk的bin目錄下的衫贬,需要將bin目錄配置在系統(tǒng)的環(huán)境變量當(dāng)中才可以在任何位置執(zhí)行此命令。
  • 簽名之后的APK文件現(xiàn)在已經(jīng)可以安裝到手機(jī)上了歇攻,不過在此之前Android還極度建議我們對簽名后的APK文件進(jìn)行一次對齊操作固惯,因?yàn)檫@樣可以使得我們的程序在Android系統(tǒng)中運(yùn)行得更快。對齊操作使用的是zipalign工具缴守,該工具存放于<Android SDK>/build-tools/<version>目錄下葬毫,將這個(gè)目錄配置到系統(tǒng)環(huán)境變量當(dāng)中就可以在任何位置執(zhí)行此命令了。命令格式如下:

zipalign 4 new_app_release.apk new_app_aligned.apk

其中4是固定值不能改變屡穗,后面指定待對齊的APK文件名和對齊后的APK文件名贴捡。運(yùn)行這段命令之后就會(huì)生成一個(gè)new_app_aligned.apk文件,如下所示:


image.png

這個(gè)new_app_aligned.apk就是我們重新打包簽名對齊后的文件了村砂,現(xiàn)在把它安裝到手機(jī)上烂斋,效果如下圖所示:
可以看到础废,應(yīng)用圖標(biāo)已經(jīng)成功改成了彩虹圈汛骂,另外點(diǎn)擊按鈕后彈出的Toast的提示也變成了我們修改后的文字色迂,說明重新打包操作確實(shí)已經(jīng)成功了。


image.png

好的歇僧,我們把反編譯代碼图张、反編譯資源、重新打包這三大主題的內(nèi)容都已經(jīng)掌握了诈悍,關(guān)于反編譯相關(guān)的內(nèi)容就到這里

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末祸轮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侥钳,更是在濱河造成了極大的恐慌适袜,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舷夺,死亡現(xiàn)場離奇詭異苦酱,居然都是意外死亡售貌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門疫萤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颂跨,“玉大人,你說我怎么就攤上這事扯饶『阆鳎” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵尾序,是天一觀的道長钓丰。 經(jīng)常有香客問我,道長每币,這世上最難降的妖魔是什么携丁? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮脯爪,結(jié)果婚禮上则北,老公的妹妹穿的比我還像新娘。我一直安慰自己痕慢,他們只是感情好尚揣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著掖举,像睡著了一般快骗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上塔次,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天方篮,我揣著相機(jī)與錄音,去河邊找鬼励负。 笑死藕溅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的继榆。 我是一名探鬼主播巾表,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼略吨!你這毒婦竟也來了集币?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤翠忠,失蹤者是張志新(化名)和其女友劉穎鞠苟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡当娱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年吃既,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趾访。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡态秧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出扼鞋,到底是詐尸還是另有隱情,我是刑警寧澤愤诱,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布云头,位于F島的核電站,受9級特大地震影響淫半,放射性物質(zhì)發(fā)生泄漏溃槐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一科吭、第九天 我趴在偏房一處隱蔽的房頂上張望昏滴。 院中可真熱鬧,春花似錦对人、人聲如沸谣殊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姻几。三九已至,卻和暖如春势告,著一層夾襖步出監(jiān)牢的瞬間蛇捌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工咱台, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留络拌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓回溺,卻偏偏與公主長得像春贸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子馅而,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容