electron源码保护的方法实现

前言

👀使用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"

总结

以上就是我的经验总结,希望对你们有帮助,学会了吗🧐,有建议或者遇到问题可以在下方评论📝留下你宝贵的建议。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值