Javascript混淆与解混淆的详细介绍(附代码)


当前第2页 返回上一页

字典函数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

var _0xd6ac = ['[41m%s[0m', 'logG', 'log'];

(function(_0x203a66, _0x6dd4f4) {

  var _0x3c5c81 = function(_0x4f427c) {

    while (--_0x4f427c) {

      _0x203a66['push'](_0x203a66['shift']());

    }

  };

  _0x3c5c81(++_0x6dd4f4);

}(_0xd6ac, 0x6e));

var _0x5b26 = function(_0x2d8f05, _0x4b81bb) {

  _0x2d8f05 = _0x2d8f05 - 0x0;

  var _0x4d74cb = _0xd6ac[_0x2d8f05];

  return _0x4d74cb;

};

通过以上发现,我们可以把JS混淆归结为三类,分别是 eval类型,hash类型,压缩类型。而压缩类型,是目前前端性能优化的常用工具,以uglify为代表。

常用的前端压缩优化工具:

JavaScript:

  • babel-minify
  • terser
  • uglify-js
  • uglify-es
  • Google Closure Compiler
  • YUI Compressor

CSS:

  • PostCSS
  • clean-css
  • CSSO
  • YUI Compressor

HTML:

  • html-minifier

从工具流(workflow) 来看,不论是 webpack 还是 gulp ,目前javascript最流行工具还是uglify。

相应的解混淆工具:

  • eval对应的解混淆工具, 随便百度都可以搜索到,如jspacker
  • JSA对应的解混淆工具unjsa
  • javascript-obfuscator对应的解混淆工具crack.js
  • 压缩类型uglify对应的工具UnuglifyJS,在线版jsnice

解混淆策略其实是依据生成代码规律编写,不外乎观察特征分析,再观察特征分析,不断调整。都是手办眼见功夫。

都没有什么难度可言,有的就是耐性。比如javascript-obfuscator对应的解混淆工具可以
分解为N因子问题:

如何查询function的作用域?
预执行变量替换可能存在类型?
...

如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

var _0xd6ac = ['[41m%s[0m', 'logG', 'log'];

(function(_0x203a66, _0x6dd4f4) {

  var _0x3c5c81 = function(_0x4f427c) {

    while (--_0x4f427c) {

      _0x203a66['push'](_0x203a66['shift']());

    }

  };

  _0x3c5c81(++_0x6dd4f4);

}(_0xd6ac, 0x6e));

var _0x5b26 = function(_0x2d8f05, _0x4b81bb) {

  _0x2d8f05 = _0x2d8f05 - 0x0;

  var _0x4d74cb = _0xd6ac[_0x2d8f05];

  return _0x4d74cb;

};

 

function logG(_0x4f1daa) {

  console[_0x5b26('0x0')]('[32m%s[0m', _0x4f1daa);

}

 

function logR(_0x38b325) {

  console[_0x5b26('0x0')](_0x5b26('0x1'), _0x38b325);

}

logG('logR');

logR(_0x5b26('0x2'));

要还原成

1

2

3

4

5

6

7

8

function logG(message) {

  console.log('\x1b[32m%s\x1b[0m', message);

}

function logR(message) {

  console.log('\x1b[41m%s\x1b[0m', message);

}

logG('logR');

logR('logG');

第一步你总得知道字典函数,然后执行字典函数 _0x5b26('0x0') 还原成 log.

那么就好办了,写代码的事。
如 https://github.com/jscck/crac...

还原后,如何重构代码,那么你还得知道代码生成之前是通过什么工具打包的webpack? 还是?

如webpack 的各种封装头和尾
https://webpack.js.org/config...

1

2

3

4

5

6

7

8

9

10

11

12

(function webpackUniversalModuleDefinition(root, factory) {

  if(typeof exports === 'object' && typeof module === 'object')

    module.exports = factory();

  else if(typeof define === 'function' && define.amd)

    define([], factory);

  else if(typeof exports === 'object')

    exports['MyLibrary'] = factory();

  else

    root['MyLibrary'] = factory();

})(typeof self !== 'undefined' ? self : this, function() {

  return _entry_return_;

});

假如再深入一点,可能会涉及到JS语法解释器, AST抽象语法树

目前涉及到 JS语法解释器, AST抽象语法树的功能如下:

prepack, esprima, babel

或者可以阅读《编程语言实现模式》,涉及到 antlr4。

当然也可以通过esprima等工具来做解混淆,只是工作量大一点,值不值的问题。

对于未来,JS商业源码加密的方向可能webassembly,先在服务端编译成wasm,源码就能真正的闭源。

有人的地方就有路,有混淆的地方就有解混淆,目前机器学习编程响应的解混淆工具也做的相当出色,比如

<img src="https://www.sri.inf.ethz.ch/assets/images/sri-logo.svg" alt="Secure, Reliable, and Intelligent Systems Lab" width="136" >

Machine Learning for Programming 产品
nice2predict,jsnice ...
查看 https://www.sri.inf.ethz.ch/r...

拓展参考

AST抽象语法树

为什么额外说一下AST抽象语法树,因为你可以 input-> ast -> output Anything。

比如你jsx转换小程序模版语法,这样你就可以用react语法来写小程序,如Taro。
mpvue, wepy, postcss …… 这些都是通过AST进行构建转换的工具,es6 -> es5, babel 都是使用AST。

AST抽象语法树大致流程:

Input 生成 AST tree

然后通过AST类型断言进行相应的转换

【相关推荐:JavaScript视频教程】

以上就是Javascript混淆与解混淆的详细介绍(附代码)的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

了解javascript中object.freeze()与const之间的区别

vue.js方法与事件的介绍

vue访问元素和组件的方法(附示例)

javascript是什么端

javascript怎么设置value属性

javascript日期格式如何转换成年月日

如何在js中改变dom元素的文本内容

javascript正则表达式如何替换

javascript中this的用法有哪些

聊聊typescript中enum(枚举)的用法

更多相关阅读请进入《混淆代码》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...