android反编译集锦

反编译apk工具

目前有几种工具:

  • smali
  • dedexer
  • dexdump
  • apktool
  • dex2jar and jd
  • AXMLPrinter2.jar

关于smali的使用,请参考jserv的http://jserv.blogspot.com/2010/05/android.html

 把 classes.dex 反编译成 jar, 然后用 jd 查看
 java 对照着 smail 就容易些了
 (反编译出来的 java, 编译不回去 只能看看)

dexdump功能比较弱,且麻烦,就不讨论介绍了。

解压apk

这里拿com.himsn.apk 做例子,apk包其实是一个zip文件,把它重命名,然后解压

 mv com.himsn.apk com.himsn.zip
 unzip com.himsn.zip

得到一驼的东西:

.
├── AndroidManifest.xml
├── classes.dex
├── META-INF
│   ├── ALIAS_NA.RSA
│   ├── ALIAS_NA.SF
│   └── MANIFEST.MF
├── res
│   ├── anim
│   │   ├── cycle_7.xml
│   │   └── shake.xml
│   ├── drawable
│   │   ├── avatar_unknown.png
│   │   ├── ...
│   │   ├── button_choose_contact.xml
│   │   ├── typing4.png
│   │   └── typing.xml
│   ├── layout
│   │   ├── add_contact.xml
│   │   ├── ...
│   │   └── two_line_list_item.xml
│   ├── menu
│   │   ├── choose_contact_offline.xml
│   │   ├── choose_contact.xml
│   │   └── main.xml
│   ├── raw
│   │   ├── key_char.jpg
│   │   ├── key_num.jpg
│   │   ├── ...
│   │   ├── key_pressed_right.png
│   │   └── winks.png
│   └── xml
│       └── preferences.xml
└── resources.arsc

目录下三个文件两个文件夹,一一来说

[deli@athena himsn]$ ls -p
AndroidManifest.xml  classes.dex  META-INF/  res/  resources.arsc

AndroidManifest.xml

这个没必要解释了,不过用vim打开,都是乱码,看看这是什么文件类型的:

[deli@athena himsn]$ file AndroidManifest.xml
AndroidManifest.xml: DBase 3 data file (4256 records)

除了这个,还有layout目录下的二进制xml文件,可以使用AXMLPrinter工具将其转换为可读的xml文件,工具下载地址:http://code.google.com/p/android4me/downloads/list, 使用很简单:

java -jar AXMLPrinter2.jar AndroidManifest.xml AndroidManifest2.xml

很多xml一个个转化很麻烦,这样的工作,当然是用shell完成了。

$ cd res
$  for file in */*.xml; do java -jar AXMLPrinter2.jar $file > temp; echo $file; mv temp $file -f; done

AndroidManifest2.xml的内容如下:(省略一部分)

<?xml version="1.0" encoding="utf-8"?>
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:versionCode="210"
	android:versionName="2.1.0"
	package="com.himsn"
	>
	<uses-sdk
		android:minSdkVersion="2"
		>
	</uses-sdk>
	<uses-permission
		android:name="android.permission.READ_PHONE_STATE"
		>
	</uses-permission>
	<application
		android:label="@7F080000"
		android:icon="@7F02002A"
		>
		<activity
			android:label="@7F080000"
			android:name=".ChooseContactActivity"
			android:launchMode="2"
			android:configChanges="0x000000E0"
			>
			<intent-filter
				>
				<action
					android:name="android.intent.action.MAIN"
					>
				</action>
				<category
					android:name="android.intent.category.LAUNCHER"
					>
				</category>
			</intent-filter>
		</activity>
		<activity
			android:theme="@7F090001"
			android:label="@7F080004"
			android:name=".AuthReqActivity"
			android:configChanges="0x000000E0"
			>
		</activity>
		<meta-data
			android:name="ADMOB_PUBLISHER_ID"
			android:value="a149c8f51949be3"
			>
		</meta-data>
	</application>
</manifest>

感觉还行,但是像 android:label="@7F080000" android:icon="@7F02002A"

@7F080000这个神秘的东西,是什么意思呢? 下面会有提到。

classes.dex

目前反编译classes.dex比较好的工具是 Dedexer,可以下载已经编译好的jar文件 ddx1.11.jar.

mkdir src
java -jar ddx1.11.jar --help
java -jar ddx1.11.jar -o -D -r -d src classes.dex

然后在src目录下,又生成一坨东西。

注意: ddx1.11.jar 对应java 1.6版本,我用 1.5.0_18,就会遇到

[deli@athena tools-common]$ java -jar ddx1.11.jar
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file

也可以下载源代码自行编译。

进入 src/com/himsn 目录

[deli@athena himsn]$ grep -i 7F080000 *

R$string.ddx:.field public static final app_name I = 2131230720 ; 0x7f080000

好家伙,回前面提到的 @7F080000,原来在 R$string。其他xml文件出现神秘的字符,grep 一下,就出来了。 xml还有其他神秘数字, 比如

<ImageView>
android:scaleType="3"

这个3是啥意思? 开始我是用最原始的方式,我深信,一切尽在ApiDemos中,结果在ApiDemos的反编译文件里grep,一般80%都可以找到,然后跟源代码对 比,就出来了。

android:scaleType="3" 就是android:scaleType="fitCenter" 类似的

| android:scaleType="7"| android:scaleType="centerInside"

android:scaleType="6" android:scaleType="centerCrop"
android:ellipsize="4" android:ellipsize="marquee"
android:ellipsize="3" android:ellipsize="end"

后面发现用eclipse打开xml layout文件,在属性选项里,点击,在下拉菜单,都有相应的数字,从0开始,那么就好办多了。

还有一些情况,比如

android:textColor="?android:01010036" android:textColor="?android:01010212"

这个比较好办,看到有android字样,就知道是系统定义的常量,在android sdk Reference android.R.xxx 页面搜索01010036,找到:

"?android:01010036" 对应 "?android:attr/textColorSecondary" "?android:01010212" 对应 "?android:attr/textColorTertiary"

反编译过两个apk,我都能把xml文件100%还原出来。

解读ddx格式

挑个src/com/himsn/HiMSN.ddx 看看吧。

.class public com/himsn/HiMSN
.super android/app/Activity
.source HiMSN.java

.field public static final ACTIVITY_ONGOING_CONTACTS I = 112	; 0x70
.field public static final ACTIVITY_WINKS I = 113	; 0x71
.field private static final TAG Ljava/lang/String; = "IMEasy"
.field private final mFilter Landroid/content/IntentFilter;
.field private mManager Lcom/shiyansucks/imeasy/manager/IMMgr;
.field mMenu Landroid/view/Menu;
.field private final mReceiver Landroid/content/BroadcastReceiver;

.method public <init>()V
.limit registers 3

.line 41
	invoke-direct	{v2},android/app/Activity/<init>	; <init>()V

.line 43
	new-instance	v0,com/himsn/HiMSN$1

....

真是难懂! 没关系,Gabor Paller为我们整理好了 Dalvik opcodes 文档,对照一下,记住常用的,慢慢研读,会有一番风景,enjoy!

学习ddx格式最简单的方法,就是把现成的代码编译成apk的,再用反编译工具弄出ddx格式文件,代码与ddx文件对照阅读,一目了然。这段时间 花了不少时间去研读ddx,或多或少做一些笔记,零零散散,再补充一下。

行首为 ".field" 字段的,是类变量。 grep "\.field" xxx.ddx ,列出所有的变量。

行首为 ".method " 字段的,是成员函数 grep "\..method " xxx.ddx ,列出所有的成员函数。

 88     if-eqz  v1,l2d9da
 89 ; v1 : single-length
 90 .line 482
 91     new-instance    v0,android/content/Intent
 92 ; v0 : Landroid/content/Intent;
 93     invoke-direct   {v0},android/content/Intent/<init>  ; <init>()V
 94 ; v0 : Landroid/content/Intent;
 95 l2d9ca:

上面的条件是这样的:

 if (v != 0) {
	 intent = new Intent(); // intent 在该代码段上边有定义过。
 } else {
	 // l2d9ca:
 }

if 里的判断顺序正好相反。

基本的数据类型

 Long => Long
 J => long
 I => int
 V => void
 Z => boolean 

Android 反编译方法的总结

ps:对于软件开发人员来说,保护代码安全也是比较重要的因素之一,不过目前来说Google Android平台选择了Java Dalvik 
VM的方式使其程序很容易破解和被修改,首先APK文件其实就是一个MIME为ZIP的压缩包,我们修改ZIP后缀名方式可以看到内部的文件结构,类似
Sun 
JavaMe的Jar压缩格式一样,不过比较去别的是Android上的二进制代码被编译成为Dex的字节码,所有的Java文件最终会编译进该文件中
去,作为托管代码既然虚拟机可以识别,那么我们就可以很轻松的反编译。所有的类调用、涉及到的方法都在里面体现到,至于逻辑的执行可以通过实时调试的方法
来查看,当然这需要借助一些我们自己编写的跟踪程序。Google最然在Android 
Market上设置了权限保护app-private文件夹的安全,但是最终我们使用修改定值的系统仍然可以获取到需要的文件。

    总结反编译主要的目的在于学习。利用反编译进行相关的汉化或修改,还是尽量不要吧,毕竟人家写个程序不容易啊!

    我目前接触的反编译的方法总共有三种,分别如下:

    1.  第一种反编译的方法主要是利用模拟器自带的一个dexdump。

       具体如下面的介绍:

       反编译一个.apk文件,需要做以下几步:1) 找到.apk安装文件   2)找到安装软件的*.dex文件    3)dump dex文件    4)分析dex文件获取想要的代码

       一、找到apk安装文件这个比较容易,把手机或者模似器安装好后,可以在eclipse的File Explorer下找到安装程序的apk译文件,也可以通过adb命令找到:

                      $ adb shell

                      # cd /system/app

                      cd /system/app

                      # ls


       二、找到安装软件的*.dex文件运行安装软件后,会在android文件系统下生成一个*.dex文件,一般在目录/data/dalvik- cache下,也可以通过adb命令找到:
                     $ adb shell

                     # cd /data/dalvik-cache

                     cd /data/dalvik-cache

                     # ls

        (注意:一般来说,如果你能够通过File Exploere找到data/dalvik-cache文件,其实一二两个步骤可以跳过,直接进入adb  shell后执行第三步;命令行中直         接输入adb shell后执行的前提是你已经在系统的环境变量中配置了tools文件,否则你得先cd到tools文件中执行adb.exe后才能执行以后的命令。另 外你得确           保自己的虚拟机中安装了应用程序才能进行下一步的操作。对于系统自带的程序,我也试了进行反编译,结果输出的txt没有具体内容,没有成功。有兴趣的             话,大家可以试一下。)

            
        三、编译软件对应的dex文件,通过以下指令:
                #dexdump -d -f -h /data/dalvik-cache/data@[email protected][email protected] > ophone.text
                指令参数解释:-d : disassemble code sections

                                    -f : display summary information from file header

                                    -h : display file header details

                                    -C : decode (demangle) low-level symbol names

                                    -S : compute sizes only

        这执行完了后,大家应该可以在dalcik-cache文件夹下找到ophone.txt文件。如果没有的话,可以重新启动虚拟 器。 之后我们可以将该txt文件导出到桌面上进行相关操作。(File Explorer中的按钮)

          四、 获取需要的代码:打开刚才得到的编译出来的text文件,会看到形如以下的代码:      

 

                   总体来看,这种反编译的效果不太理想。

    第二种是:通过dex2jar工具进行反编译。(dex2jar:http://code.google.com/p/dex2jar/downloads/list    查看Jar包的GUI工具:http://java.decompiler.free.fr/?q=jdgui

    

   

    反编译步骤:

    1、下载一个.apk程序安装包,将其文件名*.apk改为*.rar后进行解压。我这儿是将南方周末的读报器进行反编译的。
   
    2、 把其中的class.dex拷贝到dex2jar.bat所在目录。运行dex2jar.bat   class.dex,将会在其文件夹下生成classes.dex.dex2jar.jar。
    3、可以将jar文件重新命名后拷贝到GUI文件夹下,运行JD-GUI工具(它是绿色无须安装的),打开上面的jar文件,即可看到源代码。

         与第一种方法相比较,该方法生成的文件全面,代码整齐,虽然有些中文会出现乱码,id等全部是数字代替,但整体结构很完整,不 错。
   类似的工具还有Dedexerhttp://sourceforge.net/projects/dedexer/files/

   具体的应用代码为(先进入jar包所在路径):

    java -jar ddx.jar -d  <directory>  <dex file>
   可以再其中加入-o,这样可以生成一个介绍文件内部结构的日志文件。

    第三种:网上还流传着这样一种用smali工具的方法(http://code.google.com/p/smali/downloads/list):

        反编译命令  java -jar baksmali-1.2.jar  <dex文件>  -o  <新生成的文件名>

        重新编译     java -jar  smali-1.2.jar <需编译文件夹>

       本人亲自实践了一下,确实新版本的baksmali可以直接对.apk文件进行直接的反编译。


   但是这种方法生成的文件也不是很好。

     说到这儿,对于xml的文件的编译,需要工具AXMLPrinter2.jar(http://code.google.com/p/android4me/downloads/list)。 具体的使用方法,与上面的差不多,可以运用命令      java -jar AXMLPrinter2.jar main.xml > main.txt  进行相关的操作。大家可以参照这位仁兄的(http://hi.baidu.com/linrw/blog/item/cc3afd2233ab88a94723e878.html

 

查看全部评论(0)我来说两句
 

你可能感兴趣的:(java,android,File,jar,工具,反编译工具)