1、Google Android 平台选择了 Java Dalvik VM 的方式使其程序很容易破解和被修改,首先 APK 文件其实就是一个 MIME 为 ZIP 的压缩包,我们修改 ZIP 后缀名方式可以看到内部的文件结构,类似 Sun JavaMe 的 Jar 压缩格式一样,不过比较去别的是 Android 上的二进制代码被编译成为 Dex 的字节码,所有的 Java 文件最终会编译进该文件中去,作为托管代码既然虚拟机可以识别,那么我们就可以很轻松的反编译。所有的类调用、涉及到的方法都在里面体现到,至于逻辑的执行可以通过实时调试的方法来查看,当然这需要借助一些我们自己编写的跟踪程序。Googl
2、e 最然在 Android Market 上设置了权限保护 app-private 文件夹的安全,但是最终我们使用修改定值的系统仍然可以获取到需要的文件。一、dexdump 方法 dexdump 是 emulator 自带提供的查看 dex 文件的工具,可使用类似这样的命令将 dex 文件 dump 到 txt 文件中:D:Program Filesandroid-sdk-windows-1.6_r1platformsandroid-1.6toolsdexdump.exe -d classes.dex spk.dump.txt得到的文件内容,描述了类的信息,但是不怎么好阅读二、AXMLPrin
3、ter2.jar + baksmali.jar + smali.jar 方法 这个方法就强大了,AXMLPrinter2 是还原 AndroidManifest.xml 和main.xml 的工具,直接打开这两个 xml 文件是乱码,而通过还原之后,可以很明白的看到里面的内容(我猜测还是使用了字节异或的方式加的密)。baksmali.jar 是反解析 dex 的工具,smali.jar 则是再还原成 dex 的工具操作方式如下: 1. 1、java -jar AXMLPrinter2.jar D:playAndroidManifest.xml AndroidManifest.txt2. 2、j
4、ava -jar AXMLPrinter2.jar D:playreslayoutmain.xml main.txt3. 3、java -jar baksmali-1.2.5.jar -o classout/ d:playclasses.dex复制代码baksmali 可解析(注意,是解析,不是反编译)原 java 包以及引用的 lib 包,解析出的文件认真看还是能看懂,比如以下片段: 1.2.3. view plaincopy to clipboardprint?4. .class Lcom/paul/test/a; 5. .super Landroid/view/View; 6. 7. #
5、 static fields 8. .field private static final a:Landroid/graphics/Typeface; 9. 10.# instance fields 11field private b:I 12field private c:I 13field private d:Z 14field private e:J 15field private f:I 16field private l:Ljava/lang/String; 17. 18.# direct methods 19method static constructor ()V 20. .re
6、gisters 2 21. sget-object v0, Landroid/graphics/Typeface;-SANS_SERIF:Landroid/graphics/Typeface; 22. const/4 v1, 0x0 23. invoke-static v0, v1, Landroid/graphics/Typeface;-create(Landroid/graphics/Typeface;I)Landroid/graphics/Typeface; 24. move-result-object v0 25. sput-object v0, Lcom/wiyun/ad/a;-a:
7、Landroid/graphics/Typeface; 26. return-void 27end method 28.# 29.# other methods 30.# 31.# virtual methods 32method public onKeyUp(ILandroid/view/KeyEvent;)Z 33. .registers 4 34. const/16 v0, 0x42 35. if-eq p1, v0, :cond_8 36. const/16 v0, 0x17 37. if-ne p1, v0, :cond_b 38. :cond_8 39. invoke-direct
8、 p0, Lcom/paul/test/a;-d()V 40. :cond_b 41. const/4 v0, 0x0 42. invoke-virtual p0, v0, Lcom/paul/test/a;-setPressed(Z)V 43. invoke-super p0, p1, p2, Landroid/view/View;-onKeyUp(ILandroid/view/KeyEvent;)Z 44. move-result v0 45. return v0 46end method 47class Lcom/paul/test/a;48super Landroid/view/Vie
9、w;49.50.# static fields51field private static final a:Landroid/graphics/Typeface;52.53.# instance fields54field private b:I55field private c:I56field private d:Z57field private e:J58field private f:I59field private l:Ljava/lang/String;60.61.# direct methods62method static constructor ()V63. .registe
10、rs 264. sget-object v0, Landroid/graphics/Typeface;-SANS_SERIF:Landroid/graphics/Typeface;65. const/4 v1, 0x066. invoke-static v0, v1, Landroid/graphics/Typeface;-create(Landroid/graphics/Typeface;I)Landroid/graphics/Typeface;67. move-result-object v068. sput-object v0, Lcom/wiyun/ad/a;-a:Landroid/g
11、raphics/Typeface;69. return-void70end method71.#72.# other methods 73.#74.# virtual methods75method public onKeyUp(ILandroid/view/KeyEvent;)Z76. .registers 477. const/16 v0, 0x4278. if-eq p1, v0, :cond_879. const/16 v0, 0x1780. if-ne p1, v0, :cond_b81. :cond_882. invoke-direct p0, Lcom/paul/test/a;-
12、d()V83. :cond_b84. const/4 v0, 0x085. invoke-virtual p0, v0, Lcom/paul/test/a;-setPressed(Z)V86. invoke-super p0, p1, p2, Landroid/view/View;-onKeyUp(ILandroid/view/KeyEvent;)Z87. move-result v088. return v089end method90.复制代码认真一看,就知道:# static fields 定义静态变量的标记# instance fields 定义实例变量的标记# direct meth
13、ods 定义静态方法的标记# virtual methods 定义非静态方法的标记以 onKeyUp 方法为例,其中定义了处理逻辑,if-eq p1, v0, :cond_8 表示如果 p1 和 v0 相等,则执行 cond_8 的流程: 1.2. :cond_83. invoke-direct p0, Lcom/paul/test/a;-d()V4.复制代码调用 com.paul.test.a 的 d()方法不相等: if-ne p1, v0, :cond_b 则执行 cond_b 的流程: 1.2. :cond_b3. const/4 v0, 0x04.5. invoke-virtual
14、p0, v0, Lcom/paul/test/a;-setPressed(Z)V6.7. invoke-super p0, p1, p2, Landroid/view/View;-onKeyUp(ILandroid/view/KeyEvent;)Z8.9. move-result v010.复制代码大概意思就是调用 com.paul.test.a 的 setPressed 方法,然后再调用父类 View 的 onKeyUp 方法最后 1. return v0复制代码该方法,能把外部引用的 lib 包类也解析出来,能开到包的全貌。缺点在于,解析出的 smali 文件并不是反编译出的 java 文
15、件,可读性降低了,但仔细研究也能看出大概。三、dex2jar + XJad 方法一、反编译 Apk 得到 Java 源代码首先要下载两个工具:dex2jar 和 JD-GUI前者是将 apk 中的 classes.dex 转化成 Jar 文件,而 JD-GUI 是一个反编译工具,可以直接查看 Jar 包的源代码。以下是下载地址:本帖隐藏的内容dex2jar:http:/ apk 文件,将后缀改为 zip,解压,得到其中的 classes.dex,它就是 java 文件编译再通过 dx 工具打包而成的;解压下载的 dex2jar,将 classes.dex 复制到 dex2jar.bat 所在目
16、录。在命令行下定位到 dex2jar.bat 所在目录运行dex2jar.bat classes.dex生成classes.dex.dex2jar.jar生成 jar 文件的截图如下:运行 JD-GUI(jd-gui.exe),打开上面生成的 jar 包,即可看到源代码了HelloAndroid 源码(编译前的 apk 源码对照)如下:二、反编译 apk 生成程序的源代码和图片、XML 配置、语言资源等文件如果是只是汉化软件,这将特别有用。首先还是下载工具,这次用到的是 apktool下载地址: 本帖隐藏的内容http:/ 和 apktool-install-windows-r04-brut1
17、.tar.bz2(两个包都下载)具体步骤:将下载的两个包解压到同一个文件夹下,应该会有三个文件:aapt.exe,apktool.bat,apktool.jar在命令行下定位到 apktool.bat 文件夹,输入以下命令: apktool d C:*.apk C:*文件夹,如下图:命令行解释:apktool d apk 文件 输出文件夹反编译的文件如下(AndroidManifest.xml 为例):特别注意:你要反编译的文件一定要放在 C 盘的根目录里将反编译完的文件重新打包成 apk,很简单,输入 apktool b c:*文件夹(你编译出来文件夹)即可,命令如下:打包 apk 后的文件在目录 C:HelloAndroid 下,生成了两个文件夹:builddist其中,打包生成的 HelloAndroid.apk,在上面的 dist 文件夹下,Ok