frida自吐算法

使用方法:

frida -U -l tu.js -f com.xxxxxx --no-pause

代码:

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=======================\r\n");
    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(/[ \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("");
}
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参数: |hex  :"     + bytesToHex(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结果 |hex:" + bytesToHex(result));
        console.log("digest结果 |base64:" + bytesToBase64(result));
        return result;
    }
    md.digest.overload('[B').implementation = function (a) {
        //showStacks();
        console.log("======================================");
        console.log("digest参数 |str:" + bytesToString(a));
        console.log("digest参数 |hex:" + bytesToHex(a));
        var result = this.digest(a);
        console.log("digest结果: |hex" + bytesToHex(result));
        console.log("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);
        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.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.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参数: |hex  :"     + bytesToHex(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;
    }
});

 

 

或者:

// frida -U com.xxx.package -l FridaAndroidSelfVomitCrypt.js
// frida -U com.wepie.snake --load FridaAndroidSelfVomitCrypt.js --output frida_out.log

//{
//javax.crypto.Cipher
//  * Constant used to initialize cipher to encryption mode.
// public static final int ENCRYPT_MODE = 1;
//  * Constant used to initialize cipher to decryption mode.
// public static final int DECRYPT_MODE = 2;
//  * Constant used to initialize cipher to key-wrapping mode.
// public static final int WRAP_MODE = 3;
//  * Constant used to initialize cipher to key-unwrapping mode.
// public static final int UNWRAP_MODE = 4;
class javax_crypto_Cipher{
 
}
//}

class StackUtil{ 

}

/**
 * @param {String} name 
 */
function showStacks(name="") {
    StackUtil.print_stack(name);
}
 


// class BytesToX {
    /**
     * 
     * @param {Boolean} _raw 
     * @param {Boolean} _toString 
     * @param {Boolean} _toHex 
     * @param {Boolean} _toBase64
     * @param {Boolean} _toHex
     */
    function BytesToX(_raw=false,_toString=false,_toHex=false,_toBase64=false) {
        this._raw = _raw;
        this._toString = _toString;
        this._toHex = _toHex;
        this._toBase64 = _toBase64;
    }
    BytesToX.prototype.toString = function dogToString() {
        return  `  BytesToX:( _raw:${this._raw} , _toString:${this._toString  } , _toHex:${this._toHex   } , _toBase64:${this._toBase64} ) .  `;
    }
// }

const _BytesToRawStringHex=new BytesToX(/* _raw= */true,/* _toString= */true,/* _toHex= */true);
const _BytesToRaw=new BytesToX(/* _raw= */true);
const _BytesToString=new BytesToX(/* _toString= */true);
const _BytesToStringHex=new BytesToX(/* _raw= */false,/* _toString= */true,/* _toHex= */true,/* _toBase64= */false);
//TODO t
// console.log(`debug____BytesToRawStringHex:${_BytesToRawStringHex.toString()}`);
// console.log(`debug_____BytesToRaw:${_BytesToRaw.toString()}`);
// console.log(`debug_____BytesToString:${_BytesToString.toString()}`);
// console.log(`debug_____BytesToStringHex:${_BytesToStringHex.toString()}`);

// class Param {
    /**
     * 
     * @param {String} param_name 
     * @param {ArrayBuffer} param_value
     * @param {BytesToX}   bytesToX
     */
    function Param(param_name,param_value,bytesToX=_BytesToStringHex) {
        this.param_name = param_name;
        this.param_value = param_value;
        this.bytesToX=bytesToX;
        // console.log(`debug_____Param_new:${param_name} ${param_value} ${bytesToX.toString()}`);
    }
    Param.prototype.toString = function dogToString() {
        return  `  Param:( param_name:${this.param_name} , param_value:${this.param_value  } , bytesToX:${this.bytesToX.toString()   } ) .  `;
    }
// }

/**
 * 
 * @param {String} param_name 
 * @param {ArrayBuffer} param_value
 */
function NewParam(param_name,param_value){
    var p = new Param(param_name,param_value);
    // console.log(`NewParam___:${p}`);
    return p;
}
/**
 * 
 * @param {String} param_name 
 * @param {ArrayBuffer} param_value
 */
function NewParam_BytesToRawStringHex(param_name,param_value){
    var p= new Param(param_name,param_value,_BytesToRawStringHex);
    // console.log(`NewParam_BytesToRawStringHex___:${p}`);
    return p;
}
/**
 * 
 * @param {String} param_name 
 * @param {ArrayBuffer} param_value
 */
function NewParam_BytesToRaw(param_name,param_value){
    var p=  new Param(param_name,param_value,_BytesToRaw);
    // console.log(`NewParam_BytesToRaw___:${p}`);
    return p;
}
/**
 * 
 * @param {String} param_name 
 * @param {ArrayBuffer} param_value
 */
function NewParam_BytesToString(param_name,param_value){
    var p=   new Param(param_name,param_value,_BytesToString);
    // console.log(`NewParam_BytesToString___:${p}`);
    return p;
}
/**
 * 
 * @param {String} param_name 
 * @param {ArrayBuffer} param_value
 */
function NewParam_BytesToStringHex(param_name,param_value){
    var p=   new Param(param_name,param_value,_BytesToStringHex);
    // console.log(`NewParam_BytesToStringHex___:${p}`);
    return p;
}

/**
 * 
 * @param {String} clazz 
 * @param  {...Param} param_ls
 * @returns {String} log 
 */
function generate_log(clazz,...param_ls){
    var log_message=`clazz:${clazz};`;
    // console.log(`param_ls____:${param_ls.length},${typeof(param_ls)},${typeof(param_ls[0])},${param_ls[0][1].toString()} `)
    for (var param  of param_ls[0]) {
        // console.log(`param____:${param.toString()}`)
        if (!param.param_value){
            continue;
        }
        if (param.bytesToX._raw){
            log_message+=`${param.param_name}.raw:${param.param_value}~`;
        }
        if (param.bytesToX._toString){
            log_message+=`${param.param_name}.str:${bytesToString(param.param_value)}~`;
            
        }
        if (param.bytesToX._toHex){
            log_message+=`${param.param_name}.hex:${bytesToHex(param.param_value)}~`;
        }
        log_message+=";"
    }
    
    return log_message;
    
}

/**
 * @param {String} clazz 
 * @param  {...Param} param_ls
 */
function print_generated_log(clazz,...param_ls){
    console.log( 
        generate_log(clazz,param_ls)
    );
}

Java.perform(function () {

{
    const  clazz='javax.crypto.spec.SecretKeySpec';
    var SecretKeySpec = Java.use(clazz);
    // public SecretKeySpec(byte[] key, String algorithm) {}
    SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (security_key, algorithm) {
        showStacks(SecretKeySpec.class.getCanonicalName());
        var result = this.$init(security_key, algorithm);
        print_generated_log(clazz,
            NewParam("security_key",security_key),
            NewParam_BytesToRaw("algorithm",algorithm),
            NewParam_BytesToRaw("return_value",result) ) ;
        return result;
    }
}

{
    const clazz='javax.crypto.spec.DESKeySpec';
    var DESKeySpec = Java.use(clazz);
    // public DESKeySpec(byte[] key) throws InvalidKeyException 
    DESKeySpec.$init.overload('[B').implementation = function (security_key) {
        showStacks(DESKeySpec.class.getCanonicalName());
        var result = this.$init(security_key);
        print_generated_log(clazz,
            NewParam_BytesToString("security_key",security_key),
            NewParam("return_value",result) ) ;
        return result;
    }

    // public DESKeySpec(byte[] key, int offset) throws InvalidKeyException 
    DESKeySpec.$init.overload('[B', 'int').implementation = function (security_key, offset) {
        showStacks(DESKeySpec.class.getCanonicalName());
        var result = this.$init(security_key, offset);
        print_generated_log(clazz,
            NewParam("security_key",security_key),
            NewParam("offset",offset),
            NewParam("return_value",result) ) ;
        return result;
    }
}

{
    const clazz='javax.crypto.Mac';
    var Mac = Java.use(clazz);
    // public static final Mac getInstance(String algorithm)
    Mac.getInstance.overload('java.lang.String').implementation = function (algorithm) {
        showStacks(Mac.class.getCanonicalName());
        var result = this.getInstance(algorithm);
        print_generated_log(clazz,
            NewParam_BytesToString("algorithm",algorithm),
            NewParam("return_value",result) ) ;
        return result;
    }
    // public final void update(byte[] input) throws IllegalStateException 
    Mac.update.overload('[B').implementation = function (input) {
        showStacks(Mac.class.getCanonicalName());
        this.update(input);
        print_generated_log(clazz,
            NewParam_BytesToString("input",input)  ) ;
    }
    // public final void update(byte[] input, int offset, int len)
    Mac.update.overload('[B', 'int', 'int').implementation = function (input, offset, len) {
        showStacks(Mac.class.getCanonicalName());
        this.update(input, offset, len)
        print_generated_log(clazz,
            NewParam("input",input),
            NewParam("offset",offset),
            NewParam("len",len),
            NewParam("return_value",result) ) ;
    }
    // public final byte[] doFinal() throws IllegalStateException 
    Mac.doFinal.overload().implementation = function () {
        showStacks(Mac.class.getCanonicalName());
        var result = this.doFinal();
        print_generated_log(clazz,
            NewParam("return_value",result) ) ;
        return result;
    }
    // public final byte[] doFinal(byte[] input) throws IllegalStateException
    Mac.doFinal.overload('[B').implementation = function (input) {
        showStacks(Mac.class.getCanonicalName());
        var result = this.doFinal(input);
        print_generated_log(clazz,
            NewParam("input",input),
            NewParam("return_value",result) ) ;
        return result;
    }
}

{
    const clazz='java.security.MessageDigest';
    var MessageDigest = Java.use(clazz);
    // public static MessageDigest getInstance(String algorithm, String provider)
    MessageDigest.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (algorithm, provider) {
        showStacks(MessageDigest.class.getCanonicalName());
        var return_value=this.getInstance(algorithm, provider);
        print_generated_log(clazz,
            NewParam("algorithm",algorithm),
            NewParam("provider",provider),
            NewParam("return_value",return_value) ) ;
        return return_value;
    }
    // public static MessageDigest getInstance(String algorithm)
    MessageDigest.getInstance.overload('java.lang.String').implementation = function (algorithm) {
        showStacks(MessageDigest.class.getCanonicalName());
        var return_value= this.getInstance(algorithm);
        print_generated_log(clazz,
            NewParam("algorithm",algorithm),
            NewParam("return_value",return_value) ) ;
        return return_value;
    }
    // public void update(byte[] input) 
    MessageDigest.update.overload('[B').implementation = function (input) {
        showStacks(MessageDigest.class.getCanonicalName());
        this.update(input);
        print_generated_log(clazz,
            NewParam("input",input)
            ) ;
        return ;
    }
    // public void update(byte[] input, int offset, int len) 
    MessageDigest.update.overload('[B', 'int', 'int').implementation = function (input, offset, len) {
        showStacks(MessageDigest.class.getCanonicalName());
        this.update(input, offset, len)
        print_generated_log(clazz,
            NewParam("input",input),
            NewParam("offset",offset),
            NewParam("len",len)
            ) ;
        return ;
    }
    // public byte[] digest() 
    MessageDigest.digest.overload().implementation = function () {
        showStacks(MessageDigest.class.getCanonicalName());
        var return_value = this.digest();
        print_generated_log(clazz,
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    // public byte[] digest(byte[] input) 
    MessageDigest.digest.overload('[B').implementation = function (input) {
        showStacks(MessageDigest.class.getCanonicalName());
        var return_value = this.digest(input);
        print_generated_log(clazz,
            NewParam("input",input),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
}

{
    const clazz='javax.crypto.spec.IvParameterSpec';
    var IvParameterSpec = Java.use(clazz);
    // public IvParameterSpec(byte[] initialization_vector) 
    IvParameterSpec.$init.overload('[B').implementation = function (initialization_vector) {
        showStacks(IvParameterSpec.class.getCanonicalName());
        var return_value = this.$init(initialization_vector);
        print_generated_log(clazz,
            NewParam("initialization_vector",initialization_vector),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
}

{
    const clazz='javax.crypto.Cipher';
    var Cipher = Java.use(clazz);
    //javax.crypto.Cipher: public static final Cipher  getInstance(String transformation)    throws NoSuchAlgorithmException, NoSuchPaddingException
    Cipher.getInstance.overload('java.lang.String').implementation = function (transformation) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.getInstance(transformation);
        print_generated_log(clazz,
            NewParam("transformation",transformation),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    //javax.crypto.Cipher: public final void init(int operation_mode, Key security_key) throws InvalidKeyException
    Cipher.init.overload('int', 'java.security.Key').implementation = function (operation_mode, security_key) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.init(operation_mode, security_key);
        var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
        //java.security.Key: public byte[] getEncoded()
        var security_key_encoded = security_key.getEncoded();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("security_key_encoded",security_key_encoded),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    //javax.crypto.Cipher: public final void init(int operation_mode, Certificate certificate) throws InvalidKeyException
    Cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function (operation_mode, certificate) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.init(operation_mode, certificate);
        var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
        //java.security.cert.Certificate: public abstract byte[] getEncoded() throws CertificateEncodingException;
        var certificate_encoded=certificate.getEncoded();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("certificate_encoded",certificate_encoded),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    // public final void init(int operation_mode, Key key, AlgorithmParameterSpec algorithmParameterSpec) throws InvalidKeyException, InvalidAlgorithmParameterException
    Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (operation_mode, security_key, algorithmParameterSpec) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.init(operation_mode, security_key, algorithmParameterSpec);
        var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
        var security_key_encoded = security_key.getEncoded();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("security_key_encoded",security_key_encoded),
            NewParam("return_value",return_value)
            ) ;

        return return_value;
    }
    // public final void init(int operation_mode, Certificate certificate, SecureRandom secureRandom) throws InvalidKeyException
    Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (operation_mode, certificate, secureRandom) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.init(operation_mode, certificate, secureRandom);
        //忽略secureRandom(对secureRandom操作对加解密会影响?)
        var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
        //java.security.cert.Certificate: public abstract byte[] getEncoded() throws CertificateEncodingException;
        var certificate_encoded=certificate.getEncoded();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("certificate_encoded",certificate_encoded),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    // public final void init(int operation_mode, Key security_key, SecureRandom secureRandom)    throws InvalidKeyException
    Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function (operation_mode, security_key, secureRandom) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.init(operation_mode, security_key, secureRandom);
        var mode_name=javax_crypto_Cipher.get_mode_name(operation_mode);
        var security_key_encoded = security_key.getEncoded();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("security_key_encoded",security_key_encoded),
            NewParam("return_value",return_value)
            ) ;

        return return_value;
    }
    //     public final void init(int operation_mode, Key security_key, AlgorithmParameters algorithmParameters)    throws InvalidKeyException, InvalidAlgorithmParameterException
    Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function (operation_mode, security_key, algorithmParameters) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.init(operation_mode, security_key, algorithmParameters);
        var security_key_encoded = security_key.getEncoded();
        var algorithmParametersToString=algorithmParameters.toString();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("security_key_encoded",security_key_encoded),
            NewParam("algorithmParametersToString",algorithmParametersToString),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    //     public final void init(int operation_mode, Key security_key, AlgorithmParameters algorithmParameters,SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException
    Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (operation_mode, security_key, algorithmParameters, secureRandom) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.init(operation_mode, security_key, algorithmParameters, secureRandom);
        var security_key_encoded = security_key.getEncoded();
        var algorithmParametersToString=algorithmParameters.toString();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("security_key_encoded",security_key_encoded),
            NewParam("algorithmParametersToString",algorithmParametersToString),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    //     public final void init(int operation_mode, Key security_key, AlgorithmParameterSpec algorithmParameterSpec,SecureRandom secureRandom)    throws InvalidKeyException, InvalidAlgorithmParameterException
    Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function (operation_mode, security_key, algorithmParameterSpec, secureRandom) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.update(operation_mode, security_key, algorithmParameters, secureRandom);
        var security_key_encoded = security_key.getEncoded();
        var algorithmParametersToString=algorithmParameters.toString();
        print_generated_log(clazz,
            NewParam("mode_name",mode_name),
            NewParam("security_key_encoded",security_key_encoded),
            NewParam("algorithmParametersToString",algorithmParametersToString),
            NewParam("return_value",return_value)
            ) ;

        return return_value;
    }
    // public final byte[] update(byte[] input) 
    Cipher.update.overload('[B').implementation = function (input) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.update(input);
        print_generated_log(clazz,
            NewParam("input",input),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    // public final byte[] update(byte[] input, int inputOffset, int inputLen) 
    Cipher.update.overload('[B', 'int', 'int').implementation = function (input, inputOffset, inputLen) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.update(input, inputOffset, inputLen);
        print_generated_log(clazz,
            NewParam("input",input),
            NewParam("inputOffset",inputOffset),
            NewParam("inputLen",inputLen),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    // public final byte[] doFinal() throws IllegalBlockSizeException, BadPaddingException 
    Cipher.doFinal.overload().implementation = function () {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.doFinal();
        print_generated_log(clazz,
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
    // public final byte[] doFinal(byte[] input)    throws IllegalBlockSizeException, BadPaddingException 
    Cipher.doFinal.overload('[B').implementation = function (input) {
        showStacks(Cipher.class.getCanonicalName());
        var return_value = this.doFinal(input);
        print_generated_log(clazz,
            NewParam("input",input),
            NewParam("return_value",return_value)
            ) ;
        //TODO bytesToBase64(return_value)
        return return_value;
    }
}
{
    const clazz='java.security.spec.X509EncodedKeySpec';
    var X509EncodedKeySpec = Java.use(clazz);
    // public X509EncodedKeySpec(byte[] encoded_key) 
    X509EncodedKeySpec.$init.overload('[B').implementation = function (encoded_key) {
        showStacks(X509EncodedKeySpec.class.getCanonicalName());
        var return_value = this.$init(encoded_key);
        print_generated_log(clazz,
            NewParam("encoded_key",encoded_key),
            NewParam("return_value",return_value)
            ) ;
        //TODO bytesToBase64(return_value)
        return return_value;
    }
}

{
    const clazz='java.security.spec.RSAPublicKeySpec';
    var RSAPublicKeySpec = Java.use(clazz);
    // public RSAPublicKeySpec(BigInteger modulus, BigInteger public_exponent) 
    RSAPublicKeySpec.$init.overload('java.math.BigInteger', 'java.math.BigInteger').implementation = function (modulus, public_exponent) {
        showStacks(RSAPublicKeySpec.class.getCanonicalName());
        var return_value = this.$init(modulus, public_exponent);
        //TODO bytesToBase64(modulus)
        print_generated_log(clazz,
            NewParam("modulus",modulus),
            NewParam("public_exponent",public_exponent),
            NewParam("return_value",return_value)
            ) ;
        return return_value;
    }
}

{
    const clazz='java.security.KeyPairGenerator';
    var KeyPairGenerator = Java.use(clazz);
    // public KeyPair generateKeyPair() 
    KeyPairGenerator.generateKeyPair.implementation = function () 
    {
        showStacks(KeyPairGenerator.class.getCanonicalName());
        var return_value = this.generateKeyPair();
        var private_key = return_value.getPrivate().getEncoded();
        var public_key = return_value.getPublic().getEncoded();
        //change to bytesToHex(private_key) bytesToHex(public_key)
        print_generated_log(clazz,
            NewParam("private_key",private_key),
            NewParam("public_key",public_key),
            NewParam("return_value",return_value)
            ) ;

        return return_value;
    }

    // public final KeyPair genKeyPair() 
    KeyPairGenerator.genKeyPair.implementation = function () 
    {
        showStacks(KeyPairGenerator.class.getCanonicalName());
        var return_value = this.genKeyPair();

        var private_key = return_value.getPrivate().getEncoded();
        var public_key = return_value.getPublic().getEncoded();
        //TODO bytesToHex(private_key) bytesToHex(public_key)
        
        print_generated_log(clazz,
            NewParam("private_key",private_key),
            NewParam("public_key",public_key),
            NewParam("return_value",return_value)
            ) ;

        return return_value;
    }
}

});

 

 

python 启动

# -*- coding: UTF-8 -*-
import frida, sys

jsCode = """

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

(function () {
    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));
    this.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
    }
    this.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
    }
    this.hexToBase64 = function (str) {
        return base64Encode(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
    }
    this.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("");
    }
    this.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;
    }
    this.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;
    }
    this.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
    }
    this.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的方法
    this.bytesToString = function (arr) {  
        var str = '';
        arr = new Uint8Array(arr);
        for(i in arr){
            str += String.fromCharCode(arr[i]);
        }
        return str;
    }
    this.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
    }
    this.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);
        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结果:" + bytesToHex(result));
        send("doFinal结果:" + bytesToBase64(result));
        return result;
    }
    mac.doFinal.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.doFinal(a);
        send("======================================");
        send("doFinal参数:" + bytesToString(a));
        send("doFinal结果:" + bytesToHex(result));
        send("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();
        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结果:" + bytesToHex(result));
        send("digest结果:" + bytesToBase64(result));
        return result;
    }
    md.digest.overload('[B').implementation = function (a) {
        showStacks();
        send("======================================");
        send("digest参数:" + bytesToString(a));
        var result = this.digest(a);
        send("digest结果:" + bytesToHex(result));
        send("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);
        send("======================================");
        send("iv向量:" + bytesToString(a));
        send("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);
        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结果:" + bytesToHex(result));
        send("doFinal结果:" + bytesToBase64(result));
        return result;
    }
    cipher.doFinal.overload('[B').implementation = function (a) {
        showStacks();
        var result = this.doFinal(a);
        send("======================================");
        send("doFinal参数:" + bytesToString(a));
        send("doFinal结果:" + bytesToHex(result));
        send("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);
        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;
    }

});
""";

fw = open(sys.argv[1],'w+',encoding='utf-8')

def message(message, data):
    if message["type"] == 'send':
        print(u"[*] {0}".format(message['payload']))
        fw.write(u"[*] {0}\n".format(message['payload']))
        fw.flush()
    else:
        print(message)

process = frida.get_remote_device().attach(sys.argv[1])
script= process.create_script(jsCode)
script.on("message", message)
script.load()
sys.stdin.read()

 

 

转自:微信公众号:移动安全王铁头

posted @ 2021-10-10 23:45  阿布_alone  阅读(2362)  评论(1编辑  收藏  举报
TOP