上期文章:虚拟解释器组件设计
如下图所示,“.c”文件中包含了虚拟解释器的核心逻辑和相应组件,我们通过Emscripten编译器将目标C文件编译成WASM模块,该编译器基于LLVM,首先将C/C++源代码编译为抽象字节码LLVM bytecode,然后,通过Emscripten的后端编译器,将这种抽象字节码转换成asm.js格式的文件,最后使用“WASM=1”标志可以进一步将其编码成后缀是“.wasm”的WebaAssembly二进制文件。
编译器支持在编译过程中主动生成加载“.wasm”文件的胶接代码,只需要在使用“WASM=1”标志的编译命令中将目标文件的后缀设置为“.js”,这样编译后可得到两个关键的文件,一个是“.wasm”文件,其中包含有虚拟解释器的核心调度模块Dispatcher、关键的虚拟数据VMdata和VMarray,以及Handler的主体逻辑。另一个是“.js”文件,其内部主要包含加载和通信WASM模块必要的胶接代码以及解释程序Handler和VMcontext中经由宏“EM_ASM”内联的JavaScript代码片段。要实现运行时对虚拟解释器的调用,保护后的目标JavaScript程序中还要需要添加JavaScript脚本加载模块加载胶接代码所在的“.js”文件,通过该文件可以在运行时将包含虚拟解释器的“.wasm”文件加载到浏览器中。同时将虚拟解释器入口函数实例化成原目标代码的函数名,并抽取关键代码将其替换为解释器入口函数调用,这样当执行到关键函数时可以直接进入虚拟解释器中还原目标代码的功能。
JS一键VMP加密 jsvmp.com