一、目标
App安全的主战场在Native层,分析Native层的so,最趁手的兵器就是Frida和Unidbg了。
今天我们的目标是 某汽车社区App v8.0.1 so 的分析。
二、步骤
特征字符串定位
我们在上一篇教程 某汽车社区App 签名和加解密分析 已经定位了,数据加密和解密函数再java层的位置。
按照常理来说,这个java类文件中,应该有个 System.loadLibrary("libxxx") 来方便我们定位对应的so。
可惜的是,这个样本里找不到。原因大概率是脱壳不完整。
既然没这么简单,我们再回忆一下加密串的特征:
1、sd= 开头
2、数据都是大写的M开头
3、== 结尾,那大概率是Base64
有共性就好办了,我们在Native层匹配下 M 开头的字符串,匹配到了就打印Native层的堆栈。
代码语言:txt复制if(string.toString().length > 50 && string.toString().indexOf("M") == 0){
var threadef = Java.use('java.lang.Thread');
var threadinstance = threadef.$new();
console.log("[NewStringUTF] bytes:" string);
console.log(Thread.backtrace(this.context, Backtracer.FUZZY)
.map(DebugSymbol.fromAddress).join("n"))
}
跑一下
结果是出来了,但是这个结果很有料呀。 没听说过江湖上有 1ef38371-d2a4-4ade-8510-d08f5c05fe5f-32.so 这种名号的so。
全局搜索
这个奇怪的so在apk里面肯定是找不到了。我们在手机里去找一找。
要玩好Android,那么linux命令不可少,搜索文件用find命令
代码语言:txt复制find / -name '1ef38371-d2a4-4ade-8510-d08f5c05fe5f-32.so' -print
我去,没道理呀,居然搜不到?当然不会是我们find命令输错了。
在加密或者加壳的手段下,是可以实现手机只有加密文件,只在内存中加载解密后的so。
Frida Dump So
今天的重头戏就是这个了。so在内存里面,如何把它搞出来?
第一步: 把冰箱门打开
代码语言:txt复制var libxx = Process.getModuleByName("210f3bcc-51b1-4f3c-9ca4-c429ad93ded1-32.so");
console.log("*****************************************************");
console.log("name: " libxx.name);
console.log("base: " libxx.base);
console.log("size: " ptr(libxx.size));
打印出了这个神奇的so的地址和大小
代码语言:txt复制*****************************************************
name: 210f3bcc-51b1-4f3c-9ca4-c429ad93ded1-32.so
base: 0xc380c000
size: 0xec9000
第二步:把大象塞进冰箱
代码语言:txt复制var file_path = "/data/data/com.clxxx.lxxxlxxxbxxx/" libxx.name "_" libxx.base "_" ptr(libxx.size) ".so";
console.log(file_path);
var file_handle = new File(file_path, "wb");
if (file_handle && file_handle != null) {
Memory.protect(ptr(libxx.base), libxx.size, 'rwx');
var libso_buffer = ptr(libxx.base).readByteArray(libxx.size);
file_handle.write(libso_buffer);
file_handle.flush();
file_handle.close();
console.log("[dump]:", file_path);
}
注意: 写so文件的时候,把文件写在 /data/data/包名 目录下,这个目录大概率下是可以读写的。
第三步: 把冰箱门关上
最后把dump的so用adb命令 pull出来。
如果没有pull /data/data/包名 这个目录的权限,那就先copy到 /data/local/tmp 目录下面。
现在可以拖进ida愉快的分析了。
三、总结
先找共性,然后再定位。字符串定位的套路都是一样的。
如果样本没有调用 NewStringUTF 或者 GetStringUTFChars 怎么办?
我觉得还可以考虑libc.so, malloc strcpy 这些标准C函数 Hook一下,应该也会有惊喜。
Linux命令可以熟悉下,关键时刻还是有用的。
俄罗斯方块教会了我们,如果你合群,就会消失。
TIP: 本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,欢迎加入知识星球一起学习探讨技术。