FART脱壳机的使用与进阶(2)_FART使用相关原理和知识点

如何安装pixel FART

解压FART压缩包
手机关机后 按-音量键和开机键 到 fastboot界面
点击 flash-all.bat 即可自动安装完成

修复dex错误

脱下来的dex无法使用jadx工具打开 因为缺失重要信息

拖入010edit 分析dex文件

修复head头缺失的部分

ida 分析流程

1.查看导出函数 是否有目标函数 左侧搜索函数
2.没有发现有目标函数 确认为动态注册函数 查看JNI_OnLoad函数
3.shift+f12 搜索相关字符串
3.直接f5完事 看看流程图 是不是加了ollvm这种东西 字符串加密 控制流程混淆
4.f5静态分析困难 进入动态分析流程 选择 ida动态调试 或者 frida

JVM 类加载器(3)

1.BootStrap ClassLoader 引导类加载器
2.Extends
3.

Android 类加载器(8)

加壳应用运行流程

ClassLoader修正

原因 动态加载的dex不具有生命周期

几代壳

Dex 整体保护 文件中已经可以解密出来整体的
Dex 方法抽取 动态加载 So加密 内存中可以抽出整体的
Dex Method 始终不是完整Dex 即使是在内存中 需要做主动调用填充
VMP Dex2C Java函数native化 保护效果最强 付费版本
将来 指令级别的ARM指令的VMP时代

SO加固种类

1.基于init init_arry JNI_OnLoad函数的加壳
2.基于自定义的linker的加壳

识别加壳技术版本

1.识别厂商
2.识别是否抽取

整体加固 函数抽取 VMP Java2C

函数抽取特征:dex dump 后方法丢失

可以配合ollvm避免直接被查出来虚拟化后的方法

VMP特征:dex dump 后 普通 虚拟化指令 重置解析器

保护函数注册地址相识 函数逻辑类似

adb logcat|grep

Java2C: java函数变成native 非常影响效率 不建议全量使用 核心函数使用

保护函数注册地址不同 函数逻辑不同

混合使用 先使用vmp/java2c 然后进行 抽取

Dalvik虚拟机脱壳技术(4.4以及之前系统)

源代码 libcore DexClassLoader.java

BaseDexClassLoader

makerDexElements

loadDexFile

new DexFile

openDexFile

openDexFileNative ->进入C层实现加载

dalvik目录

OptMain.cpp

DexPrepare.cpp

rewriteDex 优化重写dex文件

dexFileparse

非常多的时机可以作为脱壳点 只要包含了dex文件的地址

比如脱壳点:

dexFileParse
dvmDexFileOpemPartial

dexSwapAndVerify
dvmContinueOptimization
rewriteDex

grep -ril "testActivity" ./*.dex

对于现代壳依然有效果(apk支持4.4以下可以尝试脱壳)
如果失效 可能是针对脱壳点做了优化 尝试更换脱壳点

当然如果有函数抽取 依然需要修复

源码定制实现脱壳dump:

hook实现脱壳:

脱壳点时机选择:

ART脱壳原理和脱壳方式

InMemoryDexClassLoader( 8.0引入了) 流程 用于加载内存中的Dex 增加安全性

new DexFiel()

openInMemoryDexFile

native createCookieWithDirectBuffer

native createCookieWithArray

native CreateSingleDexFileCookie

native ConverDexFilesToJavaArray

native CreateDexFile 构建dex文件

native dex_file.cc open函数 --> openCommon

直接内存加载 不生成odex文件

可以作为dump点的函数
dex起始地址和大小

  • CreateSingleDexFileCookie
  • CreateDexFile
  • dex_file.cc open
  • dex_file.cc openCommon
  • dex_file.cc DexFile构造函数

ART 下 DexClassLoder的 流程 oatdex

makeDexElements

native openDexFileNative

native OpenDexFileFromOat 首次没有oat先生成oatdex

加固的函数抽取需要阻断这个生成过程

假设阻断了流程

native dex_file.cc Open
native DexFile 构造函数
native OpenAndReadMagic
native dex_file.cc OpenFile
native dex_file.cc OpenCommon
可以作为dump点的函数
dex起始地址和大小

  • OpenAndReadMagic
  • dex_file.cc open
  • dex_file.cc openCommon
  • dex_file.cc DexFile构造函数

脱壳点优先选择 DexFile构造函数 因为两个加载方式共有了

进入dex2oat脱壳 假如没有阻止dex2oat过程
一个dex转oat的过程

  • dex2oat.cc Dex2oat函数
  • dex2oat.cc Setup函数可以作为脱壳点

编写系统源代码或者编写FRIDA插件

dex_file 的过程

补充还有非常多的脱壳点

frida hook libart.so 里面的相关函数

FART脱壳点介绍

FART框架组成

1.脱壳组件 dex dump
2.主动调用方法组件 生成.bin
3.修复dex组件

第一个脱壳点dx2at中转化的位置:

CompileMethod 对dex类方法进行编译 其中构造函数不进行编译 interpreter模式运行

ART运行函数模式:

1.interpreter模式 ART下的解释器执行
2.quick模式 直接运行dex2oat生成的arm指令

函数构造函数进入interpreter解释器执行

也就是interpreter.cc的Execute方法

在解析器这里拿到这个构造方法的ArtMethod

ArtMethod->GetDexFile->得到dex文件

脱壳核心:内存中找到DexFile对象 通过DexFile的begin和size dump dex文件 下来

直接搜索DexFile关键字

一个好脱壳点:
1.通用 对应大多数厂商
2.不容易被hook修改

class_linker.cc LinkCode 脱壳点 测试

FART主动调用组件

应对抽取方法的加固方式脱壳方案:

参考 dexhunter 和 Fupk3 两个Dalvik下的主动调用方式的toke方案

缺点 无法应对ART 无法修复VMP函数 很多app无法在Dalvik下运行

主动调用:构造虚假的调用 欺骗加固 对dex所有类进行类函数的虚拟调用

主动调用连越深效果越好,但是会耗费更多的时间

主动调用核心:

1.如何构造主动调用链 不影响到app的正常运行

FindClass
GetMethodID
CallVidMethod

DexFile.cc 确定 dumpMethodCode方法

判断是否是真实调用还是主动调用 参数判断

2.根据ArtMethod定位内存中CodeItem的起始地址

dumpArtMethod 方法

art_method.h

GetCodeItem 开始地址
如何确定方法讦诉地址 需要解析这个dex文件

codeItem的字段解析 确定大小

class_linker.cc 有关于CodeItm的初始化偏移量设置

异常处理相关字段

3.如何遍历dex并且做到全部调用

ActivityThread 线程中进行主动调用

对进行的所有的Class进行记录

getClassNameList

loadClassAndInvoke

主动调用才会触发生成.bin文件 自动在ActivityThread 启动 60秒

FART和frida

对抗FART:

1.是否加载了不应该的类
2.检测接口调用

没有修正dexClassLoader的插件化 需要使用frida枚举classLoader 激发主动调用脱壳过程

emumerateClassLoader 枚举主动

过滤掉垃圾类主动调用 控制粒度

FART修复组件

主动调用完成后 生成.bin文件

完成全部的主动调用后 这个时候dump下来的dex就是完整的。

修复组件就是解析dex中所有的类和函数

将脱下的dex和.bin合并起来
合成完整的dex文件

应对 VMP smali映射到自定义的方法里面

使用映射关系修复vmp保护的方法

JNI函数对应的地方填回去 需要去看CodeItem里面对应的native的偏移

fart_vmp.py

现在还没有通用的解决方案 主要是映射关系都不一样