使用WebAssembly保护前端JS核心代码实战

本文介绍了如何使用WebAssembly保护前端JavaScript核心代码,以防止高级命令生成和激活逻辑被轻易查看。通过emscripten将C代码编译为.wasm文件,实现了在前端直接执行和校验命令,减少了服务器压力。虽然WebAssembly提供了代码保护,但依然存在反编译的风险。
摘要由CSDN通过智能技术生成

前言

上个月我花了2天开发了一个全新的VSCode插件叫“我爱掘金”,让所有掘友可以化身为小蝌蚪,在VSCode里实时聊天。使用的是一个开源项目 workerman-todpole ,在原项目的基础上我做了大量的修改和优化。也曾试图添加一些房管功能,比如只有管理员可以使用大红色,只有管理员可以发光等等。

图片

但正义的掘友们很快就开始尝试各种能打破这种【不平等】待遇的方法,其中 @那猫小帅 同学还开发了各种 池塘机器人,可以在池塘里扮演给新手用户提供帮助的NPC。现在小蝌蚪大眼睛的创意也是那猫小帅同学提出的,简直棒棒哒💯。

需求

要实现房管功能,我需要实现一个方法,来生成和激活高级命令,激活后则可以获得高级权限。显然,我不想被别人看到这段代码里我是如何生成命令和校验命令的。

我也不想放到服务器上做成一个后端接口,因为每次都去请求接口会对服务器产生压力。而websocket每次收到消息时都需要去验证这个高级命令

所以,我确定了两个核心诉求

  • 高级命令的生成和激活直接在前端完成,避免请求服务器。

  • 不能让人看到生成和激活的核心逻辑,否则就失去了意义。

一番调研之后,发现WebAssembly可以满足我的这两点需求,接下来就是实战了。

WebAssembly介绍

WebAssembly 有一套完整的语义,并且可以生成一种 .wasm 的二进制格式,体积小且加载快, 其目标就是充分发挥硬件能力以达到原生执行效率。

运行仍然是在浏览器里,但使用一种二进制格式的.wasm文件 ,这完全能满足我的需求,并且主流浏览器对WebAssembly的兼容性很好。

比如下面这段代码,大家可以复制粘贴到浏览器的调试窗口中感受一下

WebAssembly.compile(new Uint8Array(`
  00 61 73 6d  01 00 00 00  01 0c 02 60  02 7f 7f 01
  7f 60 01 7f  01 7f 03 03  02 00 01 07  10 02 03 61
  64 64 00 00  06 73 71 75  61 72 65 00  01 0a 13 02
  08 00 20 00  20 01 6a 0f  0b 08 00 20  00 20 00 6c
  0f 0b`.trim().split(/[\s\r\n]+/g).map(str => parseInt
WebAssembly(Wasm)是一种可以在现代浏览器中运行的低级字节码格式,它旨在提供一个编译目标,可以在多种语言中编译,其中包括C++。C++编译到WebAssembly后,可以在支持WebAssembly的浏览器环境中运行,与JavaScript代码进行交互。 C++代码WebAssembly模块中运行时,可以通过WebAssemblyJavaScript接口调用宿主环境(即浏览器)中的JavaScript函数。这允许WebAssembly模块使用JavaScript的功能,例如DOM操作、异步操作、网络请求等。 要在WebAssembly中调用JavaScript代码,你需要在C++代码中定义一个JavaScript函数接口,并通过WebAssembly暴露出来。然后在JavaScript中实例化WebAssembly模块,并通过WebAssembly暴露的接口调用C++函数。以下是一个简单的例子: 1. 在C++代码中,你可以使用`EMSCRIPTEN`提供的工具和宏来定义一个可以被JavaScript调用的函数: ```cpp #include <emscripten/emscripten.h> extern "C" { EMSCRIPTEN_KEEPALIVE int add(int a, int b) { return a + b; } } ``` 2. 将C++代码编译为WebAssembly模块: 使用Emscripten编译器(`emcc`)编译上述代码WebAssembly。 3. 在JavaScript代码中加载并实例化WebAssembly模块: ```javascript WebAssembly.instantiateStreaming(fetch('your_module.wasm'), importObject) .then(result => { const exports = result.instance.exports; console.log(exports.add(1, 2)); // 这将输出3 }); ``` 通过这种方式,C++代码中的函数就可以被JavaScript调用,反之亦然。C++代码可以作为后端逻辑,通过这种方式与前端JavaScript代码进行交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大帅老猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值