frida hook AES DES RSA 自吐算法


frida hook AES DES RSA 自吐算法

大家好,我是王鐵頭 一個乙方安全公司搬磚的菜雞 今天分享的是frida hook AES DES RSA 自吐算法
持續更新移動安全,iot安全,編譯原理相關原創視頻文章

視頻演示:https://space.bilibili.com/430241559

在分析通信協議的時候 經常遇到的加密算法就是那幾個

  1. AES
  2. DES
  3. 3DES
  4. RSA

在hook AES DES RSA這些常見的加密算法之前
這里先看一下3個算法的java實現

1 AES加解密 java代碼實現

1.1 AES加密

//bytesContent 要加密的數據
//key 密鑰
public static byte[] aes_enc(byte[] bytesContent, String key) throws Exception
{
    //key相關
    byte[] raw = key.getBytes("utf-8");
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

    //"算法/模式/補碼方式" 初始化cipher
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

    //執行加密
    byte[] enc = cipher.doFinal(bytesContent);
    return enc;
}

1.2 AES解密

//bytesContent 要解密的數據
//key 密鑰
public byte[] aes_dec(byte[] bytesContent, String key) throws Exception
{
    //key相關
    byte[] raw = key.getBytes("utf-8");
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

    //"算法/模式/補碼方式" 初始化cipher
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);

    //執行解密
    byte[] dec = cipher.doFinal(bytesContent);
    return dec;
}

這里AES加解密的區別只有一點

//Cipher.DECRYPT_MODE為解密  
//Cipher.ENCRYPT_MODE 加密
cipher.init(Cipher.DECRYPT_MODE, skeySpec)

2. DES加解密 java實現代碼

2.1 DES加密

private static byte[] des_enc(byte[] data, byte[] key) throws Exception {
    // 生成一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();

    // 從原始密鑰數據創建DESKeySpec對象
    DESKeySpec dks = new DESKeySpec(key);

    // 創建一個密鑰工廠,然后用它把DESKeySpec轉換成SecretKey對象
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey securekey = keyFactory.generateSecret(dks);

    // Cipher對象實際完成加密操作
    Cipher cipher = Cipher.getInstance("DES");

    // 用密鑰初始化Cipher對象
    cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

    return cipher.doFinal(data);
}

2.2 DES解密

private static byte[] des_dec(byte[] data, byte[] key) throws Exception {
    // 生成一個可信任的隨機數源
    SecureRandom sr = new SecureRandom();

    // 從原始密鑰數據創建DESKeySpec對象
    DESKeySpec dks = new DESKeySpec(key);

    // 創建一個密鑰工廠,然后用它把DESKeySpec轉換成SecretKey對象
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey securekey = keyFactory.generateSecret(dks);

    // Cipher對象實際完成解密操作
    Cipher cipher = Cipher.getInstance("DES");

    // 用密鑰初始化Cipher對象
    cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

    return cipher.doFinal(data);
}

這里DES加解密的區別只有一點

//Cipher.DECRYPT_MODE為解密  
//Cipher.ENCRYPT_MODE 加密
cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

3. RSA加解密 java代碼實現

RSA加解密代碼實現

public static void RSA(byte[] bytesData) throws Exception
{
    //秘鑰長度為1024 生成秘鑰對
    KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);
    KeyPair keyPair= keyPairGenerator.generateKeyPair();

    //獲取公鑰 私鑰
    PublicKey publicKey=keyPair.getPublic();
    PrivateKey privateKey=keyPair.getPrivate();

    //公鑰加密 java默認"RSA"="RSA/ECB/PKCS1Padding"
    Cipher cipher=Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] encBytes = cipher.doFinal(bytesData);


    //私鑰解密 java默認"RSA"="RSA/ECB/PKCS1Padding"
    Cipher cipher1=Cipher.getInstance("RSA");
    cipher1.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] decBytes = cipher1.doFinal(encBytes);
    Log.d("xxx",new String(decBytes));
}

這里忽略前面RSA加解密都需要的生成公鑰私鑰的部分
核心功能代碼如下

3.1 RSA加密代碼

//公鑰加密 java默認"RSA"="RSA/ECB/PKCS1Padding"
Cipher cipher=Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encBytes = cipher.doFinal(bytesData);

3.2 RSA解密代碼

//私鑰解密 java默認"RSA"="RSA/ECB/PKCS1Padding"
Cipher cipher1=Cipher.getInstance("RSA");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decBytes = cipher1.doFinal(encBytes);

這里RSA加解密的區別也只有一點

//Cipher.DECRYPT_MODE為解密   publicKey  公鑰加密
//Cipher.ENCRYPT_MODE為加密   privateKey 私鑰解密
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

看了上面的一些代碼 這里可以找到一些共性
雖然實現處有些區別 但大體架構和使用的java接口是可以找到一些規律的

這里出鏡率比較高的有

  1. secretKeySpec
  2. Cipher.getInstance
  3. cipher.init
  4. cipher.doFinal
  5. DESKeySpec
    ...(后續還有 這里不一一列舉)

查閱java幫助文檔可以發現, 這些API都是一些加密算法常用的接口, 那么實現自吐 就是hook加密算法常用的API,打印相關參數,以便於快速的定位算法和相關參數 加密模式等

在網上查找 相關資料 我找到了一份frida自吐算法的源碼 鏈接如下
https://blog.csdn.net/weixin_34365417/article/details/93088342

看了上面的源碼 作者寫的還是不錯的 而且不僅hook了 我上面提到的加密算法 還hook了一些消息摘要算法 MAC家族和md家族等 也就是 md5 sha 等通信協議中常用的hash算法 另外也有對 IV這種加密中用到的向量成員的hook

這里 我修改了下源碼
修改的部分主要分為下面幾點

  1. 針對上面的打印堆棧的代碼做了修改 修復在高版本 打印堆棧不換行的問題
  2. 增加了一些hook api
  3. 把原來的 python腳本換成了js
  4. 修復一個bug
  5. ui調整 增加顯示 加密模式 解密模式 把原腳本的dec結果 改成str結果 增加dofinal str顯示

4 修改后的源碼

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

視頻演示:https://space.bilibili.com/430241559

相關代碼資料 關注公眾號 恢復關鍵字 frida 下載:

持續更新移動安全,iot安全,編譯原理相關原創視頻文章


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM