/**
* Java层标准算法hook
*/
Java.perform(function () {
/**
打印堆栈
*/
function showStack() {
let Throwable = Java.use("java.lang.Throwable");
let stackTraceString = Java.use("android.util.Log").getStackTraceString(Throwable.$new())
console.log(stackTraceString);
}
let ByteString = Java.use("com.android.okhttp.okio.ByteString");
/**
* 字节数组转为Base64
*/
function toBase64(tag, data) {
console.log(tag + " Base64:" + ByteString.of(data).base64());
}
/**
* 字节数组转为16进制
*/
function toHex(tag, data) {
console.log(tag + " Hex:" + ByteString.of(data).hex());
}
/**
* 字节数组转为明文
*/
function toUtf8(tag, data) {
console.log(tag + " Utf8:" + ByteString.of(data).utf8());
}
/**
* 打印字节数组对应的输出数据
*/
function printData(tag, data) {
toBase64(tag, data);
toHex(tag, data);
toUtf8(tag, data);
}
/***
* 消息摘要算法hook
* update 压入数据
* digest 返回加密结果
*/
function hookMessageDigest() {
let MessageDigest = Java.use("java.security.MessageDigest");
MessageDigest.update.overload('byte').implementation = function (b) {
showStack();
console.log("MessageDigest.update.overload('byte') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", Java.array('byte', [b]))
console.log("============================================================");
return result;
}
MessageDigest.update.overload('[B').implementation = function (byteArr) {
showStack();
console.log("MessageDigest.update.overload('[B') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", byteArr);
console.log("============================================================");
return result;
}
MessageDigest.digest.overload().implementation = function () {
showStack();
console.log("MessageDigest.digest.overload() is called!");
let result = this.digest.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " digest result", result);
console.log("============================================================");
return result;
}
MessageDigest.digest.overload('[B').implementation = function (byteArr) {
showStack();
console.log("MessageDigest.digest.overload('[B') is called!");
let result = this.digest.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " digest param", byteArr);
printData(algorithm + " digest result", result);
console.log("============================================================");
return result;
}
MessageDigest.digest.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) {
showStack();
console.log("MessageDigest.digest.overload('[B', 'int', 'int') is called!");
let result = this.digest.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " digest param", byteArr);
printData(algorithm + " digest result", result);
console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length);
return result;
}
}
/**
* Mac算法hook
* 1.init 初始化,秘钥
* 2.update 压入数据
* 3.doFinal 加密
*/
function hookMac() {
let Mac = Java.use("javax.crypto.Mac");
Mac.init.overload('java.security.Key').implementation = function (key) {
showStack();
console.log("Mac.init.overload('java.security.Key') is called!");
let result = this.init.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " init key", key.getEncoded())
console.log("============================================================");
return result;
}
Mac.update.overload('byte').implementation = function (b) {
showStack();
console.log("Mac.update.overload('byte') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", Java.array('byte', [b]))
console.log("============================================================");
return result;
}
Mac.update.overload('[B').implementation = function (byteArr) {
showStack();
console.log("Mac.update.overload('[B') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", byteArr)
console.log("============================================================");
return result;
}
Mac.update.overload('[B', 'int', 'int').implementation = function (byteArr, start, length) {
showStack();
console.log("Mac.update.overload('[B', 'int', 'int') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", byteArr)
console.log("============================================================" + "开始位置:" + start + " 截取长度:" + length);
return result;
}
Mac.doFinal.overload().implementation = function () {
showStack();
console.log("Mac.doFinal.overload() is called!");
let result = this.doFinal.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " doFinal result", result)
console.log("============================================================");
return result;
}
}
/**
* DES,DESEde,AES,RSA
* 1.init 加密类型,key,iv
* 2.donFinal压入数据,得到结果 update压入结果有问题
*/
function hookCipher() {
function printResult(cipherObj, result, args) {
let algorithm = cipherObj.getAlgorithm();
let mode;
if (cipherObj.opmode.value === 1) {
mode = "加密";
} else {
mode = "解密";
}
console.log(algorithm + " mode:", mode);
if (cipherObj.getParameters() != null) {
printData(algorithm + " key", cipherObj.getParameters().getEncoded());
printData(algorithm + " iv", cipherObj.getIV());
}
printData(algorithm + " doFinal param", args[0]);
printData(algorithm + " doFinal result", result);
console.log("============================================================");
}
let Cipher = Java.use("javax.crypto.Cipher");
// 不常用重载,打印调用即可,根据堆栈信息在具体去看
// init暂时注释
Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (key) {
showStack();
console.log("Cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom') is called!");
let result = this.apply(this, arguments);
return result;
}
Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (key) {
showStack();
console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom') is called!");
let result = this.apply(this, arguments);
return result;
}
// ECB模式,不带iv
Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function () {
showStack();
console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom') is called!");
let result = this.init.apply(this, arguments);
let algorithm = this.getAlgorithm();
let mode;
if (arguments[0] === 1) {
mode = "加密";
} else {
mode = "解密";
}
console.log(algorithm + " init mode:" + mode);
try {
// RSA使用私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析
printData(algorithm + " init key", arguments[1].getEncoded());
} catch (e) {
console.log(e);
}
console.log("============================================================");
return result;
}
// CBC模式,带iv
Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function () {
showStack();
console.log("Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom') is called!");
let result = this.init.apply(this, arguments);
let algorithm = this.getAlgorithm();
let ivParameterSpecObj = Java.cast(arguments[2], Java.use("javax.crypto.spec.IvParameterSpec"));
let mode;
if (arguments[0] === 1) {
mode = "加密";
} else {
mode = "解密";
}
console.log(algorithm + " init mode:" + mode);
printData(algorithm + " init key", arguments[1].getEncoded());
printData(algorithm + " init iv", ivParameterSpecObj.getIV());
console.log("============================================================");
return result;
}
Cipher.doFinal.overload().implementation = function () {
showStack();
console.log("Cipher.doFinal.overload() is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int', 'int').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int', 'int') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int', 'int', '[B').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function () {
showStack();
console.log("Cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int') is called!");
let result = this.doFinal.apply(this, arguments);
printResult(this, result, arguments);
return result;
}
}
/**
* 签名算法hook
* 私钥
*/
function hookSignature() {
let Signature = Java.use("java.security.Signature");
Signature.initSign.overload('java.security.PrivateKey').implementation = function () {
showStack();
console.log("Signature.initSign.overload('java.security.PrivateKey') is called!");
let result = this.initSign.apply(this, arguments);
let algorithm = this.getAlgorithm();
try {
// RSA使用Hex编码的私钥调用getEncoded() 会报错,异常捕获,具体逻辑,根据堆栈,去APP分析
printData(algorithm + " init key", arguments[0].getEncoded());
} catch (e) {
console.log(JSON.stringify(arguments[0]) + "|" + e);
}
console.log("============================================================");
return result;
}
Signature.update.overload('byte').implementation = function () {
showStack();
console.log("Signature.update.overload('byte') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", Java.array('byte', [b]))
console.log("============================================================");
return result;
}
Signature.update.overload('[B', 'int', 'int').implementation = function () {
showStack();
console.log("Signature.update.overload('[B', 'int', 'int') is called!");
let result = this.update.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " update param", arguments[0]);
console.log("============================================================");
return result;
}
Signature.sign.overload().implementation = function () {
showStack();
console.log("Signature.sign.overload() is called!");
let result = this.sign.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " sign result", result);
console.log("============================================================");
return result;
}
Signature.sign.overload('[B', 'int', 'int').implementation = function () {
showStack();
console.log("Signature.sign.overload('[B', 'int', 'int') is called!");
let result = this.sign.apply(this, arguments);
let algorithm = this.getAlgorithm();
printData(algorithm + " sign param", arguments[0]);
printData(algorithm + " sign result", result);
console.log("============================================================");
return result;
}
}
/**
* Base64hook
*/
function hookBase64() {
let Base64 = Java.use("android.util.Base64");
Base64.encodeToString.overload('[B', 'int').implementation = function () {
let result = this.encodeToString.apply(this, arguments);
printData("Base64 param", arguments[0]);
console.log("-------------------------------");
console.log("Base64 result:" + result);
console.log("============================================================");
return result;
}
}
// 消息摘要算法hook
hookMessageDigest();
// Mac算法hook
hookMac();
// hookCipher
hookCipher();
// 数据签名算法hook
hookSignature();
// hookBase64编码
hookBase64();
})
|