2.1.将APK解压,在lib/armeabi目录下找到libnative-lib.so,用IDA Pro打开
在IDA中搜索JNI_OnLoad函数,发现动态注册的代码:
2.2.查看动态注册表
双击off_4004,查看JNINativeMethod结构:
可以看到,CheckFlag方法实际绑定到了sub_DC8+1函数(Thumb模式)。而IDA中还有一个静态注册的函数Java_monkeylord_illusion_MainActivity_CheckFlag,这是一个常见的干扰项,真正的逻辑在动态注册的函数中。
2.3.分析真正的CheckFlag函数
双击sub_DC8,按F5生成伪代码:
函数将用户输入的字符串s和encflag字符串s2转换为C字符串。
对s的每个字符,进行运算:s[i]加上密钥字符串aLjavaLangStrin_0[i],减去64,然后调用sub_10C0,结果右移32位,再加32,得到加密后的字符。
最后比较加密后的字符串与s2(encflag),返回相应结果。
2.4.密钥字符串
双击aLjavaLangStrin_0,发现它指向一个长字符串:
这就是JNI方法签名,也是我们加密使用的密钥。由于encflag长度为13,我们只需要前13个字符作为密钥,即:"(Ljava/lang/S"。
2.5.加密算法分析
进一步分析sub_10C0函数,发现它是__aeabi_idivmod,即整数除法和取模运算。结合伪代码中的右移32位,实际上取的是除法的余数(ARM中__aeabi_idivmod返回的64位值高32位是余数,低32位是商)。
因此,加密算法可以简化为:
encrypted[i] = ( (flag[i] + key[i] - 64) % 93 ) + 32