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) * 0
This 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.charCodeAt
string.length
- String indexing (e.g.
"Hello"[1])
String.fromCharCode
number.toString(base)
string.replace(from, to) with either a string literal or a regex literal as the from argument
"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
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:
This 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 * 0and then applying the existing expression simplifications.
Example String:
This resolves to "value"
Again,
String.fromCharCodeis pure and only called with literals.Complex string example:
This resolves to "host"
Functions/Properties I have seen the sample use for this purpose:
string.charCodeAtstring.length"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