合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
### hook常用js函数封装 #### Bytes 转 String,常用于MD5,Base64等加密 ``` function bytesToString(value) { var buffer = Java.array('byte', value); var StringClass = Java.use('java.lang.String'); return StringClass.$new(buffer); } ``` #### byte[]转字符串 frida使用会中文乱码 ``` function uint8arrayToStringMethod(myUint8Arr){ return String.fromCharCode.apply(null, myUint8Arr); } ``` ``` function bytes2String(arr) { if(typeof arr === 'string') { return arr; } var str = '', _arr = arr; for(var i = 0; i < _arr.length; i++) { var one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/); if(v && one.length == 8) { var bytesLength = v[0].length; var store = _arr[i].toString(2).slice(7 - bytesLength); for(var st = 1; st < bytesLength; st++) { store += _arr[st + i].toString(2).slice(2); } try { str += String.fromCharCode(parseInt(store, 2)); } catch (error) { str += parseInt(store, 2).toString(); console.log(error); } i += bytesLength - 1; } else { try { str += String.fromCharCode(_arr[i]); } catch (error) { str += parseInt(store, 2).toString(); console.log(error); } } } return str; } ``` ``` function Uint8ArrayToString(fileData){ var dataString = ""; for (var i = 0; i < fileData.length; i++) { dataString += String.fromCharCode(fileData[i]); } return dataString } ``` ``` function byteToHexString(uint8arr) { if (!uint8arr) { return ''; } var hexStr = ''; for (var i = 0; i < uint8arr.length; i++) { var hex = (uint8arr[i] & 0xff).toString(16); hex = (hex.length === 1) ? '0' + hex : hex; hexStr += hex; } return hexStr.toUpperCase(); } ``` #### Bytes数组转 16进制 ``` function bytes2Hex16(arrBytes){ var str = ""; for (var i = 0; i < arrBytes.length; i++) { var tmp; var num = arrBytes[i]; if (num < 0) { //此处填坑,当byte因为符合位导致数值为负时候,需要对数据进行处理 tmp = (255 + num + 1).toString(16); } else { tmp = num.toString(16); } if (tmp.length == 1) { tmp = "0" + tmp; } if(i>0){ str += ""+tmp; }else{ str += tmp; } } return str; } ``` ``` function bytes2Hex16(bytes_ary){ var ByteString = Java.use("com.android.okhttp.okio.ByteString"); var str_hex = ByteString.of(bytes_ary).hex(); return str_hex; } ``` #### Bytes数组转 16进制,字母大写 ``` function bytes2Hex16(uint8arr) { if (!uint8arr) { return ''; } var hexStr = ''; for (var i = 0; i < uint8arr.length; i++) { var hex = (uint8arr[i] & 0xff).toString(16); hex = (hex.length === 1) ? '0' + hex : hex; hexStr += hex; } return hexStr.toUpperCase(); } ``` #### Bytes数组转 10进制 ``` function bytes2Hex10(arrBytes){ var str_hex = JSON.stringify(arrBytes); return str_hex; } ``` #### 字符串转byte[] ``` function stringToUint8Array(str){ var arr = []; for (var i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } var tmpUint8Array = new Uint8Array(arr); return tmpUint8Array } ``` ``` function stringToByte(str) { var bytes = new Array(); var len, c; len = str.length; for (var i = 0; i < len; i++) { c = str.charCodeAt(i); if (c >= 0x010000 && c <= 0x10FFFF) { bytes.push(((c >> 18) & 0x07) | 0xF0); bytes.push(((c >> 12) & 0x3F) | 0x80); bytes.push(((c >> 6) & 0x3F) | 0x80); bytes.push((c & 0x3F) | 0x80); } else if (c >= 0x000800 && c <= 0x00FFFF) { bytes.push(((c >> 12) & 0x0F) | 0xE0); bytes.push(((c >> 6) & 0x3F) | 0x80); bytes.push((c & 0x3F) | 0x80); } else if (c >= 0x000080 && c <= 0x0007FF) { bytes.push(((c >> 6) & 0x1F) | 0xC0); bytes.push((c & 0x3F) | 0x80); } else { bytes.push(c & 0xFF); } } return bytes; } ``` #### byte[]进行base64编码 ``` // 编码 function byte2Base64(byteArray) { var jBase64 = Java.use('java.util.Base64'); return jBase64.getEncoder().encodeToString(byteArray); } // 解码 function byte2Base642(base64Str) { var jBase64 = Java.use('java.util.Base64'); return jBase64.getDecoder().decode(base64Str); } ``` #### 获取时间 ``` /** * 获取格式化时间 2022-05-10 19:17:49 * @returns {string} */ function getFormatDate() { var date = new Date(); var month = date.getMonth() + 1; var strDate = date.getDate(); var strHours = date.getHours(); var strMinutes = date.getMinutes(); var strSeconds = date.getSeconds() if (month >= 1 && month <= 9) { month = "0" + month; } if (strDate >= 0 && strDate <= 9) { strDate = "0" + strDate; } if (strHours >= 0 && strHours <= 9) { strHours = "0" + strHours; } if (strMinutes >= 0 && strMinutes <= 9) { strMinutes = "0" + strMinutes; } if (strSeconds >= 0 && strSeconds <= 9) { strSeconds = "0" + strSeconds; } var currentDate = date.getFullYear() + "-" + month + "-" + strDate + " " + strHours + ":" + strMinutes + ":" + strSeconds; return currentDate; } /** * 2022-05-10 19:17:49 * @param inputTime 参数是毫秒级时间戳 * */ function formatDate() { var date = new Date(new Date().getTime()); var y = date.getFullYear(); var m = date.getMonth() + 1; m = m < 10 ? ('0' + m) : m; var d = date.getDate(); d = d < 10 ? ('0' + d) : d; var h = date.getHours(); h = h < 10 ? ('0' + h) : h; var minute = date.getMinutes(); var second = date.getSeconds(); minute = minute < 10 ? ('0' + minute) : minute; second = second < 10 ? ('0' + second) : second; return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second; } ``` #### Map对象转String ``` /** * Map对象转String * @param map * @returns {string} */ function mapToString(map) { var keyset = map.keySet(); var it = keyset.iterator(); var str = "{"; while (it.hasNext()) { var keystr = it.next().toString(); var valuestr = map.get(keystr); str += '"' + keystr + '":"' + valuestr + '",'; } return str.trim(',') + "}"; } ``` #### java对象转String ``` /** * java对象转String * @param javaObj * @returns {*} */ function objectToString(javaObj) { var gson = Java.use('com.google.gson.Gson').$new(); return gson.toJson(javaObj); } ``` #### 打印堆栈 ``` function showStack() { let Throwable = Java.use("java.lang.Throwable"); let stackTraceString = Java.use("android.util.Log").getStackTraceString(Throwable.$new()) console.log(stackTraceString); } ``` ### 万能算法 ``` /** * Java层标准算法hook */ Java.perform(function () { /** 打印堆栈 */ function showStack() { let Throwable = Java.use("java.lang.Throwable"); let stackTraceString = Java.use("android.util.Log").getStackTraceString(Throwable.$new()) console.log(stackTraceString); } let ByteString = Java.use("com.android.okhttp.okio.ByteString"); /** * 字节数组转为Base64 */ function toBase64(tag, data) { console.log(tag + " Base64:" + ByteString.of(data).base64()); } /** * 字节数组转为16进制 */ function toHex(tag, data) { console.log(tag + " Hex:" + ByteString.of(data).hex()); } /** * 字节数组转为明文 */ function toUtf8(tag, data) { console.log(tag + " Utf8:" + ByteString.of(data).utf8()); } /** * 打印字节数组对应的输出数据 */ function printData(tag, data) { toBase64(tag, data); toHex(tag, data); toUtf8(tag, data); } /*** * 消息摘要算法hook * update 压入数据 * digest 返回加密结果 */ function hookMessageDigest() { let MessageDigest = Java.use("java.security.MessageDigest"); MessageDigest.update.overload('byte').implementation = function (b) { showStack(); console.log("MessageDigest.update.overload('byte') is called!"); let result = this.update.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " update param", Java.array('byte', [b])) console.log("============================================================"); return result; } MessageDigest.update.overload('[B').implementation = function (byteArr) { showStack(); console.log("MessageDigest.update.overload('[B') is called!"); let result = this.update.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " update param", byteArr); console.log("============================================================"); return result; } MessageDigest.digest.overload().implementation = function () { showStack(); console.log("MessageDigest.digest.overload() is called!"); let result = this.digest.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " digest result", result); console.log("============================================================"); return result; } MessageDigest.digest.overload('[B').implementation = function (byteArr) { showStack(); console.log("MessageDigest.digest.overload('[B') is called!"); let result = this.digest.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " digest param", byteArr); printData(algorithm + " digest result", result); console.log("============================================================"); return result; } MessageDigest.digest.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) { showStack(); console.log("MessageDigest.digest.overload('[B', 'int', 'int') is called!"); let result = this.digest.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " digest param", byteArr); printData(algorithm + " digest result", result); console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length); return result; } } /** * Mac算法hook * 1.init 初始化,秘钥 * 2.update 压入数据 * 3.doFinal 加密 */ function hookMac() { let Mac = Java.use("javax.crypto.Mac"); Mac.init.overload('java.security.Key').implementation = function (key) { showStack(); console.log("Mac.init.overload('java.security.Key') is called!"); let result = this.init.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " init key", key.getEncoded()) console.log("============================================================"); return result; } Mac.update.overload('byte').implementation = function (b) { showStack(); console.log("Mac.update.overload('byte') is called!"); let result = this.update.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " update param", Java.array('byte', [b])) console.log("============================================================"); return result; } Mac.update.overload('[B').implementation = function (byteArr) { showStack(); console.log("Mac.update.overload('[B') is called!"); let result = this.update.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " update param", byteArr) console.log("============================================================"); return result; } Mac.update.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) { showStack(); console.log("Mac.update.overload('[B', 'int', 'int') is called!"); let result = this.update.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " update param", byteArr) console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length); return result; } Mac.doFinal.overload().implementation = function () { showStack(); console.log("Mac.doFinal.overload() is called!"); let result = this.doFinal.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " doFinal result", result) console.log("============================================================"); return result; } } /** * DES,DESEde,AES,RSA * 1.init 加密类型,key,iv * 2.donFinal压入数据,得到结果 update压入结果有问题 */ function hookCipher() { function printResult(cipherObj, result, args) { let algorithm = cipherObj.getAlgorithm(); let mode; if (cipherObj.opmode.value === 1) { mode = "加密"; } else { mode = "解密"; } console.log(algorithm + " mode:", mode); if (cipherObj.getParameters() != null) { printData(algorithm + " key", cipherObj.getParameters().getEncoded()); printData(algorithm + " iv", cipherObj.getIV()); } printData(algorithm + " doFinal param", args[0]); printData(algorithm + " doFinal result", result); console.log("============================================================"); } let Cipher = Java.use("javax.crypto.Cipher"); // 不常用重载,打印调用即可,根据堆栈信息在具体去看 // init暂时注释 Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (key) { showStack(); console.log("Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom') is called!"); let result = this.apply(this, arguments); return result; } Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (key) { showStack(); console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom') is called!"); let result = this.apply(this, arguments); return result; } // ECB模式,不带iv Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function () { showStack(); console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom') is called!"); let result = this.init.apply(this, arguments); let algorithm = this.getAlgorithm(); let mode; if (arguments[0] === 1) { mode = "加密"; } else { mode = "解密"; } console.log(algorithm + " init mode:" + mode); try { // RSA使用私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析 printData(algorithm + " init key", arguments[1].getEncoded()); } catch (e) { console.log(e); } console.log("============================================================"); return result; } // CBC模式,带iv Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function () { showStack(); console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom') is called!"); let result = this.init.apply(this, arguments); let algorithm = this.getAlgorithm(); let ivParameterSpecObj = Java.cast(arguments[2], Java.use("javax.crypto.spec.IvParameterSpec")); let mode; if (arguments[0] === 1) { mode = "加密"; } else { mode = "解密"; } console.log(algorithm + " init mode:" + mode); printData(algorithm + " init key", arguments[1].getEncoded()); printData(algorithm + " init iv", ivParameterSpecObj.getIV()); console.log("============================================================"); return result; } Cipher.doFinal.overload().implementation = function () { showStack(); console.log("Cipher.doFinal.overload() is called!"); let result = this.doFinal.apply(this, arguments); printResult(this, result, arguments); return result; } Cipher.doFinal.overload('[B').implementation = function () { showStack(); console.log("Cipher.doFinal.overload('[B') is called!"); let result = this.doFinal.apply(this, arguments); printResult(this, result, arguments); return result; } Cipher.doFinal.overload('[B', 'int').implementation = function () { showStack(); console.log("Cipher.doFinal.overload('[B', 'int') is called!"); let result = this.doFinal.apply(this, arguments); printResult(this, result, arguments); return result; } Cipher.doFinal.overload('[B', 'int', 'int').implementation = function () { showStack(); console.log("Cipher.doFinal.overload('[B', 'int', 'int') is called!"); let result = this.doFinal.apply(this, arguments); printResult(this, result, arguments); return result; } Cipher.doFinal.overload('[B', 'int', 'int', '[B').implementation = function () { showStack(); console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B') is called!"); let result = this.doFinal.apply(this, arguments); printResult(this, result, arguments); return result; } Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function () { showStack(); console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int') is called!"); let result = this.doFinal.apply(this, arguments); printResult(this, result, arguments); return result; } } /** * 签名算法hook * 私钥 */ function hookSignature() { let Signature = Java.use("java.security.Signature"); Signature.initSign.overload('java.security.PrivateKey').implementation = function () { showStack(); console.log("Signature.initSign.overload('java.security.PrivateKey') is called!"); let result = this.initSign.apply(this, arguments); let algorithm = this.getAlgorithm(); try { // RSA使用Hex编码的私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析 printData(algorithm + " init key", arguments[0].getEncoded()); } catch (e) { console.log(JSON.stringify(arguments[0]) + "|" + e); } console.log("============================================================"); return result; } Signature.update.overload('byte').implementation = function () { showStack(); console.log("Signature.update.overload('byte') is called!"); let result = this.update.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " update param", Java.array('byte', [b])) console.log("============================================================"); return result; } Signature.update.overload('[B', 'int', 'int').implementation = function () { showStack(); console.log("Signature.update.overload('[B', 'int', 'int') is called!"); let result = this.update.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " update param", arguments[0]); console.log("============================================================"); return result; } Signature.sign.overload().implementation = function () { showStack(); console.log("Signature.sign.overload() is called!"); let result = this.sign.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " sign result", result); console.log("============================================================"); return result; } Signature.sign.overload('[B', 'int', 'int').implementation = function () { showStack(); console.log("Signature.sign.overload('[B', 'int', 'int') is called!"); let result = this.sign.apply(this, arguments); let algorithm = this.getAlgorithm(); printData(algorithm + " sign param", arguments[0]); printData(algorithm + " sign result", result); console.log("============================================================"); return result; } } /** * Base64hook */ function hookBase64() { let Base64 = Java.use("android.util.Base64"); Base64.encodeToString.overload('[B', 'int').implementation = function () { let result = this.encodeToString.apply(this, arguments); printData("Base64 param", arguments[0]); console.log("-------------------------------"); console.log("Base64 result:" + result); console.log("============================================================"); return result; } } // 消息摘要算法hook hookMessageDigest(); // Mac算法hook hookMac(); // hookCipher hookCipher(); // 数据签名算法hook hookSignature(); // hookBase64编码 hookBase64(); }) ``` ``` var N_ENCRYPT_MODE = 1 var N_DECRYPT_MODE = 2 function showStacks() { var Exception = Java.use("java.lang.Exception"); var ins = Exception.$new("Exception"); var straces = ins.getStackTrace(); if (undefined == straces || null == straces) { return; } console.log("============================= Stack strat======================="); console.log(""); for (var i = 0; i < straces.length; i++) { var str = " " + straces[i].toString(); console.log(str); } console.log(""); console.log("============================= Stack end=======================rn"); Exception.$dispose(); } //工具相关函数 var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', base64DecodeChars = new Array((-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), 62, (-1), (-1), (-1), 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, (-1), (-1), (-1), (-1), (-1), (-1), (-1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, (-1), (-1), (-1), (-1), (-1), (-1), 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, (-1), (-1), (-1), (-1), (-1)); function stringToBase64(e) { var r, a, c, h, o, t; for (c = e.length, a = 0, r = ''; a < c;) { if (h = 255 & e.charCodeAt(a++), a == c) { r += base64EncodeChars.charAt(h >> 2), r += base64EncodeChars.charAt((3 & h) << 4), r += '=='; break } if (o = e.charCodeAt(a++), a == c) { r += base64EncodeChars.charAt(h >> 2), r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4), r += base64EncodeChars.charAt((15 & o) << 2), r += '='; break } t = e.charCodeAt(a++), r += base64EncodeChars.charAt(h >> 2), r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4), r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6), r += base64EncodeChars.charAt(63 & t) } return r } function base64ToString(e) { var r, a, c, h, o, t, d; for (t = e.length, o = 0, d = ''; o < t;) { do r = base64DecodeChars[255 & e.charCodeAt(o++)]; while (o < t && r == -1); if (r == -1) break; do a = base64DecodeChars[255 & e.charCodeAt(o++)]; while (o < t && a == -1); if (a == -1) break; d += String.fromCharCode(r << 2 | (48 & a) >> 4); do { if (c = 255 & e.charCodeAt(o++), 61 == c) return d; c = base64DecodeChars[c] } while (o < t && c == -1); if (c == -1) break; d += String.fromCharCode((15 & a) << 4 | (60 & c) >> 2); do { if (h = 255 & e.charCodeAt(o++), 61 == h) return d; h = base64DecodeChars[h] } while (o < t && h == -1); if (h == -1) break; d += String.fromCharCode((3 & c) << 6 | h) } return d } function hexToBase64(str) { return base64Encode(String.fromCharCode.apply(null, str.replace(/r|n/g, "").replace(/([da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" "))); } function base64ToHex(str) { for (var i = 0, bin = base64Decode(str.replace(/[ rn]+$/, "")), hex = []; i < bin.length; ++i) { var tmp = bin.charCodeAt(i).toString(16); if (tmp.length === 1) tmp = "0" + tmp; hex[hex.length] = tmp; } return hex.join(""); } function hexToBytes(str) { var pos = 0; var len = str.length; if (len % 2 != 0) { return null; } len /= 2; var hexA = new Array(); for (var i = 0; i < len; i++) { var s = str.substr(pos, 2); var v = parseInt(s, 16); hexA.push(v); pos += 2; } return hexA; } function bytesToHex(arr) { var str = ''; var k, j; for (var i = 0; i < arr.length; i++) { k = arr[i]; j = k; if (k < 0) { j = k + 256; } if (j < 16) { str += "0"; } str += j.toString(16); } return str; } function stringToHex(str) { var val = ""; for (var i = 0; i < str.length; i++) { if (val == "") val = str.charCodeAt(i).toString(16); else val += str.charCodeAt(i).toString(16); } return val } function stringToBytes(str) { var ch, st, re = []; for (var i = 0; i < str.length; i++) { ch = str.charCodeAt(i); st = []; do { st.push(ch & 0xFF); ch = ch >> 8; } while (ch); re = re.concat(st.reverse()); } return re; } //将byte[]转成String的方法 function bytesToString(arr) { var str = ''; arr = new Uint8Array(arr); for (var i in arr) { str += String.fromCharCode(arr[i]); } return str; } function bytesToBase64(e) { var r, a, c, h, o, t; for (c = e.length, a = 0, r = ''; a < c;) { if (h = 255 & e[a++], a == c) { r += base64EncodeChars.charAt(h >> 2), r += base64EncodeChars.charAt((3 & h) << 4), r += '=='; break } if (o = e[a++], a == c) { r += base64EncodeChars.charAt(h >> 2), r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4), r += base64EncodeChars.charAt((15 & o) << 2), r += '='; break } t = e[a++], r += base64EncodeChars.charAt(h >> 2), r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4), r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6), r += base64EncodeChars.charAt(63 & t) } return r } function base64ToBytes(e) { var r, a, c, h, o, t, d; for (t = e.length, o = 0, d = []; o < t;) { do r = base64DecodeChars[255 & e.charCodeAt(o++)]; while (o < t && r == -1); if (r == -1) break; do a = base64DecodeChars[255 & e.charCodeAt(o++)]; while (o < t && a == -1); if (a == -1) break; d.push(r << 2 | (48 & a) >> 4); do { if (c = 255 & e.charCodeAt(o++), 61 == c) return d; c = base64DecodeChars[c] } while (o < t && c == -1); if (c == -1) break; d.push((15 & a) << 4 | (60 & c) >> 2); do { if (h = 255 & e.charCodeAt(o++), 61 == h) return d; h = base64DecodeChars[h] } while (o < t && h == -1); if (h == -1) break; d.push((3 & c) << 6 | h) } return d } //stringToBase64 stringToHex stringToBytes //base64ToString base64ToHex base64ToBytes // hexToBase64 hexToBytes // bytesToBase64 bytesToHex bytesToString Java.perform(function () { var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec'); secretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (a, b) { showStacks(); var result = this.$init(a, b); console.log("======================================"); console.log("算法名:" + b + "|str密钥:" + bytesToString(a)); console.log("算法名:" + b + "|Hex密钥:" + bytesToHex(a)); return result; } var DESKeySpec = Java.use('javax.crypto.spec.DESKeySpec'); DESKeySpec.$init.overload('[B').implementation = function (a) { showStacks(); var result = this.$init(a); console.log("======================================"); var bytes_key_des = this.getKey(); console.log("des密钥 |str " + bytesToString(bytes_key_des)); console.log("des密钥 |hex " + bytesToHex(bytes_key_des)); return result; } DESKeySpec.$init.overload('[B', 'int').implementation = function (a, b) { showStacks(); var result = this.$init(a, b); console.log("======================================"); var bytes_key_des = this.getKey(); console.log("des密钥 |str " + bytesToString(bytes_key_des)); console.log("des密钥 |hex " + bytesToHex(bytes_key_des)); return result; } var mac = Java.use('javax.crypto.Mac'); mac.getInstance.overload('java.lang.String').implementation = function (a) { showStacks(); var result = this.getInstance(a); console.log("======================================"); console.log("算法名:" + a); return result; } mac.update.overload('[B').implementation = function (a) { //showStacks(); this.update(a); console.log("======================================"); console.log("update:" + bytesToString(a)) } mac.update.overload('[B', 'int', 'int').implementation = function (a, b, c) { //showStacks(); this.update(a, b, c) console.log("======================================"); console.log("update:" + bytesToString(a) + "|" + b + "|" + c); } mac.doFinal.overload().implementation = function () { //showStacks(); var result = this.doFinal(); console.log("======================================"); console.log("doFinal结果: |str :" + bytesToString(result)); console.log("doFinal结果: |hex :" + bytesToHex(result)); console.log("doFinal结果: |base64 :" + bytesToBase64(result)); return result; } mac.doFinal.overload('[B').implementation = function (a) { //showStacks(); var result = this.doFinal(a); console.log("======================================"); console.log("doFinal参数: |str :" + bytesToString(a)); console.log("doFinal结果: |str :" + bytesToString(result)); console.log("doFinal结果: |hex :" + bytesToHex(result)); console.log("doFinal结果: |base64 :" + bytesToBase64(result)); return result; } var md = Java.use('java.security.MessageDigest'); md.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (a, b) { //showStacks(); console.log("======================================"); console.log("算法名:" + a); return this.getInstance(a, b); } md.getInstance.overload('java.lang.String').implementation = function (a) { //showStacks(); console.log("======================================"); console.log("算法名:" + a); return this.getInstance(a); } md.update.overload('[B').implementation = function (a) { //showStacks(); console.log("======================================"); console.log("update:" + bytesToString(a)) return this.update(a); } md.update.overload('[B', 'int', 'int').implementation = function (a, b, c) { //showStacks(); console.log("======================================"); console.log("update:" + bytesToString(a) + "|" + b + "|" + c); return this.update(a, b, c); } md.digest.overload().implementation = function () { //showStacks(); console.log("======================================"); var result = this.digest(); console.log("digest结果:" + bytesToHex(result)); console.log("digest结果:" + bytesToBase64(result)); return result; } md.digest.overload('[B').implementation = function (a) { //showStacks(); console.log("======================================"); console.log("digest参数:" + bytesToString(a)); var result = this.digest(a); console.log("digest结果:" + bytesToHex(result)); console.log("digest结果:" + bytesToBase64(result)); return result; } var ivParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec'); ivParameterSpec.$init.overload('[B').implementation = function (a) { //showStacks(); var result = this.$init(a); console.log("======================================"); console.log("iv向量: |str:" + bytesToString(a)); console.log("iv向量: |hex:" + bytesToHex(a)); return result; } var cipher = Java.use('javax.crypto.Cipher'); cipher.getInstance.overload('java.lang.String').implementation = function (a) { //showStacks(); var result = this.getInstance(a); console.log("======================================"); console.log("模式填充:" + a); return result; } cipher.init.overload('int', 'java.security.Key').implementation = function (a, b) { //showStacks(); var result = this.init(a, b); console.log("======================================"); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } var bytes_key = b.getEncoded(); console.log("init key:" + "|str密钥:" + bytesToString(bytes_key)); console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key)); return result; } cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function (a, b) { //showStacks(); var result = this.init(a, b); console.log("======================================"); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } return result; } cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (a, b, c) { //showStacks(); var result = this.init(a, b, c); console.log("======================================"); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } var bytes_key = b.getEncoded(); console.log("init key:" + "|str密钥:" + bytesToString(bytes_key)); console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key)); return result; } cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (a, b, c) { //showStacks(); var result = this.init(a, b, c); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } return result; } cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function (a, b, c) { //showStacks(); var result = this.init(a, b, c); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } var bytes_key = b.getEncoded(); console.log("init key:" + "|str密钥:" + bytesToString(bytes_key)); console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key)); return result; } cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function (a, b, c) { //showStacks(); var result = this.init(a, b, c); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } var bytes_key = b.getEncoded(); console.log("init key:" + "|str密钥:" + bytesToString(bytes_key)); console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key)); return result; } cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (a, b, c, d) { //showStacks(); var result = this.init(a, b, c, d); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } var bytes_key = b.getEncoded(); console.log("init key:" + "|str密钥:" + bytesToString(bytes_key)); console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key)); return result; } cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function (a, b, c, d) { //showStacks(); var result = this.update(a, b, c, d); if (N_ENCRYPT_MODE == a) { console.log("init | 加密模式"); } else if(N_DECRYPT_MODE == a) { console.log("init | 解密模式"); } var bytes_key = b.getEncoded(); console.log("init key:" + "|str密钥:" + bytesToString(bytes_key)); console.log("init key:" + "|Hex密钥:" + bytesToHex(bytes_key)); return result; } cipher.update.overload('[B').implementation = function (a) { //showStacks(); var result = this.update(a); console.log("======================================"); console.log("update:" + bytesToString(a)); return result; } cipher.update.overload('[B', 'int', 'int').implementation = function (a, b, c) { //showStacks(); var result = this.update(a, b, c); console.log("======================================"); console.log("update:" + bytesToString(a) + "|" + b + "|" + c); return result; } cipher.doFinal.overload().implementation = function () { //showStacks(); var result = this.doFinal(); console.log("======================================"); console.log("doFinal结果: |str :" + bytesToString(result)); console.log("doFinal结果: |hex :" + bytesToHex(result)); console.log("doFinal结果: |base64 :" + bytesToBase64(result)); return result; } cipher.doFinal.overload('[B').implementation = function (a) { //showStacks(); var result = this.doFinal(a); console.log("======================================"); console.log("doFinal参数: |str :" + bytesToString(a)); console.log("doFinal结果: |str :" + bytesToString(result)); console.log("doFinal结果: |hex :" + bytesToHex(result)); console.log("doFinal结果: |base64 :" + bytesToBase64(result)); return result; } var x509EncodedKeySpec = Java.use('java.security.spec.X509EncodedKeySpec'); x509EncodedKeySpec.$init.overload('[B').implementation = function (a) { //showStacks(); var result = this.$init(a); console.log("======================================"); console.log("RSA密钥:" + bytesToBase64(a)); return result; } var rSAPublicKeySpec = Java.use('java.security.spec.RSAPublicKeySpec'); rSAPublicKeySpec.$init.overload('java.math.BigInteger', 'java.math.BigInteger').implementation = function (a, b) { //showStacks(); var result = this.$init(a, b); console.log("======================================"); //console.log("RSA密钥:" + bytesToBase64(a)); console.log("RSA密钥N:" + a.toString(16)); console.log("RSA密钥E:" + b.toString(16)); return result; } var KeyPairGenerator = Java.use('java.security.KeyPairGenerator'); KeyPairGenerator.generateKeyPair.implementation = function () { //showStacks(); var result = this.generateKeyPair(); console.log("======================================"); var str_private = result.getPrivate().getEncoded(); var str_public = result.getPublic().getEncoded(); console.log("公钥 |hex" + bytesToHex(str_public)); console.log("私钥 |hex" + bytesToHex(str_private)); return result; } KeyPairGenerator.genKeyPair.implementation = function () { //showStacks(); var result = this.genKeyPair(); console.log("======================================"); var str_private = result.getPrivate().getEncoded(); var str_public = result.getPublic().getEncoded(); console.log("公钥 |hex" + bytesToHex(str_public)); console.log("私钥 |hex" + bytesToHex(str_private)); return result; } }); ```