wsxk / wsxk.github.io

MIT License
5 stars 0 forks source link

Android 逆向学习 #168

Open wsxk opened 9 months ago

wsxk commented 9 months ago

https://wsxk.github.io/android%E9%80%86%E5%90%91%E5%AD%A6%E4%B9%A0/

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

APK文件

  APK文件构成

      AndroidManifest.xml
      res

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

  Dalvik虚拟机
  ART(Android RunTime)虚拟机
  ART虚拟机(android 7.0后版本)

APK程序执行流程 smali语言 android运行的架构

  arm
  x86
  mips

android中so的加载流程 android程序加载过程 android动态调试下断点

  雷神模拟器下调试

.class和.dex文件的区别

  class文件
  dex文件

反编译常见工具

  javap-java JDK自带
  jad
  CFR
  jd-jui
  jeb
  jadx

reference

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文件

归纳为三类:

应用级别的:java_com_XXX;

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

系统级别的: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