1. 代码混淆(sojson…)
Function构造函数
-
格式化代码
-
断点打在最后一行
-
注入代码后查看混淆前代码
Function.prototype.constructor_ = Function.prototype.constructor; Function.prototype.constructor = function(x){ if(x == 'debugger'){ return function(){} } return Function.prototype.constructor_(x); }
eval函数
- 格式化代码
- 断点打在最后一行
- 注入代码后查看混淆前代码
eval = function(){ debugger; }
2. 补环境
vm2
-
官网(npm install vm2)
-
代码
var fs = require('fs') // https://www.mpmjs.com/package/vm2 npm i vm2 // 作用:将 node 环境转为纯净 v8 const { VM } =require('vm2') const vm = new VM() const data = fs.readFileSync('xxx.js', 'utf8') debugger vm.run(data) debugger
-
使用 vm2 后,不能 debugger 与无环境调试,改进后
- index.js
var fs = require('fs') // https://www.mpmjs.com/package/vm2 npm i vm2 // 作用:将 node 环境转为纯净 v8 const { VM, VMScript } =require('vm2') const file = `${__dirname}/xxx.js` const windowFile = `${__dirname}/window.js` const vm = new VM() const script = new VMScript(fs.readFileSync(windowFile)+fs.readFileSync(file),`${__dirname}/调试名.js`) debugger vm.run(script) debugger
- window.js
window = this window.document = { referrer:'https:/xxx.com' }
- index.js
-
注意
- process:可检测是否是node,v8与浏览器中未定义
. 服务器rpc解密
-
步骤
- 服务器创建指定websocket
- 浏览器注入代码并连接到服务器,服务器返回唯一id
- 脚本加密时带上唯一id和明文请求服务器,服务器根据唯一id发送明文给加密浏览器,浏览器返回服务器密文,服务器返回脚本密文
- 浏览器应一直运行
-
浏览器注入代码
!(function(){ // e:加密函数 window.encrypt = e // url:ws地址 let url = '' let ws = new WebSocket(url) ws.onopen = function(event){ } ws.onmessage = function(event){ ws.send(window.encrypt(event.data)) } })()
. 多线程调试Worker
- 说明
- new Worker不会改变,直接搜
- 主线程打断点不会显示Threads
- 主线程不能直接调用子线程的方法
- 将多线程改为单线程
-
主要代码
// 所有线程的缓存 var Workers = {} // 线程本身(子线程) var Worker_self = function(){} Worker_self.prototype.postMessage = function(data){ if(typeof(this.main.onmessage) != 'undefined'){ this.main.onmessage({ data }) } } Worker_self.prototype.onmessageEvents = [] Worker_self.prototype.onmessage = function(data){ this.onmessageEvents.forEach(value=>value(data)) } Worker_self.prototype.main = undefined Worker_self.prototype.addEventListener = function(type,func,b){ if(type == 'message'){ this.onmessageEvents.push(func) } } // 开启线程(主线程) var Worker = function(jsname, jscode){ jsname = MD5_Encrypt(jsname) jscode = atob(jscode) if(typeof(Workers[jsname]) == 'undefined'){ Workers[jsname] = new Worker_self() this.self_ = Workers[jsname] Workers[jsname].main = this eval('self = window.Workers[\''+jsname+'\'];'+jscode) } } Worker.prototype.postMessage = function(data){ this.self_.onmessage({ data }) } Worker.prototype.onmessage = undefined Worker.prototype.self_ = undefined // jsname:js文件名称(MD5加密) // jscode:js代码(base64编码) var worker = new Worker('','') worker.onmessage = function(event){ window.zzz = event.data } worker.postMessage('test')
-
加密算法(放在主要代码之前)
var CryptoJS = CryptoJS || (function (Math, undefined) { var crypto; if (typeof window !== 'undefined' && window.crypto) { crypto = window.crypto; } if (typeof self !== 'undefined' && self.crypto) { crypto = self.crypto; } if (typeof globalThis !== 'undefined' && globalThis.crypto) { crypto = globalThis.crypto; } if (!crypto && typeof window !== 'undefined' && window.msCrypto) { crypto = window.msCrypto; } if (!crypto && typeof global !== 'undefined' && global.crypto) { crypto = global.crypto; } if (!crypto && typeof require === 'function') { try { crypto = require('crypto'); } catch (err) {} } var cryptoSecureRandomInt = function () { if (crypto) { if (typeof crypto.getRandomValues === 'function') { try { return crypto.getRandomValues(new Uint32Array(1))[0]; } catch (err) {} } if (typeof crypto.randomBytes === 'function') { try { return crypto.randomBytes(4).readInt32LE(); } catch (err) {} } } throw new Error('Native crypto module could not be used to get secure random number.'); }; var create = Object.create || (function () { function F() {} return function (obj) { var subtype; F.prototype = obj; subtype = new F(); F.prototype = null; return subtype; }; }()); var C = {}; var C_lib = C.lib = {}; var Base = C_lib.Base = (function () { return { extend: function (overrides) { var subtype = create(this); if (overrides) { subtype.mixIn(overrides); } if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { subtype.init = function () { subtype.$super.init.apply(this, arguments); }; } subtype.init.prototype = subtype; subtype.$super = this; return subtype; }, create: function () { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, init: function () {}, mixIn: function (properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } if (properties.hasOwnProperty('toString')) { this.toString = properties.toString; } }, clone: function () { return this.init.prototype.extend(this); } }; }()); var WordArray = C_lib.WordArray = Base.extend({ init: function (words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, toString: function (encoder) { return (encoder || Hex).stringify(this); }, concat: function (wordArray) { var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; this.clamp(); if (thisSigBytes % 4) { for (var i = 0; i < thatSigBytes; i++) { var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); } } else { for (var j = 0; j < thatSigBytes; j += 4) { thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2]; } } this.sigBytes += thatSigBytes; return this; }, clamp: function () { var words = this.words; var sigBytes = this.sigBytes; words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); words.length = Math.ceil(sigBytes / 4); }, clone: function () { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, random: function (nBytes) { var words = []; var r = (function (m_w) { var m_w = m_w; var m_z = 0x3ade68b1; var mask = 0xffffffff; return function () { m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; var result = ((m_z << 0x10) + m_w) & mask; result /= 0x100000000; result += 0.5; return result * (Math.random() > .5 ? 1 : -1); } }); var RANDOM = false, _r; try { cryptoSecureRandomInt(); RANDOM = true; } catch (err) {} for (var i = 0, rcache; i < nBytes; i += 4) { if (!RANDOM) { _r = r((rcache || Math.random()) * 0x100000000); rcache = _r() * 0x3ade67b7; words.push((_r() * 0x100000000) | 0); continue; } words.push(cryptoSecureRandomInt()); } return new WordArray.init(words, nBytes); } }); var C_enc = C.enc = {}; var Hex = C_enc.Hex = { stringify: function (wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 0x0f).toString(16)); } return hexChars.join(''); }, parse: function (hexStr) { var hexStrLength = hexStr.length; var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); } return new WordArray.init(words, hexStrLength / 2); } }; var Latin1 = C_enc.Latin1 = { stringify: function (wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(''); }, parse: function (latin1Str) { var latin1StrLength = latin1Str.length; var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); } return new WordArray.init(words, latin1StrLength); } }; var Utf8 = C_enc.Utf8 = { stringify: function (wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error('Malformed UTF-8 data'); } }, parse: function (utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ reset: function () { this._data = new WordArray.init(); this._nDataBytes = 0; }, _append: function (data) { if (typeof data == 'string') { data = Utf8.parse(data); } this._data.concat(data); this._nDataBytes += data.sigBytes; }, _process: function (doFlush) { var processedWords; var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { nBlocksReady = Math.ceil(nBlocksReady); } else { nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); } var nWordsReady = nBlocksReady * blockSize; var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { this._doProcessBlock(dataWords, offset); } processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } return new WordArray.init(processedWords, nBytesReady); }, clone: function () { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ cfg: Base.extend(), init: function (cfg) { this.cfg = this.cfg.extend(cfg); this.reset(); }, reset: function () { BufferedBlockAlgorithm.reset.call(this); this._doReset(); }, update: function (messageUpdate) { this._append(messageUpdate); this._process(); return this; }, finalize: function (messageUpdate) { if (messageUpdate) { this._append(messageUpdate); } var hash = this._doFinalize(); return hash; }, blockSize: 512 / 32, _createHelper: function (hasher) { return function (message, cfg) { return new hasher.init(cfg).finalize(message); }; }, _createHmacHelper: function (hasher) { return function (message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); var C_algo = C.algo = {}; return C; }(Math)); (function (Math) { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; var T = []; (function () { for (var i = 0; i < 64; i++) { T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; } }()); var MD5 = C_algo.MD5 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]); }, _doProcessBlock: function (M, offset) { for (var i = 0; i < 16; i++) { var offset_i = offset + i; var M_offset_i = M[offset_i]; M[offset_i] = ((((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)); } var H = this._hash.words; var M_offset_0 = M[offset + 0]; var M_offset_1 = M[offset + 1]; var M_offset_2 = M[offset + 2]; var M_offset_3 = M[offset + 3]; var M_offset_4 = M[offset + 4]; var M_offset_5 = M[offset + 5]; var M_offset_6 = M[offset + 6]; var M_offset_7 = M[offset + 7]; var M_offset_8 = M[offset + 8]; var M_offset_9 = M[offset + 9]; var M_offset_10 = M[offset + 10]; var M_offset_11 = M[offset + 11]; var M_offset_12 = M[offset + 12]; var M_offset_13 = M[offset + 13]; var M_offset_14 = M[offset + 14]; var M_offset_15 = M[offset + 15]; var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; a = FF(a, b, c, d, M_offset_0, 7, T[0]); d = FF(d, a, b, c, M_offset_1, 12, T[1]); c = FF(c, d, a, b, M_offset_2, 17, T[2]); b = FF(b, c, d, a, M_offset_3, 22, T[3]); a = FF(a, b, c, d, M_offset_4, 7, T[4]); d = FF(d, a, b, c, M_offset_5, 12, T[5]); c = FF(c, d, a, b, M_offset_6, 17, T[6]); b = FF(b, c, d, a, M_offset_7, 22, T[7]); a = FF(a, b, c, d, M_offset_8, 7, T[8]); d = FF(d, a, b, c, M_offset_9, 12, T[9]); c = FF(c, d, a, b, M_offset_10, 17, T[10]); b = FF(b, c, d, a, M_offset_11, 22, T[11]); a = FF(a, b, c, d, M_offset_12, 7, T[12]); d = FF(d, a, b, c, M_offset_13, 12, T[13]); c = FF(c, d, a, b, M_offset_14, 17, T[14]); b = FF(b, c, d, a, M_offset_15, 22, T[15]); a = GG(a, b, c, d, M_offset_1, 5, T[16]); d = GG(d, a, b, c, M_offset_6, 9, T[17]); c = GG(c, d, a, b, M_offset_11, 14, T[18]); b = GG(b, c, d, a, M_offset_0, 20, T[19]); a = GG(a, b, c, d, M_offset_5, 5, T[20]); d = GG(d, a, b, c, M_offset_10, 9, T[21]); c = GG(c, d, a, b, M_offset_15, 14, T[22]); b = GG(b, c, d, a, M_offset_4, 20, T[23]); a = GG(a, b, c, d, M_offset_9, 5, T[24]); d = GG(d, a, b, c, M_offset_14, 9, T[25]); c = GG(c, d, a, b, M_offset_3, 14, T[26]); b = GG(b, c, d, a, M_offset_8, 20, T[27]); a = GG(a, b, c, d, M_offset_13, 5, T[28]); d = GG(d, a, b, c, M_offset_2, 9, T[29]); c = GG(c, d, a, b, M_offset_7, 14, T[30]); b = GG(b, c, d, a, M_offset_12, 20, T[31]); a = HH(a, b, c, d, M_offset_5, 4, T[32]); d = HH(d, a, b, c, M_offset_8, 11, T[33]); c = HH(c, d, a, b, M_offset_11, 16, T[34]); b = HH(b, c, d, a, M_offset_14, 23, T[35]); a = HH(a, b, c, d, M_offset_1, 4, T[36]); d = HH(d, a, b, c, M_offset_4, 11, T[37]); c = HH(c, d, a, b, M_offset_7, 16, T[38]); b = HH(b, c, d, a, M_offset_10, 23, T[39]); a = HH(a, b, c, d, M_offset_13, 4, T[40]); d = HH(d, a, b, c, M_offset_0, 11, T[41]); c = HH(c, d, a, b, M_offset_3, 16, T[42]); b = HH(b, c, d, a, M_offset_6, 23, T[43]); a = HH(a, b, c, d, M_offset_9, 4, T[44]); d = HH(d, a, b, c, M_offset_12, 11, T[45]); c = HH(c, d, a, b, M_offset_15, 16, T[46]); b = HH(b, c, d, a, M_offset_2, 23, T[47]); a = II(a, b, c, d, M_offset_0, 6, T[48]); d = II(d, a, b, c, M_offset_7, 10, T[49]); c = II(c, d, a, b, M_offset_14, 15, T[50]); b = II(b, c, d, a, M_offset_5, 21, T[51]); a = II(a, b, c, d, M_offset_12, 6, T[52]); d = II(d, a, b, c, M_offset_3, 10, T[53]); c = II(c, d, a, b, M_offset_10, 15, T[54]); b = II(b, c, d, a, M_offset_1, 21, T[55]); a = II(a, b, c, d, M_offset_8, 6, T[56]); d = II(d, a, b, c, M_offset_15, 10, T[57]); c = II(c, d, a, b, M_offset_6, 15, T[58]); b = II(b, c, d, a, M_offset_13, 21, T[59]); a = II(a, b, c, d, M_offset_4, 6, T[60]); d = II(d, a, b, c, M_offset_11, 10, T[61]); c = II(c, d, a, b, M_offset_2, 15, T[62]); b = II(b, c, d, a, M_offset_9, 21, T[63]); H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; }, _doFinalize: function () { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); var nBitsTotalL = nBitsTotal; dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ((((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ((((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)); data.sigBytes = (dataWords.length + 1) * 4; this._process(); var hash = this._hash; var H = hash.words; for (var i = 0; i < 4; i++) { var H_i = H[i]; H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); } return hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); function FF(a, b, c, d, x, s, t) { var n = a + ((b & c) | (~b & d)) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } function GG(a, b, c, d, x, s, t) { var n = a + ((b & d) | (c & ~d)) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } function HH(a, b, c, d, x, s, t) { var n = a + (b ^ c ^ d) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } function II(a, b, c, d, x, s, t) { var n = a + (c ^ (b | ~d)) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } C.MD5 = Hasher._createHelper(MD5); C.HmacMD5 = Hasher._createHmacHelper(MD5); }(Math)); function MD5_Encrypt(word) { return CryptoJS.MD5(word).toString(); //反转: //return CryptoJS.MD5(word).toString().split("").reverse().join(""); } (function () { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; var Base64 = C_enc.Base64 = { stringify: function (wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var map = this._map; wordArray.clamp(); var base64Chars = []; for (var i = 0; i < sigBytes; i += 3) { var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; var triplet = (byte1 << 16) | (byte2 << 8) | byte3; for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); } } var paddingChar = map.charAt(64); if (paddingChar) { while (base64Chars.length % 4) { base64Chars.push(paddingChar); } } return base64Chars.join(''); }, parse: function (base64Str) { var base64StrLength = base64Str.length; var map = this._map; var reverseMap = this._reverseMap; if (!reverseMap) { reverseMap = this._reverseMap = []; for (var j = 0; j < map.length; j++) { reverseMap[map.charCodeAt(j)] = j; } } var paddingChar = map.charAt(64); if (paddingChar) { var paddingIndex = base64Str.indexOf(paddingChar); if (paddingIndex !== -1) { base64StrLength = paddingIndex; } } return parseLoop(base64Str, base64StrLength, reverseMap); }, _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' }; function parseLoop(base64Str, base64StrLength, reverseMap) { var words = []; var nBytes = 0; for (var i = 0; i < base64StrLength; i++) { if (i % 4) { var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); nBytes++; } } return WordArray.create(words, nBytes); } }()); function B64_Encrypt(word) { var src = CryptoJS.enc.Utf8.parse(word); return CryptoJS.enc.Base64.stringify(src); } function B64_Decrypt(word) { var src = CryptoJS.enc.Base64.parse(word); return CryptoJS.enc.Utf8.stringify(src); }
-