最近在补app壳的东西,东西很多,脑子很晕,故写个博客来整理整理
本篇仅作梳理和简单回顾,更多分析内容在前面几篇博客
大致分为:
前置知识
壳通识
一代壳 dexclassloader 我理解的落地加载
一代壳 inmemorydexclassloader 我理解的不落地加载
二代壳 dalvik下抽取壳的实现
二代壳 art下抽取壳的实现
前置知识
JVM的三种类加载器

委托关系

class加载流程

class继承关系

壳通识
attachbasecontext和oncreate的初识
了解一下如何进入我们的app代码的

activitythread
handlebindapplication
makeapplication
newapplication
attach
attachbasecontext


解决dexclassloader加载的类的问题

其实说白了,沟槽的也就是classloader不合适,要我们自己的classloader来才行
然后举了一个第一种方法反射替换的例子
oncreate
startTestActivityFirstMethodstar
replaceClassloader 通过反射 替换了目标dex当中mclassloader
startTestActivityFirstMethodstar 完成对目标dex目标activity的调用
注意manifest还要改
注意是替换组件的classloader

第二种呢

其实也是通过反射来实现插入的,
DexClassLoader dexClassLoader=new DexClassLoader(dexfilepath,optfile.getAbsolutePath(),libfile.getAbsolutePath(),bootClassloader);
把插入的dexclassloader的parent变成现在classloader的parent
把现在的parent变成dexclassloader
加壳
加壳,有两种方式,
本身没有application的声明,只要自己进行声明,然后壳程序实现解密,加载就可以
另外的一种要额外去调用原apk的application
8以上的inmemoryclassloader从内存中读,避免直接被找到文件
4左右的 opendexfile是文件形式 安全性低
壳发展
动态加载
是dex加壳,插件化,热更新的一个基础
什么是热加载 就是用到的时候再去加载

其实我觉得dex加密 有分落地和不落地的
vmp 解释器 找到映射关系
dex2c 语义转换很恶心
要关注JNI相关的调用
一代壳 dexclassloader 脱壳方案

文件加载和内存加载两种表现形式
核心总是在内存当中把dex文件dump下来
多数输在看源码了



一代壳 inmemorydexclassloader 脱壳
inmemory


dexclassloader
其实应该不是放在不落地加载壳里的。。之前那个落地加载壳基于安卓四的opendexfile,上面那个是安卓8art8下inmemory的不落地加载,这个是安卓8art下dexclassloader生成oat时的情况

在art进行抽取实现的时候也要阻塞这个dex2oat
阻塞成功后的分支
opendexfilesfromoat不成功
dexfile::open 这还之前的open还不一样 有openandreadmagic等
opencommon
mapfile


一个整体壳的脱壳方法
一种是inmemorydexclassloader
一种是禁用掉dex2oat之后用dexclassloader
甚于说对class加载或者method列的时候,都可以,只要对内存中dex文件有操作,都可以尝试。
二代壳 dalvik下抽取壳的实现
记住恢复时间永远要早于这个被调用时机

这些里面还是有很多的

以dexclassloader的loadclass为例
loadclass
findclass
loadclassbinaryname
defineclass
dvmgetrawdexfiledex
dvmdefineclass
findclassnoinit
dvmlookupclass
dexfindclass 也是姜维师傅找到得以抽取函数复原的一个时机点
二代壳 art下抽取壳的实现
俩事
- 干掉dex2oat
- 实现抽取函数的还原
干掉dex2oat
为什么要干掉oat?
就是这个dex2oat的产物oat,如果生成了这个oat,后续所用代码会从这个文件里获得,以至于我们动态修改的dex的smali就不会生效了。
其实也有俩方案
禁用dex2oat 阻止掉dex2oat的过程
还原时机早于dex2oat
我们选第一个
需要回顾到dex2oat的部分
generateoatfilenochecks
dex2oat
exec
execandreturncode
execve
上面的流程中的打断都会阻断oat的生成,所以尝试hook 试execve

实现抽取函数的还原
对classmethod的流程

其中有个东西至关重要 codeitem
loadmethod里面完成赋值,所以这就是一个时机

深入看看, Artmethod里面有个变量 很重要

这就是我们说的codeitem
当一个class加载好之后,就准备好了这个每个函数对于的artmethod对象,每个artmethod对象都和java层的method 一一对应
当我们禁用了de2oat 就都在解释模式下运行
就可以找到这个codeitem

根据dex结构,找到codeitem位置 加上16字节为十六进制

通过先调用原loadmethod获得codeitem,再判断是不是想要的方法,在进行还原
