摘要:抽象語法樹大致流程生成然后通過類型斷言進行相應的轉換反編譯工具全集小程序推薦逆向反編譯四大工具利器年支持的反編譯工具匯總原文
像軟件加密與解密一樣,javascript的混淆與解混淆同屬于同一個范疇。道高一尺,魔高一丈。沒有永恒的黑,也沒有永恒的白。一切都是資本市場驅動行為,現在都流行你能為人解決什么問題,這個概念。那么市場究竟能容納多少個能解決這種問題的利益者。JS沒有秘密。
其實本人不贊成javascript進行hash混淆處理,一拖慢運行時速度,二體積大。JS代碼前端可獲取,天生賦予“開源”屬性,都可以在chrome devTools下查看。JS非壓縮性混淆完全違法前端優(yōu)化準則。
目前網絡上可以搜索的JS混淆工具不外乎以下幾種:eval混淆,也是最早JS出現的混淆加密,據說第一天就被破解,修改一下代碼,alert一下就可以破解了。這種方法從出生的那天就失去了意義。其實JS加密(混淆)是相對于可讀性而言的,其實真正有意義的就是壓縮型混淆uglify這一類,即可減少體重,也可減少可讀性。
但是,也不能排除部分商業(yè)源代碼使用hash類型混淆源代碼,比如 miniui 使用的JSA加密, fundebug使用的javascript-obfuscator。
下面通過代碼來說明 JSA加密 和 javascript-obfuscator 的區(qū)別:
要混淆的代碼:
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")
可以發(fā)現,其實沒有做什么什么修改,只是做了一些變量替換。想還原也比較簡單的。這里就不拿它來做代表,也沒有什么人用。
通過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"));
這個復雜得多,但是分析一下你會發(fā)現,其實多了一個字典,所有方法變量,都有可能存在字典中,調用時先調用字典還原方法名變量再執(zhí)行。
其實入口都是變量的規(guī)則。
字典函數:
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; };
通過以上發(fā)現,我們可以把JS混淆歸結為三類,分別是 eval類型,hash類型,壓縮類型。而壓縮類型,是目前前端性能優(yōu)化的常用工具,以uglify為代表。
常用的前端壓縮優(yōu)化工具: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
解混淆策略其實是依據生成代碼規(guī)律編寫,不外乎觀察特征分析,再觀察特征分析,不斷調整。都是手辦眼見功夫。
都沒有什么難度可言,有的就是耐性。比如javascript-obfuscator對應的解混淆工具可以
分解為N因子問題:
如何查詢function的作用域?
預執(zhí)行變量替換可能存在類型?
...
如:
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");
第一步你總得知道字典函數,然后執(zhí)行字典函數 _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商業(yè)源碼加密的方向可能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...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109299.html
摘要:面試如何防騙一份優(yōu)秀的前端開發(fā)工程師簡歷是怎么樣的作為,有哪些一般人我都告訴他,但是他都不聽的忠告如何面試前端工程師 更多資源請Star:https://github.com/maidishike... 文章轉自:https://github.com/jsfront/mo... 3月份前端資源分享 1. Javascript 使用judge.js做信息判斷 javascript...
摘要:最近重構了一個項目,引入了部分用法,最大的感受是讓這門語言變得更加嚴謹,更加方便。通過該方法獲得位置后還得比較一次才能判斷是否存在。再來看看的寫法使用數組來初始化一個,構造器能確保不重復地使用這些值。下面提供鏈接,供有興趣的朋友參考。 最近重構了一個SPA項目,引入了部分ES6用法,最大的感受是ES6讓javascript這門語言變得更加嚴謹,更加方便。本篇將結合實戰(zhàn)經驗,對最常用的部...
摘要:個高級多線程面試題及回答后端掘金在任何面試當中多線程和并發(fā)方面的問題都是必不可少的一部分。默認為提供了年杭州面試經歷掘金想換個環(huán)境試試覺得做的不是自己想要的。源碼網站安居客項目架構演進掘金本文已授權微信公眾號獨家發(fā)布。 15 個高級 Java 多線程面試題及回答 - 后端 - 掘金在任何Java面試當中多線程和并發(fā)方面的問題都是必不可少的一部分。如果你想獲得任何股票投資銀行的前臺資訊職...
閱讀 2211·2021-11-22 13:54
閱讀 3375·2019-08-29 12:25
閱讀 3439·2019-08-28 18:29
閱讀 3579·2019-08-26 13:40
閱讀 3275·2019-08-26 13:32
閱讀 955·2019-08-26 11:44
閱讀 2227·2019-08-23 17:04
閱讀 2967·2019-08-23 17:02