stephenmathieson / node-obfuscator

maintainer wanted → Obfuscate your node packages because your boss says so!
216 stars 36 forks source link

backlash and vertical tab characters in string were not correctly obfuscated #30

Open shiwanlin opened 8 years ago

shiwanlin commented 8 years ago

On this version of obfuscator:

├─┬ obfuscator@0.5.4
│ ├── commander@2.0.0
│ └─┬ uglify-js@2.4.24
│   ├── async@0.2.10
│   ├─┬ source-map@0.1.34
│   │ └── amdefine@1.0.0
│   ├── uglify-to-browserify@1.0.2
│   └─┬ yargs@3.5.4
│     ├── camelcase@1.2.1
│     ├─┬ decamelize@1.1.2
│     │ └── escape-string-regexp@1.0.4
│     ├── window-size@0.1.0
│     └── wordwrap@0.0.2

In both cases I got a fatal error from node when executing the obfuscated codes of some large production code base as shown below. However I could not reproduce the same fatal error when testing with a simple test program. In both programs, the behaviors are incorrect.

SyntaxError: Unexpected token ILLEGAL
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:413:25)
    at Object.Module._extensions..js (module.js:452:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:475:10)
    at startup (node.js:117:18)
    at node.js:951:3

The problem lies in /lib/utils.js:exports.hex() -

    if (map[char]) {
      result += map[char];
    } else if ('\\' == char) {
      result += '\\' + str[++i];
    } else {
      result += '\\x' + str.charCodeAt(i).toString(16);
    }

In the case of a single character of escaped backlash, it will cause str[++i] producing "undefined". For the case of '\v', the leading zero is perhaps dropped by the charCodeAt(i).

Suggested fix: expanding the map object in /lib/utils.js to include all the official JavaScript special characters as defined in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types:

/**
 * Escape map.
 */

var map = {
  '\b': '\\b',
  '\f': '\\f',
  '\n': '\\n',
  '\r': '\\r',
  '\t': '\\t',
  '\v': '\\v',
  '\\': '\\\\',
  '\0': '\\0'.
  '\"': '\\"',
  "\'": "\\'"
};