Replace array-mapped variables with the actual variable name/string?

半城伤御伤魂 提交于 2019-11-30 09:31:47

I haven't seen any online deobfuscator that does this yet, but the principle is simple.
Construct a text filter that parses the "key" array and then replaces each instance that that array is referenced, with the appropriate array value.

For example, suppose you have a file, evil.js that looks like this (AFTER you have run it though jsbeautifier.org with the Detect packers and obfuscators? and the Unescape printable chars... options set):

var _0xf17f = ["(", ")", 'div', "createElement", "id", "log", "console"];
var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);
var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);
var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];
window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);

In that case, the "key" variable would be _0xf17f and the "key" array would be ["(", ")", ...].

The filter process would look like this:

  1. Extract the key name using text processing on the js file. Result: _0xf17f
  2. Extract the string src of the key array. Result:

    keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
    
  3. In javascript, we can then use .replace() to parse the rest of the JS src. Like so:

var keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
var restOfSrc   = "var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);\n"
                + "var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);\n"
                + "var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];\n"
                + "window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);\n"
                ;
var keyArray    = eval (keyArrayStr);
//-- Note that `_0xf17f` is the key name we already determined.
var keyRegExp   = /_0xf17f\s*\[\s*(\d+)\s*\]/g;

var deObsTxt    = restOfSrc.replace (keyRegExp, function (matchStr, p1Str) {
    return '"' + keyArray[ parseInt(p1Str, 10) ] + '"';
} );
console.log (deObsTxt);

if you run that code, you get:

var _0x41dcx3 = eval("(" + '{id: 3}' + ")");
var _0x41dcx4 = document["createElement"]("div");
var _0x41dcx5 = _0x41dcx3["id"];
window["console"]["log"](_0x41dcx5);

-- which is a bit easier to read/understand.


I've also created an online page that takes JS source and does all 3 remapping steps in a slightly more automated and robust manner. You can see it at:

jsbin.com/hazevo

(Note that that tool expects the source to start with the "key" variable declaration, like your code samples do)

@Brock Adams solution is brilliant, but there is a small bug: it doesn't take into account simple quoted vars.

Example:

var _0xbd34 = ["hello ", '"my" world'];
(function($) {
  alert(_0xbd34[0] + _0xbd34[1])
});

If you try to decipher this example, it will result on this:

alert("hello " + ""my" world")

To resolve this, just edit the replacedSrc.replace into @Brock code:

replacedSrc     = replacedSrc.replace (nameRegex, function (matchStr, p1Str) {
    var quote = keyArry[parseInt (p1Str, 10)].indexOf('"')==-1? '"' : "'";
    return quote + keyArry[ parseInt (p1Str, 10) ] + quote;
} );

Here you have a patched version.

for (var i = 0; i < _0x21e9.length; i++) {
  var funcName = _0x21e9[i];
  _0x21e9[funcName] = funcName;
}

this will add all the function names as keys to the array. allowing you to do

date[_0x21e9["getMonth"]]()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!