将数组映射变量替换为实际的变量名称/字符串

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

本文关键字:变量名 字符串 映射 数组 变量 替换      更新时间:2023-09-26

我正在尝试编辑 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"]().
似乎

没有一个在线混淆器这样做,我怎么能?


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

这是代码的另一部分:

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

.",[18] 是"删除"。手动替换它会给出一个奇怪的结果。

我还没有看到任何在线混淆器可以做到这一点,但原理很简单。
构造一个文本筛选器,该筛选器分析"key"数组,然后将引用该数组的每个实例替换为适当的数组值。

例如,假设你有一个文件,evil.js看起来像这样(在你运行它之后,jsbeautifier.org 设置了Detect packers and obfuscators?Unescape printable chars...选项):

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,"key"数组将被["(", ")", ...]

筛选过程如下所示:

  1. 使用 js 文件上的文本处理提取密钥名称。结果:_0xf17f
  2. 提取密钥数组的字符串源。结果:

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

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

如果运行该代码,则会得到:

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

- 这更容易阅读/理解。


我还创建了一个在线页面,该页面采用JS源代码,并以稍微自动化和健壮的方式执行所有3个重新映射步骤。您可以在以下位置看到它:

jsbin.com/hazevo

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

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

这里有一个修补的版本。

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

这会将所有函数名称作为键添加到数组中。

date[_0x21e9["getMonth"]]()