免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
内容参考于:图灵Python学院
本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。
工具下载:
链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3
提取码:6tw3
复制这段内容后打开百度网盘手机App,操作更方便哦
上一个内容:20.安卓逆向-frida基础-hook分析调试技巧2-hookDES
上一个内容通过使用FirdaHook了DES算法,并成功得到了明文、key、iv,本次接着继续
hookAES
首先是AES算法标准实现
![]()
package com.example.course1.suanfa; import android.util.Base64; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES { public static String aes(String args) throws Exception{ SecretKeySpec key = new SecretKeySpec("123456789abcdef1234567890abcdef".getBytes(), "AES"); AlgorithmParameterSpec iv = new IvParameterSpec("1234567890abcdef".getBytes()); Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding"); aes.init(1, key, iv); return Base64.encodeToString(aes.doFinal(args.getBytes("UTF-8")), 0); } }
Frida Hook脚本代码:在DES基础上改的
function bytesToHex(arr) { var str = ""; for (var i = 0; i < arr.length; i++) { var tmp = arr[i]; if (tmp < 0) { tmp = (255 + tmp + 1).toString(16); } else { tmp = tmp.toString(16); } if (tmp.length == 1) { tmp = "0" + tmp; } str += tmp; } return str; } function bytesToBase64(e) { var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 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 bytesToString(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); } str += String.fromCharCode(parseInt(store, 2)); i += bytesLength - 1; } else { str += String.fromCharCode(_arr[i]); } } return str; } function _log() { console.log("=====================================================================") } function main() { Java.perform(function () { // 获取 iv var IvParameterSpec = Java.use("javax.crypto.spec.IvParameterSpec") IvParameterSpec.$init.overload("[B").implementation = function(str) { console.log(`DES IV bytesToString:${bytesToString(str)}`) console.log(`DES IV bytesToHex:${bytesToHex(str)}`) return this.$init(str) } var Cipher = Java.use("javax.crypto.Cipher") Cipher.getInstance.overload('java.lang.String').implementation = function(str) { console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String'):${str}`) return this.getInstance(str) } Cipher.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function(str1,str2) { console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String', 'java.lang.String') :${str1} || ${str2}`) return this.getInstance(str1, str2) } Cipher.update.overload('[B').implementation = function(str) { console.log(`DES 明文 Cipher.update.overload('[B') bytesToString:${bytesToString(str)}`) return this.update(str) } Cipher.update.overload('[B', 'int', 'int').implementation = function(str,i1, i2) { console.log(`DES 明文 Cipher.update.overload('[B', 'int', 'int') :${bytesToString(str)} 入参2:${i1} 入参3:${i2}`) return this.update(str, i1, i2) } Cipher.doFinal.overload('[B').implementation = function(str) { console.log(`des密文入参 Cipher.doFinal.overload('[B') bytesToString:${bytesToString(str)}`) console.log(`des密文入参 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(str)}`) var m = this.doFinal(str) console.log(`des密文返回值 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(m)}`) console.log(`des密文返回值 Cipher.doFinal.overload('[B') bytesToBase64:${bytesToBase64(m)}`) return m } Cipher.doFinal.overload().implementation = function() { var m = this.doFinal() console.log(`des密文返回值 Cipher.doFinal.overload() bytesToHex:${bytesToHex(m)}`) console.log(`des密文返回值 Cipher.doFinal.overload() bytesToBase64:${bytesToBase64(m)}`) return m } var SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec") SecretKeySpec.$init.overload('[B','java.lang.String').implementation = function (b,str){ _log() console.log(`${str}算法 SecretKeySpec.$init.overload('[B','java.lang.String'),key:${bytesToString(b)}`) return this.$init(b,str) } }) } main()
![]()
AES比上一个内容中的DES多了下方的代码,其它的代码都是从DES中复制过来的
![]()
SHA算法
首先是sha算法的标准实现,sha算法和MD5算法一样,所以它可以直接使用MD5的FridaHook脚本
![]()
使用MD5的FridaHook脚本效果图
![]()
HMAC算法
首先HMAC算法的标准实现
![]()
package com.example.course1.suanfa; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class HMAC { public static String mac_1(String args) throws NoSuchAlgorithmException, InvalidKeyException { String str = "HmacSHA1"; SecretKey key = new SecretKeySpec("FridaHook".getBytes(), str); Mac mac = Mac.getInstance(str); mac.init(key); mac.update(args.getBytes()); byte[] digest = mac.doFinal(); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } public static String mac_2(String args) throws NoSuchAlgorithmException, InvalidKeyException{ String str = "HmacSHA1"; SecretKey key = new SecretKeySpec("FridaHook".getBytes(), str); Mac mac = Mac.getInstance(str); mac.init(key); mac.update(args.getBytes(),2,5); byte[] digest = mac.doFinal("xialuo".getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } }
FridaHook脚本:与AES的FridaHook脚本差不多,直接在AES的FridaHook文件里写的
![]()
function bytesToHex(arr) { var str = ""; for (var i = 0; i < arr.length; i++) { var tmp = arr[i]; if (tmp < 0) { tmp = (255 + tmp + 1).toString(16); } else { tmp = tmp.toString(16); } if (tmp.length == 1) { tmp = "0" + tmp; } str += tmp; } return str; } function bytesToBase64(e) { var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 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 bytesToString(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); } str += String.fromCharCode(parseInt(store, 2)); i += bytesLength - 1; } else { str += String.fromCharCode(_arr[i]); } } return str; } function _log() { console.log("=====================================================================") } function main() { Java.perform(function () { var suanfaName=''; // 获取 iv var IvParameterSpec = Java.use("javax.crypto.spec.IvParameterSpec") IvParameterSpec.$init.overload("[B").implementation = function(str) { console.log(`${suanfaName} IV bytesToString:${bytesToString(str)}`) console.log(`${suanfaName} IV bytesToHex:${bytesToHex(str)}`) return this.$init(str) } var Cipher = Java.use("javax.crypto.Cipher") Cipher.getInstance.overload('java.lang.String').implementation = function(str) { console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String'):${str}`) return this.getInstance(str) } Cipher.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function(str1,str2) { console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String', 'java.lang.String') :${str1} || ${str2}`) return this.getInstance(str1, str2) } Cipher.update.overload('[B').implementation = function(str) { console.log(`${suanfaName} 明文 Cipher.update.overload('[B') bytesToString:${bytesToString(str)}`) return this.update(str) } Cipher.update.overload('[B', 'int', 'int').implementation = function(str,i1, i2) { console.log(`${suanfaName} 明文 Cipher.update.overload('[B', 'int', 'int') :${bytesToString(str)} 入参2:${i1} 入参3:${i2}`) return this.update(str, i1, i2) } Cipher.doFinal.overload('[B').implementation = function(str) { console.log(`${suanfaName}密文入参 Cipher.doFinal.overload('[B') bytesToString:${bytesToString(str)}`) console.log(`${suanfaName}密文入参 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(str)}`) var m = this.doFinal(str) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload('[B') bytesToBase64:${bytesToBase64(m)}`) return m } Cipher.doFinal.overload().implementation = function() { var m = this.doFinal() console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload() bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload() bytesToBase64:${bytesToBase64(m)}`) return m } var SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec") SecretKeySpec.$init.overload('[B','java.lang.String').implementation = function (b,str){ _log() suanfaName = str console.log(`${str}算法 SecretKeySpec.$init.overload('[B','java.lang.String'),key:${bytesToString(b)}`) return this.$init(b,str) } var Mac = Java.use("javax.crypto.Mac") Mac.update.overload('[B').implementation = function(str) { console.log(`${suanfaName} 明文 Cipher.update.overload('[B') bytesToString:${bytesToString(str)}`) return this.update(str) } Mac.update.overload('[B', 'int', 'int').implementation = function(str,i1, i2) { console.log(`${suanfaName} 明文 Cipher.update.overload('[B', 'int', 'int') :${bytesToString(str)} 入参2:${i1} 入参3:${i2}`) return this.update(str, i1, i2) } Mac.doFinal.overload('[B').implementation = function(str) { console.log(`${suanfaName}密文入参 Cipher.doFinal.overload('[B') bytesToString:${bytesToString(str)}`) console.log(`${suanfaName}密文入参 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(str)}`) var m = this.doFinal(str) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload('[B') bytesToBase64:${bytesToBase64(m)}`) return m } Mac.doFinal.overload().implementation = function() { var m = this.doFinal() console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload() bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload() bytesToBase64:${bytesToBase64(m)}`) return m } }) } main()
RSA算法非对称加密算法,需要知道的它是 公钥还是私钥、key、明文、加密完的结果
RSA算法标准实现
package com.example.course1.suanfa; import android.util.Base64; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; public class RSA { public static String 公钥 = "vvvvvv"; public static String 私钥 = "qqqqqq"; public static PublicKey getPublicKey(String key) throws Exception { return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode(key, 0))); } public static PrivateKey getPrivateKey(String key) throws Exception { return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(key, 0))); } public static String sign(String data)throws Exception{ PrivateKey priK = getPrivateKey(私钥); Signature sig = Signature.getInstance("SHA256withRSA"); sig.initSign(priK); sig.update(data.getBytes()); return Base64.encodeToString(sig.sign(), 0); } public static boolean cerify(byte[]data, byte[] sign)throws Exception{ PublicKey pubK = getPublicKey(公钥); Signature sig = Signature.getInstance("SHA256withRSA"); return true; } public static String rsa(String args)throws Exception{ return Base64.encodeToString(encrypt("xialuo"), 0); } private static byte[] encrypt(String plaintext) throws Exception { PublicKey publicKey = getPublicKey(公钥); Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC"); cipher.init(1, publicKey); return cipher.doFinal(plaintext.getBytes()); } private static byte[] decrypt(String encrypted) throws Exception { PublicKey publicKey = getPublicKey(公钥); Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC"); cipher.init(2, publicKey); return cipher.doFinal(encrypted.getBytes()); } }
Frida Hook脚本使用HMAC的,如下图可以得到明文、密文,没法得到钥匙
![]()
然后它的钥匙通过hook Base64的decode方法来得到,如下图红框
![]()
通过hook X509的构造方法来实现获取钥匙,如下图
![]()
使用FridaHook真实的app,app很复杂但也得到了一些东西
![]()
整合之后的Frida Hook算法脚本,它可以hook AES算法、DES算法、HMAC算法、MD5算法、RSA算法、SHA算法
function bytesToHex(arr) { var str = ""; for (var i = 0; i < arr.length; i++) { var tmp = arr[i]; if (tmp < 0) { tmp = (255 + tmp + 1).toString(16); } else { tmp = tmp.toString(16); } if (tmp.length == 1) { tmp = "0" + tmp; } str += tmp; } return str; } function bytesToBase64(e) { var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 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 bytesToString(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); } str += String.fromCharCode(parseInt(store, 2)); i += bytesLength - 1; } else { str += String.fromCharCode(_arr[i]); } } return str; } function _log() { console.log("=====================================================================") } function main() { Java.perform(function () { /** * MD5 * */ var MessageDigest = Java.use('java.security.MessageDigest') /** * hook Update 方法获取明文数据 * */ MessageDigest.getInstance.overload('java.lang.String').implementation = function (str) { _log() console.log('算法名:',str) return this.getInstance(str) } MessageDigest.update.overload('byte').implementation=function (str) { console.log(`byte算法入参:${str}`) return this.update(str) } MessageDigest.update.overload('java.nio.ByteBuffer').implementation=function (str) { console.log(`java.nio.ByteBuffer算法入参:${str}`) return this.update(str) } MessageDigest.update.overload('[B').implementation=function (str) { // [B是字节需要转成字符串我们人才认识,toUtf8方法可以把字节转换文字(文字指的是字母、数字、中文、英文) console.log(`update.overload('[B') bytesToString 算法入参:${bytesToString(str)}`) console.log(`update.overload('[B') bytesToBase64 算法入参:${bytesToBase64(str)}`) return this.update(str) } MessageDigest.update.overload('[B', 'int', 'int').implementation=function (str, a1, a2) { console.log(`'[B', 'int', 'int算法 入参1:${str},入参2:${a1},入参3:${a2}`) return this.update(str, a1, a2) } /** * hook digest 方法获取加密之后的数据 * */ MessageDigest.digest.overload().implementation=function () { var res = this.digest() console.log(`digest.overload()返回值:${bytesToHex(res)}`); console.log(`digest.overload()bytesToHex返回值:${bytesToHex(res)}`); console.log(`digest.overload()bytesToBase64返回值:${bytesToBase64(res)}`); return res } MessageDigest.digest.overload("[B").implementation=function (arr) { console.log(`digest.overload("[B") bytesToString 入参:${bytesToString(arr)}`); console.log(`digest.overload("[B") bytesToBase64 入参:${bytesToBase64(arr)}`); var res = this.digest(arr); console.log(`digest.overload("[B")bytesToString返回值:${bytesToString(res)}`); console.log(`digest.overload("[B")bytesToHex返回值:${bytesToHex(res)}`); console.log(`digest.overload("[B")bytesToBase64返回值:${bytesToBase64(res)}`); return res } // =========================================================DES================================================================ var SecretKeyFactory = Java.use("javax.crypto.SecretKeyFactory") SecretKeyFactory.getInstance.overload('java.lang.String').implementation = function(str) { console.log(`算法是----》${str}《------------------------------------------------------------》`) return this.getInstance(str) } // 获取 key var DESKeySpec = Java.use("javax.crypto.spec.DESKeySpec") DESKeySpec.$init.overload('[B').implementation = function(str) { console.log(`DESKeySpec.$init.overload--》DES的Key bytesToString:${bytesToString(str)}`) console.log(`DESKeySpec.$init.overload--》DES的key bytesToHexKey:${bytesToHex(str)}`) return this.$init(str) } // =========================================================AES================================================================ var suanfaName=''; // 获取 iv var IvParameterSpec = Java.use("javax.crypto.spec.IvParameterSpec") IvParameterSpec.$init.overload("[B").implementation = function(str) { console.log(`${suanfaName} IV bytesToString:${bytesToString(str)}`) console.log(`${suanfaName} IV bytesToHex:${bytesToHex(str)}`) return this.$init(str) } var Cipher = Java.use("javax.crypto.Cipher") Cipher.getInstance.overload('java.lang.String').implementation = function(str) { console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String'):${str}`) return this.getInstance(str) } Cipher.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function(str1,str2) { console.log(`Cipher 加密模式 Cipher.getInstance.overload('java.lang.String', 'java.lang.String') :${str1} || ${str2}`) return this.getInstance(str1, str2) } Cipher.update.overload('[B').implementation = function(str) { console.log(`${suanfaName} 明文 Cipher.update.overload('[B') bytesToString:${bytesToString(str)}`) return this.update(str) } Cipher.update.overload('[B', 'int', 'int').implementation = function(str,i1, i2) { console.log(`${suanfaName} 明文 Cipher.update.overload('[B', 'int', 'int') :${bytesToString(str)} 入参2:${i1} 入参3:${i2}`) return this.update(str, i1, i2) } Cipher.doFinal.overload('[B').implementation = function(str) { console.log(`${suanfaName}密文入参 Cipher.doFinal.overload('[B') bytesToString:${bytesToString(str)}`) console.log(`${suanfaName}密文入参 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(str)}`) var m = this.doFinal(str) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload('[B') bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload('[B') bytesToBase64:${bytesToBase64(m)}`) return m } Cipher.doFinal.overload().implementation = function() { var m = this.doFinal() console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload() bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Cipher.doFinal.overload() bytesToBase64:${bytesToBase64(m)}`) return m } var SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec") SecretKeySpec.$init.overload('[B','java.lang.String').implementation = function (b,str){ _log() suanfaName = str console.log(`${str}算法 SecretKeySpec.$init.overload('[B','java.lang.String'),bytesToString key:${bytesToString(b)}`) console.log(`${str}算法 SecretKeySpec.$init.overload('[B','java.lang.String'),bytesToBase64 key:${bytesToBase64(b)}`) return this.$init(b,str) } var Mac = Java.use("javax.crypto.Mac") Mac.update.overload('[B').implementation = function(str) { console.log(`${suanfaName} Mac.update.overload('[B') 明文 bytesToString:${bytesToString(str)}`) return this.update(str) } Mac.update.overload('[B', 'int', 'int').implementation = function(str,i1, i2) { console.log(`${suanfaName} Mac.update.overload('[B', 'int', 'int') 明文 :${bytesToString(str)} 入参2:${i1} 入参3:${i2}`) return this.update(str, i1, i2) } Mac.doFinal.overload('[B').implementation = function(str) { console.log(`${suanfaName}密文入参 Mac.doFinal.overload('[B') bytesToString:${bytesToString(str)}`) console.log(`${suanfaName}密文入参 Mac.doFinal.overload('[B') bytesToHex:${bytesToHex(str)}`) var m = this.doFinal(str) console.log(`${suanfaName}密文返回值 Mac.doFinal.overload('[B') bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Mac.doFinal.overload('[B') bytesToBase64:${bytesToBase64(m)}`) return m } Mac.doFinal.overload().implementation = function() { var m = this.doFinal() console.log(`${suanfaName}密文返回值 Mac.doFinal.overload() bytesToHex:${bytesToHex(m)}`) console.log(`${suanfaName}密文返回值 Mac.doFinal.overload() bytesToBase64:${bytesToBase64(m)}`) return m } var Base64 = Java.use("android.util.Base64") Base64.decode.overload('java.lang.String', 'int').implementation = function(str, i) { _log() console.log(`Base64.decode.overload('java.lang.String', 'int')入参1:${str} 入参2:${i}`) return this.decode(str, i) } var X509EncodedKeySpec = Java.use('java.security.spec.X509EncodedKeySpec') X509EncodedKeySpec.$init.overload('[B').implementation = function (b){ _log() console.log(`RSA算法 X509EncodedKeySpec 入参钥匙:${bytesToBase64(b)}`) return this.$init(b) } }) } main()