Simple block of code
Using array declaration
Array declaring are a nice and compact way to rewrite a block of code especially if we are re-using result from previous operation.
Example :
foo = 1;
bar = foo + 2;
Can be rewritten as :
[bar = [foo = 1][0] + 2];
This example is trivial, but there is one interesting thing to note. Most unobfuscator won't be able to rewrite the code in a nice way. If you use this pattern with larger amount of code, it will be a pain for people to understand the code even if they use tools.
Note : You can use the same principle with object declaration, but the syntax is less light and easier to follow.
Comma and parentheses
Using comma in parentheses is an other way to obfuscate code that is very similar to the previous one. It's something that most people don't know about and it's something that can leave most people perplex about the result.
Example :
({a:1},{a:2}).a
What is the result of this expression ? 1, 2 or an error ?
The actual answer is 2, because when you separate multiple operation with a comma in parentheses, the result of the parentheses is the result of the last operation. Once you know it it's simple, but for people that aren't aware of it, it can be puzzling.
Lisp style
This one last trick is interesting just for the look. It's mainly about syntax that use an abusive amount of parentheses.
Example :
(function z(){ return(z); })((foo = (1)))((bar = ((foo) + (2))))((alert((bar))))
If you are using a lot of a specific set of character in general, your code will be harder to read. Parentheses here are just an example, but it could also apply to "{" and "}".
Rewriting conditional block of code
In javascript it's possible to replace block of code that uses if/else statement using the conditional operator (ternary operator), logic operator (&&, ||), parentheses and comma.
Let's first take a look at what we can do with logic operator, parentheses and comma. This technique primarily uses the fact that logic operator are evaluated in a lazy way and that some block of code will only be executed in the cases we want.
Example :
if (test == 2) {
bob = 1;
foo = bob + 2;
}
Can be rewritten as :
(test == 2 && (bob = 1, foo = bob + 2))
With this technique we can also transform else statement with a little bit of logic.
Example :
if (test == 2) {
bob = 1;
foo = bob + 2;
} else {
bob = 2;
}
Can be rewritten as :
((test == 2 && (bob = 1, foo = bob + 2, true)) || (bob = 2))
Note : The "true" is added there to make sure the first part of the expression always evaluate to true if test equals 2. This is a good trick to make sure the code will do the exact same thing even if we swap the "bob = 1, foo = bob + 2" part for something else. "true" can also be replaced with "1" or any expression that is truthy.
There is also the conditional operator (often called the ternary operator) that is useful to achieve the same thing. For the 2 previous examples using the conditional operator it would look like this :
(test == 2) ? (bob = 1, foo = bob + 2) : void(0)
and
(test == 2) ? (bob = 1, foo = bob + 2) : (bob = 2)
Great, Thanks !
ReplyDelete