aardio封裝庫) 微軟開源的js引擎(ChakraCore)

Python成长路發表於2024-05-01

前言

做爬蟲肯定少不了JavaScript引擎的使用,比如在Python中現在一般用pyexecjs2來執行JavaScript程式碼,另外還有一些其他執行JavaScript的庫:

  • https://github.com/eight04/node_vm2: rpc呼叫nodejs,需要安裝node
  • https://github.com/eight04/deno_vm: rpc呼叫deno,需要安裝deno
  • https://github.com/wistn/pyChakraCore: 呼叫ChakraCore.dll

aardio執行js

如果本地安裝有nodejs,aardio範例裡也有rpc呼叫node執行JavaScript的例子。

但是rpc呼叫需要依賴本地的nodejs環境,給別人使用也不方便,需要讓人先安裝nodejs。而ChakraCore這個微軟開源的js引擎可以直接呼叫dll來實現,不需要額外依賴。所以這篇文章我來封裝下aardio下的ChakraCore。

有了js引擎的話,又可以利用JavaScript優秀的庫資源來豐富aardio的庫。比如載入crypt-js給aardio增加一些加密演算法(AES、DES等)。

下載地址

封裝好的程式碼可以到github下載

下載地址:https://github.com/kanadeblisst00/aardio-extlibs

開始封裝

倉庫地址:https://github.com/chakra-core/ChakraCore

編譯dll

倉庫給出的編譯好的dll檔案還是2020年的,但是程式碼最近一直在更新,所以最好是自己編譯一個,防止之前的有bug還沒修復到。

根據官方給的文件,下載原始碼後使用vs2017開啟Build下的Chakra.Core.sln,然後改一下編譯的架構為x86。右鍵生成解決方案,一步就過了,沒有什麼坑(最喜歡編譯這種專案了)。

生成的dll檔案在Build\VcBuild\bin\x86_release下,只需要ChakraCore.dll這一個檔案。

封裝思路

封裝這個庫用了不少時間,基本是參考上面pyChakraCore的程式碼。就不說具體怎麼做的(無非就是參考Python的程式碼和看github和官方文件嗎,碰到不會的在搜尋一下),有興趣的可以自己看看庫程式碼,下面說說怎麼使用。

測試這個dll無法使用aardio的記憶體載入,也就是說打包的時候只能帶上這個dll,不能直接打包進exe。

案例

說幾個簡單使用的案例,因為還沒有深度使用,後面想到什麼在增加吧

例子1

import console; 
import ChakraCore;

io.open()

var core = ChakraCore();
core.start();

console.dump(core.run('(()=>{return Uint8Array.from([1,2,3,4]).buffer;})()'))
console.dump(core.run('(()=>{let a = {"a":1,"b":2};return a;})()'))
console.dump(core.callFunction('pretty', {"a":1,"v":"111"}))
console.dump(core.run('console.log("aaaaa",undefined,null,false,{a:1,b:2},function(){})'))

console.pause(true);

例子2

先定義函式再呼叫

import console; 
import ChakraCore;

io.open()

var core = ChakraCore();
core.start();

core.run("
	function add(a,b){
		return a+b;
	}	
")
var a = 1;
var b = 2;
console.log("a+b=", core.callFunction("add", a,b))


console.pause(true);

例子3

註冊aardio函式為JavaScript函式,這裡以atobbtoa這兩個函式為例,ChakraCore沒有自帶這兩個函式,而瀏覽器有,所以我們用aardio來實現。我在庫程式碼裡已經內建了console.logsetTimeout,有興趣的可以自己看怎麼實現。

import console; 
import ChakraCore;
import crypt.bin;
io.open()

var core = ChakraCore();
core.start();

var btoa = function(ptr_callee, isConstructCall, ptrj_arguments, argumentCount, callbackState){
	// ptr_callee不知道是什麼
	// isConstructCall表示是不是構造方法
	// ptrj_arguments是引數的陣列
	// argumentCount是引數的個數
	// callbackState也不知道是什麼
	var pointerSize = 4;
	var jStr = ..raw.convert(ptrj_arguments, {ptr p}, pointerSize).p;
	var aStr = ChakraCore.jValueToString(jStr);
	var result = crypt.bin.encodeBase64(aStr);
	var jResult = core.JsCreateString(result,#result,);
	return jResult;
};

var atob = function(ptr_callee, isConstructCall, ptrj_arguments, argumentCount, callbackState){
	var pointerSize = 4;
	var jStr = ..raw.convert(ptrj_arguments, {ptr p}, pointerSize).p;
	var aStr = ChakraCore.jValueToString(jStr);
	var result = crypt.bin.decodeBase64(aStr);
	var jResult = core.JsCreateString(result,#result,);
	return jResult;
}

core.registerMethod(btoa, "btoa");
core.registerMethod(atob, "atob");
var result = core.run('btoa("Hello, world")')
console.log("btoa: ", result)
console.log("atob: ", core.callFunction("atob", result))
console.pause(true);

而且比較有意思的是,這樣註冊的JavaScript函式列印出來的也是function () { [native code] },可惜和瀏覽器還是有區別,瀏覽器會加上函式名function btoa() { [native code] }

例子4

呼叫crypt-js實現下加密AES CBC加密演算法

import console; 
import ChakraCore;

io.open()

var core = ChakraCore();
core.start();

core.run($"~\lib\ChakraCore\.res\crypto-js.js")

var js = /*
let key = CryptoJS.enc.Utf8.parse("1234567890000000");
let iv = CryptoJS.enc.Utf8.parse("1234567890000000");

let s = "Hello World";
let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(s), key, {
	iv: iv,
	mode: CryptoJS.mode.CBC,
	padding: CryptoJS.pad.Pkcs7
});

var eData = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
console.log("加密字串: ", eData);

let decrypted = CryptoJS.AES.decrypt(eData,key, {    
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});
let dData= decrypted.toString(CryptoJS.enc.Utf8).toString();
console.log("解密字串: ", dData);
*/

core.run(js)
console.pause(true);

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章