分析Android程序
当拿到一个apk之后,我们应该怎样分析它?刚刚看完了Android软件安全权威指南前面一部分,尝试着梳理一下知识,那么接下来就开始吧
1 安装apk
由于只有一个手机,而后面可能会涉及到恶意软件分析,所以在这里,着重讨论的是使用电脑上的Android虚拟机,目前使用的是Win 10系统加上模拟器。接下来开始吧。
1.1 安装&测试
在我目前使用的Win10电脑上进行arm环境的模拟会出现闪退,而这个问题我暂时并没有解决掉,所以对于arm 环境的模拟,我使用的是模拟器。
1.1.1 emulator
常用的命令主要有两个
1 | $ emulator -list-avds # 查看当前可用的avd |
1.1.2 adb(Android 调试桥)
我目前使用的是网易mumuAndroid模拟器
打开模拟器之后使用adb 手动连接模拟器端口
常用指令
1 | $ adb connect ip # 连接到设备 |
对于文件夹中 已经存在的文件 a.apk
,我想安装它,使用的命令如下:
1 | $ adb connect 127.0.0.1:7555 # 使用adb连接到虚拟机 |
2 反编译apk
将apk安装进虚拟机之后能大概查看下app的功能,便于我们后面进一步的分析,之后我们需要做的是分析apk,并将它反编译。
1
2
3
4 > $ file *.apk
> .\a.apk: Zip archive data, at least v2.0 to extract
> $ unzip *.apk
>
将apk 解压缩之后我们可以得到:
original
目录下的META_INF
目录:包含了apk的签名信息AndroidManifest.xml
: 编译好的AXML二进制格式文件- res 目录,程序中使用的资源信息
resources.arsc
:编译好的二进制资源信息assets
: 资源文件classes.dex
程序的可执行代码,如果开启了MutliDex
,会有多个dex文件
对于apk的详细分析我们之后再说明,现在假定我们拿到的apk文件可以直接反编译:
可以使用的工具有
- apktools :官方文档在这
- jd-jui :查看工具
- jadx: 查看工具
- jeb: 提供了方法交叉引用和重命名
- ida pro
反编译之后得到的文件有:
1 | Mode LastWriteTime Length Name |
接下来就是对反编译之后的samli文件分析过程:
smali
文件时Dalvik
字节码文件,官方网站是Dalvik字节码
对于Dalvik字节码的一个总结如下:
2.1 Dalvik 字节码文件
编写的.java
文件经过编译之后得到java字节码文件.class
,.class
文件再编译得到.dex
文件,.dex
文件在虚拟机上能够执行,.dex
文件经过反编译之后就得到了Dalvik字节码文件,完整的过程以及流程如下:
Dalvik虚拟机和Java虚拟机区别
- Java虚拟机运行
.class
java字节码文件,Dalvik虚拟机运行的是.dex
Dalvik字节码文件 - 传统的java文件通过编译生成java字节码保存在
.class
文件中,java虚拟机通过解码.class
文件来运行程序,而 Dalvik虚拟机运行的是Dalvik字节码文件,它都是通过java字节码转换而来,并被打包到一个.dex
可执行文件中,Dalvik虚拟机通过解释DEX文件来执行字节码 - Java虚拟机基于栈架构,而Dalvik虚拟机基于寄存器架构,数据间访问更快。
2.2 虚拟机的启动流程
Android系统启动加载内核后—-> 执行init进程 —-> 启动Zygote进程 —-> 初始化Dalvik虚拟机 —> 启动system_server进入Zygote模式,用socket等待命令 —> Zygote收到命令后fork一个Dalvik虚拟机实例来执行程序入口函数。
其中Zygote有三种创建进程的方法:
- fork()创建Zygote进程
- forkAndSpecialize()创建非Zygote进程
- forkSystemServer()创建系统服务进程
fork后 —> 虚拟机通过loadClassFromDex完成装载(用gDvm.loadedClass全局哈希表存储查询类) —> dvmVerifyCodeFlow对代码检验 —> FindClass查找装载main方法类 —> dvmInterpret初始化解释器并执行字节码流。
3 一个简单ctf题解
反编译之后,有三个文件
可以看到实现的是一个 enigma密码机 ,直接根据最后的密码解了即可:
1 | from collections import deque#双端队列 |