用实际变量名/字符串替换数组映射变量?

时间:2014-12-23 19:57:11

标签: javascript jquery greasemonkey deobfuscation

我正在尝试编辑Greasemonkey / jQuery脚本。我不能在这里发布链接。
使用minify对代码进行模糊处理和压缩 它是这样开始的:

var _0x21e9 = ["\x67\x65\x74\x4D\x6F\x6E\x74\x68", "\x67\x65\x74\x55\x54\x43\x44\x61\x74\x65", ...

解码后,我得到了这个:

var _0x21e9=["getMonth","getUTCDate","getFullYear", ...   

这是一个巨大的名单(500+)。然后,它有一些像这样的变量:

 month = date[_0x21e9[0]](), day = date[_0x21e9[1]](), ...

_0x21e9 [0]是getMonth,_0x21e9 [1]是getUTCDate等。

是否可以用实际变量名替换方括号?怎么样?
我对javascript / jQuery知之甚少,无法按照现在的方式“读取”代码 我只想使用这个巨大脚本中的一些函数并删除其他我不需要的函数。

更新:我尝试使用jsbeautifier.org,如此处和重复的问题所示,但没有改变,除了“缩进”。

它没有用解码的名称替换数组变量 例如:

  1. jsbeautifier仍然给出:month = date[_0x21e9[0]]()
  2. 但我需要:month = date["getMonth"]()
  3. 没有一个在线反混淆者似乎这样做,我怎么能?


    我有没有办法与某人共享代码,至少是其中的一部分?我看过我不能发贴pastebin,或类似的。我不能在这里发布完整的代码。

    以下是代码的另一部分:

    $(_0x21e9[8] + vid)[_0x21e9[18]]();    
    

    [8]是“。” [18]是“删除”。手动更换它会产生奇怪的结果。

3 个答案:

答案 0 :(得分:10)

我还没有看过任何这样做的在线反混淆器,但原理很简单 构造一个解析“key”数组的文本过滤器,然后用适当的数组值替换该数组被引用的每个实例。

例如,假设您有一个文件 evil.js ,看起来像这样(在您使用Detect packers and obfuscators?和{{1} jsbeautifier.org之后运行它选项集):

Unescape printable chars...

在这种情况下,“key”变量为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); ,“key”数组为_0xf17f

过滤过程如下所示:

  1. 使用js文件上的文本处理提取密钥名称。结果:["(", ")", ...]
  2. 提取键数组的字符串src。结果:

    _0xf17f
  3. 在javascript中,我们可以使用keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]'; 来解析JS src的其余部分。像这样:

  4. .replace()

    如果你run that code,你会得到:

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

    - 这有点容易阅读/理解。


    我还创建了一个获取JS源代码的在线页面,并以更加自动化和健壮的方式完成所有3个重新映射步骤。你可以在以下地址看到它:

    jsbin.com/hazevo

    (注意,该工具希望源代码以“key”变量声明开头,就像代码示例一样)

答案 1 :(得分:3)

@Brock Adams解决方案很棒,但有一个小错误:它没有考虑简单的引用变量。

示例:

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

如果您尝试破译此示例,则会产生以下结果:

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

要解决此问题,只需将replacedSrc.replace编辑为@Brock代码:

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

这里有patched version

答案 2 :(得分:0)

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

这会将所有函数名称添加为数组的键。允许你这样做

date[_0x21e9["getMonth"]]()