mirror of
https://github.com/stulle123/kakaotalk_analysis.git
synced 2025-02-06 15:05:47 +00:00
Update LOCO tracer script
This commit is contained in:
parent
11484d9ac9
commit
c638dca359
|
@ -42,51 +42,72 @@ Java.perform(function () {
|
||||||
hookCipherGetInstance2();
|
hookCipherGetInstance2();
|
||||||
hookCipherGetInstance3();
|
hookCipherGetInstance3();
|
||||||
hookCipherInit();
|
hookCipherInit();
|
||||||
hookCipherInit2(); // Kakaotalk
|
|
||||||
hookCipherInit3();
|
hookCipherInit3();
|
||||||
hookCipherInit4(); // Kakaotalk
|
|
||||||
hookCipherInit5();
|
hookCipherInit5();
|
||||||
hookCipherInit6(); // Kakaotalk
|
|
||||||
hookCipherInit7();
|
hookCipherInit7();
|
||||||
hookCipherInit8();
|
hookCipherInit8();
|
||||||
hookDoFinal();
|
|
||||||
hookDoFinal2(); // Kakaotalk
|
|
||||||
hookDoFinal3();
|
|
||||||
hookDoFinal4();
|
|
||||||
hookDoFinal5();
|
|
||||||
hookDoFinal6();
|
|
||||||
hookDoFinal7();
|
|
||||||
hookUpdate();
|
hookUpdate();
|
||||||
hookUpdate2();
|
hookUpdate2();
|
||||||
hookUpdate3();
|
hookUpdate3();
|
||||||
hookUpdate4();
|
hookUpdate4();
|
||||||
hookUpdate5();
|
hookUpdate5();
|
||||||
hookIVParameterSpecDefInit1(); // Kakaotalk
|
|
||||||
hookIVParameterSpecDefInit2(); // Kakaotalk
|
|
||||||
hookSecretKeySpecDefInit1(); // Kakaotalk
|
|
||||||
hookSecretKeySpecDefInit2(); // Kakaotalk
|
|
||||||
hookKeyGeneratorGetInstance(); // Kakaotalk
|
hookKeyGeneratorGetInstance(); // Kakaotalk
|
||||||
hookKeyGeneratorGetInstance2();
|
hookKeyGeneratorGetInstance2();
|
||||||
hookKeyGeneratorGetInstance3();
|
hookKeyGeneratorGetInstance3();
|
||||||
hookKeyGeneratorInit(); // Kakaotalk
|
hookKeyGeneratorInit(); // Kakaotalk
|
||||||
hookKeyGeneratorGenerateKey(); // Kakaotalk
|
|
||||||
hookKeyPairGeneratorGetInstance(); // Kakaotalk
|
hookKeyPairGeneratorGetInstance(); // Kakaotalk
|
||||||
hookPBEKeySpec();
|
|
||||||
hookPBEKeySpec2();
|
|
||||||
hookPBEKeySpec3(); // Kakaotalk
|
|
||||||
// hookV2SLSinkInit(); // Kakaotalk
|
|
||||||
*/
|
*/
|
||||||
hookDoFinal2(); // Kakaotalk
|
// hookV2SLSinkInit(); // Kakaotalk
|
||||||
hookKeyGeneratorGenerateKey(); // Kakaotalk
|
hookCipherInit();
|
||||||
|
hookCipherInit2(); // Kakaotalk
|
||||||
|
// hookCipherInit3();
|
||||||
|
// hookCipherInit4(); // Kakaotalk
|
||||||
|
// hookCipherInit5();
|
||||||
|
hookCipherInit6(); // Kakaotalk
|
||||||
|
// hookCipherInit7();
|
||||||
|
// hookCipherInit8();
|
||||||
|
// hookPBEKeySpec();
|
||||||
|
// hookPBEKeySpec2();
|
||||||
// hookPBEKeySpec3(); // Kakaotalk
|
// hookPBEKeySpec3(); // Kakaotalk
|
||||||
|
hookDoFinal();
|
||||||
|
// hookDoFinal2(); // Kakaotalk
|
||||||
|
hookDoFinal3();
|
||||||
|
hookDoFinal4();
|
||||||
|
hookDoFinal5();
|
||||||
|
hookDoFinal7();
|
||||||
|
// hookIVParameterSpecDefInit1(); // Kakaotalk
|
||||||
|
// hookIVParameterSpecDefInit2(); // Kakaotalk
|
||||||
|
// hookSecretKeySpecDefInit1(); // Kakaotalk
|
||||||
|
// hookSecretKeySpecDefInit2(); // Kakaotalk
|
||||||
|
hookKeyGeneratorGenerateKey(); // Kakaotalk
|
||||||
|
hookLocoCipherHelper();
|
||||||
|
// hookLocoCipherHelper_2();
|
||||||
|
hookLocoCipherHelper_3();
|
||||||
|
hookLocoCipherHelper_4();
|
||||||
|
hookLocoCipherHelper_6();
|
||||||
|
hookSecretChatHelper();
|
||||||
|
hookSecretChatHelper_2();
|
||||||
|
hookSecretChatHelper_3();
|
||||||
|
hookLocoPubKeyInfo();
|
||||||
|
// hookWTFbase64();
|
||||||
|
// hookLocoCipherHelper_5();
|
||||||
|
// hookLocoSKeyInfo();
|
||||||
|
// hookTalkLocoPKStore();
|
||||||
|
// hookTalkLocoPKStore_2();
|
||||||
|
// hookAESCTRHelper();
|
||||||
|
// hookAESCTRKeySet();
|
||||||
|
// enableWebviewDebugging();
|
||||||
|
// hookTest();
|
||||||
|
// hookURIController();
|
||||||
|
// deepLinkSniffer();
|
||||||
|
// hookStrings();
|
||||||
});
|
});
|
||||||
|
|
||||||
const locoClasses = ["c41.c", "cv.a", "cv.b", "mw0.a", "mw0.c", "mw0.d", "mw0.e", "com.android.org.conscrypt.KeyGeneratorImpl"];
|
|
||||||
const secretChatClasses = ["xa1.a", "xa1.i", "xa1.k", "LocoCipherHelper"];
|
|
||||||
const locoKey = Java.array("byte", [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
const locoKey = Java.array("byte", [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||||
|
const doNotHookFileNames = ["SimpleCipher.kt", "AccountUpdater.kt", "DataBaseResourceCrypto.kt", "CookieContentEncryptor.java", "Aes256Cipher.kt", "V2SLSink.kt", "V2SLSource.kt", "V2SLHandshake.kt", "LocoV2SLSocket.kt"]
|
||||||
const patchKey = true;
|
const patchKey = true;
|
||||||
const printStacktrace = false;
|
const printStacktrace = true;
|
||||||
const hookAllClasses = false
|
const hookAllClasses = false;
|
||||||
|
|
||||||
var StringCls = null;
|
var StringCls = null;
|
||||||
Java.perform(function () {
|
Java.perform(function () {
|
||||||
|
@ -103,7 +124,8 @@ function hookCipherGetInstance() {
|
||||||
cipherGetInstance.implementation = function (type) {
|
cipherGetInstance.implementation = function (type) {
|
||||||
var tmp = this.getInstance(type);
|
var tmp = this.getInstance(type);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName());
|
||||||
console.log("[Cipher.getInstance()]: type: " + type);
|
console.log("[Cipher.getInstance()]: type: " + type);
|
||||||
console.log("[Cipher.getInstance()]: cipherObj: " + tmp);
|
console.log("[Cipher.getInstance()]: cipherObj: " + tmp);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
|
@ -118,9 +140,9 @@ function hookCipherGetInstance() {
|
||||||
|
|
||||||
function hookCipherGetInstance2() {
|
function hookCipherGetInstance2() {
|
||||||
var cipherGetInstance = Java.use("javax.crypto.Cipher")["getInstance"].overload("java.lang.String", "java.security.Provider");
|
var cipherGetInstance = Java.use("javax.crypto.Cipher")["getInstance"].overload("java.lang.String", "java.security.Provider");
|
||||||
cipherGetInstance.implementation = function (transforamtion, provider) {
|
cipherGetInstance.implementation = function (transformation, provider) {
|
||||||
console.log("[Cipher.getInstance2()]: transforamtion: " + transforamtion + ", provider: " + provider);
|
console.log("[Cipher.getInstance2()]: transformation: " + transformation + ", provider: " + provider);
|
||||||
var tmp = this.getInstance(transforamtion, provider);
|
var tmp = this.getInstance(transformation, provider);
|
||||||
console.log("[Cipher.getInstance2()]: cipherObj: " + tmp);
|
console.log("[Cipher.getInstance2()]: cipherObj: " + tmp);
|
||||||
cipherList.push(tmp);
|
cipherList.push(tmp);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
@ -129,9 +151,9 @@ function hookCipherGetInstance2() {
|
||||||
|
|
||||||
function hookCipherGetInstance3() {
|
function hookCipherGetInstance3() {
|
||||||
var cipherGetInstance = Java.use("javax.crypto.Cipher")["getInstance"].overload("java.lang.String", "java.lang.String");
|
var cipherGetInstance = Java.use("javax.crypto.Cipher")["getInstance"].overload("java.lang.String", "java.lang.String");
|
||||||
cipherGetInstance.implementation = function (transforamtion, provider) {
|
cipherGetInstance.implementation = function (transformation, provider) {
|
||||||
console.log("[Cipher.getInstance3()]: transforamtion: " + transforamtion + ", provider: " + provider);
|
console.log("[Cipher.getInstance3()]: transformation: " + transformation + ", provider: " + provider);
|
||||||
var tmp = this.getInstance(transforamtion, provider);
|
var tmp = this.getInstance(transformation, provider);
|
||||||
console.log("[Cipher.getInstance3()]: cipherObj: " + tmp);
|
console.log("[Cipher.getInstance3()]: cipherObj: " + tmp);
|
||||||
cipherList.push(tmp);
|
cipherList.push(tmp);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
@ -161,20 +183,26 @@ function hookCipherInit2() {
|
||||||
cipherInit.implementation = function (mode, secretKey) {
|
cipherInit.implementation = function (mode, secretKey) {
|
||||||
var tmp = this.init(mode, secretKey);
|
var tmp = this.init(mode, secretKey);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
var key = secretKey.getEncoded();
|
||||||
console.log("[Cipher.init2()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " , cipherObj: " + this);
|
console.log("[Cipher.init2()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " , cipherObj: " + this);
|
||||||
if (printStacktrace) {
|
console.log("Caller: " + caller.getFileName());
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
// dumpByteArray("Secret key", key);
|
||||||
console.log(stacktrace);
|
var key_base64 = Java.use("android.util.Base64").encodeToString(key, 0);
|
||||||
}
|
console.log("Base64 encoded key: " + key_base64);
|
||||||
console.log("##############################################")
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
}
|
}
|
||||||
|
console.log("##############################################")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hookCipherInit3() {
|
function hookCipherInit3() {
|
||||||
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.Key", "java.security.AlgorithmParameters");
|
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.Key", "java.security.AlgorithmParameters");
|
||||||
cipherInit.implementation = function (mode, secretKey, alParam) {
|
cipherInit.implementation = function (mode, secretKey, alParam) {
|
||||||
|
var key = secretKey.getEncoded();
|
||||||
|
dumpByteArray("Secret key", key);
|
||||||
console.log("[Cipher.init3()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " alParam:" + alParam + " , cipherObj: " + this);
|
console.log("[Cipher.init3()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " alParam:" + alParam + " , cipherObj: " + this);
|
||||||
var tmp = this.init(mode, secretKey, alParam);
|
var tmp = this.init(mode, secretKey, alParam);
|
||||||
}
|
}
|
||||||
|
@ -185,8 +213,13 @@ function hookCipherInit4() {
|
||||||
cipherInit.implementation = function (mode, secretKey, spec) {
|
cipherInit.implementation = function (mode, secretKey, spec) {
|
||||||
var tmp = this.init(mode, secretKey, spec);
|
var tmp = this.init(mode, secretKey, spec);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName());
|
||||||
console.log("[Cipher.init4()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " spec:" + spec + " , cipherObj: " + this);
|
console.log("[Cipher.init4()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " spec:" + spec + " , cipherObj: " + this);
|
||||||
|
var key = secretKey.getEncoded();
|
||||||
|
dumpByteArray("Secret key", key);
|
||||||
|
var ivParameterSpec = Java.cast(spec, Java.use("javax.crypto.spec.IvParameterSpec"));
|
||||||
|
dumpByteArray("IV", ivParameterSpec.getIV());
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
console.log(stacktrace);
|
console.log(stacktrace);
|
||||||
|
@ -199,6 +232,8 @@ function hookCipherInit4() {
|
||||||
function hookCipherInit5() {
|
function hookCipherInit5() {
|
||||||
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.cert.Certificate", "java.security.SecureRandom");
|
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.cert.Certificate", "java.security.SecureRandom");
|
||||||
cipherInit.implementation = function (mode, cert, secureRandom) {
|
cipherInit.implementation = function (mode, cert, secureRandom) {
|
||||||
|
var key = secureRandom.getEncoded();
|
||||||
|
dumpByteArray("Secret key", key);
|
||||||
console.log("[Cipher.init5()]: mode: " + decodeMode(mode) + ", cert: " + cert + " secureRandom:" + secureRandom + " , cipherObj: " + this);
|
console.log("[Cipher.init5()]: mode: " + decodeMode(mode) + ", cert: " + cert + " secureRandom:" + secureRandom + " , cipherObj: " + this);
|
||||||
var tmp = this.init(mode, cert, secureRandom);
|
var tmp = this.init(mode, cert, secureRandom);
|
||||||
}
|
}
|
||||||
|
@ -209,8 +244,13 @@ function hookCipherInit6() {
|
||||||
cipherInit.implementation = function (mode, secretKey, secureRandom) {
|
cipherInit.implementation = function (mode, secretKey, secureRandom) {
|
||||||
var tmp = this.init(mode, secretKey, secureRandom);
|
var tmp = this.init(mode, secretKey, secureRandom);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
var key = secretKey.getEncoded();
|
||||||
console.log("[Cipher.init6()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " secureRandom:" + secureRandom + " , cipherObj: " + this);
|
console.log("[Cipher.init6()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " secureRandom:" + secureRandom + " , cipherObj: " + this);
|
||||||
|
console.log("Caller: " + caller.getFileName());
|
||||||
|
// dumpByteArray("Secret key", key);
|
||||||
|
var secret_key_base64 = Java.use("android.util.Base64").encodeToString(key, 0);
|
||||||
|
console.log("Secret key: " + secret_key_base64)
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
console.log(stacktrace);
|
console.log(stacktrace);
|
||||||
|
@ -223,6 +263,8 @@ function hookCipherInit6() {
|
||||||
function hookCipherInit7() {
|
function hookCipherInit7() {
|
||||||
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.Key", "java.security.spec.AlgorithmParameterSpec", "java.security.SecureRandom");
|
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.Key", "java.security.spec.AlgorithmParameterSpec", "java.security.SecureRandom");
|
||||||
cipherInit.implementation = function (mode, secretKey, spec, secureRandom) {
|
cipherInit.implementation = function (mode, secretKey, spec, secureRandom) {
|
||||||
|
var key = secretKey.getEncoded();
|
||||||
|
dumpByteArray("Secret key", key);
|
||||||
console.log("[Cipher.init7()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " spec:" + spec + " secureRandom: " + secureRandom + " , cipherObj: " + this);
|
console.log("[Cipher.init7()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " spec:" + spec + " secureRandom: " + secureRandom + " , cipherObj: " + this);
|
||||||
var tmp = this.init(mode, secretKey, spec, secureRandom);
|
var tmp = this.init(mode, secretKey, spec, secureRandom);
|
||||||
}
|
}
|
||||||
|
@ -231,6 +273,8 @@ function hookCipherInit7() {
|
||||||
function hookCipherInit8() {
|
function hookCipherInit8() {
|
||||||
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.Key", "java.security.AlgorithmParameters", "java.security.SecureRandom");
|
var cipherInit = Java.use("javax.crypto.Cipher")["init"].overload("int", "java.security.Key", "java.security.AlgorithmParameters", "java.security.SecureRandom");
|
||||||
cipherInit.implementation = function (mode, secretKey, alParam, secureRandom) {
|
cipherInit.implementation = function (mode, secretKey, alParam, secureRandom) {
|
||||||
|
var key = secretKey.getEncoded();
|
||||||
|
dumpByteArray("Secret key", key);
|
||||||
console.log("[Cipher.init8()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " alParam:" + alParam + " secureRandom: " + secureRandom + " , cipherObj: " + this);
|
console.log("[Cipher.init8()]: mode: " + decodeMode(mode) + ", secretKey: " + secretKey.$className + " alParam:" + alParam + " secureRandom: " + secureRandom + " , cipherObj: " + this);
|
||||||
var tmp = this.init(mode, secretKey, alParam, secureRandom);
|
var tmp = this.init(mode, secretKey, alParam, secureRandom);
|
||||||
}
|
}
|
||||||
|
@ -260,10 +304,13 @@ function hookDoFinal2() {
|
||||||
cipherInit.implementation = function (byteArr) {
|
cipherInit.implementation = function (byteArr) {
|
||||||
var tmp = this.doFinal(byteArr);
|
var tmp = this.doFinal(byteArr);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
console.log("[Cipher.doFinal2()]: " + " cipherObj: " + this);
|
console.log("[Cipher.doFinal2()]: " + " cipherObj: " + this);
|
||||||
|
console.log("Caller " + caller.getFileName())
|
||||||
dumpByteArray("In buffer (cipher: " + this.getAlgorithm() + ")", byteArr);
|
dumpByteArray("In buffer (cipher: " + this.getAlgorithm() + ")", byteArr);
|
||||||
dumpByteArray("Result", tmp);
|
// dumpByteArray("Result", tmp);
|
||||||
|
var result_base64 = Java.use("android.util.Base64").encodeToString(tmp, 0);
|
||||||
|
console.log("Result in Base64: " + result_base64)
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
console.log(stacktrace);
|
console.log(stacktrace);
|
||||||
|
@ -400,7 +447,8 @@ function hookIVParameterSpecDefInit1() {
|
||||||
var ivParameterSpecDef = ivParameterSpecDef = Java.use("javax.crypto.spec.IvParameterSpec").$init.overload("[B");
|
var ivParameterSpecDef = ivParameterSpecDef = Java.use("javax.crypto.spec.IvParameterSpec").$init.overload("[B");
|
||||||
ivParameterSpecDef.implementation = function (arr) {
|
ivParameterSpecDef.implementation = function (arr) {
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName());
|
||||||
dumpByteArray("IV", arr)
|
dumpByteArray("IV", arr)
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
@ -416,7 +464,8 @@ function hookIVParameterSpecDefInit2() {
|
||||||
var ivParameterSpecDef = ivParameterSpecDef = Java.use("javax.crypto.spec.IvParameterSpec").$init.overload("[B", "int", "int");
|
var ivParameterSpecDef = ivParameterSpecDef = Java.use("javax.crypto.spec.IvParameterSpec").$init.overload("[B", "int", "int");
|
||||||
ivParameterSpecDef.implementation = function (arr, off, len) {
|
ivParameterSpecDef.implementation = function (arr, off, len) {
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName())
|
||||||
dumpByteArray("IV", arr)
|
dumpByteArray("IV", arr)
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
@ -436,8 +485,9 @@ function hookSecretKeySpecDefInit1() {
|
||||||
var secretKeySpecDef = Java.use("javax.crypto.spec.SecretKeySpec").$init.overload("[B", "java.lang.String");
|
var secretKeySpecDef = Java.use("javax.crypto.spec.SecretKeySpec").$init.overload("[B", "java.lang.String");
|
||||||
secretKeySpecDef.implementation = function (arr, alg) {
|
secretKeySpecDef.implementation = function (arr, alg) {
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
dumpByteArray("Original " + alg + " Secret Key", arr);
|
console.log(caller.getFileName())
|
||||||
|
dumpByteArray(alg + " Secret Key", arr);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
console.log(stacktrace);
|
console.log(stacktrace);
|
||||||
|
@ -452,7 +502,8 @@ function hookSecretKeySpecDefInit2() {
|
||||||
var secretKeySpecDef = Java.use("javax.crypto.spec.SecretKeySpec").$init.overload("[B", "int", "int", "java.lang.String");
|
var secretKeySpecDef = Java.use("javax.crypto.spec.SecretKeySpec").$init.overload("[B", "int", "int", "java.lang.String");
|
||||||
secretKeySpecDef.implementation = function (arr, off, len, alg) {
|
secretKeySpecDef.implementation = function (arr, off, len, alg) {
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName())
|
||||||
dumpByteArray(alg + " Secret Key", arr);
|
dumpByteArray(alg + " Secret Key", arr);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
@ -474,7 +525,8 @@ function hookKeyGeneratorGetInstance() {
|
||||||
keyGeneratorInit.implementation = function (type) {
|
keyGeneratorInit.implementation = function (type) {
|
||||||
var tmp = this.getInstance(type);
|
var tmp = this.getInstance(type);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName());
|
||||||
console.log("[KeyGenerator.getInstance()]: type: " + type);
|
console.log("[KeyGenerator.getInstance()]: type: " + type);
|
||||||
console.log("[KeyGenerator.getInstance()]: cipherObj: " + tmp);
|
console.log("[KeyGenerator.getInstance()]: cipherObj: " + tmp);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
|
@ -490,8 +542,10 @@ function hookKeyGeneratorGetInstance() {
|
||||||
function hookKeyGeneratorGetInstance2() {
|
function hookKeyGeneratorGetInstance2() {
|
||||||
var keyGeneratorInit = Java.use("javax.crypto.KeyGenerator")["getInstance"].overload("java.lang.String", "java.lang.String");
|
var keyGeneratorInit = Java.use("javax.crypto.KeyGenerator")["getInstance"].overload("java.lang.String", "java.lang.String");
|
||||||
keyGeneratorInit.implementation = function (alg, provider) {
|
keyGeneratorInit.implementation = function (alg, provider) {
|
||||||
|
var tmp = this.getInstance(alg, provider);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName());
|
||||||
console.log("[KeyGenerator.getInstance2()]: Algorithm: " + alg);
|
console.log("[KeyGenerator.getInstance2()]: Algorithm: " + alg);
|
||||||
console.log("[KeyGenerator.getInstance2()]: Provider: " + provider);
|
console.log("[KeyGenerator.getInstance2()]: Provider: " + provider);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
|
@ -507,8 +561,10 @@ function hookKeyGeneratorGetInstance2() {
|
||||||
function hookKeyGeneratorGetInstance3() {
|
function hookKeyGeneratorGetInstance3() {
|
||||||
var keyGeneratorInit = Java.use("javax.crypto.KeyGenerator")["getInstance"].overload("java.lang.String", "java.security.Provider");
|
var keyGeneratorInit = Java.use("javax.crypto.KeyGenerator")["getInstance"].overload("java.lang.String", "java.security.Provider");
|
||||||
keyGeneratorInit.implementation = function (alg, provider) {
|
keyGeneratorInit.implementation = function (alg, provider) {
|
||||||
|
var tmp = this.getInstance(alg, provider);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName());
|
||||||
console.log("[KeyGenerator.getInstance2()]: Algorithm: " + alg);
|
console.log("[KeyGenerator.getInstance2()]: Algorithm: " + alg);
|
||||||
console.log("[KeyGenerator.getInstance2()]: Provider: " + provider);
|
console.log("[KeyGenerator.getInstance2()]: Provider: " + provider);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
|
@ -529,7 +585,8 @@ function hookKeyGeneratorInit() {
|
||||||
keyGeneratorInit.implementation = function (length, secureRandom) {
|
keyGeneratorInit.implementation = function (length, secureRandom) {
|
||||||
var tmp = this.init(length, secureRandom);
|
var tmp = this.init(length, secureRandom);
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log(caller.getFileName());
|
||||||
console.log("[KeyGenerator.init()]: secureRandom:" + secureRandom + " , cipherObj: " + this);
|
console.log("[KeyGenerator.init()]: secureRandom:" + secureRandom + " , cipherObj: " + this);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
@ -548,24 +605,24 @@ function hookKeyGeneratorGenerateKey() {
|
||||||
generateKey.implementation = function () {
|
generateKey.implementation = function () {
|
||||||
var tmp = this.generateKey();
|
var tmp = this.generateKey();
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
const secretKeySpec = Java.cast(tmp, Java.use("javax.crypto.spec.SecretKeySpec"));
|
||||||
const secretKeySpec = Java.cast(tmp, Java.use("javax.crypto.spec.SecretKeySpec"));
|
const encodedKey = secretKeySpec.getEncoded();
|
||||||
const encodedKey = secretKeySpec.getEncoded();
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
/*
|
|
||||||
console.log("[KeyGenerator.generateKey()]: Object: " + tmp);
|
console.log("[KeyGenerator.generateKey()]: Object: " + tmp);
|
||||||
dumpByteArray("[KeyGenerator.generateKey()]: Key:", encodedKey);
|
console.log("Caller: " + caller.getFileName());
|
||||||
|
dumpByteArray("[KeyGenerator.generateKey()]: Key", encodedKey);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
console.log(stacktrace);
|
console.log(stacktrace);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if (patchKey) {
|
|
||||||
const SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec");
|
|
||||||
var fakeKey = SecretKeySpec.$new(locoKey, "AES");
|
|
||||||
tmp = fakeKey
|
|
||||||
}
|
|
||||||
console.log("##############################################");
|
|
||||||
}
|
}
|
||||||
|
if (patchKey) {
|
||||||
|
console.log("Patching LOCO AES key...")
|
||||||
|
const SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec");
|
||||||
|
var fakeKey = SecretKeySpec.$new(locoKey, "AES");
|
||||||
|
tmp = fakeKey
|
||||||
|
}
|
||||||
|
console.log("##############################################");
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,14 +634,13 @@ function hookKeyPairGeneratorGetInstance() {
|
||||||
var keyPairGetInstance = Java.use("java.security.KeyPairGenerator")["getInstance"].overload("java.lang.String");
|
var keyPairGetInstance = Java.use("java.security.KeyPairGenerator")["getInstance"].overload("java.lang.String");
|
||||||
keyPairGetInstance.implementation = function (alg) {
|
keyPairGetInstance.implementation = function (alg) {
|
||||||
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
if (locoClasses.includes(caller.getClassName()) || hookAllClasses) {
|
console.log(caller.getFileName());
|
||||||
console.log("[KeyPairGenerator.getInstance()]: Algorithm:" + alg);
|
console.log("[KeyPairGenerator.getInstance()]: Algorithm:" + alg);
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
console.log(stacktrace);
|
console.log(stacktrace);
|
||||||
}
|
|
||||||
console.log("##############################################")
|
|
||||||
}
|
}
|
||||||
|
console.log("##############################################")
|
||||||
return this.getInstance(alg);
|
return this.getInstance(alg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,7 +670,10 @@ function hookPBEKeySpec2() {
|
||||||
function hookPBEKeySpec3() {
|
function hookPBEKeySpec3() {
|
||||||
var PBEKeySpec = Java.use('javax.crypto.spec.PBEKeySpec')['$init'].overload('[C', '[B', 'int', 'int');
|
var PBEKeySpec = Java.use('javax.crypto.spec.PBEKeySpec')['$init'].overload('[C', '[B', 'int', 'int');
|
||||||
PBEKeySpec.implementation = function (pass, salt, iter, keyLength) {
|
PBEKeySpec.implementation = function (pass, salt, iter, keyLength) {
|
||||||
console.log("[PBEKeySpec.PBEKeySpec3()]: password: " + charArrayToString(pass) + " iter: " + iter + " key length: " + keyLength);
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log("[PBEKeySpec.PBEKeySpec3()]: iter: " + iter + " key length: " + keyLength);
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
dumpByteArray("Password", charArrayToString(pass).getBytes());
|
||||||
dumpByteArray("Salt", salt)
|
dumpByteArray("Salt", salt)
|
||||||
if (printStacktrace) {
|
if (printStacktrace) {
|
||||||
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
@ -639,6 +698,494 @@ function hookV2SLSinkInit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hookLocoCipherHelper() {
|
||||||
|
var locoCipherHelper = Java.use("com.kakao.talk.secret.LocoCipherHelper$e")["$init"].overload("java.lang.String", "long");
|
||||||
|
locoCipherHelper.implementation = function (arg0, arg1) {
|
||||||
|
var tmp = this.$init(arg0, arg1);
|
||||||
|
console.log("hookLocoCipherHelper called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
console.log("Master key: " + arg0);
|
||||||
|
console.log("Nonce: " + arg1);
|
||||||
|
console.log(this.toString());
|
||||||
|
console.log("##############################################")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookLocoCipherHelper_2() {
|
||||||
|
var locoCipherHelper = Java.use("com.kakao.talk.secret.LocoCipherHelper")["s"].overload("com.kakao.talk.secret.LocoCipherHelper$c", "[B", "[B");
|
||||||
|
locoCipherHelper.implementation = function (arg0, arg1, arg2) {
|
||||||
|
console.log("hookLocoCipherHelper2 called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
var ret = locoCipherHelper.call(this, arg0, arg1, arg2);
|
||||||
|
console.log(ret)
|
||||||
|
return locoCipherHelper.call(this, arg0, arg1, arg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookLocoCipherHelper_3() {
|
||||||
|
var locoCipherHelper = Java.use("com.kakao.talk.secret.LocoCipherHelper")["e"].overload("java.lang.String");
|
||||||
|
locoCipherHelper.implementation = function (arg0) {
|
||||||
|
console.log("hookLocoCipherHelper3 called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
var private_key = locoCipherHelper.call(this, arg0);
|
||||||
|
// var encoded_key = Java.use("android.util.Base64").encodeToString(private_key.getEncoded(), 0);
|
||||||
|
console.log("Generate RSA private key from string: " + arg0);
|
||||||
|
// console.log(encoded_key)
|
||||||
|
console.log("##############################################");
|
||||||
|
return locoCipherHelper.call(this, arg0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookLocoCipherHelper_4() {
|
||||||
|
var locoCipherHelper = Java.use("com.kakao.talk.secret.LocoCipherHelper")["f"].overload("java.lang.String");
|
||||||
|
locoCipherHelper.implementation = function (arg0) {
|
||||||
|
console.log("hookLocoCipherHelper4 called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
var ret = locoCipherHelper.call(this, arg0);
|
||||||
|
console.log("Caller " + caller.getFileName());
|
||||||
|
console.log("Generate RSA public key from string: " + arg0);
|
||||||
|
var public_key = locoCipherHelper.call(this, arg0);
|
||||||
|
// var encoded_key = Java.use("android.util.Base64").encodeToString(public_key.getEncoded(), 0);
|
||||||
|
// console.log(encoded_key);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("##############################################");
|
||||||
|
return locoCipherHelper.call(this, arg0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookLocoCipherHelper_5() {
|
||||||
|
var locoCipherHelper = Java.use("com.kakao.talk.secret.LocoCipherHelper$b")["$init"].overload("com.kakao.talk.secret.LocoCipherHelper$d", "com.kakao.talk.secret.LocoCipherHelper$c");
|
||||||
|
locoCipherHelper.implementation = function (arg0, arg1) {
|
||||||
|
var tmp = this.$init(arg0, arg1);
|
||||||
|
console.log("hookLocoCipherHelper5 called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
console.log(arg0);
|
||||||
|
console.log(arg1);
|
||||||
|
console.log(this.toString());
|
||||||
|
console.log("##############################################")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookLocoCipherHelper_6() {
|
||||||
|
var locoCipherHelper = Java.use("com.kakao.talk.secret.LocoCipherHelper")["l"].overload();
|
||||||
|
locoCipherHelper.implementation = function () {
|
||||||
|
console.log("hookLocoCipherHelper6 called!");
|
||||||
|
key = locoCipherHelper.call(this);
|
||||||
|
dumpByteArray("Generated shared secret", key);
|
||||||
|
console.log("##############################################")
|
||||||
|
return locoCipherHelper.call(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookLocoPubKeyInfo() {
|
||||||
|
var locoPubKeyInfo = Java.use("tz0.n")["$init"].overload("com.kakao.talk.loco.protocol.LocoBody");
|
||||||
|
locoPubKeyInfo.implementation = function (locoBody) {
|
||||||
|
var tmp = this.$init(locoBody);
|
||||||
|
console.log("locoPubKeyInfo called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
console.log(locoBody);
|
||||||
|
console.log("##############################################")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookSecretChatHelper() {
|
||||||
|
var secretChatHelper = Java.use("com.kakao.talk.secret.b")["k"].overload("long", "long");
|
||||||
|
secretChatHelper.implementation = function (arg0, arg1) {
|
||||||
|
console.log("secretChatHelper called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
console.log("Long 1: " + arg0);
|
||||||
|
console.log("Long 2: " + arg1);
|
||||||
|
var ret = secretChatHelper.call(this, arg0, arg1);
|
||||||
|
console.log("##############################################")
|
||||||
|
return secretChatHelper.call(this, arg0, arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookSecretChatHelper_2() {
|
||||||
|
var secretChatHelper = Java.use("com.kakao.talk.secret.b$e")["a"].overload("long", "long");
|
||||||
|
secretChatHelper.implementation = function (arg0, arg1) {
|
||||||
|
console.log("secretChatHelper2 called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
console.log("Long 1: " + arg0);
|
||||||
|
console.log("Long 2: " + arg1);
|
||||||
|
var ret = secretChatHelper.call(this, arg0, arg1);
|
||||||
|
console.log(ret);
|
||||||
|
console.log(this.a);
|
||||||
|
console.log("##############################################")
|
||||||
|
return secretChatHelper.call(this, arg0, arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookSecretChatHelper_3() {
|
||||||
|
var secretChatHelper = Java.use("com.kakao.talk.secret.b$e")["b"].overload("com.kakao.talk.secret.b$d");
|
||||||
|
secretChatHelper.implementation = function (arg0) {
|
||||||
|
console.log("secretChatHelper3 called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName());
|
||||||
|
console.log(this.a);
|
||||||
|
console.log("##############################################")
|
||||||
|
return secretChatHelper.call(this, arg0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookWTFbase64() {
|
||||||
|
var wtfBase64 = Java.use("com.kakao.talk.util.r")["a"].overload("java.lang.String");
|
||||||
|
wtfBase64.implementation = function (arg0) {
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
if (!(doNotHookFileNames.includes(caller.getFileName())) || hookAllClasses) {
|
||||||
|
console.log("WTF called");
|
||||||
|
console.log("Caller: " + caller.getFileName());
|
||||||
|
console.log("Base64 encoded: " + arg0);
|
||||||
|
var ret = wtfBase64.call(this, arg0);
|
||||||
|
dumpByteArray("Base64 decoded bytes", ret);
|
||||||
|
console.log("##############################################")
|
||||||
|
}
|
||||||
|
return wtfBase64.call(this, arg0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookLocoSKeyInfo() {
|
||||||
|
var locoSKeyInfo = Java.use("tz0.o")["$init"].overload("com.kakao.talk.loco.protocol.LocoBody");
|
||||||
|
locoSKeyInfo.implementation = function (arg0) {
|
||||||
|
var tmp = this.$init(arg0);
|
||||||
|
console.log("hookLocoSKeyInfo called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log("au: " + this.a);
|
||||||
|
console.log("sk: " + this.b);
|
||||||
|
console.log("as: " + this.c);
|
||||||
|
console.log("pt: " + this.d);
|
||||||
|
console.log("apt: " + this.e);
|
||||||
|
console.log("st: " + this.f);
|
||||||
|
console.log("##############################################")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookTalkLocoPKStore() {
|
||||||
|
var talkLocoPKStore = Java.use("df1.e4")["toString"].overload();
|
||||||
|
talkLocoPKStore.implementation = function () {
|
||||||
|
console.log("talkLocoPKStore called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName())
|
||||||
|
var ret = talkLocoPKStore.call(this);
|
||||||
|
console.log(ret)
|
||||||
|
console.log("##############################################")
|
||||||
|
return talkLocoPKStore.call(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookTalkLocoPKStore_2() {
|
||||||
|
var talkLocoPKStore = Java.use("df1.e4$a")["toString"].overload();
|
||||||
|
talkLocoPKStore.implementation = function () {
|
||||||
|
console.log("talkLocoPKStore2 called!");
|
||||||
|
var caller = Java.use("java.lang.Exception").$new().getStackTrace()[1];
|
||||||
|
console.log(caller.getFileName())
|
||||||
|
var ret = talkLocoPKStore.call(this);
|
||||||
|
console.log(ret)
|
||||||
|
console.log("##############################################")
|
||||||
|
return talkLocoPKStore.call(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookAESCTRHelper() {
|
||||||
|
var AESCTRHelper = Java.use("sy.a")["b"].overload("java.lang.String", "[B", "int", "javax.crypto.spec.PBEKeySpec");
|
||||||
|
AESCTRHelper.implementation = function (arg0, arg1, arg2, arg3) {
|
||||||
|
console.log("hookAESCTRHelper called!");
|
||||||
|
dumpByteArray("Generated IV", arg1);
|
||||||
|
console.log("##############################################");
|
||||||
|
return AESCTRHelper.call(this, arg0, arg1, arg2, arg3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookAESCTRKeySet() {
|
||||||
|
var AESCTRKeySet = Java.use("sy.b")["$init"].overload("[B", "[B", "[B");
|
||||||
|
AESCTRKeySet.implementation = function (arg0, arg1, arg2) {
|
||||||
|
console.log("AESCTRKeySet called!");
|
||||||
|
dumpByteArray("Secret key", arg0);
|
||||||
|
dumpByteArray("IV", arg1);
|
||||||
|
dumpByteArray("arg2", arg2);
|
||||||
|
console.log("##############################################");
|
||||||
|
return AESCTRKeySet.call(this, arg0, arg1, arg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableWebviewDebugging() {
|
||||||
|
var Webview = Java.use("android.webkit.WebView");
|
||||||
|
Webview.loadUrl.overload("java.lang.String").implementation = function (url) {
|
||||||
|
console.log("\n[+]Loading URL from", url);
|
||||||
|
console.log("[+]Setting the value of setWebContentsDebuggingEnabled() to TRUE");
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
var js = this.getSettings().getJavaScriptEnabled();
|
||||||
|
console.log("[+]JS enabled: " + js);
|
||||||
|
|
||||||
|
var mw = this.getSettings().supportMultipleWindows();
|
||||||
|
console.log("[+]Mutliple windows?: " + mw);
|
||||||
|
|
||||||
|
var fa = this.getSettings().getAllowFileAccess();
|
||||||
|
console.log("[+]File access: " + fa);
|
||||||
|
|
||||||
|
var uf = this.getSettings().getAllowUniversalAccessFromFileURLs();
|
||||||
|
console.log("[+]Universal file access: " + uf);
|
||||||
|
|
||||||
|
this.setWebContentsDebuggingEnabled(true);
|
||||||
|
this.loadUrl.overload("java.lang.String").call(this, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
Webview.loadUrl.overload("java.lang.String", "java.util.Map").implementation = function (url, additionalHttpHeaders) {
|
||||||
|
console.log("\n[+]Loading URL from", url);
|
||||||
|
console.log("[+]Additional Headers:");
|
||||||
|
var headers = Java.cast(additionalHttpHeaders, Java.use("java.util.Map"));
|
||||||
|
printMap(headers);
|
||||||
|
console.log("[+]Setting the value of setWebContentsDebuggingEnabled() to TRUE");
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
var js = this.getSettings().getJavaScriptEnabled();
|
||||||
|
console.log("[+]JS enabled: " + js);
|
||||||
|
|
||||||
|
var mw = this.getSettings().supportMultipleWindows();
|
||||||
|
console.log("[+]Mutliple windows?: " + mw);
|
||||||
|
|
||||||
|
var fa = this.getSettings().getAllowFileAccess();
|
||||||
|
console.log("[+]File access: " + fa);
|
||||||
|
|
||||||
|
var uf = this.getSettings().getAllowUniversalAccessFromFileURLs();
|
||||||
|
console.log("[+]Universal file access: " + uf);
|
||||||
|
|
||||||
|
this.setWebContentsDebuggingEnabled(true);
|
||||||
|
this.loadUrl.overload("java.lang.String", "java.util.Map").call(this, url, additionalHttpHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
|
Webview.addJavascriptInterface.implementation = function (object, name) {
|
||||||
|
console.log('[+]Javascript interface:' + object.$className + ' instantiated as: ' + name);
|
||||||
|
this.addJavascriptInterface(object, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var WebviewClient = Java.use("android.webkit.WebViewClient");
|
||||||
|
WebviewClient.onPageStarted.overload("android.webkit.WebView", "java.lang.String", "android.graphics.Bitmap").implementation = function (view, url, favicon) {
|
||||||
|
console.log("onPageStarted URL: " + url);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
this.onPageStarted.overload("android.webkit.WebView", "java.lang.String", "android.graphics.Bitmap").call(this, view, url, favicon);
|
||||||
|
}
|
||||||
|
|
||||||
|
var loadURL = Java.use("com.kakao.talk.gametab.widget.webview.KGWebViewLayout").j.overload("android.webkit.WebView", "java.lang.String", "java.util.Map");
|
||||||
|
loadURL.implementation = function (arg0, arg1, arg2) {
|
||||||
|
console.log("KGWebViewLayout loadURL START");
|
||||||
|
console.log(arg0);
|
||||||
|
console.log(arg1);
|
||||||
|
printMap(arg2);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("KGWebViewLayout loadURL END");
|
||||||
|
return this.j(arg0, arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var webviewHelper = Java.use("com.kakao.talk.widget.webview.WebViewHelper");
|
||||||
|
|
||||||
|
var downloadFile = webviewHelper.newDownloadFile.overload("java.lang.String");
|
||||||
|
downloadFile.implementation = function (arg0) {
|
||||||
|
console.log(arg0);
|
||||||
|
var ret = this.newDownloadFile(arg0);
|
||||||
|
console.log(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
var processDownload = webviewHelper.processDownload.overload("android.content.Context", "java.lang.String", "java.lang.String", "java.lang.String");
|
||||||
|
processDownload.implementation = function (arg0, arg1, arg2, arg3) {
|
||||||
|
console.log(arg0);
|
||||||
|
console.log(arg1);
|
||||||
|
console.log(arg2);
|
||||||
|
console.log(arg3);
|
||||||
|
var ret = this.processDownload(arg0, arg1, arg2, arg3);
|
||||||
|
console.log(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
var hookHelp = Java.use("com.kakao.talk.webview.activity.HelpActivity").shouldOverrideUrlLoading.overload("android.webkit.WebView", "java.lang.String");
|
||||||
|
hookHelp.implementation = function (arg0, arg1) {
|
||||||
|
console.log("HELP START");
|
||||||
|
console.log(arg0);
|
||||||
|
console.log(arg1);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("HELP END");
|
||||||
|
return this.shouldOverrideUrlLoading(arg0, arg1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
var hookHelp2 = Java.use("com.kakao.talk.webview.activity.HelpActivity")["a"].overload("java.lang.String");
|
||||||
|
hookHelp2.implementation = function (arg0) {
|
||||||
|
console.log("HELP START");
|
||||||
|
console.log(arg0);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("HELP END");
|
||||||
|
return this.a(arg0);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var hookHelp3 = Java.use("com.kakao.talk.webview.activity.HelpActivity")["loadUrl"].overload("java.lang.String", "java.util.Map");
|
||||||
|
hookHelp3.implementation = function (arg0, arg1) {
|
||||||
|
console.log("HELP START");
|
||||||
|
console.log(arg0);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("HELP END");
|
||||||
|
return this.loadUrl(arg0, arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookTest() {
|
||||||
|
var hookTest = Java.use("db2.q").O.overload("java.lang.String", "java.lang.String", "java.lang.Boolean");
|
||||||
|
hookTest.implementation = function (arg0, arg1, arg2) {
|
||||||
|
this.O.overload("java.lang.String", "java.lang.String", "java.lang.Boolean").call(this, arg0, arg1, arg2);
|
||||||
|
console.log(arg0);
|
||||||
|
console.log(arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookURIController() {
|
||||||
|
var hookTest = Java.use("xv0.k").b.overload("android.content.Context", "android.net.Uri", "java.util.Map");
|
||||||
|
hookTest.implementation = function (arg0, arg1, arg2) {
|
||||||
|
console.log("URI Controller START");
|
||||||
|
console.log(arg0);
|
||||||
|
console.log(arg1);
|
||||||
|
printMap(arg2);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "");
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("URI Controller END");
|
||||||
|
return this.b(arg0, arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hookTest2 = Java.use("xv0.k").a.overload("android.content.Context", "android.net.Uri", "java.util.Map");
|
||||||
|
hookTest2.implementation = function (arg0, arg1, arg2) {
|
||||||
|
console.log("URI Controller 2 START");
|
||||||
|
console.log(arg0);
|
||||||
|
console.log(arg1);
|
||||||
|
printMap(arg2);
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "");
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("URI Controller 2 END");
|
||||||
|
return this.a(arg0, arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hookStartIntent = Java.use("xv0.k").e.overload("android.content.Context", "java.lang.String");
|
||||||
|
hookStartIntent.implementation = function (context, str) {
|
||||||
|
console.log("Context: " + context);
|
||||||
|
console.log("String: " + str);
|
||||||
|
return this.e(context, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
var hookIntentChecker = Java.use("xv0.k").d.overload("android.content.Context", "java.lang.String", "java.lang.Boolean");
|
||||||
|
hookIntentChecker.implementation = function (context, str, bool) {
|
||||||
|
console.log("Context: " + context);
|
||||||
|
console.log("String: " + str);
|
||||||
|
return this.d(context, str, bool);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function deepLinkSniffer() {
|
||||||
|
var Intent = Java.use("android.content.Intent");
|
||||||
|
Intent.getData.implementation = function () {
|
||||||
|
var action = this.getAction() !== null ? this.getAction().toString() : false;
|
||||||
|
if (action) {
|
||||||
|
console.log("[*] Intent.getData() was called");
|
||||||
|
console.log("[*] Activity: " + this.getComponent().getClassName());
|
||||||
|
console.log("[*] Action: " + action);
|
||||||
|
var uri = this.getData();
|
||||||
|
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
var extra = this.getStringExtra("url");
|
||||||
|
|
||||||
|
if (extra !== null) {
|
||||||
|
console.log("Extra data: " + extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uri !== null) {
|
||||||
|
console.log("\n[*] Data");
|
||||||
|
uri.getScheme() && console.log("- Scheme:\t" + uri.getScheme() + "://");
|
||||||
|
uri.getHost() && console.log("- Host:\t\t/" + uri.getHost());
|
||||||
|
uri.getQuery() && console.log("- Params:\t" + uri.getQuery());
|
||||||
|
uri.getFragment() && console.log("- Fragment:\t" + uri.getFragment());
|
||||||
|
console.log("\n\n");
|
||||||
|
} else {
|
||||||
|
console.log("[-] No data supplied.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookStrings() {
|
||||||
|
let StringBuilder = Java.use("java.lang.StringBuilder");
|
||||||
|
StringBuilder.toString.overload().implementation = function () {
|
||||||
|
let StringBuilderResult = this.toString.call(this);
|
||||||
|
|
||||||
|
if (StringBuilderResult !== null && StringBuilderResult.indexOf("file:") != -1) {
|
||||||
|
if (printStacktrace) {
|
||||||
|
var stacktrace = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()).replace("java.lang.Exception", "")
|
||||||
|
console.log(stacktrace);
|
||||||
|
}
|
||||||
|
console.log("[+] StringBuilder:\t", StringBuilderResult);
|
||||||
|
}
|
||||||
|
return StringBuilderResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
let StringBuffer = Java.use("java.lang.StringBuffer");
|
||||||
|
StringBuffer.toString.overload().implementation = function () {
|
||||||
|
let StringBufferResult = this.toString.call(this);
|
||||||
|
|
||||||
|
if (StringBufferResult !== null && StringBufferResult.indexOf("http") != -1) {
|
||||||
|
console.log("[+] StringBuffer:\t", StringBufferResult);
|
||||||
|
}
|
||||||
|
return StringBufferResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utils */
|
||||||
|
function printMap(map) {
|
||||||
|
var mapIter = map.entrySet().iterator();
|
||||||
|
while (mapIter.hasNext()) {
|
||||||
|
console.log(mapIter.next())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function decodeMode(mode) {
|
function decodeMode(mode) {
|
||||||
if (mode == 1)
|
if (mode == 1)
|
||||||
return "Encrypt mode";
|
return "Encrypt mode";
|
||||||
|
@ -657,7 +1204,7 @@ function charArrayToString(charArray) {
|
||||||
return StringCls.$new(charArray);
|
return StringCls.$new(charArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All below is hexdump implementation*/
|
/* All below is hexdump implementation */
|
||||||
function dumpByteArray(title, byteArr) {
|
function dumpByteArray(title, byteArr) {
|
||||||
if (byteArr != null) {
|
if (byteArr != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -682,6 +1229,7 @@ function _fillUp(value, count, fillWith) {
|
||||||
ret += fillWith;
|
ret += fillWith;
|
||||||
return ret + value;
|
return ret + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hexdumpJS(arrayBuffer, offset, length) {
|
function hexdumpJS(arrayBuffer, offset, length) {
|
||||||
|
|
||||||
var view = new DataView(arrayBuffer);
|
var view = new DataView(arrayBuffer);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user