1. 简介
将apk文件解压后有两部分文件需要处理,一种是xml文件,另一种一个dex文件(.dex),我们可以从.dex文件中得到.class,利用后者再得到大家垂涎已久的java文件。
对这三种格式的文件进行反编译处理的方法如下:
2) 从dex到class:公认dex2jar.bat,实现反编译;公认的强者;
3) 而class到java的方式要更多样化一些,因为只是查看反编译后的代码:jd-gui(推荐),Jodeclipse(Jode的Eclipse插件),JadClipse(Jad的Eclipse插件)。
2. 常用工具
2.1 dex2jar及实例
下载:http://code.google.com/p/dex2jar/downloads/list,相关文档。
功能:可用于修改apk的代码,详细功能如下:
• 把dex转换为jar
• 修改jar中的.class文件
• 把jar转换为dex,且放回apk中
• 签名apk
其实例如下所示:
2.1.1 创建一个apk
android create project --name test_apk --path test_apk --package a.b --activity Main --target 1
cd test_apk
ant debug
cd bin
test_apk/bin/test_apk-debug.apk便是我们将要修改的apk
2.1.2 把apk转换为可修改的格式(jasmin)
我们不能直接修改.jar(或.class)文件。dex2jar可把.class或.jar文件转换为jasmin文件。所以可把apk转换为jar文件,然后反编译它。其执行命令如下:
# convert classes.dex in test_apk-debug.apk to test_apk-debug_dex2jar.jar
d2j-dex2jar.sh -f -o test_apk-debug_dex2jar.jar test_apk-debug.apk
# verify jar
d2j-asm-verify.sh test_apk-debug_dex2jar.jar
# convert to jasmin format
d2j-jar2jasmin.sh -f -o test_apk_jasmin test_apk-debug_dex2jar.jar
2.1.3 编辑test_apk_jasmin/a/b/Main.j 以输出log信息
修改之前的Main.j:
.bytecode 50.0
.class public synchronized a/b/Main
.super android/app/Activity
.method public <init>()V
aload 0
invokespecial android/app/Activity/<init>()V
return
.limit locals 1
.limit stack 1
.end method
.method public onCreate(Landroid/os/Bundle;)V
aload 0
aload 1
invokespecial android/app/Activity/onCreate(Landroid/os/Bundle;)V
aload 0
ldc_w 2130903040
invokevirtual a/b/Main/setContentView(I)V
return
.limit locals 2
.limit stack 2
.end method
修改之后的Main.j:
.bytecode 50.0
.class public synchronized a/b/Main
.super android/app/Activity
.method public <init>()V
aload 0
invokespecial android/app/Activity/<init>()V
return
.limit locals 1
.limit stack 1
.end method
.method public onCreate(Landroid/os/Bundle;)V
aload 0
aload 1
invokespecial android/app/Activity/onCreate(Landroid/os/Bundle;)V
aload 0
ldc_w 2130903040
invokevirtual a/b/Main/setContentView(I)V
ldc "TESTAPK"
ldc "*********HI only for test***********"
invokestatic android/util/Log/d(Ljava/lang/String;Ljava/lang/String;)I
pop
return
.limit locals 2
.limit stack 2
.end method
即增加了以下四行代码:
ldc "TESTAPK"
ldc "*********HI only for test***********"
invokestatic android/util/Log/d(Ljava/lang/String;Ljava/lang/String;)I
pop
其对应的源码为(in Main.java):
package a.b;
import android.app.Activity;
import android.os.Bundle;
//import android.util.Log;
public class Main extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("TESTAPK","*********HI only for test***********"); // 对应上面的4行代码
}
}
2.1.4 重新生成apk包
# build jar
d2j-jasmin2jar.sh -f -o test_apk_jasmin.jar test_apk_jasmin/
# verify jar
d2j-asm-verify.sh test_apk_jasmin.jar
# convert to dex
d2j-jar2dex.sh -f -o classes.dex test_apk_jasmin.jar
# make a copy
cp test_apk-debug.apk test_apk-debug-toast.apk
# replace classes.dex in test_apk-debug-toast.apk
zip -r test_apk-debug-toast.apk classes.dex
# sign the apk
d2j-apk-sign.sh -f -o test_apk-debug-toast-signed.apk test_apk-debug-toast.apk
2.1.5 运行apk包
# uninstall previously apk
adb uninstall a.b
# install
adb install test_apk-debug-toast-signed.apk
# start main activity
adb shell am start -n a.b/.Main
以上命令都在Linux环境下执行,若需要在Windows环境下运行,命令需要做做下修改:
1) 把命令的.sh后缀修改为.bat后缀
2) 把zip修改为winRAR或winZIP
2.2 JD-GUI
下载:http://java.decompiler.free.fr/?q=jdgui
功能:JD-GUI是一个独立的图形工具,它可显示“.class”和“.jar”文件的Java源代码。您可以浏览被重构的源代码并访问方法和字段。其界面如下图所示:
2.3 AXMLPrinter2.jar
下载:http://code.google.com/p/android4me/downloads/list
功能:把Android二进制XML文件转换为可读的XML文件
使用方法:java -jar AXMLPrinter2.jar AndroidManifest.xml > AndroidManifest-r.xml
2.4 apktool
下载:http://code.google.com/p/android-apktool/downloads/list
功能:它是一个用于逆向分析第三方的二进制Android应用。它可以把资源(.xml, .dex等)分解为接近原来的形式,在修改之后可以重新生成应用;且可以一步一步地调试smali代码。
使用方法:
1) apktool d (要反编译的文件) (输出文件夹)
如:apktool d test.apk test #反编译 test.apk到文件夹test
或 apktool.bat d -f test.apk test
2) apktool b (目标文件夹)
从目标文件夹中重建APK,生成的APK在"目标文件夹"\dist文件夹里,叫out.apk。
这个out.apk是没有签名的,需要进行签名。
它把.dex转换为一系统的.smali(Java汇编)代码。
参考:http://shazhuzhu1.iteye.com/blog/1415328
http://blog.csdn.net/android_tutor/article/details/5724435
http://www.cnblogs.com/dartagnan/archive/2011/03/24/2003437.html