难点在于
1.vmp虚拟机,自定义的寄存器和堆栈数据管理。
2.快速迭代的版本,没有标准的快照格式进行解析。
1.基于重打包和静态快照解析不可靠。
reFlutter和JEB推出了两种快照分析方式。
一个是基于动态的重打包替换dump。
一个是JEB推出的静态解析插件,针对特定的版本格式解析。
这种很容易针对,修改一下快照的版本hash值就全部失效。这在reflutter下的issue全是版本失效的问题,甚至我可以故意给个错误的版本hash,让你替换之后报错还找不到原因。
静态解析那也可以针对,除了修改版本还可以修改字节顺序,静态依赖于源码的解析顺序。我把这个顺序改了静态解析直接挂。
如果有一种不依赖于特定版本的快照解析工具才算是完整的解析工具。所以我理想的解析快照应该像jadx那种一样。
2.也不是一定要分析libapp.so
flutter的侧重在于ui展示,很多加密相关的东西其实还是会用传统的NDK去写。一上来就分析libapp其实不太对,除非整个app只有libapp一个so。
hook 原生到flutter的通信服务可以拦截到许多信息。
3.分析libapp步骤
这个不太好说,事实上我没有一个准确的路线步骤去分析这个。
大概率上,如果我不清楚他的版本我只能硬着头皮打开ida去分析。
假设有一个so字符串没有处理而且方法名保留了下来,还是有大概率能分析的。
有时间我给一个自写的demo处理。
编译阶段加上混淆选择
flutter build apk --release
架构
flutter build apk --target-platform android-arm64 --release 不加混淆
flutter build apk --target-platform android-arm64 --release --obfuscate --split-debug-info=/<project-name>/<directory> 加上混淆
好消息是 flutter混淆只开启了方法命的混淆,代码流程上不会进行混淆。 本身字符串也不会被加密 所以问题不大。
坏消息是 即使是这样我们也找不到对应的方法体。
如果你是开发者 可以找到 生成的 app.android-xxx.symbols 混淆对应文件
但是你是逆向开发肯定拿不到这些东西,当然也有人提出过其他方案来恢复抹去的方法名。
比如:
1.二进制文件对比
这个技巧在于如果软件发布者发布了两个版本,一个没有混淆一个混淆了。而且两个版本差异不大的情况下,使用文本对比工具找出某些只有方法名不同的区段。
这个方法只能说太玄学了。
2.引擎文件对比
有时候我们只想知道哪些方法属于框架本身,哪些方法属于软件本身。同样可以使用一些对比工具,不过还是要找对版本对比。工程量还是很大的。
到这里大家应该放弃了对混淆函数的命名恢复工作,下面我们来想一下。我们必须要知道符号才能逆向吗。
虽然getMd5/getBase64确实比 sub_xx1/sub_xx2看起来要直观的多,但是也并非完全不可行。
数据方法调用追踪
在界面上输入一个字符串 111 经过加密变成 222 显示出来
在界面上输入一个字符串 222 经过加密变成 333 显示出来
你可能直接猜到了经过了什么方法进行了运算,即使你没有打开ida做任何分析。
但是没有这么简单的过程给你,就像是一个大大的黑盒。你的输入可能经过了n次方法才输出一个很长的加密字符给你。
回想一下ndk里面调用jni方法进行加密的操作,即使进行了ollvm混淆。我们可以通过伪C代码分析参数的传递,
然后使用frida等工具不断的hook分析。依然可以找到真正的分支进行处理,也能大概分析出参数的流转过程。
到了flutter这里有什么问题呢:
1.没有一键f5变成伪c代码,目前还没有工具可以做到这点。大概率以后也不会有。
2.没有直接的调用关系,方法之间使用共享池子间接的调用。关于这点后面会提到。
[注意]APP应用上架合规检测服务,协助应用顺利上架!
最后于 2022-11-4 17:34
被小黄鸭爱学习编辑
,原因: