在逆向某易新闻时,发现该App是个React App,请求参数生成逻辑似乎是在js层处理的。故此进行React Native逆向的学习。
React App js层
React Native是一个流行的跨平台移动应用开发框架,它允许开发者使用JavaScript 和 React 来构建应用。
使用 React Native 打包的应用,应用的一部分或全部界面和逻辑是用 JavaScript 实现的,而JavaScript 代码和资源会被打包成 main.jsbundle 文件,也可能通过https://github.com/facebook/hermes压缩成`Hermes`字节码文件(`.hbc`)。最终生成的文件的路径在asset目录下。
以某易新闻为例,asset目录下仅有一个basics.android.hbc文件,查看该文件信息:
1 2
| $ file basics.android.hbc basics.android.hbc: Hermes JavaScript bytecode, version 89
|
确认是Hermes JavaScript bytecode后,使用hermes-dec或者hbctool工具反编译出js文件(注意反编译工具支持得版本信息要对得上)
1 2 3 4 5 6 7 8 9 10
| D:\CTFTools\hermes-dec>python hbc_file_parser.py basics.android.hbc
D:\CTFTools\hermes-dec>python hbc_disassembler.py basics.android.hbc newsreader.hasm
[+] Disassembly output wrote to "newsreader.hasm"
D:\CTFTools\hermes-dec>python hbc_decompiler.py basics.android.hbc newsreader.js
[+] Decompiled output wrote to "newsreader.js"
|
然后看了一眼反编译出的js文件,发现进行了vmp保护!
对于js层的逆向,如果没有jsvmp的保护,可以在目标函数出添加自己的逻辑,打印日志,重新打包成bundle文件添加到App中
React App java层
React Native 加载 Bundle 的核心类是 CatalystInstanceImpl 或 JSBundleLoader。我们可以 Hook 它们的构造函数或加载方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| function findRNBundlePath() { Java.perform(function() { console.log("开始寻找 React Native Bundle 路径...");
try { var JSBundleLoader = Java.use("com.facebook.react.bridge.JSBundleLoader"); JSBundleLoader.createAssetLoader.implementation = function(context, assetUrl, syncFallback) { console.log("################ createAssetLoader Found Bundle (Assets) ################"); console.log("Asset URL: " + assetUrl); return this.createAssetLoader(context, assetUrl, syncFallback); };
JSBundleLoader.createFileLoader.overload('java.lang.String', 'java.lang.String', 'boolean').implementation = function(fileName, assetUrl, syncFallback) { console.log("################ createFileLoader Found Bundle (File) ################"); console.log("File Path: " + fileName); return this.createFileLoader(fileName, assetUrl, syncFallback); };
JSBundleLoader.createFileLoader.overload('java.lang.String').implementation = function(fileName) { console.log("################ createFileLoader Found Bundle (File) ################"); console.log("File Path: " + fileName); return this.createFileLoader(fileName); }; } catch(e) { console.log("JSBundleLoader hook failed: " + e); }
try { var ReactInstanceManagerBuilder = Java.use("com.facebook.react.ReactInstanceManagerBuilder"); ReactInstanceManagerBuilder.setBundleAssetName.implementation = function(name) { console.log("################ setBundleAssetName Bundle Name Set ################"); console.log("Name: " + name); return this.setBundleAssetName(name); }; ReactInstanceManagerBuilder.setJSBundleFile.implementation = function(path) { console.log("################ setJSBundleFile Bundle File Set ################"); console.log("Path: " + path); return this.setJSBundleFile(path); }; } catch(e) { } }); }
|
使用spawn模式,打印出它到底加载了哪个文件作为 Bundle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| [Pixel XL::com.netease.newsreader.activity ]-> 开始寻找 React Native Bundle 路径... # Path: assets://basics.android.hbc # # # Asset URL: assets://basics.android.hbc # Asset URL: assets://basics.android.hbc # Asset URL: assets://basics.android.hbc # Asset URL: assets://basics.android.hbc # Asset URL: assets://basics.android.hbc # Asset URL: assets://basics.android.hbc # Path: assets://basic_3.android.hbc # Asset URL: assets://basic_3.android.hbc # Path: assets://basics.android.hbc # Asset URL: assets://basics.android.hbc # Path: assets://basic_3.android.hbc # Asset URL: assets://basic_3.android.hbc
|
还额外加载了basic_3.android.hbc,但是在asset目录下找不到!
另外React Native开发的App通过LoadScript加载js脚本,也可以hook该函数获取相关信息。
参考:
https://github.com/bongtrop/hbctool
https://github.com/P1sec/hermes-dec
React应用逆向工程:深入解析与反编译JS文件技巧 - 云原生实践
从去哪儿看React Native安卓App逆向 - 吾爱破解 - 52pojie.cn
React Native Hermes 逆向实践-Android安全-看雪安全社区|专业技术交流与安全研究论坛
和原生端通信 · React Native 中文网
https://fuping.site/2023/11/23/ios-reverse-reactnative-case/
https://cloud.tencent.com/developer/article/1593007
https://reactnative.dev/docs/handling-touches