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 | .class public LHelloworld; #类名 |
使用smali.jar编译成dex文件
1 | java -jar smali.jar -o classes.dex Helloworld.smali |
压缩成Helloworld.zip,放入模拟器测试
1 | adb push Helloworld.zip /data/local |
得到执行结果(前面有碰到过权限问题,记得先adb root进root模式,这里注意下自己的模拟器,As的模拟器sdk后面带有Google play的不能root,带APIs的可以):
Android程序破解
就现在而言,好像懂得不是很多,但是根据上面的知识,已经可以得到两个Android程序修改的方向了:
- 对反汇编的smali文件分析修改,然后重新打包回去
- 对apk解包出的dex文件进行分析修改,然后重新打包回去
下面简述下这两种方法,用以下程序作示例
修改smali文件
主要流程:
- 用apktool解包出string.xml和public.xml,从中找到关键信息的资源id
- 在smali中找到对应位置,结合前后逻辑进行分析修改
- 用apktool重新打包,并用signapk签名
详述:
1 | apktool d crackme02.apk |
其中,资源文件在res里面,values文件夹下有strings.xml和public.xml,strings.xml自然就是在编写android程序时的字符串资源,而public.xml就是资源的id,在其中可以找到需要字符串的id
在smali文件夹下就是得到的反汇编smali文件,在其中搜索资源id对应找到关键smali代码位置:
熟悉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,以免报签名不相同错误
最后成功的结果图:
总结
Android逆向的很多基础知识包括Dalvik指令集,smali语法等需要熟练掌握,本例子只是一个最简单的程序,不包含任何的混淆等等反反编译手段,只做一个入门尝试:)