摘要:抽象语法树大致流程生成然后通过类型断言进行相应的转换反编译工具全集小程序推荐逆向反编译四大工具利器年支持的反编译工具汇总原文
像软件加密与解密一样,javascript的混淆与解混淆同属于同一个范畴。道高一尺,魔高一丈。没有永恒的黑,也没有永恒的白。一切都是资本市场驱动行为,现在都流行你能为人解决什么问题,这个概念。那么市场究竟能容纳多少个能解决这种问题的利益者。JS没有秘密。
其实本人不赞成javascript进行hash混淆处理,一拖慢运行时速度,二体积大。JS代码前端可获取,天生赋予“开源”属性,都可以在chrome devTools下查看。JS非压缩性混淆完全违法前端优化准则。
目前网络上可以搜索的JS混淆工具不外乎以下几种:eval混淆,也是最早JS出现的混淆加密,据说第一天就被破解,修改一下代码,alert一下就可以破解了。这种方法从出生的那天就失去了意义。其实JS加密(混淆)是相对于可读性而言的,其实真正有意义的就是压缩型混淆uglify这一类,即可减少体重,也可减少可读性。
但是,也不能排除部分商业源代码使用hash类型混淆源代码,比如 miniui 使用的JSA加密, fundebug使用的javascript-obfuscator。
下面通过代码来说明 JSA加密 和 javascript-obfuscator 的区别:
要混淆的代码:
function logG(message) { console.log("x1b[32m%sx1b[0m", message); } function logR(message) { console.log("x1b[41m%sx1b[0m", message); } logG("logR"); logR("logG");
通过JSA加密混淆后生成的代码
function o00($){console.log("x1b[32m%sx1b[0m",$)}function o01($){console.log("x1b[41m%sx1b[0m",$)}o00("logR");o01("logG")
然后再beautifier一下:
function o00($) { console.log("x1b[32m%sx1b[0m", $) } function o01($) { console.log("x1b[41m%sx1b[0m", $) } o00("logR"); o01("logG")
可以发现,其实没有做什么什么修改,只是做了一些变量替换。想还原也比较简单的。这里就不拿它来做代表,也没有什么人用。
通过javascript-obfuscator混淆后生成的代码
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"));
再beautifier一下:
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"));
这个复杂得多,但是分析一下你会发现,其实多了一个字典,所有方法变量,都有可能存在字典中,调用时先调用字典还原方法名变量再执行。
其实入口都是变量的规则。
字典函数:
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的作用域?
预执行变量替换可能存在类型?
...
如:
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"));
要还原成
function logG(message) { console.log("x1b[32m%sx1b[0m", message); } function logR(message) { console.log("x1b[41m%sx1b[0m", message); } logG("logR"); logR("logG");
第一步你总得知道字典函数,然后执行字典函数 _0x5b26("0x0") 还原成 log.
那么就好办了,写代码的事。
如 https://github.com/jscck/crack.js/blob/master/crack.js
还原后,如何重构代码,那么你还得知道代码生成之前是通过什么工具打包的webpack? 还是?
如webpack 的各种封装头和尾
https://webpack.js.org/config...
(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,源码就能真正的闭源。
有人的地方就有路,有混淆的地方就有解混淆,目前机器学习编程响应的解混淆工具也做的相当出色,比如
Machine Learning for Programming 产品
nice2predict,jsnice ...
查看 https://www.sri.inf.ethz.ch/r...
为什么额外说一下AST抽象语法树,因为你可以 input-> ast -> output Anything。
比如你jsx转换小程序模版语法,这样你就可以用react语法来写小程序,如Taro。
mpvue, wepy, postcss …… 这些都是通过AST进行构建转换的工具,es6 -> es5, babel 都是使用AST。
AST抽象语法树大致流程:
Input 生成 AST tree
然后通过AST类型断言进行相应的转换
http://esprima.org/demo/parse...
反编译工具全集小程序
https://github.com/qwerty4721...
推荐.Net、C# 逆向反编译四大工具利器
https://www.cnblogs.com/ldc21...
2018年支持java8的Java反编译工具汇总
https://blog.csdn.net/yannqi/...
原文:http://blog.w3cub.com/blog/20...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/109299.html
摘要:面试如何防骗一份优秀的前端开发工程师简历是怎么样的作为,有哪些一般人我都告诉他,但是他都不听的忠告如何面试前端工程师 更多资源请Star:https://github.com/maidishike... 文章转自:https://github.com/jsfront/mo... 3月份前端资源分享 1. Javascript 使用judge.js做信息判断 javascript...
摘要:最近重构了一个项目,引入了部分用法,最大的感受是让这门语言变得更加严谨,更加方便。通过该方法获得位置后还得比较一次才能判断是否存在。再来看看的写法使用数组来初始化一个,构造器能确保不重复地使用这些值。下面提供链接,供有兴趣的朋友参考。 最近重构了一个SPA项目,引入了部分ES6用法,最大的感受是ES6让javascript这门语言变得更加严谨,更加方便。本篇将结合实战经验,对最常用的部...
摘要:个高级多线程面试题及回答后端掘金在任何面试当中多线程和并发方面的问题都是必不可少的一部分。默认为提供了年杭州面试经历掘金想换个环境试试觉得做的不是自己想要的。源码网站安居客项目架构演进掘金本文已授权微信公众号独家发布。 15 个高级 Java 多线程面试题及回答 - 后端 - 掘金在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职...
阅读 2210·2021-11-22 13:54
阅读 3375·2019-08-29 12:25
阅读 3439·2019-08-28 18:29
阅读 3577·2019-08-26 13:40
阅读 3271·2019-08-26 13:32
阅读 954·2019-08-26 11:44
阅读 2227·2019-08-23 17:04
阅读 2967·2019-08-23 17:02