-
Notifications
You must be signed in to change notification settings - Fork 141
Description
I have come across a sample which obfuscates string and number literals with string functions.
The functions used are standard functions which are "Pure", meaning they return the same result for the same input and do not modify anything else (only return a value). Thus, it should be possible to evaluate these statically.
Example Number:
29 + "7\x84k#[Lx4v'Q.f{~)\x87Z".charCodeAt(15) * 0This resolves to 29. This could be solved by realizing that string.charCodeAt is pure and has only Literals as arguments, then evaluating it statically and inlining its result (41) -> 29 + 41 * 0
and then applying the existing expression simplifications.
Example String:
"v" + "a" + String.fromCharCode(108) + "ue"This resolves to "value"
Again, String.fromCharCode is pure and only called with literals.
Complex string example:
")eh2onsIt"[(17 + ":}+R`O�X91t�7".charCodeAt(3) * 297404038).toString(31 + "EON�RrV4U}THScd".charCodeAt(11) * 0)](/[2n\)eI]/g, "") This resolves to "host"
Functions/Properties I have seen the sample use for this purpose:
string.charCodeAtstring.length- String indexing (e.g.
"Hello"[1]) String.fromCharCodenumber.toString(base)string.replace(from, to)with either a string literal or a regex literal as thefromargument"C&".replace(/[C]/g, "")="&""".replace("4zocluLvEI", "")=""
This seems to be currently ignored by any JS deobfuscator I could find.
The only JS deobfuscator that seems to handle this correctly is restringer, but it actually executes the pure-detected expressions in a sandbox and uses (outdated) node-gyp, so it can not run in the browser, requires python and microsoft c++ build tools installed, and does not work with node 24