在分析APK、DEX或者原生二进制程序的时候,如果发现Strings窗口里面看不到域名、接口路径和一些关键的提示文字,这通常意味着样本里的字符串已经被加密了,或者是在程序运行的时候才会把它们解密出来。这时候,就需要弄清楚JEB Decompiler到底应该怎么去分析字符串加密,以及怎么去定位字符串解密的具体逻辑,而不能仅仅依靠全局搜索明文来完成。JEB这个工具支持反编译、交叉引用、脚本编写和插件扩展,也有一些能够自动解密部分受保护字符串的现成例子,但面对复杂的样本,最终还是得靠人工来找到那个执行解密的函数。
一、JEB Decompiler怎么分析字符串加密
要分析字符串加密,得先弄清楚密文存放在什么地方,然后再找出是哪里调用了执行解密的逻辑;要是连密文和解密函数都找不到,那后面就只能靠猜了。
1、先查看Strings窗口:先把样本打开,让它完整地跑完一遍分析,再进到Strings视图里面去查看;按照一些讨论里的说法,可以在字符串标签页里直接查看字符串,如果碰上字符串被加密的情况,可以试着执行一次全局分析,因为在分析过程结束后,有一部分字符串可能会被恢复出来。
2、搜索异常字符串形态:接下来,要去搜索那些形态异常的字符串,加密后的字符串常常会呈现出像“aGVsbG8=”这样的Base64编码片段、无法阅读的控制字符、长度很短的数组、十六进制形式的常量,或者一大段看起来毫无实际意义的字段;找到这些内容之后,再用交叉引用的功能去确认它们分别被哪些方法读取过。
3、查看调用位置:然后,要对可疑的字符串或者数组执行交叉引用,这样就能直接跳到调用它们的地方;假如有好几处位置都调用了同一个很短的方法,并且返回值的类型又是String,那么这个方法是统一解密入口的可能性就很高了,因为程序通常会把解密操作封装在一个独立的函数里反复使用。
4、标记可疑函数:最后,把这样的可疑函数重新命名一下,比如改成decryptString、decodeText或者标记为待确认的解密函数,同时给它加上注释;JEB本身支持交互式地重命名、添加注释以及扩展脚本,很适合一边分析一边把结论给整理出来。
二、JEB Decompiler字符串解密逻辑怎么定位
在定位解密逻辑的时候,需要把眼光重点放在函数的输入参数、有没有固定的密钥、循环处理的流程以及最后的返回值上;多数被加密的字符串,最终都会经过一个像“把密文输进去,让明文流出来”这样的函数。
1、找返回String的方法:首先,要去反编译出来的代码里搜索那些返回值是字符串类型的方法,特别是参数为字符串、字节数组、整型数组或者只是一个索引值的方法;即使方法名称被混淆了,也可以依靠参数和返回值的类型来锁定它,因为解密函数一般都需要接收加密数据并返回解密后的字符串。如果在方法内部发现了Base64解码、异或运算、字符的位移操作,或者是对数组进行重新排列之类的处理,就更要多加留意。
2、看是否有固定密钥:其次,要注意观察是否存在固定不变的密钥,许多解密函数都会硬编码一个密钥、一个数字数组,或者存放在类的静态字段里面;有些第三方的示例代码也展示过类似的流程,就是先分析出解密的算法和密钥,再把这一整套逻辑移植到脚本里去批量解密。
3、追踪调用链:接下来,从可疑的解密函数出发,向上追踪是谁在调用它,再去看看调用之后拿到的返回结果是不是被用在了URL拼接、命令执行、Intent跳转、类名的反射调用、日志记录或者配置信息的读取这些地方;一旦返回值的用途变得越明确,就越能有把握地断定这个函数就是字符串的解密入口。
4、对比多个调用样本:最后,还可以多挑几个不同的密文输入,手工或者用脚本执行一下解密逻辑,检查输出结果是不是变成了能够正常阅读的文本;要是好几个样本都能够得到正常的明文,那就可以把这个函数的命名和注释给固定下来了。
三、JEB字符串解密结果怎么复核
把明文解密出来以后,还要再确认一下结果的可信度,不要一看到可读的文本就立刻下结论,特别是在处理混淆样本的时候,里面很可能会混进一些用于诱导的字符串,或者来自根本不会执行的无效分支。
1、确认运行路径:首先,要去查看一下解密函数所在的那个分支是不是真的会被执行到,有些字符串虽然技术上能够被解密,但是它们只待在那些早已废弃的代码或者专门用来反分析的逻辑里面,对实际程序并没有意义。
2、批量输出结果:其次,等到算法确认了以后,便可以利用JEB的脚本来批量地处理密文,并且给它加上注释;PNF示例代码里也曾经给出过在Java AST层面进行解密字符串脚本的思路,不过其说明文档也建议,在遇到更加复杂的场景时,最好优先考虑从中间表示层去进行处理。
3、区分自动解密和人工解密:再次,需要把JEB的自动解密功能和人工解密区分开来,JEB会在它认为安全且合理的范围里尝试清理代码并恢复一部分字符串,但并不是所有的保护手段都能够被它自动完成;在官方给出的案例里也提到过,受保护的二进制程序里面的字符串,有可能是在第一次被调用的时候才进行动态解密的,这还得结合反编译的结果继续往深里分析。
4、保留分析记录:最后,要把跟这次分析相关的记录都保留下来,比如密文所在的位置、负责解密的函数、密钥的来源、输出的样例还有调用的位置等等;这样一来,等到后续样本更新升级之后,就可以直接把记录拿来对照,看看算法到底有没有发生改变。
总结
所以,对JEB Decompiler进行字符串加密分析,大体上可以按照“先去查看字符串列表,再去搜索那些形态异常的密文,接着追踪交叉引用关系,然后定位到解密函数,最后再对输出结果进行验证”这样的顺序来推进。解密逻辑通常会集中在那些返回值为字符串类型的方法里头,常见的特征包括Base64编解码、异或运算、数组顺序的重新排列、固定不变的密钥以及循环变换操作。等到确定了具体的算法之后,再借用脚本来给明文批量地添加注释,这样分析的效率就能提高不少。
