首页
社区
课程
招聘
[原创]简单分析onCreate
发表于: 16小时前 361

[原创]简单分析onCreate

16小时前
361

dex vmp简单分析onCreate

前言

本人小白一枚,学习其他大佬的教程,发现还是太吃力了,觉得vmp是无法逾越的宏沟,然后也尝试看过一些大佬的文章,有的没样本,有的反调过不了没法复现,于是有了这篇文章,不过样本有点老了,不过学个基本流程感觉还行,刷到这篇[教程]([原创/]某企业加固dex vmp简单分析-Android安全-看雪安全社区|专业技术交流与安全研究论坛),马上大4了,找工作感觉迷茫,。

贴个带时间的图证明一下不是抄的

image-20260612195144947

脱完壳看一下onCreate发现被A.V代理了,其实说白了就是一个vmp入口,0xab000000应该对应的就是vmp需要解释执行的函数,简单介绍vmp,其实就是一个解释器而已,解释自定义的字节码,和你正常写的程序差不多,然后虚拟化寄存器和堆栈(简单理解就是申请一块内存然后放对应寄存器的值而已,这个样本应该没有虚拟栈(毕竟都是通过jni解释执行的),原理感觉很简单,但是还是感觉有点难

然后看看V函数是个啥,那么多跳板函数,感觉是根据返回值定义的,这就不说了,现在主要找一下V函数绑定在哪里的

跑一下脚本,脚本附件应该会提供

然后就看到这个函数大概的样子,很明显 ((dword_C0118 * (dword_C0118 - 1)) & 1) != 0 && dword_C0120 >= 10这个表达式是一个不透明谓词,可以装hrtng去除。后面那个是装了的样子

装了的样子,这个函数应该是ida反编译的错误导致的,因为正常应该是5个参数,前两个固定,后3个是传入的,不懂建议问ai,第一个参数是根据传入的索引0xab000000在对应的地址取出来的,就叫vmState(后面分析出来的,存储对应onCreate方法的一些信息),至于后面那几个后面看trace日志确定的

然后进入函数看看看见这个函数*(a1 + 56),前面说了a1是一个vmState的结构体,但是结构体有什么东西我们并不知道,我猜的是一个方法表method_table[a2]这样取一个对应方法的基本信息,这个是后面分析出来的,简单看一下

然后看到这个函数,被加密了,可以自己跑一遍模拟执行啥的,或者frida自己hook一下就能发现是一个malloc,不是重点就不讲了,

这里用到了v10就是上面取的method结构体,8LL * (v10 + 18)申请了这么大的空间,可以得出v12可能就是我们需要找的虚拟寄存器,照着源码,看基本能实锤,并且(v10 + 18)是7,而这个方法正好使用了那么多的寄存器

image-20260612205053937

寄存器的初始化,一样的不说了,__memset_aarch64寄存器清0

然后发现这个函数,看见switch 以为是个vmp解释器,半天找不到虚拟字节码啥的,也不知道用来做啥的,就没管了,不过好像art虚拟机也有一个类似的前置操作,感兴趣可以自己去找一下,这就不说了

这个才是真正的入口

进入函数看看

off_BD040,发现了很多函数,基本有256个吧,好像官方opcode也是那么多,不过不重要

接下来看 __asm { BR X8 }是这么实现跳转的和x2有关,x2是前面取的method,上面好像命名错了,不管了,最开始猜测了一下x8哪里应该是一个switch跳转,所以尝试用ida自带的识别了一下,不过用处不大,他跳转的地方也有br跳转,不过还是贴一下,所以根据这个跳转可以合理推测x26就是我们的虚拟字节码,可以自己写个frida dump下来看看

image-20260612211521756

然后基本就水到这里了,上trace文件看看,trace工具是乐子人大佬的 ,第一条虚拟指令w26应该算是pc指针了,然后根据取出的指令码又进行了一次跳转,

可以在自己文本工具吧这个地址用颜色标出来,后面可以直接看

image-20260612212430951

然后又取了2字节,并且取了高8位

image-20260612213238667

然后写了个x0到对应的地址,w19是索引,是不是可以合理推测一下,x14就是虚拟寄存器的基地址,所以标出来,然后x0是什么?

发现是是NewGlobalRef的返回结果

image-20260612213901117

image-20260612220525497

0x5d580这个地址跳过去看看,a2这个偏移大概率是env了

然后日志有这个,v13这么来的,合理猜测一下来自于字符串常量池里面的

这里好像也能对上,0x97a前面取的指令,不知道这个猜测对不对,开始我直接拿着索引去dex文件里面找了,并且也印证了猜测

image-20260612221635745

然后这个我也不知道这么印证,我猜测可能是一个tostring方法,有方法的话求告知

然后整理一下

这是没加壳的

这里0x65应该是寄存器索引,跟一下自己就能出来,这里取了一个5的索引,因为trace要闪退我就单独对入口trace了一份,x3就是这个寄存器的值 A.V((int) 0xab000000, this, new Object[]{r5}); 这个的this,然后有个知识点就是,这个onCreate总共使用了,7个寄存器,有一个参数,所以0-6,6就是参数寄存器,5就是this指针p0,0-4就是通用寄存器(如果有误请纠正)

然后有取了2字节

主要跟一下对字节码和虚拟寄存器和jni就行了,所以后面一大坨就不看了然后找到这里有个字符串,看着有点像方法签名

CallNonvirtualVoidMethodA 调用父类的一个方法,然后没有返回值,所以就不会操作虚拟寄存器,所以这个方法是什么好难猜啊,上面有些东西懒得找了又臭又长,上面一些操作应该是拼接这个方法签名,然后进行调用,然后5,6两个参数寄存器,5是this指针会隐式传入,前面指令流取的0x7是啥,方法索引呗

image-20260612230455773

整理一下

这个就是给v6寄存器赋值

image-20260612231337352

结构太像了 不太想看了

CallVoidMethodA 方法调用也没有返回值

image-20260613120613279

整理一下

这两条指令是成对出现的,函数调用有返回值就会用move-result-object v6进行接收

整理一下

类名拼接

类型转换

image-20260613161244813

整理一下

这条简单 就是加载2字节到对应寄存器,这也可以很清晰的看到中间一坨寄存器清0操作,明显的字节码分割线

image-20260613163426290

写个frida 可以看看拿的是什么字段

整理一下

image-20260613170750705

很明显了,就是获取一个对象的长度,而对象就是上一步的v6对象

整理一下


[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!

上传的附件:
收藏
免费 17
打赏
分享
最新回复 (1)
雪    币: 3761
活跃值: (4974)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
看看
3小时前
0
游客
登录 | 注册 方可回帖
返回