ホームページ  >  記事  >  ウェブフロントエンド  >  Javascript の難読化と難読化解除の詳細な紹介 (コード付き)

Javascript の難読化と難読化解除の詳細な紹介 (コード付き)

不言
不言転載
2019-04-02 10:28:0310372ブラウズ

この記事では、JavaScript の難読化と難読化解除 (コード付き) について詳しく説明します。これには一定の参考価値があります。必要な友人は参照できます。お役に立てれば幸いです。

ソフトウェアの暗号化と復号化と同様、JavaScript の難読化と難読化解除は同じカテゴリに属します。スティックを使いこなしながらもヤードを狙う。永遠の黒も永遠の白もありません。すべては資本市場によって動かされており、人々のためにどのような問題を解決できるかという概念が現在人気です。では、市場はこの問題を解決できるステークホルダーを何人まで収容できるのでしょうか? JS には秘密はありません。

実のところ、私は JavaScript のハッシュ難読化には同意しません。第一に、実行速度が遅くなり、第二に、容量が大きくなります。 JS コード フロントエンドが利用可能であり、本質的に「オープン ソース」であり、chrome devTools で表示できます。 JS の非圧縮難読化は、フロントエンドの最適化原則に完全に違反します。

現在インターネット上で検索できる JS 難読化ツールは次のものにすぎません:

eval 難読化は、JS に登場した最も初期の難読化暗号でもあります。初日。コードを変更してください。1 つのアラートでクラックできます。この方法は生まれた日から意味を失います。実際、JS 暗号化 (難読化) は可読性と関連しており、実際に意味があるのは、重量と可読性を軽減できる圧縮難読化 uglify のタイプです。

ただし、一部の商用ソース コードでは、miniui で使用される JSA 暗号化や fundebug で使用される javascript-obfuscator など、ソース コードを難読化するためにハッシュ タイプが使用されている可能性を排除できません。

次のコードは、JSA 暗号化と javascript-obfuscator の違いを示しています。

難読化されるコード:

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');

JSA 暗号化と難読化によって生成されたコード

function o00($){console.log("\x1b[32m%s\x1b[0m",$)}function o01($){console.log("\x1b[41m%s\x1b[0m",$)}o00("logR");o01("logG")

次に、もう一度美化します:

function o00($) {
  console.log("\x1b[32m%s\x1b[0m", $)
}

function o01($) {
  console.log("\x1b[41m%s\x1b[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 型、ハッシュ型、圧縮型の 3 つのカテゴリに分類できます。圧縮タイプは現在、uglify に代表されるフロントエンドのパフォーマンス最適化によく使用されるツールです。

一般的に使用されるフロントエンド圧縮最適化ツール:

JavaScript:

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

CSS:

  • PostCSS
  • clean-css
  • CSSO
  • YUI Compressor

HTML:

  • html-minifier

ツール フロー (ワークフロー) の観点から見ると、webpack にせよ gulp にせよ、現在最も人気のある JavaScript ツールは uglify です。

対応する難読化解除ツール:

  • eval に対応する難読化解除ツールは、jspacker など、Baidu で検索できます。
  • JSA unjsa に対応する難読化解除ツール
  • javascript-obfuscator に対応する難読化解除ツール crash.js
  • 圧縮タイプ uglify に対応するツール UnuglifyJS、jsnice のオンライン バージョン

難読化解除戦略は実際には次のとおりです。コードを定期的に書くことは、機能分析を観察し、次に機能分析を観察し、継続的に調整を行うことに他なりません。どれも安心して見れる数字ばかりです。

難しいことはまったくありません。必要なのは忍耐だけです。たとえば、javascript-obfuscator に対応する難読化解除ツールは、
N 要素問題に分解できます。

関数のスコープをクエリするにはどうすればよいですか?
実行前の変数置換に可能なタイプは何ですか?
...

例:

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%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...

(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="安全、信頼性、インテリジェントなシステム ラボ" width="136" >

プログラミング製品のための機械学習

nice2predict、jsnice...
https://www.sri.inf.ethz.ch/r...
を表示

拡張リファレンス

AST 抽象構文ツリー

入力 -> ast -> 出力 何でもできるため、AST 抽象構文ツリーについてさらに説明する必要があります。

たとえば、jsx をミニ プログラム テンプレート構文に変換すると、反応構文を使用して Taro などのミニ プログラムを作成できます。
mpvue、wepy、postcss... これらはすべて AST を使用してビルドおよび変換するためのツールです。es6 -> es5、babel はすべて AST を使用します。

AST 抽象構文ツリーの一般的なプロセス:

入力により AST ツリーが生成されます

次に、AST 型アサーションを通じて対応する変換を実行します

[関連する推奨事項:JavaScriptビデオチュートリアル]

以上がJavascript の難読化と難読化解除の詳細な紹介 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。