各位聪明绝顶,才高八斗的读者们你们好!今天我们主要讨论编译之后的RC4算法识别。
题外话,之前看到一个蛋疼的小知识,说“势”这个字最好不好查词典释义。我是很好奇的,果然后来无法直视势不可挡这个成语。

言归正传,我们将上一篇的Java与C的代码都编译一下,分别反编译看看。
Java版

Java版的就很好识别,几乎与源码没啥区别。
C版
这里我们先给出RC4加密算法在逆向分析过程中的快速识别经验:
-
首先判断明文和密文长度是否相等,等长则代表是序列密码。
-
接下来判断是否是RC4。RC4算法中的初始化算法(KSA)中有两轮非常显著的长度为256的循环体,用于根据给定的key生成s盒。伪随机子密码生成算法(PRGA)会根据上一步得到的扰乱的s盒,进一步生成子密钥流,最终和给定的明文进行逐字节的异或。
由于 so 是可以加 ollvm 的,而且还可以做字符混淆,所以逆向起来不会像Java那么容易,在我们找到一个怀疑对象函数之后,就可以通过编写frida脚本或xposed插件完成对相应函数的主动调用,判断当输入明文为任意长度时的密文长度。
关于 ndk 的混淆是有很多文章的,自己可以尝试一下控制流混淆与字符串混淆。
我们看一个混淆之后的例子:
sub_F658(&unk_38008, dest);
unk_38008实际上是一个字符串,不过这个字符串被混淆了,在 init 阶段后才会被解密。
看里面的逻辑:
sub_F0AC((__int64)v7, (__int64)a1, v4);
v2 = strlen(a2);
return sub_F3C4(v7, a2, v2);
有2个函数比较可疑,先看 sub_F0AC:

先看1处,有一个很明显的交换数组元素的逻辑。
再看2处,只有当 v7 = 915845509 的时候才会交换逻辑,循环次数是 256 次,这些都与 RC4 的 init 阶段是一样。
当然这里也只是大胆猜测,而且混淆级别开的没那么高,所以还能看清楚一定的逻辑。实际上这里就已经很难看出来第一个给 S 盒赋值的循环在哪里了,只能根据 result 的位置来看。
后面我们可以使用hook来验证我们的想法。
再看 sub_F3C4

最低0.47元/天 解锁文章
3379

被折叠的 条评论
为什么被折叠?



