一.看android的源代碼
目前累計(jì)服務(wù)客戶(hù)上1000+,積累了豐富的產(chǎn)品開(kāi)發(fā)及服務(wù)經(jīng)驗(yàn)。以網(wǎng)站設(shè)計(jì)水平和技術(shù)實(shí)力,樹(shù)立企業(yè)形象,為客戶(hù)提供成都做網(wǎng)站、網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷(xiāo)、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。成都創(chuàng)新互聯(lián)始終以務(wù)實(shí)、誠(chéng)信為根本,不斷創(chuàng)新和提高建站品質(zhì),通過(guò)對(duì)領(lǐng)先技術(shù)的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究、對(duì)客戶(hù)形象的視覺(jué)傳遞、對(duì)應(yīng)用系統(tǒng)的結(jié)合,為客戶(hù)提供更好的一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶(hù),共同發(fā)展進(jìn)步。
1)將Apkd.apk 用zip解壓后,出現(xiàn)了一個(gè)classes.dex文件
2014/02/19 19:42
.
2014/02/19 19:42
..
2014/02/19 15:35 1,656 AndroidManifest.xml
2014/02/19 15:35 687,024 classes.dex
2014/02/19 15:49
META-INF
2014/02/19 15:49
res
2014/02/19 15:35 2,200 resources.arsc
2)進(jìn)入到dex2jar目錄中,運(yùn)行情況如下:
D:\developer\tools\test_apk\dex2jar-0.0.9.15dex2jar.bat "..\Apkd(d2j)\classes.d
ex"
this cmd is deprecated, use the d2j-dex2jar if possible
dex2jar version: translator-0.0.9.15
dex2jar ..\Apkd(d2j)\classes.dex - ..\Apkd(d2j)\classes_dex2jar.jar
Done.
在apk所在的目錄會(huì)出現(xiàn) classes_dex2jar.jar 文件。
3) 用JD-GUI對(duì)jar包進(jìn)行查看,可以查看源文件
二.反編譯apk
1.在 下載 APKTOOL中的三個(gè)文件(aapt.exe、apktool.bat、apktool.jar)解壓縮到你的Windows安裝目錄下,以方便使用Dos命令.
2012/12/06 11:44 854,016 aapt.exe
2014/02/19 17:15 277,372 Apkd.apk //示例用 apk文件
2012/12/23 23:39 92 apktool.bat
2013/02/03 02:37 2,655,843 apktool.jar
2.進(jìn)入到apktool.bat所在的目錄,運(yùn)行:
apktool d Apkd.apk decode_dir
反編譯后,decode_dir目錄下的內(nèi)容如下:
2014/02/19 17:16 716 AndroidManifest.xml
2014/02/19 17:16 237 apktool.yml
2014/02/19 17:18
build
2014/02/19 17:16
res
2014/02/19 17:16
smali
此時(shí)我可以查看原文件AndroidManifest.xml了,也是查看smali源文件(是用smali語(yǔ)言寫(xiě)的,可以對(duì)照java看)。
三.APKTOOL的使用
1).decode
該命令用于進(jìn)行反編譯apk文件,一般用法為
apktool d
代表了要反編譯的apk文件的路徑,最好寫(xiě)絕對(duì)路徑,比如C:\MusicPlayer.apk
代表了反編譯后的文件的存儲(chǔ)位置,比如C:\MusicPlayer
如果你給定的已經(jīng)存在,那么輸入完該命令后會(huì)提示你,并且無(wú)法執(zhí)行,需要你重新修改命令加入-f指令
apktool d –f
這樣就會(huì)強(qiáng)行覆蓋已經(jīng)存在的文件
2).build
該命令用于編譯修改好的文件,一般用法為
apktool b
這里的
就是剛才你反編譯時(shí)輸入的
(如C:\MusicPlayer),輸入這行命令后,如果一切正常,你會(huì)發(fā)現(xiàn)C:\MusicPlayer內(nèi)多了2個(gè)文件夾build和dist,其中分別存儲(chǔ)著編譯過(guò)程中逐個(gè)編譯的文件以及最終打包的apk文件。
3).install-framework
該命令用于為APKTool安裝特定的framework-res.apk文件,以方便進(jìn)行反編譯一些與ROM相互依賴(lài)的APK文件。具體情況請(qǐng)看常見(jiàn)問(wèn)題
四.smali與java源碼對(duì)照,并做出相應(yīng)的修改
java源代碼:
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.*;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView a = (TextView)this.findViewById(R.id.test) ;
a.setText("raoliang");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
對(duì)應(yīng)的smali源代碼:
.class public Lali/text/apkd/MainActivity;
.super Landroid/app/Activity;
.source "MainActivity.java"
# direct methods
.method public constructor ()V
.locals 0
.prologue
.line 8
invoke-direct {p0}, Landroid/app/Activity;-()V
return-void
.end method
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 2
.parameter "savedInstanceState"
.prologue
.line 12
invoke-super {p0, p1}, Landroid/app/Activity;-onCreate(Landroid/os/Bundle;)V
.line 13
const/high16 v1, 0x7f03
invoke-virtual {p0, v1}, Lali/text/apkd/MainActivity;-setContentView(I)V
.line 14
const/high16 v1, 0x7f08
invoke-virtual {p0, v1}, Lali/text/apkd/MainActivity;-findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/TextView;
.line 15
.local v0, a:Landroid/widget/TextView;
const-string v1, "raoliang"
invoke-virtual {v0, v1}, Landroid/widget/TextView;-setText(Ljava/lang/CharSequence;)V
.line 16
return-void
.end method
.method public onCreateOptionsMenu(Landroid/view/Menu;)Z
.locals 2
.parameter "menu"
.prologue
.line 21
invoke-virtual {p0}, Lali/text/apkd/MainActivity;-getMenuInflater()Landroid/view/MenuInflater;
move-result-object v0
const/high16 v1, 0x7f07
invoke-virtual {v0, v1, p1}, Landroid/view/MenuInflater;-inflate(ILandroid/view/Menu;)V
.line 22
const/4 v0, 0x1
return v0
.end method
通過(guò)對(duì)比可以看到,常量是沒(méi)有必變的,可以根據(jù)的smali的語(yǔ)法,進(jìn)行相應(yīng)的修改
五.3、打包、簽名和安裝修改后的apk
修改完了,就可以打包回apk了。執(zhí)行以下命令:
apktool b decode_dir
在mygame目錄下的dist在會(huì)看到打包好的apk。
當(dāng)然,現(xiàn)在一般是無(wú)法安裝的,因?yàn)閍pk還沒(méi)有簽名。下面就來(lái)簽名。簽名需要keystore文件,我已經(jīng)有專(zhuān)用的keystore了,如果還沒(méi)有,請(qǐng)參閱這里進(jìn)行生成。
執(zhí)行以下命令為重新編譯的my_game.apk簽名:
jarsigner -verbose -keystore demo.keystore Apkd.apk demo.keystore
最后,在安裝到手機(jī)前,需要把手機(jī)中的已有版本先卸載,因?yàn)槿绻灻煌遣荒芨采w安裝的,會(huì)提示“應(yīng)用程序未安裝”錯(cuò)誤。
完整的運(yùn)行情況如下:
D:\developer\tools\test_apk\new\decode\distkeytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore
輸入keystore密碼:
再次輸入新密碼:
您的名字與姓氏是什么?
[Unknown]: rao
您的組織單位名稱(chēng)是什么?
[Unknown]: rao
您的組織名稱(chēng)是什么?
[Unknown]:
您所在的城市或區(qū)域名稱(chēng)是什么?
[Unknown]:
您所在的州或省份名稱(chēng)是什么?
[Unknown]:
該單位的兩字母國(guó)家代碼是什么
[Unknown]:
CN=rao, OU=rao, O=Unknown, L=Unknown, ST=Unknown, C=Unknown 正確嗎?
[否]: y
輸入的主密碼
(如果和 keystore 密碼相同,按回車(chē)):
D:\developer\tools\test_apk\new\decode\distjarsigner -verbose -keystore demo.keystore Apkd.apk demo.keystore
輸入密鑰庫(kù)的口令短語(yǔ):
正在添加: META-INF/MANIFEST.MF
正在添加: META-INF/DEMO_KEY.SF
正在添加: META-INF/DEMO_KEY.RSA
正在簽名: res/drawable-hdpi/ic_launcher.png
正在簽名: res/drawable-mdpi/ic_launcher.png
正在簽名: res/drawable-xhdpi/ic_launcher.png
正在簽名: res/drawable-xxhdpi/ic_launcher.png
正在簽名: res/layout/activity_main.xml
正在簽名: res/menu/main.xml
正在簽名: AndroidManifest.xml
正在簽名: classes.dex
正在簽名: resources.arsc
D:\developer\tools\test_apk\new\decode\dist
到此為止,修改后的apk可以正常的安裝了,不過(guò),在安裝之前,必須要先卸載以前的apk,不能直接替換(因?yàn)楹灻灰粯樱?/p>
1、配置好JAVA環(huán)境變量,下載:apktool 解壓的文件放在C盤(pán)根目錄的apktool文件夾里(apktool文件夾自己創(chuàng)立)
2打開(kāi)命令提示符,(開(kāi)始-運(yùn)行-輸入cmd)
3輸入:cd \apktool 系統(tǒng)指令到了apktool文件夾(這里就是為什么要把解壓的apktool解壓的文件放到apktool文件夾的原因,當(dāng)然你也可以自命名文件夾的名稱(chēng),那么比如arc,那么指令就變成了:cd \arc 前提是你必須把a(bǔ)pktool解壓的文件放到這個(gè)文件夾里面)
4使用RE管理器把系統(tǒng)里面的framework-res.apk 與 SystemUI.apk 提取出來(lái)放在apktool文件夾里面
5 如果只是想反編譯framework-res.apk
輸入apktool if framework-res.apk(框架的建立)
6開(kāi)始最重要的反編譯,輸入指令,apktool d framework-res.apk
(反編輯的APK一定要用沒(méi)換過(guò)圖片的,否則回編輯失敗)
7最后反編譯完成
修改代碼完成后,輸入代碼:apktool d framework-res 即可完成回編譯
8回編譯后的新的 apk在framework/dis 文件夾里面
9如果反編譯的是系統(tǒng)文件,比如,SystemUI.apk 那么必須進(jìn)行掛載框架,反編譯時(shí),必須敲入一下命令:(然后再重復(fù)7-9步驟)
apktool if framework-res.apk
apktool if SystemUI.apk
10對(duì)于三星手機(jī)(比如9100、9108/9100G),如果反編譯SystemUI.apk要敲入一下命令進(jìn)行框架掛載apktool if framework-res.apk
apktool if twframework-res.apk
apktool if SystemUI.apk
11回編譯的命令是 apktool b XXX (沒(méi)有后面的apk后綴)反編譯的命令是 apktool d xxx (有后面的apk)
一、Apk反編譯得到Java源代碼
下載上述反編譯工具包,打開(kāi)apk2java目錄下的dex2jar-0.0.9.9文件夾,內(nèi)含apk反編譯成java源碼工具,以及源碼查看工具。
apk反編譯工具dex2jar,是將apk中的classes.dex轉(zhuǎn)化成jar文件
源碼查看工具jdgui,是一個(gè)反編譯工具,可以直接查看反編譯后的jar包源代碼
具體步驟:
首先將apk文件后綴改為zip并解壓,得到其中的classes.dex,它就是java文件編譯再通過(guò)dx工具打包而成的,將classes.dex復(fù)制到dex2jar.bat所在目錄dex2jar-0.0.9.9文件夾。
在命令行下定位到dex2jar.bat所在目錄,運(yùn)行
dex2jar.bat classes.dex
生成
classes_dex2jar.jar
然后,進(jìn)入jdgui文件夾雙擊jd-gui.exe,打開(kāi)上面生成的jar包c(diǎn)lasses_dex2jar.jar,即可看到源代碼了
二、apk反編譯生成程序的源代碼和圖片、XML配置、語(yǔ)言資源等文件
如果是漢化軟件,這將特別有用
首先還是要下載上述反編譯工具包,其中最新的apktool,請(qǐng)到google code下載
apktool(google code)
具體步驟:
下載上述反編譯工具包,打開(kāi)apk2java目錄下的apktool1.4.1文件夾,內(nèi)含三個(gè)文件:aapt.exe,apktool.bat,apktool.jar
注:里面的apktool_bk.jar是備份的老版本,最好用最新的apktool.jar
在命令行下定位到apktool.bat文件夾,輸入以下命令:apktool.bat d -f abc123.apk abc123
三、 圖形化反編譯apk
上述步驟一、二講述了命令行反編譯apk,現(xiàn)在提供一種圖形化反編譯工具:Androidfby
首先,下載上述反編譯工具包,打開(kāi)Androidfby目錄,雙擊Android反編譯工具.exe,就可以瀏覽打開(kāi)要反編譯的apk
PS: 最近沒(méi)工作,沒(méi)工作就沒(méi)需求,沒(méi)需求就沒(méi)什么技術(shù)總結(jié)的靈感,那就沒(méi)更新什么。但是兩個(gè)月不更新了,要是三個(gè)月不更新就會(huì)出大事,所以這次打算做一件有意思又不難的事。
之前有發(fā)文章寫(xiě)過(guò)反編譯,今天就來(lái)試試反編譯之正編譯,開(kāi)玩笑的,就是試試手動(dòng)編譯的過(guò)程, 平時(shí)我們?cè)陧?xiàng)目中編譯出包都是使用Gradle直接執(zhí)行assemble任務(wù)就能解決,我打算試試手動(dòng)模擬整個(gè)過(guò)程。當(dāng)然我也是第一次這樣搞,所以如果有寫(xiě)得不對(duì)的地方,還望指出。
眾所周知,apk實(shí)質(zhì)上就是一個(gè)壓縮包。復(fù)習(xí)一下,我們寫(xiě)個(gè)最簡(jiǎn)單的Demo,然后打包,然解壓,注意是解壓,不是反編譯,意義是不同的。
注意我這個(gè)Demo很簡(jiǎn)單,什么都不引入
然后我們看看整個(gè)出包的過(guò)程,隨便從網(wǎng)上拿張圖
然后這里我們用Android SDK給我們提供的工具來(lái)完成整個(gè)流程,工具在sdk文件夾下的build-tools文件夾下,有什么aapt.exe、dx.bat,用的就是這些
這步應(yīng)該是整個(gè)流程最簡(jiǎn)單的吧,我感覺(jué),所以從最簡(jiǎn)單的開(kāi)始。
我們先看看生成的dex有什么
對(duì)比項(xiàng)目,我是一開(kāi)始最基本的項(xiàng)目,什么都沒(méi)動(dòng),所以只有一個(gè)MainActivity.clas,所以這里肯定是要先想辦法得到BuildConfig.class和R.class。
輸入命令:
aapt p -f -m -J 輸出路徑 -S res路徑 -I android.jar路徑 -M Manifest路徑
下一步,我們需要BuildConfig.class
這個(gè)BuildConfig.java是由gradle在我們配置好gradle之后自己幫我們生成的,所以我們直接拿來(lái)用,然后再javac就得到class文件了
然后我們?cè)倬幾g我們的MainActivity.java并將它們放到同一個(gè)文件夾下, MainActivity因?yàn)橐昧薃ndroid.jar和R文件,所以編譯時(shí)注意點(diǎn),我為此被動(dòng)好好的復(fù)習(xí)了一遍javac,都是淚
最后一步,我們用dx工具就能打出dex文件了
然后執(zhí)行命令就得到一個(gè)Dex文件,看看這個(gè)文件里面和上面直接打出的apk中的Dex文件有什么不同:
看圖,我們上一步已經(jīng)生成.dex了,那么我們需要和compiled Resource 還有 Other Resource 一起生成APK。
我們先來(lái)生成compiled Resource,也就是resources.arsc
發(fā)現(xiàn)之前使用aapt生成R文件的時(shí)候沒(méi)寫(xiě)完整,當(dāng)時(shí)可以加一個(gè)-F參數(shù)直接生成arsc和Manifest
導(dǎo)出的abc.zip里面就有resources.arsc和AndroidManifest.xml。
因?yàn)橹皩?xiě)漏了,所以肯定要重新編一次MainActivity.java和Dex
我們把剛才的dex文件和aapt生成的resources.arsc、AndroidManifest.xml和res放到一個(gè)文件夾里面。
PS:res文件夾也是上面aapt的命令生成的
然后我們對(duì)比這個(gè)文件夾和之前apk解壓的文件夾
最后運(yùn)行
看來(lái)是成功了。
再說(shuō)說(shuō)遇到的還有兩個(gè)問(wèn)題,并說(shuō)下我解決問(wèn)題的思路
(1)我把它們都放到一個(gè)文件夾之后,我壓縮成壓縮包,然后改后綴成.apk,然后發(fā)現(xiàn)安裝不了,我就直接反編譯,發(fā)現(xiàn)發(fā)編譯失敗,提示包有問(wèn)題,以我多點(diǎn)玩包的經(jīng)驗(yàn),我感覺(jué)就是壓縮工具出了問(wèn)題,然后我去下個(gè)“好壓”(這不是廣告?。缓缶湍苷7淳幾g了。
(2)但是還是安裝不了,再根據(jù)我多年的玩包經(jīng)驗(yàn),我感覺(jué)是簽名問(wèn)題,然后我隨便給這個(gè)包上一個(gè)簽名,就能正常安裝得到上圖的結(jié)果了。
總體來(lái)說(shuō),還真挺好玩的,這整個(gè)過(guò)程,就是翻車(chē)了幾次。做完之后感覺(jué)非常牛逼,為什么這樣說(shuō),因?yàn)槲抑肋@整個(gè)過(guò)程,我就可以做到,我不經(jīng)過(guò)gradle來(lái)打包,我自己寫(xiě)個(gè)python腳本來(lái)調(diào)用aapt和dx來(lái)打包也是能做到的。
當(dāng)然上面純屬異想天開(kāi),因?yàn)檫@是個(gè)什么都沒(méi)有的Demo所以覺(jué)得簡(jiǎn)單,要是一個(gè)真實(shí)的項(xiàng)目,我感覺(jué)肯定要有很多坑,別的先不說(shuō),一個(gè)項(xiàng)目那么多依賴(lài)關(guān)系,我這javac要搞死人。
最后如果有不對(duì)的地方,希望有大佬能夠指出,畢竟能運(yùn)行也不能證明完全沒(méi)問(wèn)題。然后我使用的build-tools是28的,不敢保證其它版本包括以后版本的玩法都一樣。
第一:使用apktool直接反編譯apk
第二:apk中包含的內(nèi)容
第三:進(jìn)入到hellodemo\smali\com\example\hello,打開(kāi)MainActivity.smali。找到:
const-string v1, "\u4f60\u597d",
修改為:
const-string v1, "hello",
第四:然后在命令行輸入:apktool b hellodemo hellodemo1.apk。這回重新打包成hellodemo1.apk。
第五:然后給新生成的apk進(jìn)行簽名。把這個(gè)apk拷貝到autosign的目錄下面,然后切換過(guò)去,在命令行輸入:java -jar signapk.jar testkey.x509.pem testkey.pk8 hellodemo1.apk hellodemo.apk。
第六:把生成的hellodemo.apk安裝到手機(jī),可以看到主界面上已經(jīng)顯示的是hello,而不再是你好。說(shuō)明反編譯重新打包成功!
[img]下載附件解壓在桌面,打開(kāi)桌面Android lollipop special文件夾里點(diǎn)擊Android lollipop special.bat文件輸入apktool回車(chē)測(cè)試apktool可用性 提取ROM里的框架和ui 放在桌面Android lollipop special文件夾里點(diǎn)擊Android lollipop special.bat文件輸入apktool if framework-res.apk回車(chē)加載框架完成 反編譯ui打開(kāi)桌面Android lollipop special文件夾里點(diǎn)擊Android lollipop special.bat文件輸入apktool d SystemUI.apk回車(chē)反編譯完成 回編譯ui打開(kāi)桌面Android lollipop special文件夾里點(diǎn)擊Android lollipop special.bat文件輸入apktool b SystemUI回車(chē)回編譯完成