我试图在静态分析上使用ida pro对android ndk(arm)进行反向工程。但是,似乎有很多无用的跳转到相同的位置,并且将随机值设置为R1进行比较并再次跳转。如下图。几乎每个函数都在执行类似的操作-首先进行初始化(诸如推入寄存器之类的东西),然后它会跳转到某个地方进行编码(例如图片的右上角),将随机值加载到R1寄存器中并将其与R0进行比较,然后执行跳转,但它总是会再次跳回到上角。



这是另一种情况,似乎loc_FFBA及其后面的分支充当了一个很大的开关,但没有做什么几乎每个分支最终都将再次跳回loc_FFBA毫无道理。可以有一个红色->绿色->蓝色->红色的流程,但它甚至没有任何意义。您可以看到蓝色的跳转甚至没有用,因为如果跳转到蓝色(R0> 0x6fe5e521),我肯定会跳到红色(R0> 0x661cf941)...



我的问题是,作者是否故意这样做是为了防止反向工程?如果是这样,如何实现?对我来说,听起来好像作者在他的C ++代码中将需要大量if-else和goto子句,但这也将减慢开发速度,因为他可能会混淆自己...而且看来.so ndk打包了,因为通过使用调试器,我发现通常它实际上所做的只是将资源文件解码为apk并动态加载,但是所有解密都是通过调用JNI函数进行AES解密来加载APK来完成的,而不是用C ++来完成,所以混乱的跳跃似乎也与解密无关...

如果确实是这样,也许会有某种编译器会生成垃圾故意混淆?

评论

这似乎是CFG拼合模糊处理

#1 楼

不幸的是,没有足够的代码来确切说明其含义,但是,就像@ 0xec所说的那样,它看起来很像是控制流扁平化。
通常,这种代码转换是由混淆器自动完成的。 br />
有一些令人困惑的编译器,其中之一进行CFG展平。据我所知,这种编译器不是唯一的一种,还有很多其他的。这个特定的混淆编译器基于LLVM框架,如果您想了解其实现方式-此处提供了CFG展平的代码。另外,您可以在此处找到有关如何对小型程序进行反混淆的示例。

评论


非常有趣,但是在我看来,混淆比静态分析中的打包更具抵抗力,因为对于打包,原始机器代码几乎总是可以本地恢复的,但是对于混淆,它就是这样。

–Y M
17年7月6日在18:01

#2 楼

这是一篇博客文章,更详细地描述了该技术,以及一些有关如何撤消该技术的提示:

https://blog.quarkslab.com/deobfuscation-recovering-an-ollvm-protected -program.html

编辑

2017年的另一篇文章:

https://blog.rpis.ec/2017/12/dissection- llvm-obfuscator-p1.html