V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
meso5533
V2EX  ›  JavaScript

有将 JS(非 TypeScript)编译成 wasm 然后用 JS 的 WebAssembly 接口调用的成功案例吗?

  •  1
     
  •   meso5533 · 2022-09-19 11:51:14 +08:00 · 4432 次点击
    这是一个创建于 801 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司想尝试用 wasm 作为 js 代码保护的一种方式

    如果确实不可行请敲醒我,我知道 wasm 本身不应该是这么用的

    目前试了一下: https://github.com/Shopify/javy

    按照他的教程编译后用 wasmtime 确实可以运行,但是用 JS 的 WebAssembly 接口调用就会报错:

    WebAssembly.instantiateStreaming(fetch("xxxxxxx/index.wasm"), {
      wasi_snapshot_preview1: {
        fd_close: (e) => {
          console.log("fd_close", e);
        },
        fd_write: (e) => {
          console.log("fd_write", e);
        },
        fd_read: (e) => {
          console.log("fd_read", e);
        },
        fd_seek: (e) => {
          console.log("fd_seek", e);
        },
        environ_get: (e) => {
          console.log("fd_environ_get", e);
        },
        environ_sizes_get: (e) => {
          console.log("fd_environ_sizes_get", e);
        },
        clock_time_get: (e) => {
          console.log("clock_time_get", e);
        },
        fd_fdstat_get: (e) => {
          console.log("fd_fdstat_get", e);
        },
        proc_exit: (e) => {
          console.log("proc_exit", e);
        },
      },
      env: {},
    }).then((obj) => {
      console.log(obj.instance.exports.main({ n: 100, bar: "test" }));
    });
    
    RuntimeError: unreachable
        at xxxxxxx/index.wasm:wasm-function[193]:0x110ec
        at xxxxxxx/index.wasm:wasm-function[318]:0x1a4fc
        at xxxxxxx/index.wasm:wasm-function[28]:0x1489
        at xxxxxxx/index.wasm:wasm-function[88]:0x728f
        at xxxxxxx/index.wasm:wasm-function[57]:0x38ab
        at xxxxxxx/index.wasm:wasm-function[287]:0x18880
        at xxxxxxx/index.wasm:wasm-function[39]:0x1cb6
        at xxxxxxx/index.wasm:wasm-function[193]:0x11422
        at xxxxxxx/index.wasm:wasm-function[318]:0x1a4fc
        at xxxxxxx/index.wasm:wasm-function[28]:0x1489
    
    第 1 条附言  ·  2022-09-19 14:29:07 +08:00
    研究了一下,将 js 打包成 wasm 的原理好像都是在 wasm 实现一个简单的 js 运行时来执行代码
    js 不能直接地打包成 wasm 的原因好像是因为它是动态语言,不能很好地编译成 WebAssembly 字节码?
    反正公司暂时放弃这个想法了
    祝大家摸鱼快乐!
    16 条回复    2022-09-23 15:09:58 +08:00
    mxT52CRuqR6o5
        1
    mxT52CRuqR6o5  
       2022-09-19 11:53:50 +08:00
    理论上没觉得哪里有问题,而且用 wasm 加密是一个很正常的用法
    lmshl
        2
    lmshl  
       2022-09-19 12:20:58 +08:00 via iPhone
    不存在的
    唯一最接近的是 AssemblyScript ,是一个 typescript 子集,限制了 ts 动态能力的语言。
    如果确实有必要,可以考虑将系统核心逻辑用 rust 编写,比如抢红包或下单前的检查,签名生成等,最后在中调用这部分逻辑。

    或者简单点,找个混淆器把 js 混淆一遍也够了
    nomagick
        3
    nomagick  
       2022-09-19 12:26:30 +08:00   ❤️ 1
    在浏览器运行的代码有啥好保护的,敝帚自珍

    移除一下注释和换行,加密好了
    wdwwtzy
        4
    wdwwtzy  
       2022-09-19 12:29:59 +08:00   ❤️ 1
    不如用 c# 来写 WebAssembly ,最终浏览器加载的都是编译后的 dll
    参见 demo
    https://blazor-demo.github.io/Counter
    rekulas
        5
    rekulas  
       2022-09-19 13:36:45 +08:00
    @nomagick 前端也相当于一个 app ,可以直接分析出与后端的交互逻辑,自然也有加密意义
    taowen
        6
    taowen  
       2022-09-19 14:39:28 +08:00
    可以用 webassembly 编译一个 quickjs ,类似 https://github.com/taowen/define-function/blob/main/build.sh
    然后用 https://openkraken.com/guide/advanced/use-quickjs-bytecode 把 js 转成 bytecode
    jones2000
        7
    jones2000  
       2022-09-19 14:47:15 +08:00
    用 c++写呗, 门槛高, 卷的人也少,做 ppt 的时候,这个功能还是一个亮点可以吹。
    qrobot
        8
    qrobot  
       2022-09-19 14:56:00 +08:00
    思路很新奇, 但是反编译 wasm 难吗? 直接 wasm-decompile 反编译, 甚至比 js 的可读性还高
    0o0O0o0O0o
        9
    0o0O0o0O0o  
       2022-09-19 15:21:22 +08:00 via iPhone
    如果公司就是想探索这方面,为了应付差事,可以考虑#6 的方案,不过最好修改一下 quickjs 的 opcode 。

    因为最近分析过一个挺大的 wasm 应用,unity 编写 il2cpp 后再编译成了 wasm ,个人感觉,将足够复杂的 c/cpp 编写的运行时编译为 wasm 目前在保护方面还是很有用的。而且可以结合 c/cpp 的一些传统保护思路来做。
    DingJZ
        10
    DingJZ  
       2022-09-19 15:46:03 +08:00
    https://www.infoq.cn/article/Rdm3z4k0Q8HkOFSxshcm?utm_source=rss&utm_medium=article
    之前看过的一个分享,没试过,看理论可行
    0o0O0o0O0o
        11
    0o0O0o0O0o  
       2022-09-19 16:04:52 +08:00 via iPhone
    @DingJZ 这个作者印象深刻,他在 V2EX 发过一个早期的"vmp"实现
    /t/549319
    还发过一些前端保护的总结
    /t/552383

    然后这类话题每次都会产生"前端代码是否需要保护"的争论,哈哈
    HFX3389
        12
    HFX3389  
       2022-09-19 16:52:02 +08:00
    @0o0O0o0O0o #11 就怕前端代码保护的是:以下内容需要关注公众号回复“密码”,获取密码后才能继续观看;登录后可见
    YuJianrong
        13
    YuJianrong  
       2022-09-19 23:18:15 +08:00
    #6 题主引用的这个“javy”就是基于 quickjs 的。
    用于保护源代码也不是不行,不过从性能上看这样跑的 JS 慢了成百上千倍,还有一些本来其他虚拟机没有的问题(比如 quickjs 是用引用计数的,会循环引用造成泄漏)。quickjs 这个方案主要是用于在一个 JS 环境中安全地运行第三方的 JS 代码,不是用于加密客户端代码的。
    现代 JS 工具链(比如 webpack+terser )会把几乎所有的可读函数名、变量名全部改掉并精简代码,可读性几乎为 0 了,用另一个虚拟机只是能更大程度增加破解困难度而已。
    DingJZ
        14
    DingJZ  
       2022-09-20 12:07:00 +08:00
    @0o0O0o0O0o #11 离谱,之前没看过前面这些,包括这个贴下面的评论,很好玩。
    昨天看了一篇文章,找不到原文了,讲近两年前端的分享大会之类的,听众的想法都是这做的是啥,又 tm 用不到,我没有场景。
    不如只关注技术,好玩最重要。
    seakingii
        15
    seakingii  
       2022-09-20 13:11:07 +08:00
    推荐用其它语言,比如 RUST,GO,C#写 WASM 供 JAVASCRIPT 调用,这些方案成熟点
    用 JS 写 WASM 我倒是没怎么见过
    humbass
        16
    humbass  
       2022-09-23 15:09:58 +08:00
    按 OP 的说法,如果是为了保护代码,在 NODEJS 这边可以直接使用 V8 的虚拟机保护。只要指定 node 版本就可以了,浏览器的话只能使用 WASM 方案了,核心的逻辑部分改成 TS 写,就可以直接编译为 WASM 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3027 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:34 · PVG 08:34 · LAX 16:34 · JFK 19:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.