▒ 目录 ▒
🛫 问题
描述
因工作需要,经常写写短小精悍的js,然后再去掉注释,混淆,再加密,麻烦的很。
实在忍不了,做个工具方便以后开发:
- 编写公共函数,方便代码维护
- 每个工程独立目录管理
- webpack打包
- 混淆js代码
- 加密(简单的做个转码:base64、rc4等)
环境
版本号 | 描述 | |
---|---|---|
文章日期 | 2023-06-29 | |
操作系统 | Win11 - 21H2 - 22000.1335 | |
node -v | v16.16.0 | |
1️⃣ 工程化
初始化项目:npm init
找个目录,调用
npm init
来初始化 package.json(它是 NodeJS 约定的用来存放项目的信息和配置等信息的文件)。
根据提示填写项目信息即可,也可以一路回车,最后直接修改package.json文件。
图省事儿,可以执行:
npm init -y
(y 代表yes ,省去了默认选项点击)。
最终的代码:
{
"name": "ls",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "cd src/steam_limit && node xxx.js",
"steam_xxx": "cd src/steam_limit && npx webpack && cross-env BUILD_TARGET=steam_xxx node ../dev-tools/base64.js",
"poststop---foo": "node src/dev-tools/base64.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/plugin-transform-modules-umd": "^7.22.5",
"cross-env": "^7.0.3",
"javascript-obfuscator": "^4.0.2",
"js-base64": "^3.7.5",
"webpack-cli": "^5.1.4",
"webpack-obfuscator": "^3.5.1"
}
}
项目目录结构
目录结果按照习惯编写就行,下面是小编的目录,仅供参考。
编写基础库(export / module.exports)
这里以隐藏元素为例,编写并导出函数
function hide__(ele, is_hide=true) {
if (!ele) {
return;
}
// var val = is_hide ? 'none' : '';
// ele.style.display = val;
var val = is_hide ? 'hidden' : '';
ele.style.visibility = val;
}
function hide_all(ele,is_hide=true) {
for (var i = 0; i < ele.length; ++i) {
hide__(ele[i], is_hide);
}
}
module.exports = {
hide__,
hide_all
}
这里特别注意的是导出需要使用
module.exports
,都是exports
是module.exports
的别名,可是小编使用exports
并不能导出函数。
编写入口文件(import)
这个很简单,在自己的文件中,使用
import
引入函数即可,注意目录层次。
示例:
// 引入函数
import { hide__, hide_all} from "../../common/hide";
// 直接隐藏所有元素
hide_all(document.body)
编译命令(npx)
小编需要使用webpack打包,这里使用
npx
运行,如下图。
同时搭配VSCdoe插件NPM SCRIPTS
,当多个项目时,极大提高工作效率。
2️⃣ webpack打包
从最初的需求来看,为了可以实现模块化,同时帮忙打包、混淆代码。我们选择
webpack
来实现再适合不过了。
安装
npm i -D webpack-cli
配置
在功能目录中,我们创建
webpack.config.js
文件。
指定最初的
module.exports = {
// mode: "development",
mode: "production",
entry: "./src/index.js",
output: {
filename : "./dist.js"
}
};
有了这些,我们直接执行
npm run steam_xxx
,即可打包出可执行文件dist.js
,十分方便。
3️⃣ js代码混淆
公司代码提供给第三方使用,为了安全不泄露源码,需要对给出的代码进行加密混淆,前端代码虽然无法做到完全加密混淆,但是通过使用 webpack-obfuscator 通过增加随机废代码段、字符编码转义等方法可以使构建代码完全混淆,达到无法恢复源码甚至无法阅读的目的。
其中有各种配置参数,可参考文章《代码加密混淆插件webpack-obfuscator》: https://juejin.cn/post/7159431931975696397。
安装
npm install --save-dev webpack-obfuscator javascript-obfuscator
配置
作为webpack的一个插件,我们只需要在
webpack.config.js
文件中增加相关设置即可。
具体参数含义如下面代码中的注释。
需要注意的是,有些配置项导致代码无法正常运行
,这时候需要不断尝试修正,或者将相关代码排除出去。
const WebpackObfuscator = require('webpack-obfuscator');
module.exports = {
// mode: "development",
mode: "production",
entry: "./src/index.js",
output: {
filename : "./dist.js"
},
plugins: [
new WebpackObfuscator({
compact: true,
rotateUnicodeArray: true,
identifierNamesGenerator: 'mangled', // 'hexadecimal',
renameGlobals: true,
rotateStringArray: true,//通过固定和随机(在代码混淆时生成)的位置移动数组。这使得将删除的字符串的顺序与其原始位置相匹配变得更加困难。如果原始源代码不小,建议使用此选项,因为辅助函数可以引起注意。
selfDefending: true,//混淆后的代码,不能使用代码美化,同时需要配置 cpmpat:true;
stringArray: true,//删除字符串文字并将它们放在一个特殊的数组中
stringArrayEncoding: ['base64'], //'rc4',
// TODO: 加上stringArrayThreshold,steam_limit生成的代码没生效
// stringArrayThreshold: 1,
transformObjectKeys: true,
unicodeEscapeSequence: false //允许启用/禁用字符串转换为unicode转义序列。Unicode转义序列大大增加了代码大小,并且可以轻松地将字符串恢复为原始视图。建议仅对小型源代码启用此选项。
},
// 数组内是需要排除的文件
['abc.js']
)
]
};
效果图
下面是混淆的示例,代码已经无法恢复了。
🛬 结论
上面就是真个开发的所有过程,希望对大家有帮助。
如果有更好的方案,欢迎评论区一起交流。
📖 参考资料
- webpack-obfuscator官网:https://github.com/javascript-obfuscator/webpack-obfuscator
- 总结一些网站加密和混淆技术 https://blog.csdn.net/qq_44911774/article/details/107670879
- 【JS逆向系列】ob混淆 https://juejin.cn/post/7024294000689414157
- 30 分钟掌握 Webpack https://www.bilibili.com/video/BV11g411y7Sd
- 代码加密混淆插件webpack-obfuscator https://juejin.cn/post/7159431931975696397
- frida 模块化探索: https://blog.csdn.net/iloveitvm/article/details/109723523