在我学习JavaScript的过程中,我今天遇到了一个脚本中的这个奇怪的代码,我试图阅读它的代码和理解。
var j =["\\1A\\W\\1g","\\X\\S\\1p\\M","\\I\\G\\x\\H\\x\\H\\V\\I\\M","\\s\\W\\L\\1o\\z","\\W\\z\\W\\H","\\1v\\S\\1p\\1B\\T\\z\\1C\\G\\x\\I\\M\\G\\H\\V"];
我试着像这样控制记录j变量的值。
console.log(j[1] + '' + j[2] + '' + j[3] + '' + j[4] + '' + j[5] + '' + j[6]);
但不幸的是,控制台给了我一个错误,这是"未定义"。那么有没有人可以帮我弄清楚如何阅读这段代码。
答案 0 :(得分:1)
正如其他人在评论中提到的,这是JavaScript混淆。从它的外观来看,它试图从页面读取值(通过jQuery)。这是一个快速细分:
在您与脚本关联的小提琴中,您会发现在minified
或packed
代码上调用了eval。它有两个部分 - 执行的脚本和传递的参数。当你对脚本进行美化时,它看起来像这样:
function(d, e, a, c, b, f) {
b = function(a) {
return (a < e ? "" : b(parseInt(a / e))) + (35 < (a %= e) ? String.fromCharCode(a + 29) : a.toString(36))
};
if (!"".replace(/^/, String)) {
for (; a--;) f[b(a)] = c[a] || b(a);
c = [function(a) {
return f[a]
}];
b = function() {
return "\\w+"
};
a = 1
}
for (; a--;) c[a] && (d = d.replace(new RegExp("\\b" + b(a) + "\\b", "g"), c[a]));
return d
}
返回长代码串(分配给变量J),然后进行评估。这将返回另一个值数组(found here)加密函数和其他自执行函数。这就是加密函数的样子:
var CryptoJS = CryptoJS || function(e, f) {
var g = {},
_0xda47x5 = g[_0x52e0[0]] = {},
_0xda47x6 = function() {},
_0xda47x7 = _0xda47x5[_0x52e0[1]] = {
extend: function(a) {
_0xda47x6[_0x52e0[2]] = this;
var b = new _0xda47x6;
a && b[_0x52e0[3]](a);
b[_0x52e0[5]](_0x52e0[4]) || (b[_0x52e0[4]] = function() {
b[_0x52e0[7]][_0x52e0[4]][_0x52e0[6]](this, arguments)
});
b[_0x52e0[4]][_0x52e0[2]] = b;
b[_0x52e0[7]] = this;
return b
},
create: function() {
var a = this[_0x52e0[8]]();
a[_0x52e0[4]][_0x52e0[6]](a, arguments);
return a
},
init: function() {},
mixIn: function(a) {
for (var b in a) {
a[_0x52e0[5]](b) && (this[b] = a[b])
};
a[_0x52e0[5]](_0x52e0[9]) && (this[_0x52e0[9]] = a[_0x52e0[9]])
},
clone: function() {
return this[_0x52e0[4]][_0x52e0[2]][_0x52e0[8]](this)
}
},
_0xda47x8 = _0xda47x5[_0x52e0[10]] = _0xda47x7[_0x52e0[8]]({
init: function(a, b) {
a = this[_0x52e0[11]] = a || [];
this[_0x52e0[12]] = b != f ? b : 4 * a[_0x52e0[13]]
},
toString: function(a) {
return (a || _0xda47xa)[_0x52e0[14]](this)
},
concat: function(a) {
var b = this[_0x52e0[11]],
_0xda47x10 = a[_0x52e0[11]],
_0xda47x11 = this[_0x52e0[12]];
a = a[_0x52e0[12]];
this[_0x52e0[15]]();
if (_0xda47x11 % 4) {
for (var c = 0; c < a; c++) {
b[_0xda47x11 + c >>> 2] |= (_0xda47x10[c >>> 2] >>> 24 - 8 * (c % 4) & 255) << 24 - 8 * ((_0xda47x11 + c) % 4)
}
} else {
if (65535 < _0xda47x10[_0x52e0[13]]) {
for (c = 0; c < a; c += 4) {
b[_0xda47x11 + c >>> 2] = _0xda47x10[c >>> 2]
}
} else {
b[_0x52e0[16]][_0x52e0[6]](b, _0xda47x10)
}
};
this[_0x52e0[12]] += a;
return this
},
clamp: function() {
var a = this[_0x52e0[11]],
_0xda47xf = this[_0x52e0[12]];
a[_0xda47xf >>> 2] &= 4294967295 << 32 - 8 * (_0xda47xf % 4);
a[_0x52e0[13]] = e[_0x52e0[17]](_0xda47xf / 4)
},
clone: function() {
var a = _0xda47x7[_0x52e0[19]][_0x52e0[18]](this);
a[_0x52e0[11]] = this[_0x52e0[11]][_0x52e0[20]](0);
return a
},
random: function(a) {
for (var b = [], _0xda47x10 = 0; _0xda47x10 < a; _0xda47x10 += 4) {
b[_0x52e0[16]](4294967296 * e[_0x52e0[21]]() | 0)
};
return new _0xda47x8[_0x52e0[4]](b, a)
}
}),
_0xda47x9 = g[_0x52e0[22]] = {},
_0xda47xa = _0xda47x9[_0x52e0[23]] = {
stringify: function(a) {
var b = a[_0x52e0[11]];
a = a[_0x52e0[12]];
for (var c = [], _0xda47x11 = 0; _0xda47x11 < a; _0xda47x11++) {
var d = b[_0xda47x11 >>> 2] >>> 24 - 8 * (_0xda47x11 % 4) & 255;
c[_0x52e0[16]]((d >>> 4).toString(16));
c[_0x52e0[16]]((d & 15).toString(16))
};
return c[_0x52e0[25]](_0x52e0[24])
},
parse: function(a) {
for (var b = a[_0x52e0[13]], _0xda47x10 = [], _0xda47x11 = 0; _0xda47x11 < b; _0xda47x11 += 2) {
_0xda47x10[_0xda47x11 >>> 3] |= parseInt(a[_0x52e0[26]](_0xda47x11, 2), 16) << 24 - 4 * (_0xda47x11 % 8)
};
return new _0xda47x8[_0x52e0[4]](_0xda47x10, b / 2)
}
},
_0xda47xb = _0xda47x9[_0x52e0[27]] = {
stringify: function(a) {
var b = a[_0x52e0[11]];
a = a[_0x52e0[12]];
for (var c = [], _0xda47x11 = 0; _0xda47x11 < a; _0xda47x11++) {
c[_0x52e0[16]](String[_0x52e0[28]](b[_0xda47x11 >>> 2] >>> 24 - 8 * (_0xda47x11 % 4) & 255))
};
return c[_0x52e0[25]](_0x52e0[24])
},
parse: function(a) {
for (var b = a[_0x52e0[13]], _0xda47x10 = [], _0xda47x11 = 0; _0xda47x11 < b; _0xda47x11++) {
_0xda47x10[_0xda47x11 >>> 2] |= (a[_0x52e0[29]](_0xda47x11) & 255) << 24 - 8 * (_0xda47x11 % 4)
};
return new _0xda47x8[_0x52e0[4]](_0xda47x10, b)
}
},
_0xda47xc = _0xda47x9[_0x52e0[30]] = {
stringify: function(a) {
try {
return decodeURIComponent(escape(_0xda47xb[_0x52e0[14]](a)))
} catch (c) {
throw Error(_0x52e0[31]);
}
},
parse: function(a) {
return _0xda47xb[_0x52e0[32]](unescape(encodeURIComponent(a)))
}
},
_0xda47xd = _0xda47x5[_0x52e0[33]] = _0xda47x7[_0x52e0[8]]({
reset: function() {
this[_0x52e0[34]] = new _0xda47x8[_0x52e0[4]];
this[_0x52e0[35]] = 0
},
_append: function(a) {
_0x52e0[36] == typeof a && (a = _0xda47xc[_0x52e0[32]](a));
this[_0x52e0[34]][_0x52e0[37]](a);
this[_0x52e0[35]] += a[_0x52e0[12]]
},
_process: function(a) {
var b = this[_0x52e0[34]],
_0xda47x10 = b[_0x52e0[11]],
_0xda47x11 = b[_0x52e0[12]],
_0xda47x12 = this[_0x52e0[38]],
_0xda47xb = _0xda47x11 / (4 * _0xda47x12),
_0xda47xb = a ? e[_0x52e0[17]](_0xda47xb) : e[_0x52e0[40]]((_0xda47xb | 0) - this[_0x52e0[39]], 0);
a = _0xda47xb * _0xda47x12;
_0xda47x11 = e[_0x52e0[41]](4 * a, _0xda47x11);
if (a) {
for (var c = 0; c < a; c += _0xda47x12) {
this._doProcessBlock(_0xda47x10, c)
};
c = _0xda47x10[_0x52e0[42]](0, a);
b[_0x52e0[12]] -= _0xda47x11
};
return new _0xda47x8[_0x52e0[4]](c, _0xda47x11)
},
clone: function() {
var a = _0xda47x7[_0x52e0[19]][_0x52e0[18]](this);
a[_0x52e0[34]] = this[_0x52e0[34]][_0x52e0[19]]();
return a
},
_minBufferSize: 0
});
_0xda47x5[_0x52e0[43]] = _0xda47xd[_0x52e0[8]]({
cfg: _0xda47x7[_0x52e0[8]](),
init: function(a) {
this[_0x52e0[44]] = this[_0x52e0[44]][_0x52e0[8]](a);
this[_0x52e0[45]]()
},
reset: function() {
_0xda47xd[_0x52e0[45]][_0x52e0[18]](this);
this._doReset()
},
update: function(a) {
this._append(a);
this._process();
return this
},
finalize: function(a) {
a && this._append(a);
return this._doFinalize()
},
blockSize: 16,
_createHelper: function(c) {
return function(a, b) {
return (new c[_0x52e0[4]](b))[_0x52e0[46]](a)
}
},
_createHmacHelper: function(c) {
return function(a, b) {
return (new h[_0x52e0[47]][_0x52e0[4]](c, b))[_0x52e0[46]](a)
}
}
});
var h = g[_0x52e0[48]] = {};
return g
}(Math);
我不会粘贴其他自动执行的功能,但如果您感兴趣,可以在此处找到它们:https://gist.github.com/anonymous/73b41a89f073653ee405
一些更有趣的变量名称是:
var code_text1 = $(_0x52e0[111])[_0x52e0[110]]();
var decrypted = CryptoJS[_0x52e0[106]][_0x52e0[71]](code_text1, _0x52e0[112]);
var plaintext2 = decrypted.toString(CryptoJS[_0x52e0[22]].Utf8);
var code_text2 = plaintext2[_0x52e0[113]](/[^[\]]+(?=])/g);
var secretBlog = code_text2[0];
var urlBlog = code_text2[1];
eval本身会中断,因为code_text
在执行$(_0x52e0[111])[_0x52e0[110]]();
时尝试设置该值,其中 - {dempfucscated}为$('.buyer')['text']()
我的猜测 - 纯粹是我的猜测,因为它取决于执行此代码的位置,是否会将其注入电子商务网站,该网站读取值(基于buyer
文本),以及发送(或重定向)到(秘密)博客或其他URL。
无论如何,希望这有助于学习JS并获得乐趣!
答案 1 :(得分:1)
嗯,你应该首先美化代码。如果代码一团糟,真的很难看到去哪里。第一步是让它更漂亮(我使用jsbeautifier)。
从那里你可以看到类似的代码:
eval(function(d, e, a, c, b, f) { ... }(...))
由于不涉及复杂的混淆,我们可以简单地用变量语句替换eval
。
var x = (function(d, e, a, c, b, f) { ... }(...))
这里我们基本上是在告诉变量&#34; x&#34;等于函数返回的代码。接下来,console.log()
x
的价值就像这样。
console.log(x);
您会注意到代码现在更具可读性,进步!如果查看输出代码,您会注意到它遵循类似的编码字符模式。我们可以通过将这个代码输入到jsbeautifier的简单文本区域中来对这些代码进行反混淆处理。&#34; Unescape Printable Chars&#34;检查。
从这里开始,您会在渲染代码的底部注意到另一个eval
语句。我不会进入另一个级别,但希望这篇文章能为您提供反混淆的基础知识。要继续进行反混淆,您只需删除if语句并将eval更改为另一个变量声明和返回的console.log()
。
当您进一步进行反混淆时,您将能够更多地了解来源。
如果您想查看其源代码,JavaScript混淆器CryptoJS是开源的。
祝你好运!