起因
前阵子dpt-shell项目有个老哥提了一个issuse,说是libdpt.so报毒了。
后来和另外一个的老哥讨论这个话题,他提到:
我想有道理,检测平台应该是检测特征码啥的,把自己的so加密了,没准就能过检测。有了点子,接下来就开始构思。
加密思路
我们加密的目的很简单,就是为了过检测。那就先按老哥说的,简单的对so的section进行加密。这种加密方式之前也有了解过,而且我们有源码,所以加密实现起来也很简单。加密和还原流程大体是这样:
-
在源码里使用
__attribute__ ((section(".bitcode")))
注解,将需要加密的函数放到指定的section -
使用外部程序对so的指定section进行加密
-
在
.init_array
被调用的时候,把指定section解密,还原到section在内存里的位置
这样,后续的代码就能正常被执行了。当然也要注意:
-
加密的后的数据应与被加密的数据等长度,不然写入到so中将会破坏其他数据。所以加密算法我选择了RC4,不考虑安全,RC4很符合
-
.init_array
节的函数不能被加密,不然cpu执行不了
代码实现
在需要加密的函数前面加上注解,把他们放到指定节,比如:
从so文件中读取指定section的偏移(offset)和大小(size),并将section的数据进行RC4加密后写入原来的位置
在so的.init_array
里做解密。先获取指定section的偏移和大小,再对指定section赋予读写权限,然后再对section的数据进行解密,解密的数据写回原来的位置。最后还原section的访问权限
折腾成功以后,我们来看下代码段加密后的效果
.rodata
也做了加密,加密效果是这样的:
检测结果
刚开始的时候没有对.rodata
节进行加密,送检测结果还是报毒。后来想到字符串是否也做下加密?对.rodata
也加密后,就没有报毒了!
总结
-
字符串检测结果是病毒检测的一个重要指标
-
部分检测项会模拟执行检测,因为有尝试在
.init_array
函数里直接abort,检测就全部通过了 -
可能我的这一套字符串加解密,在病毒分析引擎上跑不起来
-
ollvm加固并不能过病毒检测
原文始发于微信公众号(luoyesiqiu):一次过病毒检测的经历