反编译APK文件的三种方法(转)
因为学习Android编程的需要,有时我们需要对网络上发布的应用项目进行学习,可是Android项目一般是通过APK文件进行发布的,我们看不到源代码,嘿嘿,办法总会有的,而且不止一个...
ps:对于软件开发人员来说,保护代码安全也是比较重要的因素之一,不过目前来说Google Android平台选择了Java Dalvik VM的方式使其程序很容易破解和被修改,首先APK文件其实就是一个MIME为ZIP的压缩包,我们修改ZIP后缀名方式可以看到内部的文件结构,类似Sun JavaMe的Jar压缩格式一样,不过比较去别的是Android上的二进制代码被编译成为Dex的字节码,所有的Java文件最终会编译进该文件中去,作为托管代码既然虚拟机可以识别,那么我们就可以很轻松的反编译。所有的类调用、涉及到的方法都在里面体现到,至于逻辑的执行可以通过实时调试的方法来查看,当然这需要借助一些我们自己编写的跟踪程序。Google最然在Android Market上设置了权限保护app-private文件夹的安全,但是最终我们使用修改定值的系统仍然可以获取到需要的文件。
一、dexdump方法
dexdump是emulator自带提供的查看dex文件的工具,可使用类似这样的命令将dex文件dump到txt文件中:
D:\Program Files\android-sdk-windows-1.6_r1\platforms\android-1.6\tools>dexdump.exe -d classes.dex > spk.dump.txt
得到的文件内容,描述了类的信息,但实在是不好读啊~~~~
二、dex2jar + XJad 方法
该方法是使用dex2jar.jar包,将classes.dex文件解包成jar,在通过XJad(或者其他class反编译工具)进行java反编译。如:
1、dex2jar.bat d:\play\classes.dex
默认的输出路径同classes.dex,生成的文件名为classes.dex.dex2jar.jar
2、使用XJad反编译该jar包
之后的使用方法,大家都懂的:)
该方法的好处在于,通过XJad反编译后,大家可直接开到java源文件,缺点在于只能反编译出开发时的java文件,而开发时使用的lib包不能反编译出来。
三、AXMLPrinter2.jar + baksmali.jar + smali.jar 方法
这个方法就强大了,AXMLPrinter2是还原AndroidManifest.xml和main.xml的工具,直接打开这两个xml文件是乱码,而通过还原之后,可以很明白的看到里面的内容(我猜测还是使用了字节异或的方式加的密)。
baksmali.jar是反解析dex的工具,smali.jar则是再还原成dex的工具
操作方式如下:
1、java -jar AXMLPrinter2.jar D:\play\AndroidManifest.xml > AndroidManifest.txt
2、java -jar AXMLPrinter2.jar D:\play\res\layout\main.xml > main.txt
3、java -jar baksmali-1.2.5.jar -o classout/ d:\play\classes.dex
baksmali可解析(注意,是解析,不是反编译)原java包以及引用的lib包,解析出的文件认真看还是能看懂,比如以下片段:
view plaincopy to clipboardprint?
.class Lcom/paul/test/a;
.super Landroid/view/View;
# static fields
.field private static final a:Landroid/graphics/Typeface;
# instance fields
.field private b:I
.field private c:I
.field private d:Z
.field private e:J
.field private f:I
.field private l:[Ljava/lang/String;
# direct methods
.method static constructor <clinit>()V
.registers 2
sget-object v0, Landroid/graphics/Typeface;->SANS_SERIF:Landroid/graphics/Typeface;
const/4 v1, 0x0
invoke-static {v0, v1}, Landroid/graphics/Typeface;->create(Landroid/graphics/Typeface;I)Landroid/graphics/Typeface;
move-result-object v0
sput-object v0, Lcom/wiyun/ad/a;->a:Landroid/graphics/Typeface;
return-void
.end method
#
# other methods ..........
#
# virtual methods
.method public onKeyUp(ILandroid/view/KeyEvent;)Z
.registers 4
const/16 v0, 0x42
if-eq p1, v0, :cond_8
const/16 v0, 0x17
if-ne p1, v0, :cond_b
:cond_8
invoke-direct {p0}, Lcom/paul/test/a;->d()V
:cond_b
const/4 v0, 0x0
invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V
invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
move-result v0
return v0
.end method
.class Lcom/paul/test/a;
.super Landroid/view/View;
# static fields
.field private static final a:Landroid/graphics/Typeface;
# instance fields
.field private b:I
.field private c:I
.field private d:Z
.field private e:J
.field private f:I
.field private l:[Ljava/lang/String;
# direct methods
.method static constructor <clinit>()V
.registers 2
sget-object v0, Landroid/graphics/Typeface;->SANS_SERIF:Landroid/graphics/Typeface;
const/4 v1, 0x0
invoke-static {v0, v1}, Landroid/graphics/Typeface;->create(Landroid/graphics/Typeface;I)Landroid/graphics/Typeface;
move-result-object v0
sput-object v0, Lcom/wiyun/ad/a;->a:Landroid/graphics/Typeface;
return-void
.end method
#
# other methods ..........
#
# virtual methods
.method public onKeyUp(ILandroid/view/KeyEvent;)Z
.registers 4
const/16 v0, 0x42
if-eq p1, v0, :cond_8
const/16 v0, 0x17
if-ne p1, v0, :cond_b
:cond_8
invoke-direct {p0}, Lcom/paul/test/a;->d()V
:cond_b
const/4 v0, 0x0
invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V
invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
move-result v0
return v0
.end method
认真一看,就知道:
# static fields 定义静态变量的标记
# instance fields 定义实例变量的标记
# direct methods 定义静态方法的标记
# virtual methods 定义非静态方法的标记
以onKeyUp方法为例,其中定义了处理逻辑,if-eq p1, v0, :cond_8 表示如果p1和v0相等,则执行cond_8的流程:
:cond_8
invoke-direct {p0}, Lcom/paul/test/a;->d()V
调用com.paul.test.a的d()方法
不相等: if-ne p1, v0, :cond_b 则执行cond_b的流程:
:cond_b
const/4 v0, 0x0
invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V
invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
move-result v0
大概意思就是调用com.paul.test.a的setPressed方法,然后再调用父类View的onKeyUp方法
最后 return v0
该方法,能把外部引用的lib包类也解析出来,能开到包的全貌。缺点在于,解析出的smali文件并不是反编译出的java文件,可读性降低了,但仔细研究也能看出大概。
反编译APK文件的三种方法(转)的更多相关文章
- Xamarin android如何反编译apk文件
Xamarin android 如何反编译 apk文件 这里推荐一款XamarinAndroid开发的小游戏,撸棍英雄,游戏很简单,的确的是有点大.等一下我们来翻翻译这个Xamarin Android ...
- 反编译APK文件
有时源代码丢失了,这时如果有apk文件的话,是可以对apk文件反编译得到源文件的,本文介绍一下简单的反编译apk文件的过程. 1.工具 反编译apk需要的工具有两个:apk2java和apktool, ...
- Android开发学习之反编译APK文件
反编译的目的在于学习一些优秀的Android应用程序代码. 在进行反编译之前,需要准备好下面的软件工具(这些文件都放在同一文件下): 这些工具的下载地址:http://down.51cto.com/d ...
- VC中加载LIB库文件的三种方法
VC中加载LIB库文件的三种方法 在VC中加载LIB文件的三种方法如下: 方法1:LIB文件直接加入到工程文件列表中 在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中&quo ...
- 【Android】Eclipse自己主动编译NDK/JNI的三种方法
[Android]Eclipse自己主动编译NDK/JNI的三种方法 SkySeraph Sep. 18th 2014 Email:skyseraph00@163.com 一.Eclipse关联cy ...
- 【Android】Eclipse自动编译NDK/JNI的三种方法
[Android]Eclipse自动编译NDK/JNI的三种方法 SkySeraph Sep. 18th 2014 Email:skyseraph00@163.com 更多精彩请直接访问SkySer ...
- 把swf反编译成fla的几种方法
2007年著 第一种方法: 利用IMPERATOR FLA1.63 ,这个软件有演示版 和正式版 , 演示版不能反编译Action Scropt,在利用正式版反编译的过程中有时会丢失Action Sc ...
- VC6.0加载lib文件的三种方法
MFC编写程序,都要用到动态链接库,MFC相关的动态库有MFCD42和MFC42等,MFC框架程序已经自动加载,那么如何引入第三方的动态链接库到工程中呢? 静态链接库是要先把程序中所需要使用的函数编译 ...
- Logstash处理json格式日志文件的三种方法
假设日志文件中的每一行记录格式为json的,如: {"Method":"JSAPI.JSTicket","Message":"JS ...
随机推荐
- Guava HashMultiMap(MultiMap)反转映射
(一)MultiMap 多重map,一个key可以对应多个值(多个值放在一个list中),可用于分组 举例: Multimap<String, Integer> map = HashMul ...
- springboot 整合 mongodb实现 批量更新数据
现需求:需要批量将1000个数据先查询在更新到mongodb(如果查询不到数据,则添加数据) 1:工具类BathUpdateOptions import org.springframework.dat ...
- hibernate的一对多和多对一关联
一对一的关联就不写了,一般项目也用不到,如果可以一对一就直接合成一个表了,也不会出现一对一的关系. 本文主要研究一对多的关系. 1.一对多的关系研究: (1)RDB中关系表达: 多的一方创建外键指向 ...
- Linux内核源码分析--内核启动之(2)Image内核启动(汇编部分)(Linux-3.0 ARMv7) 【转】
转自:http://blog.chinaunix.net/uid-25909619-id-4938389.html 在完成了zImage自解压之后,就跳转到了解压后的内核(也就是vmlinux的bin ...
- (maven项目)使用java -jar命令遇到的小问题|xx.jar中没有主清单或Error:Invalid or corrupt jarfile xx.jar
xx.jar中没有主清单或Error:Invalid or corrupt jarfile xx.jar 遇到这个问题,是因为你的jar包没有设置主类的入口. 即在META-INF文件夹的MANIFE ...
- 页面跳转时中间参数保存(memcache/cookie)
2014年1月19日 17:30:27 我这篇文章就说了一句话:用cookie保存页面间跳转时的参数 情景: 客服在后台操作的时候,经常从列表页进入到编辑页,编辑完信息后,还要自动返回之前的列表页 问 ...
- mysql 当前时间
1. mysql 获取当前时间 select now() ,current_timestamp(),localtimestamp(),sysdate() ,curdate(),curtime(),u ...
- DEEP COMPRESSION小记
2016ICLR最佳论文 Deep Compression: Compression Deep Neural Networks With Pruning, Trained Quantization A ...
- fhq treap 学习笔记
序 今天心血来潮,来学习一下fhq treap(其实原因是本校有个OIer名叫fh,当然不是我) 简介 fhq treap 学名好像是"非旋转式treap及可持久化"...听上去怪 ...
- Java编程的逻辑 (17) - 继承实现的基本原理
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...