首页
社区
课程
招聘
[原创]typora的launch.dist.js解读
发表于: 1天前 667

[原创]typora的launch.dist.js解读

1天前
667

我在研究typora逆向的时候我遇到了JSC 

我很感兴趣 

好奇JS本身是不支持加载JSC的 

它是如何做到require的时候引入了JSC的 

过程中发现它是来自于:

7d5K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6T1P5i4c8W2L8X3!0V1k6g2)9J5c8X3u0&6N6r3g2F1L8$3c8W2 这个项目 

把JS变成JSC的里面会自动嵌入进去这段js加载逻辑


JS本身不支持运行V8编译的字节码(JSC)

但Bytenode作者利用了

Node暴露的V8 code cache被借来执行编译好的字节码

我们可以看到上面图片

答案是写上上面了

原因是它修改了 Node 的模块加载机制

Module._extensions[".jsc"] = loadJsc;

当遇到.jsc文件的时候 会走loadJsc函数


我们详细看看loadJsc函数

首先是一个fs.readFileSync

读取里面字节buffer

用了一个setFlagHashHeader函数 

目的是

为了把dummyBytecode里面的V8 header复制到JSC buffer里面 

让JSC代码执行的时候可以通过V8引擎的校验


大白话:


相当于:

告诉V8:这个bytecode是在你当前配置下生成的


问:他们V8在执行这个JSC文件字节码不对应的问题?

答:Typora 自带完整的 Electron 运行  不依赖系统安装的 Node.js 或 V8 所以不需要 并且JSC也是里面自带的V8引擎编译的


问:既然引擎是同一套 那为什么会出现flag hash不同出现需要特地覆盖的情况?

答:是因为构造时的JSC V8引擎的参数是默认参数  然后在执行JSC后的V8引擎不是默认参数 如下图


Launch.dist.js里面在V8引擎执行的时候加入了以下的参数

最终才导致的flag hash变化

接着继续看

sourceLength是在读取源码的长度为空间开辟做准备

buffer.slice(8,12)可以读取出jsc的源码长度

buffer2Number是把大端数据变成小端数据

dummySource用”\u200b”

原因也是很无聊

(我开始以为是什么很厉害的说法 干嘛不直接用空格) 

就是因为单纯人看不到而已


V8官方代码里面就是只对长度进行hash 

也就是长度对的上就行了

在开辟成功后会把开辟好的放到vm.script中占位让V8接受cachedData   V8本身设计也是这样如果cachedData通过校验了那就会优先运行它  

你可以认为是缓存来的 

对于V8来说这样可以节省编译时间


大白话:

优先读字节码

是因为 「同一份脚本编译过就别再编译」 这个性能设计

runInThisContext就是相当于开关运行了

总结:

作者的思路很巧妙

能够特地去研究V8引擎的特性利用cache来运行字节码

还能够实现保护增加逆向难度


[内核课程]《Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

收藏
免费 0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回