Android 逆向学习

2022-04-12

android逆向是门很深的学问,之前在学习re时有接触过一些,但没有很系统的了解过,刚刚好老师上了门逆向课(它的android的课件有许多对我来说是知识盲区,可以好好了解以下)

APK文件

说起android逆向,大概情况就是给你一个APK文件,好,开始分析它吧。

要分析APK文件,我们首先得知道APK文件是什么。

APK(application package)其实是一个压缩包文件,android应用(一般是java写的,现在有转用Kotlin的倾向)在编译完成后,会和所有的资源文件(比如说图片)和数据统一打包成APK。

我们可以用解压缩程序打开他们,但是只能看到其中一部分的内容,另一部分是被加密后的(虽说是加密,其实是可逆的算法,只是一般的解压缩程序没有提供解密功能)

APK文件构成

一般情况下完整的APK是由如下组成的:

AndroidManifest.xml

其中AndroidManifest.xml是比较有用的东西

android应用程序中,用户感知的是一个个的应用界面(在程序中对应的是一个activity类,创建时执行onCreate函数,不可见时执行onStop函数),AndroidManifest.xml中的参数会配置入口的Activity界面

Activity中的application参数配置了程序的入口

在实例中可以看到,入口名称是cn.kwaiching.crackme.CrackMe

这里有对application更详细的描述

res

res目录比较重要的string.xml和public.xml(解密后才能找得到),其实是resources.asrc里的内容

string.xml 存放 实际的字符串和 在 程序中的变量名称 的对应关系

public.xml 存放 程序中的变量名称 和 程序中变量的ID 的对应关系

在实际的反编译代码中,往往是使用ID来代表字符串

android程序的运行机制-虚拟机

为了让android程序崩溃时不会影响到整个系统,使用了虚拟机机制来运行android程序

Dalvik虚拟机

Android4.4之前使用的虚拟机机制

使用JIT(just-in-time)机制,每次执行应用时,将程序的代码(dex码)翻译为机器语言(机器码)执行,程序运行同样的逻辑时,速度会更快

基于寄存器

缺陷:每次程序重新启动,就要重来一遍编译过程,浪费资源

ART(Android RunTime)虚拟机

采用AOT(Ahead-Of-Time)技术

在安装apk程序时启动dex2oat过程把dex预编译为ELF文件,每次运行程序不用重新编译

内存管理也有了较大的改进

缺陷:

应用安装和升级会比较耗时(需要重新编译ELF文件)

优化后的文件占用额外存储空间

ART虚拟机(android 7.0后版本)

Android 7.0后,又重新加入了JIT技术,采用AOT/JIT混合的策略

特点如下:

APK程序执行流程

smali语言

对Dalvik字节码的翻译,这里不详细讲它的语法规则了 smali也算是一种高级语言了。
话说其实现在逆向一般也看smali转换后的java源码(

android运行的架构

arm

arm指令集有一个子集,THUMB指令集

x86

android 1.6开始提供了x86的支持

mips

android 4.1提供了mips支持

android中so的加载流程

.init–>.init array–>JNI_Onload–>java_com_XXX

在脱壳的过程中有时候会在一些系统级的.so中下断点比如:fopen, fget, dvmdexfileopen,等等

而.init以及.init_array一般会作为壳的入口地方,称它为外壳级的.so文件

归纳为三类:

  1. 应用级别的:java_com_XXX;

  2. 外壳级别的:JNI_Onload, .init, .init_array;

  3. 系统级别的:fopen,fget,dvmdexfileopen;

android程序加载过程

首先是“init_array”,Android系统在加载App时,通过系统的 linker程序先加载这个函数,对App进行初始化

然后再调用“JNI_OnLoad”

android动态调试下断点

这个我实际只在夜神模拟器的x86上有试验过,经验还是太少了,毕竟android大多是还是arm程序,等有空实操后再书写如何下断点吧

雷神模拟器下调试

缺陷:只能调试x86的程序,arm经常出问题,碰到反调试一般用不了(

步骤

adb push debug_server /local/data/tmp/debug_server # debug_server指代IDA文件夹中的对应的执行文件
adb shell #进入模拟器shell
su
chmod 777 /local/data/tmp/debug_server #给予权限
./local/data/tmp/debug_server

#接下来再开一个cmd
adb forward tcp:23946 tcp:23946 #(端口转发,调试手 机上的某个进程要有协议支持通信)

#ida的debuger attach附加即可

.class和.dex文件的区别

class文件

class文件:能够被JVM(JavaVirtualMachine)识别,加载并执行的文件格式

class文件的作用:记录一个类文件的所有信息,记住是所有信息

dex文件

dex文件:能够被DVM或者Art虚拟机执行并且加载的文件格式。

dex文件的作用: 记录整个工程中所有类文件的信息,记住是整个工程

反编译常见工具

javap-java JDK自带

功能:class->java源码
较为轻量。推荐不用,可能少东西….

jad

功能: class->java源码
网址在这:
https://varaneckas.com/jad/ 但是有点问题,jad长期不更新,对Java中的新功能支持很差,例如lambda表达式。反编译时,经常会报错误

CFR

功能:class->java源码
比前面两个好,最近更新是2021,还是比较新的,CFR可以编译 Java9,10,12 中的新功能,甚至可以将其他JVM语言的class文件反编译成Java文件 网址:
http://www.benf.org/other/cfr/

jd-jui

功能:class->java源码
图形化界面,可以直接拖入一整个jar包,图形化界面比较好看
网址:
http://java-decompiler.github.io/

jeb

功能:十分丰富,主要用于android逆向
需要自己找破解版(高级一点的)

jadx

功能:和jeb类同,但是是开源的,不如jeb好用,但是开源
网址:https://github.com/skylot/jadx

reference

class文件和dex文件
https://blog.csdn.net/LIZHONGPING00/article/details/103501619