Cause:
In the study of the crawler found a lot of Web sites have appeared in the same way of JS confusion, and the name is Pde.js, the suspicion is the use of the same obfuscation tool, so study a bit.
This tool is called JS Packer, is not a special obfuscation tool, but a JS compression tool, its official website address is: http://dean.edwards.name/packer/
Support two compression methods, one is shrink variables more conventional compression method, is to remove some whitespace comment and so on, the other is Base62 encode, is a more suitable compression of the content of the word repetition rate is high compression method.
Compression example
All discussions are based on Base62 encode compression mode, input:
Alter ("Hello, World");
Output:
Eval (function (p,a,c,k,e,r) {e=string;if (! '). Replace (/^/,string)) {while (c--) r[c]=k[c]| | C;k=[function (e) {return r[e]}];e=function () {return ' \\w+ '};c=1};while (c--) if (K[c]) p=p.replace (New RegExp (' \\b ' +e ( c) + ' \\b ', ' G '), k[c]); return p} (' 0 ("1, 2"); ', 3,3, ' Alter|hello|world '. Split (' | '), 0,{}))
After formatting:
eval (function (p, a, C, K, E, R) { e = String; if (! '). Replace (/^/, String)) { while (c--) r[c] = K[c] | | c; K = [function (e) { return r[e] }]; E = function () { return ' \\w+ ' }; c = 1 } ; while (c--) if (k[c]) p = p.replace (new RegExp (' \\b ' + E (c) + ' \\b ', ' G '), k[c]);
The above code looks very bluffing, in fact the principle is very simple, we patiently analyzed.
Compression principle:
In short, the same word is compressed, specifically to extract all the words as a dictionary, and then the source code to represent the word in the place of the reference dictionary subscript, so that when the repetition of a lot of words when the compression effect is better, but when the repetition of the word is a little less than the loss of the method.
Bring specific data to the specific analysis, such as the following code:
Console.log ("AAAAA"); Console.log ("aaaaa"); Console.log ("bbbb");
Format after compression:
eval (function (p, a, C, K, E, R) { e = String; if (! '). Replace (/^/, String)) { while (c--) r[c] = K[c] | | c; K = [function (e) { return r[e] }]; E = function () { return ' \\w+ ' }; c = 1 }; while (c--) if (k[c]) p = p.replace (new RegExp (' \\b ' + E (c) + ' \\b ', ' G '), k[c]); Return P} (' 0.1 ("2"); 0.1 ("2"); 0.1 ("3"); ', 4, 4, ' console|log|aaaaa|bbbb '. Split (' | '), 0, {}))
You can see that the rule is already obvious, the first parameter ' 0.1 ("2"), 0.1 ("2"), 0.1 ("3"); The number in the ' console|log|aaaaa|bbbb '. Split (' | ') in the subscript, when extracting only need to re-index the number of words can be.
Here is a simple explanation of the decompression algorithm:
P Replace all the words in the original content with the compressed content of the dictionary subscript//A dictionary size, temporarily not used//C dictionary size, in the decompression of the associated compressed content and dictionary//K dictionary//E in the decompression, when replace the second parameter support function, is \\w+, otherwise Subscript corresponding String//R used to save dictionary eval when accelerating decompression (function (p, a, C, K, E, r) {e = String; Detects whether the current browser supports replace (regex, function), if supported, can speed up the decompression speed//If not supported, you can directly ignore the IF (! ". Replace (/^/, String)) {//Copy the compressed word, because K has other uses while (c--) r[c] = K[c] | | c; K[0] is used to find the replacement string for each matching subscript k = [function (e) {return r[e]}]; Used to split the original content E = function () {return ' \\w+ '}; When the decompression is accelerated, the equivalent of the while becomes if C = 1}; Use the dictionary to expand the compressed subscript code, if there is no acceleration above, C equals the number of dictionary words, to a replacement//if support for replace (string, function), the match to each number will be passed to K[c] To get the string that it should be replaced with while (c--) if (k[c]) p = p.replace (new RegExp (' \\b ' + E (c) + ' \\b ', ' G '), k[c]); Complete decompression return P} (' 0.1 ("2"); 0.1 ("2"); 0.1 ("3"); ', 4, 4, ' console|log|aaaaa|bbbb '. Split (' | '), 0, {}))
Unzip the gadget
I put this type of eval (Blablabla ...) in the form of eval compression, and wrote a simple decompression gadget for this.
Ideas:
1. Since this must be done on a Web page, it is only possible to simulate execution.
2. There may not be a single layer of eval, so you should be able to easily make multiple successive eval.
The HTML code is as follows:
The effect is as follows:
Resources:
1./packer/
2. JS obfuscation encryption compression-webmaster Tools
3. JavaScript online compression pack/Unzip tool-JavaScript Packer-Chi Wen Studio
4. What does "if (!)". Replace (/^/, String)) "Do?
5. JavaScript replace () method
Jspacker Compression and decompression research (JS eval)