diff --git a/lib/Constants.js b/lib/Constants.js index 0e7d3fb5..2653fe90 100644 --- a/lib/Constants.js +++ b/lib/Constants.js @@ -95,7 +95,7 @@ module.exports = { NORMAL: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'.split(''), REVERSE: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'.split('') }, - FUNCS_REGEX: /d\.push\(e\)|d\.reverse\(\)|d\[0\]\)\[0\]\)|f=d\[0];d\[0\]|d\.length;d\.splice\(e,1\)|function\(d\){for\(var|reverse\(\)\.forEach|unshift\(d\.pop\(\)\)|switch/, + FUNCS_REGEX: /d\.push\(e\)|d\.reverse\(\)|d\[0\]\)\[0\]\)|f=d\[0];d\[0\]|d\.length;d\.splice\(e,1\)|function\(\){for\(var|function\(d,e,f\){var h=f|function\(d\){for\(var|reverse\(\)\.forEach|unshift\(d\.pop\(\)\)|function\(d,e\){for\(var f/, FUNCS: { PUSH: 'd.push(e)', REVERSE_1: 'd.reverse()', @@ -105,12 +105,15 @@ module.exports = { SWAP0_2: 'f=d[0];d[0]', ROTATE_1: 'reverse().forEach', ROTATE_2: 'unshift(d.pop())', - TRANSLATE: 'switch' + BASE64_DIA: 'function(){for(var', + TRANSLATE_1: 'function(d,e){for(var f', + TRANSLATE_2: 'function(d,e,f){var h=f' }, // Helper functions, felt like Utils.js wasn't the right place for them: formatNTransformData: (data) => { return data .replace(/function\(d,e\)/g, '"function(d,e)').replace(/function\(d\)/g, '"function(d)') + .replace(/function\(\)/, '"function()').replace(/function\(d,e,f\)/g, '"function(d,e,f)') .replace(/,b,/g, ',"b",').replace(/,b/g, ',"b"').replace(/b,/g, '"b",').replace(/b]/g, '"b"]') .replace(/\[b/g, '["b"').replace(/}]/g, '"]').replace(/},/g, '}",').replace(/""/g, '') .replace(/length]\)}"/g, 'length])}'); diff --git a/lib/NToken.js b/lib/NToken.js index f8acb5e0..868f50a0 100644 --- a/lib/NToken.js +++ b/lib/NToken.js @@ -19,7 +19,7 @@ class NToken { if (el != null && typeof el != 'number') { const is_reverse_base64 = el.includes('case 65:'); (({ // Identifies the transformation functions and emulates them accordingly. - [Constants.FUNCS.PUSH]: () => el = (arr, item) => this.push(arr, item), + [Constants.FUNCS.PUSH]: () => el = (arr, i) => this.push(arr, i), [Constants.FUNCS.SPLICE]: () => el = (arr, i) => this.splice(arr, i), [Constants.FUNCS.SWAP0_1]: () => el = (arr, i) => this.swap0(arr, i), [Constants.FUNCS.SWAP0_2]: () => el = (arr, i) => this.swap0(arr, i), @@ -27,7 +27,9 @@ class NToken { [Constants.FUNCS.ROTATE_2]: () => el = (arr, i) => this.rotate(arr, i), [Constants.FUNCS.REVERSE_1]: () => el = (arr) => this.reverse(arr), [Constants.FUNCS.REVERSE_2]: () => el = (arr) => this.reverse(arr), - [Constants.FUNCS.TRANSLATE]: () => el = (arr, token) => this.translate(arr, token, is_reverse_base64) + [Constants.FUNCS.BASE64_DIA]: () => el = () => this.getBase64Dia(is_reverse_base64), + [Constants.FUNCS.TRANSLATE_1]: () => el = (arr, token) => this.translate1(arr, token, is_reverse_base64), + [Constants.FUNCS.TRANSLATE_2]: () => el = (arr, token, base64_dic) => this.translate2(arr, token, base64_dic) })[this.getFunc(el)] || (() => el === 'b' && (el = n_token)))(); } return el; @@ -41,10 +43,11 @@ class NToken { let transformation_calls = [...Utils.getStringBetweenStrings(this.raw_code.replace(/\n/g, ''), 'try{', '}catch').matchAll(this.transformation_calls_regex)].map((params) => ({ index: params[1], params: params[2] })); transformation_calls.forEach((data) => { const param_index = data.params.split(',').map((param) => param.match(/c\[(.*?)\]/)[1]); - transformations[data.index](transformations[param_index[0]], transformations[param_index[1]]); + const base64_dia = (param_index[2] && transformations[param_index[2]]()); + transformations[data.index](transformations[param_index[0]], transformations[param_index[1]], base64_dia); }); } catch (err) { - console.error(err); + console.error('Could not transform n-token, download may be throttled:', err); return n; } @@ -60,13 +63,25 @@ class NToken { return JSON.parse(Constants.formatNTransformData(data)); } - translate(arr, token, is_reverse_base64) { + translate1(arr, token, is_reverse_base64) { const characters = is_reverse_base64 && Constants.BASE64_DIALECT.REVERSE || Constants.BASE64_DIALECT.NORMAL; arr.forEach(function(char, index, loc) { this.push(loc[index] = characters[(characters.indexOf(char) - characters.indexOf(this[index]) + 64) % characters.length]); }, token.split('')); } + translate2(arr, token, characters) { + let chars_length = characters.length; + arr.forEach(function(char, index, loc) { + this.push(loc[index] = characters[(characters.indexOf(char) - characters.indexOf(this[index]) + index + chars_length--) % characters.length]); + }, token.split('')); + } + + getBase64Dia(is_reverse_base64) { + const characters = is_reverse_base64 && Constants.BASE64_DIALECT.REVERSE || Constants.BASE64_DIALECT.NORMAL; + return characters; + } + swap0(arr, index) { const old_value = arr[0]; index = (index % arr.length + arr.length) % arr.length;