commit c3b9da38219c65d44c910f53a6c9aaca40167bad Author: sanex3339 Date: Mon May 9 11:17:04 2016 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2d2b47d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +node_modules \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 00000000..75654b1c --- /dev/null +++ b/index.js @@ -0,0 +1,20 @@ +"use strict"; +const Obfuscator_1 = require('./src/Obfuscator'); +let escodegen = require('escodegen'), esprima = require('esprima'), RawSource = require('webpack-core/lib/RawSource'); +class JavaScriptObfuscator { + static obfuscate(sourceCode, options) { + let astTree = esprima.parse(sourceCode), obfuscator = new Obfuscator_1.Obfuscator(options); + obfuscator.obfuscateNode(astTree); + return JavaScriptObfuscator.generateCode(astTree); + } + static generateCode(astTree) { + return new RawSource(escodegen.generate(astTree, JavaScriptObfuscator.escodegenParams)); + } +} +JavaScriptObfuscator.escodegenParams = { + format: {}, + verbatim: 'x-verbatim-property' +}; +exports.JavaScriptObfuscator = JavaScriptObfuscator; +module.exports = JavaScriptObfuscator; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/index.js.map b/index.js.map new file mode 100644 index 00000000..16a64ac0 --- /dev/null +++ b/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAIb,6BAA2B,kBAAkB,CAAC,CAAA;AAI9C,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,EAChC,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,EAC5B,SAAS,GAAQ,OAAO,CAAC,4BAA4B,CAAC,CAAC;AAE3D;IAeI,OAAc,SAAS,CAAE,UAAkB,EAAE,OAAY;QACrD,IAAI,OAAO,GAAQ,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EACxC,UAAU,GAAe,IAAI,uBAAU,CAAC,OAAO,CAAC,CAAC;QAErD,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAElC,MAAM,CAAC,oBAAoB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;IAKD,OAAe,YAAY,CAAE,OAAY;QACrC,MAAM,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC,CAAC;IAC5F,CAAC;AACL,CAAC;AA1BkB,oCAAe,GAAQ;IAClC,MAAM,EAAE,EAEP;IACD,QAAQ,EAAE,qBAAqB;CAClC,CAAC;AATO,4BAAoB,uBA8BhC,CAAA;AAED,MAAM,CAAC,OAAO,GAAG,oBAAoB,CAAC"} \ No newline at end of file diff --git a/index.ts b/index.ts new file mode 100644 index 00000000..a37e33e0 --- /dev/null +++ b/index.ts @@ -0,0 +1,45 @@ +"use strict"; + +declare let module: any; + +import { Obfuscator } from './src/Obfuscator'; +import { UnicodeArrayNodesGroup } from './src/node-groups/UnicodeArrayNodesGroup'; +import { Utils } from './src/Utils'; + +let escodegen = require('escodegen'), + esprima = require('esprima'), + RawSource: any = require('webpack-core/lib/RawSource'); + +export class JavaScriptObfuscator { + /** + * @type any + */ + private static escodegenParams: any = { + format: { + //compact: true + }, + verbatim: 'x-verbatim-property' + }; + + /** + * @param sourceCode + * @param options + */ + public static obfuscate (sourceCode: string, options: any): string { + let astTree: any = esprima.parse(sourceCode), + obfuscator: Obfuscator = new Obfuscator(options); + + obfuscator.obfuscateNode(astTree); + + return JavaScriptObfuscator.generateCode(astTree); + } + + /** + * @param astTree + */ + private static generateCode (astTree: any): string { + return new RawSource(escodegen.generate(astTree, JavaScriptObfuscator.escodegenParams)); + } +} + +module.exports = JavaScriptObfuscator; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..73decc5f --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "javascript-obfuscator", + "version": "0.0.9", + "description": "JavaScript obfuscator", + "main": "index.js", + "dependencies": { + }, + "devDependencies": { + "lite-server": "^1.3.1", + "tsd": "^0.6.5", + "typescript": "*" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/sanex3339/javascript-obfuscator.git" + }, + "scripts": { + "tsc": "tsc", + "tsc:w": "tsc -w", + "lite": "lite-server", + "start": "concurrent \"npm run tsc:w\" \"npm run lite\" " + }, + "author": { + "name": "sanex3339" + }, + "license": "ISC" +} diff --git a/readme.md b/readme.md new file mode 100644 index 00000000..1f70cab5 --- /dev/null +++ b/readme.md @@ -0,0 +1,50 @@ +#JavaScript obfuscator for Node.js + +JavaScript obfuscator for Node.js and free alternative of [js-obfuscator](https://github.com/caiguanhao/js-obfuscator) without any limits. + +###Installation + +Install the package with NPM and add it to your devDependencies: + +`npm install --save-dev javascript-obfuscator` + +###Usage: + +```javascript +var JavaScriptObfuscator = require('javascript-obfuscator'); + +var obfuscatedCode = JavaScriptObfuscator.obfuscate( + `var variable = 'abc'; console.log(variable);`, + { + rotateUnicodeArray: false + } +); +``` + +## obfuscate(sourceCode, options) + +###sourceCode +Type: `string` Default: `null` + +Any valid SourceCode + +###options +Type: `Object` Default: `null` + +Options for JavaScript obfuscator: + +```javascript +{ + rotateUnicodeArray: false +} +``` + +####Available options +#####rotateUnicodeArray +Default: `true` + +For more hard understanding of code, during each obfuscation all literal values are stored in array as Unicode codes sequence. +This options will rotate all values inside array at random value during obfuscation of code, and insert inside source code helper function +which will rotate array values back to their original indexes. +This option affected only on visual code organisation, because we can easily get original array during debug process. +Not recommended for small source code, because helper function will attract attention. \ No newline at end of file diff --git a/src/Obfuscator.js b/src/Obfuscator.js new file mode 100644 index 00000000..b3c86fc3 --- /dev/null +++ b/src/Obfuscator.js @@ -0,0 +1,89 @@ +"use strict"; +const AppendState_1 = require('./enums/AppendState'); +const FunctionDeclarationObfuscator_1 = require('./node-obfuscators/FunctionDeclarationObfuscator'); +const FunctionObfuscator_1 = require('./node-obfuscators/FunctionObfuscator'); +const LiteralObfuscator_1 = require('./node-obfuscators/LiteralObfuscator'); +const MemberExpressionObfuscator_1 = require('./node-obfuscators/MemberExpressionObfuscator'); +const MethodDefinitionObfuscator_1 = require('./node-obfuscators/MethodDefinitionObfuscator'); +const ObjectExpressionObfuscator_1 = require('./node-obfuscators/ObjectExpressionObfuscator'); +const UnicodeArrayNode_1 = require('./nodes/UnicodeArrayNode'); +const UnicodeArrayNodesGroup_1 = require('./node-groups/UnicodeArrayNodesGroup'); +const Utils_1 = require('./Utils'); +const VariableDeclarationObfuscator_1 = require('./node-obfuscators/VariableDeclarationObfuscator'); +let estraverse = require('estraverse'); +class Obfuscator { + constructor(options) { + this.nodes = new Map(); + this.nodeObfuscators = new Map([ + ['ClassDeclaration', [FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator]], + ['FunctionDeclaration', [ + FunctionDeclarationObfuscator_1.FunctionDeclarationObfuscator, + FunctionObfuscator_1.FunctionObfuscator + ]], + ['ArrowFunctionExpression', [FunctionObfuscator_1.FunctionObfuscator]], + ['FunctionExpression', [FunctionObfuscator_1.FunctionObfuscator]], + ['MethodDefinition', [MethodDefinitionObfuscator_1.MethodDefinitionObfuscator]], + ['VariableDeclaration', [VariableDeclarationObfuscator_1.VariableDeclarationObfuscator]], + ['ObjectExpression', [ObjectExpressionObfuscator_1.ObjectExpressionObfuscator]], + ['MemberExpression', [MemberExpressionObfuscator_1.MemberExpressionObfuscator]], + ['Literal', [LiteralObfuscator_1.LiteralObfuscator]] + ]); + this.options = { + rotateUnicodeArray: true + }; + Object.assign(this.options, options); + } + obfuscateNode(node) { + if (this.options['rotateUnicodeArray']) { + this.setNodesGroup('unicodeArrayNodesGroup', new UnicodeArrayNodesGroup_1.UnicodeArrayNodesGroup(node)); + } + else { + this.setNode('unicodeArrayNode', new UnicodeArrayNode_1.UnicodeArrayNode(node, Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH))); + } + this.beforeObfuscation(node); + estraverse.replace(node, { + leave: (node, parent) => this.nodeController(node, parent) + }); + this.afterObfuscation(node); + } + setNode(nodeName, node) { + this.nodes.set(nodeName, node); + } + setNodesGroup(groupName, nodesGroup) { + let nodes = nodesGroup.getNodes(); + nodes.forEach((node, key) => { + this.nodes.set(key, node); + }); + } + afterObfuscation(node) { + this.nodes.forEach((node) => { + if (node.getAppendState() === AppendState_1.AppendState.AfterObfuscation) { + node.appendNode(); + } + }); + } + beforeObfuscation(node) { + this.nodes.forEach((node) => { + if (node.getAppendState() === AppendState_1.AppendState.BeforeObfuscation) { + node.appendNode(); + } + }); + } + ; + nodeController(node, parent) { + switch (node.type) { + default: + this.initializeNodeObfuscators(node, parent); + } + } + initializeNodeObfuscators(node, parent) { + if (!this.nodeObfuscators.has(node.type)) { + return; + } + this.nodeObfuscators.get(node.type).forEach((obfuscator) => { + new obfuscator(this.nodes).obfuscateNode(node, parent); + }); + } +} +exports.Obfuscator = Obfuscator; +//# sourceMappingURL=Obfuscator.js.map \ No newline at end of file diff --git a/src/Obfuscator.js.map b/src/Obfuscator.js.map new file mode 100644 index 00000000..e15d5b0f --- /dev/null +++ b/src/Obfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Obfuscator.js","sourceRoot":"","sources":["Obfuscator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/Obfuscator.ts b/src/Obfuscator.ts new file mode 100644 index 00000000..bfa39ece --- /dev/null +++ b/src/Obfuscator.ts @@ -0,0 +1,148 @@ +import { INode } from './interfaces/INode'; +import { INodeObfuscator } from './interfaces/INodeObfuscator'; +import { INodesGroup } from './interfaces/INodesGroup'; + +import { AppendState } from './enums/AppendState'; + +import { FunctionDeclarationObfuscator } from './node-obfuscators/FunctionDeclarationObfuscator'; +import { FunctionObfuscator } from './node-obfuscators/FunctionObfuscator'; +import { LiteralObfuscator } from './node-obfuscators/LiteralObfuscator'; +import { NodesGroup } from './node-groups/NodesGroup'; +import { MemberExpressionObfuscator } from './node-obfuscators/MemberExpressionObfuscator'; +import { MethodDefinitionObfuscator } from './node-obfuscators/MethodDefinitionObfuscator'; +import { ObjectExpressionObfuscator } from './node-obfuscators/ObjectExpressionObfuscator'; +import { UnicodeArrayNode } from './nodes/UnicodeArrayNode'; +import { UnicodeArrayNodesGroup } from './node-groups/UnicodeArrayNodesGroup'; +import { UnicodeArrayRotateFunctionNode } from './nodes/UnicodeArrayRotateFunctionNode'; +import { Utils } from './Utils'; +import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclarationObfuscator'; + +let estraverse = require('estraverse'); + +export class Obfuscator { + /** + * @type {Map} + */ + private nodes: Map = new Map (); + + /** + * @type {Map} + */ + private nodeObfuscators: Map = new Map ([ + ['ClassDeclaration', [FunctionDeclarationObfuscator]], + ['FunctionDeclaration', [ + FunctionDeclarationObfuscator, + FunctionObfuscator + ]], + ['ArrowFunctionExpression', [FunctionObfuscator]], + ['FunctionExpression', [FunctionObfuscator]], + ['MethodDefinition', [MethodDefinitionObfuscator]], + ['VariableDeclaration', [VariableDeclarationObfuscator]], + ['ObjectExpression', [ObjectExpressionObfuscator]], + ['MemberExpression', [MemberExpressionObfuscator]], + ['Literal', [LiteralObfuscator]] + ]); + + /** + * @type any + */ + private options: any = { + rotateUnicodeArray: true + }; + + /** + * @param options + */ + constructor (options: any) { + Object.assign(this.options, options); + } + + /** + * @param node + */ + public obfuscateNode (node: any): void { + if (this.options['rotateUnicodeArray']) { + this.setNodesGroup('unicodeArrayNodesGroup', new UnicodeArrayNodesGroup(node)); + } else { + this.setNode( + 'unicodeArrayNode', + new UnicodeArrayNode(node, Utils.getRandomVariableName(UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH)) + ); + } + + this.beforeObfuscation(node); + + estraverse.replace(node, { + leave: (node, parent) => this.nodeController(node, parent) + }); + + this.afterObfuscation(node); + } + + /** + * @param nodeName + * @param node + */ + public setNode (nodeName: string, node: INode): void { + this.nodes.set(nodeName, node); + } + + /** + * @param groupName + * @param nodesGroup + */ + public setNodesGroup (groupName: string, nodesGroup: NodesGroup): void { + let nodes: Map = nodesGroup.getNodes(); + + nodes.forEach((node: INode, key: string) => { + this.nodes.set(key, node); + }); + } + + /** + * @param node + */ + private afterObfuscation (node: any): void { + this.nodes.forEach((node: INode) => { + if (node.getAppendState() === AppendState.AfterObfuscation) { + node.appendNode(); + } + }); + } + + /** + * @param node + */ + private beforeObfuscation (node: any): void { + this.nodes.forEach((node: INode) => { + if (node.getAppendState() === AppendState.BeforeObfuscation) { + node.appendNode(); + } + }); + }; + + /** + * @param node + * @param parent + */ + private nodeController (node, parent): void { + switch (node.type) { + default: + this.initializeNodeObfuscators(node, parent); + } + } + + /** + * @param node + * @param parent + */ + private initializeNodeObfuscators (node: any, parent: any): void { + if (!this.nodeObfuscators.has(node.type)) { + return; + } + + this.nodeObfuscators.get(node.type).forEach((obfuscator: Function) => { + new ( obfuscator(this.nodes)).obfuscateNode(node, parent); + }); + } +} \ No newline at end of file diff --git a/src/Utils.js b/src/Utils.js new file mode 100644 index 00000000..1cadc2b2 --- /dev/null +++ b/src/Utils.js @@ -0,0 +1,37 @@ +"use strict"; +class Utils { + static arrayRotate(array, times, reverse = false) { + if (times < 0) { + return; + } + let newArray = array, temp; + while (times--) { + if (!reverse) { + temp = newArray.pop(); + newArray.unshift(temp); + } + else { + temp = newArray.shift(); + newArray.push(temp); + } + } + return newArray; + } + static decToHex(dec) { + return (dec + Math.pow(16, 6)).toString(16).substr(-6); + } + static getRandomInteger(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + static getRandomVariableName(length = 6) { + const prefix = '_0x'; + return `${prefix}${(Utils.decToHex(Utils.getRandomInteger(10000, 9999999))).substr(0, length)}`; + } + static stringToUnicode(string) { + return `'${string.replace(/[\s\S]/g, (escape) => { + return `\\u${('0000' + escape.charCodeAt(0).toString(16)).slice(-4)}`; + })}'`; + } +} +exports.Utils = Utils; +//# sourceMappingURL=Utils.js.map \ No newline at end of file diff --git a/src/Utils.js.map b/src/Utils.js.map new file mode 100644 index 00000000..003b3628 --- /dev/null +++ b/src/Utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Utils.js","sourceRoot":"","sources":["Utils.ts"],"names":[],"mappings":";AAAA;IAOI,OAAc,WAAW,CAAE,KAAY,EAAE,KAAa,EAAE,OAAO,GAAY,KAAK;QAC5E,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC;QACX,CAAC;QAED,IAAI,QAAQ,GAAU,KAAK,EACvB,IAAS,CAAC;QAEd,OAAO,KAAK,EAAE,EAAE,CAAC;YACb,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;gBACX,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC;gBACtB,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACxB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;QACL,CAAC;QAED,MAAM,CAAC,QAAQ,CAAC;IACpB,CAAC;IAMD,OAAc,QAAQ,CAAC,GAAW;QAC9B,MAAM,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAOD,OAAc,gBAAgB,CAAC,GAAW,EAAE,GAAW;QACnD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC7D,CAAC;IAMD,OAAc,qBAAqB,CAAE,MAAM,GAAW,CAAC;QACnD,MAAM,MAAM,GAAG,KAAK,CAAC;QAErB,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;IACpG,CAAC;IAMD,OAAc,eAAe,CAAE,MAAc;QACzC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM;YACxC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,CAAC,CAAC,GAAG,CAAC;IACV,CAAC;AACL,CAAC;AAhEY,aAAK,QAgEjB,CAAA"} \ No newline at end of file diff --git a/src/Utils.ts b/src/Utils.ts new file mode 100644 index 00000000..9de958fc --- /dev/null +++ b/src/Utils.ts @@ -0,0 +1,65 @@ +export class Utils { + /** + * @param array + * @param times + * @param reverse + * @returns {any[]} + */ + public static arrayRotate (array: any[], times: number, reverse: boolean = false) { + if (times < 0) { + return; + } + + let newArray: any[] = array, + temp: any; + + while (times--) { + if (!reverse) { + temp = newArray.pop(); + newArray.unshift(temp); + } else { + temp = newArray.shift(); + newArray.push(temp); + } + } + + return newArray; + } + + /** + * @param dec + * @returns {string} + */ + public static decToHex(dec: number): string { + return (dec + Math.pow(16, 6)).toString(16).substr(-6); + } + + /** + * @param min + * @param max + * @returns {number} + */ + public static getRandomInteger(min: number, max: number): number { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + /** + * @param length + * @returns {any} + */ + public static getRandomVariableName (length: number = 6): string { + const prefix = '_0x'; + + return `${prefix}${(Utils.decToHex(Utils.getRandomInteger(10000, 9999999))).substr(0, length)}`; + } + + /** + * @param string + * @returns {string} + */ + public static stringToUnicode (string: string): string { + return `'${string.replace(/[\s\S]/g, (escape) => { + return `\\u${('0000' + escape.charCodeAt(0).toString(16)).slice(-4)}`; + })}'`; + } +} \ No newline at end of file diff --git a/src/enums/AppendState.js b/src/enums/AppendState.js new file mode 100644 index 00000000..debe74a3 --- /dev/null +++ b/src/enums/AppendState.js @@ -0,0 +1,7 @@ +"use strict"; +(function (AppendState) { + AppendState[AppendState["BeforeObfuscation"] = 0] = "BeforeObfuscation"; + AppendState[AppendState["AfterObfuscation"] = 1] = "AfterObfuscation"; +})(exports.AppendState || (exports.AppendState = {})); +var AppendState = exports.AppendState; +//# sourceMappingURL=AppendState.js.map \ No newline at end of file diff --git a/src/enums/AppendState.js.map b/src/enums/AppendState.js.map new file mode 100644 index 00000000..f959cb1b --- /dev/null +++ b/src/enums/AppendState.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AppendState.js","sourceRoot":"","sources":["AppendState.ts"],"names":[],"mappings":";AAAA,WAAY,WAAW;IAAE,uEAAiB,CAAA;IAAE,qEAAgB,CAAA;AAAA,CAAC,EAAjD,mBAAW,KAAX,mBAAW,QAAsC;AAA7D,IAAY,WAAW,GAAX,mBAAiD,CAAA"} \ No newline at end of file diff --git a/src/enums/AppendState.ts b/src/enums/AppendState.ts new file mode 100644 index 00000000..4e4a3230 --- /dev/null +++ b/src/enums/AppendState.ts @@ -0,0 +1 @@ +export enum AppendState {BeforeObfuscation, AfterObfuscation} \ No newline at end of file diff --git a/src/interfaces/INode.js b/src/interfaces/INode.js new file mode 100644 index 00000000..7b4f01d1 --- /dev/null +++ b/src/interfaces/INode.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=INode.js.map \ No newline at end of file diff --git a/src/interfaces/INode.js.map b/src/interfaces/INode.js.map new file mode 100644 index 00000000..af51676d --- /dev/null +++ b/src/interfaces/INode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"INode.js","sourceRoot":"","sources":["INode.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/src/interfaces/INode.ts b/src/interfaces/INode.ts new file mode 100644 index 00000000..a5fa489b --- /dev/null +++ b/src/interfaces/INode.ts @@ -0,0 +1,32 @@ +import { AppendState } from '../enums/AppendState'; + +export interface INode { + appendNode (): void; + + /** + * @returns {AppendState} + */ + getAppendState (): AppendState; + + /** + * @returns any + */ + getNode (): any; + + /** + * @returns {string} + */ + getNodeIdentifier ? (): string; + + /** + * @returns any + */ + getNodeData ? (): any; + + /** + * @param node + */ + setNode (node: any): void; + + updateNode (): void; +} \ No newline at end of file diff --git a/src/interfaces/INodeObfuscator.js b/src/interfaces/INodeObfuscator.js new file mode 100644 index 00000000..c8210376 --- /dev/null +++ b/src/interfaces/INodeObfuscator.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=INodeObfuscator.js.map \ No newline at end of file diff --git a/src/interfaces/INodeObfuscator.js.map b/src/interfaces/INodeObfuscator.js.map new file mode 100644 index 00000000..6eb24e18 --- /dev/null +++ b/src/interfaces/INodeObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"INodeObfuscator.js","sourceRoot":"","sources":["INodeObfuscator.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/src/interfaces/INodeObfuscator.ts b/src/interfaces/INodeObfuscator.ts new file mode 100644 index 00000000..fffbc81b --- /dev/null +++ b/src/interfaces/INodeObfuscator.ts @@ -0,0 +1,7 @@ +export interface INodeObfuscator { + /** + * @param node + * @param parentNode + */ + obfuscateNode (node: any, parentNode?: any): void; +} \ No newline at end of file diff --git a/src/interfaces/INodesGroup.js b/src/interfaces/INodesGroup.js new file mode 100644 index 00000000..bb149a22 --- /dev/null +++ b/src/interfaces/INodesGroup.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=INodesGroup.js.map \ No newline at end of file diff --git a/src/interfaces/INodesGroup.js.map b/src/interfaces/INodesGroup.js.map new file mode 100644 index 00000000..aa1763ea --- /dev/null +++ b/src/interfaces/INodesGroup.js.map @@ -0,0 +1 @@ +{"version":3,"file":"INodesGroup.js","sourceRoot":"","sources":["INodesGroup.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/src/interfaces/INodesGroup.ts b/src/interfaces/INodesGroup.ts new file mode 100644 index 00000000..731e46fc --- /dev/null +++ b/src/interfaces/INodesGroup.ts @@ -0,0 +1,8 @@ +import { INode } from './INode'; + +export interface INodesGroup { + /** + * @returns {Map } + */ + getNodes (): Map ; +} \ No newline at end of file diff --git a/src/node-groups/NodesGroup.js b/src/node-groups/NodesGroup.js new file mode 100644 index 00000000..76fd38f4 --- /dev/null +++ b/src/node-groups/NodesGroup.js @@ -0,0 +1,8 @@ +"use strict"; +class NodesGroup { + getNodes() { + return this.nodes; + } +} +exports.NodesGroup = NodesGroup; +//# sourceMappingURL=NodesGroup.js.map \ No newline at end of file diff --git a/src/node-groups/NodesGroup.js.map b/src/node-groups/NodesGroup.js.map new file mode 100644 index 00000000..310db545 --- /dev/null +++ b/src/node-groups/NodesGroup.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NodesGroup.js","sourceRoot":"","sources":["NodesGroup.ts"],"names":[],"mappings":";AAIA;IASW,QAAQ;QACX,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;AACL,CAAC;AAZqB,kBAAU,aAY/B,CAAA"} \ No newline at end of file diff --git a/src/node-groups/NodesGroup.ts b/src/node-groups/NodesGroup.ts new file mode 100644 index 00000000..9127ca9f --- /dev/null +++ b/src/node-groups/NodesGroup.ts @@ -0,0 +1,17 @@ +import { INode } from '../interfaces/INode'; + +import { INodesGroup } from '../interfaces/INodesGroup'; + +export abstract class NodesGroup implements INodesGroup { + /** + * @type {Map} + */ + protected nodes: Map ; + + /** + * @returns {Map} + */ + public getNodes (): Map { + return this.nodes; + } +} \ No newline at end of file diff --git a/src/node-groups/UnicodeArrayNodesGroup.js b/src/node-groups/UnicodeArrayNodesGroup.js new file mode 100644 index 00000000..9fa552ac --- /dev/null +++ b/src/node-groups/UnicodeArrayNodesGroup.js @@ -0,0 +1,29 @@ +"use strict"; +const NodesGroup_1 = require('./NodesGroup'); +const UnicodeArrayNode_1 = require('../nodes/UnicodeArrayNode'); +const UnicodeArrayRotateFunctionCallNode_1 = require('../nodes/UnicodeArrayRotateFunctionCallNode'); +const UnicodeArrayRotateFunctionNode_1 = require('../nodes/UnicodeArrayRotateFunctionNode'); +const Utils_1 = require('../Utils'); +class UnicodeArrayNodesGroup extends NodesGroup_1.NodesGroup { + constructor(astTree) { + super(); + this.unicodeArrayRotateFunctionIdentifier = Utils_1.Utils.getRandomVariableName(); + let unicodeArrayName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH), unicodeArrayRotateValue = Utils_1.Utils.getRandomInteger(100, 500); + this.nodes = new Map([ + [ + 'unicodeArrayNode', + new UnicodeArrayNode_1.UnicodeArrayNode(astTree, unicodeArrayName, unicodeArrayRotateValue) + ], + [ + 'unicodeArrayRotateFunctionNode', + new UnicodeArrayRotateFunctionNode_1.UnicodeArrayRotateFunctionNode(astTree, this.unicodeArrayRotateFunctionIdentifier, unicodeArrayName) + ], + [ + 'unicodeArrayRotateFunctionCallNode', + new UnicodeArrayRotateFunctionCallNode_1.UnicodeArrayRotateFunctionCallNode(astTree, this.unicodeArrayRotateFunctionIdentifier, unicodeArrayName, unicodeArrayRotateValue) + ] + ]); + } +} +exports.UnicodeArrayNodesGroup = UnicodeArrayNodesGroup; +//# sourceMappingURL=UnicodeArrayNodesGroup.js.map \ No newline at end of file diff --git a/src/node-groups/UnicodeArrayNodesGroup.js.map b/src/node-groups/UnicodeArrayNodesGroup.js.map new file mode 100644 index 00000000..d5973bf5 --- /dev/null +++ b/src/node-groups/UnicodeArrayNodesGroup.js.map @@ -0,0 +1 @@ +{"version":3,"file":"UnicodeArrayNodesGroup.js","sourceRoot":"","sources":["UnicodeArrayNodesGroup.ts"],"names":[],"mappings":";AAEA,6BAA2B,cAAc,CAAC,CAAA;AAC1C,mCAAiC,2BAA2B,CAAC,CAAA;AAC7D,qDAAmD,6CAA6C,CAAC,CAAA;AACjG,iDAA+C,yCAAyC,CAAC,CAAA;AACzF,wBAAsB,UAAU,CAAC,CAAA;AAEjC,qCAA4C,uBAAU;IASlD,YAAa,OAAY;QACrB,OAAO,CAAC;QANJ,yCAAoC,GAAW,aAAK,CAAC,qBAAqB,EAAE,CAAC;QAQjF,IAAI,gBAAgB,GAAW,aAAK,CAAC,qBAAqB,CAAC,mCAAgB,CAAC,2BAA2B,CAAC,EACpG,uBAAuB,GAAW,aAAK,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAEvE,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAkB;YAClC;gBACI,kBAAkB;gBAClB,IAAI,mCAAgB,CAChB,OAAO,EACP,gBAAgB,EAChB,uBAAuB,CAC1B;aACJ;YACD;gBACI,gCAAgC;gBAChC,IAAI,+DAA8B,CAC9B,OAAO,EACP,IAAI,CAAC,oCAAoC,EACzC,gBAAgB,CACnB;aACJ;YACD;gBACI,oCAAoC;gBACpC,IAAI,uEAAkC,CAClC,OAAO,EACP,IAAI,CAAC,oCAAoC,EACzC,gBAAgB,EAChB,uBAAuB,CAC1B;aACJ;SACJ,CAAC,CAAA;IACN,CAAC;AACL,CAAC;AA3CY,8BAAsB,yBA2ClC,CAAA"} \ No newline at end of file diff --git a/src/node-groups/UnicodeArrayNodesGroup.ts b/src/node-groups/UnicodeArrayNodesGroup.ts new file mode 100644 index 00000000..39dd6290 --- /dev/null +++ b/src/node-groups/UnicodeArrayNodesGroup.ts @@ -0,0 +1,52 @@ +import { INode } from '../interfaces/INode'; + +import { NodesGroup } from './NodesGroup'; +import { UnicodeArrayNode } from '../nodes/UnicodeArrayNode'; +import { UnicodeArrayRotateFunctionCallNode } from '../nodes/UnicodeArrayRotateFunctionCallNode'; +import { UnicodeArrayRotateFunctionNode } from '../nodes/UnicodeArrayRotateFunctionNode'; +import { Utils } from '../Utils'; + +export class UnicodeArrayNodesGroup extends NodesGroup { + /** + * @type {string} + */ + private unicodeArrayRotateFunctionIdentifier: string = Utils.getRandomVariableName(); + + /** + * @param astTree + */ + constructor (astTree: any) { + super(); + + let unicodeArrayName: string = Utils.getRandomVariableName(UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH), + unicodeArrayRotateValue: number = Utils.getRandomInteger(100, 500); + + this.nodes = new Map ([ + [ + 'unicodeArrayNode', + new UnicodeArrayNode( + astTree, + unicodeArrayName, + unicodeArrayRotateValue + ) + ], + [ + 'unicodeArrayRotateFunctionNode', + new UnicodeArrayRotateFunctionNode( + astTree, + this.unicodeArrayRotateFunctionIdentifier, + unicodeArrayName + ) + ], + [ + 'unicodeArrayRotateFunctionCallNode', + new UnicodeArrayRotateFunctionCallNode( + astTree, + this.unicodeArrayRotateFunctionIdentifier, + unicodeArrayName, + unicodeArrayRotateValue + ) + ] + ]) + } +} \ No newline at end of file diff --git a/src/node-obfuscators/FunctionDeclarationObfuscator.js b/src/node-obfuscators/FunctionDeclarationObfuscator.js new file mode 100644 index 00000000..24c523d0 --- /dev/null +++ b/src/node-obfuscators/FunctionDeclarationObfuscator.js @@ -0,0 +1,37 @@ +"use strict"; +const NodeObfuscator_1 = require('./NodeObfuscator'); +const Utils_1 = require('../Utils'); +let estraverse = require('estraverse'); +class FunctionDeclarationObfuscator extends NodeObfuscator_1.NodeObfuscator { + constructor(...args) { + super(...args); + this.functionName = new Map(); + } + obfuscateNode(functionDeclarationNode, parentNode) { + if (parentNode.type === 'Program') { + return; + } + this.replaceFunctionName(functionDeclarationNode); + this.replaceFunctionCalls(parentNode); + } + replaceFunctionName(functionDeclarationNode) { + estraverse.replace(functionDeclarationNode.id, { + leave: (node) => { + if (node.type !== 'Identifier') { + return; + } + this.functionName.set(node.name, Utils_1.Utils.getRandomVariableName()); + node.name = this.functionName.get(node.name); + } + }); + } + replaceFunctionCalls(functionParentNode) { + estraverse.replace(functionParentNode, { + leave: (node, parentNode) => { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.functionName); + } + }); + } +} +exports.FunctionDeclarationObfuscator = FunctionDeclarationObfuscator; +//# sourceMappingURL=FunctionDeclarationObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/FunctionDeclarationObfuscator.js.map b/src/node-obfuscators/FunctionDeclarationObfuscator.js.map new file mode 100644 index 00000000..0b01989a --- /dev/null +++ b/src/node-obfuscators/FunctionDeclarationObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FunctionDeclarationObfuscator.js","sourceRoot":"","sources":["FunctionDeclarationObfuscator.ts"],"names":[],"mappings":";AAAA,iCAA+B,kBAAkB,CAAC,CAAA;AAClD,wBAAsB,UAAU,CAAC,CAAA;AAEjC,IAAI,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAWvC,4CAAmD,+BAAc;IAAjE;QAAmD,eAAc;QAIrD,iBAAY,GAAyB,IAAI,GAAG,EAAoB,CAAC;IAyC7E,CAAC;IAnCU,aAAa,CAAE,uBAA4B,EAAE,UAAe;QAC/D,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC;QACX,CAAC;QAED,IAAI,CAAC,mBAAmB,CAAC,uBAAuB,CAAC,CAAC;QAClD,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAKO,mBAAmB,CAAE,uBAA4B;QACrD,UAAU,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,EAAE;YAC3C,KAAK,EAAE,CAAC,IAAI;gBACR,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC;oBAC7B,MAAM,CAAC;gBACX,CAAC;gBAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,aAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;gBAChE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAKO,oBAAoB,CAAE,kBAAuB;QACjD,UAAU,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACnC,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU;gBACpB,IAAI,CAAC,+BAA+B,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9E,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;AACL,CAAC;AA7CY,qCAA6B,gCA6CzC,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/FunctionDeclarationObfuscator.ts b/src/node-obfuscators/FunctionDeclarationObfuscator.ts new file mode 100644 index 00000000..4a3983ef --- /dev/null +++ b/src/node-obfuscators/FunctionDeclarationObfuscator.ts @@ -0,0 +1,60 @@ +import { NodeObfuscator } from './NodeObfuscator'; +import { Utils } from '../Utils'; + +let estraverse = require('estraverse'); + +/** + * replaces: + * function foo () { //... }; + * foo(); + * + * by: + * function _0x12d45f () { //... }; + * _0x12d45f(); + */ +export class FunctionDeclarationObfuscator extends NodeObfuscator { + /** + * @type {Map} + */ + private functionName: Map = new Map (); + + /** + * @param functionDeclarationNode + * @param parentNode + */ + public obfuscateNode (functionDeclarationNode: any, parentNode: any): void { + if (parentNode.type === 'Program') { + return; + } + + this.replaceFunctionName(functionDeclarationNode); + this.replaceFunctionCalls(parentNode); + } + + /** + * @param functionDeclarationNode + */ + private replaceFunctionName (functionDeclarationNode: any): void { + estraverse.replace(functionDeclarationNode.id, { + leave: (node) => { + if (node.type !== 'Identifier') { + return; + } + + this.functionName.set(node.name, Utils.getRandomVariableName()); + node.name = this.functionName.get(node.name); + } + }); + } + + /** + * @param functionParentNode + */ + private replaceFunctionCalls (functionParentNode: any): void { + estraverse.replace(functionParentNode, { + leave: (node, parentNode) => { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.functionName); + } + }); + } +} \ No newline at end of file diff --git a/src/node-obfuscators/FunctionObfuscator.js b/src/node-obfuscators/FunctionObfuscator.js new file mode 100644 index 00000000..be2b4155 --- /dev/null +++ b/src/node-obfuscators/FunctionObfuscator.js @@ -0,0 +1,36 @@ +"use strict"; +const NodeObfuscator_1 = require('./NodeObfuscator'); +const Utils_1 = require('../Utils'); +let estraverse = require('estraverse'); +class FunctionObfuscator extends NodeObfuscator_1.NodeObfuscator { + constructor(...args) { + super(...args); + this.functionParams = new Map(); + } + obfuscateNode(functionNode) { + this.replaceFunctionParams(functionNode); + this.replaceFunctionParamsInBody(functionNode); + } + replaceFunctionParams(functionNode) { + functionNode.params.forEach((paramsNode) => { + estraverse.replace(paramsNode, { + leave: (node, parentNode) => { + if (node.type !== 'Identifier') { + return; + } + this.functionParams.set(node.name, Utils_1.Utils.getRandomVariableName()); + node.name = this.functionParams.get(node.name); + } + }); + }); + } + replaceFunctionParamsInBody(functionNode) { + estraverse.replace(functionNode.body, { + leave: (node, parentNode) => { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.functionParams); + } + }); + } +} +exports.FunctionObfuscator = FunctionObfuscator; +//# sourceMappingURL=FunctionObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/FunctionObfuscator.js.map b/src/node-obfuscators/FunctionObfuscator.js.map new file mode 100644 index 00000000..7f32952d --- /dev/null +++ b/src/node-obfuscators/FunctionObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FunctionObfuscator.js","sourceRoot":"","sources":["FunctionObfuscator.ts"],"names":[],"mappings":";AAAA,iCAA+B,kBAAkB,CAAC,CAAA;AAClD,wBAAsB,UAAU,CAAC,CAAA;AAEjC,IAAI,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAUvC,iCAAwC,+BAAc;IAAtD;QAAwC,eAAc;QAI1C,mBAAc,GAAyB,IAAI,GAAG,EAAoB,CAAC;IAsC/E,CAAC;IAjCU,aAAa,CAAE,YAAiB;QACnC,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC;QACzC,IAAI,CAAC,2BAA2B,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC;IAKO,qBAAqB,CAAE,YAAiB;QAC5C,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU;YACnC,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE;gBAC3B,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU;oBACpB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC;wBAC9B,MAAM,CAAC;oBACV,CAAC;oBAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,aAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;oBAClE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnD,CAAC;aACJ,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAKO,2BAA2B,CAAE,YAAiB;QAClD,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE;YAClC,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU;gBACpB,IAAI,CAAC,+BAA+B,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAChF,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;AACL,CAAC;AA1CY,0BAAkB,qBA0C9B,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/FunctionObfuscator.ts b/src/node-obfuscators/FunctionObfuscator.ts new file mode 100644 index 00000000..6538bece --- /dev/null +++ b/src/node-obfuscators/FunctionObfuscator.ts @@ -0,0 +1,56 @@ +import { NodeObfuscator } from './NodeObfuscator'; +import { Utils } from '../Utils'; + +let estraverse = require('estraverse'); + +/** + * replaces: + * function foo (argument1) { return argument1; }; + * + * by: + * function foo (_0x12d45f) { return _0x12d45f; }; + * + */ +export class FunctionObfuscator extends NodeObfuscator { + /** + * @type {Map} + */ + private functionParams: Map = new Map (); + + /** + * @param functionNode + */ + public obfuscateNode (functionNode: any): void { + this.replaceFunctionParams(functionNode); + this.replaceFunctionParamsInBody(functionNode); + } + + /** + * @param functionNode + */ + private replaceFunctionParams (functionNode: any): void { + functionNode.params.forEach((paramsNode) => { + estraverse.replace(paramsNode, { + leave: (node, parentNode) => { + if (node.type !== 'Identifier') { + return; + } + + this.functionParams.set(node.name, Utils.getRandomVariableName()); + node.name = this.functionParams.get(node.name); + } + }); + }); + } + + /** + * @param functionNode + */ + private replaceFunctionParamsInBody (functionNode: any): void { + estraverse.replace(functionNode.body, { + leave: (node, parentNode) => { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.functionParams); + } + }); + } +} \ No newline at end of file diff --git a/src/node-obfuscators/LiteralObfuscator.js b/src/node-obfuscators/LiteralObfuscator.js new file mode 100644 index 00000000..fd4fc1e3 --- /dev/null +++ b/src/node-obfuscators/LiteralObfuscator.js @@ -0,0 +1,23 @@ +"use strict"; +const NodeObfuscator_1 = require('./NodeObfuscator'); +let escodegen = require('escodegen'), estraverse = require('estraverse'); +class LiteralObfuscator extends NodeObfuscator_1.NodeObfuscator { + obfuscateNode(literalNode, parentNode) { + if (parentNode.type === 'Property' && parentNode.key === literalNode) { + return; + } + switch (typeof literalNode.value) { + case 'string': + if (literalNode['x-verbatim-property']) { + break; + } + literalNode['x-verbatim-property'] = { + content: this.replaceLiteralStringByArrayElement(literalNode.value), + precedence: escodegen.Precedence.Primary + }; + break; + } + } +} +exports.LiteralObfuscator = LiteralObfuscator; +//# sourceMappingURL=LiteralObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/LiteralObfuscator.js.map b/src/node-obfuscators/LiteralObfuscator.js.map new file mode 100644 index 00000000..ffa02a5e --- /dev/null +++ b/src/node-obfuscators/LiteralObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"LiteralObfuscator.js","sourceRoot":"","sources":["LiteralObfuscator.ts"],"names":[],"mappings":";AAAA,iCAA+B,kBAE/B,CAAC,CAFgD;AAEjD,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,EAChC,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAEvC,gCAAuC,+BAAc;IAK1C,aAAa,CAAE,WAAgB,EAAE,UAAe;QACnD,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,KAAK,UAAU,IAAI,UAAU,CAAC,GAAG,KAAK,WAAW,CAAC,CAAC,CAAC;YACnE,MAAM,CAAC;QACX,CAAC;QAED,MAAM,CAAC,CAAC,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/B,KAAK,QAAQ;gBACT,EAAE,CAAC,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;oBACrC,KAAK,CAAC;gBACV,CAAC;gBAED,WAAW,CAAC,qBAAqB,CAAC,GAAG;oBACjC,OAAO,EAAG,IAAI,CAAC,kCAAkC,CAAC,WAAW,CAAC,KAAK,CAAC;oBACpE,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,OAAO;iBAC3C,CAAC;gBAEF,KAAK,CAAC;QACd,CAAC;IACL,CAAC;AACL,CAAC;AAxBY,yBAAiB,oBAwB7B,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/LiteralObfuscator.ts b/src/node-obfuscators/LiteralObfuscator.ts new file mode 100644 index 00000000..9dc904a9 --- /dev/null +++ b/src/node-obfuscators/LiteralObfuscator.ts @@ -0,0 +1,30 @@ +import { NodeObfuscator } from './NodeObfuscator' + +let escodegen = require('escodegen'), + estraverse = require('estraverse'); + +export class LiteralObfuscator extends NodeObfuscator { + /** + * @param literalNode + * @param parentNode + */ + public obfuscateNode (literalNode: any, parentNode: any): void { + if (parentNode.type === 'Property' && parentNode.key === literalNode) { + return; + } + + switch (typeof literalNode.value) { + case 'string': + if (literalNode['x-verbatim-property']) { + break; + } + + literalNode['x-verbatim-property'] = { + content : this.replaceLiteralStringByArrayElement(literalNode.value), + precedence: escodegen.Precedence.Primary + }; + + break; + } + } +} \ No newline at end of file diff --git a/src/node-obfuscators/MemberExpressionObfuscator.js b/src/node-obfuscators/MemberExpressionObfuscator.js new file mode 100644 index 00000000..54986032 --- /dev/null +++ b/src/node-obfuscators/MemberExpressionObfuscator.js @@ -0,0 +1,49 @@ +"use strict"; +const NodeObfuscator_1 = require('./NodeObfuscator'); +let escodegen = require('escodegen'), estraverse = require('estraverse'); +class MemberExpressionObfuscator extends NodeObfuscator_1.NodeObfuscator { + obfuscateNode(memberExpressionNode) { + estraverse.replace(memberExpressionNode.property, { + leave: (node, parentNode) => { + switch (node.type) { + case 'Literal': + this.literalNodeController(node); + break; + case 'Identifier': + if (memberExpressionNode.computed) { + break; + } + memberExpressionNode.computed = true; + this.identifierNodeController(node); + break; + } + } + }); + } + identifierNodeController(node) { + let nodeValue = node['name']; + node['type'] = 'Literal'; + node['value'] = nodeValue; + node['raw'] = `'${nodeValue}'`; + node['x-verbatim-property'] = { + content: this.replaceLiteralStringByArrayElement(nodeValue), + precedence: escodegen['Precedence']['Primary'] + }; + delete node['name']; + } + literalNodeController(node) { + switch (typeof node.value) { + case 'string': + if (node['x-verbatim-property']) { + break; + } + node['x-verbatim-property'] = { + content: this.replaceLiteralStringByArrayElement(node.value), + precedence: escodegen['Precedence']['Primary'] + }; + break; + } + } +} +exports.MemberExpressionObfuscator = MemberExpressionObfuscator; +//# sourceMappingURL=MemberExpressionObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/MemberExpressionObfuscator.js.map b/src/node-obfuscators/MemberExpressionObfuscator.js.map new file mode 100644 index 00000000..1d85efa5 --- /dev/null +++ b/src/node-obfuscators/MemberExpressionObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MemberExpressionObfuscator.js","sourceRoot":"","sources":["MemberExpressionObfuscator.ts"],"names":[],"mappings":";AAAA,iCAA+B,kBAE/B,CAAC,CAFgD;AAEjD,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,EAChC,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAEvC,yCAAgD,+BAAc;IAInD,aAAa,CAAE,oBAAyB;QAC3C,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,EAAE;YAC9C,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU;gBACpB,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;oBAChB,KAAK,SAAS;wBACV,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;wBAEjC,KAAK,CAAC;oBAEV,KAAK,YAAY;wBACb,EAAE,CAAC,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;4BAChC,KAAK,CAAC;wBACV,CAAC;wBAED,oBAAoB,CAAC,QAAQ,GAAG,IAAI,CAAC;wBACrC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;wBAEpC,KAAK,CAAC;gBACd,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAcO,wBAAwB,CAAE,IAAS;QACvC,IAAI,SAAS,GAAW,IAAI,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,SAAS,GAAG,CAAC;QAC/B,IAAI,CAAC,qBAAqB,CAAC,GAAG;YAC1B,OAAO,EAAG,IAAI,CAAC,kCAAkC,CAAC,SAAS,CAAC;YAC5D,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC;SACjD,CAAC;QAEF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAWO,qBAAqB,CAAE,IAAS;QACpC,MAAM,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACxB,KAAK,QAAQ;gBACT,EAAE,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;oBAC9B,KAAK,CAAC;gBACV,CAAC;gBAED,IAAI,CAAC,qBAAqB,CAAC,GAAG;oBAC1B,OAAO,EAAG,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC;oBAC7D,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC;iBACjD,CAAC;gBAEF,KAAK,CAAC;QACd,CAAC;IACL,CAAC;AACL,CAAC;AA7EY,kCAA0B,6BA6EtC,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/MemberExpressionObfuscator.ts b/src/node-obfuscators/MemberExpressionObfuscator.ts new file mode 100644 index 00000000..b392f84f --- /dev/null +++ b/src/node-obfuscators/MemberExpressionObfuscator.ts @@ -0,0 +1,83 @@ +import { NodeObfuscator } from './NodeObfuscator' + +let escodegen = require('escodegen'), + estraverse = require('estraverse'); + +export class MemberExpressionObfuscator extends NodeObfuscator { + /** + * @param memberExpressionNode + */ + public obfuscateNode (memberExpressionNode: any): void { + estraverse.replace(memberExpressionNode.property, { + leave: (node, parentNode) => { + switch (node.type) { + case 'Literal': + this.literalNodeController(node); + + break; + + case 'Identifier': + if (memberExpressionNode.computed) { + break; + } + + memberExpressionNode.computed = true; + this.identifierNodeController(node); + + break; + } + } + }); + } + + /** + * replaces: + * object.identifier = 1; + * + * by: + * object[_0x23d45[25]] = 1; + * + * and skip: + * object[identifier] = 1; + * + * @param node + */ + private identifierNodeController (node: any): void { + let nodeValue: string = node['name']; + + node['type'] = 'Literal'; + node['value'] = nodeValue; + node['raw'] = `'${nodeValue}'`; + node['x-verbatim-property'] = { + content : this.replaceLiteralStringByArrayElement(nodeValue), + precedence: escodegen['Precedence']['Primary'] + }; + + delete node['name']; + } + + /** + * replaces: + * object['literal'] = 1; + * + * by: + * object[_0x23d45[25]] = 1; + * + * @param node + */ + private literalNodeController (node: any): void { + switch (typeof node.value) { + case 'string': + if (node['x-verbatim-property']) { + break; + } + + node['x-verbatim-property'] = { + content : this.replaceLiteralStringByArrayElement(node.value), + precedence: escodegen['Precedence']['Primary'] + }; + + break; + } + } +} \ No newline at end of file diff --git a/src/node-obfuscators/MethodDefinitionObfuscator.js b/src/node-obfuscators/MethodDefinitionObfuscator.js new file mode 100644 index 00000000..2a0a4b97 --- /dev/null +++ b/src/node-obfuscators/MethodDefinitionObfuscator.js @@ -0,0 +1,28 @@ +"use strict"; +const NodeObfuscator_1 = require('./NodeObfuscator'); +let estraverse = require('estraverse'); +class MethodDefinitionObfuscator extends NodeObfuscator_1.NodeObfuscator { + constructor(...args) { + super(...args); + this.methodName = new Map(); + this.ignoredNames = ['constructor']; + } + obfuscateNode(methodDefinitionNode, parentNode) { + this.replaceMethodName(methodDefinitionNode); + } + replaceMethodName(methodDefinitionNode) { + estraverse.replace(methodDefinitionNode.key, { + leave: (node) => { + if (node.type !== 'Identifier' || + this.ignoredNames.indexOf(node.name) >= 0 || + methodDefinitionNode.computed === true) { + return; + } + methodDefinitionNode.computed = true; + node.name = this.replaceLiteralStringByArrayElement(node.name); + } + }); + } +} +exports.MethodDefinitionObfuscator = MethodDefinitionObfuscator; +//# sourceMappingURL=MethodDefinitionObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/MethodDefinitionObfuscator.js.map b/src/node-obfuscators/MethodDefinitionObfuscator.js.map new file mode 100644 index 00000000..721e05ec --- /dev/null +++ b/src/node-obfuscators/MethodDefinitionObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MethodDefinitionObfuscator.js","sourceRoot":"","sources":["MethodDefinitionObfuscator.ts"],"names":[],"mappings":";AAAA,iCAA+B,kBAAkB,CAAC,CAAA;AAGlD,IAAI,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAWvC,yCAAgD,+BAAc;IAA9D;QAAgD,eAAc;QAIlD,eAAU,GAAyB,IAAI,GAAG,EAAoB,CAAC;QAK/D,iBAAY,GAAa,CAAC,aAAa,CAAC,CAAC;IA6BrD,CAAC;IAvBU,aAAa,CAAE,oBAAyB,EAAE,UAAe;QAC5D,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;IACjD,CAAC;IAKO,iBAAiB,CAAE,oBAAyB;QAChD,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAC,GAAG,EAAE;YACzC,KAAK,EAAE,CAAC,IAAI;gBACR,EAAE,CAAC,CACC,IAAI,CAAC,IAAI,KAAK,YAAY;oBAC1B,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;oBACzC,oBAAoB,CAAC,QAAQ,KAAK,IACtC,CAAC,CAAC,CAAC;oBACC,MAAM,CAAC;gBACX,CAAC;gBAED,oBAAoB,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnE,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;AACL,CAAC;AAtCY,kCAA0B,6BAsCtC,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/MethodDefinitionObfuscator.ts b/src/node-obfuscators/MethodDefinitionObfuscator.ts new file mode 100644 index 00000000..7a96a40c --- /dev/null +++ b/src/node-obfuscators/MethodDefinitionObfuscator.ts @@ -0,0 +1,53 @@ +import { NodeObfuscator } from './NodeObfuscator'; +import { Utils } from '../Utils'; + +let estraverse = require('estraverse'); + +/** + * replaces: + * function foo () { //... }; + * foo(); + * + * by: + * function _0x12d45f () { //... }; + * _0x12d45f(); + */ +export class MethodDefinitionObfuscator extends NodeObfuscator { + /** + * @type {Map} + */ + private methodName: Map = new Map (); + + /** + * @type {string[]} + */ + private ignoredNames: string[] = ['constructor']; + + /** + * @param methodDefinitionNode + * @param parentNode + */ + public obfuscateNode (methodDefinitionNode: any, parentNode: any): void { + this.replaceMethodName(methodDefinitionNode); + } + + /** + * @param methodDefinitionNode + */ + private replaceMethodName (methodDefinitionNode: any): void { + estraverse.replace(methodDefinitionNode.key, { + leave: (node) => { + if ( + node.type !== 'Identifier' || + this.ignoredNames.indexOf(node.name) >= 0 || + methodDefinitionNode.computed === true + ) { + return; + } + + methodDefinitionNode.computed = true; + node.name = this.replaceLiteralStringByArrayElement(node.name); + } + }); + } +} \ No newline at end of file diff --git a/src/node-obfuscators/NodeObfuscator.js b/src/node-obfuscators/NodeObfuscator.js new file mode 100644 index 00000000..8f517528 --- /dev/null +++ b/src/node-obfuscators/NodeObfuscator.js @@ -0,0 +1,29 @@ +"use strict"; +const Utils_1 = require('../Utils'); +class NodeObfuscator { + constructor(nodes) { + this.nodes = nodes; + } + replaceNodeIdentifierByNewValue(node, parentNode, namesMap) { + if (node.type === 'Identifier' && namesMap.has(node.name)) { + if ((parentNode.type === 'Property' && parentNode.key === node) || + (parentNode.type === 'MemberExpression' && parentNode.computed === false && parentNode.property === node)) { + return; + } + node.name = namesMap.get(node.name); + } + } + replaceLiteralStringByArrayElement(nodeValue) { + let value = Utils_1.Utils.stringToUnicode(nodeValue), unicodeArray = this.nodes.get('unicodeArrayNode').getNodeData(), sameIndex = unicodeArray.indexOf(value), index; + if (sameIndex < 0) { + index = unicodeArray.length; + unicodeArray.push(Utils_1.Utils.stringToUnicode(nodeValue)); + } + else { + index = sameIndex; + } + return `${this.nodes.get('unicodeArrayNode').getNodeIdentifier()}[${index}]`; + } +} +exports.NodeObfuscator = NodeObfuscator; +//# sourceMappingURL=NodeObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/NodeObfuscator.js.map b/src/node-obfuscators/NodeObfuscator.js.map new file mode 100644 index 00000000..9ac6a017 --- /dev/null +++ b/src/node-obfuscators/NodeObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NodeObfuscator.js","sourceRoot":"","sources":["NodeObfuscator.ts"],"names":[],"mappings":";AAIA,wBAAsB,UAAU,CAAC,CAAA;AAEjC;IASI,YAAY,KAA0B;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IAaS,+BAA+B,CAAE,IAAS,EAAE,UAAe,EAAE,QAA8B;QACjG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACxD,EAAE,CAAC,CACC,CAAC,UAAU,CAAC,IAAI,KAAK,UAAU,IAAI,UAAU,CAAC,GAAG,KAAK,IAAI,CAAC;gBAC3D,CAAC,UAAU,CAAC,IAAI,KAAK,kBAAkB,IAAI,UAAU,CAAC,QAAQ,KAAK,KAAK,IAAI,UAAU,CAAC,QAAQ,KAAK,IAAI,CAC5G,CAAC,CAAC,CAAC;gBACC,MAAM,CAAC;YACX,CAAC;YAED,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IAMS,kCAAkC,CAAE,SAAiB;QAC3D,IAAI,KAAK,GAAW,aAAK,CAAC,eAAe,CAAC,SAAS,CAAC,EAChD,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,WAAW,EAAE,EAC/D,SAAS,GAAW,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,EAC/C,KAAa,CAAC;QAElB,EAAE,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;YAChB,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC;YAC5B,YAAY,CAAC,IAAI,CAAC,aAAK,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;QACxD,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,KAAK,GAAG,SAAS,CAAC;QACtB,CAAC;QAED,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,EAAE,IAAI,KAAK,GAAG,CAAC;IACjF,CAAC;AACL,CAAC;AAxDqB,sBAAc,iBAwDnC,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/NodeObfuscator.ts b/src/node-obfuscators/NodeObfuscator.ts new file mode 100644 index 00000000..7b05ecdb --- /dev/null +++ b/src/node-obfuscators/NodeObfuscator.ts @@ -0,0 +1,63 @@ +import { INode } from '../interfaces/INode'; +import { INodeObfuscator } from '../interfaces/INodeObfuscator'; + +import { UnicodeArrayNode } from '../nodes/UnicodeArrayNode'; +import { Utils } from '../Utils'; + +export abstract class NodeObfuscator implements INodeObfuscator { + /** + * @param Map + */ + protected nodes: Map ; + + /** + * @param nodes + */ + constructor(nodes: Map ) { + this.nodes = nodes; + } + + /** + * @param node + * @param parentNode + */ + public abstract obfuscateNode (node: any, parentNode?: any): void; + + /** + * @param node + * @param parentNode + * @param namesMap + */ + protected replaceNodeIdentifierByNewValue (node: any, parentNode: any, namesMap: Map ) { + if (node.type === 'Identifier' && namesMap.has(node.name)) { + if ( + (parentNode.type === 'Property' && parentNode.key === node) || + (parentNode.type === 'MemberExpression' && parentNode.computed === false && parentNode.property === node) + ) { + return; + } + + node.name = namesMap.get(node.name); + } + } + + /** + * @param nodeValue + * @returns {string} + */ + protected replaceLiteralStringByArrayElement (nodeValue: string): string { + let value: string = Utils.stringToUnicode(nodeValue), + unicodeArray = this.nodes.get('unicodeArrayNode').getNodeData(), + sameIndex: number = unicodeArray.indexOf(value), + index: number; + + if (sameIndex < 0) { + index = unicodeArray.length; + unicodeArray.push(Utils.stringToUnicode(nodeValue)); + } else { + index = sameIndex; + } + + return `${this.nodes.get('unicodeArrayNode').getNodeIdentifier()}[${index}]`; + } +} \ No newline at end of file diff --git a/src/node-obfuscators/ObjectExpressionObfuscator.js b/src/node-obfuscators/ObjectExpressionObfuscator.js new file mode 100644 index 00000000..29e1e8c2 --- /dev/null +++ b/src/node-obfuscators/ObjectExpressionObfuscator.js @@ -0,0 +1,48 @@ +"use strict"; +const NodeObfuscator_1 = require('./NodeObfuscator'); +const Utils_1 = require('../Utils'); +let escodegen = require('escodegen'), estraverse = require('estraverse'); +class ObjectExpressionObfuscator extends NodeObfuscator_1.NodeObfuscator { + obfuscateNode(objectExpressionNode) { + objectExpressionNode.properties.forEach((property) => { + estraverse.replace(property.key, { + leave: (node, parentNode) => { + switch (node.type) { + case 'Literal': + this.literalNodeController(node); + break; + case 'Identifier': + this.identifierNodeController(node); + break; + } + } + }); + }); + } + literalNodeController(node) { + switch (typeof node.value) { + case 'string': + if (node['x-verbatim-property']) { + break; + } + node['x-verbatim-property'] = { + content: Utils_1.Utils.stringToUnicode(node.value), + precedence: escodegen['Precedence']['Primary'] + }; + break; + } + } + identifierNodeController(node) { + let nodeValue = node['name']; + node['type'] = 'Literal'; + node['value'] = nodeValue; + node['raw'] = `'${nodeValue}'`; + node['x-verbatim-property'] = { + content: Utils_1.Utils.stringToUnicode(nodeValue), + precedence: escodegen['Precedence']['Primary'] + }; + delete node['name']; + } +} +exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator; +//# sourceMappingURL=ObjectExpressionObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/ObjectExpressionObfuscator.js.map b/src/node-obfuscators/ObjectExpressionObfuscator.js.map new file mode 100644 index 00000000..f8b8722c --- /dev/null +++ b/src/node-obfuscators/ObjectExpressionObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ObjectExpressionObfuscator.js","sourceRoot":"","sources":["ObjectExpressionObfuscator.ts"],"names":[],"mappings":";AAAA,iCAA+B,kBAC/B,CAAC,CADgD;AACjD,wBAAsB,UAAU,CAAC,CAAA;AAEjC,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,EAChC,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAYvC,yCAAgD,+BAAc;IAInD,aAAa,CAAE,oBAAyB;QAC3C,oBAAoB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ;YAC7C,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE;gBAC7B,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU;oBACpB,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;wBAChB,KAAK,SAAS;4BACV,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;4BAEjC,KAAK,CAAC;wBAEV,KAAK,YAAY;4BACb,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;4BAEpC,KAAK,CAAC;oBACd,CAAC;gBACL,CAAC;aACJ,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAKO,qBAAqB,CAAE,IAAS;QACpC,MAAM,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACxB,KAAK,QAAQ;gBACT,EAAE,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;oBAC9B,KAAK,CAAC;gBACV,CAAC;gBAED,IAAI,CAAC,qBAAqB,CAAC,GAAG;oBAC1B,OAAO,EAAG,aAAK,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;oBAC3C,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC;iBACjD,CAAC;gBAEF,KAAK,CAAC;QACd,CAAC;IACL,CAAC;IAKO,wBAAwB,CAAE,IAAS;QACvC,IAAI,SAAS,GAAW,IAAI,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,SAAS,GAAG,CAAC;QAC/B,IAAI,CAAC,qBAAqB,CAAC,GAAG;YAC1B,OAAO,EAAG,aAAK,CAAC,eAAe,CAAC,SAAS,CAAC;YAC1C,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC;SACjD,CAAC;QAEF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;AACL,CAAC;AA3DY,kCAA0B,6BA2DtC,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/ObjectExpressionObfuscator.ts b/src/node-obfuscators/ObjectExpressionObfuscator.ts new file mode 100644 index 00000000..4a798c2a --- /dev/null +++ b/src/node-obfuscators/ObjectExpressionObfuscator.ts @@ -0,0 +1,76 @@ +import { NodeObfuscator } from './NodeObfuscator' +import { Utils } from '../Utils'; + +let escodegen = require('escodegen'), + estraverse = require('estraverse'); + +/** + * replaces: + * var object = { 'PSEUDO': 1 }; + * + * or: + * var object = { PSEUDO: 1 }; + * + * by: + * var object = { '\u0050\u0053\u0045\u0055\u0044\u004f': 1 }; + */ +export class ObjectExpressionObfuscator extends NodeObfuscator { + /** + * @param objectExpressionNode + */ + public obfuscateNode (objectExpressionNode: any): void { + objectExpressionNode.properties.forEach((property) => { + estraverse.replace(property.key, { + leave: (node, parentNode) => { + switch (node.type) { + case 'Literal': + this.literalNodeController(node); + + break; + + case 'Identifier': + this.identifierNodeController(node); + + break; + } + } + }); + }); + } + + /** + * @param node + */ + private literalNodeController (node: any): void { + switch (typeof node.value) { + case 'string': + if (node['x-verbatim-property']) { + break; + } + + node['x-verbatim-property'] = { + content : Utils.stringToUnicode(node.value), + precedence: escodegen['Precedence']['Primary'] + }; + + break; + } + } + + /** + * @param node + */ + private identifierNodeController (node: any): void { + let nodeValue: string = node['name']; + + node['type'] = 'Literal'; + node['value'] = nodeValue; + node['raw'] = `'${nodeValue}'`; + node['x-verbatim-property'] = { + content : Utils.stringToUnicode(nodeValue), + precedence: escodegen['Precedence']['Primary'] + }; + + delete node['name']; + } +} \ No newline at end of file diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.js b/src/node-obfuscators/VariableDeclarationObfuscator.js new file mode 100644 index 00000000..6adc67e9 --- /dev/null +++ b/src/node-obfuscators/VariableDeclarationObfuscator.js @@ -0,0 +1,43 @@ +"use strict"; +const NodeObfuscator_1 = require('./NodeObfuscator'); +const Utils_1 = require('../Utils'); +let estraverse = require('estraverse'); +class VariableDeclarationObfuscator extends NodeObfuscator_1.NodeObfuscator { + constructor(...args) { + super(...args); + this.variableName = new Map(); + } + obfuscateNode(variableDeclarationNode, parentNode) { + if (parentNode.type === 'Program') { + return; + } + this.replaceVariableName(variableDeclarationNode); + this.replaceVariableCalls(parentNode); + } + replaceVariableName(variableDeclarationNode) { + variableDeclarationNode.declarations.forEach((declarationNode) => { + estraverse.replace(declarationNode, { + leave: (node) => { + if (node.type !== 'VariableDeclarator') { + return; + } + estraverse.replace(node.id, { + leave: (node) => { + this.variableName.set(node.name, Utils_1.Utils.getRandomVariableName()); + node.name = this.variableName.get(node.name); + } + }); + } + }); + }); + } + replaceVariableCalls(variableParentNode) { + estraverse.replace(variableParentNode, { + leave: (node, parentNode) => { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableName); + } + }); + } +} +exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator; +//# sourceMappingURL=VariableDeclarationObfuscator.js.map \ No newline at end of file diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.js.map b/src/node-obfuscators/VariableDeclarationObfuscator.js.map new file mode 100644 index 00000000..092937eb --- /dev/null +++ b/src/node-obfuscators/VariableDeclarationObfuscator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"VariableDeclarationObfuscator.js","sourceRoot":"","sources":["VariableDeclarationObfuscator.ts"],"names":[],"mappings":";AAAA,iCAA+B,kBAAkB,CAAC,CAAA;AAClD,wBAAsB,UAAU,CAAC,CAAA;AAEjC,IAAI,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAYvC,4CAAmD,+BAAc;IAAjE;QAAmD,eAAc;QAIrD,iBAAY,GAAyB,IAAI,GAAG,EAAoB,CAAC;IA+C7E,CAAC;IAzCU,aAAa,CAAE,uBAA4B,EAAE,UAAe;QAC/D,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC;QACX,CAAC;QAED,IAAI,CAAC,mBAAmB,CAAC,uBAAuB,CAAC,CAAC;QAClD,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAKO,mBAAmB,CAAE,uBAA4B;QACrD,uBAAuB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,eAAe;YACzD,UAAU,CAAC,OAAO,CAAC,eAAe,EAAE;gBAChC,KAAK,EAAE,CAAC,IAAI;oBACR,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAoB,CAAC,CAAC,CAAC;wBACrC,MAAM,CAAC;oBACX,CAAC;oBAED,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE;wBACxB,KAAK,EAAE,CAAC,IAAI;4BACR,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,aAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC;4BAChE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACjD,CAAC;qBACJ,CAAC,CAAC;gBACP,CAAC;aACJ,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAKO,oBAAoB,CAAE,kBAAuB;QACjD,UAAU,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACnC,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU;gBACpB,IAAI,CAAC,+BAA+B,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9E,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;AACL,CAAC;AAnDY,qCAA6B,gCAmDzC,CAAA"} \ No newline at end of file diff --git a/src/node-obfuscators/VariableDeclarationObfuscator.ts b/src/node-obfuscators/VariableDeclarationObfuscator.ts new file mode 100644 index 00000000..936d66aa --- /dev/null +++ b/src/node-obfuscators/VariableDeclarationObfuscator.ts @@ -0,0 +1,67 @@ +import { NodeObfuscator } from './NodeObfuscator'; +import { Utils } from '../Utils'; + +let estraverse = require('estraverse'); + +/** + * replaces: + * var variable = 1; + * variable++; + * + * by: + * var _0x12d45f = 1; + * _0x12d45f++; + * + */ +export class VariableDeclarationObfuscator extends NodeObfuscator { + /** + * @type {Map} + */ + private variableName: Map = new Map (); + + /** + * @param variableDeclarationNode + * @param parentNode + */ + public obfuscateNode (variableDeclarationNode: any, parentNode: any): void { + if (parentNode.type === 'Program') { + return; + } + + this.replaceVariableName(variableDeclarationNode); + this.replaceVariableCalls(parentNode); + } + + /** + * @param variableDeclarationNode + */ + private replaceVariableName (variableDeclarationNode: any): void { + variableDeclarationNode.declarations.forEach((declarationNode) => { + estraverse.replace(declarationNode, { + leave: (node) => { + if (node.type !== 'VariableDeclarator') { + return; + } + + estraverse.replace(node.id, { + leave: (node) => { + this.variableName.set(node.name, Utils.getRandomVariableName()); + node.name = this.variableName.get(node.name); + } + }); + } + }); + }); + } + + /** + * @param variableParentNode + */ + private replaceVariableCalls (variableParentNode: any): void { + estraverse.replace(variableParentNode, { + leave: (node, parentNode) => { + this.replaceNodeIdentifierByNewValue(node, parentNode, this.variableName); + } + }); + } +} \ No newline at end of file diff --git a/src/nodes/Node.js b/src/nodes/Node.js new file mode 100644 index 00000000..8fbba11e --- /dev/null +++ b/src/nodes/Node.js @@ -0,0 +1,21 @@ +"use strict"; +const AppendState_1 = require('../enums/AppendState'); +class Node { + constructor() { + this.appendState = AppendState_1.AppendState.BeforeObfuscation; + } + getAppendState() { + return this.appendState; + } + getNode() { + return this.node; + } + setNode(node) { + this.node = node; + } + updateNode() { + this.node = this.getNodeStructure(); + } +} +exports.Node = Node; +//# sourceMappingURL=Node.js.map \ No newline at end of file diff --git a/src/nodes/Node.js.map b/src/nodes/Node.js.map new file mode 100644 index 00000000..ccb6d7d2 --- /dev/null +++ b/src/nodes/Node.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Node.js","sourceRoot":"","sources":["Node.ts"],"names":[],"mappings":";AAEA,8BAA4B,sBAAsB,CAAC,CAAA;AAEnD;IAWI;QAPU,gBAAW,GAAgB,yBAAW,CAAC,iBAAiB,CAAC;IAOnD,CAAC;IAOV,cAAc;QACjB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;IAKM,OAAO;QACV,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAKM,OAAO,CAAE,IAAS;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IAEM,UAAU;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACxC,CAAC;AAML,CAAC;AA5CqB,YAAI,OA4CzB,CAAA"} \ No newline at end of file diff --git a/src/nodes/Node.ts b/src/nodes/Node.ts new file mode 100644 index 00000000..3050667c --- /dev/null +++ b/src/nodes/Node.ts @@ -0,0 +1,49 @@ +import { INode } from '../interfaces/INode'; + +import { AppendState } from '../enums/AppendState'; + +export abstract class Node implements INode { + /** + * @type {AppendState} + */ + protected appendState: AppendState = AppendState.BeforeObfuscation; + + /** + * @type any + */ + protected node: any; + + constructor () {} + + public abstract appendNode (): void; + + /** + * @returns {AppendState} + */ + public getAppendState (): AppendState { + return this.appendState; + } + + /** + * @returns any + */ + public getNode (): any { + return this.node; + } + + /** + * @param node + */ + public setNode (node: any): void { + this.node = node; + } + + public updateNode (): void { + this.node = this.getNodeStructure(); + } + + /** + * @returns any + */ + protected abstract getNodeStructure (): any; +} diff --git a/src/nodes/UnicodeArrayNode.js b/src/nodes/UnicodeArrayNode.js new file mode 100644 index 00000000..667878cf --- /dev/null +++ b/src/nodes/UnicodeArrayNode.js @@ -0,0 +1,70 @@ +"use strict"; +const Node_1 = require('./Node'); +const Utils_1 = require('../Utils'); +const AppendState_1 = require('../enums/AppendState'); +let escodegen = require('escodegen'), estraverse = require('estraverse'); +class UnicodeArrayNode extends Node_1.Node { + constructor(astTree, unicodeArrayName, unicodeArrayRotateValue = 0) { + super(); + this.appendState = AppendState_1.AppendState.AfterObfuscation; + this.unicodeArray = []; + this.astTree = astTree; + this.unicodeArrayName = unicodeArrayName; + this.unicodeArrayRotateValue = unicodeArrayRotateValue; + this.node = this.getNodeStructure(); + } + appendNode() { + estraverse.replace(this.astTree, { + leave: (node, parent) => { + switch (node.type) { + case 'Program': + node.body.unshift(this.getNode()); + break; + } + } + }); + } + getNodeIdentifier() { + return this.unicodeArrayName; + } + getNodeData() { + return this.unicodeArray; + } + getNode() { + Utils_1.Utils.arrayRotate(this.unicodeArray, this.unicodeArrayRotateValue); + this.updateNode(); + return this.node; + } + getNodeStructure() { + return { + 'type': 'VariableDeclaration', + 'declarations': [ + { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': this.unicodeArrayName + }, + 'init': { + 'type': 'ArrayExpression', + 'elements': this.unicodeArray.map((value) => { + return { + 'type': 'Literal', + 'value': value, + 'raw': `'${value}'`, + 'x-verbatim-property': { + 'content': value, + precedence: escodegen.Precedence.Primary + } + }; + }) + } + } + ], + 'kind': 'var' + }; + } +} +UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH = 4; +exports.UnicodeArrayNode = UnicodeArrayNode; +//# sourceMappingURL=UnicodeArrayNode.js.map \ No newline at end of file diff --git a/src/nodes/UnicodeArrayNode.js.map b/src/nodes/UnicodeArrayNode.js.map new file mode 100644 index 00000000..05eb56ac --- /dev/null +++ b/src/nodes/UnicodeArrayNode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"UnicodeArrayNode.js","sourceRoot":"","sources":["UnicodeArrayNode.ts"],"names":[],"mappings":";AAAA,uBAAqB,QAAQ,CAAC,CAAA;AAC9B,wBAAsB,UAAU,CAAC,CAAA;AAEjC,8BAA4B,sBAAsB,CAAC,CAAA;AAEnD,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,EAChC,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAEvC,+BAAsC,WAAI;IAyCtC,YAAa,OAAY,EAAE,gBAAwB,EAAE,uBAAuB,GAAW,CAAC;QACpF,OAAO,CAAC;QAjCF,gBAAW,GAAgB,yBAAW,CAAC,gBAAgB,CAAC;QAU1D,iBAAY,GAAa,EAAE,CAAC;QAyBhC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,uBAAuB,GAAG,uBAAuB,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACxC,CAAC;IAEM,UAAU;QACb,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE;YAC7B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM;gBAChB,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;oBAChB,KAAK,SAAS;wBACV,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;wBAElC,KAAK,CAAC;gBACd,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAKM,iBAAiB;QACpB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;IACjC,CAAC;IAKM,WAAW;QACd,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAKM,OAAO;QACV,aAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAEnE,IAAI,CAAC,UAAU,EAAE,CAAC;QAElB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAKS,gBAAgB;QACtB,MAAM,CAAC;YACH,MAAM,EAAE,qBAAqB;YAC7B,cAAc,EAAE;gBACZ;oBACI,MAAM,EAAE,oBAAoB;oBAC5B,IAAI,EAAE;wBACF,MAAM,EAAE,YAAY;wBACpB,MAAM,EAAE,IAAI,CAAC,gBAAgB;qBAChC;oBACD,MAAM,EAAE;wBACJ,MAAM,EAAE,iBAAiB;wBACzB,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK;4BACpC,MAAM,CAAC;gCACH,MAAM,EAAE,SAAS;gCACjB,OAAO,EAAE,KAAK;gCACd,KAAK,EAAE,IAAI,KAAK,GAAG;gCACnB,qBAAqB,EAAE;oCACnB,SAAS,EAAG,KAAK;oCACjB,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,OAAO;iCAC3C;6BACJ,CAAC;wBACN,CAAC,CAAC;qBACL;iBACJ;aACJ;YACD,MAAM,EAAE,KAAK;SAChB,CAAC;IACN,CAAC;AACL,CAAC;AApHiB,4CAA2B,GAAW,CAAC,CAAC;AAJ7C,wBAAgB,mBAwH5B,CAAA"} \ No newline at end of file diff --git a/src/nodes/UnicodeArrayNode.ts b/src/nodes/UnicodeArrayNode.ts new file mode 100644 index 00000000..823bf1be --- /dev/null +++ b/src/nodes/UnicodeArrayNode.ts @@ -0,0 +1,129 @@ +import { Node } from './Node'; +import { Utils } from '../Utils'; + +import { AppendState } from '../enums/AppendState'; + +let escodegen = require('escodegen'), + estraverse = require('estraverse'); + +export class UnicodeArrayNode extends Node { + /** + * @type {number} + */ + public static UNICODE_ARRAY_RANDOM_LENGTH: number = 4; + + /** + * @type {AppendState} + */ + protected appendState: AppendState = AppendState.AfterObfuscation; + + /** + * @type any + */ + private astTree: any; + + /** + * @type {string[]} + */ + private unicodeArray: string[] = []; + + /** + * @type {string} + */ + private unicodeArrayName: string; + + /** + * @type {number} + */ + private unicodeArrayRotateValue: number; + + /** + * @type any + */ + protected node: any; + + /** + * @param astTree + * @param unicodeArrayName + * @param unicodeArrayRotateValue + */ + constructor (astTree: any, unicodeArrayName: string, unicodeArrayRotateValue: number = 0) { + super(); + + this.astTree = astTree; + this.unicodeArrayName = unicodeArrayName; + this.unicodeArrayRotateValue = unicodeArrayRotateValue; + this.node = this.getNodeStructure(); + } + + public appendNode (): void { + estraverse.replace(this.astTree, { + leave: (node, parent) => { + switch (node.type) { + case 'Program': + node.body.unshift(this.getNode()); + + break; + } + } + }); + } + + /** + * @returns {string} + */ + public getNodeIdentifier (): string { + return this.unicodeArrayName; + } + + /** + * @returns {string[]} + */ + public getNodeData (): string[] { + return this.unicodeArray; + } + + /** + * @returns any + */ + public getNode (): any { + Utils.arrayRotate(this.unicodeArray, this.unicodeArrayRotateValue); + + this.updateNode(); + + return this.node; + } + + /** + * @returns any + */ + protected getNodeStructure (): any { + return { + 'type': 'VariableDeclaration', + 'declarations': [ + { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': this.unicodeArrayName + }, + 'init': { + 'type': 'ArrayExpression', + 'elements': this.unicodeArray.map((value) => { + return { + 'type': 'Literal', + 'value': value, + 'raw': `'${value}'`, + 'x-verbatim-property': { + 'content' : value, + precedence: escodegen.Precedence.Primary + } + }; + }) + } + } + ], + 'kind': 'var' + }; + } +} \ No newline at end of file diff --git a/src/nodes/UnicodeArrayRotateFunctionCallNode.js b/src/nodes/UnicodeArrayRotateFunctionCallNode.js new file mode 100644 index 00000000..1afc9a39 --- /dev/null +++ b/src/nodes/UnicodeArrayRotateFunctionCallNode.js @@ -0,0 +1,54 @@ +"use strict"; +const Node_1 = require('./Node'); +let estraverse = require('estraverse'); +class UnicodeArrayRotateFunctionCallNode extends Node_1.Node { + constructor(astTree, unicodeArrayRotateFunctionName, unicodeArrayName, unicodeArrayRotateValue) { + super(); + this.astTree = astTree; + this.unicodeArrayRotateFunctionName = unicodeArrayRotateFunctionName; + this.unicodeArrayName = unicodeArrayName; + this.unicodeArrayRotateValue = unicodeArrayRotateValue; + this.node = this.getNodeStructure(); + } + appendNode() { + estraverse.replace(this.astTree, { + leave: (node, parent) => { + switch (node.type) { + case 'Program': + node.body.unshift(this.getNode()); + break; + } + } + }); + } + getNodeStructure() { + return { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'Identifier', + 'name': this.unicodeArrayRotateFunctionName + }, + 'arguments': [ + { + 'type': 'Identifier', + 'name': this.unicodeArrayName + }, + { + 'type': 'Literal', + 'value': this.unicodeArrayRotateValue, + 'raw': `'${this.unicodeArrayRotateValue}'` + }, + { + 'type': 'Literal', + 'value': true, + 'raw': 'true' + } + ] + } + }; + } +} +exports.UnicodeArrayRotateFunctionCallNode = UnicodeArrayRotateFunctionCallNode; +//# sourceMappingURL=UnicodeArrayRotateFunctionCallNode.js.map \ No newline at end of file diff --git a/src/nodes/UnicodeArrayRotateFunctionCallNode.js.map b/src/nodes/UnicodeArrayRotateFunctionCallNode.js.map new file mode 100644 index 00000000..9ee0acff --- /dev/null +++ b/src/nodes/UnicodeArrayRotateFunctionCallNode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"UnicodeArrayRotateFunctionCallNode.js","sourceRoot":"","sources":["UnicodeArrayRotateFunctionCallNode.ts"],"names":[],"mappings":";AAAA,uBAAqB,QAAQ,CAAC,CAAA;AAE9B,IAAI,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAEvC,iDAAwD,WAAI;IAgCxD,YACI,OAAY,EACZ,8BAAsC,EACtC,gBAAwB,EACxB,uBAA+B;QAE/B,OAAO,CAAC;QAER,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,8BAA8B,GAAG,8BAA8B,CAAC;QACrE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,uBAAuB,GAAG,uBAAuB,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACxC,CAAC;IAEM,UAAU;QACb,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE;YAC7B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM;gBAChB,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;oBAChB,KAAK,SAAS;wBACV,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;wBAElC,KAAK,CAAC;gBACd,CAAC;YACL,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAKS,gBAAgB;QACtB,MAAM,CAAC;YACH,MAAM,EAAE,qBAAqB;YAC7B,YAAY,EAAE;gBACV,MAAM,EAAE,gBAAgB;gBACxB,QAAQ,EAAE;oBACN,MAAM,EAAE,YAAY;oBACpB,MAAM,EAAE,IAAI,CAAC,8BAA8B;iBAC9C;gBACD,WAAW,EAAE;oBACT;wBACI,MAAM,EAAE,YAAY;wBACpB,MAAM,EAAE,IAAI,CAAC,gBAAgB;qBAChC;oBACD;wBACI,MAAM,EAAE,SAAS;wBACjB,OAAO,EAAE,IAAI,CAAC,uBAAuB;wBACrC,KAAK,EAAE,IAAI,IAAI,CAAC,uBAAuB,GAAG;qBAC7C;oBACD;wBACI,MAAM,EAAE,SAAS;wBACjB,OAAO,EAAE,IAAI;wBACb,KAAK,EAAE,MAAM;qBAChB;iBACJ;aACJ;SACJ,CAAC;IACN,CAAC;AACL,CAAC;AA3FY,0CAAkC,qCA2F9C,CAAA"} \ No newline at end of file diff --git a/src/nodes/UnicodeArrayRotateFunctionCallNode.ts b/src/nodes/UnicodeArrayRotateFunctionCallNode.ts new file mode 100644 index 00000000..7577144b --- /dev/null +++ b/src/nodes/UnicodeArrayRotateFunctionCallNode.ts @@ -0,0 +1,96 @@ +import { Node } from './Node'; + +let estraverse = require('estraverse'); + +export class UnicodeArrayRotateFunctionCallNode extends Node { + /** + * @type any + */ + private astTree: any; + + /** + * @type {string} + */ + private unicodeArrayName: string; + + /** + * @type {number} + */ + private unicodeArrayRotateValue: number; + + /** + * @param {string} + */ + private unicodeArrayRotateFunctionName: string; + + /** + * @type any + */ + protected node: any; + + /** + * @param astTree + * @param unicodeArrayRotateFunctionName + * @param unicodeArrayName + * @param unicodeArrayRotateValue + */ + constructor ( + astTree: any, + unicodeArrayRotateFunctionName: string, + unicodeArrayName: string, + unicodeArrayRotateValue: number + ) { + super(); + + this.astTree = astTree; + this.unicodeArrayRotateFunctionName = unicodeArrayRotateFunctionName; + this.unicodeArrayName = unicodeArrayName; + this.unicodeArrayRotateValue = unicodeArrayRotateValue; + this.node = this.getNodeStructure(); + } + + public appendNode (): void { + estraverse.replace(this.astTree, { + leave: (node, parent) => { + switch (node.type) { + case 'Program': + node.body.unshift(this.getNode()); + + break; + } + } + }); + } + + /** + * @returns any + */ + protected getNodeStructure (): any { + return { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'Identifier', + 'name': this.unicodeArrayRotateFunctionName + }, + 'arguments': [ + { + 'type': 'Identifier', + 'name': this.unicodeArrayName + }, + { + 'type': 'Literal', + 'value': this.unicodeArrayRotateValue, + 'raw': `'${this.unicodeArrayRotateValue}'` + }, + { + 'type': 'Literal', + 'value': true, + 'raw': 'true' + } + ] + } + }; + } +} \ No newline at end of file diff --git a/src/nodes/UnicodeArrayRotateFunctionNode.js b/src/nodes/UnicodeArrayRotateFunctionNode.js new file mode 100644 index 00000000..f0125856 --- /dev/null +++ b/src/nodes/UnicodeArrayRotateFunctionNode.js @@ -0,0 +1,269 @@ +"use strict"; +const Node_1 = require('./Node'); +const Utils_1 = require('../Utils'); +let estraverse = require('estraverse'); +class UnicodeArrayRotateFunctionNode extends Node_1.Node { + constructor(astTree, unicodeArrayRotateFunctionName, unicodeArrayName) { + super(); + this.astTree = astTree; + this.unicodeArrayRotateFunctionName = unicodeArrayRotateFunctionName; + this.unicodeArrayName = unicodeArrayName; + this.node = this.getNodeStructure(); + } + appendNode() { + estraverse.replace(this.astTree, { + leave: (node, parent) => { + switch (node.type) { + case 'Program': + node.body.push(this.getNode()); + break; + } + } + }); + } + getNodeIdentifier() { + return this.unicodeArrayRotateFunctionName; + } + getNodeStructure() { + return { + 'type': 'FunctionExpression', + 'id': { + 'type': 'Identifier', + 'name': this.unicodeArrayRotateFunctionName + }, + 'params': [ + { + 'type': 'Identifier', + 'name': 'array' + }, + { + 'type': 'Identifier', + 'name': 'times' + }, + { + 'type': 'Identifier', + 'name': 'reverse' + } + ], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'IfStatement', + 'test': { + 'type': 'BinaryExpression', + 'operator': '<', + 'left': { + 'type': 'Identifier', + 'name': 'times' + }, + 'right': { + 'type': 'Literal', + 'value': 0, + 'raw': '0' + } + }, + 'consequent': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'ReturnStatement', + 'argument': null + } + ] + }, + 'alternate': null + }, + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'reverse' + }, + 'right': { + 'type': 'LogicalExpression', + 'operator': '||', + 'left': { + 'type': 'Identifier', + 'name': 'reverse' + }, + 'right': { + 'type': 'Literal', + 'value': false, + 'raw': 'false' + } + } + } + }, + { + 'type': 'VariableDeclaration', + 'declarations': [ + { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': 'temp' + }, + 'init': null + } + ], + 'kind': 'var' + }, + { + 'type': 'WhileStatement', + 'test': { + 'type': 'UpdateExpression', + 'operator': '--', + 'argument': { + 'type': 'Identifier', + 'name': 'times' + }, + 'prefix': false + }, + 'body': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'IfStatement', + 'test': { + 'type': 'UnaryExpression', + 'operator': '!', + 'argument': { + 'type': 'Identifier', + 'name': 'reverse' + }, + 'prefix': true + }, + 'consequent': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'temp' + }, + 'right': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'pop', + 'x-verbatim-property': Utils_1.Utils.stringToUnicode('pop') + } + }, + 'arguments': [] + } + } + }, + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'unshift', + 'x-verbatim-property': Utils_1.Utils.stringToUnicode('unshift') + } + }, + 'arguments': [ + { + 'type': 'Identifier', + 'name': 'temp' + } + ] + } + } + ] + }, + 'alternate': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'temp' + }, + 'right': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'shift', + 'x-verbatim-property': Utils_1.Utils.stringToUnicode('shift') + } + }, + 'arguments': [] + } + } + }, + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'push', + 'x-verbatim-property': Utils_1.Utils.stringToUnicode('push') + } + }, + 'arguments': [ + { + 'type': 'Identifier', + 'name': 'temp' + } + ] + } + } + ] + } + } + ] + } + } + ] + }, + 'generator': false, + 'expression': false + }; + } +} +exports.UnicodeArrayRotateFunctionNode = UnicodeArrayRotateFunctionNode; +//# sourceMappingURL=UnicodeArrayRotateFunctionNode.js.map \ No newline at end of file diff --git a/src/nodes/UnicodeArrayRotateFunctionNode.js.map b/src/nodes/UnicodeArrayRotateFunctionNode.js.map new file mode 100644 index 00000000..abfd6d8f --- /dev/null +++ b/src/nodes/UnicodeArrayRotateFunctionNode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"UnicodeArrayRotateFunctionNode.js","sourceRoot":"","sources":["UnicodeArrayRotateFunctionNode.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/nodes/UnicodeArrayRotateFunctionNode.ts b/src/nodes/UnicodeArrayRotateFunctionNode.ts new file mode 100644 index 00000000..68aec677 --- /dev/null +++ b/src/nodes/UnicodeArrayRotateFunctionNode.ts @@ -0,0 +1,307 @@ +import { Node } from './Node'; +import { Utils } from '../Utils'; + +let estraverse = require('estraverse'); + +export class UnicodeArrayRotateFunctionNode extends Node { + /** + * @type any + */ + private astTree: any; + /** + * @type {string} + */ + private unicodeArrayName: string; + + /** + * @param {string} + */ + private unicodeArrayRotateFunctionName: string; + + /** + * @type any + */ + protected node: any; + + /** + * @param astTree + * @param unicodeArrayRotateFunctionName + * @param unicodeArrayName + */ + constructor ( + astTree: any, + unicodeArrayRotateFunctionName: string, + unicodeArrayName: string + ) { + super(); + + this.astTree = astTree; + this.unicodeArrayRotateFunctionName = unicodeArrayRotateFunctionName; + this.unicodeArrayName = unicodeArrayName; + this.node = this.getNodeStructure(); + } + + public appendNode (): void { + estraverse.replace(this.astTree, { + leave: (node, parent) => { + switch (node.type) { + case 'Program': + node.body.push(this.getNode()); + + break; + } + } + }); + } + + /** + * @returns {string} + */ + public getNodeIdentifier (): string { + return this.unicodeArrayRotateFunctionName; + } + + /** + * @returns any + */ + protected getNodeStructure (): any { + return { + 'type': 'FunctionExpression', + 'id': { + 'type': 'Identifier', + 'name': this.unicodeArrayRotateFunctionName + }, + 'params': [ + { + 'type': 'Identifier', + 'name': 'array' + }, + { + 'type': 'Identifier', + 'name': 'times' + }, + { + 'type': 'Identifier', + 'name': 'reverse' + } + ], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'IfStatement', + 'test': { + 'type': 'BinaryExpression', + 'operator': '<', + 'left': { + 'type': 'Identifier', + 'name': 'times' + }, + 'right': { + 'type': 'Literal', + 'value': 0, + 'raw': '0' + } + }, + 'consequent': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'ReturnStatement', + 'argument': null + } + ] + }, + 'alternate': null + }, + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'reverse' + }, + 'right': { + 'type': 'LogicalExpression', + 'operator': '||', + 'left': { + 'type': 'Identifier', + 'name': 'reverse' + }, + 'right': { + 'type': 'Literal', + 'value': false, + 'raw': 'false' + } + } + } + }, + { + 'type': 'VariableDeclaration', + 'declarations': [ + { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': 'temp' + }, + 'init': null + } + ], + 'kind': 'var' + }, + { + 'type': 'WhileStatement', + 'test': { + 'type': 'UpdateExpression', + 'operator': '--', + 'argument': { + 'type': 'Identifier', + 'name': 'times' + }, + 'prefix': false + }, + 'body': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'IfStatement', + 'test': { + 'type': 'UnaryExpression', + 'operator': '!', + 'argument': { + 'type': 'Identifier', + 'name': 'reverse' + }, + 'prefix': true + }, + 'consequent': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'temp' + }, + 'right': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'pop', + 'x-verbatim-property': Utils.stringToUnicode('pop') + } + }, + 'arguments': [] + } + } + }, + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'unshift', + 'x-verbatim-property': Utils.stringToUnicode('unshift') + } + }, + 'arguments': [ + { + 'type': 'Identifier', + 'name': 'temp' + } + ] + } + } + ] + }, + 'alternate': { + 'type': 'BlockStatement', + 'body': [ + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'temp' + }, + 'right': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'shift', + 'x-verbatim-property': Utils.stringToUnicode('shift') + } + }, + 'arguments': [] + } + } + }, + { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'array' + }, + 'property': { + 'type': 'Literal', + 'name': 'push', + 'x-verbatim-property': Utils.stringToUnicode('push') + } + }, + 'arguments': [ + { + 'type': 'Identifier', + 'name': 'temp' + } + ] + } + } + ] + } + } + ] + } + } + ] + }, + 'generator': false, + 'expression': false + }; + } +} \ No newline at end of file diff --git a/src/typings/node/node.d.ts b/src/typings/node/node.d.ts new file mode 100644 index 00000000..6b673d61 --- /dev/null +++ b/src/typings/node/node.d.ts @@ -0,0 +1,1283 @@ +// Type definitions for Node.js v0.10.1 +// Project: http://nodejs.org/ +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/************************************************ +* * +* Node.js v0.10.1 API * +* * +************************************************/ + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: any; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +declare var require: { + (id: string): any; + resolve(id:string): string; + cache: any; + extensions: any; + main: any; +}; + +declare var module: { + exports: any; + require(id: string): any; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +}; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +interface Buffer extends NodeBuffer {} +declare var Buffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +} + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare module NodeJS { + export interface ErrnoException extends Error { + errno?: any; + code?: string; + path?: string; + syscall?: string; + } + + export interface EventEmitter { + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream {} + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + openssl: string; + }; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; }; + nextTick(callback: Function): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?:number[]): number[]; + + // Worker + send?(message: any, sendHandle?: any): void; + } + + export interface Timer { + ref() : void; + unref() : void; + } +} + +/** + * @deprecated + */ +interface NodeBuffer { + [index: number]: number; + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + length: number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + readUInt8(offset: number, noAsset?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + writeUInt8(value: number, offset: number, noAssert?: boolean): void; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeInt8(value: number, offset: number, noAssert?: boolean): void; + writeInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeFloatLE(value: number, offset: number, noAssert?: boolean): void; + writeFloatBE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): void; + fill(value: any, offset?: number, end?: number): void; +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module 'querystring' { + export function stringify(obj: any, sep?: string, eq?: string): string; + export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any; + export function escape(): any; + export function unescape(): any; +} + +declare module 'events' { + export class EventEmitter implements NodeJS.EventEmitter { + static listenerCount(emitter: EventEmitter, event: string): number; + + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } +} + +declare module 'http' { + import events = require('events'); + import net = require('net'); + import stream = require('stream'); + + export interface Server extends events.EventEmitter { + listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; + listen(path: string, callback?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(cb?: any): Server; + address(): { port: number; family: string; address: string; }; + maxHeadersCount: number; + } + export interface ServerRequest extends events.EventEmitter, stream.Readable { + method: string; + url: string; + headers: any; + trailers: string; + httpVersion: string; + setEncoding(encoding?: string): void; + pause(): void; + resume(): void; + connection: net.Socket; + } + export interface ServerResponse extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + setHeader(name: string, value: string): void; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: Function): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientResponse extends events.EventEmitter, stream.Readable { + statusCode: number; + httpVersion: string; + headers: any; + trailers: any; + setEncoding(encoding?: string): void; + pause(): void; + resume(): void; + } + export interface Agent { maxSockets: number; sockets: any; requests: any; } + + export var STATUS_CODES: any; + export function createServer(requestListener?: (request: ServerRequest, response: ServerResponse) =>void ): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: any, callback?: Function): ClientRequest; + export function get(options: any, callback?: Function): ClientRequest; + export var globalAgent: Agent; +} + +declare module 'cluster' { + import child = require('child_process'); + import events = require('events'); + + export interface ClusterSettings { + exec?: string; + args?: string[]; + silent?: boolean; + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): void; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + } + + export var settings: ClusterSettings; + export var isMaster: boolean; + export var isWorker: boolean; + export function setupMaster(settings?: ClusterSettings): void; + export function fork(env?: any): Worker; + export function disconnect(callback?: Function): void; + export var worker: Worker; + export var workers: Worker[]; + + // Event emitter + export function addListener(event: string, listener: Function): void; + export function on(event: string, listener: Function): any; + export function once(event: string, listener: Function): void; + export function removeListener(event: string, listener: Function): void; + export function removeAllListeners(event?: string): void; + export function setMaxListeners(n: number): void; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; +} + +declare module 'zlib' { + import stream = require('stream'); + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module 'os' { + export function tmpDir(): string; + export function hostname(): string; + export function type(): string; + export function platform(): string; + export function arch(): string; + export function release(): string; + export function uptime(): number; + export function loadavg(): number[]; + export function totalmem(): number; + export function freemem(): number; + export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[]; + export function networkInterfaces(): any; + export var EOL: string; +} + +declare module 'https' { + import tls = require('tls'); + import events = require('events'); + import http = require('http'); + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string) => any; + } + + export interface RequestOptions { + host?: string; + hostname?: string; + port?: number; + path?: string; + method?: string; + headers?: any; + auth?: string; + agent?: any; + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + } + + export interface Agent { + maxSockets: number; + sockets: any; + requests: any; + } + export var Agent: { + new (options?: RequestOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module 'punycode' { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): string; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module 'repl' { + import stream = require('stream'); + import events = require('events'); + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + } + export function start(options: ReplOptions): events.EventEmitter; +} + +declare module 'readline' { + import events = require('events'); + import stream = require('stream'); + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string, length: number): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: Function): void; + pause(): void; + resume(): void; + close(): void; + write(data: any, key?: any): void; + } + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output: NodeJS.WritableStream; + completer?: Function; + terminal?: boolean; + } + export function createInterface(options: ReadLineOptions): ReadLine; +} + +declare module 'vm' { + export interface Context { } + export interface Script { + runInThisContext(): void; + runInNewContext(sandbox?: Context): void; + } + export function runInThisContext(code: string, filename?: string): void; + export function runInNewContext(code: string, sandbox?: Context, filename?: string): void; + export function runInContext(code: string, context: Context, filename?: string): void; + export function createContext(initSandbox?: Context): Context; + export function createScript(code: string, filename?: string): Script; +} + +declare module 'child_process' { + import events = require('events'); + import stream = require('stream'); + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle: any): void; + disconnect(): void; + } + + export function spawn(command: string, args?: string[], options?: { + cwd?: string; + stdio?: any; + custom?: any; + env?: any; + detached?: boolean; + }): ChildProcess; + export function exec(command: string, options: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function exec(command: string, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, args: string[], options: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: string; + killSignal?: string; + }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function fork(modulePath: string, args?: string[], options?: { + cwd?: string; + env?: any; + encoding?: string; + }): ChildProcess; +} + +declare module 'url' { + export interface Url { + href: string; + protocol: string; + auth: string; + hostname: string; + port: string; + host: string; + pathname: string; + search: string; + query: string; + slashes: boolean; + hash?: string; + path?: string; + } + + export interface UrlOptions { + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: any; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; + export function format(url: UrlOptions): string; + export function resolve(from: string, to: string): string; +} + +declare module 'dns' { + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; +} + +declare module 'net' { + import stream = require('stream'); + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): void; + resume(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + remoteAddress: string; + remotePort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface Server extends Socket { + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + maxConnections: number; + connections: number; + } + export function createServer(connectionListener?: (socket: Socket) =>void ): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; + export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module 'dgram' { + import events = require('events'); + + export function createSocket(type: string, callback?: Function): Socket; + + interface Socket extends events.EventEmitter { + send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: Function): void; + bind(port: number, address?: string): void; + close(): void; + address: { address: string; family: string; port: number; }; + setBroadcast(flag: boolean): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + } +} + +declare module 'fs' { + import stream = require('stream'); + import events = require('events'); + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + } + + export interface ReadStream extends stream.Readable {} + export interface WriteStream extends stream.Writable {} + + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string, uid: number, gid: number): void; + export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string, mode: number): void; + export function chmodSync(path: string, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string, mode: number): void; + export function lchmodSync(path: string, mode: string): void; + export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string): Stats; + export function lstatSync(path: string): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string, dstpath: string): void; + export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; + export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string): string; + export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; + export function realpathSync(path: string, cache?: {[path: string]: string}): string; + export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function unlinkSync(path: string): void; + export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function rmdirSync(path: string): void; + export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdirSync(path: string, mode?: number): void; + export function mkdirSync(path: string, mode?: string): void; + export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function openSync(path: string, flags: string, mode?: number): number; + export function openSync(path: string, flags: string, mode?: string): number; + export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string, atime: number, mtime: number): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void ): void; + export function readFileSync(filename: string, encoding: string): string; + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; + export function exists(path: string, callback?: (exists: boolean) => void): void; + export function existsSync(path: string): boolean; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: number; + bufferSize?: number; + }): ReadStream; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: string; + bufferSize?: number; + }): ReadStream; + export function createWriteStream(path: string, options?: { + flags?: string; + encoding?: string; + string?: string; + }): WriteStream; +} + +declare module 'path' { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; +} + +declare module 'string_decoder' { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + detectIncompleteChar(buffer: Buffer): number; + } + export var StringDecoder: { + new (encoding: string): NodeStringDecoder; + }; +} + +declare module 'tls' { + import crypto = require('crypto'); + import net = require('net'); + import stream = require('stream'); + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface TlsOptions { + pfx?: any; //string or buffer + key?: any; //string or buffer + passphrase?: string; + cert?: any; + ca?: any; //string or buffer + crl?: any; //string or string array + ciphers?: string; + honorCipherOrder?: any; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; //array or Buffer; + SNICallback?: (servername: string) => any; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: any; //string | Buffer + key?: any; //string | Buffer + passphrase?: string; + cert?: any; //string | Buffer + ca?: any; //Array of string | Buffer + rejectUnauthorized?: boolean; + NPNProtocols?: any; //Array of string | Buffer + servername?: string; + } + + export interface Server extends net.Server { + // Extended base methods + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + + listen(port: number, host?: string, callback?: Function): Server; + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; + export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; +} + +declare module 'crypto' { + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: any; //string | string array + crl: any; //string | string array + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string): Hmac; + interface Hash { + update(data: any, input_encoding?: string): Hash; + digest(encoding?: string): string; + } + interface Hmac { + update(data: any, input_encoding?: string): Hmac; + digest(encoding?: string): string; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + interface Cipher { + update(data: any, input_encoding?: string, output_encoding?: string): string; + final(output_encoding?: string): string; + setAutoPadding(auto_padding: boolean): void; + createDecipher(algorithm: string, password: any): Decipher; + createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + } + interface Decipher { + update(data: any, input_encoding?: string, output_encoding?: string): void; + final(output_encoding?: string): string; + setAutoPadding(auto_padding: boolean): void; + } + export function createSign(algorithm: string): Signer; + interface Signer { + update(data: any): void; + sign(private_key: string, output_format: string): string; + } + export function createVerify(algorith: string): Verify; + interface Verify { + update(data: any): void; + verify(object: string, signature: string, signature_format?: string): boolean; + } + export function createDiffieHellman(prime_length: number): DiffieHellman; + export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; + interface DiffieHellman { + generateKeys(encoding?: string): string; + computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; + getPrime(encoding?: string): string; + getGenerator(encoding: string): string; + getPublicKey(encoding?: string): string; + getPrivateKey(encoding?: string): string; + setPublicKey(public_key: string, encoding?: string): void; + setPrivateKey(public_key: string, encoding?: string): void; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: string) => any): void; + export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; +} + +declare module 'stream' { + import events = require('events'); + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(data: Buffer, encoding: string, callback: Function): void; + _write(data: string, encoding: string, callback: Function): void; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + writable: boolean; + constructor(opts?: DuplexOptions); + _write(data: Buffer, encoding: string, callback: Function): void; + _write(data: string, encoding: string, callback: Function): void; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions {} + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + _transform(chunk: Buffer, encoding: string, callback: Function): void; + _transform(chunk: string, encoding: string, callback: Function): void; + _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform {} +} + +declare module 'util' { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; +} + +declare module 'assert' { + function internal (value: any, message?: string): void; + module internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: {message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function}); + } + + export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + } + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + } + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module 'tty' { + import net = require('net'); + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + } +} + +declare module 'domain' { + import events = require('events'); + + export class Domain extends events.EventEmitter { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): Domain; + on(event: string, listener: Function): Domain; + once(event: string, listener: Function): Domain; + removeListener(event: string, listener: Function): Domain; + removeAllListeners(event?: string): Domain; + } + + export function create(): Domain; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..cd4aad8c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": true, + "noImplicitAny": false + } +} \ No newline at end of file diff --git a/tsd.json b/tsd.json new file mode 100644 index 00000000..d0290d98 --- /dev/null +++ b/tsd.json @@ -0,0 +1,12 @@ +{ + "version": "v4", + "repo": "borisyankov/DefinitelyTyped", + "ref": "master", + "path": "src/typings", + "bundle": "typings/tsd.d.ts", + "installed": { + "node/node.d.ts": { + "commit": "6834f97fb33561a3ad40695084da2b660efaee29" + } + } +} \ No newline at end of file diff --git a/typings/tsd.d.ts b/typings/tsd.d.ts new file mode 100644 index 00000000..901997d9 --- /dev/null +++ b/typings/tsd.d.ts @@ -0,0 +1 @@ +///