sablejs / sablejs Goto Github PK
View Code? Open in Web Editor NEW🏖️ The safer and faster ECMA5.1 interpreter written by JavaScript
License: Other
🏖️ The safer and faster ECMA5.1 interpreter written by JavaScript
License: Other
@zdrin If you want to new EventDispatcher, you should bind cax to sablejs, like cax4sablejs doc said:
const cax4sablejs = require("cax4sablejs");
const VM = require("sablejs/runtime")();
const vm = new VM();
cax4sablejs(vm); // that's all!
If you want to call sablejs inner function from outside, you can use vm.call
, for example:
// a function is on sablejs inner enviorment
function a(){
print('a');
}
// get sablejs inner function and call it
const global = vm.getGlobal();
const vA = vm.getProperty(global, 'a');
vm.call(vA, vm.createUndefined()); // will log 'a'
Originally posted by @ErosZy in #10 (comment)
一般自己打包后的代码,或者很多第三方库都是umd导出的,能否提供支持在run之后直接返回导出的内容,这样在易用性上和对现有项目的兼容上会好很多。
举一个场景,在一个项目里,只对不涉及dom的语言或者加密算法模块进行保护,其他模块不需要改动。
大佬 你好
假设我的js如下
function sign(data) {
//进行签名算法
return data;
}
编译后我如何通vm调用这个sign算法并传参呢
windows下执行sablejs -i fib.js -o ouput 能下载对应的编译工具,但是再次执行没有任何输出内容。
处理器: AMD Ryzen 5 5600G with Radeon Graphics
系统 Windows 11 专业版
使用webpack打包后的js文件无法编译
var sm4=new SM4Util(); let encryptDataCBC = sm4.encryptData_CBC('this is a test'); // 'let' should be 'var' print(encryptDataCBC); // 'console' and 'alert' not included in vm, so you should use 'print' insteadmodify and run it, you will get
key error! iv error! prbpqTP2HDcvvm9snbKC9Q==there is my original code and compiled result.
if you have any other problem, please reopen it, thanks.
多谢,
var sm4=new SM4Util(); let encryptDataCBC = sm4.encryptData_CBC('this is a test'); // 'let' should be 'var' print(encryptDataCBC); // 'console' and 'alert' not included in vm, so you should use 'print' insteadmodify and run it, you will get
key error! iv error! prbpqTP2HDcvvm9snbKC9Q==there is my original code and compiled result.
if you have any other problem, please reopen it, thanks.
多谢。顺便问一下,sablejs 2.0预计什么时间可以开源出来呢
Originally posted by @panchaowu in #25 (comment)
我试着这样创建一个 [1,2,3] 的包装对象,但貌似有问题,请大佬指教一下
const vArray = vm.createArray(3);
vm.setProperty(vArray, 0, vm.createNumber(1))
vm.setProperty(vArray, 1, vm.createNumber(2))
vm.setProperty(vArray, 2, vm.createNumber(3))
这能正确工作,是我搞错了,抱歉
Can sablejs faster than v8 engine ?
可以支持微信小程序么
Inspired by this article, but it looks like this repo has been inactive for a while, so I am curious about the progress and feature of sablejs.
转换vite打包后的代码,报这个错,求解?谢谢
`
[ryan@ryanos dist]$ ~/soft/sablejs-linux-x64 -i sinan.es.js -o test.js
[ERROR] compile failed: SyntaxError: Parenthesized pattern (2:22)
at Parser. (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:3460:15)
at Parser.checkPatternErrors (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:773:29)
at Parser.toAssignable (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:1955:47)
at Parser.parseMaybeAssign (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:2476:23)
at Parser.parseVar (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:1299:26)
at Parser.parseVarStatement (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:1163:10)
at Parser.parseStatement (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:911:19)
at Parser.parseTopLevel (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:813:23)
at Parser.parse (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:586:17)
at Function.parse (/snapshot/sablejs-private-repo/node_modules/acorn/dist/acorn.js:636:37)
`
您好,看您在介绍中,浏览器环境下的代码中有:const VM = require("sablejs/runtime")();
我要做的就是加密网站中的JS代码
但我在实际测试中,浏览器控制台提示无法使用require,然后创建require变量后,说require不是函数,改成了require("runtime.js文件路径"),然后console.log(VM)的时候反馈undefined。
所以,想咨询一下,不是在node.js下,而是作为加密网站JS代码功能使用的时候,我做错了什么呢?菜鸟一枚,多谢指教!
我使用sable.js编译了代码,然后引入了运行时<script src="https://cdn.jsdelivr.net/npm/[email protected]/runtime.js"></script>
然后我就这样使用,结果无法使用
// 编译后的代码
var code = 'JTI1N0IlMjUyMm5hbWUlMjUyMI1MjJzdHJpY3QlMjUyMiUyNTN';
var vm = new sablejs();
// 发现vm还是一个函数
console.log(vm)
// source should be base64 string via sablejs compiling
vm.run('<compile source ' + code + '>');
在react环境下使用sablejs 会导致整个页面崩溃
codesandbox
在issues#12展示了,如何在外部调用使用sablejs保护的函数。但是存在的问题是,这个函数的入口和出口在前端是可以调试出来的,只是函数内部的逻辑不可见。也就是前端可以解耦出关键函数来,不需要知道内部具体逻辑,方便爬虫或者攻击。
由于sablejs的vm里不支持location对象,所以通过限制域名在当前域名下使用也行不通。
那么sablejs如何才能有效避免函数劫持呢?今后有这方便计划么?
首先非常感谢您的耐心解答,已经解决了问题。但又遇到个问题,就是当丢到vm中的脚本里包含document,window对象时,会报not defined的错误,想问下,是不支持这些对象么?然后包含jquery的脚本也会报错。如果不行的话,是否有办法在外部这个脚本中调用vm中脚本里的函数呢?其实就是想实现浏览器和服务端传输数据的加密,又不想暴露加密思路。感谢感谢!
[root@ecs-ab44 sablejs]# sablejs -v
(node:1978837) UnhandledPromiseRejectionWarning: /usr/local/lib/node_modules/sablejs/node_modules/string-kit/lib/format.js:327
markupTarget = this.shiftedMarkup?.[ runtime.shift ]?.[ markup ] ;
^
SyntaxError: Unexpected token .
at Module._compile (internal/modules/cjs/loader.js:723:23)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object. (/usr/local/lib/node_modules/sablejs/node_modules/string-kit/lib/string.js:62:2)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
(node:1978837) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1978837) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
output.js 代码如下:
ajax({
url: "https://api.apishop.net/common/weather/get15DaysWeatherByArea",
method: "GET",
success: function (response) {
console.log(response);
},
});
执行 sablejs -i output.js -o output.txt
外层的JS代码
function App() {
useEffect(() => {
console.log("starting");
const VM = require("sablejs/runtime")();
const vm = new VM();
const vGlobal = vm.getGlobal();
const vConsole = vm.createObject();
const vLog = vm.createFunction("log", function () {
const temp = [];
for (let i = 0; i < arguments.length; i++) {
temp.push(vm.asString(arguments[i]));
}
console.log(...temp);
return vm.createUndefined();
});
const vAjax = vm.createFunction("ajax", function (vOption) {
const option = {};
const vUrl = vm.getProperty(vOption, "url");
const vMethod = vm.getProperty(vOption, "method");
const vSuccess = vm.getProperty(vOption, "success");
if (vm.isString(vUrl)) {
option.url = vm.asString(vUrl);
}
if (vm.isString(vMethod)) {
option.method = vm.asString(vMethod);
}
if (vm.isFunction(vSuccess)) {
option.success = function(response) {
vm.call(
vSuccess,
vm.createUndefined(),
vm.createString(response)
);
};
}
function send(option) {
let xhr = new XMLHttpRequest();
xhr.withCredentials = option.withCredentials || false;
xhr.open((option.method || "GET").toLowerCase(), option.url, true);
xhr.onload = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
const response = xhr.responseText;
console.log(response);
option.success(response);
}
};
xhr.send(null);
}
send(option);
return vm.createUndefined();
});
vm.setProperty(vGlobal, "ajax", vAjax);
vm.setProperty(vConsole, "log", vLog);
vm.setProperty(vGlobal, "console", vConsole);
(async () => {
const resp = await fetch("./output.txt");
const data = await resp.text();
vm.run(data);
vm.destroy();
})();
}, []);
return <div>JS safty</div>;
}
运行时报这个错误
runtime.js:1 Uncaught TypeError: Cannot read properties of null (reading 'top')
at ef.call (runtime.js:1:1)
at Object.option.success (index.js:40:1)
at XMLHttpRequest.xhr.onload (index.js:57:1)
[INFO] start download compiler: sablejs-osx-arm64...
[ERROR] download failed: Request failed with status code 404
runtime.js:1 Uncaught Error: Uncaught TypeError: string is not callable
at au (runtime.js:1)
at as (runtime.js:1)
at aC (runtime.js:1)
at eg (runtime.js:1)
The distributed binary for MacOS sablejs-osx-x64
, doesn't seem to work for me on macOS 12.5.1.
It runs and terminates with exit code 4, producing no output file.
I verified that it is not something wrong with the JavaScript input file - compiling it on Linux using the supplied binary on Ubuntu 20.04 works properly.
Can't seem to find the source code to self-compile my own binary.
Is it made public somewhere?
Otherwise, recompile & redistribute the MacOS binary, after verifying if it is indeed broken somewhere.
Attached sablejs-osx-x64.zip
// inside vm compiled to file 'output'
function fib(n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2);
}
var start = Date.now();
console.log("[INFO] fib: " + fib(30));
console.log("[INFO] time consuming: " + (Date.now() - start) + "ms");
function sign(data) {
return data + ", do what you want";
}
<html>
<body>
<script src="./runtime.js"></script>
<script>
var vm = new (sablejs())();
const vGlobal = vm.getGlobal();
const vConsole = vm.createObject();
const vLog = vm.createFunction("log", function () {
const temp = [];
for (let i = 0; i < arguments.length; i++) {
temp.push(vm.asString(arguments[i]));
}
console.log(...temp);
return vm.createUndefined();
});
vm.setProperty(vConsole, "log", vLog);
vm.setProperty(vGlobal, "console", vConsole);
(async () => {
const resp = await fetch("output");
const data = await resp.text();
vm.run(data);
const vFunc = vm.getProperty(vGlobal, 'sign');
var vFunc_Ret=vm.call(vFunc, vm.createString("Hello World!"));
const vFuncValue = vm.asString(vFunc_Ret);
console.log("return:",vFuncValue); // <-----
vm.destroy();
})();
</script>
</body>
</html>
Finally, the return is:
return: function sign(data){ [byte code] }
Why not "Hello World! , do what you want"
需求:希望在浏览器端运行代码混淆demo。
代码:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/runtime.js"></script>
<script>
var vm = new (sablejs ())()
vm.run('JTI1N0IlMjUyMm5hbWUlMjUyMiUyNTNBJTI1MjIlMjUyMiUyNTJDJTI1MjJzY3JpcHQlMjUyMiUyNTNBdHJ1ZSUyNTJDJTI1MjJzdHJpY3QlMjUyMiUyNTNBZmFsc2UlMjUyQyUyNTIybGlnaHR3ZWlnaHQlMjUyMiUyNTNBZmFsc2UlMjUyQyUyNTIyYXJndW1lbnRzJTI1MjIlMjUzQWZhbHNlJTI1MkMlMjUyMm51bXBhcmFtcyUyNTIyJTI1M0EwJTI1MkMlMjUyMnBzJTI1MjIlMjUzQSUyNTVCJTI1NUQlMjUyQyUyNTIydnQlMjUyMiUyNTNBJTI1NUIlMjUyMmZpYiUyNTIyJTI1NUQlMjUyQyUyNTIyZnQlMjUyMiUyNTNBJTI1NUIlMjU3QiUyNTIybmFtZSUyNTIyJTI1M0ElMjUyMmZpYiUyNTIyJTI1MkMlMjUyMnNjcmlwdCUyNTIyJTI1M0FmYWxzZSUyNTJDJTI1MjJzdHJpY3QlMjUyMiUyNTNBZmFsc2UlMjUyQyUyNTIybGlnaHR3ZWlnaHQlMjUyMiUyNTNBdHJ1ZSUyNTJDJTI1MjJhcmd1bWVudHMlMjUyMiUyNTNBZmFsc2UlMjUyQyUyNTIybnVtcGFyYW1zJTI1MjIlMjUzQTElMjUyQyUyNTIycHMlMjUyMiUyNTNBJTI1NUIlMjUyMm4lMjUyMiUyNTVEJTI1MkMlMjUyMnZ0JTI1MjIlMjUzQSUyNTVCJTI1MjJuJTI1MjIlMjUyQyUyNTIyZmliJTI1MjIlMjU1RCUyNTJDJTI1MjJmdCUyNTIyJTI1M0ElMjU1QiUyNTVEJTI1MkMlMjUyMnN0JTI1MjIlMjUzQSUyNTVCJTI1NUQlMjUyQyUyNTIybnQlMjUyMiUyNTNBJTI1NUIyJTI1MkMxJTI1NUQlMjUyQyUyNTIyZXQlMjUyMiUyNTNBJTI1NUIlMjU1RCUyNTJDJTI1MjJkZnQlMjUyMiUyNTNBJTI1NUIlMjU1RCUyNTJDJTI1MjJvcGNvZGUlMjUyMiUyNTNBJTI1NUIxOSUyNTJDMjIlMjUyQzIlMjUyQzAlMjUyQzIwJTI1MkMxJTI1MkM3JTI1MkMwJTI1MkMxMDUlMjUyQzg0JTI1MkMzNCUyNTJDMjAlMjUyQzIlMjUyQzE0JTI1MkMyMCUyNTJDMSUyNTJDNyUyNTJDMSUyNTJDOTclMjUyQzQzJTI1MkMxJTI1MkMyMCUyNTJDMiUyNTJDMTQlMjUyQzIwJTI1MkMxJTI1MkM3JTI1MkMwJTI1MkM5NyUyNTJDNDMlMjUyQzElMjUyQzU3JTI1MkM4MyUyNTJDMzYlMjUyQzIwJTI1MkMxJTI1MkM4NiUyNTJDMTQlMjUyQzg2JTI1NUQlMjU3RCUyNTVEJTI1MkMlMjUyMnN0JTI1MjIlMjUzQSUyNTVCJTI1NUQlMjUyQyUyNTIybnQlMjUyMiUyNTNBJTI1NUIxMCUyNTVEJTI1MkMlMjUyMmV0JTI1MjIlMjUzQSUyNTVCJTI1NUQlMjUyQyUyNTIyZGZ0JTI1MjIlMjUzQSUyNTVCJTI1NUQlMjUyQyUyNTIyb3Bjb2RlJTI1MjIlMjUzQSUyNTVCOSUyNTJDMCUyNTJDMjIlMjUyQzElMjUyQzAlMjUyQzE0JTI1MkMwJTI1MkMyMCUyNTJDMSUyNTJDMTQlMjUyQzclMjUyQzAlMjUyQzQzJTI1MkMxJTI1MkM4NiUyNTVEJTI1N0Q=')
</script>
以上代码不会报错,似乎虚拟机正常运行,但原始代码中删去了范例代码里的console.log部分,如果加入则会提示console不存在。请问想调用浏览器内建组件,比如console,document,window,screen这些应该怎么做,谢谢。
通过淘宝镜像安装后 (npm i sablejs -g --registry=https://registry.npm.taobao.org)
D:\Prg\npm\sablejs\node_modules\nodejs-file-downloader\Download.js:265
for await (let chunk of stream) {
^^^^^
是我哪个步骤不对吗
lifuhaideMacBook-Pro:utils lifuhai$ sablejs -i test.js -o output
[INFO] start download compiler: sablejs-osx-arm64...
[ERROR] download failed: Request timed out
such as sablejs-win-x64.exe
//test.js
console.log(1)
Then I run sablejs -i test.js -o output
//main.js
const fs = require('fs');
const data = fs.readFileSync("output").toString();
const VM = require('sablejs/runtime')();
const vm = new VM();
vm.run(data);
vm.destroy();
Then I run node main.js
,output is as follows:
test % node main.js
test/node_modules/sablejs/runtime.js:1
(function (exports, require, module, __filename, __dirname) { 'use strict';!function(a,b){'function'==typeof define&&define['amd']?define('sablejs',b):'object'==typeof module&&module['exports']?module['exports']=b():a['sablejs']=b();}('undefined'!=typeof self?self:this,function(){return function(){var a0={},a1=a0['HAS_TYPED']='undefined'!=typeof Uint8Array&&'undefined'!=typeof Uint16Array,a2=!0x1,a3=!0x1;try{'a'===String['fromCharCode']['apply'](null,[0x61])&&(a2=!0x0);}catch(ew){}if(a1)try{'a'===String['fromCharCode']['apply'](null,new Uint8Array([0x61]))&&(a3=!0x0);}catch(ex){}a0['CAN_CHARCODE_APPLY']=a2,a0['CAN_CHARCODE_APPLY_TYPED']=a3,a0['APPLY_BUFFER_SIZE']=0xfffd,a0['APPLY_BUFFER_SIZE_OK']=null,a2=!0x1,(-0x1!=='abcほげ'['lastIndexOf']('ほげ',0x1)&&(a2=!0x0),a0['STRING_LASTINDEXOF_BUG']=a2),a0['BASE62TABLE']='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',(a3=a0['TABLE_LENGTH']='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijk
Error: Uncaught ReferenceError: 'console' is not defined
Why did this happen?Can you give some examples for running?Thanks in advance
For learning.
尝试使用Windows 10来编译(WSL炸了所以没法用),环境是React17+NodeJS16,,提示import关键字被占用了,导致无法编译想要的文件
项目通过create-react-app创建,尝试在目录中运行sablejs src/components/request.js
[ERROR] compile failed: SyntaxError: The keyword 'import' is reserved (1:0)
at Parser.<anonymous> (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:3460:15)
at Parser.checkUnreserved (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:3367:12)
at Parser.parseIdent (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:3396:12)
at Parser.parseExprAtom (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:2759:21)
at Parser.parseExprSubscripts (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:2627:21)
at Parser.parseMaybeUnary (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:2593:19)
at Parser.parseExprOps (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:2520:21)
at Parser.parseMaybeConditional (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:2503:21)
at Parser.parseMaybeAssign (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:2470:21)
at Parser.parseExpression (C:\snapshot\sablejs-private-repo\node_modules\acorn\dist\acorn.js:2433:21)
加密的代码只有一行
var CryptoJS = require('crypto')
解释器运行时报错
I follow the #12 that the example you posted in the end, and I try it in my demo but browser show me this:
Uncaught Error: Uncaught TypeError: undefined is not callable
runtime.js
is unfortunately very compressed.
Is this project open-sourced in any way? Or this is just a repo for the final npm artifacts?
Thank you for the work. But as this is pretty much MIT-ish licensed, without source code, hardly can we trust any project with it.
sablejs 1.x has been running well on YoTest, but because of the private opcode design, we don't open all code for community(preventing decompiling). After discussions, sablejs 2.0 will plan to open all code! To reach this goal, we will make a major upgrade to the current code of 1.x, include:
1. remove the private opcode design and transform for the stack operation directly
2. dynamically import inner object for sandbox
Since sablejs 1.x is fully stack-based vm, we will have a big loop to execute the relevant opcode code. However, this approach causes a significant performance loss due to the failure of branch prediction:
for (;;) {
switch (opcode) {
case 0: {
// ...
}
case 1: {
// ...
}
case 2: {
// ...
}
}
}
After using the latest d8 and perf for profiling, about 30% of the performance consumption is wasted. To solve this problem, and to make V8 better able to help us with JIT, we will perform the equivalent transform operation directly, consider the following example:
function add() {
return 1 + 2 + 3;
}
In 1.x, we will get linear opcode bytes, which will then be executed by vm. But in 2.0, we will compile directly to the following code:
function __C_add(J) {
__pushNumber(J, 1);
__pushNumber(J, 2);
__R_add(J);
__pushNumber(J, 3);
__R_add(J);
}
Here, stack manipulation methods such as __pushNumber
are still provided by runtime. In this way, together with the relevant compilation optimizations in 1.x, there will be a relatively large performance improvment for frequent execution(benchmark can be followed by DoppioJVM Web JIT implement).
(function(){
for(var i = 0; i < 10000000; i++);
}());
// sablejs 2.0: 276.279ms --- baseline
// sablejs 1.0.6 878ms --- slower: 218.11%
// quickjs-wasm: 228ms --- faster: 17.39%
At the same time, this brings the benefit of not having to rely on opcode, so we can directly open all of sablejs's code.
In most of the usage of the current feedback, it is basically using sablejs for JSVMP. But sablejs 1.x is mainly designed with sandbox as the core, after 2.0 we will mainly aim at JSVMP while taking into account the functionality of sandbox,(the Inner Object will be import on demand according to your needs).
Also, when you are using JSVMP only, sablejs 2.0 will get a very big performance improvment thanks to V8's object optimization!
I considered for releasing sablejs 2.0 in mid-2022, please look forward to it! 😁
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.