android APK反编译的方法

news/2024/7/3 7:02:33

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

 因为学习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文件,可读性降低了,但仔细研究也能看出大概。

转载于:https://my.oschina.net/u/579890/blog/149071


http://www.niftyadmin.cn/n/4613426.html

相关文章

机器学习数据的标准化(normalization)和归一化

数据的标准化&#xff08;normalization&#xff09;和归一化 数据的标准化&#xff08;normalization&#xff09;是将数据按比例缩放&#xff0c;使之落入一个小的特定区间。在某些比较和评价的指标处理中经常会用到&#xff0c;去除数据的单位限制&#xff0c;将其转化为无量…

python 数据预处理

观察数据 housing.info()housing.describe()housing.hist(bins50, figsize(20,15)) # 连续数据 plt.show() 离散变量使用value_counts()观察&#xff1a; housing[‘ocean_proximity’].value_counts() 分割数据为测试数据和训练数据 方法1 train_test_split from sklearn.m…

Linuxshell之如何控制脚本

写在前面&#xff1a;案例、常用、归类、解释说明。&#xff08;By Jim&#xff09; CtrlC组合键可以生产SIGINT信号CtrlZ组合键生产SIGTSTP信号&#xff0c;停止进程后程序仍然留在内存中&#xff0c;能够从停止的地方继续运行。捕获信号#!/bin/bash# testing output in a bac…

MySQL全文检索笔记 转载

1. MySQL 4.x版本及以上版本提供了全文检索支持&#xff0c;但是表的存储引擎类型必须为MyISAM&#xff0c;以下是建表SQL&#xff0c;注意其中显式设置了存储引擎类型 CREATE TABLE articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,title VARCHAR(200),body T…

Python使用 sklearn pipeline进行数据清洗

setup pipeline from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler num_pipeline Pipeline([ (‘imputer’, Imputer(strategy“median”)), #中值写入 (‘attribs_adder’, CombinedAttributesAdder()),#增加比例列 (‘std_scaler’…

Swift iOS macOS 多语言支持,国际化支持, Localization Localizable

Swift iOS macOS 多语言支持&#xff0c;国际化支持&#xff0c; Localization Localizable 搞开发一定要不断的提升自己的英文水平&#xff0c;因为很多文档都是英文的&#xff0c;像 iOS 的开发API文档等等。学好英文&#xff0c;你就可以在编程的世界里任意遨游。 完成一个项…

Swift iOS macOS 字符串 插入到已排序的数组中,字符串对比

Swift iOS macOS 字符串 插入到已排序的数组中&#xff0c;字符串对比 今天需要实现这样一个功能&#xff1a; 有一个字符串 ad&#xff0c;需要按顺序插入到这样一个字符串数组中。 注意&#xff1a;这个数组中有近8万条数据&#xff0c;所以不可能每添加一个数据都重新排序一…

python 回归和决策树 数据验证和参数调整

cross_val_score, cv10, 随机分成10个子集 ​from sklearn.model_selection import cross_val_score scores cross_val_score(tree_reg, housing_prepared, housing_labels, scoring“neg_mean_squared_error”, cv10) tree_rmse_scores np.sqrt(-scores) def display_scor…