现在的位置: 首页 > 综合 > 正文

Android 反编译资料

2013年10月09日 ⁄ 综合 ⁄ 共 14043字 ⁄ 字号 评论关闭

一、反编译流程图

                 

二、工具使用方法(命令)

准备工作

假设我的工作目录为 $AndroidDecompile ,首先要将 system.img 中(或者说从源码中编译好的)几个重要的 odex 文件拷贝到工作目录中,他们是: core.odex, ext.odex, framework.odex, android.policy.odex, services.odex (也可以放在别的目录,通过设置BOOTCLASSPATH 指定,默认就是当前目录,关于 BOOTCLASSPATH 请参考 baksmali 的帮助信息)。

 

下载以下工具到 $AndroidDecompile 中:

Baksmali :

http://code.google.com/p/smali/downloads/list

 

Smali :

http://code.google.com/p/smali/downloads/list

 

Dex2jar :

http://code.google.com/p/dex2jar/downloads/list

 

JD-GUI (Java Decompile GUI) :

http://java.deco mpiler.free.fr/?q=jdgui <!--[if !supportNestedAnchors]--> <!--[endif]-->

 

AutoSign :

http://d.download.csdn.net/down/2768910/fjfdszj

 

Apktool

http://code.google.com/p/android-apktool/downloads/list

 

假设我们有一个应用,它的类文件编译后被单独拿了出来,即有两个文件 app.apk  app.odex ,把他们放在 $AndroidDecompile下。

 

1. 使用 baksmali.jar  odex 文件分解为 smali 文件

$ java –jar baksmali-1.2.5.jar –x app.odex

如果成功的话,会在 $AndroidDecompile 下生成一个 out 目录,里面是一些以“ .smali ”为后缀名的文件,在此不深究这些文件的作用。

 

2. 使用 smali.jar  out/ 目录下的 smali 文件转换为 classes.dex

$ java -Xmx512M –jar smali-1.2.5.jar out –o classes.dex

classes.dex 便是 Dalvik VM 所使用的编译后的类文件格式,在正常的 apk 文件里都会有。

 

3. 使用 dex2jar  classes.dex 反编译为 jar 文件

将下载后的 dex2jar 压缩包解压后,里面会有 dex2jar.sh(  dex2jar.bat) 文件,假如 classes.dex 文件与 dex2jar.sh 在同一目录下,使用以下方式将 classes.dex 反编译为 jar 文件:

$dex2jar.bat classes.dex

如果执行成功,则会在当前目录下生成反编译后的文件 classes.dex.dex2jar.jar 

dex2jar 即可以操作 dex 文件,也可以直接操作 apk 文件,它的使用规则为:

dex2jar file1.dexORapk file2.dexORapk ...

 

4. 使用 JD-GUI 查看反编译后的 jar 文件

JD-GUI 是一个可视化的 Java 反编译代码查看器,它可以实时的将 class 文件反编译成 java 文件进行查看。解压下载的 jd-gui 文件,执行目录中的 jd-gui 可执行文件启动,然后加载上一步中反编译好的 classes.dex.dex2jar.jar 文件即可。

 

5. 将从 odex 反编译后的 classes.dex 与其他资源文件重新打包成一个完整的 apk

以上我们假设的情况是应用程序编译后的类文件从 apk 文件中被剥离出来,下面要做的是如何将上述步骤中得到的 classes.dex  apk中的其他文件重新打包成一个可用的 apk 

首先将反编译后的 classes.dex 和原先的 app.apk (不含 classes.dex )重新压缩成一个完整的 app.apk  apk 文件可用压缩工具打开),也就是说将 classes.dex 放进 app.apk 中。

将下载的 AutoSign 文件解压,可以看到有 signapk.jar (还有个 Sign.bat )文件,执行以下命令给 app.apk 文件签名,就可以生成一个可以运行的 apk 文件了。

$ java -jar signapk.jar testkey.x509.pem testkey.pk8 app.apk app_signed.apk

 

6. apktool 的使用

网上还有个工具是 apktool ,可以对 apk 进行解析,反编译资源文件,并将类文件解析成 smali 文件;同时还可以将解析后的文件重新打包成 apk 。功能和以上介绍的几个工具类似,它的使用方法如下:

apktool d app.apk and     反编译 app.apk 到文件夹 and

apktool b app                 从文件夹 app 重建 APK ,输出到 ABC/dist/out.apk

具体的使用方法在此不再赘述,请参考官方网站,或者:

http://www.geeka.net/2010/05/apktool-decode-android-google-code/

 

7. 我的 $AndroidDecompile 目录下的文件的截图

 

 

三、一些工具的帮助信息

1. baksmali 的帮助信息

usage: java -jar baksmali.jar [options] <dex-file>

disassembles and/or dumps a dex file

  -?,--help                                 Prints the help message then exits.

  -b,--no-debug-info                          Specify twice for debug options

                            don't write out debug info (.local,

                                            .param, .line, etc.)

  -c,--bootclasspath <BOOTCLASSPATH>      The bootclasspath jars to use, for

                                           analysis. Defaults to

                                           core.jar:ext.jar:framework.jar:andro

                                           id.policy.jar:services.jar. If the

                                           value begins with a :, it will be

                                           appended to the default

                                           bootclasspath instead of replacing it

  -d,--bootclasspath-dir <DIR>                 The base folder to look for the

                                            bootclasspath files in. Defaults to

                                           the current directory

  -f,--code-offsets                            Add comments to the disassembly

                                           containing the code offset for each address

  -l,--use-locals                              Output the .locals directive with

                                           the number of non-parameter

                                           registers, rather than the .register

  -o,--output <DIR>                           Directive with the total number of  register

                                            the directory where the disassembled

                                            files will be placed. The default is out

  -p,--no-parameter-registers                   Use the v<n> syntax instead of the

                                           p<n> syntax for registers mapped to

                                           method parameters

  -r,--register-info <REGISTER_INFO_TYPES>   Print the specificed type(s) of

                                           register information for each

                                           instruction. "ARGS,DEST" is the

                                           default if no types are specified.

                                           Valid values are:

                                           ALL: all pre- and post-instruction registers.

                                           ALLPRE: all pre-instruction registers

                                            ALLPOST: all post-instruction registers

                                           ARGS: any pre-instruction registers

                                                used as arguments to the instruction

                                            DEST: the post-instruction

                                                destination register, if any

                                           MERGE: Any pre-instruction register

                                                has been merged from more than 1

                                                different post-instruction register

                                                from its predecessors

                                           FULLMERGE: For each register that

                                               would be printed by MERGE, also show

                                              the incoming register types that

                                              were merged

  -s,--sequential-labels                        Create label names using a

                                           sequential numbering scheme per

                                           label type, rather than using the

                                           bytecode address

  -v,--version                                Prints the version then exits

  -x,--deodex                               Deodex the given odex file. This

                                           option is ignored if the input file

                                           is not an odex file

 

2. smali 的帮助信息

usage: java -jar smali.jar [options] [--] [<smali-file>|folder]*

assembles a set of smali files into a dex file

  -?,--help            prints the help message then exits. Specify twice for

                      debug options

  -o,--output <FILE>   the name of the dex file that will be written. The default

                      is out.dex

  -v,--version         prints the version then exits

 

3. auto-sign 的帮助信息

SignApk.jar is a tool included with the Android platform source bundle.

testkey.pk8 is the private key that is compatible with the recovery image included in this zip file

testkey.x509.pem is the corresponding certificate/public key

 

Usage:

java -jar signapk.jar testkey.x509.pem testkey.pk8 update.zip update_signed.zip

 

4. apktool 的帮助信息

Apktool v1.3.2 - a tool for reengineering Android apk files

Copyright 2010 Ryszard Wi?niewski <brut.alll@gmail.com>

Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)

 

Usage: apktool [-v|--verbose] COMMAND [...]

 

COMMANDs are:

 

    d[ecode] [OPTS] <file.apk> [<dir>]

        Decode <file.apk> to <dir>.

 

        OPTS:

 

        -s, --no-src

            Do not decode sources.

        -r, --no-res

            Do not decode resources.

        -d, --debug

            Decode in debug mode. Check project page for more info.

        -f, --force

            Force delete destination directory.

        -t <tag>, --frame-tag <tag>

            Try to use framework files tagged by <tag>.

        --keep-broken-res

            Use if there was an error and some resources were dropped, e.g.:

            "Invalid config flags detected. Dropping resources", but you

            want to decode them anyway, even with errors. You will have to

            fix them manually before building.

    b[uild] [OPTS] [<app_path>] [<out_file>]

        Build an apk from already decoded application located in <app_path>.

 

        It will automatically detect, whether files was changed and perform

        needed steps only.

 

        If you omit <app_path> then current directory will be used.

        If you omit <out_file> then <app_path>/dist/<name_of_original.apk>

        will be used.

 

        OPTS:

 

        -f, --force-all

            Skip changes detection and build all files.

        -d, --debug

            Build in debug mode. Check project page for more info.

 

    if|install-framework <framework.apk> [<tag>]

        Install framework file to your system.

For additional info, see: http://code.google.com/p/android-apktool/

 

 

另外还有一篇文章:

主要目标:对于没有SD卡但想要安装运行那些只有SD卡支持的apk程序的(比如仙剑)。

  次要目标:apk程序反编译、汉化、修改程序的数据读取和保存路径。

  本文针对“思维导图 Thinking Space Pro 2.16”的apk程序ThinkingSpacePro.apk进行修改。题外话,这程序人手配备一个,不错的东西。

一、相关工具(针对windows系统)

二、反编译 

  说要把apk“装冰箱(反编译)”分三步走:

  • 第一步:先把apk程序(这里用ThinkingSpacePro.apk)程序放到 E:/apktool/ 下。
  • 第二步:启动windows的cmd.exe,用命令行cd到 E:/apktool 目录下。
  • 第三步:键入命令
    1. apktool d ThinkingSpacePro.apk

    这个命令的格式 是:

    1. apktool d xxx.apk output

    其中 d 参数用来指示工具要进行反编译操作,xxx.apk是要反编译的程序,output 源码输出 的路径。如果最后不指定输出的路径,默认是放在同目录下的 xxx 文件夹下(即apk程序名称去掉.apk后的名称)。如果你的apk文件名称中有空格,那键入命令时用双引号引起来,不过为方便起见,反编译之前把apk文件名中的空格都去掉先。
    运行反编译命令后会在同级目录下得到一个 ThinkingSpacePro 文件夹,源文件都在里面了。

三、汉化 

  汉化这个比较简单,在反编译apk程序得到源码后,一般程序的文档都放在 res目录下,都是些xml文档,用记事本之类的打开查看一下,一般都会比较容易看出来哪些是可以汉化的文本。这个就不去弄它了。可能不同程序还有不一样 的,反正英语差点,汉化这种事我也不去深究了。你如果只想汉化的话,进res文件夹找找,完成汉化后就可以直接重新编译程序了(最后讲编译),不用太多的 编程知识。思维导图本身支持多国语言(都在源文件的res文件夹里),所以也用不着汉化了。但大致的汉化过程就是这样了。

  另外貌视还有Android ResEdit之类的专用汉化软件 ,不用搞什么反编译,用起来可能更简单。

四、SDcard to Flash 

  对于N5p,app2sd只是一个传说,不过sd2flash下面就可以实现。用SD卡玩机的人可以无视。

  下面这个是本文的重点。目的就是要修改程序的默认数据读取和保存路径,主要针对那些必须有SD卡才能使用的程序。比如说一个游戏它 分为主程序和游戏的关卡数据。主程序可能只有1M,但游戏关卡数据可能是几十甚至上百M,这类游戏一般是主程序安装在内存中,而关卡数据会要求你安装或下 载到SD卡上。如果你没有SD卡,那就玩不成了。我之所以要改它的路径,就是不想让它占我的SD卡,N5p不是自带8G(实际好像只有 6.5G)Flash闪存么,那为什么不用它?下面的修改就是要欺骗apk程序,我们的Flash闪存就是程序你要的SD卡。

  正式修 改时,除了要修改所有源文件(主要是.smali程序源文件)中的/sdcard 路径,使之指向 /flash 外,还要修改含有 Environment.getExternalStorageState 和 Environment.getExternalStorageDirectory 的源文件,前者用于检测是否安装SD卡,后者获取SD卡的路径。

  那么从头来修改思维导图 Thinking Space Pro 2.16的数据读写路径。原版程序你必须要有SD卡才能正常保存你的数据,修改之后,所有数据读取、保存都针对N5p自己的Flash闪存,从而解放SD卡。

  • 用apktool反编译ThinkingSpacePro.apk
    1. apktool d ThinkingSpacePro.apk

    反编译后得到ThinkingSpacePro文件夹,存放着程序源文件。

  • 使用UltraFileSearch搜索ThinkingSpacePro文件夹中所有包含"sdcard"文字的文件(搜索 时,UltraFileSearch去掉"Whole word"的选项)。没有UltraFileSearch可以用windows系统自带的搜索工具,只是要用搜索文件中包含有指定内容的文件,而不是搜索 文件名(我的系统搜索工具坏了,所以用UltraFileSearch这个软件代替)。
  • 对搜索到的文件(主要是其中的.smali程序源文件)用记事本打开编辑,将文件中所有 "/sdcard" 的字串改成 "/flash" 字串,这样将原先指向 /sdcard 的路径全部指向 /flash 路径。
  • 搜索程序中判断SD卡是否安装的方法,修改它使判断SD卡是否安装的方法返回True。一般的检测SD卡是否安装的方法是用下面的代码判断的:
    1. Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

    所以用UltraFileSearch查找包含有"getExternalStorageState"字串的文件。 
    有些软件会用这个检测,有些软件则不用它,所以找不到的话可以窃喜:不用那么复杂了。
    针对思维导图这个程序,在App.smali中会找到(其它程序不一定在这里)。具体查找到的代码如下:

    1. .method public static isSdPresent()Z
    2. .locals 2
    3. .prologue
    4. .line 476
    5. invoke-static {}, Landroid/os/Environment;->getExternalStorageState()Ljava/lang/String;
    6. move-result-object v0
    7. const-string v1, "mounted"
    8. invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
    9. move-result v0
    10. return v0
    11. .end method

    这个是Dalvik opcodes,修改它需要一点专业知识(参考这里 ), 修改成如下(后来发现似乎只需要将最后的 return v0 改成 return 1 就可以了,不过没去做测试,对Dalvik opcodes尚未仔细研究过):

    1. .method public static isSdPresent()Z
    2. .locals 2
    3. .prologue
    4. .line 476
    5. const-string v0, "mounted"
    6. const-string v1, "mounted"
    7. invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
    8. move-result v0
    9. return v0
    10. .end method

    改后因为v0始终等于v1,所以这个方法就返回True,这样就欺骗程序我们已经安装了SD卡了。

  • 搜索程序中获取SD卡路径的方法,修改它使它返回的路径从原来的指向 sdcard 变成 flash,再次欺骗程序我们的 flash 就是我们的 sdcard。一般的获取SD卡路径的方法如下:
    1. Environment.getExternalStorageDirectory

    注意这个方法返回的是一个java.io.File对象,而不是字符串,修改时要注意这一点。所以用UltraFileSearch搜索包 含"getExternalStorageDirectory"的文件(主要是.smali文件),针对思维导图这个程序会搜索到App.smali和 FileIO.smali二个文件,分别打开修改。具体对于App.smali相关内容如下(FileIO.smali也是类似):

    1. .line 246
    2. :cond_0
    3. new-instance v2, Ljava/lang/StringBuilder;
    4. invoke-direct {v2}, Ljava/lang/StringBuilder;->()V
    5. invoke-static {}, Landroid/os/Environment;->getExternalStorageDirectory()Ljava/io/File;
    6. move-result-object v3
    7. invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
    8. move-result-object v2
    9. sget-object v3, Ljava/io/File;->separator:Ljava/lang/String;

    把它修改成如下:

    1. .line 246
    2. :cond_0
    3. new-instance v2, Ljava/lang/StringBuilder;
    4. invoke-direct {v2}, Ljava/lang/StringBuilder;->()V
    5. const-string v3, "/flash"
    6. invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
    7. move-result-object v2
    8. sget-object v3, Ljava/io/File;->separator:Ljava/lang/String;

五、重新编译程序 

  修改完成后,回到cmd.exe窗口,键入重新编译的命令:
  apktool b ThinkingSpacePro 
  第一次编译会出状况,后来发现是源码中的AndroidManifest.xml这个配置文件有问题,在这个文件的倒数第二行:

  1. <supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:resizeable="true" />

  问题就出在那个android:xlargeScreens="true"上,好像不支持吧。所以删掉它,变成:

  1. <supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:resizeable="true" />

  再次重新编译,成功。
  重新编译后,编译输出的apk程序文件保存在 ThinkingSpacePro 子目录下的 dist 文件夹下。
  这时候工作都基本完成了,不过,这个生成的apk程序还不能直接安装使用,因为缺少签名。

六、签名 

  抓鬼用保鲜膜,打鬼用巧克力,签名用Auto-Sign。这个工具的下载和使用方法网上搜吧。我这里不说了,已经出了本文的范围。

   另外像物理空间Space Physic这个游戏的修改方法与此类似,不过它还要简单一点。还有像仙剑,它的修改不用涉及Dalvik opcodes,所以更简单,不过,它的不同点在于还要修改.so文件(.so文件相当于动态连接库dll文件),对.so的修改时用hedit等二进制 编辑工具打开后将 "/sdcard" 替换为 "//flash" 即可。 

  全当抛砖引玉,你可能有不同的目的来修改原程序,不过万变不离其宗,大致如此。

  如果你仍然不知道我上面改来改去到底在改什么,那么可以在你的N5p不插SD卡的情况下安装原版的思维导图这个软件,看能不能正常运行和使用;然后,卸载原版,同样在不插SD卡的情况下,安装我的修改版,看能否正常运行和使用了。

  题外话,仙剑这个程序修改后能运行,但过了几分钟就自动退出,原先以为我修改的有问题,后来拿原版的用SD卡玩,一样没过几分钟就自动退出,网上一搜都有这种情况,所以不是我改的有问题,原本程序移植的就有问题。

  最后提供思维导图和仙剑的Flash版(不需要SD卡即可运行),FLASH_ThinkingSpacePro2.16.apk、FLASH_PAL31.apk。对于仙剑这里只提供主程序,游戏数据用论坛 的那个原版的,把 pal 上传到 N5p的flash闪存中(而不需要SD卡),就是连接电脑 后出现的 "N5 Pro" 的那个磁盘(这个仙剑移植的不咱地,无故自动退出、菜单不支持触摸需要物理按键、分辨率太低造成大大的马赛克等等),安装FLASH_PAL31.apk即可。

  修改程序的下载地址:http://u.115.com/file/t597954474 
  仙剑原版(只用数据):http://bbs.imp3.net/viewthread.php?tid=962491&extra=&highlight=%CF%C9%BD%A3&page=1


抱歉!评论已关闭.