app逆向文章整理-1


本文来自52破解文章。

原文链接https://www.52pojie.cn/thread-408645-1-1.html APK的组成 <资源目录1:asset和res都是资源目录但是有所区别,见下面说明> lib文件夹: <so库存放位置,一般由NDK编译得到,常见于使用游戏引擎活INI native调用的工程中> META-INF文件夹: <存放工程一些属性文件,例如Manifest.MF> res文件夹: <资源目录2:asset和res都是资源目录但是有所区别,见下面说明> AndroidManifest.xml <Android 工程的基本配置属性文件> classes.dex <Java代码编译得到Dalvik VM能直接执行的文件,下面有介绍> resources.arsc <对res目录下的资源的一个索引文件,保存了原工程中strings.xml等文件内容> 其他文件夹 etc. res目录下的资源文件在编译时会自动生成索引文件(R.java),在java代码中用 R.xxx.yyy来引用;而asset目录下的资源文件不需要生成索引,在java代码中需要AssetManager来访问; 一般来说,除了音频和视频资源(需要放在raw或asset下),使用java开发的 Android工程使用到的资源文件都会放在res下:使用C++游戏引擎(或使用lua Unity3D等) 的资源文件均需要放在asset下. Dalvik字节码是什么? Dalvik字节码是学习破解的基础,对它我们需要了解一下 Dalvik是google专门为Android操作系统设计的一个虚拟机,经过深度的优化。虽然Android 上的程序是使用java开发的,但是Dalvik和标准的java虚拟机JVM还是两回事。Dalvik VM 是基于寄存器的,而JVM是基于栈的;Dalvik有专属的文件执行格式dex(dalvik executable), 而JVM则执行的是java字节码。Dalvik VM比JVM速度更快,占用空间更少。 通过Dalvik的字节码我们不能直接看到原来的逻辑代码,这时需要借助如Apktool或 dex2jar+jd-gul工具来帮助查看。但是,注意的是最终我们修改APK需要操作的文件是 .smali文件,而不是导出来的java文件重新编译。

Smali--破解的重中之重
什么是smali
smali,Baksmali分别是指安卓系统里的java虚拟机(Dalvik)所使用的一种。dex格式
文件的汇编器,反汇编器。其语法是一种宽松式的jasmin/dedexer语法,而且它实现了.dex
格式所有功能(注解,调试信息,线路信息等)
当我们对APK文件进行反汇编后,便会生成此类的文件,小编在此对smali文件进行简要的介绍。
其中在Davlik字节码中,寄存器都是32位的,能够支持任何类型,64位类型(Long、Double)
用2个寄存器表示:Dalvik字节码有两种类型:原始类型;引用类型(包括对象和数组)
原始类型
    B--byte
    C--char
    D--double
    F--flota
    I--int
    J--long
    S--short
    V--void
    Z--boolean
    [XXX--array
    Lxxx/YYY--object

这里解析下最后两项,数组的表示方法是:在基本类型钱加上黔中括号“[”,例如int数组和float
数组分别表示为:[I [F;对象的表示则以L作为开头,格式是:LpackageName/objectName;(
注意必须有个分好跟在最后),例如Srting对象在smali中为:Ljava/lang/String;,
其中java/lang对应java.lang包,String就是定义在该包中的一个对象。
既然类是用LpackageName/objectName;来表示,那类里面的内部类又如何在smali中引用呢?
答案是:LpackageName/objectName$subObjectName;。也就是在内部类前加"$"符号,关于“
$”符号更多的规则将在后面谈到。
Func-Name(Para-Type1Para-Type2Para-Type3...)Return-Type
注意参数与参数之间没有任何分隔符,同样举几个例子就容易明白了:
1.hello()V
    没错,这就是void hello()。
2.hello(III)Z
    这个则是boolean hello(int,int,int)。
3.hello(Z[I[ILjava/lang/String;J)Ljava/lang/String;
    看出这是Srting hello(boolean,int[],int[],String,long)了吗

Smali基本语法
.field private isFlag:z 定义变量
.method 方法
.parameter 方法参数
.prologue 方法开始
.line 123 此方法位于第123行
invoke-super 调用父函数
const/high16 v0,0x7fo3 把0x7fo3赋值给v0
invoke-direct 调用函数
return-void 函数返回void
.end method 函数结束
new-instance 创建实例
input-object 对象赋值
iget-object 调用方法
invoke-static 调用静态函数

条件跳转分支:
"if-eq vA,vB,:cond_**" 如果vA等于vB则跳转到:cond_**
eq 等于
"if-ne vA,vB,:cond_**" 如果vA不等于vB则跳转到:cond_**
ne 不等于
"if-It vA,vB,:cond_**" 如果vA小于vB则跳转到:cond_**
It小于
"if-ge vA,vB,:cond_**" 如果vA大于等于vB则跳转到:cond_**
ge大于等于
"if-gt vA,vB,:cond_**" 如果vA大于vB则跳转到:cond_**
gt大于
"if-le vA,vB,:cond_**" 如果vA小于等于vB则跳转到:cond_**
le小于等于
"if-eqz vA,vB,:cond_**" 如果vA等于0则跳转到:cond_**
eqz等于0
"if-nez vA,vB,:cond_**" 如果vA不等于0则跳转到:cond_**
nez不等于0
"if-Itz vA,vB,:cond_**" 如果vA小于0则跳转到:cond_**
Itz小于0
"if-gez vA,vB,:cond_**" 如果vA大于等于0则跳转到:cond_**
gez大于等于0
"if-gtz vA,vB,:cond_**" 如果vA大于0则跳转到:cond_**
gtz大于等于0
"if-lez vA,vB,:cond_**" 如果vA小于等于0则跳转到:cond_**
lez小于等于0