Статья относительно длинная и подготовлена для всех, чтобы обеспечить эффективную передачу знаний.
Обфускация кода JavaScript — это метод, который преобразует и модифицирует код, чтобы усложнить его понимание и реверс-инжиниринг. Его основная цель — повысить сложность и запутанность кода, тем самым улучшая безопасность кода и возможности защиты интеллектуальной собственности.
Вот некоторые из основных последствий запутывания кода JavaScript:
Основная цель технологии сжатия кода — уменьшить размер файлов, чтобы веб-страницы или программы могли загружаться быстрее. Вообще говоря, пробелы, разрывы строк, комментарии и ненужные символы в коде будут удалены в процессе сжатия кода.
// исходный код
let v = "Hello World";
function foo(param) {
console.log(param);
}
foo(v);
// После сжатия
let v="Hello World";function foo(param){console.log(param)}foo(v);
Хотя сжатый код не меняет имена переменных, функций и т. д., он становится «комком», что все равно мешает нам читать. К счастью, сжатый код в принципе можно отформатировать непосредственно на некоторых онлайн-сайтах.
https://c.runoob.com/front-end/51/ https://tool.ip138.com/javascript/ https://www.sojson.com/yasuojs.html
Технологии обфускации кода различаются. В зависимости от используемой технологии большинство из них делают исходный код длиннее, но суть не в этом. Суть в том, чтобы сделать код нечитабельным и вы вообще его не сможете понять.
// исходный код
let v = "Hello World";
function foo(param) {
console.log(param)
}
foo(v);
// Простой После путаницы
eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('3 0="4 5";6 1(2){7.8(2)}1(0);',9,9,'v|foo|a|let|Hello|World|function|console|log'.split('|'),0,{}))
Запутанный код выглядит несколько странно и не похож на что-то, созданное людьми, что мешает общему анализу. Однако этот тип кода можно деобфусцировать непосредственно на некоторых онлайн-сайтах.
https://matthewfl.com/unPacker.html
После деобфускации я обнаружил, что весь код восстановлен. Вы говорите, что это обфускация, а это бесполезно, вы говорите, что это сжатие, но размер кода оно, похоже, не уменьшает.
Попробуем посмотреть время выполнения кода до и после обфускации.
// До путаницы
const t0 = performance.now();
let v = "Hello World";
function foo(param) {
console.log(param);
}
foo(v)
const t1 = performance.now();
console.log(t1 - t0, 'milliseconds');
// После путаницы
const t0 = performance.now();
eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('3 0="4 5";6 1(2){7.8(2)}1(0);',9,9,'v|foo|a|let|Hello|World|function|console|log'.split('|'),0,{}))
const t1 = performance.now();
console.log(t1 - t0, 'milliseconds');
Судя по этому вольному тесту, кажется, что он не может ускорить выполнение кода.
Этот вид packer
Технология, которая объединяет сжатие и обфускацию, хотя и не может эффективно защитить исходный код, но, по крайней мере, в определенной степени предотвращает автоматический анализ программы.
Далее мы рассмотрим немного более сложную путаницу.
// исходный код
let v = "Hello World";
function foo(param) {
console.log(param);
}
foo(v);
// После путаницы
const _0x44c967=_0x635b;(function(_0x32c587,_0xad783a){const _0x5f038b=_0x635b,_0xdd5abd=_0x32c587();while(!![]){try{const _0x36db7d=parseInt(_0x5f038b(0x1a4))/0x1*(-parseInt(_0x5f038b(0x1b0))/0x2)+parseInt(_0x5f038b(0x1a8))/0x3+-parseInt(_0x5f038b(0x1a5))/0x4+parseInt(_0x5f038b(0x1aa))/0x5*(parseInt(_0x5f038b(0x1a7))/0x6)+-parseInt(_0x5f038b(0x1af))/0x7*(parseInt(_0x5f038b(0x1ad))/0x8)+-parseInt(_0x5f038b(0x1ae))/0x9+-parseInt(_0x5f038b(0x1a6))/0xa*(-parseInt(_0x5f038b(0x1a9))/0xb);if(_0x36db7d===_0xad783a)break;else _0xdd5abd['push'](_0xdd5abd['shift']());}catch(_0x32d69b){_0xdd5abd['push'](_0xdd5abd['shift']());}}}(_0x2573,0x793ce));let v=_0x44c967(0x1ab);function foo(_0xddf157){const _0x57965d=_0x44c967;console[_0x57965d(0x1ac)](_0xddf157);}function _0x2573(){const _0x160bca=['7054758QHxQzs','7RhaGlF','2gnZgYk','139201SpYUUf','3355792nqHQax','9583830DxWDsR','3389808yzigdv','413817ZWQdzF','22UIVwDV','5AHuxCv','Hello\x20World','log','2888576mOrpTw'];_0x2573=function(){return _0x160bca;};return _0x2573();}function _0x635b(_0x119657,_0x5aecf8){const _0x257388=_0x2573();return _0x635b=function(_0x635be2,_0x5b4e35){_0x635be2=_0x635be2-0x1a4;let _0xe244e9=_0x257388[_0x635be2];return _0xe244e9;},_0x635b(_0x119657,_0x5aecf8);}foo(v);
Если бы не несколько ключевых слов, я бы даже не был уверен, что это так. javascript
код
правда, возможно, восстановить подобную путаницу будет сложнее Понятно,Но да, мы можем посмотреть, как приезжают,foo
Название функции не изменено. Вероятно, она еще полезна, но стоит ли оно того — вопрос.
Из приведенных выше случаев мы видим, что приезжать,Путаница между сжатием кода и кодом не означает, что это две полностью две технологии.,Просто предметы разные,Эти два метода часто комбинируются.,Поэтому в следующих статьях не будут подробно различаться сжатие кода и путаница кода.,Все они вместе называются путаницей кода.
В этой главе мы познакомим вас с некоторыми существующими методами обфускации. На мой взгляд, если нет готовых инструментов, временные затраты на решение сложных обфускаций слишком высоки, и оно того не стоит. Действительно, следующий контент более склонен понимать особенности языка и специальные методы, используемые при анализе различных методов.
UglifyJS — это набор инструментов для парсера, минификатора, минификатора и украшения JavaScript. https://lisperator.net/uglifyjs/ https://github.com/mishoo/UglifyJS/ https://github.com/LiPinghai/UglifyJSDocCN/blob/master/README.md
Как использовать
npm install uglify-js -g
uglifyjs example.js -c -m --mangle-props
// исходный код
const person = {
age: 18,
name: 'Tom'
}
function greet(name) {
var message = "Hello, " + name + "!";
return message;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name)
console.log(greeting);
console.log(greeting2);
// -c После сжатия
const person={age:18,name:"Tom"};function greet(name){return"Hello, "+name+"!"}var userName="John",greeting=greet(userName),greeting2=greet(person.name);console.log(greeting),console.log(greeting2);
мы проходим -b
Красивое отображение параметров
// -c После сжатия -b Украсить вывод
const person = {
age: 18,
name: "Tom"
};
function greet(name) {
return "Hello, " + name + "!";
}
var userName = "John", greeting = greet(userName), greeting2 = greet(person.name);
console.log(greeting), console.log(greeting2);
существовать -c
После сжатия
var
наделятьценитьзаявление Объединить в Понятно в одну строкуconsole.log
Объединить в Понятно в одну строку// -m После путаницы -b Украсить вывод
const person = {
age: 18,
name: "Tom"
};
function greet(e) {
var r = "Hello, " + e + "!";
return r;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name);
console.log(greeting);
console.log(greeting2);
существовать -m
После путаницы
name -> e
message -> r
// -m --mangle-props назад -b Украсить вывод
const person = {
g: 18,
name: "Tom"
};
function greet(e) {
var r = "Hello, " + e + "!";
return r;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name);
console.log(greeting);
console.log(greeting2);
существовать -m --mangle-props
назад
name -> e
message -> r
age -> g
// -c -m --mangle-props назад -b Украсить вывод
const person = {
g: 18,
name: "Tom"
};
function greet(e) {
return "Hello, " + e + "!";
}
var userName = "John", greeting = greet(userName), greeting2 = greet(person.name);
console.log(greeting), console.log(greeting2);
По сути, вышеуказанные эффекты суммируются, но вы можете видеть, что самые внешние переменные по-прежнему не перепутаны. Если вы хотите, чтобы самые высокие переменные были запутаны, вам нужно использовать . --toplevel
параметр
// --toplevel -c -m --mangle-props назад -b Украсить вывод
function o(o) {
return "Hello, " + o + "!";
}
o("John"), o("Tom");
console.log("Hello, John!"), console.log("Hello, Tom!");
Если честно, это более жестоко, просто убейте нас напрямую. выполнения Все Даватьдавай разберемся Понятно,И нашверно слона убили прямо Понятно,Может быть, да, потому что в продолжении назад не используется правильный символ приезжать.,В настоящее время мы пытаемся изменить исходный код,существоватьвыходназад Снова Даватьвернослонвсвойствонаделятьценить
// исходный код
const person = {
age: 18,
name: 'Tom'
}
function greet(name) {
var message = "Hello, " + name + "!";
return message;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name)
console.log(greeting);
console.log(greeting2);
person.name = "Kevin"
// --toplevel -c -m --mangle-props назад -b Украсить вывод
var o = {
o: 18,
name: "Tom"
};
function n(o) {
return "Hello, " + o + "!";
}
n("John");
var e = n(o.name);
console.log("Hello, John!"), console.log(e), o.name = "Kevin";
на этот раз Поскольку наше свойство верноверно слонв выполняет операцию Понятное присвоениеценить, код помогает нам сохранить Понятноверно слон,использовать --toplevel
назад,За исключением Понятно, результат выполнения тот же.,Большая часть контента становится Понятной
Однако, как вы можете видеть здесь, объект name
свойства, а также console.log
Судя по описанию на официальном сайте, он не изменился. UglifyJS
верно javascript
Имена собственных функций и свойств не запутаны.
проходитьверно UglifyJS Анализ результатов путаницы показал, что путаница может быть достигнута за счет следующих аспектов:
https://tool.chinaz.com/tools/jscodeconfusion.aspx
// исходный код
const person = {
age: 18,
name: 'Tom'
}
function greet(name) {
var message = "Hello, " + name + "!";
return message;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name)
console.log(greeting);
console.log(greeting2);
person.name = "Kevin"
// После путаницыизкод
const person = {
age: 18,
name: '\x54\x6f\x6d'
}
function greet(ifBR1) {
var rQnCc2 = "\x48\x65\x6c\x6c\x6f\x2c " + ifBR1 + "\x21";
return rQnCc2;
}
var zj3 = "\x4a\x6f\x68\x6e";
var $t$4 = greet(zj3);
var HhUkMNt5 = greet(person["\x6e\x61\x6d\x65"])
console["\x6c\x6f\x67"]($t$4);
console["\x6c\x6f\x67"](HhUkMNt5);
person["\x6e\x61\x6d\x65"] = "\x4b\x65\x76\x69\x6e"
person
вернослонв name
Недвижимость переоценить Tom -> \x54\x6f\x6d
greet
вформапараметрбыл переименован Понятно name -> ifBR1
greet
внаделятьценитьзаявлениевнитьодеяло替换 Hello, -> \x48\x65\x6c\x6c\x6f\x2c
, ! -> \x21
person.name -> person['name']
name -> \x6e\x61\x6d\x65
javascript
встроенные методы log
был переименован log -> \x6e\x61\x6d\x65
Приведенное выше да основано на сводке изменений в предыдущем назадкодизе.,верно для переменного имени, если функция форма, изменение имени, все уверены, да думает, что это очень распространено Понятно,Потому что пока фронт назад последователен,Это не изменит значения кода. здесь нужно внимание изда,казатьсясуществовать javascript
сама строка и ее ascii hex
Эффект выражения из такой же, как да из (существовать во многих языках означает да как из)
Этот вид метода обфускации можно использовать по следующему адресу:
Этот вид запутывания Написать автоматическое восстановление не должно быть сложно, и, возможно, удастся завершить часть существующей онлайн-платформы.
https://www.sojson.com/jsjiemi.html
https://tool.chinaz.com/js.aspx
// исходный код
const person = {
age: 18,
name: 'Tom'
}
function greet(name) {
var message = "Hello, " + name + "!";
return message;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name)
console.log(greeting);
console.log(greeting2);
person.name = "Kevin"
// После путаницы
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"',19,19,'name|var|greet|person|greeting|message|greeting2|userName|console|log|Tom|18|const|age|function|John|Kevin|Hello|return'.split('|'),0,{}))
Сначала отформатируйте его
eval(function(p, a, c, k, e, d) {
e = function(c) {
return (c < a ? "": e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
};
if (!''.replace(/^/, String)) {
while (c--) d[e(c)] = k[c] || e(c);
k = [function(e) {
return d[e]
}];
e = function() {
return '\\w+'
};
c = 1;
};
while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p;
} ('c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"', 19, 19, 'name|var|greet|person|greeting|message|greeting2|userName|console|log|Tom|18|const|age|function|John|Kevin|Hello|return'.split('|'), 0, {}))
Целое eval(code)
Этот Форма вида фактически выполнена да code
контент здесь code
даодиннитьтипизпеременная,code
Содержание следующее
function(p, a, c, k, e, d) {
e = function(c) {
return (c < a ? "": e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
};
if (!''.replace(/^/, String)) {
while (c--) d[e(c)] = k[c] || e(c);
k = [function(e) {
return d[e]
}];
e = function() {
return '\\w+'
};
c = 1;
};
while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p;
} ('c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"', 19, 19, 'name|var|greet|person|greeting|message|greeting2|userName|console|log|Tom|18|const|age|function|John|Kevin|Hello|return'.split('|'), 0, {})
Абстрактно говоря, это function(param){}(params)
Этот видформа,Этот вид формы немедленно вызвать выражение функции, просто прямой вызов анонимной функции, параметр просто да params
, например
(function(param){
console.log(param);
})("Hello, World!");
Другими словами, eval функцияпараметрда Это выражение функции немедленного вызова возвращает результат, который следует данитьценить.
Понятное решение Понятное решение назад, мы Сначала посмотрели немедленно выражение вызова функции изпараметрдачто из
'c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"', 19, 19, 'name|var|greet|person|greeting|message|greeting2|userName|console|log|Tom|18|const|age|function|John|Kevin|Hello|return'.split('|'), 0, {}
Связь с анонимной функцией в форме параметра будет следующей:
p -> 'c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"'
a -> 19
c -> 19
k ->'name|var|greet|person|greeting|message|greeting2|userName|console|log|Tom|18|const|age|function|John|Kevin|Hello|return'.split('|')
e -> 0
d -> {}
Парсинг для анализа анонимных функций
function(p, a, c, k, e, d) {
e = function(c) {
return (c < a ? "": e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
};
if (!''.replace(/^/, String)) {
while (c--) d[e(c)] = k[c] || e(c);
k = [function(e) {
return d[e]
}];
e = function() {
return '\\w+'
};
c = 1;
};
while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p;
}
Анонимные функции разделены на три части.
e
Назначенная функцияif
суждениезаявлениеwhile
циклСначала посмотри if
заявление
if (!''.replace(/^/, String)) {
while (c--) d[e(c)] = k[c] || e(c);
k = [function(e) {
return d[e]
}];
e = function() {
return '\\w+'
};
c = 1;
};
Заявление об условии true
,Затем прочитайте содержание виз
while (c--) d[e(c)] = k[c] || e(c);
c
Значение 19
, k[c]
очевидно,существоватьэтот пока циклсередина,k[c]
Они все ценные, давайте посмотрим e(c)
результат
while
циклназад, на самом деле да Воля множество становится Понятно верный значок d
k = [function(e) {
return d[e]
}];
Присвойте массив k
Первый член — это функция, основанная на имени атрибута из d
верно Получить атрибуты из изображения изценить
e = function() {
return '\\w+'
};
c = 1;
Назначьте функцию e
, эта функция очень проста, она просто возвращает \\w+
нить; дать переменную c
Назначено 1
В это время каждыйпеременная Содержание следующее
p -> 'c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"'
a -> 19
c -> 1
k -> Набор
e -> функция
d -> настоящий слон
while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
здесь while (c--)
Это прикрытие, потому что выше уже было c
установлен на 1 , поэтому он эквивалентен следующему коду абзаца
c = 0
if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
Судя по состоянию k[c]
Эквивалент функции, курс заявления определения функции да true
,Таким образом, код упрощается до
c = 0
func = function(e) {
return d[e]
}
p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), func);
в e
На самом деле функция вообще не имеет параметра формы, поэтому e(c)
в c
вообще никакого смысла,e(c)
Эквивалентно '\\w+'
,Таким образом, приведенный выше изкод эквивалентен
p = 'c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"'
func = function(e) {
return d[e]
}
p = p.replace(new RegExp('\\b\\w+\\b', 'g'), func);
Код этого абзаца заменяет заявление, первое регулярное выражение дапроходить соответствует всем словам
\\b
:Представлять словоизграница,используется для сопоставления словизначалоилиокончание。использоватьдвойная косая черта \\
дапотому что в существовании регулярное выражение, обратная косая черта \
да — специальный символ, который необходимо экранировать.\\w+
:表示одинилинесколько букв、числоили Подчеркнутый символ。\w
да — это предопределенный класс символов, который соответствует буквам, цифрам и знакам подчеркивания.\\b
:Снова次Представлять словоизграница,Используется для обеспечения полного соответствия слова.Что делать, если совпадение есть? Рассматривайте совпадающий контент как func
изпараметр, выполнить func
функция,и Воля возвращает ценить, заменяя контент, соответствующий приезжатьиз,Вернуться на замену
return p
Окончательный возврат замены назадизнитьпеременная p
Так,Так как он был наконец выполнен изкод после того, как еда заменилась назад,возвращатьсянитьпеременнаяp
Давать eval
исполнение, если бы мы хотели p
Что произойдет, если вы выведете его напрямую?
// Изменить назад
console.log(функция(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('c 3={d:b,0:\'a\'}e 2(0){1 5="h, "+0+"!";i 5}1 7="f";1 4=2(7);1 6=2(3.0)8.9(4);8.9(6);3.0="g"',19,19,'name|var|greet|person|greeting|message|greeting2|userName|console|log|Tom|18|const|age|function|John|Kevin|Hello|return'.split('|'),0,{}))
нашисточниккод Просто восстановить Понятно
На этом этапе можно задуматься. А важно ли, как происходит процесс замены?
Это вообще не важно,Потому что его можно полностью превратить в черный ящик.,Не стесняйтесь настраиватьизверноисходный кодировать, чтобы изменить,назад обеспечивает окончательный и обратный процесс сокращения,финальныйпроходить eval
Для реализации, возвращаясь к первоначальному намерению приезжатьнаш, мы анализируем Эту из Очки знаний, используемые при запутанном сжатии
eval
Функция Волянит выполняется в виде кодаfunction(param){}(params)
Нет, все остальное можно изменить.
https://www.jshaman.com/ Отечественная компания JShaman разрабатывает коммерческие криптографические продукты из jscode
Бесплатная версия может быть использована напрямую
// исходный код
const person = {
age: 18,
name: 'Tom'
}
function greet(name) {
var message = "Hello, " + name + "!";
return message;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name);
console.log(greeting);
console.log(greeting2);
person.name = "Kevin";
// После путаницы
const person={"\u0061\u0067\u0065":0x12,"\u006e\u0061\u006d\u0065":"\u0054\u006f\u006d"};function greet(_0x753eb2){var _0x4445de=" ,olleH".split("").reverse().join("")+_0x753eb2+"\u0021";return _0x4445de;}var userName="nhoJ".split("").reverse().join("");var greeting=greet(userName);var greeting2=greet(person["\u006e\u0061\u006d\u0065"]);console["\u006c\u006f\u0067"](greeting);console["\u006c\u006f\u0067"](greeting2);person["\u006e\u0061\u006d\u0065"]="niveK".split("").reverse().join("");
Давайте отформатируем его
// Формат назад
const person = {
"\u0061\u0067\u0065": 0x12,
"\u006e\u0061\u006d\u0065": "\u0054\u006f\u006d"
};
function greet(_0x753eb2) {
var _0x4445de = " ,olleH".split("").reverse().join("") + _0x753eb2 + "\u0021";
return _0x4445de;
}
var userName = "nhoJ".split("").reverse().join("");
var greeting = greet(userName);
var greeting2 = greet(person["\u006e\u0061\u006d\u0065"]);
console["\u006c\u006f\u0067"](greeting);
console["\u006c\u006f\u0067"](greeting2);
person["\u006e\u0061\u006d\u0065"] = "niveK".split("").reverse().join("");
Unicode это имя таблицы кодировки Unicode кодирование на самом деле имеет разные формы реализации, в \u0000 Этот Форма вида — это escape-последовательность Юникода, форма выражения дав, которую часто называют Unicode кодировка, которая также будет использоваться ниже Unicode Вызывается по коду, надеюсь, это никому не доставляет хлопот.
Unicode
кодированиеUnicode
кодирование_0x
Начиная с из формы из символов_0x
Начиная с из формы из символов"Hello, " -> " ,olleH".split("").reverse().join("")
Говоря о прибытии, первоначальный характер даверно подвергается процессу Понимания, а результат остается неизменным.! -> \u0021
Некоторые персонажи становятся Unicode
кодирование"John" -> "nhoJ".split("").reverse().join("")
Unicode
кодированиеформаТехнология, используемая в бесплатной версии, также относительно проста. Основные моменты, которые можно резюмировать:
Unicode
формавыражатьhttps://obfuscator.io/ https://github.com/javascript-obfuscator/javascript-obfuscator Бесплатный и эффективный JavaScript Обфускаторы (в том числе верно ES2022 из поддержки). Усложняет копирование и не позволяет людям украсть вашу работу. Этот инструмент является отличным веб-сайтом. Пользовательский интерфейс (и открытый исходный код)
img
Размещение этого значка на официальном сайте может означать, что этот проект зашифрован и заставляет людей выглядеть так, будто им хочется плакать.
Для этого инструмента существует множество настраиваемых элементов. Давайте сначала воспользуемся формой по умолчанию на официальном сайте, чтобы увидеть эффект.
// исходный код
const person = {
age: 18,
name: 'Tom'
}
function greet(name) {
var message = "Hello, " + name + "!";
return message;
}
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name);
console.log(greeting);
console.log(greeting2);
person.name = "Kevin";
// После путаницы
var _0x5665ce=_0x1ec8;(function(_0x24a0fc,_0x32277b){var _0x470fc7=_0x1ec8,_0x314734=_0x24a0fc();while(!![]){try{var _0x19fb94=-parseInt(_0x470fc7(0xca))/0x1+parseInt(_0x470fc7(0xc8))/0x2+parseInt(_0x470fc7(0xc9))/0x3+-parseInt(_0x470fc7(0xc5))/0x4+-parseInt(_0x470fc7(0xc4))/0x5+-parseInt(_0x470fc7(0xcb))/0x6+parseInt(_0x470fc7(0xcd))/0x7;if(_0x19fb94===_0x32277b)break;else _0x314734['push'](_0x314734['shift']());}catch(_0x11f2da){_0x314734['push'](_0x314734['shift']());}}}(_0xd8be,0xcb4d8));const person={'age':0x12,'name':'Tom'};function greet(_0x232d03){var _0x158862='Hello,\x20'+_0x232d03+'!';return _0x158862;}function _0x1ec8(_0x200d59,_0x33a7d8){var _0xd8be2c=_0xd8be();return _0x1ec8=function(_0x1ec879,_0x3bf5b6){_0x1ec879=_0x1ec879-0xc4;var _0x4acfea=_0xd8be2c[_0x1ec879];return _0x4acfea;},_0x1ec8(_0x200d59,_0x33a7d8);}var userName=_0x5665ce(0xc6),greeting=greet(userName),greeting2=greet(person[_0x5665ce(0xcc)]);function _0xd8be(){var _0x303cd1=['4525950NEPdZY','5502416viTywx','John','log','2506568dDijWh','1830627XxDgMI','46606dGrOiI','2093556sEUamv','name','11518927TWTtrQ'];_0xd8be=function(){return _0x303cd1;};return _0xd8be();}console['log'](greeting),console[_0x5665ce(0xc7)](greeting2),person[_0x5665ce(0xcc)]='Kevin';
Попробуйте отформатировать его
// Формат назад
var _0x5665ce = _0x1ec8; (function(_0x24a0fc, _0x32277b) {
var _0x470fc7 = _0x1ec8,
_0x314734 = _0x24a0fc();
while ( !! []) {
try {
var _0x19fb94 = -parseInt(_0x470fc7(0xca)) / 0x1 + parseInt(_0x470fc7(0xc8)) / 0x2 + parseInt(_0x470fc7(0xc9)) / 0x3 + -parseInt(_0x470fc7(0xc5)) / 0x4 + -parseInt(_0x470fc7(0xc4)) / 0x5 + -parseInt(_0x470fc7(0xcb)) / 0x6 + parseInt(_0x470fc7(0xcd)) / 0x7;
if (_0x19fb94 === _0x32277b) break;
else _0x314734['push'](_0x314734['shift']());
} catch(_0x11f2da) {
_0x314734['push'](_0x314734['shift']());
}
}
} (_0xd8be, 0xcb4d8));
const person = {
'age': 0x12,
'name': 'Tom'
};
function greet(_0x232d03) {
var _0x158862 = 'Hello,\x20' + _0x232d03 + '!';
return _0x158862;
}
function _0x1ec8(_0x200d59, _0x33a7d8) {
var _0xd8be2c = _0xd8be();
return _0x1ec8 = function(_0x1ec879, _0x3bf5b6) {
_0x1ec879 = _0x1ec879 - 0xc4;
var _0x4acfea = _0xd8be2c[_0x1ec879];
return _0x4acfea;
},
_0x1ec8(_0x200d59, _0x33a7d8);
}
var userName = _0x5665ce(0xc6),
greeting = greet(userName),
greeting2 = greet(person[_0x5665ce(0xcc)]);
function _0xd8be() {
var _0x303cd1 = ['4525950NEPdZY', '5502416viTywx', 'John', 'log', '2506568dDijWh', '1830627XxDgMI', '46606dGrOiI', '2093556sEUamv', 'name', '11518927TWTtrQ'];
_0xd8be = function() {
return _0x303cd1;
};
return _0xd8be();
}
console['log'](greeting),
console[_0x5665ce(0xc7)](greeting2),
person[_0x5665ce(0xcc)] = 'Kevin';
Если мы не знаем исход кодда Что?,Кажется, да в полном отчаянии,ноданассуществовать Знатьисходный кодизкейс,Это также можно проанализировать
// верная часть определения изображения
// исходный код
const person = {
age: 18,
name: 'Tom'
}
// После путаницы
const person = {
'age': 0x12,
'name': 'Tom'
};
верная часть определения изображенияосновнойда Волясвойствоценитьсередина数ценитьформаиспользовать Понятно 16 шестнадцатеричное представление
// Часть определения функции
// исходный код
function greet(name) {
var message = "Hello, " + name + "!";
return message;
}
// После путаницы
function greet(_0x232d03) {
var _0x158862 = 'Hello,\x20' + _0x232d03 + '!';
return _0x158862;
}
Основные изменения в определении функции заключаются в следующем:
_0x
из формы_0x
из формы' ' -> \x20
// Глобальная переменная часть определения
// исходный код
var userName = "John";
var greeting = greet(userName);
var greeting2 = greet(person.name);
// После путаницы
var userName = _0x5665ce(0xc6),
greeting = greet(userName),
greeting2 = greet(person[_0x5665ce(0xcc)]);
Обычно это нормально настроить. _0x5665ce(0xc6)
,А также параметр,параметр еще не является оригинальным и его различное кодирование,Давайте наклеим Функционкод
var _0x5665ce = _0x1ec8;
_0x5665ce
изценитьравный _0x1ec8
, давайте посмотрим _0x1ec8
function _0x1ec8(_0x200d59, _0x33a7d8) {
var _0xd8be2c = _0xd8be();
return _0x1ec8 = function(_0x1ec879, _0x3bf5b6) {
_0x1ec879 = _0x1ec879 - 0xc4;
var _0x4acfea = _0xd8be2c[_0x1ec879];
return _0x4acfea;
},
_0x1ec8(_0x200d59, _0x33a7d8);
}
Эта форма функции немного интересна. Придумайте вызов функции, и результату выполнения Воляфункции присваивается переменная, а затем возвращается назад. return
Понятно,по-видимомуreturn
Два возвращаемых значения, первое возвращаемое значение новое. _0x1ec8
Функция второго возвратаценитьдаверно в новом; _0x1ec8
Возвращаемое значение вызова функции, Передать isparameter Нарихара _0x1ec8
Функция в параметре, без изменений
var userName = _0x5665ce(0xc6)
мы знаем userName
Значение John
,нода В настоящее время кажется userName
Значение должно быть определением функции. Давайте выведем его.
здесь мы действительно можем сравнить eval packer
Понятно,Это всего лишь простая замена замены,Несмотря на то Воляисходный коды извлечены частично,Хранение, сращивание, замена и т.п. в различных формах, таких как множество, словари и т.п.,Наконец восстановить,здесь Поверхность не используетсяприезжатьсложныйиз Грамматика иjs
Характеристики самого языка, поэтому мы не можем ничему научиться, разгадывая его постепенно; этоткод Это другое Понятно,Давайте разгадаем это шаг за шагом,Попробуйте изучить идеи виз
В настоящее время я уже выполнил некоторые из вышеперечисленных результатов, например, из назначенной цены, функции и т. д., что привело к понятным сомнениям.,Это отличается от моего предыдущего понимания,такнас Воля После путаницыизкод аннотация
// Частичный кодAbstract назад
function func1(param1, param2) {
var var_1 = 'test';
return func1 = function(new_param1, new_param2) {
new_param1 = new_param1 - 0xc4;
var var_2 = new_param1;
return var_2;
},
func1(param1, param2);
}
var a, b = func1(0xc6)
console.log(a) // Результат выполненияда undefined
console.log(b) // Результат выполненияда 2 , то есть да — это число ценить, а не определенная функция
Если мы используем две переменные для получения func1
Каков будет результат выполнения
На этот раз это стало переменной b
Значение 2 ,a
для undefined
Если мы используем три переменные для получения func1
Каков будет результат выполнения
// Частичный кодAbstract назад
function func1(param1, param2) {
var var_1 = 'test';
return func1 = function(new_param1, new_param2) {
new_param1 = new_param1 - 0xc4;
var var_2 = new_param1;
return var_2;
},
func1(param1, param2);
}
var a, b, c = func1(0xc6)
console.log(a)
console.log(b)
console.log(b)
на этот раз c
Значение 2 Понятно
Если у нас есть только переменные a
получать func1
возвращаемое значение, но изменить func1
Возвращаемое значение оставляет только новое определение функции.
function func1(param1, param2) {
var var_1 = 'test';
return func1 = function(new_param1, new_param2) {
new_param1 = new_param1 - 0xc4;
var var_2 = new_param1;
return var_2;
}
}
var a = func1(0xc6)
console.log(a)
на этот раз возвращает результат определения функции, в этот раз, если мы используем двепеременную получение func1
результат выполнения
function func1(param1, param2) {
var var_1 = 'test';
return func1 = function(new_param1, new_param2) {
new_param1 = new_param1 - 0xc4;
var var_2 = new_param1;
return var_2;
}
}
var a, b = func1(0xc6)
console.log(a)
console.log(b)
Переменные в это время b
Значениефункцияопределение Понятно
Итак, здесь есть два измерения сложной сцены.,Мы снова абстрагируемся,Новое определение изфункции больше не имеет того же имени, что и исходная Функция Понятно.
function func1(o1) {
return func2 = function(n1) {
return n1;
}, 2
}
var a, b, c = func1(0xc6)
console.log(a)
console.log(b)
console.log(c)
Кажется, что результат не изменился. Может быть, когда определение функции и другие типы возвращаются одновременно, ее значение автоматически становится равным. undefined
Понятно??
function func1(o1) {
return () => {}, 2, "3"
}
var a, b, c = func1(0xc6)
console.log(a)
console.log(b)
console.log(c)
На этот раз мы создадим три возвращаемых значения, а именно: определение функции, числовое значение и строку.
Посмотри на это,Я в замешательстве,После запроса информации,Я ищу место Понятнодва измерения сложности по причине
В JavaScript функция может иметь только один возврат ценить.,Просто скажите, что если вы еще не изучали этот материал раньше
js
кто бы мог подуматьприезжать Бар!而且return 1, 2
также Нет会报错,Да будет реализовано в соответствии с определенными спецификациями.,В конце концов вернуть больше всего назад аценить
На этом этапе нам не нужна абстракция. Понятно, и мы можем продолжить рассмотрение. _0x1ec8
Задействована еще одна функция _0xd8be
Понятно
function _0xd8be() {
var _0x303cd1 = ['4525950NEPdZY', '5502416viTywx', 'John', 'log', '2506568dDijWh', '1830627XxDgMI', '46606dGrOiI', '2093556sEUamv', 'name', '11518927TWTtrQ'];
_0xd8be = function() {
return _0x303cd1;
};
return _0xd8be();
}
Эта функция возвращает массив, и следующий процесс выполнения такой же, как и eval packer
Никакой разницы. Понятно, как бороться с ничьими вещами.
console['log'](greeting),
console[_0x5665ce(0xc7)](greeting2),
person[_0x5665ce(0xcc)] = 'Kevin';
Об этой части особо сказать нечего, это просто компенсационная проблема.
Кроме Понятно, мы обсуждали изкод,И абзац никогда не обсуждался,Но да, это работает Понятно
(function(_0x24a0fc, _0x32277b) {
var _0x470fc7 = _0x1ec8,
_0x314734 = _0x24a0fc();
while ( !! []) {
try {
var _0x19fb94 = -parseInt(_0x470fc7(0xca)) / 0x1 + parseInt(_0x470fc7(0xc8)) / 0x2 + parseInt(_0x470fc7(0xc9)) / 0x3 + -parseInt(_0x470fc7(0xc5)) / 0x4 + -parseInt(_0x470fc7(0xc4)) / 0x5 + -parseInt(_0x470fc7(0xcb)) / 0x6 + parseInt(_0x470fc7(0xcd)) / 0x7;
if (_0x19fb94 === _0x32277b) break;
else _0x314734['push'](_0x314734['shift']());
} catch(_0x11f2da) {
_0x314734['push'](_0x314734['shift']());
}
}
} (_0xd8be, 0xcb4d8));
этот абзацкод Кажетсядаодин Выражение функции немедленного вызова,Он включает в себя много содержания и труден для понимания.,Но когда удали этот абзац кодназад,верно Весь результат выполнения не имеет никакого влияния,Итак, этот абзац да Дават. Давайте добавим код блокировки и смерти.
Далее мы можем подвести итог JavaScript obfuscator
Конфигурация по По умолчанию запутывание с использованием некоторых методов Понятно
функция(параметр)
извернутьценить, чтобы получить
Как выполнить функцию,не важно,это может измениться,нодафункциясередина涉及Понятно Точка вмешательства_0x
,При этом функция внутренне предполагает выездные расчеты.,Процесс расчета включает в себя использование шестнадцатеричных чисел (0x).,так _0x
и 0x
Легко спутать, как плохо ты говоришьjavascript
Функция имеет только одно возвращаемое свойство ценитьиз, что сбивает с толку.Давайте посмотрим дальше JavaScript obfuscator
Какое влияние окажут эти элементы конфигурации?
https://obfuscator.io/#code
Официальный сайт предоставляет понятные графические элементы конфигурации и достоверный анализ элементов конфигурации. Вы также можете просмотреть их на официальном сайте.
существоватьпредварительнонастраиватьсередина,На картинке четыре пресета,Индивидуальных пунктов настройки должно быть несколько десятков.,Четыре пресета используют разные конфигурации,Немногокартинасередина杯、Большая чашка、догонять Большая чашкаизиметь в виду
Элементов конфигурации много и скриншоты недостаточно полные. Для их просмотра можно зайти на официальный сайт.
среда выполнения отображаемого кодирования
eval
nodejs
Это зависит от конкретной среды выполнения. Понятно
тип: string|number
по умолчанию: 0
Начальное число случайных чисел, хотя в официальном описании существования говорится да. string|number
, но судя по настройкам официального сайта, он должен поддерживать только number
, Настройка начального значения случайного числа может сделать случайность более безопасной. К счастью, некоторое время назад мастер проанализировал уязвимости, вызванные некоторыми алгоритмами генерации случайных чисел.
Boolean
Тип опций конфигурации
Эта опция глобально отключает вызовы консоли для всех скриптов.
добавив console.log、console.info、console.error、console.warn、console.debug、console.exception и console.trace
Замените их пустыми функциями, чтобы отключить их. Это усложняет использование отладчика.
Давайте проверим эту опцию и попробуем отменить другие опции на данный момент.
// исходный код
console.log("Hello World!");
// После путаницы
var b = (function () {
var c = !![];
return function (d, e) {
var f = c ? function () {
if (e) {
var g = e['apply'](d, arguments);
e = null;
return g;
}
} : function () {
};
c = ![];
return f;
};
}());
var a = b(this, function () {
var c;
try {
var d = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
c = d();
} catch (l) {
c = window;
}
var f = c['console'] = c['console'] || {};
var g = [
'log',
'warn',
'info',
'error',
'exception',
'table',
'trace'
];
for (var h = 0x0; h < g['length']; h++) {
var i = b['constructor']['prototype']['bind'](b);
var j = g[h];
var k = f[j] || i;
i['__proto__'] = b['bind'](b);
i['toString'] = k['toString']['bind'](k);
f[j] = i;
}
});
a();
console['log']('Hello\x20World!');
Давайте выполним это путаницыизкод
Можно смотреть приезжать, ведь да Воля вывод на консоль запрещен Понятно
Кратко разберем, как это делается
Кодобщий состоит из четырех частей,Последняя часть не означает «Понятно».,前面основнойдасоздавать Понятнодвапеременная,назадвызов Понятноводинсвойстводляфункцияизпеременная,заставить его выполнить,нас Можетсуществовать a
и b
Вывод между переменными, чтобы узнать, были ли они заблокированы в данный момент.
существовать a
Попробуйте сделать то же самое перед выполнением
Видно, что все предыдущие шаги — это предзнаменование и исполнение. a
Функцияназад вывод на консоль отключен Понятно
иметь Понятновозможноиз Понятноразвязатьназад,Вы можете начать анализировать шаг за шагом,Да b
часть
// b часть
var b = (function () {
var c = !![];
return function (d, e) {
var f = c ? function () {
if (e) {
var g = e['apply'](d, arguments);
e = null;
return g;
}
} : function () {
};
c = ![];
return f;
};
}());
С этим должен быть знаком каждый: Понятно,Также дано выражение функции немедленного вызова.,Тогда мы сможем напрямую посмотреть, что выполняет это выражение назадрезультатда
Вы можете посмотреть приезжать,Это выражение дает анонимную функцию,Воля匿имяфункциянаделятьценитьдать переменную b
Конкретное выполнение данного пункта зависит от c
Стоимость a
часть
// a часть
var a = b(this, function () {
var c;
try {
var d = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
c = d();
} catch (l) {
c = window;
}
var f = c['console'] = c['console'] || {};
var g = [
'log',
'warn',
'info',
'error',
'exception',
'table',
'trace'
];
for (var h = 0x0; h < g['length']; h++) {
var i = b['constructor']['prototype']['bind'](b);
var j = g[h];
var k = f[j] || i;
i['__proto__'] = b['bind'](b);
i['toString'] = k['toString']['bind'](k);
f[j] = i;
}
});
общий a
да b
Возвращаемое значение вызова функции, параметр (this, function)
function (d, e) {
var f = c ? function () {
if (e) {
var g = e['apply'](d, arguments);
e = null;
return g;
}
} : function () {
};
c = ![];
return f;
};
здесь интересно, Понятно, а да — тернарный оператор. f = c ? func1(){} : func2(){}
, здесь согласно c
судить о ценности f
конечное значение переменной
Людям легко усомниться в изде, c
приезжатьконецсуществоватьгде,хорошийкартина没иметь c
изDefinition, параметра нет, но да b
в выражении немедленного вызова return
раньше имел это значение
(function(){
var c = !![];
return function(){}
})
Но даздесьиз c
Хотя мы влюблены друг в друга return
Она относится к внешнему слою с точки зрения изфункции, но да в целом является также дасуществоватьфункцию внутри тела из, существующего в настоящее время. Является ли это все еще эффективным в обстоятельствах вида?
здесьизграмматикасуществовать javascript
По-китайски это называется закрытие, также считается да. javascript
языковые особенности
закрытие(closure)дафункцияи его комплектиз Состояние окружающей среды(lexical environment,лексическая среда)из Цитироватьизкомбинация。换而言Из,закрытиепозволять开发者Может从внутреннийфункциядоступ к внешнемуфункцияиз Объем。существовать JavaScript , замыкание будет создано одновременно с созданием функции. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
function outer() {
var outerVar = 'Hello';
function inner() {
var innerVar = ' World';
console.log(outerVar + innerVar);
}
return inner;
}
var closure = outer();
closure();
здесь выглядит как closure
переменнаяравныйизда inner
функция,Зависит от Взакрытиеграмматикаизжитьсуществовать,На самом деле, это условие inner
А сочетание его верхнего окружения (включая переменные) и эффект замыкания можно проверить по результатам выполнения.
Так позвони b
Функциивремя,c
Значение true
,Поэтому это упрощается до
function (d, e) {
var f = function () {
if (e) {
var g = e['apply'](d, arguments);
e = null;
return g;
}
};
c = ![];
return f;
};
Вы можете видеть приезжать, на самом деле здесь также дазакрытие, существует анонимная функция, встроенная внутри. Понятно анонимная функция, пройдите, дайте переменную f
跟нас上面из案例没иметь区别,здесьтак называемыйиз Окружающая средадаd
и e
, d
В принципе, это такая же общая картина, e
даафункция и, конечно же, ручной сброс на false
из c
Дальше идет большая часть приезжать a()
, на самом деле, это просто да f()
,Упрощено следующим образом
var d = window;
var e = function () {
var c;
try {
var d = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
c = d();
} catch (l) {
c = window;
}
var f = c['console'] = c['console'] || {};
var g = [
'log',
'warn',
'info',
'error',
'exception',
'table',
'trace'
];
for (var h = 0x0; h < g['length']; h++) {
var i = b['constructor']['prototype']['bind'](b);
var j = g[h];
var k = f[j] || i;
i['__proto__'] = b['bind'](b);
i['toString'] = k['toString']['bind'](k);
f[j] = i;
}
};
var a = function () {
if (e) {
var g = e['apply'](d, arguments);
e = null;
return g;
}
};
a();
очевидно e
изценить Нетда false
,Итак, условие входазаявлениесередина, на самом деле, это просто даслово
var g = e['apply'](d, arguments);
наш e
даафункция, афункцияиз apply
Что означает атрибут да?
здесь Это снова включает в себяприезжатьjavascript
функцияизхарактеристика Понятно —— apply
Function
примерapply()
метод примет заданноеthis
ценитьи作длямножество(илидобрыймножествовернослон)поставлятьизarguments
Вызовите эту функцию. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
apply(thisArg)
apply(thisArg, argsArray)
thisArg
вызов func
предоставлено на this
ценить. Если функция не в строгом режиме (Strict_mode), то null
и undefined
会одеяло替换дляобщая ситуациявернослон,Исходная цена будет преобразована в «верно слон».
argsArray
НеобязательныйИконка класса множествоверно для изображенныхвызов func
Если параметр отсутствует или не требуется указывать параметр для функции, тогда null
или undefined
。
Приведите пример
function greet(msg) {
console.log(`Hello, ${this.name}!`);
console.log(msg)
}
var person1 = {
name: 'John'
};
var persion2 = {
name: 'Alice'
};
greet.apply(person1, ["John is best!"]);
console.log("----------")
greet.apply(persion2, ["Alice, come on."]);
здесь greet
Функция От кого именно здоровается зависит this
Кого оно представляет? apply
из Эффектдаобозначениефункциявызовкогдаизthis
ценить.
Анонимнаяфункцияда Нет apply
методический
arguments
да — это специальный значок изверно, который содержит Понятнофункциявызов при передаче всех параметров, независимо от того, определена ли да или существующая функция в определении Понятно для этих параметров. Оно похоже на множество, но не является настоящим измножеством. Он имеет такие свойства и методы, как множество, например length
Доступ к свойствам и индексам, но других методов у него нет.
Итак, вышеизкодиззначениедаобозначение Понятноe
Когда функция выполняется this
даобщая ситуациявернослон,назад выполняется по оригинальной версии.
Далее мы посмотрим e
функция
var e = function () {
var c;
try {
var d = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
c = d();
} catch (l) {
c = window;
}
var f = c['console'] = c['console'] || {};
var g = [
'log',
'warn',
'info',
'error',
'exception',
'table',
'trace'
];
for (var h = 0x0; h < g['length']; h++) {
var i = b['constructor']['prototype']['bind'](b);
var j = g[h];
var k = f[j] || i;
i['__proto__'] = b['bind'](b);
i['toString'] = k['toString']['bind'](k);
f[j] = i;
}
};
сначала дапроходить try...catch
Давать c
руководить Понятнонаделятьценить
Сначала посмотриодин разtry
внутренний код
var d = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
c = d();
Кажется, что да создаёт Понятно функцию d
,Изназадсновавызов d
функция,и Волявозвращатьсяценитьнаделятьценить Давать c
Этот абзац кодиспользовать Понятно Javascript
Встроенная структурная функция Function
, он может принять нитпараметр и преобразовать его в объект-функцию, что случается очень редко, Поскольку такой способ написания сделает читабельность очень плохой, я не ожидал, что приезжать будут путать с существованием, здесь Понятно, а также да JavaScript
изхарактеристика Понятно
bf976b12gy1ghfo72u6qlg206m05ydg2
Воля 16 шестнадцатеричное представление символа восстанавливается следующим образом: назад
var d = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
c = d();
Этот абзац на самом деле возвращает Понятное выражение немедленной функции вызова, используемое для получения глобального истинного объекта, поэтому c
Значениеобщая ситуациявернослон
Фактически, из catch
вкод также может видеть подсказки
var f = c['console'] = c['console'] || {};
var g = [
'log',
'warn',
'info',
'error',
'exception',
'table',
'trace'
];
определениедвапеременнаяf
иg
, f
даиндивидуальныйвернослон;g
да Набор, на самом деле, это просто да f
из一些成员свойствоимя称,f[g]
Сразудахотетьодеяло禁止из,Поэтому следующий исход следует сочетать с да Воля,назадпроходить Несколько способов запретить это
for (var h = 0x0; h < g['length']; h++) {
var i = b['constructor']['prototype']['bind'](b);
var j = g[h];
var k = f[j] || i;
i['__proto__'] = b['bind'](b);
i['toString'] = k['toString']['bind'](k);
f[j] = i;
}
абзац for
циклкод,определение Понятно i j k
три переменные
var i = b['constructor']['prototype']['bind'](b);
b
Первая часть выражения «да немедленно вызвать» возвращает функцию, поэтому здесь также есть «да». func.constructor.prototype.bind(func)
здесьсновада javascript
изхарактеристика Понятно
здесь涉及几индивидуальный概念constructor
、prototype
、proto
img
constructor
даструктурафункция,prototype
Конструктивная функция имеет prototype
свойство,Указывает на экземпляр верного объекта и прототип верного объекта. Экземплярное изображение имеет атрибут proto.,Указатель на экземпляр
Это выглядит сложно,Особенно их имя так сбивает с толку.,Заставляет людей терять желание помнить,Просто картинаяверно в память о старшинстве и памяти,Вы можете надеть его только при использовании приезжатьиз
Картинки из следующей статьи https://www.cnblogs.com/xiaohuochai/p/5721552.html https://blog.csdn.net/cc18868876837/article/details/81211729
Теперь мы начинаем анализировать приведенный выше код абзаца.
b['constructor']
Также дасуществовать в поисках силы верно слон b
изструктурировать функцию, она просто изструктурировать функцию Function
b['constructor']['prototype']
эквивалентно Function
из prototype
свойство,это указывает на экземплярвернослонb
из原формавернослон
b['constructor']['prototype']['bind'](b)
вызов Понятно bind
метод, этот метод Function.prototype
серединажитьсуществовать,Чтосуществовать Пример b
Мы живем в Китае
bind
Метод заключается в изменении окружения (это) ,具体Сразуда Воляthis
Укажите на параметр, например
const obj = {
x: 1
}
x = 0
var b = function() {
console.log("1111")
console.log(this.x)
}
console.log('-- 1 --')
var i = b
i()
console.log('-- 2 --')
i = b.bind(obj)
i()
Это можно увидеть сквозь bind
метод, функция Воля нового поколения i
изthis
Зависит отwindow/global
становиться Понятно obj
Далее я расширю этот случай
const obj = {
x: 1
}
x = 0
var b = function() {
console.log("1111")
console.log(this.x)
}
console.log('-- 1 --')
var i = b
i()
console.log('-- 2 --')
i = b.bind(obj)
i()
console.log('-- 3 --')
i = b.constructor.prototype.bind(obj)
i()
здесь интересно Понятно, зачем приезжать b.constructor.prototype.bind(obj)
здесь не выводится Понятно?
Эту модель я придумал назад и абстрагировал ее из,Я ищу любую информацию,Я уже давно об этом думаю и до сих пор не понимаю.,Я тоже не понимаю Понятно
на самом деледа因длявызов bind методический Нетда b Да Function.prototype , так что приезжай i
Нисколько b
Функция является основой для изменения Понятной среды из, что приводит к вышеописанной ситуации из
Теперь мы можем вернуться и проанализировать этот абзац кода Понятно.
var i = b['constructor']['prototype']['bind'](b);
Хотя сначала да b
,передачаизпараметртакжеда b
, но на самом деле генерирует новый шаблон Функций, это не так. b
,так i
Естественно b
Функции разные Понятно
var j = g[h];
var k = f[j] || i;
j
Просто да вспомогательная переменная - имя атрибута, подскажите k
获取свойствоизценить,Например console.log
переоценить, поэтому k
Просто да, чтобы меня забанили из метода Понятно
i['__proto__'] = b['bind'](b);
i['toString'] = k['toString']['bind'](k);
f[j] = i;
банда Шинда i
Функция добавляет некоторые атрибуты, такие как цепные связи, символы кода и т. д., но да на самом деле не имеет особого смысла. Удаление первых двух строк напрямую почти не влияет. Главное, это самая задняя строка да, Воля. i
Функция назначает ценить Давать, чтобы заблокировать метод из, то есть указанный вызов. console.log
等эквивалентновызов i
,Конечно, выхода не будет.,Доехать Понятно экранировать из-за эффекта
Эта часть анализа немного длинная. Следующий шаг — это, главным образом, понимание элементов конфигурации.
тип:Boolean
значение по умолчанию:false
⚠️ использоватьэтот вариант После путаницы, ни в коем случае не меняйте обфускационный изкод, потому что любое из изменений, например, очернение кода, вызовет самозащиту, код Воля больше не будет работать! ⚠️этот вариант强制Воляcompact
установлен наtrue Эта опция делает выходной код устойчивым к форматированию и переименованию. Если попытаться существовать, запутайтесь в исходном коде onuse. JavaScript Украшатель,код Воля больше не работает,Это усложняет понимание и модификацию.
// исходный код
console.log(123)
// После путаницы
var b=(function(){var c=!![];return function(d,e){var f=c?function(){if(e){var g=e['apply'](d,arguments);e=null;return g;}}:function(){};c=![];return f;};}());var a=b(this,function(){return a['toString']()['search']('(((.+)+)+)+$')['toString']()['constructor'](a)['search']('(((.+)+)+)+$');});a();console['log'](0x7b);
код работает нормально
Попробуйте украсить/отформатировать код.
// 美化назад
вар б = (функция() {
вар c = !![];
возвращаемая функция(d, e) {
вар ж = с?
функция() {
если (е) {
var g = e['apply'](d, аргументы);
е = ноль;
вернуть г;
}
}: функция() {};
с = ![];
вернуть f;
};
} ());
var a = b(это,
функция() {
return a['toString']()['search']('(((.+)+)+)+$')['toString']()['constructor'](a)['search'] ('(((.+)+)+)+$');
});
а();
консоль['журнал'](0x7b);
В это время выполнение будет остановлено и результат не будет возвращен.
проходить top
Мы обнаружили, что компьютеры CPU
Заполняемость node
Почти до места проживания Понятно 100%
Поскольку мы знаемисходный код,То есть, самая задняя линия,Поэтому он должен зависнуть по вышеуказанным причинам.,он продолжает выводить,Посмотрите, в чем проблема
финальный发сейчасдаэтот абзацкодпозволятьнашкомпьютерCPU
Заполняемость растет
return a['toString']()['search']('(((.+)+)+)+$')['toString']()['constructor'](a)['search']('(((.+)+)+)+$');
Это метод защиты, использующий регулярное сопоставление,Формат назадизнить Зависит от В换行、空格等字符出сейчас,Заставит обычное сопоставление войти в бесконечный цикл,Фактически, такого рода проблемы иногда возникают во время обычных функций.,Все называют это обычной бомбой,Подробности можно найти в《разговор в белой шляпеwebБезопасность 第二版》370
Страница
тип:Boolean
значение по умолчанию:false
⚠️ Если вы откроете инструменты разработчика, вы можете получить зависание. Этот вариант вряд ли использует инструменты разработчика из функций отладчика (независимо от того, на чем основано WebKit извозвращатьсяда Mozilla Firefox начальство).
// исходный код
console.log(123)
// После путаницы
var H = (function () {
var m = !![];
return function (I, T) {
var s = m ? function () {
if (T) {
var y = T['apply'](I, arguments);
T = null;
return y;
}
} : function () {
};
m = ![];
return s;
};
}());
(function () {
H(this, function () {
var m = new RegExp('function\x20*\x5c(\x20*\x5c)');
var I = new RegExp('\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)', 'i');
var T = a('init');
if (!m['test'](T + 'chain') || !I['test'](T + 'input')) {
T('0');
} else {
a();
}
})();
}());
console['log'](0x7b);
function a(m) {
function I(T) {
if (typeof T === 'string') {
return function (s) {
}['constructor']('while\x20(true)\x20{}')['apply']('counter');
} else {
if (('' + T / T)['length'] !== 0x1 || T % 0x14 === 0x0) {
(function () {
return !![];
}['constructor']('debu' + 'gger')['call']('action'));
} else {
(function () {
return ![];
}['constructor']('debu' + 'gger')['apply']('stateObject'));
}
}
I(++T);
}
try {
if (m) {
return I;
} else {
I(0x0);
}
} catch (T) {
}
}
анализ стека результатов можно увидеть,debug
да вызвано кодом на картинке из
Если вы смотрите код прибытия, проанализируйте его сами,Вместо того, чтобы просто смотреть на следующий контент и слова,У вас также может возникнуть вопрос: С логической точки зрения,Обычно вы должны иметь возможность передвигаться пешком.,Что ж, в изображении не рассматривалось, где приезжать, хранятся условия оценки, позволяющие определить, является ли да средой отладки?
Это верно,датакиз,Меня тоже этот вопрос беспокоит уже давно,После анализа,я发сейчас Понятноob
использоватьизтехника
Он собирается поехать сюда, и здесь I
Функция рекурсии, поэтому эти debug
код Сразуда Выполнюиз,и будет продолжать выполнять,существование Внешняя страница кажется ничем,Но как только да войдет в инструменты разработчика,застрянет
Но здесь есть другая проблема,как остановить,Если вы продолжите выполнять из,Пустая трата пользовательских ресурсов, заявили в министерстве,Это также может привести к тому, что код не сможет продолжить выполнение.
здесь я должен сказать, что во всех языках разработки есть что-то Понятное —— аномальное
Рекурсивный вызов debug
приведет к Страница面аномальный,Если исключение не перехвачено,вызовет прерывание кода,Давайте посмотрим на этот клип ниже:
try {
if (m) {
return I;
} else {
I(0x0);
}
} catch (T) {
}
Если вы посмотрите на «Понятно» выше и «Изкод», вы должны знать, что код вводится первым. return I
; Вторая запись назад I(0x0)
,этот时开始进入никто休止из debug
, но система да тупо не допустит сбоя операционной системы, поэтому это вызовет аномальное событие. Из кода видно, что при возникновении аномального события оно будет. try...catch
захватыватьприезжать,Тогда назад ничего не сделал,Продолжайте выполнять оставшийся логический код.
Как доказать это, два шага
Прежде всего, необходимо доказать, что существование не открывает консоль из,назадбашнясуществовать Нет断изосуществлятьdebug
。нас Можетсуществовать debug
Добавлено в исходник alert(1)
код, анализ найден кодоназад alert(T)
самый подходящийиз
здесь требует внимания,В качестве кода возврата назад используется выражение немедленного вызова.,такздесь Должно быть добавлено ;
, в противном случае будет сообщено об ошибке
Если браузер не открывает инструмент отладки браузера, обновите его и посмотрите эффект.
Нажмите «ОК», и надпись «Назад» будет появляться постоянно.
Это подтвердит, что первый шаг Понятно, и действительно, был выполнен назадбашнясуществовать. debug
Во-вторых, нам нужно убедиться, что неограниченное debug
приведет каномальный
Мы напрямую выводим аномальную информацию,Если вы ввели аномальныйиз,Сразу会以弹窗из формыобратная связьприезжать Страница面上
обновить страницу
аномальный信息 RangeError: Maximum call stack size exceeded
,Нажмите «ОК», чтобы продолжить выполнение.
Это второй шаг для проверки Понятнонаша, поэтому ob
и没иметьиспользовать Что高深技术,Просто дацикл,Изназадверноциклруководить Понятно Запутать
debugProtectionInterval
Тип: номер Значение по умолчанию: 0 ⚠️ Могу заморозить тебя из Браузер! использовать Используйте на свой страх и риск. При настройке используйте временные интервалы в миллисекундах из модели принудительной отладки на вкладке «Консоль», что затрудняет использование других функций инструментов разработчика. Если вы включите Понятно debugProtection, это действительно так. Предложенияценитьсуществовать 2000 приезжать 4000 между миллисекундами.
о debugger
из Атака и защита,Уже есть очень зрелые статьи, обучающие всех, как обходить,Можно обратиться к
https://cloud.tencent.com/developer/article/2176916
тип:Boolean
значение по умолчанию:false
防止Запутать require
импортировать。существовать某些случай,Когда по какой-то причине среда выполнения требует использовать только статические данные для импорта,Это может помочь.
Тип: строковый массив значение по умолчанию:[]
⚠️ этот вариант Нет适用В目标:'node'
разрешено толькосуществоватьконкретный домени/или子域上运行Запутатьизисточниккод。Кому-то это мешаеткопироватьи粘贴您изисточниккодисуществоватьзапустить его в другом месте。 Если исходный код не работает на этом варианте обозначениеиз домена, то Браузер Воля перенаправляет приезжать, пропускает приезжать. domainLockRedirectUrl
Опции из URL
。 Несколько доменов и поддоменов Вы можете заблокировать несколько доменов и поддоменов. Например, заблокировать его, чтобы существовал только код. www.example.com
Для продолжения добавьте www.example.com
。сделать этосуществоватьвключать любые поддомены(example.com、sub.example.com
)из Запуск в корневом домене,пожалуйстаиспользовать .example.com
。
// исходный код
console.log(123)
настройкиrunizдоменное имя vvvvvvv.com
// После путаницы
var b = (function () {
var c = !![];
return function (d, e) {
var f = c ? function () {
if (e) {
var g = e['apply'](d, arguments);
return e = null, g;
}
} : function () {
};
return c = ![], f;
};
}()), a = b(this, function () {
var c;
try {
var f = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
c = f();
} catch (G) {
c = window;
}
var g = new RegExp('[BXLZnQeBEYJRfanRwqdJEWKiMKnktgsV]', 'g'), h = 'vBvXvvvvvLZn.QecBEYoJRfanmRwqdJEWKiMKnktgsV'['replace'](g, '')['split'](';'), j, k, l, m, n = function (H, I, J) {
if (H['length'] != I)
return ![];
for (var K = 0x0; K < I; K++) {
for (var L = 0x0; L < J['length']; L += 0x2) {
if (K == J[L] && H['charCodeAt'](K) != J[L + 0x1])
return ![];
}
}
return !![];
}, o = function (H, I, J) {
return n(I, J, H);
}, p = function (H, I, J) {
return o(I, H, J);
}, q = function (H, I, J) {
return p(I, J, H);
};
for (var r in c) {
if (n(r, 0x8, [
0x7,
0x74,
0x5,
0x65,
0x3,
0x75,
0x0,
0x64
])) {
j = r;
break;
}
}
for (var s in c[j]) {
if (q(0x6, s, [
0x5,
0x6e,
0x0,
0x64
])) {
k = s;
break;
}
}
for (var t in c[j]) {
if (p(t, [
0x7,
0x6e,
0x0,
0x6c
], 0x8)) {
l = t;
break;
}
}
if (!('~' > k))
for (var u in c[j][l]) {
if (o([
0x7,
0x65,
0x0,
0x68
], u, 0x8)) {
m = u;
break;
}
}
if (!j || !c[j])
return;
var v = c[j][k], w = !!c[j][l] && c[j][l][m], x = v || w;
if (!x)
return;
var y = ![];
for (var z = 0x0; z < h['length']; z++) {
var k = h[z], A = k[0x0] === String['fromCharCode'](0x2e) ? k['slice'](0x1) : k, B = x['length'] - A['length'], C = x['indexOf'](A, B), D = C !== -0x1 && C === B;
D && ((x['length'] == k['length'] || k['indexOf']('.') === 0x0) && (y = !![]));
}
if (!y) {
var E = new RegExp('[yRfrmZJUPqRCIfxNmCiQpmppBKF]', 'g'), F = 'aybRfourtm:ZJUbPlanqkRCIfxNmCiQpmppBKF'['replace'](E, '');
c[j][l] = F;
}
});
a(), console['log'](0x7b);
Это не должно быть слишком сложно,здесь Волянаш域имя混入Понятнонитьсередина,Затем индекс назадсуществоватьпрохождения отфильтровывается.,Изназадисредапеременнаяидтиверно Сравнивать,Просто выполните то же самое,Если другое, прыгайте
Перейдите по URL-адресу в предыдущей статье.
тип:Boolean
значение по умолчанию:false
давать возможность Запутатькодизисточник映射генерировать。 Карты исходных кодов помогают устранять обфускации JavaScript источниккод。если ты хочешьилинуждатьсясуществовать生产серединаруководить调试,Вы можете Воля отделить исходные файлы карты и загрузить приехать в секретную локацию.,Тогда назад Воля Браузер указывает туда.
Это не имеет прямого отношения к технологии обфускации. В основном это зависит от требований отладки.
Следующие несколько из них связаны с изменениями персонажей, в основном с различными изменениями.
тип:Boolean
значение по умолчанию:true
удалитьнитьхарактери Воляони ставят специальныемножествосередина。Например,var m = "Hello World"
; внить“Hello World”
Воляодеяло替换для var m = _0x12c456[0x1];
существовало до того, как мы увидели этот вид. Понятно, что персонаж Воля становится множеством индексов для получения ценить.
тип:Boolean
значение по умолчанию:true
⚠️ stringArray
Должно быть включено Воля stringArray
множество мобильных фиксированных и случайных (существоватькод, генерируемый при путанице) позиций. Из-за этого удаленному заказу на изнесение Воля становится сложнее соответствовать исходному положению.
Проще говоря, выбор да из ценитьиз должен быть более случайным.
тип:Boolean
значение по умолчанию:true
⚠️ stringArray
Должно быть включено перетасовать в случайном порядке stringArray
Элементы массива.
Тип: номер Значение по умолчанию: 0.8 Минимальное значение: 0 Максимальное значение: 1 ⚠️ stringArray
Параметры Должно быть включено Вы можете использовать эту настройку, чтобы настроить вставку текста Волянить. stringArray
из вероятности (от 0 приезжать 1)。 этотнастраиватьверно В大формакод特别иметь用,因для它会重复вызовнитьмножествои会减медленныйкодскорость。stringArrayThreshold: 0
равный stringArray: false
。
Элементы конфигурации на официальном сайте по умолчанию да. 0.75 , не да 0.8
тип:Boolean
значение по умолчанию:true
⚠️ stringArray
Параметры Должно быть включено Включить дополнительное смещение индекса для всех нит множествовызов
Тип: строковый массив значение по умолчанию:['hexadecimal-number']
⚠️ stringArray
Параметры Должно быть включено Позволяет управлять индексом нитьмножествовызов по типу. каждый stringArray
Индексы вызовов преобразуются по случайно выбранному типу из переданного списка. Это делает возможными многие виды использования. Доступные значения:
'hexadecimal-number'
(по умолчанию):Волянитьмножествовызов索引Конвертироватьдля十六进制число'hexadecimal-numeric-string'
:Волянитьмножествовызов索引Конвертироватьдля十六进制числонитьсуществовать 2.9.0 版本Из前,
javascript-obfuscator
Воля Все индексы нитмножествовызов преобразуются в шестнадцатеричный тип нит. Это немного усложняет ручную деобфускацию, но позволяет автоматическим деобфускаторам легко их обнаружить. Новый тип шестнадцатеричных чисел усложняет автоматическое обнаружение кода в нить множествовызовмодели. В будущем Воля добавит больше типов.
тип:Boolean
значение по умолчанию:false
⚠️ stringArray
Параметры Должно быть включено давать возможностьверно stringArray
извызовиз конверсии. в соответствии с stringArrayCallsTransformThreshold
ценить,Эти параметры вызова могут извлекать различные изверно слоны. поэтому,Автоматически становится сложнее найти верность множествоизвызов.
stringArrayCallsTransformThreshold
Тип: номер Значение по умолчанию: 0.5 ⚠️ stringArray
и stringArrayCallsTransformThreshold
Параметры Должно быть включено ты можешьиспользоватьэтотнастраиватькорректироватьвернонитьмножествоизвызоводеяло Конвертироватьиз вероятности (от 0 приезжать 1)。
// исходный код
function hi() {
console.log("Hello World!");
}
hi();
// Проверить этот товар путаницы
function hi() {
var c = {
d: 0x0,
e: 0x1
};
console[b(c.d)](b(c.e));
}
function b(c, d) {
var e = a();
b = function (f, g) {
f = f - 0x0;
var h = e[f];
return h;
};
return b(c, d);
}
hi();
function a() {
var d = [
'log',
'Hello\x20World!'
];
a = function () {
return d;
};
return a();
}
// еще нет Проверить этот товар путаницы
function hi() {
console[b(0x0)](b(0x1));
}
function b(c, d) {
var e = a();
b = function (f, g) {
f = f - 0x0;
var h = e[f];
return h;
};
return b(c, d);
}
function a() {
var c = [
'log',
'Hello\x20World!'
];
a = function () {
return c;
};
return a();
}
hi();
Вы можете увидеть проверку прибытия назад и появиться Понятно несколько похожих. c.d、c.e
Этот видвызов путь
Тип: номер Значение по умолчанию: 1 ⚠️ stringArray
Параметры Должно быть включено область настройки корневого корня или функции нить множества оберток. Фактическое количество оберток в диапазоне каждый ограничено количеством литеральных узлов в диапазоне.
Я также поискал некоторую информацию, чтобы понять этот вариант.,ob
Ручка проектанитьжить储существоватьмножествовнутри,Вопрос о том, чтобы снова взять цену, уже обсуждался ранее.,здесьиз обертки,Просто обратитесь к дафункции,Эта функция отвечает за получение цен из множества по индексу.,具体нравиться何包装Сразу看 ob
Понятно, этот элемент конфигурации сообщает вам, сколько Этих будет в настройке. видфункция, а не сколько используется для хранения измножество га
Тип: строка значение по умолчанию:variable
⚠️ stringArray
и stringArrayWrappersCount
Параметры Должно быть включено Разрешить выбор по stringArrayWrappersCount
Опции прилагаются из типа обертки. Доступные значения:
'variable'
:существоватькаждый Объемиз Верхнее креплениепеременнаяобертка。Высокая производительность。'function'
:существоватькаждый Объем内из Добавление случайного местоположения Функциональная оболочка。性能Сравниватьпеременнаямедленный,Но обеспечивает более строгую запутывание.Когда потеря производительности действительно запутывает приложение, оно мало влияет,Настоятельно рекомендуетсяиспользовать Функциональная оболочкаруководить更高程度из Запутать。
тип обертки с изображением,Я выше сказал, что обертка - это просто дафункция,Из официальной конфигурации,Только один тип,Также дапеременная обертка,Но официального случая Давать переменную обертку не существует.,官网возвращатьсядабрать Функциональная оболочка Примериз
Тогда давайте попрактикуемся сами
// исходный код
const foo = 'foo';
function test () {
const bar = 'bar';
console.log(foo, bar);
}
test();
// Живописные снежинки
константа d = б;
функция а() {
константа е = [
'фу',
'бар',
'бревно'
];
а = функция() {
вернуть f;
};
вернуть ( ) ;
} }
const foo = d(0x0);
функция б(с, d) {
константа е = а();
б = функция (f, g) {
е = е -- 0x0;
пусть h = e[f];
вернуть ч;
};
вернуть б (в, г);
} }
функция тест() {
константа е = б;
константа с = е (0x1);
консоль [e (0x2)] (foo, c);
} }
тест ( ) ;
// После путаницы Функциональная оболочка
function b(c, d) {
const e = a();
b = function (f, g) {
f = f - 0x0;
let h = e[f];
return h;
};
return b(c, d);
}
const foo = 'foo';
function test() {
const c = d(0xe4, 0xe5);
function d(c, e) {
return b(e - 0xe5, c);
}
console[d(0xe5, 0xe6)](foo, c);
}
function a() {
const f = [
'bar',
'log'
];
a = function () {
return f;
};
return a();
}
test();
По сравнению с проведением, основные отличия изкода заключаются в следующем:
// переменнаяобертка
function test() {
const e = b;
const c = e(0x1);
console[e(0x2)](foo, c);
}
// Функциональная оболочка
function test() {
const c = d(0xe4, 0xe5);
function d(c, e) {
return b(e - 0xe5, c);
}
console[d(0xe5, 0xe6)](foo, c);
}
Я не думаю, что это имеет какой-либо смысл
Тип: номер Значение по умолчанию: 2 ⚠️ stringArray
Параметры Должно быть включено ⚠️ В настоящее время эта опция влияет только stringArrayWrappersType
Опция функцииценить добавить из оболочки Позволяет контролировать максимальное количество множество оберток параметров. Минимальная цена по умолчанию составляет 2. Рекомендуемое значение находится между 2 и 5 между.
этотда Функциональная оболочка才иметьиз
тип:Boolean
значение по умолчанию:true
⚠️ stringArray
и stringArrayWrappersCount
Параметры Должно быть включено Включает цепочку между обертками нитмножество.
Тип: строковый массив значение по умолчанию:[]
⚠️ stringArray Параметры Должно быть включено Эта опция может замедлить работу вашего скрипта. использовать base64 или rc4 верно stringArray Из всего текста есть кодирование, вставленное в существующую среду выполнения, которая декодируется из специального кода. каждый stringArray ценить Воляпроходить случайным образом выбрать изкодирование из списка доставки для кодирования. Это делает возможным использование разнообразного кодирования. Доступные значения:
'none'
(логическое значениеценить):Неткодирование stringArray ценить'base64'
(нить):использовать base64 кодирование stringArray ценить'rc4'
(нить):использовать rc4 верно stringArray ценитьруководитькодирование。Сравнивать base64 Назначайте встречу медленно 30-50%, но получить первоначальную цену сложнее. Предложения rc4 Отключено при кодировании unicodeEscapeSequence Параметр предотвращения путаницы. Код слишком велик.Это должен быть даверно магазин изнить кодирование магазина
тип:Boolean
значение по умолчанию:false
Воляхарактернить拆分для长度для splitStringsChunkLength
Опции ценитьиз блока.
Тип: номер Значение по умолчанию: 10 настраивать splitStrings
Опции издлина блока。
тип:Boolean
значение по умолчанию:false
позволятьдавать возможность/Запрещатьнить Конвертироватьдля unicode последовательность выхода. Unicode Escape-последовательности значительно увеличивают размер Понятнокода, и нить может легко восстановить исходный вид. Рекомендуется включать это только для небольших источников.
Я это уже видел, в этом нет ничего нового.
Тип: строковый массив значение по умолчанию:[]
давать возможностьнитьхарактеризбросать,Долженнитьхарактерипередачаиз RegExp
совпадения шаблонов. ⚠️ Эта опция влияет только на stringArrayThreshold
(или Воля может из другого порогаценить) Конверсия изнить Должен Параметры优Первый ВreservedStrings
Параметры,Но не имеет приоритета над условными комментариями.
Если такие есть, обязательно запутайте изнинить,Можно добавить в жильё множество,Принудительное преобразование
Тип: строковый массив значение по умолчанию:[]
Запрещатьнитьхарактериз Конвертировать,Долженнитьхарактерипередачаиз RegExp
совпадения шаблонов.
Обязательно сохраните изнить, можно поместить в существующее множество
Далее введите часть имени идентификатора Понятно, которая также является именем дапеременной и так далее.
Тип: строка значение по умолчанию:hexadecimal
настраивать标识符имя称генерировать器。 Доступные значения:
dictionary
из списка идентификаторов Список словарей из имени идентификатораhexadecimal
картина Имена идентификаторов, такие как _0xabc123,manged
:短标识符имя称,нравиться a、b、c
mangled-shuffled
:и mangled
То же самое, но алфавитный порядок нарушен.Это очень важно,В какой форме генерируются эти переменные имена?,Предыдущий из Демонстрация как понятно просто,Все选择из manged
Тип: строковый массив значение по умолчанию:[]
дляidentifierNamesGenerator
настраиватьсловарь идентификаторов:dictionary
。dictionary
вкаждый标识符Все Воля用В几индивидуальный变体середина,Символы каждый и из имеют разный регистр. поэтому,dictionary
середина标识符из数量отвечать Должен取决В原始источниккодвколичество идентификаторов。
Если у вас есть словарь (множество символов),Там куча персонажей,Таким образом вы можете обозначииеиспользовать этот словарь для замены тех идентификаторов, которые подлежат замене.
Тип: строка значение по умолчанию:''
настраивать所иметьобщая идентификатор ситуации из префикса. 当您想хотеть Запутать多индивидуальныйдокумент时,пожалуйстаиспользоватьэтотпараметры.этот вариантиметь助В避免这些документизобщая ситуация标识符Из间изконфликт。каждыйдокументиз前缀отвечать Должен Нет同。
тип:Boolean
значение по умолчанию:false
⚠️этот Параметры可能会破坏你изкод。仅当您Знать它из作用时才давать возможность它! давать возможностьобщая ситуацияпеременнаяифункцияимя称и声明из Запутать。
тип:Boolean
значение по умолчанию:false
⚠️этот вариант可能会破坏您изкод。仅当您Знать它из作用时才давать возможность它! Включает переименование имени атрибута. Все встроенное DOM Свойства и ядро JavaScript Атрибуты класса В игнорируются.
renamePropertiesMode
параметры.identifierNamesGenerator
параметры.reservedNames
параметры.Тип: строка значение по умолчанию: safe
⚠️ Несмотря на тосуществоватьsafe
модель Вниз,renameProperties
Опции также могут испортить вам исходник. обозначение renameProperties
Режим опций:
safe
2.11.0 Отпустите назадиз поведения по умолчанию. Попробуйте переименовать свойства более безопасным способом, чтобы предотвратить ошибки во время выполнения. При использовании этой модели некоторые атрибуты Воля исключены из существующего переименования.unsafe
2.11.0 Поведение по умолчанию до версий. Переименовывайте свойства небезопасным способом, без каких-либо ограничений.Если один файл имеет тот же атрибут «из существования», что и другой файл, используйте опцию «использовать_идентификаторы_кэша», чтобы сохранить одинаковое имя атрибута «из» между этими файлами.
Тип: строковый массив значение по умолчанию:[]
Запрещать标识符из Запутатьигенерировать,这些标识符ипередачаиз RegExp
совпадения шаблонов.
тип:Boolean
значение по умолчанию:true
компактныйизкодвыходсуществоватьна одной линии。
Просто сжимаем код в одну строку
тип:Boolean
значение по умолчанию:true
проходить简化давать возможность额外изкод Запутать。 ⚠️ существуетFuture из версии, логический литерал запутан (true => !![]
) Воля перешёл по этому варианту.
Этот вариант упрощен,Измените некоторую легко читаемую логику исходного кодирования на троичные операторы и т. д.,Есть некоторые детали,Вы можете изучить это.
тип:Boolean
значение по умолчанию:false
давать возможностьвернослон键из Конвертировать。
// исходный код
var object = {
foo: 'test1',
bar: {
baz: 'test2'
}
};
// После путаницы
var a = {};
a['baz'] = 'test2';
var b = {};
b['foo'] = 'test1';
b['bar'] = a;
var object = b;
Похоже, что преобразование ключа верверно в из не очень очевидно и не дает официального эффекта приезжать.
Возможно, да придется открыть другие опции, а не только настройки "шестнадцатеричной модели"
тип:Boolean
значение по умолчанию:false
Разрешить преобразование чисел в выражения
// исходный код
var demo1 = 23;
var demo2 = 24;
var result = demo1 + demo2;
// После путаницы
var demo1 = 0x29d * -0x2 + -0x22f7 + -0x2 * -0x1424;
var demo2 = -0x17b8 * 0x1 + -0x1933 * 0x1 + 0x3103;
var result = demo1 + demo2;
Сначала я отметил не тот вариант Понятно,Я все еще думаю, что это немного просто,сейчассуществовать Может Понятно
тип:Boolean
значение по умолчанию:false
⚠️ Эта опция сильно влияет на производительность, работая максимально медленно, 1.5 раз。использовать controlFlowFlatteningThreshold
настройки Процент узлов, на которые влияет выравнивание потока управления. Включает выравнивание потока управления. Сглаживание потока управления — это преобразование, которое не позволяет программе понять исходную структуру.
окодвыравнивание потока управления Можно обратиться кнекоторые статьи
https://www.cnblogs.com/ichunqiu/p/7383045.html
Посмотри на этоиндивидуальный扁平化,Я всегда могу вспомнить строчку из «Китайского партнера»: «Мать двадцать лет потратила на то, чтобы вырастить его.,А другой женщине понадобилось всего двадцать минут, чтобы снова превратить его в Понимаемого дурака.
Тип: номер Значение по умолчанию: 0.75 Минимальное значение: 0 Максимальное значение: 1controlFlowFlattening
Преобразование Воля применяется к любому заданному узлу вероятности. этотнастраиватьверно В大формакод特别иметь用,因для大量控制流Конвертировать会减медленныйкодскоростьи增加кодразмер。controlFlowFlatteningThreshold: 0
равный controlFlowFlattening: false
。
тип:Boolean
значение по умолчанию:false
⚠️ Значительно увеличена путаница в размере кода (до 200%), только если путаница в размере кодирования не важна. использовать deadCodeInjectionThreshold настройки Процент узлов, затронутых внедрением мертвого кода. ⚠️ Эта опция должна быть включена принудительно stringArray параметры. использовать С помощью этой опции добавляются случайные блоки мертвого кода Воля.
Код смерти тоже раздражает
// исходный код
console.log(1)
// После путаницы
var _0x54c615 = _0x4d77;
(function (_0x2f01cd, _0x282040) {
var _0xfd38d6 = _0x4d77;
var _0x418071 = _0x2f01cd();
while (!![]) {
try {
var _0x5384d1 = parseInt(_0xfd38d6(0x1ed)) / 0x1 + -parseInt(_0xfd38d6(0x1f2)) / 0x2 + -parseInt(_0xfd38d6(0x1eb)) / 0x3 + -parseInt(_0xfd38d6(0x1e9)) / 0x4 * (-parseInt(_0xfd38d6(0x1f1)) / 0x5) + -parseInt(_0xfd38d6(0x1ec)) / 0x6 * (parseInt(_0xfd38d6(0x1f0)) / 0x7) + parseInt(_0xfd38d6(0x1ef)) / 0x8 + parseInt(_0xfd38d6(0x1ea)) / 0x9;
if (_0x5384d1 === _0x282040) {
break;
} else {
_0x418071['push'](_0x418071['shift']());
}
} catch (_0x99f199) {
_0x418071['push'](_0x418071['shift']());
}
}
}(_0x2499, 0x8b99e));
function _0x4d77(_0x53739e, _0x427c10) {
var _0x249929 = _0x2499();
_0x4d77 = function (_0x4d7790, _0x3cb070) {
_0x4d7790 = _0x4d7790 - 0x1e9;
var _0x4fc869 = _0x249929[_0x4d7790];
return _0x4fc869;
};
return _0x4d77(_0x53739e, _0x427c10);
}
console[_0x54c615(0x1ee)](0x1);
function _0x2499() {
var _0x3c0042 = [
'4uTkwuQ',
'8809173qEYNab',
'1628760aaOeDK',
'84qlULXN',
'99299HMwqSP',
'log',
'4523368ohaBbo',
'437311NMYccT',
'1998515lIAtLG',
'107744EAbXbU'
];
_0x2499 = function () {
return _0x3c0042;
};
return _0x2499();
}
Тип: номер Значение по умолчанию: 0.4 Минимальное значение: 0 Максимальное значение: 1 позволятьнастраивать受 deadCodeInjection 影响из节点百分Сравнивать。
Если вы подпишетесь на меня и посмотрите Понятное дело целиком. ob
из Запутать方式,поздравления,По сути, уже верно, что путаница означает, что существует Понятное Понятное решение.,ob
даиндивидуальный优秀изпроект,Если у проекта есть способ оценить,Вся признательность за эту статью будет удвоена за передачу этого проекта.
Дальше контент будет намного проще Понятно,Интересно, но не депрессивно,Кажется, я только что вышел ob
из你尤其нуждаться它,если не нужно,Вы также можете пропустить
https://utf-8.jp/public/jjencode.html
Поверьте, судя по названию,ты уже знаешь,Это метод кодирования, позволяющий добиться путаницы из,Но я не думаю, что это может выглядеть странно.
// исходный код
console.log("Hello, JavaScript")
// кодированиеназад
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$$__+$._$+"\\"+$.__$+$.$_$+$.$$_+"\\"+$.__$+$.$$_+$._$$+$._$+(![]+"")[$._$_]+$.$$$_+"."+(![]+"")[$._$_]+$._$+"\\"+$.__$+$.$__+$.$$$+"(\\\"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+",\\"+$.$__+$.___+"\\"+$.__$+$.__$+$._$_+$.$_$_+"\\"+$.__$+$.$$_+$.$$_+$.$_$_+"\\"+$.__$+$._$_+$._$$+$.$$__+"\\"+$.__$+$.$$_+$._$_+"\\"+$.__$+$.$_$+$.__$+"\\"+$.__$+$.$$_+$.___+$.__+"\\\")"+"\"")())();
Принцип на самом деле не сложный,Но если он создан людьми, это должно быть весьма интересно.,Если вы хотите узнать больше о том, как проектировать Понятно,Можно обратиться к以Вниз文章
https://yuanbug.github.io/2019/08/14/2019/my-js-obfuscation-encode/
Метод расшифровки этого вида также очень прост. Существует множество существующих платформ, которые могут обеспечить расшифровку.
http://www.hiencode.com/jjencode.html
https://utf-8.jp/public/aaencode.html
// исходный код
console.log("Hello, JavaScript")
// После путаницы
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
декодировать веб-сайт
http://www.metools.info/code/aaencode214.html
https://jsfuck.com/
// исходный код
console.log(1)
// После путаницы
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()(([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[+[]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])
обфускация кода да защита кода и предотвращение обратного проектирования изоптимизации,Но я не чувствую себя окончательным решением,Я считаю, что обфускация кода будет продолжать играть важную роль в окончательном решении проблемы существования.
Спасибо за создание инструмента для обфускации кода.、Методы и способы борьбы с людьми, добивающимися расшифровки