Android 应用gl,使用了加固i,老版本的应用gl是js源码,新版本更新后,刚开始以为是加密了源码,分析后才知道是使用了Hermes优化引擎。
Hermes是Facebook为React Native开源的一款javascript优化引擎。
原来的index.android.bundle是javascript的,被Hermes优化后变成了Bytecode。
Hermes优化的优化效果如下:
优化前:

优化后:

应用gl使用了加固i,在被root 的手机上运行,闪退。
绕过方法也很简单,在magisk的设置中,开启遵守排除列表,然后在配置排除列表中选择应用gl

应用被添加到排除列表后,将没办法使用lspoed,只能使用frida

抓包可以看到登录接口有个signcode加密参数,69e34d747c5757236142a19f4595d313 是32位字符串,猜测跟md5相关
由于我分析过应用gl前面版本,所以知道它是React Native开发的
但当你们拿到新app的时候,需要先对apk文件,app数据目录进行一次搜索
解压 apk, 使用命令 grep -r "signcode" *,搜索一下apk下有没有signcode,第一次没搜到(备注:应用gl把代码打包到assets/android-rn.zip里了)
在app的数据目录下,使用命令 grep -r "signcode" *,搜索一下,在文件./files/RN/rnbundle/index.android.bundle下搜索到了signcode
把./files/RN/rnbundle/index.android.bundle拿出来
使用010editor打开后,就看到如下图的内容:

刚打开index.android.bundle, 我就猜测这个文件难道被加密了?(备注:在这之前我没有分析过被Hermes优化的应用)。
因为应用gl有加固i,我并没有研究加固,于是只能研究React Native的源码,看不能找到最终加载源码的地方
下载源码 c44K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6X3j5h3y4W2j5X3!0G2K9#2)9J5c8Y4u0W2j5h3y4@1i4K6u0V1L8X3q4@1K9i4k6W2i4K6u0W2k6$3W2@1
在源码中搜索 LoadScript,找到2个可疑的函数
这2个函数是native,使用3f2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6D9j5i4y4@1K9h3&6Y4i4K6u0V1P5h3q4F1k6#2)9J5c8X3k6J5K9h3c8S2i4K6g2X3K9r3!0G2K9#2)9#2k6X3I4A6j5X3q4J5N6q4)9J5c8X3u0D9L8$3u0Q4x3V1k6E0j5i4y4@1k6i4u0Q4x3V1k6Z5L8$3!0C8i4K6g2X3f1X3g2Y4K9i4y4@1k6i4u0z5j5i4c8A6N6X3g2K6i4K6u0W2K9Y4y4Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0g2Q4z5p5k6Q4b7f1k6Q4c8e0c8Q4b7V1u0Q4b7e0g2Q4c8e0k6Q4z5o6W2Q4b7V1g2Q4c8e0g2Q4z5o6S2Q4b7U0m8Q4c8e0g2Q4z5o6N6Q4b7V1c8Q4c8e0k6Q4z5e0g2Q4b7U0m8Q4c8e0g2Q4b7f1k6Q4b7U0W2Q4c8e0g2Q4b7V1q4Q4z5e0c8Q4c8e0N6Q4z5f1q4Q4z5o6c8K6L8H3`.`.
对jniLoadScriptFromAssets和jniLoadScriptFromFile进行hook,需要配合hook_dlopen一起使用,因为frida注入的时候,libreactnativejni.so还没有加载。
jniLoadScriptFromFile被加载,传入参数为index.android.bundle文件路径
继续阅读源码,jniLoadScriptFromFile中会调用loadScriptFromString
loadScriptFromString
hook loadScriptFromString后,可以知道loadSynchronously为0, 继续分析loadBundle
runOnExecutorQueue的参数是一个Lambda表达式,它的回调函数里面调用了loadBundle,在源码中搜索loadBundle,找到了很多处实现代码,这时候我们酒不知道loadBundle具体实现在哪里,继续写hook代码hook_loadBundle
facebook::react::JSIExecutor::loadBundle函数中调用了evaluateJavaScript
hook "*evaluateJavaScript*",
evaluateJavaScriptWithSourceMap函数 在React Native源码中没有搜到,在另一个hermes项目(e7aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6X3j5h3y4W2j5X3!0G2K9#2)9J5c8X3S2W2M7X3#2W2M7#2!0q4c8W2!0n7b7#2)9^5z5g2!0q4y4q4!0n7z5q4!0m8c8q4!0q4y4W2)9^5z5g2!0n7c8g2!0q4y4g2)9^5z5q4!0n7x3q4!0q4y4q4!0n7b7g2)9^5y4X3g2$3j5h3I4#2j5i4c8W2d9X3q4$3j5g2y4U0M7X3W2H3N6q4N6A6N6r3S2e0L8%4g2J5j5$3g2y4j5i4m8Q4c8e0g2Q4z5o6N6Q4b7V1c8Q4c8e0k6Q4z5e0g2Q4b7U0m8Q4c8e0g2Q4z5e0u0Q4z5p5y4W2N6X3q4D9N6h3q4@1k6f1A6S2N6X3q4e0j5%4u0A6M7s2c8Q4c8e0g2Q4z5o6N6Q4b7V1c8Q4c8e0k6Q4z5e0g2Q4b7U0l9`.
evaluateJavaScript函数对应so的地址0xbb867431 libhermes.so!0x11431
evaluateJavaScriptWithSourceMap函数中调用了prepareJavaScriptWithSourceMap函数, 继续调用isHermesBytecode函数
isHermesBytecode用来判断是否是Hermes的Bytecode
MAGIC和index.android.bunddle的前8个字节是一直的,至此已经知道index.android.bundle并不是被应用gl加密了,而是被Hermes编译成了bytecode

前面的分析过程,已经知道了index.android.bundle是Hermes的bytecode,没办法直接查看源码,需要借助其他工具进行反编译
Hermes官方提供了hbcdump工具,可以进行反编译,但使用起来比较麻烦,有另一个开源工具hbctool可以对hermesbytecode进行反编译与回编译
57eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6T1L8$3&6Y4N6s2u0G2M7q4)9J5c8X3S2T1j5%4c8G2L8$3H3`. 提供了59, 62, 74, 76版本的反编译
2e2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6F1K9h3!0K6k6h3N6S2i4K6u0r3K9r3u0U0N6r3!0G2L8q4)9J5c8Y4c8J5k6h3g2Q4x3V1k6V1M7X3q4X3N6q4)9J5c8X3S2T1j5#2)9J5k6s2j5^5y4l9`.`. 对84版本的Hermes进行补充
安装可以反编译84版本的hbctool
反编译
回编译
bytecode反编译出来的代码如下:搜索两处能md5相关的代码


并不需要深入bytecode,指令详情,了解几个简单指令即可。
只需要写一个打印日志的函数,变成成bytecode,反编译后替换掉这两个函数就能看到这两个md5函数的输入参数
先编译Hermes源码,会得到./build/bin/hermes工具,
test.js
写了一些简单的js代码,把test.js编译成bytecode
010editor打开test.hbc可以看到MAGIC

反编译test.hbc
得到
把反编译出来的bytecode,替换到md5函数中
需要对字符串的id进行修改,字符串对应hbctool反编译出来的string.json中的字符串id
再次回编译,得到index.android.bundle.re
现在替换app目录下的index.android.bundle
结束app, 运行 adb logcat "*:S ReactNative:V ReactNativeJS:V", 再次运行app就可以到得到md5函数的输入参数
算法分析完成
e0eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6X3j5h3y4W2j5X3!0G2K9#2)9J5c8Y4u0W2j5h3y4@1i4K6u0V1L8X3q4@1K9i4k6W2i4K6u0W2k6$3W2@1
aaeK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6D9j5i4y4@1K9h3&6Y4i4K6u0V1P5h3q4F1k6#2)9J5c8X3k6J5K9h3c8S2i4K6g2X3K9r3!0G2K9#2)9#2k6X3I4A6j5X3q4J5N6l9`.`.
352K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6X3j5h3y4W2j5X3!0G2K9#2)9J5c8X3S2W2M7X3#2W2M7H3`.`.
3f6K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6T1L8$3&6Y4N6s2u0G2M7q4)9J5c8X3S2T1j5%4c8G2L8$3H3`.
63dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6F1K9h3!0K6k6h3N6S2i4K6u0r3K9r3u0U0N6r3!0G2L8q4)9J5c8Y4c8J5k6h3g2Q4x3V1k6V1M7X3q4X3N6q4)9J5c8X3S2T1j5#2)9J5k6s2j5^5y4l9`.`.
function hook_ssl() {
Java.perform(function () {
var ClassName
=
"com.android.org.conscrypt.Platform"
;
var Platform
=
Java.use(ClassName);
var targetMethod
=
"checkServerTrusted"
;
var
len
=
Platform[targetMethod].overloads.length;
console.log(targetMethod,
len
);
for
(var i
=
0
; i <
len
;
+
+
i) {
Platform[targetMethod].overloads[i].implementation
=
function () {
console.log(
"class:"
, ClassName,
"target:"
, targetMethod,
" i:"
, i, arguments);
};
}
var ClassName
=
"com.android.org.conscrypt.TrustManagerImpl"
;
var Platform
=
Java.use(ClassName);
var targetMethod
=
"checkTrustedRecursive"
;
var
len
=
Platform[targetMethod].overloads.length;
console.log(targetMethod,
len
);
var ArrayList
=
Java.use(
"java.util.ArrayList"
)
var X509Certificate
=
Java.use(
"java.security.cert.X509Certificate"
);
for
(var i
=
0
; i <
len
;
+
+
i) {
Platform[targetMethod].overloads[i].implementation
=
function () {
console.log(
"class:"
, ClassName,
"target:"
, targetMethod,
" i:"
, i, arguments);
return
ArrayList.$new();
};
}
});
}
function hook_ssl() {
Java.perform(function () {
var ClassName
=
"com.android.org.conscrypt.Platform"
;
var Platform
=
Java.use(ClassName);
var targetMethod
=
"checkServerTrusted"
;
var
len
=
Platform[targetMethod].overloads.length;
console.log(targetMethod,
len
);
for
(var i
=
0
; i <
len
;
+
+
i) {
Platform[targetMethod].overloads[i].implementation
=
function () {
console.log(
"class:"
, ClassName,
"target:"
, targetMethod,
" i:"
, i, arguments);
};
}
var ClassName
=
"com.android.org.conscrypt.TrustManagerImpl"
;
var Platform
=
Java.use(ClassName);
var targetMethod
=
"checkTrustedRecursive"
;
var
len
=
Platform[targetMethod].overloads.length;
console.log(targetMethod,
len
);
var ArrayList
=
Java.use(
"java.util.ArrayList"
)
var X509Certificate
=
Java.use(
"java.security.cert.X509Certificate"
);
for
(var i
=
0
; i <
len
;
+
+
i) {
Platform[targetMethod].overloads[i].implementation
=
function () {
console.log(
"class:"
, ClassName,
"target:"
, targetMethod,
" i:"
, i, arguments);
return
ArrayList.$new();
};
}
});
}
Binary
file
.
/
files
/
RN
/
rnbundle
/
index.android.bundle matches
Binary
file
.
/
files
/
RN
/
rnbundle
/
index.android.bundle matches
cp .
/
files
/
RN
/
rnbundle
/
index.android.bundle
/
data
/
local
/
tmp
/
index.android.bundle
chmod
777
/
data
/
local
/
tmp
/
index.android.bundle
adb pull
/
data
/
local
/
tmp
/
index.android.bundle
cp .
/
files
/
RN
/
rnbundle
/
index.android.bundle
/
data
/
local
/
tmp
/
index.android.bundle
chmod
777
/
data
/
local
/
tmp
/
index.android.bundle
adb pull
/
data
/
local
/
tmp
/
index.android.bundle
private native void jniLoadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously);
private native void jniLoadScriptFromFile(String fileName, String sourceURL, boolean loadSynchronously);
private native void jniLoadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously);
private native void jniLoadScriptFromFile(String fileName, String sourceURL, boolean loadSynchronously);
[RegisterNatives] java_class: com.facebook.react.bridge.CatalystInstanceImpl name: jniLoadScriptFromAssets sig: (Landroid
/
content
/
res
/
AssetManager;Ljava
/
lang
/
String;Z)V fnPtr:
0xb4e99a85
fnOffset:
0x80a85
callee:
0xb4d2021d
libhermes
-
executor
-
release.so!_ZN8facebook3jni6JClass15registerNativesESt16initializer_listI15JNINativeMethodE
+
0x20
[RegisterNatives] java_class: com.facebook.react.bridge.CatalystInstanceImpl name: jniLoadScriptFromFile sig: (Ljava
/
lang
/
String;Ljava
/
lang
/
String;Z)V fnPtr:
0xb4e99aa1
fnOffset:
0x80aa1
callee:
0xb4d2021d
libhermes
-
executor
-
release.so!_ZN8facebook3jni6JClass15registerNativesESt16initializer_listI15JNINativeMethodE
+
0x20
这时候会遇到一个问题,callee在libhermes
-
executor
-
release.so,使用ida打开libhermes
-
executor
-
release.so后,去fnOffset:
0x80a85
和fnOffset:
0x80aa1
找不到对应的函数。
于是使用frida的 Process.findModuleByAddress(ptr(
0xb4e99a85
)) 找jniLoadScriptFromAssets函数所在的模块,在libreactnativejni.so里面
{
"base"
:
"0xb4e19000"
,
"name"
:
"libreactnativejni.so"
,
"path"
:
"/data/app/~~klydM6uPsWM_heluFCfyKQ==/com.xxxxx.xxx.xxxxxxxxxx.xxxxxx-zC5SUJ_WxA0rwldHieq_fg==/lib/arm/libreactnativejni.so"
,
"size"
:
815104
}
[RegisterNatives] java_class: com.facebook.react.bridge.CatalystInstanceImpl name: jniLoadScriptFromAssets sig: (Landroid
/
content
/
res
/
AssetManager;Ljava
/
lang
/
String;Z)V fnPtr:
0xb4e99a85
fnOffset:
0x80a85
callee:
0xb4d2021d
libhermes
-
executor
-
release.so!_ZN8facebook3jni6JClass15registerNativesESt16initializer_listI15JNINativeMethodE
+
0x20
[RegisterNatives] java_class: com.facebook.react.bridge.CatalystInstanceImpl name: jniLoadScriptFromFile sig: (Ljava
/
lang
/
String;Ljava
/
lang
/
String;Z)V fnPtr:
0xb4e99aa1
fnOffset:
0x80aa1
callee:
0xb4d2021d
libhermes
-
executor
-
release.so!_ZN8facebook3jni6JClass15registerNativesESt16initializer_listI15JNINativeMethodE
+
0x20
这时候会遇到一个问题,callee在libhermes
-
executor
-
release.so,使用ida打开libhermes
-
executor
-
release.so后,去fnOffset:
0x80a85
和fnOffset:
0x80aa1
找不到对应的函数。
于是使用frida的 Process.findModuleByAddress(ptr(
0xb4e99a85
)) 找jniLoadScriptFromAssets函数所在的模块,在libreactnativejni.so里面
{
"base"
:
"0xb4e19000"
,
"name"
:
"libreactnativejni.so"
,
"path"
:
"/data/app/~~klydM6uPsWM_heluFCfyKQ==/com.xxxxx.xxx.xxxxxxxxxx.xxxxxx-zC5SUJ_WxA0rwldHieq_fg==/lib/arm/libreactnativejni.so"
,
"size"
:
815104
}
function hook_dlopen(module_name, fun) {
var android_dlopen_ext
=
Module.findExportByName(null,
"android_dlopen_ext"
);
if
(android_dlopen_ext) {
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
var pathptr
=
args[
0
];
if
(pathptr) {
this.path
=
(pathptr).readCString();
if
(this.path.indexOf(module_name) >
=
0
) {
this.canhook
=
true;
console.log(
"android_dlopen_ext:"
, this.path);
}
}
},
onLeave: function (retval) {
if
(this.canhook) {
fun();
}
}
});
}
}
function hook_libreactnativejni() {
let base_libreactnativejni
=
Module.findBaseAddress(
"libreactnativejni.so"
);
if
(base_libreactnativejni
=
=
null) {
return
;
}
let jniLoadScriptFromAssets
=
base_libreactnativejni.add(
0x80a85
);
let jniLoadScriptFromFile
=
base_libreactnativejni.add(
0x80aa1
);
/
/
private native void jniLoadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously);
Interceptor.attach(jniLoadScriptFromAssets, {
onEnter(args) {
console.log(
"jniLoadScriptFromAssets:"
, Java.vm.tryGetEnv().getStringUtfChars(args[
3
]).readCString())
}
})
/
/
private native void jniLoadScriptFromFile(String fileName, String sourceURL, boolean loadSynchronously);
Interceptor.attach(jniLoadScriptFromFile, {
onEnter(args) {
console.log(
"jniLoadScriptFromFile:"
, Java.vm.tryGetEnv().getStringUtfChars(args[
2
]).readCString(), Java.vm.tryGetEnv().getStringUtfChars(args[
3
]).readCString())
}
})
}
setImmediate(()
=
> {
hook_dlopen(
"libreactnativejni.so"
, hook_libreactnativejni)
hook_libreactnativejni();
})
function hook_dlopen(module_name, fun) {
var android_dlopen_ext
=
Module.findExportByName(null,
"android_dlopen_ext"
);
if
(android_dlopen_ext) {
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
var pathptr
=
args[
0
];
if
(pathptr) {
this.path
=
(pathptr).readCString();
if
(this.path.indexOf(module_name) >
=
0
) {
this.canhook
=
true;
console.log(
"android_dlopen_ext:"
, this.path);
}
}
},
onLeave: function (retval) {
if
(this.canhook) {
fun();
}
}
});
}
}
function hook_libreactnativejni() {
let base_libreactnativejni
=
Module.findBaseAddress(
"libreactnativejni.so"
);
if
(base_libreactnativejni
=
=
null) {
return
;
}
let jniLoadScriptFromAssets
=
base_libreactnativejni.add(
0x80a85
);
let jniLoadScriptFromFile
=
base_libreactnativejni.add(
0x80aa1
);
/
/
private native void jniLoadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously);
Interceptor.attach(jniLoadScriptFromAssets, {
onEnter(args) {
console.log(
"jniLoadScriptFromAssets:"
, Java.vm.tryGetEnv().getStringUtfChars(args[
3
]).readCString())
}
})
/
/
private native void jniLoadScriptFromFile(String fileName, String sourceURL, boolean loadSynchronously);
Interceptor.attach(jniLoadScriptFromFile, {
onEnter(args) {
console.log(
"jniLoadScriptFromFile:"
, Java.vm.tryGetEnv().getStringUtfChars(args[
2
]).readCString(), Java.vm.tryGetEnv().getStringUtfChars(args[
3
]).readCString())
}
})
}
setImmediate(()
=
> {
hook_dlopen(
"libreactnativejni.so"
, hook_libreactnativejni)
hook_libreactnativejni();
})
void CatalystInstanceImpl::jniLoadScriptFromFile(
const std::string &fileName,
const std::string &sourceURL,
bool
loadSynchronously) {
auto reactInstance
=
instance_;
if
(!reactInstance) {
return
;
}
switch (getScriptTagFromFile(fileName.c_str())) {
/
/
根据文件头判断脚本类型,
case ScriptTag::MetroHBCBundle: {
std::unique_ptr<const JSBigFileString> script;
RecoverableError::runRethrowingAsRecoverable<std::system_error>(
[&fileName, &script]() {
script
=
JSBigFileString::fromPath(fileName);
});
const char
*
buffer
=
script
-
>c_str();
uint32_t bufferLength
=
(uint32_t)script
-
>size();
uint32_t offset
=
8
;
while
(offset < bufferLength) {
uint32_t segment
=
offset
+
4
;
uint32_t moduleLength
=
bufferLength < segment ?
0
:
*
(((uint32_t
*
)
buffer
)
+
offset
/
4
);
reactInstance
-
>loadScriptFromString(
std::make_unique<const JSBigStdString>(
std::string(
buffer
+
segment,
buffer
+
moduleLength
+
segment)),
sourceURL,
false);
offset
+
=
((moduleLength
+
3
) & ~
3
)
+
4
;
}
break
;
}
case ScriptTag::RAMBundle:
instance_
-
>loadRAMBundleFromFile(fileName, sourceURL, loadSynchronously);
break
;
case ScriptTag::String:
default: {
std::unique_ptr<const JSBigFileString> script;
RecoverableError::runRethrowingAsRecoverable<std::system_error>(
[&fileName, &script]() {
script
=
JSBigFileString::fromPath(fileName);
});
instance_
-
>loadScriptFromString(
std::move(script), sourceURL, loadSynchronously);
}
}
}
void CatalystInstanceImpl::jniLoadScriptFromFile(
const std::string &fileName,
const std::string &sourceURL,
bool
loadSynchronously) {
auto reactInstance
=
instance_;
if
(!reactInstance) {
return
;
}
switch (getScriptTagFromFile(fileName.c_str())) {
/
/
根据文件头判断脚本类型,
case ScriptTag::MetroHBCBundle: {
std::unique_ptr<const JSBigFileString> script;
RecoverableError::runRethrowingAsRecoverable<std::system_error>(
[&fileName, &script]() {
script
=
JSBigFileString::fromPath(fileName);
});
const char
*
buffer
=
script
-
>c_str();
uint32_t bufferLength
=
(uint32_t)script
-
>size();
uint32_t offset
=
8
;
while
(offset < bufferLength) {
uint32_t segment
=
offset
+
4
;
uint32_t moduleLength
=
bufferLength < segment ?
0
:
*
(((uint32_t
*
)
buffer
)
+
offset
/
4
);
reactInstance
-
>loadScriptFromString(
std::make_unique<const JSBigStdString>(
std::string(
buffer
+
segment,
buffer
+
moduleLength
+
segment)),
sourceURL,
false);
offset
+
=
((moduleLength
+
3
) & ~
3
)
+
4
;
}
break
;
}
case ScriptTag::RAMBundle:
instance_
-
>loadRAMBundleFromFile(fileName, sourceURL, loadSynchronously);
break
;
case ScriptTag::String:
default: {
std::unique_ptr<const JSBigFileString> script;
RecoverableError::runRethrowingAsRecoverable<std::system_error>(
[&fileName, &script]() {
script
=
JSBigFileString::fromPath(fileName);
});
instance_
-
>loadScriptFromString(
std::move(script), sourceURL, loadSynchronously);
}
}
}
void Instance::loadScriptFromString(
std::unique_ptr<const JSBigString> string,
std::string sourceURL,
bool
loadSynchronously) {
SystraceSection s(
"Instance::loadScriptFromString"
,
"sourceURL"
, sourceURL);
if
(loadSynchronously) {
loadBundleSync(nullptr, std::move(string), std::move(sourceURL));
}
else
{
loadBundle(nullptr, std::move(string), std::move(sourceURL));
}
}
void Instance::loadScriptFromString(
std::unique_ptr<const JSBigString> string,
std::string sourceURL,
bool
loadSynchronously) {
SystraceSection s(
"Instance::loadScriptFromString"
,
"sourceURL"
, sourceURL);
if
(loadSynchronously) {
loadBundleSync(nullptr, std::move(string), std::move(sourceURL));
}
else
{
loadBundle(nullptr, std::move(string), std::move(sourceURL));
}
}
let loadScriptFromString
=
base_libreactnativejni.add(
0xA0BF8
+
1
);
Interceptor.attach(loadScriptFromString, {
onEnter(args) {
console.log(
"loadScriptFromString:"
, (args[
1
]), ptr(args[
2
]).add(Process.pointerSize
*
2
).readPointer().readCString(), args[
3
])
}
})
let loadScriptFromString
=
base_libreactnativejni.add(
0xA0BF8
+
1
);
Interceptor.attach(loadScriptFromString, {
onEnter(args) {
console.log(
"loadScriptFromString:"
, (args[
1
]), ptr(args[
2
]).add(Process.pointerSize
*
2
).readPointer().readCString(), args[
3
])
}
})
void Instance::loadBundle(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
callback_
-
>incrementPendingJSCalls();
SystraceSection s(
"Instance::loadBundle"
,
"sourceURL"
, sourceURL);
nativeToJsBridge_
-
>loadBundle(
std::move(bundleRegistry), std::move(string), std::move(sourceURL));
}
/
/
Instance::loadBundle调用了nativeToJsBridge_
-
>loadBundle,
void NativeToJsBridge::loadBundle(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL) {
runOnExecutorQueue(
[this,
bundleRegistryWrap
=
folly::makeMoveWrapper(std::move(bundleRegistry)),
startupScript
=
folly::makeMoveWrapper(std::move(startupScript)),
startupScriptSourceURL
=
std::move(startupScriptSourceURL)](JSExecutor
*
executor) mutable {
auto bundleRegistry
=
bundleRegistryWrap.move();
if
(bundleRegistry) {
executor
-
>setBundleRegistry(std::move(bundleRegistry));
}
try
{
executor
-
>loadBundle(
std::move(
*
startupScript), std::move(startupScriptSourceURL));
} catch (...) {
m_applicationScriptHasFailure
=
true;
throw;
}
});
}
/
/
NativeToJsBridge::loadBundle里面调用了NativeToJsBridge::runOnExecutorQueue
void Instance::loadBundle(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> string,
std::string sourceURL) {
callback_
-
>incrementPendingJSCalls();
SystraceSection s(
"Instance::loadBundle"
,
"sourceURL"
, sourceURL);
nativeToJsBridge_
-
>loadBundle(
std::move(bundleRegistry), std::move(string), std::move(sourceURL));
}
/
/
Instance::loadBundle调用了nativeToJsBridge_
-
>loadBundle,
void NativeToJsBridge::loadBundle(
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
std::unique_ptr<const JSBigString> startupScript,
std::string startupScriptSourceURL) {
runOnExecutorQueue(
[this,
bundleRegistryWrap
=
folly::makeMoveWrapper(std::move(bundleRegistry)),
startupScript
=
folly::makeMoveWrapper(std::move(startupScript)),
startupScriptSourceURL
=
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2022-7-4 22:16
被Imyang编辑
,原因: