Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 632
nex Avatar asked Dec 23 '14 19:12

nex


People also ask

How to dynamically name variables in js?

In JavaScript, dynamic variable names can be achieved by using 2 methods/ways given below. eval(): The eval() function evaluates JavaScript code represented as a string in the parameter. A string is passed as a parameter to eval(). If the string represents an expression, eval() evaluates the expression.

How do I convert a string to an array in JavaScript?

The split() method splits a string into an array of substrings. The split() method returns the new array. The split() method does not change the original string. If (" ") is used as separator, the string is split between words.

What is dynamic declaration in JavaScript?

Dynamic variables are those types of variables that don't have any specific name in the code through hard coded. A dynamic variable name is auto-generated while running the program. It is possible to create a dynamic variable in JavaScript and then using it for a specific task.

Why would you rename many variables in an array?

The reason to rename the variables is normally to use the data in some way. There generally no good reason to go back and rename the variable in an existing dataset. Instead fix the process that creates the dataset or the process that uses it. Re: rename many variables using array?

Is it better to use macro or array for variable names?

Like @Reeza said, it's much easier to just type in the names in the ARRAY statement. If you need to apply this process multiple times with many different sets of variable names, I might reconsider and recommend the macro approach.

How to replace all occurrences of environment variables in a file?

Each variable reference will be replaced with the current value of the variable, or the empty string if the variable is not defined. The command below replaces all occurrences of environment variables of the form $VAR in a file. compgen -e | xargs -I @ sh -c 'printf "s|\$%q\>|%q|g " "@" "$@"' | sed -f /dev/stdin input.file > output.file

How do I rename a variable in Proc?

You can rename variables with Proc Datasets, and you can use arrays to automate the process with a data _null_ step that generates statements and executes them with call execute as shown below. You cannot mix variable types in the same array, so you neew two arrays, one for numeric variables and another for character variables.


2 Answers

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

like image 54
Ivan Avatar answered Oct 12 '22 07:10

Ivan


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)

like image 38
Brock Adams Avatar answered Oct 12 '22 07:10

Brock Adams