0%

Android逆向分析初步(1)

Android逆向分析与软件安全_基本的android逆向分析方向与基础知识概述

  Android逆向分析最基本和常见的就是APK文件,里面包含有Dalwik虚拟机的专用可执行文件格式dex(dalvik VM executes),解压APK文件即可看到。文中略去了关于DEX的具体的结构和Dalvik虚拟机的各种工作流程的叙述,主要记录下第一次实际操作的过程方便后面查阅。

Java虚拟机与Dalvik虚拟机

  Java虚拟机上运行的是java字节码(.class)文件,而Dalvik虚拟机上运行的是一种由java字节码优化减少体积后形成的dalvik字节码,存放在上述dex文件中。
  两者的架构也是不同的,Java虚拟机基于栈结构,频繁的从栈上读取与写入数据,而Dalvik虚拟机则是通过寄存器传值,速度快很多。可以了解下Dalvik汇编语言的知识。

DEX反汇编

  DEX文件反汇编工具baksmali和dedexer,两种反汇编代码基本结构组织基本相同。了解下Dalvik的指令集很重要。主要是smali语法,在Android逆向中十分重要。课后练习的一个smali语法的Helloworld示例程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.class public LHelloworld; #类名
.super Ljava/lang/Object; #父类
.method public static main([Ljava/lang/String;)V #声明静态main方法
.registers 4 #程序中使用v0 v1 v2 寄存器和一个参数寄存器
.parameter #参数 一个
.prologue #代码起始指令
nop
nop
nop
nop
const/16 v0,0x8
const/4 v1,0x5
const/4 v2,0x3
move v1,v2
new-array v0,v0, [I
array-length v1,v0
new-instance v1,Ljava/lang/StringBuilder; #示例操作指令
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V # 方法调用指令
if-nez v0, :cond_0
goto :goto_0
:cond_0
int-to-float v2,v2
add-float v2,v2,v2
cmpl-float v0,v2,v2
#字段操作
sget-object v0,Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1,"Hello world" #构造字符串
invoke-virtual {v0,v1},Ljava/io/PrintStream;->println(Ljava/lang/String;)V #方法调用
:goto_0
return-void
.end methods

使用smali.jar编译成dex文件

1
java -jar smali.jar -o classes.dex Helloworld.smali

压缩成Helloworld.zip,放入模拟器测试

1
2
adb push Helloworld.zip /data/local
adb shell dalvikvm -cp /data/local/Helloworld.zip Helloworld

得到执行结果(前面有碰到过权限问题,记得先adb root进root模式,这里注意下自己的模拟器,As的模拟器sdk后面带有Google play的不能root,带APIs的可以):

图 1

Android程序破解

  就现在而言,好像懂得不是很多,但是根据上面的知识,已经可以得到两个Android程序修改的方向了:

  • 对反汇编的smali文件分析修改,然后重新打包回去
  • 对apk解包出的dex文件进行分析修改,然后重新打包回去

  下面简述下这两种方法,用以下程序作示例

图 2

修改smali文件

主要流程:

  • 用apktool解包出string.xml和public.xml,从中找到关键信息的资源id
  • 在smali中找到对应位置,结合前后逻辑进行分析修改
  • 用apktool重新打包,并用signapk签名

详述:

1
apktool d crackme02.apk

图 3

  其中,资源文件在res里面,values文件夹下有strings.xml和public.xml,strings.xml自然就是在编写android程序时的字符串资源,而public.xml就是资源的id,在其中可以找到需要字符串的id

图 4

图 5

在smali文件夹下就是得到的反汇编smali文件,在其中搜索资源id对应找到关键smali代码位置:

图 6

熟悉smali的话,这个程序挺简单的,这里就是一个关键判断,结果不为0则跳转到cond_0标号,将其修改为相反逻辑if_eqz后保存

apktool重新打包

1
apktool b crackme02

用signapk签名

1
signapk crackme02.apk

之后adb install安装查看是否破解成功,不出意外,应该成了

修改DEX文件

主要流程:

  • 用apktool解包出string.xml和public.xml,从中找到关键信息的资源id
  • 解压apk得到classes.dex,放入ida pro反汇编,搜索资源id字段,分析前后逻辑,十六进制修改器修改dex关键位置
  • 新的classes.dex用dexfixer重新进行校验和计算
  • 删除原来apk的META-INF 和 classes.dex
  • aapt将新的classes.dex放入
  • signapk签名

这种方法和前面的差不多,不过多叙述
找资源id和前面一样;
apk直接解压得到classes.dex用ida反汇编,alt+T搜索id字符串,找到对应位置后,找到附近的关键代码,对应到hex窗口的偏移,16进制编辑器将对应偏移位置将if-nez语句的39修改为38(if-eqz)后保存;
用dexfixer重新计算填充dex文件的校验和;
然后删除原来的META-INF 和classes.dex 将新的classes.dex放入

1
aapt a source.apk classes.dex

然后signapk签名后adb install安装测试
(adb install安装前记得卸载掉之前的app,以免报签名不相同错误

最后成功的结果图:

图 7

总结

Android逆向的很多基础知识包括Dalvik指令集,smali语法等需要熟练掌握,本例子只是一个最简单的程序,不包含任何的混淆等等反反编译手段,只做一个入门尝试:)