> Writing an unminifier is pretty feasible and the only real trouble with reading the resulting code is the meaningless variable names.
Reviewing code with meaningless variable names is still several orders of magnitude harder than reviewing the original code though. I agree code though an obfuscater is another step up however.
> 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.Automated checking tools don't really care about human-friendly user functions' names. They will however check for calls to dangerous APIs (eg: XMLHttpRequest(url), eval(stuff) ) and some dangerous patterns (eg: background actions unprompted by the user ).
You're agreeing. Minification makes things as small as possible. No one said otherwise. The "minimum amount of code changes" could very well be "a lot of changes".
Obfuscation is more like the maximum amount of code changes possible while keeping semantics.
Writing an unminifier is pretty feasible and the only real trouble with reading the resulting code is the meaningless variable names. Writing a deobfuscator is intentionally hard.