Re:Trustworthy Chrome Extensions, by default
by skrebbel on Monday October 01, 2018 @04:18PM
(#18116464)
Sure, but you're saying it yourself:
> even if it requires a lot of changes
A minifier will not make changes that are not required. In fact a lot of the more obscure changes can still be easily detected by code and reversed. Eg most minifiers will turn
if(hello) {
alert("hi");
}
into
hello&&alert("hi");
That seems cryptic to the untrained reader. But you can probably imagine writing an unminifier that can detect that the result of that expression is not assigned to anything and that the && is only used for lazy evaluation. This means that you could restore the original "if". Now note that the only reason you can do this is because minifiers follow this same pattern all the time. Every if with a small body is minified in this same way. Unminifiers know the patterns that minifiers use and reverse them where possible. It's pretty fun to do actually.
An obfuscator, on the other side, will try to vary the patterns by which code is changed as much as possible, and as randomly as possible. Depending on a random seed, the same if might be turned into
var b=52,w="toString",h=History;
(((hello==(b-51))||(!b))&&(()=>alert(h[w].call(h).substr(9,2)))())
This is a lot harder to turn back into that if, and essentially impossible for reviewers to follow. A good static analysis tool could probably do some flow analysis and derive that hello is checked for truthiness, the !b check is superfluous and the function expression is immediately invoked, and still restore that if. But real decent obfuscators can do similar static analysis and have access to much more data, by definition (especially if the input code is typed). Eg it would use existing variables in scope that it knows are truthy/falsy/etc and needlessly add them to checks (maybe even bring them into scope from elsewhere). The more code you have, the better you can obfuscate it. Writing a good obfuscator is hard (writing a shitty one is peanuts and a lot of fun), but writing a useful deobfuscator that can handle non-shitty obfuscators is nearly impossible.
> even if it requires a lot of changes
A minifier will not make changes that are not required. In fact a lot of the more obscure changes can still be easily detected by code and reversed. Eg most minifiers will turn
into That seems cryptic to the untrained reader. But you can probably imagine writing an unminifier that can detect that the result of that expression is not assigned to anything and that the && is only used for lazy evaluation. This means that you could restore the original "if". Now note that the only reason you can do this is because minifiers follow this same pattern all the time. Every if with a small body is minified in this same way. Unminifiers know the patterns that minifiers use and reverse them where possible. It's pretty fun to do actually.An obfuscator, on the other side, will try to vary the patterns by which code is changed as much as possible, and as randomly as possible. Depending on a random seed, the same if might be turned into
This is a lot harder to turn back into that if, and essentially impossible for reviewers to follow. A good static analysis tool could probably do some flow analysis and derive that hello is checked for truthiness, the !b check is superfluous and the function expression is immediately invoked, and still restore that if. But real decent obfuscators can do similar static analysis and have access to much more data, by definition (especially if the input code is typed). Eg it would use existing variables in scope that it knows are truthy/falsy/etc and needlessly add them to checks (maybe even bring them into scope from elsewhere). The more code you have, the better you can obfuscate it. Writing a good obfuscator is hard (writing a shitty one is peanuts and a lot of fun), but writing a useful deobfuscator that can handle non-shitty obfuscators is nearly impossible.