9

I am trying to edit a Greasemonkey/jQuery script. I can't post the link here.
The code is obfuscated and compressed with minify.
It starts like this:

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

After "decoding" it, I got this:

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

It is a huge list (500+ ). Then, it has some variables like this:

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

_0x21e9[0] is getMonth, _0x21e9[1] is getUTCDate, etc.

Is it possible to replace the square brackets with the actual variable name? How?
I have little knowledge in javascript/jQuery and can not "read" the code the way it is right now.
I just want to use some functions from this huge script and remove the others I do not need.

Update: I tried using jsbeautifier.org as suggested here and in the duplicated question but nothing changed, except the "indent".

It did not replace the array variables with the decoded names.
For example:

  1. jsbeautifier still gives: month = date[_0x21e9[0]]().
  2. But I need: month = date["getMonth"]().

None of the online deobfuscators seem to do this, How can I?


Is there a way for me to share the code with someone, at least part of it? I read I can not post pastebin, or similar here. I can not post it the full code here.

Here is another part of the code:

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

[8] is "." and [18] is "remove". Manually replacing it gives a strange result.

8
  • Why would you want to replace the square brackets with the actual variable name? What would be the point of accessing a variable named _0x21e9getMonth to retrieve the string "getMonth". ? Commented Dec 23, 2014 at 20:01
  • It is a huge list of 500+ strings. To know [0] is getMonth, I have to manually check the list and count. If it is [500], I willll have to count the strings separated by a comma. How can I do this? It is not my script, I just want to remove the things I will not use. Commented Dec 23, 2014 at 20:07
  • This code is pretty 'obfuscated'... Are you trying to decode someones javascript and use it? Meaning, this code was probably obfuscated for a reason and if you know who did it then they can just as easily revert it. Commented Dec 23, 2014 at 20:11
  • It is not my script. It adds some functions to a forum I use, like blocking users, adding some menus etc. I want to remove all of it and keep only the function to refresh the page. Some users were even saying it was "keylogger". I just want to remove some functions for personal use, I did not even post the script here. Commented Dec 23, 2014 at 20:20
  • Okay, I see that this is a new wrinkle on the "standard" deobfuscation questions. To do what you want, you will need to write a "filter" to parse the JS text, substituting array values -- Basically, an automated search and replace. I'm going offline, but I'll post an answer in several hours if someone doesn't beat me to it. Commented Dec 23, 2014 at 22:06

3 Answers 3

14

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)

Sign up to request clarification or add additional context in comments.

Comments

4

@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.

Comments

0
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"]]()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.