本文介绍了使用Frida进行加密参数hook的实战技巧,包括Python和JavaScript的实现,无需应用脱壳,适用于加密参数的动态分析。

一、python终极版

import frida  # 导入frida模块
import sys  # 导入sys模块

jscode = """
function showStacks() {
    Java.perform(function() {
        send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
        var kgh = Java.use("com.kc.openset.util.VerifyUtil");
            kgh.getMD5Verify.overload('java.lang.String','java.lang.String').implementation = function (x1,x2) {
                console.log("getMD5Verify x1:",x1);
                console.log("getMD5Verify x2:",x2);
                var result = this.getMD5Verify(x1,x2);
                    console.log(result);
                    return result;
     
                
                }
    });
}

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;
}

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);
        send("======================================");
        send("算法名:" + b + "|Dec密钥:" + bytesToString(a));
        send("算法名:" + b + "|Hex密钥:" + bytesToHex(a));
        return result;
    }
    var mac = Java.use('javax.crypto.Mac');
    mac.getInstance.overload('java.lang.String').implementation = function (a) {
        showStacks();
        var result = this.getInstance(a);
        send("======================================");
        send("算法名:" + a);
        return result;
    }
    mac.update.overload('[B').implementation = function (a) {
        showStacks();
        this.update(a);
        send("======================================");
        send("update:" + bytesToString(a))
    }
    mac.update.overload('[B','int','int').implementation = function (a,b,c) {
        showStacks();
        this.update(a,b,c)
        send("======================================");
        send("update:" + bytesToString(a) + "|" + b + "|" + c);
    }
    mac.doFinal.overload().implementation = function () {
        showStacks();
        var result = this.doFinal();
        send("======================================");
        send("doFinal结果(hex):" + bytesToHex(result));
        send("doFinal结果(base64):" + bytesToBase64(result));
        return result;
    }
    mac.doFinal.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.doFinal(a);
        send("======================================");
        send("doFinal参数:" + bytesToString(a));
        send("doFinal结果(hex):" + bytesToHex(result));
        send("doFinal结果(base):" + 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();
        send("======================================");
        send("算法名:" + a);
        return this.getInstance(a, b);
    }
    md.getInstance.overload('java.lang.String').implementation = function (a) {
        showStacks();
        send("======================================");
        send("算法名:" + a);
        return this.getInstance(a);
    }
    md.update.overload('[B').implementation = function (a) {
        showStacks();
        send("======================================");
        send("update:" + bytesToString(a))
        return this.update(a);
    }
    md.update.overload('[B','int','int').implementation = function (a,b,c) {
        showStacks();
        send("======================================");
        send("update:" + bytesToString(a) + "|" + b + "|" + c);
        return this.update(a,b,c);
    }
    md.digest.overload().implementation = function () {
        showStacks();
        send("======================================");
        var result = this.digest();
        send("digest结果(hex):" + bytesToHex(result));
        send("digest结果(base64):" + bytesToBase64(result));
        return result;
    }
    md.digest.overload('[B').implementation = function (a) {
        showStacks();
        send("======================================");
        send("digest参数:" + bytesToString(a));
        var java_string = Java.use("java.lang.String");
        console.log('bArr to string: ' + java_string.$new(a));
        console.log(bytesToString(a));
        var result = this.digest(a);
        send("digest结果(hex):" + bytesToHex(result));
        send("digest结果(base64):" + 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);
        send("======================================");
        send("iv向量:" + bytesToString(a));
        send("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);
        send("======================================");
        send("模式填充:" + a);
        return result;
    }
    cipher.update.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.update(a);
        send("======================================");
        send("update:" + bytesToString(a));
        return result;
    }
    cipher.update.overload('[B','int','int').implementation = function (a,b,c) {
        showStacks();
        var result = this.update(a,b,c);
        send("======================================");
        send("update:" + bytesToString(a) + "|" + b + "|" + c);
        return result;
    }
    cipher.doFinal.overload().implementation = function () {
        showStacks();
        var result = this.doFinal();
        send("======================================");
        send("doFinal结果(hex):" + bytesToHex(result));
        send("doFinal结果(base64):" + bytesToBase64(result));
        return result;
    }
    cipher.doFinal.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.doFinal(a);
        send("======================================");
        send("doFinal参数:" + bytesToString(a));
        send("doFinal结果(hex):" + bytesToHex(result));
        send("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);
        send("======================================");
        send("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);
        send("======================================");
        //send("RSA密钥:" + bytesToBase64(a));
        send("RSA密钥N:" + a.toString(16));
        send("RSA密钥E:" + b.toString(16));
        return result;
    }
});
"""


def on_message(message, data):  # js中执行send函数后要回调的函数
    if message["type"] == "send":
        print("[*] {0}".format(message["payload"]))
    else:
        print(message)


process = frida.get_usb_device().attach('app名')  # app名
script = process.create_script(jscode)  # 创建js脚本
script.on('message', on_message)  # 加载回调函数,也就是js中执行send函数规定要执行的python函数
script.load()  # 加载脚本
sys.stdin.read()

二、python终极版2

# -*- coding: UTF-8 -*-
# 代码引用自 guyezhou51

import frida
import sys
import datetime


def on_message(message, data):      # 该函数可在frida中使用send(a); 输出python类型内容
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)


def get_js():
    htmlstr = '''
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;
    }
    mylog("===================== Stack strat=======================","","",0);    
    for (var i = 0; i < straces.length; i++) {
        var str = "   " + straces[i].toString();
        mylog(str,"","",0);
    }
    mylog("====================== Stack end=======================","","",0);
    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 bytesToHex(arr) {
    var str = '';
    arr = new Uint8Array(arr);
    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;
};
//将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) {
    e = new Uint8Array(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;
};
//stringToBase64 stringToHex stringToBytes
//base64ToString base64ToHex base64ToBytes
//               hexToBase64  hexToBytes    
// bytesToBase64 bytesToHex bytesToString
function mylog(s,code,s2,ii){
    if(ii==1){ 
        //输出hex类型
        var str =  bytesToHex(code)+s2;
        console.log(s+" |HEX :"+str);
        send(s+" |HEX :"+str);
        //输出base64
        str = bytesToBase64(code)+s2;
        console.log( s+" |BASE64 :"+str);
        send(s+" |BASE64 :"+str);
        //输出string类型
        str =  bytesToString(code)+s2;
        console.log(s+" |str :"+str);
        send(s+" |str :"+str);
    }else{
        console.log(s);
        send(s);
    }
};
Java.perform(function () {
    var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');
    var AE算法名称 = null;
    secretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (a, b) {
        showStacks();
        var result = this.$init(a, b);
        mylog("======================================","","",0);
        mylog("算法名:" + b + "| 密钥" , a,"",1);   
        AE算法名称=b;    
        return result;
    };
    secretKeySpec.$init.overload('[B', 'int','int','java.lang.String').implementation = function (a,i1,i2, b) {
        showStacks();
        var result = this.$init(a,i1,i2,b);
        mylog("======================================","","",0);
        mylog("算法名:" + b + "| 密钥" , a,"    |开始取的位置"+i1+"取长度:"+i2,1);   
        AE算法名称=b;    
        return result;
    };
    var DESKeySpec = Java.use('javax.crypto.spec.DESKeySpec');
    DESKeySpec.$init.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.$init(a);
        mylog("======================================","","",0);
        var bytes_key_des = this.getKey();
        mylog("des密钥 " ,bytes_key_des,"",1);        
        return result;
    };
    DESKeySpec.$init.overload('[B', 'int').implementation = function (a, b) {
        showStacks();
        var result = this.$init(a, b);
        mylog("======================================","","",0);
        var bytes_key_des = this.getKey();
        mylog("des密钥 " , bytes_key_des,"",1);      
        return result;
    };
    //3des
    var DESedeKeySpec = Java.use('javax.crypto.spec.DESedeKeySpec');
    DESedeKeySpec.$init.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.$init(a);
        mylog("======================================","","",0);
        var bytes_key_des = this.getKey();
        mylog("des密钥 " ,bytes_key_des,"",1);        
        return result;
    };
    DESedeKeySpec.$init.overload('[B', 'int').implementation = function (a, b) {
        showStacks();
        var result = this.$init(a, b);
        mylog("======================================","","",0);
        var bytes_key_des = this.getKey();
        mylog("des密钥 " , bytes_key_des,"",1);      
        return result;
    };
    var mac = Java.use('javax.crypto.Mac');
    var MAC算法名称=null;
    mac.getInstance.overload('java.lang.String').implementation = function (a) {
        showStacks();
        var result = this.getInstance(a);
        mylog("======================================","","",0);
        mylog("Mac算法名:" + a,"","",0);
        MAC算法名称 =a;
        return result;
    };
    mac.update.overload('[B').implementation = function (a) {
        showStacks();
        this.update(a);
        mylog("======================================","","",0);
        mylog(MAC算法名称+"update:" ,a,"",1);
    };
    mac.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
        showStacks();
        this.update(a, b, c);
        mylog("======================================","","",0);
        mylog(MAC算法名称+"update:" , a , "|" + b + "|" + c,1);      
    };
    mac.update.overload('java.nio.ByteBuffer').implementation = function (a) {
        showStacks();
        this.update(a);
        mylog("======================================","","",0);
        mylog(MAC算法名称+"update:" ,a.array() , "",1);      
    };
    mac.doFinal.overload().implementation = function () {
        showStacks();
        var result = this.doFinal();
        mylog("======================================","","",0);
        mylog(MAC算法名称+"doFinal结果:", result,"",1);
        return result;
    };
    mac.doFinal.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.doFinal(a);
        mylog("======================================","","",0);
        mylog(MAC算法名称+"doFinal参数:",a,"",1);
        return result;
    };
    mac.doFinal.overload('[B','int').implementation = function (a,b) {
        showStacks();
        var result = this.doFinal(a,b);
        mylog("======================================","","",0);
        mylog(MAC算法名称+"doFinal参数:",a,"  |  "+b,1);
        return result;
    };
    var md = Java.use('java.security.MessageDigest');
    var HX算法名称=null;
    md.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (a, b) {
        showStacks();
        mylog("======================================","","",0);
        mylog("算法名:" + a,"","",0);
        HX算法名称 = a;
        return this.getInstance(a, b);
    };
    md.getInstance.overload('java.lang.String', 'java.security.Provider').implementation = function (a, b) {
        showStacks();
        mylog("======================================","","",0);
        mylog("算法名:" + a,"","",0);
        HX算法名称 = a;
        return this.getInstance(a, b);
    };
    md.getInstance.overload('java.lang.String').implementation = function (a) {
        showStacks();
        mylog("======================================","","",0);
        mylog("算法名:" + a,"","",0);
        HX算法名称 = a;
        return this.getInstance(a);
    };
    md.update.overload('[B').implementation = function (a) {
        showStacks();
        mylog("======================================","","",0);
        mylog(HX算法名称+"_update:" , a,"",1);     
        return this.update(a);
    };
    md.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
        showStacks();
        mylog("======================================","","",0);
        mylog(HX算法名称+"_update:" , a , "|" + b + "|" + c,1);       
        return this.update(a, b, c);
    };
    md.update.overload('java.nio.ByteBuffer').implementation = function (a) {
        showStacks();
        this.update(a);
        mylog("======================================","","",0);
        mylog(HX算法名称+"update:" ,a.array() , "",1);      
    };
    md.digest.overload().implementation = function () {
        showStacks();
        mylog("======================================","","",0);
        var result = this.digest();
        mylog(HX算法名称+"_digest结果:" , result,"",1);        
        return result;
    };
    md.digest.overload('[B').implementation = function (a) {
        showStacks();
        mylog("======================================","","",0);
        mylog(HX算法名称+"_digest参数:" , a,"",1);
        var result = this.digest(a);
        mylog(HX算法名称+"_digest结果:" , result,"",1);        
        return result;
    } ; 
    md.digest.overload('[B','int','int').implementation = function (a,b,c) {
        showStacks();
        mylog("======================================","","",0);
        mylog(HX算法名称+"_digest参数:" , a,"   |"+b+"|"+c,1);
        var result = this.digest(a,b,c);
        mylog(HX算法名称+"_digest结果:" , result,"",1);        
        return result;
    };
    var ivParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec');
    ivParameterSpec.$init.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.$init(a);
        mylog("======================================","","",0);
        mylog("iv向量: " ,a,"",1);
        return result;
    };
    var ivParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec');
    ivParameterSpec.$init.overload('[B','int','int').implementation = function (a,b,c) {
        showStacks();
        var result = this.$init(a,b,c);
        mylog("======================================","","",0);
        mylog("iv向量: " ,a,"   |"+b+"|"+c,1);
        return result;
    };
    var cipher = Java.use('javax.crypto.Cipher');
    cipher.getInstance.overload('java.lang.String').implementation = function (a) {
        showStacks();
        var result = this.getInstance(a);
        mylog("======================================","","",0);
        mylog(AE算法名称+"_模式填充:" + a,"","",0);
        return result;
    };
    cipher.init.overload('int', 'java.security.Key').implementation = function (a, b) {
        showStacks();
        var result = this.init(a, b);
        mylog("======================================","","",0);
        if (N_ENCRYPT_MODE == a) 
        {
            mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        };
        var bytes_key = b.getEncoded();
        mylog(AE算法名称+"_init key:" + "|密钥" , bytes_key,"",1);       
        return result;
    };
    cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function (a, b) {
        showStacks();
        var result = this.init(a, b);
        mylog("======================================","","",0);
        if (N_ENCRYPT_MODE == a) 
        {
            mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        };
        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);
        mylog("======================================","","",0);
        if (N_ENCRYPT_MODE == a) 
        {
            mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        };
        var bytes_key = b.getEncoded();
        mylog(AE算法名称+"_init key:" + "|密钥" ,bytes_key,"",1); 
        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) 
        {
            mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        };
        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) 
        {
            mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        };
         var bytes_key = b.getEncoded();
        mylog(AE算法名称+"_init key:" + "密钥:" , bytes_key,"",1);       
        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) 
        {
           mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        };
        var bytes_key = b.getEncoded();
        mylog(AE算法名称+"_init key:" + "密钥:" , bytes_key,"",1);
        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) 
        {
            mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        }
        var bytes_key = b.getEncoded();
        mylog(AE算法名称+"_init key:" + "密钥:" , bytes_key,"",1);        
        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) 
        {
            mylog(AE算法名称+"_init  | 加密模式","","",0);    
        }
        else if(N_DECRYPT_MODE == a)
        {
            mylog(AE算法名称+"_init  | 解密模式","","",0);    
        };
         var bytes_key = b.getEncoded();
        mylog(AE算法名称+"_init key:" + "|密钥:" ,bytes_key,"",1);       
        return result;
    };
    cipher.update.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.update(a);
        mylog("======================================","","",0);
        mylog(AE算法名称+"_update:" , a,"",1);  
        return result;
    };
    cipher.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
        showStacks();
        var result = this.update(a, b, c);
        mylog("======================================","","",0);
        mylog(AE算法名称+"_update: " , a , "|" + b + "|" + c,1);
        return result;
    };
    cipher.update.overload('[B', 'int', 'int','[B').implementation = function (a, b, c,d) {
        showStacks();
        var result = this.update(a, b, c, d);
        mylog("======================================","","",0);
        mylog(AE算法名称+"_update: " , a , "|" + b + "|" + c,1);
        mylog(AE算法名称+"_update:结果: " , d , "|" + b + "|" + c,1);
        return result;
    };
    cipher.update.overload('[B', 'int', 'int','[B','int').implementation = function (a, b, c,d,e) {
        showStacks();
        var result = this.update(a, b, c, d,e);
        mylog("======================================","","",0);
        mylog(AE算法名称+"_update: " , a , "|" + b + "|" + c + "|" + e,1);
        mylog(AE算法名称+"_update:结果: " , d , "|" + b + "|" + c+ "|" + e,1);
        return result;
    }  ;  
    cipher.update.overload('java.nio.ByteBuffer', 'java.nio.ByteBuffer').implementation = function (a, b) {
        showStacks();
        var result = this.update(a,b);        
        mylog("======================================","","",0);
        mylog(AE算法名称+"(ByteBuffer)_update: " , a.array() ,"",1);
        mylog(AE算法名称+"(ByteBuffer)_update:结果: " , b.array(), "" ,1);
        return result;
    };
    cipher.doFinal.overload().implementation = function () {
        showStacks();
        var result = this.doFinal();
        mylog("======================================","","",0);
        mylog(AE算法名称+"_doFinal结果: ",result,"",1);
        return result;
    };
    cipher.doFinal.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.doFinal(a);
        mylog("======================================","","",0);
        mylog(AE算法名称+"_doFinal参数: " ,a,"",1);
        mylog(AE算法名称+"_doFinal结果: ",result,"",1);
        return result;
    };
    cipher.doFinal.overload('[B','int').implementation = function (a,b) {
        showStacks();
        var result = this.doFinal(a,b);
        mylog("======================================","","",0);        
        mylog(AE算法名称+"_doFinal结果: ", a,"   |"+b,1);
        return result;
    };
    cipher.doFinal.overload('[B','int','int').implementation = function (a,b,c) {
        showStacks();
        var result = this.doFinal(a,b,c);
        mylog("======================================","","",0);        
        mylog(AE算法名称+"_doFinal参数: " ,a,"   |"+b+"|"+c,1);
        mylog(AE算法名称+"_doFinal结果: ",result,"",1);
        return result;
    };
    cipher.doFinal.overload('[B','int','int','[B','int').implementation = function (a,b,c,d,e) {
        showStacks();
        var result = this.doFinal(a,b,c,d,e);
        mylog("======================================","","",0);        
        mylog(AE算法名称+"_doFinal参数: " ,a,"   |"+b+"|"+c,1);
        mylog(AE算法名称+"_doFinal结果: ",d,"  |"+e,1);
        return result;
    };
    cipher.doFinal.overload('[B','int','int','[B').implementation = function (a,b,c,d) {
        showStacks();
        var result = this.doFinal(a,b,c,d);
        mylog("======================================","","",0);        
        mylog(AE算法名称+"_doFinal参数: " ,a,"   |"+b+"|"+c,1);
        mylog(AE算法名称+"_doFinal结果: ",d,"",1);
        return result;
    };
    var x509EncodedKeySpec = Java.use('java.security.spec.X509EncodedKeySpec');
    x509EncodedKeySpec.$init.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.$init(a);
        mylog("======================================","","",0);
        mylog("RSA公钥:" + bytesToBase64(a),"","",0);
        return result;
    };
    
    var PKCS8EncodedKeySpec = Java.use('java.security.spec.PKCS8EncodedKeySpec');
    PKCS8EncodedKeySpec.$init.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.$init(a);
        mylog("======================================","","",0);
        mylog("RSA私钥:" + bytesToBase64(a),"","",0);
        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);
        mylog("======================================","","",0);
        //console.log("RSA公钥:" + bytesToBase64(a));
        mylog("RSA密钥N:" + a.toString(16),"","",0);
        mylog("RSA密钥E:" + b.toString(16),"","",0);
        return result;
    };
    var KeyPairGenerator = Java.use('java.security.KeyPairGenerator');
    KeyPairGenerator.generateKeyPair.implementation = function () 
    {
        showStacks();
        var result = this.generateKeyPair();
        mylog("======================================","","",0);
        var str_private = result.getPrivate().getEncoded();
        var str_public = result.getPublic().getEncoded();
        mylog("公钥 |hex:" + bytesToHex(str_public),"","",0);
        mylog("私钥 |hex:" + bytesToHex(str_private),"","",0);
        return result;
    };
    KeyPairGenerator.genKeyPair.implementation = function () 
    {
        showStacks();
        var result = this.genKeyPair();
        mylog("======================================","","",0);
        var str_private = result.getPrivate().getEncoded();
        var str_public = result.getPublic().getEncoded();
        mylog("公钥 |hex:" + bytesToHex(str_public),"","",0);
        mylog("私钥 |hex:" + bytesToHex(str_private),"","",0);
        return result;
    };
        //返回输出流
        var OutStream = Java.use('java.io.OutputStream');
        OutStream['write'].overload('[B').implementation = function(data) {   
            showStacks();
            var ret = this.write(data);
            mylog("======================================","","",0);
            mylog("TCP接收 输出流:",data,"" ,1);
            return ret;
        };
        //返回输出流
        OutStream['write'].overload('[B','int','int').implementation = function(data,a,b) {   
            showStacks();
            var ret = this.write(data,a,b);
            mylog("======================================","","",0);
            mylog("TCP接收 输出流:",data,"  |"+a+"|"+b  ,1);
            return ret;
        };
         //返回输入流
    var Stream = Java.use('java.io.InputStream');
    Java.use("java.net.Socket").getInputStream.overload().implementation=function(){
        showStacks();
        mylog("tcp 输入流======================================","","",0);
        var rets = this.getInputStream()     
        return rets;
    };
    Stream['read'].overload('[B').implementation = function(data) {   
        mylog("tcp 输入流======================================","","",0);
            showStacks();
            var ret = this.read(data);
            mylog("======================================","","",0);
            mylog("tcp 输入流:",data,"" ,1);
            return ret;
        };
            //返回输入流
    Stream['read'].overload('[B','int','int').implementation = function(data,a,b) {  
        mylog("tcp 输入流======================================","","",0); 
        showStacks();
        var ret = this.read(data,a,b);
        mylog("======================================","","",0);
        mylog("tcp 输入流:",data,"  |"+a+"|"+b ,1);
        return ret;
    };
});
    '''
    return htmlstr


def mians(pakname):
    print(pakname)
    jscod = get_js()
    process = frida.get_device_manager().add_remote_device("127.0.0.1:8080").attach(pakname)
    script = process.create_script(jscod)
    script.on("message", on_message)
    script.load()
    sys.stdin.read()


if __name__ == "__main__":
    mians("App名")  # App name

三、hook方法一

function showStacks() {
    Java.perform(function () {
      console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
    });
}

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));
var stringToBase64 = function (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
}
var base64ToString = function (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
}
var hexToBase64 = function (str) {
    return base64Encode(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
var base64ToHex = function (str) {
    for (var i = 0, bin = base64Decode(str.replace(/[ \r\n]+$/, "")), 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("");
}
var hexToBytes = function (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;
}
var bytesToHex = function (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;
}
var stringToHex = function (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
}
var stringToBytes = function (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的方法
var bytesToString = function (arr) {  
    var str = '';
    var i;
    arr = new Uint8Array(arr);
    for(i in arr){
        str += String.fromCharCode(arr[i]);
    }
    return str;
}
var bytesToBase64=function(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
}
var base64ToBytes=function(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 + "|Dec密钥:" + bytesToString(a));
    console.log("算法名:" + b + "|Hex密钥:" + bytesToHex(a));
    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结果:" + bytesToHex(result));
    console.log("doFinal结果:" + bytesToBase64(result));
    return result;
}
mac.doFinal.overload('[B').implementation = function (a) {
    showStacks();
    var result = this.doFinal(a);
    console.log("======================================");
    console.log("doFinal参数:" + bytesToString(a));
    console.log("doFinal结果:" + bytesToHex(result));
    console.log("doFinal结果:" + 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向量:" + bytesToString(a));
    console.log("iv向量:" + 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.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结果:" + bytesToHex(result));
    console.log("doFinal结果:" + bytesToBase64(result));
    return result;
}
cipher.doFinal.overload('[B').implementation = function (a) {
    showStacks();
    var result = this.doFinal(a);
    console.log("======================================");
    console.log("doFinal参数:" + bytesToString(a));
    console.log("doFinal结果:" + bytesToHex(result));
    console.log("doFinal结果:" + 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;
}
});

转载自:https://blog.csdn.net/weixin_51111267/article/details/131303876?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7EPayColumn-1-131303876-blog-133276655.235%5Ev43%5Econtrol&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7EPayColumn-1-131303876-blog-133276655.235%5Ev43%5Econtrol&utm_relevant_index=1