obfuscator混淆过的代码,反混淆后有很多伪代码,有些规则不太好找,会导致伪代码无法删除。
obfuscator 解密工具地址dejs
现将伪代码模板整理如下:如有清理不彻底的情况,可手动删除。
这些代码也就是让反混淆的人在控制台查看的时候,进入死循环一直无法执行下去的控制逻辑。
(function () {
{globalVariableTemplate}
that.setInterval({debugProtectionFunctionName}, {debugProtectionInterval});
})();
(function () {
{callControllerFunctionName}(
this,
function () {
const regExp1 = new RegExp('function *\\( *\\)');
const regExp2 = new RegExp('\\+\\+ *\(?:[a-zA-Z_$][0-9a-zA-Z_$]*\)', 'i');
const result = {debugProtectionFunctionName}('init');
if (!regExp1.test(result + 'chain') || !regExp2.test(result + 'input')) {
result('0');
} else {
{debugProtectionFunctionName}();
}
}
)();
})();
if (typeof counter === 'string') {
return (function (arg) {}.constructor('while (true) {}').apply('counter'));
} else {
if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
(function () {return true;}.constructor('debu' + 'gger').call('action'));
} else {
(function () {return false;}.constructor('debu' + 'gger').apply('stateObject'));
}
}
if (typeof counter === 'string') {
const func = function () {
while (true) {}
};
return func();
} else {
if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
debugger;
} else {
debugger;
}
}
function {debugProtectionFunctionName} (ret) {
function debuggerProtection (counter) {
{debuggerTemplate}
debuggerProtection(++counter);
}
try {
if (ret) {
return debuggerProtection;
} else {
debuggerProtection(0);
}
} catch (y) {}
}
这个模板的伪代码在混淆代码中有大量的使用。这个伪代码在多种类型表达式中有使用,目前工具尚无法完美的删除这些伪代码。后面时间富裕的话,会将该代码进行删除。
const {callControllerFunctionName} = (function(){
let firstCall = true;
return function (context, fn){
const rfn = firstCall ? function(){
if(fn){
const res = fn.apply(context, arguments);
fn = null;
return res;
}
} : function(){}
firstCall = false;
return rfn;
}
})()
let that;
try {
const getGlobal = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
that = getGlobal();
} catch (e) {
that = window;
}
const getGlobal = function () {
let globalObject;
try {
globalObject = Function('return (function() ' + '{}.constructor("return this")( )' + ');')();
} catch (e) {
globalObject = window;
}
return globalObject;
};
const that = getGlobal();
const {consoleLogDisableFunctionName} = {callControllerFunctionName}(this, function () {
{globalVariableTemplate}
const consoleObject = (that.console = that.console || {});
const methods = ['log', 'warn', 'info', 'error', 'exception', 'table', 'trace'];
for (let index = 0; index < methods.length; index++){
const func = {callControllerFunctionName}.constructor.prototype.bind({callControllerFunctionName});
const methodName = methods[index];
const originalFunction = consoleObject[methodName] || func;
func.__proto__ = {callControllerFunctionName}.bind({callControllerFunctionName});
func.toString = originalFunction.toString.bind(originalFunction);
consoleObject[methodName] = func;
}
});
{consoleLogDisableFunctionName}();
const {domainLockFunctionName} = {callControllerFunctionName}(this, function () {
{globalVariableTemplate}
const regExp = new RegExp("[{domainsStringDiff}]", "g");
const domains = "{domains}".replace(regExp, "").split(";");
let document;
let domain;
let location;
let hostname;
const isName = function(name, length, cs) {
if (name.length != length) {
return false;
}
for (let i = 0; i < length; i++) {
for (let j = 0; j < cs.length; j += 2) {
if (i == cs[j] && name.charCodeAt(i) != cs[j+1]) {
return false;
}
}
}
return true;
};
const isNameVariant1 = function(cs, name, length) {
return isName(name, length, cs);
};
const isNameVariant2 = function(name, cs, length) {
return isNameVariant1(cs, name, length);
};
const isNameVariant3 = function(length, name, cs) {
return isNameVariant2(name, cs, length);
};
for (let d in that) {
if (isName(d, 8, [7, 116, 5, 101, 3, 117, 0, 100])) {
document = d;
break;
}
}
for (let d1 in that[document]) {
if (isNameVariant3(6, d1, [5, 110, 0, 100])) {
domain = d1;
break;
}
}
for (let d2 in that[document]) {
if (isNameVariant2(d2, [7, 110, 0, 108], 8)) {
location = d2;
break;
}
}
if (!("~" > domain)) {
for (let d3 in that[document][location]) {
if (isNameVariant1([7, 101, 0, 104], d3, 8)) {
hostname = d3;
break;
}
}
}
if (!document || !that[document]) {
return;
}
const documentDomain = that[document][domain];
const documentLocationHostName = !!that[document][location] && that[document][location][hostname];
const currentDomain = documentDomain || documentLocationHostName;
if (!currentDomain) {
return;
}
let ok = false;
for (let i = 0; i < domains.length; i++) {
const domain = domains[i];
const domainNormalized = domain[0] === String.fromCharCode(46)
? domain.slice(1)
: domain;
const position = currentDomain.length - domainNormalized.length;
const lastIndex = currentDomain.indexOf(domainNormalized, position);
const endsWith = lastIndex !== -1 && lastIndex === position;
if (endsWith) {
if (currentDomain.length == domain.length || domain.indexOf(".") === 0) {
ok = true;
}
}
}
if (!ok) {
const regExp2 = new RegExp("[{domainLockRedirectUrlDiff}]", "g");
const domainLockRedirectUrl = "{hiddenDomainLockRedirectUrl}".replace(regExp2, "");
that[document][location] = domainLockRedirectUrl;
}
});
{domainLockFunctionName}();
const {selfDefendingFunctionName} = {callControllerFunctionName}(this, function () {
return {selfDefendingFunctionName}
.toString()
.search('(((.+)+)+)+$')
.toString()
.constructor({selfDefendingFunctionName})
.search('(((.+)+)+)+$');
});
{selfDefendingFunctionName}();