前言
👀使用npm 下载一个工具asar
全局安装
npm install -g asar
安装完成以后,找到你安装的electron软件的安装目录,找到一个.asar
后缀的文件💥,然后在当前路径下打开终端💻
假设我找到的文件是app.asar
📌
asar extract app.asar ./fs
执行完这个命令以后你会看到当前目录下面多了一个fs
的文件夹。然后嘛你打开这个fs
的文件夹进去看看就知道为啥要保护源码了😁
一、思路
我使用到代码混淆😵,然后将混淆后的代码编译成V8🎱字节码💻。这样可以有效的保护🧱源码。
二、实现
1.安装代码混淆的工具javascript-obfuscator
点击👉去GitHubjavascript-obfuscator
npm install --save-dev javascript-obfuscator
npm install --save-dev webpack-obfuscator // webpack插件
安装完了以后在你的webpack配置文件里面的plugins
里面加上
// 记得把这个插件引入进来
import JavaScriptObfuscator from 'webpack-obfuscator';
plugins: [
new JavaScriptObfuscator({
compact: true, // 压缩代码
controlFlowFlattening: false, // 是否启用控制流扁平化(降低1.5倍的运行速度)
deadCodeInjection: false, /// 随机的死代码块(增加了混淆代码的大小)
debugProtection: false, // 此选项几乎不可能使用开发者工具的控制台选项卡
debugProtectionInterval: false, // 如果选中,则会在“控制台”选项卡上使用间隔强制调试模式,从而更难使用“开发人员工具”的其他功能。
disableConsoleOutput: true, // 通过用空函数替换它们来禁用console.log,console.info,console.error和console.warn。这使得调试器的使用更加困难。
identifierNamesGenerator: 'hexadecimal', // 标识符的混淆方式 hexadecimal(十六进制) mangled(短标识符)
log: false,
renameGlobals: false, // 是否启用全局变量和函数名称的混淆
rotateStringArray: true, // 通过固定和随机(在代码混淆时生成)的位置移动数组。这使得将删除的字符串的顺序与其原始位置相匹配变得更加困难。如果原始源代码不小,建议使用此选项,因为辅助函数可以引起注意。
selfDefending: true, // 混淆后的代码,不能使用代码美化,同时需要配置 cpmpat:true;
stringArray: true, // 删除字符串文字并将它们放在一个特殊的数组中
stringArrayEncoding: ['base64'],
stringArrayThreshold: 0.75,
unicodeEscapeSequence: false// 允许启用/禁用字符串转换为unicode转义序列。Unicode转义序列大大增加了代码大小,并且可以轻松地将字符串恢复为原始视图。建议仅对小型源代码启用此选项。
}, [])
]
接下来你的webpack在打包代码的时候就会帮你混淆代码。然后你对比混淆之前打包的代码就会觉得阅读起来非常困难😭
2.安装bytenode
bytenode可以将你的JavaScript代码编程成V8字节码,这可以有效的保护你的源码😎
点击👉去GitHub仓库bytenode
先安装
npm install --save bytenode
假设你的文件目录结构是这样的👇
📁dist // dist 里面是打包好的渲染进程的js文件
📁node_modules
📁src
📑main.js // 打包以后的主进程js文件
现在你要做的就是加一个脚本,将你打包好的js文件编译成jsc文件,然后将原来的js文件里面的内容替换成简单的两行代码
require("bytenode");require("./xxx.jsc");
以主进程为例
在根目录下添加一个bytenode.js
的文件
📁dist // dist 里面是打包好的渲染进程的js文件
📁node_modules
📁src
📑bytenode.js // 将js文件编译成字节码的脚本文件
📑main.js // 打包以后的主进程js文件
'use strict';
const fs = require('fs');
const path = require('path');
const bytenode = require('bytenode');
const v8 = require('v8');
v8.setFlagsFromString('--no-lazy');
const pathName = path.join(__dirname, './main.js');
try {
(async function () {
try {
await bytenode.compileFile({
filename: pathName,
electron: true, // electron的项目这个参数一定要加上
compileAsModule: true
}, `${pathName}c`);
// 将原来的js文件里面的内容替换成下面的内容
fs.writeFileSync(pathName, 'require("bytenode");require("./main.jsc");', 'utf8');
} catch (e) {
console.error(`run_bytenode_err: ${e}`);
}
}());
} catch (e) {
console.error(`run_bytenode_err: ${e}`);
}
写好脚本文件以后需要在package.json
文件里面去添加脚本了
假如你之前打包软件执行的是yarn package
"scripts": {
"build": "xxxxxxxxxxxxxxxxx", // 假设这是你的webpack打包代码的脚本
"electron-build": "xxxxxxxxxxxxxxxxx" // 假设这是你的electron打包的脚本
"package": "yarn build && yarn electron-build", // 假设这是打包软件的脚本
},
现在我们添加bytenode的脚本
"scripts": {
"build": "xxxxxxxxxxxxxxxxx", // 假设这是你的webpack打包代码的脚本
"bytenode": "node ./bytenode.js", // 添加bytenode的脚本 执行之前写好的js文件
"electron-build": "xxxxxxxxxxxxxxxxx" // 假设这是你的electron打包的脚本
"package": "yarn build && yarn bytenode && yarn electron-build", // 在这里加上bytenode的脚本
},
注意
“electron-build” 打包📦的时候需要把编译好的jsc文件和 node_modules
里面bytenode
的包加进去一起打包,在scripts
字段同级的build
字段里面,
github 有添加bytenode 的electron项目模板🚀地址 大家可以去参考参考
"build": {
"productName": "testapp",
"files": [
"node_modules/",// 如果你的项目之前没有打包node_modules那现在把node_modules加上一起打包
"dist/",
"main.js",
"main.jsc" // 现在把编译好的字节码文件也加进来
],
"scripts": {
"build": "xxxxxxxxxxxxxxxxx", // 假设这是你的webpack打包代码的脚本
"bytenode": "node ./bytenode.js", // 添加bytenode的脚本 执行之前写好的js文件
"electron-build": "xxxxxxxxxxxxxxxxx" // 假设这是你的electron打包的脚本
"package": "yarn build && yarn bytenode && yarn electron-build", // 在这里加上bytenode的脚本
},
现在执行在终端执行yarn package
命令
📁dist // dist 里面是打包好的渲染进程的js文件
📁node_modules
📁src
📑bytenode.js // 将js文件编译成字节码的脚本文件
📑main.js // 打包以后的主进程js文件
📄main.jsc // 编译成功的字节码文件
渲染进程也是一样的做法。
将打包好的js文件编译成🔨jsc字节码文件 ----> 替换📤js文件里面的代码(引入📥jsc文件) ----> 把编译出来的jsc文件加进去一起打包📦
如果没有提示报错信息那就大功告成了。
可能遇到的问题
我在代码混淆的地方,改变参数把代码混淆的程度加大了,然后打包出来的软件出现了白屏的情况😭😭😭,把混淆程度改小之后又能正常运行了。
还有可能遇到文件加载失败白屏的问题(可能报错提示找不到某个jsc文件,要么是你没有把编译好的jsc文件加进去一起打包😂,要么就是在require("xxxx.jsc")
的时候路径不对🤣),建议调试的时候打上带debug🐛的包查看报错信息。
版本问题
bytenode "bytenode": "^1.3.3",
electron "electron": "11.0.5"
,
"javascript-obfuscator": "^2.19.0",
node版本建议使用14.17.0
webpack "webpack": "^5.5.1",",
"webpack-obfuscator": "^3.4.1"
总结
以上就是我的经验总结,希望对你们有帮助,学会了吗🧐,有建议或者遇到问题可以在下方评论📝留下你宝贵的建议。