Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Einführung in die Verschleierung und Entschleierung von Javascript (mit Code)

Detaillierte Einführung in die Verschleierung und Entschleierung von Javascript (mit Code)

不言
不言nach vorne
2019-04-02 10:28:0310290Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Einführung in die Verschleierung und Entschleierung von Javascript (mit Code). Ich hoffe, dass er Ihnen als Referenz dienen wird.

Wie die Softwareverschlüsselung und -entschlüsselung gehören auch die JavaScript-Verschleierung und -Entschleierung zur gleichen Kategorie. Das Tao ist einen Fuß hoch und der Teufel ist einen Fuß hoch. Es gibt kein ewiges Schwarz und kein ewiges Weiß. Alles wird vom Kapitalmarkt bestimmt und das Konzept, welche Probleme man für die Menschen lösen kann, ist mittlerweile populär. Wie viele Stakeholder kann der Markt also aufnehmen, um dieses Problem zu lösen? JS hat keine Geheimnisse.

Eigentlich bin ich mit der Hash-Verschleierung in JavaScript nicht einverstanden. Erstens verlangsamt es die Laufzeit und zweitens ist es sperrig. Das JS-Code-Frontend ist verfügbar, von Natur aus „Open Source“ und kann unter Chrome DevTools angezeigt werden. Die nicht komprimierbare JS-Verschleierung verstößt vollständig gegen die Prinzipien der Front-End-Optimierung.

Die derzeit im Internet durchsuchbaren JS-Verschleierungstools sind nichts anderes als die folgenden:

eval obfuscation ist auch die früheste Verschleierungsverschlüsselung, die in JS auftauchte. Es heißt, dass sie geknackt wurde Am ersten Tag. Bitte ändern Sie den Code, er kann mit einer Warnung geknackt werden. Ab dem Tag der Geburt verliert diese Methode ihre Bedeutung. Tatsächlich hängt die JS-Verschlüsselung (Verschleierung) von der Lesbarkeit ab. Tatsächlich ist die Art der komprimierten Verschleierung hässlich, was Gewicht und Lesbarkeit verringern kann.

Es kann jedoch nicht ausgeschlossen werden, dass einige kommerzielle Quellcodes einen Hash-Typ verwenden, um den Quellcode zu verschleiern, wie z. B. die von Miniui verwendete JSA-Verschlüsselung und der von Fundebug verwendete Javascript-Obfuscator.

Im Folgenden wird Code verwendet, um den Unterschied zwischen JSA-Verschlüsselung und Javascript-Obfuscator zu veranschaulichen:

Zu verschleiernder Code:

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

Code, der durch Verschleierung der JSA-Verschlüsselung generiert wird

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

Dann wieder Verschönerer:

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

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

Sie können feststellen, dass tatsächlich keine Änderungen vorgenommen wurden, sondern nur einige Variablenersetzungen. Die Wiederherstellung ist relativ einfach. Ich werde es hier nicht stellvertretend verwenden, und niemand verwendet es.

Der Code, der nach der Verschleierung durch Javascript-Obfuscator generiert wurde

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

Noch einmal Verschönerung:

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

Das ist viel komplizierter, aber wenn Sie es analysieren, werden Sie es dort finden Ist eigentlich ein zusätzliches Wörterbuch, alle Methodenvariablen können im Wörterbuch vorhanden sein. Rufen Sie beim Aufrufen zuerst das Wörterbuch auf, um die Methodennamenvariable wiederherzustellen, und führen Sie sie dann aus.
Tatsächlich sind die Eingänge alle Regeln von Variablen.

Wörterbuchfunktion:

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;
};

Anhand der obigen Erkenntnisse können wir JS-Verwirrung in drei Kategorien einteilen, nämlich Bewertungstyp, Hash-Typ und Komprimierungstyp. Der Komprimierungstyp ist ein häufig verwendetes Tool zur Front-End-Leistungsoptimierung, dargestellt durch uglify.

Häufig verwendete Front-End-Komprimierungsoptimierungstools:

JavaScript:

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

CSS:

  • PostCSS
  • clean-css
  • CSSO
  • YUI Compressor

HTML:

  • html-minifier

Aus Sicht des Tool-Flows (Workflow), sei es Webpack oder Gulp, ist Uglify derzeit das beliebteste Tool für JavaScript.

Das entsprechende Deobfuscation-Tool:

  • Das zu eval entsprechende Deobfuscation-Tool kann auf Baidu durchsucht werden, z. B. jspacker
  • JSAs entsprechendes Deobfuscation-Tool unjsa
  • Das Deobfuskationstool crack.js entspricht Javascript-Obfuscator
  • Das Tool UnuglifyJS entspricht dem Komprimierungstyp uglify, die Online-Version jsnice

Die Deobfuskationsstrategie wird tatsächlich basierend auf generiert Regelmäßiges Schreiben von Code ist nichts anderes als das Beobachten der Feature-Analyse, das anschließende Beobachten der Feature-Analyse und das Vornehmen kontinuierlicher Anpassungen. Es sind alles Figuren, die man leicht erkennen kann.

Es gibt überhaupt keine Schwierigkeiten, alles was Sie brauchen ist Geduld. Beispielsweise kann das dem Javascript-Obfuscator entsprechende Deobfuscator-Tool
in ein N-Faktor-Problem zerlegt werden:

Wie frage ich den Umfang einer Funktion ab?
Mögliche Typen für die Variablenersetzung vor der Ausführung?
...

Zum Beispiel:

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

muss auf

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

zurückgesetzt werden. Der erste Schritt besteht darin, die Wörterbuchfunktion zu kennen und dann die Wörterbuchfunktion auszuführen _0x5b26('0x0') zum Wiederherstellen auf log.

Dann wird es einfacher, Code zu schreiben.
Zum Beispiel https://github.com/jscck/crac...

Wie man den Code nach der Wiederherstellung rekonstruiert, dann müssen Sie auch wissen, welches Tool-Webpack zuvor zum Packen des Codes verwendet wurde es erzeugen oder?

Zum Beispiel verschiedene Kapselungsheader und -tails von 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_;
});

Wenn Sie tiefer gehen, kann es sich um JS-Syntax handeln Interpreter, abstrakter AST-Syntaxbaum

Beinhaltet derzeit den JS-Syntaxinterpreter. Die Funktionen des AST-abstrakten Syntaxbaums sind wie folgt:

Prepack, Esprima, Babel

Oder Sie können Lesen Sie „Programmiersprachen-Implementierungsmuster“, einschließlich antlr4.

Natürlich können Sie zur Entschleierung auch Tools wie esprima verwenden, aber es ist nur ein bisschen mehr Arbeit und ob es sich lohnt.

Für die Zukunft könnte die Richtung der kommerziellen JS-Quellcodeverschlüsselung Webassembly sein. Kompilieren Sie ihn zunächst auf der Serverseite in wasm, und der Quellcode kann wirklich geschlossen sein.

Wo Menschen sind, ist eine Straße, und wo Verwirrung herrscht, ist auch Entschleierung. Die aktuellen Entschleierungswerkzeuge für die maschinelle Lernprogrammierung sind ebenfalls sehr gut, wie zum Beispiel

Labor für sichere, zuverlässige und intelligente Systeme

Maschinelles Lernen für Programmierprodukte
nice2predict, jsnice...
Ansicht https://www.sri.inf.ethz.ch/r...

Erweiterte Referenz

AST Abstract Syntax Tree

Warum zusätzlich über AST Abstract Syntax Tree sprechen, denn Sie können alles eingeben->

Wenn Sie beispielsweise jsx in die Syntax von Miniprogrammvorlagen konvertieren, können Sie die Reaktionssyntax verwenden, um Miniprogramme wie Taro zu schreiben.
mpvue, wepy, postcss... Dies sind alles Tools zum Erstellen und Konvertieren über AST es6 -> es5, babel verwenden alle AST.

Der allgemeine Prozess des abstrakten AST-Syntaxbaums:

Eingabe generiert einen AST-Baum

und führt dann die entsprechende Konvertierung durch AST-Typ-Assertion durch

[Verwandte Empfehlungen: JavaScript-Video-Tutorial

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Verschleierung und Entschleierung von Javascript (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen