實(shí)驗(yàn)環(huán)境:
windows + jdk1.6
需要的工具:
1).反編譯包apktool.jar? https://code.google.com/p/android-apktool/downloads/list
2).aapt.exe apktool.bat? https://code.google.com/p/android-apktool/downloads/list
3).顯示源代碼工具( java)JD-GUI http://jd.benow.ca/
4).keytool 和 jarsigner
5).將classes.dex轉(zhuǎn)成jar文件 dex2jar? https://code.google.com/p/dex2jar/
一.看android的源代碼
1)將Apkd.apk 用zip解壓后撬呢,出現(xiàn)了一個classes.dex文件
2014/02/19? 19:42? ? <DIR>? ? ? ? ? .
2014/02/19? 19:42? ? <DIR>? ? ? ? ? ..
2014/02/19? 15:35? ? ? ? ? ? 1,656 AndroidManifest.xml
2014/02/19? 15:35? ? ? ? ? 687,024 classes.dex
2014/02/19? 15:49? ? <DIR>? ? ? ? ? META-INF
2014/02/19? 15:49? ? <DIR>? ? ? ? ? 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.15>dex2jar.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所在的目錄會出現(xiàn) classes_dex2jar.jar 文件。
3) 用JD-GUI對jar包進(jìn)行查看魂拦,可以查看源文件
二.反編譯apk
1.在 下載 APKTOOL中的三個文件(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? ? <DIR>? ? ? ? ? build
2014/02/19? 17:16? ? <DIR>? ? ? ? ? res
2014/02/19? 17:16? ? <DIR>? ? ? ? ? smali
此時我可以查看原文件AndroidManifest.xml了,也是查看smali源文件(是用smali語言寫的借尿,可以對照java看)。
三.APKTOOL的使用
1).decode
該命令用于進(jìn)行反編譯apk文件,一般用法為
apktool d <file.apk> <dir>
<file.apk>代表了要反編譯的apk文件的路徑路翻,最好寫絕對路徑狈癞,比如C:\MusicPlayer.apk
<dir>代表了反編譯后的文件的存儲位置,比如C:\MusicPlayer
如果你給定的<dir>已經(jīng)存在茂契,那么輸入完該命令后會提示你蝶桶,并且無法執(zhí)行,需要你重新修改命令加入-f指令
apktool d –f <file.apk> <dir>
這樣就會強(qiáng)行覆蓋已經(jīng)存在的文件
2).build
該命令用于編譯修改好的文件掉冶,一般用法為
apktool b <dir>
這里的<dir>就是剛才你反編譯時輸入的<dir>(如C:\MusicPlayer),輸入這行命令后真竖,如果一切正常,你會發(fā)現(xiàn)C:\MusicPlayer內(nèi)多了2個文件夾build和dist厌小,其中分別存儲著編譯過程中逐個編譯的文件以及最終打包的apk文件恢共。
3).install-framework
該命令用于為APKTool安裝特定的framework-res.apk文件,以方便進(jìn)行反編譯一些與ROM相互依賴的APK文件璧亚。具體情況請看常見問題
四.smali與java源碼對照讨韭,并做出相應(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;
}
}
對應(yīng)的smali源代碼:
.class public Lali/text/apkd/MainActivity;
.super Landroid/app/Activity;
.source "MainActivity.java"
# direct methods
.method public constructor <init>()V
? ? .locals 0
? ? .prologue
? ? .line 8
? ? invoke-direct {p0}, Landroid/app/Activity;-><init>()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
通過對比可以看到,常量是沒有必變的癣蟋,可以根據(jù)的smali的語法透硝,進(jìn)行相應(yīng)的修改
五.3、打包疯搅、簽名和安裝修改后的apk
修改完了濒生,就可以打包回apk了。執(zhí)行以下命令:
apktool b decode_dir
在mygame目錄下的dist在會看到打包好的apk幔欧。
當(dāng)然罪治,現(xiàn)在一般是無法安裝的,因?yàn)閍pk還沒有簽名琐馆。下面就來簽名规阀。簽名需要keystore文件,我已經(jīng)有專用的keystore了瘦麸,如果還沒有谁撼,請參閱這里進(jìn)行生成。
執(zhí)行以下命令為重新編譯的my_game.apk簽名:
jarsigner -verbose -keystore demo.keystore Apkd.apk demo.keystore
最后滋饲,在安裝到手機(jī)前厉碟,需要把手機(jī)中的已有版本先卸載,因?yàn)槿绻灻煌犁裕遣荒芨采w安裝的箍鼓,會提示“應(yīng)用程序未安裝”錯誤。
完整的運(yùn)行情況如下:
D:\developer\tools\test_apk\new\decode\dist>keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore
輸入keystore密碼:
再次輸入新密碼:
您的名字與姓氏是什么呵曹?
? [Unknown]:? rao
您的組織單位名稱是什么款咖?
? [Unknown]:? rao
您的組織名稱是什么何暮?
? [Unknown]:
您所在的城市或區(qū)域名稱是什么?
? [Unknown]:
您所在的州或省份名稱是什么铐殃?
? [Unknown]:
該單位的兩字母國家代碼是什么
? [Unknown]:
CN=rao, OU=rao, O=Unknown, L=Unknown, ST=Unknown, C=Unknown 正確嗎海洼?
? [否]:? y
輸入<demo.keystore>的主密碼
? ? ? ? (如果和 keystore 密碼相同,按回車):
D:\developer\tools\test_apk\new\decode\dist>jarsigner -verbose -keystore demo.keystore Apkd.apk demo.keystore
輸入密鑰庫的口令短語:
? 正在添加: 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可以正常的安裝了坏逢,不過,在安裝之前赘被,必須要先卸載以前的apk是整,不能直接替換(因?yàn)楹灻灰粯樱?/p>
參考 這里 http://developer.android.com/tools/publishing/app-signing.html
六.常見的問題
參考 這里吧,貌似比較不錯
七.參考文檔
apktool反編譯詳細(xì)使用教程 http://bbs.lidroid.com/forum.php?mod=viewthread&tid=102159
APKTOOL的使用心得 http://www.cnblogs.com/CuriosityWzk/archive/2012/01/06/2315150.html
Signing Your Applications http://developer.android.com/tools/publishing/app-signing.html
Smali--Dalvik虛擬機(jī)指令語言-->【android_smali語法學(xué)習(xí)一】 http://blog.csdn.net/wdaming1986/article/details/8299996
Android中的簽名機(jī)制 http://wenku.baidu.com/link?url=dLZZuD8yYUXHpkb97XLW9TMJWGpe05_l2TAV7Hxy_mVwHwQ4A57x-aRUYgk1bl6ybaBZwy9NhUI_96ubEg9oehTLkTfNaVlRHsTp4ZYjx-W
http://code.google.com/p/android-apktool/wiki/FrameworkFiles