如果有描述不准确的地方,还请各位大佬指正
某加密的最近的版本,网上资料比较少,是比较早的,没有混淆的,以及没有指令抽取的
这里分析的实例,是某加密直接把壳代码写到了原始dex里面去
1)反调试 网上的大部分资料都是些基础的反调试,而且SO是没有经过ollvm混淆的,所以都是些比较直观的能看到代码
而现在大部分是ollvm混淆过,另外加UPX压缩壳,以及SO自解密等
2)dump dex,另一种找到dex.035的地址
3) 修复被抽取指令,找到codeitem的insns指针,取出指令,填充到被nop的dex里面去
4) 重打包APK 应该是做了对抗dex2smali,无法转回去,不过有办法
先看看Application
这个样本解压开虽然直接能看到dex,但是还是通过调试dump了一次,这样可以了解一下反调试
SO被ollvm混淆了,看起来很费力,所以都是从一些关键点下断点去调试和绕过
1-反调试
关于反调试,有文章介绍了17中反调试,可以参考一下,现有资料博客能搜到的反调试,就这几种
时间检测, 检测status,检测ida端口,以及java层的反调试
但是现在的壳已经不止这几种了,多而杂,现在常见的信号反调试,以及断点检测就比较麻烦
可以参考 IDA技巧 这位大神的方法,定位到initarray段的入口,和进入jni_onload的地址,
1.1 信号反调试,常识性的反调试,可以在bad_signal下断
信号函数通常是 signal(SIGN_NO, antidebug_func)
跟进去看看 0xB388D391所在的函数内容,这个函数要在解密后才可以看到,就是获取pid,杀死
信号1,2,3的定义是
SIGHUP 终止进程 终端线路挂断
SIGINT 终止进程 中断进程
SIGQUIT 建立CORE文件终止进程,并且生成core文件
绕过方法就是,signal注册信号函数的时候,吧函数地址改为0,让他注册失败
1.2
进入到initarray段的时候,会有很多个函数,我的做法是通常跳过,如果某一次跳过崩了,就进去找反调试
,就是这里的BLX R4,是循环进入initarray段内的函数
fget断点后看到status检测,修改为0即可,后面还会遇到检测,应该是检测了多次,可以用hook过掉,或者IDA直接手动改掉端口号
然后转换为数字 ,这个比较简单直接改掉字符串就行。
1.3 时间反调试,通常就是检测代码运行时间,暴力一点,R0保存的传入的参数,tm所以直接写0
struct timeval tm;
gettimeofday(&tm, NULL);
时间反调试是status检测是在同一函数内,这个结构看起来比较费力,而且比较多的是无效的if语句,还是找找汇编的关键点来的快
,
1.4 在application的几个native函数
找前面提到的java函数注册为native函数的地址
看R2指针数据 是结构体,也就是0xBEE221E0
对应结构体,BEE221C8地址处就是函数名称,bee22198就是方法签名,可以看下面2张图
也就是在java层的attachBaseContext中的第一个
则be867090就是壳的第一个执行java层native函数
到第二个函数,这个点不像其他的 status是检测端口,时间是检测运行是否过长,以及信号注册函数
猜测可能是一个全局变量,存在这里,然后有我还没有发现的检测点,然后后面在判断这个全局变量(不知道这个解释是否合理)
如下图是运行到N.r这个里面进去
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2019-2-27 04:14
被贝a塔编辑
,原因: