Fix crypto js and add the automatic tracing in the db

This commit is contained in:
ping2A 2024-11-20 09:14:56 +01:00
parent f8daa928e3
commit fca5f2eff5
4 changed files with 948 additions and 762 deletions

View File

@ -1,8 +1,8 @@
// Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets
console.log('[+] LOADING INTERNAL/UTILS.JS');
console.log("[+] LOADING INTERNAL/UTILS.JS");
'use strict';
("use strict");
var FLAG_SECURE_VALUE = "";
var mode = "";
@ -12,7 +12,7 @@ var requestBody = "";
var responseHeaders = "";
var responseBody = "";
const java_lang_threadObj = Java.use('java.lang.Thread').$new();
const java_lang_threadObj = Java.use("java.lang.Thread").$new();
function getStackTrace() {
const stack = java_lang_threadObj.currentThread().getStackTrace();
@ -33,8 +33,8 @@ function flatten(obj) {
}
const Packet = {
id: 'AG-EVENT',
payload: '',
id: "AG-EVENT",
payload: "",
toString() {
return JSON.stringify(flatten(this));
@ -84,26 +84,26 @@ function agBinderPacket(source, payload) {
}
function dumpIntent(intent) {
var cmp = ""
var cmp = "";
if (intent.getComponent()) {
cmp = intent.getComponent().getClassName()
cmp = intent.getComponent().getClassName();
}
return {action: intent.getAction(), cmp: cmp, flags: intent.getFlags()}
return { action: intent.getAction(), cmp: cmp, flags: intent.getFlags() };
}
function dumpReceiver(receiver) {
if (receiver != null) {
return { name: receiver.getClass().toString() }
return { name: receiver.getClass().toString() };
}
return {}
return {};
}
function dumpFilter(filter) {
if (filter != null) {
actions_list = []
categories_list = []
actions_list = [];
categories_list = [];
for (iAction = 0; iAction < filter.countActions(); iAction++) {
actions_list.push(filter.getAction(iAction));
@ -113,129 +113,150 @@ function dumpFilter(filter) {
categories_list.push(filter.getCategory(iCategory));
}
return {actions: actions_list, categories: categories_list}
return { actions: actions_list, categories: categories_list };
}
return {}
return {};
}
function dumpWebview(wv){
function dumpWebview(wv) {
return {
getAllowContentAccess: wv.getSettings().getAllowContentAccess(), getJavaScriptEnabled: wv.getSettings().getJavaScriptEnabled(), getAllowFileAccess: wv.getSettings().getAllowFileAccess(),
getAllowFileAccessFromFileURLs: wv.getSettings().getAllowFileAccessFromFileURLs(), getAllowUniversalAccessFromFileURLs: wv.getSettings().getAllowUniversalAccessFromFileURLs()
}
getAllowContentAccess: wv.getSettings().getAllowContentAccess(),
getJavaScriptEnabled: wv.getSettings().getJavaScriptEnabled(),
getAllowFileAccess: wv.getSettings().getAllowFileAccess(),
getAllowFileAccessFromFileURLs: wv
.getSettings()
.getAllowFileAccessFromFileURLs(),
getAllowUniversalAccessFromFileURLs: wv
.getSettings()
.getAllowUniversalAccessFromFileURLs(),
};
}
var Color = {
RESET: "\x1b[39;49;00m", Black: "0;01", Blue: "4;01", Cyan: "6;01", Gray: "7;11", Green: "2;01", Purple: "5;01", Red: "1;01", Yellow: "3;01",
RESET: "\x1b[39;49;00m",
Black: "0;01",
Blue: "4;01",
Cyan: "6;01",
Gray: "7;11",
Green: "2;01",
Purple: "5;01",
Red: "1;01",
Yellow: "3;01",
Light: {
Black: "0;11", Blue: "4;11", Cyan: "6;11", Gray: "7;01", Green: "2;11", Purple: "5;11", Red: "1;11", Yellow: "3;11"
}
Black: "0;11",
Blue: "4;11",
Cyan: "6;11",
Gray: "7;01",
Green: "2;11",
Purple: "5;11",
Red: "1;11",
Yellow: "3;11",
},
};
function enumerateModules(){
function enumerateModules() {
var modules = Process.enumerateModules();
colorLog('[+] Enumerating loaded modules:',{c: Color.Blue});
colorLog("[+] Enumerating loaded modules:", { c: Color.Blue });
for (var i = 0; i < modules.length; i++)
console.log(modules[i].path + modules[i].name);
}
function getApplicationContext() {
return Java.use('android.app.ActivityThread').currentApplication().getApplicationContext();
}
return Java.use("android.app.ActivityThread")
.currentApplication()
.getApplicationContext();
}
function traceClass(targetClass)
{
console.log("entering traceClass")
function traceClass(targetClass) {
colorLog("[+] entering traceClass", { c: Color.Red });
var hook = Java.use(targetClass);
var methods = hook.class.getDeclaredMethods();
hook.$dispose();
console.log("entering pasedMethods")
colorLog("[+] entering parsedMethods", { c: Color.Blue });
var parsedMethods = [];
methods.forEach(function(method) {
try{
parsedMethods.push(method.toString().replace(targetClass + ".", "TOKEN").match(/\sTOKEN(.*)\(/)[1]);
}
catch(err){}
methods.forEach(function (method) {
try {
parsedMethods.push(
method
.toString()
.replace(targetClass + ".", "TOKEN")
.match(/\sTOKEN(.*)\(/)[1],
);
} catch (err) {}
});
console.log("entering traceMethods")
colorLog("[+] entering traceMethods", { c: Color.Blue });
var targets = uniqBy(parsedMethods, JSON.stringify);
targets.forEach(function(targetMethod) {
try{
targets.forEach(function (targetMethod) {
try {
traceMethod(targetClass + "." + targetMethod);
}
catch(err){}
} catch (err) {}
});
}
function uniqBy(array, key)
{
function uniqBy(array, key) {
var seen = {};
return array.filter(function(item) {
return array.filter(function (item) {
var k = key(item);
return seen.hasOwnProperty(k) ? false : (seen[k] = true);
});
}
function traceMethod(targetClassMethod)
{
function traceMethod(targetClassMethod) {
var delim = targetClassMethod.lastIndexOf(".");
if (delim === -1) return;
var targetClass = targetClassMethod.slice(0, delim)
var targetMethod = targetClassMethod.slice(delim + 1, targetClassMethod.length)
var targetClass = targetClassMethod.slice(0, delim);
var targetMethod = targetClassMethod.slice(
delim + 1,
targetClassMethod.length,
);
var hook = Java.use(targetClass);
var overloadCount = hook[targetMethod].overloads.length;
colorLog("Tracing " + targetClassMethod + " [" + overloadCount + " overload(s)]",{c: Color.Green});
colorLog(
"Tracing " + targetClassMethod + " [" + overloadCount + " overload(s)]",
{ c: Color.Green },
);
for (var i = 0; i < overloadCount; i++) {
hook[targetMethod].overloads[i].implementation = function() {
colorLog("\n[+] Entering: " + targetClassMethod,{c: Color.Red});
hook[targetMethod].overloads[i].implementation = function () {
colorLog("\n[+] Entering: " + targetClassMethod, {
c: Color.Yellow,
});
if (arguments.length) console.log();
for (var j = 0; j < arguments.length; j++) {
console.log("\targ[" + j + "]: " + arguments[j]);
agPacket({ arg: arguments[j] }).send();
}
// print retval
var retval = this[targetMethod].apply(this, arguments); // rare crash (Frida bug?)
console.log("\n\tRetval: " + retval);
var retval = this[targetMethod].apply(this, arguments);
agPacket({ ret: retval }).send();
colorLog("\n[-] Exiting " + targetClassMethod);
return retval;
}
};
}
}
var Utf8 = {
encode : function (string) {
string = string.replace(/\r\n/g,"\n");
encode: function (string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
} else if (c > 127 && c < 2048) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
@ -244,58 +265,70 @@ var Utf8 = {
return utftext;
},
// publi
decode : function (utftext) {
decode: function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
var c = (c1 = c2 = 0);
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
} else if (c > 191 && c < 224) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(
((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63),
);
i += 3;
}
}
return string;
}
}
},
};
function describeJavaClass(className) {
var jClass = Java.use(className);
console.log(JSON.stringify({
console.log(
JSON.stringify(
{
_name: className,
_methods: Object.getOwnPropertyNames(jClass.__proto__).filter(function(m) {
return !m.startsWith('$') // filter out Frida related special properties
|| m == 'class' || m == 'constructor' // optional
_methods: Object.getOwnPropertyNames(jClass.__proto__).filter(
function (m) {
return (
!m.startsWith("$") || // filter out Frida related special properties
m == "class" ||
m == "constructor"
); // optional
},
),
_fields: jClass.class.getFields().map(function (f) {
return f.toString();
}),
_fields: jClass.class.getFields().map(function(f) {
return f.toString()
})
}, null, 2));
},
null,
2,
),
);
}
var colorLog = function (input, kwargs) {
kwargs = kwargs || {};
var logLevel = kwargs['l'] || 'log', colorPrefix = '\x1b[3', colorSuffix = 'm';
if (typeof input === 'object')
input = JSON.stringify(input, null, kwargs['i'] ? 2 : null);
if (kwargs['c'])
input = colorPrefix + kwargs['c'] + colorSuffix + input + Color.RESET;
var logLevel = kwargs["l"] || "log",
colorPrefix = "\x1b[3",
colorSuffix = "m";
if (typeof input === "object")
input = JSON.stringify(input, null, kwargs["i"] ? 2 : null);
if (kwargs["c"])
input = colorPrefix + kwargs["c"] + colorSuffix + input + Color.RESET;
console[logLevel](input);
};
var processArgs = function(command, envp, dir) {
var processArgs = function (command, envp, dir) {
var output = {};
if (command) {
console.log("Command: " + command);
@ -310,21 +343,24 @@ var processArgs = function(command, envp, dir) {
// output.dir = dir;
}
// return output;
};
var _byteArraytoHexString = function (byteArray) {
if (!byteArray) {
return "null";
}
var _byteArraytoHexString = function(byteArray) {
if (!byteArray) { return 'null'; }
if (byteArray.map) {
return byteArray.map(function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('');
return byteArray
.map(function (byte) {
return ("0" + (byte & 0xff).toString(16)).slice(-2);
})
.join("");
} else {
return byteArray + "";
}
}
};
var updateInput = function(input) {
var updateInput = function (input) {
if (input.length && input.length > 0) {
var normalized = byteArraytoHexString(input);
} else if (input.array) {
@ -333,43 +369,42 @@ var _byteArraytoHexString = function(byteArray) {
var normalized = input.toString();
}
return normalized;
}
};
var byteArraytoHexString = function(byteArray) {
var byteArraytoHexString = function (byteArray) {
if (byteArray && byteArray.map) {
return byteArray.map(function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
return byteArray
.map(function (byte) {
return ("0" + (byte & 0xff).toString(16)).slice(-2);
})
.join("");
} else {
return JSON.stringify(byteArray);
}
}
};
var hexToAscii = function(input) {
var hexToAscii = function (input) {
var hex = input.toString();
var str = '';
var str = "";
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
var displayString = function(input){
var str = input.replace('[','');
var str1 = str.replace(']','');
var res = str1.split(',');
var ret = '';
for(var i = 0; i<res.length; i++){
if(res[i] > 31 && res[i]<127)
ret += String.fromCharCode(res[i]);
else ret += ' ';
};
var displayString = function (input) {
var str = input.replace("[", "");
var str1 = str.replace("]", "");
var res = str1.split(",");
var ret = "";
for (var i = 0; i < res.length; i++) {
if (res[i] > 31 && res[i] < 127) ret += String.fromCharCode(res[i]);
else ret += " ";
}
colorLog("[+] PARSING TO STRING: " + ret,{c:Color.Green});
colorLog('',{c:Color.RESET});
}
var normalize = function(input) {
colorLog("[+] PARSING TO STRING: " + ret, { c: Color.Green });
colorLog("", { c: Color.RESET });
};
var normalize = function (input) {
if (input.length && input.length > 0) {
var normalized = byteArraytoHexString(input);
} else if (input.array) {
@ -378,9 +413,9 @@ var normalize = function(input) {
var normalized = input.toString();
}
return normalized;
}
};
var normalizeInput = function(input) {
var normalizeInput = function (input) {
if (input.array) {
var normalized = byteArraytoHexString(input.array());
} else if (input.length && input.length > 0) {
@ -389,88 +424,90 @@ var normalizeInput = function(input) {
var normalized = JSON.stringify(input);
}
return normalized;
}
};
var getMode = function(Cipher, mode) {
var getMode = function (Cipher, mode) {
if (mode === 2) {
mode = "DECRYPT";
} else if (mode === 1) {
mode = "ENCRYPT";
}
return mode;
}
};
var getRandomValue = function(arg) {
if (!arg) { return 'null'; }
var type = arg.toString().split('@')[0].split('.');
var getRandomValue = function (arg) {
if (!arg) {
return "null";
}
var type = arg.toString().split("@")[0].split(".");
type = type[type.length - 1];
if (type === "SecureRandom") {
if (arg.getSeed) {
return byteArraytoHexString(arg.getSeed(10));
}
}
}
};
var normalizeKey = function(cert_or_key) {
var type = cert_or_key.toString().split('@')[0].split('.');
var normalizeKey = function (cert_or_key) {
var type = cert_or_key.toString().split("@")[0].split(".");
type = type[type.length - 1];
if (type === "SecretKeySpec") {
return byteArraytoHexString(cert_or_key.getEncoded());
} else {
return "non-SecretKeySpec: " + cert_or_key.toString() + ", encoded: " + byteArraytoHexString(cert_or_key.getEncoded()) + ", object: " + JSON.stringify(cert_or_key);
return (
"non-SecretKeySpec: " +
cert_or_key.toString() +
", encoded: " +
byteArraytoHexString(cert_or_key.getEncoded()) +
", object: " +
JSON.stringify(cert_or_key)
);
}
}
var byteArrayToString = function(input) {
var buffer = Java.array('byte', input);
};
var byteArrayToString = function (input) {
var buffer = Java.array("byte", input);
var result = "";
for(var i = 0; i < buffer.length; i++) {
if(buffer[i] > 31 && buffer[i]<127) {
result += (String.fromCharCode(buffer[i]));
}
else {
result += ' ';
for (var i = 0; i < buffer.length; i++) {
if (buffer[i] > 31 && buffer[i] < 127) {
result += String.fromCharCode(buffer[i]);
} else {
result += " ";
}
}
return result;
}
};
var byteArrayToStringE = function(input){
var buffer = Java.array('byte', input);
var byteArrayToStringE = function (input) {
var buffer = Java.array("byte", input);
var result = "";
var unprintable = false;
for(var i = 0; i < buffer.length; ++i){
if(buffer[i] > 31 && buffer[i]<127)
result+= (String.fromCharCode(buffer[i]));
for (var i = 0; i < buffer.length; ++i) {
if (buffer[i] > 31 && buffer[i] < 127)
result += String.fromCharCode(buffer[i]);
else {
unprintable = true;
result = "Input cant be transformed to ascii string";
break;
}
}
return result;
}
};
function readStreamToHex (stream) {
function readStreamToHex(stream) {
var data = [];
var byteRead = stream.read();
while (byteRead != -1)
{
data.push( ('0' + (byteRead & 0xFF).toString(16)).slice(-2) );
while (byteRead != -1) {
data.push(("0" + (byteRead & 0xff).toString(16)).slice(-2));
/* <---------------- binary to hex ---------------> */
byteRead = stream.read();
}
stream.close();
return data.join('');
return data.join("");
}
const jni_struct_array = [
"reserved0",
"reserved1",
@ -704,35 +741,33 @@ const jni_struct_array = [
"NewDirectByteBuffer",
"GetDirectBufferAddress",
"GetDirectBufferCapacity",
"GetObjectRefType"
]
"GetObjectRefType",
];
/*
Calculate the given funcName address from the JNIEnv pointer
*/
function getJNIFunctionAdress(jnienv_addr,func_name){
var offset = jni_struct_array.indexOf(func_name) * Process.pointerSize
function getJNIFunctionAdress(jnienv_addr, func_name) {
var offset = jni_struct_array.indexOf(func_name) * Process.pointerSize;
// console.log("offset : 0x" + offset.toString(16))
return Memory.readPointer(jnienv_addr.add(offset))
return Memory.readPointer(jnienv_addr.add(offset));
}
// Hook all function to have an overview of the function called
function hook_all(jnienv_addr){
jni_struct_array.forEach(function(func_name){
function hook_all(jnienv_addr) {
jni_struct_array.forEach(function (func_name) {
// Calculating the address of the function
if(!func_name.includes("reserved"))
{
var func_addr = getJNIFunctionAdress(jnienv_addr,func_name)
Interceptor.attach(func_addr,{
onEnter: function(args){
console.log("[+] Entered : " + func_name)
if (!func_name.includes("reserved")) {
var func_addr = getJNIFunctionAdress(jnienv_addr, func_name);
Interceptor.attach(func_addr, {
onEnter: function (args) {
console.log("[+] Entered : " + func_name);
},
});
}
})
}
})
});
}
function inspectObject(obj) {
@ -742,15 +777,16 @@ function inspectObject(obj) {
const fields = obj_class.getDeclaredFields();
const methods = obj_class.getMethods();
console.log("Inspecting " + obj.getClass().toString());
console.log("[+]------------------------------Fields------------------------------:");
for (var i in fields)
console.log("\t\t" + fields[i].toString());
console.log("[+]------------------------------Methods-----------------------------:");
for (var i in methods)
console.log("\t\t" + methods[i].toString());
console.log(
"[+]------------------------------Fields------------------------------:",
);
for (var i in fields) console.log("\t\t" + fields[i].toString());
console.log(
"[+]------------------------------Methods-----------------------------:",
);
for (var i in methods) console.log("\t\t" + methods[i].toString());
}
//------------------------https://github.com/CreditTone/hooker----------------------------
function classExists(className) {
@ -758,45 +794,61 @@ function classExists(className) {
try {
var clz = Java.use(className);
exists = true;
} catch(err) {
} catch (err) {
//console.log(err);
}
return exists;
};
}
function methodInBeat(invokeId, timestamp, methodName, executor) {
var startTime = timestamp;
var startTime = timestamp;
var androidLogClz = Java.use("android.util.Log");
var exceptionClz = Java.use("java.lang.Exception");
var threadClz = Java.use("java.lang.Thread");
var currentThread = threadClz.currentThread();
var stackInfo = androidLogClz.getStackTraceString(exceptionClz.$new());
var str = ("------------startFlag:" + invokeId + ",objectHash:"+executor+",thread(id:" + currentThread.getId() +",name:" + currentThread.getName() + "),timestamp:" + startTime+"---------------\n");
var str =
"------------startFlag:" +
invokeId +
",objectHash:" +
executor +
",thread(id:" +
currentThread.getId() +
",name:" +
currentThread.getName() +
"),timestamp:" +
startTime +
"---------------\n";
str += methodName + "\n";
str += stackInfo.substring(20);
str += ("------------endFlag:" + invokeId + ",usedtime:" + (new Date().getTime() - startTime) +"---------------\n");
console.log(str);
};
str +=
"------------endFlag:" +
invokeId +
",usedtime:" +
(new Date().getTime() - startTime) +
"---------------\n";
console.log(str);
}
function log(str) {
console.log(str);
};
}
function tryGetClass(className) {
var clz = undefined;
try {
clz = Java.use(className);
} catch(e) {}
} catch (e) {}
return clz;
}
var containRegExps = new Array()
var containRegExps = new Array();
var notContainRegExps = new Array(RegExp(/\.jpg/), RegExp(/\.png/))
var notContainRegExps = new Array(RegExp(/\.jpg/), RegExp(/\.png/));
function check(str) {
str = str.toString();
if (! (str && str.match)) {
if (!(str && str.match)) {
return false;
}
for (var i = 0; i < containRegExps.length; i++) {
@ -813,22 +865,28 @@ function check(str) {
}
//------------------------https://github.com/CreditTone/hooker EOF----------------------------
function sendAppInfo(){
var context = null
var ActivityThread = Java.use('android.app.ActivityThread');
function sendAppInfo() {
var context = null;
var ActivityThread = Java.use("android.app.ActivityThread");
var app = ActivityThread.currentApplication();
if (app != null) {
context = app.getApplicationContext();
var app_classname = app.getClass().toString().split(' ')[1];
var app_classname = app.getClass().toString().split(" ")[1];
var filesDirectory= context.getFilesDir().getAbsolutePath().toString();
var cacheDirectory= context.getCacheDir().getAbsolutePath().toString();
var externalCacheDirectory= context.getExternalCacheDir().getAbsolutePath().toString();
var codeCacheDirectory= 'getCodeCacheDir' in context ? context.getCodeCacheDir().getAbsolutePath().toString() : 'N/A';
var obbDir= context.getObbDir().getAbsolutePath().toString();
var packageCodePath= context.getPackageCodePath().toString();
var applicationName= app_classname;
var filesDirectory = context.getFilesDir().getAbsolutePath().toString();
var cacheDirectory = context.getCacheDir().getAbsolutePath().toString();
var externalCacheDirectory = context
.getExternalCacheDir()
.getAbsolutePath()
.toString();
var codeCacheDirectory =
"getCodeCacheDir" in context
? context.getCodeCacheDir().getAbsolutePath().toString()
: "N/A";
var obbDir = context.getObbDir().getAbsolutePath().toString();
var packageCodePath = context.getPackageCodePath().toString();
var applicationName = app_classname;
var info = {};
info.applicationName = applicationName;
@ -839,26 +897,27 @@ function sendAppInfo(){
info.obbDir = obbDir;
info.packageCodePath = packageCodePath;
agSysPacket({information: "app", info: info}).send();
agSysPacket({ information: "app", info: info }).send();
} else {
console.log("No context yet!")
console.log("No context yet!");
}
}
//------------------------https://github.com/CreditTone/hooker EOF----------------------------
function notifyNewSharedPreference(key, value) {
var k = key;
var v = value;
Java.use('android.app.SharedPreferencesImpl$EditorImpl').putString.overload('java.lang.String', 'java.lang.String').implementation = function(k, v) {
console.log('[SharedPreferencesImpl]', k, '=', v);
Java.use("android.app.SharedPreferencesImpl$EditorImpl").putString.overload(
"java.lang.String",
"java.lang.String",
).implementation = function (k, v) {
console.log("[SharedPreferencesImpl]", k, "=", v);
return this.putString(k, v);
}
};
}
// Send some stuff about the app
setTimeout(function() {
setTimeout(function () {
sendAppInfo();
}, 1000);

View File

@ -1,86 +1,142 @@
// Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets
colorLog('[+] LOADING ENCRYPTION/CIPHER.JS', {c: Color.Red});
colorLog("[+] LOADING ENCRYPTION/CIPHER.JS", { c: Color.Red });
var cipher = Java.use('javax.crypto.Cipher');
var cipher = Java.use("javax.crypto.Cipher");
cipher.init.overload('int', 'java.security.Key').implementation = function(mode, key) {
var operation = '';
cipher.init.overload("int", "java.security.Key").implementation = function (
mode,
key,
) {
var operation = "";
var algorithm = this.getAlgorithm();
if(mode == 1)
operation = "Encrypting";
else if(mode == 2)
operation = "Decrypting";
if (mode == 1) operation = "Encrypting";
else if (mode == 2) operation = "Decrypting";
agPacket({algorithm: algorithm, operation: operation, mode: mode, key: byteArraytoHexString(key.getEncoded())}).send();
agPacket({
algorithm: algorithm,
operation: operation,
mode: mode,
key: byteArraytoHexString(key.getEncoded()),
}).send();
return this.init(mode, key);
}
};
cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function(mode, key, paramsec) {
var operation = '';
cipher.init.overload(
"int",
"java.security.Key",
"java.security.spec.AlgorithmParameterSpec",
).implementation = function (mode, key, paramsec) {
var operation = "";
var algorithm = this.getAlgorithm();
var castedToIv = Java.cast(paramsec, Java.use('javax.crypto.spec.IvParameterSpec'));
if(mode == 1)
operation = "Encrypting";
else if(mode == 2)
operation = "Decrypting";
if (mode == 1) operation = "Encrypting";
else if (mode == 2) operation = "Decrypting";
agPacket({
algorithm: algorithm,
mode: mode,
operation: operation,
key: byteArraytoHexString(key.getEncoded()),
iv: paramsec,
}).send();
agPacket({algorithm: algorithm, mode: mode, operation: operation, key: byteArraytoHexString(key.getEncoded()), iv: byteArraytoHexString(castedToIv.getIV())}).send();
return this.init(mode, key, paramsec);
}
};
cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function(mode, key, paramsec, secRnd){
var operation = '';
cipher.init.overload(
"int",
"java.security.Key",
"java.security.AlgorithmParameters",
"java.security.SecureRandom",
).implementation = function (mode, key, paramsec, secRnd) {
var operation = "";
var algorithm = this.getAlgorithm();
var castedToIv = Java.cast(paramsec, Java.use('javax.crypto.spec.IvParameterSpec'));
if(mode == 1)
operation = "Encrypting";
else if(mode == 2)
operation = "Decrypting";
if (mode == 1) operation = "Encrypting";
else if (mode == 2) operation = "Decrypting";
agPacket({algorithm: algorithm, mode: mode, operation: operation, key: byteArraytoHexString(key.getEncoded()), iv: byteArraytoHexString(castedToIv.getIV())}).send();
agPacket({
algorithm: algorithm,
mode: mode,
operation: operation,
key: byteArraytoHexString(key.getEncoded()),
iv: paramsec,
secRnd: secRnd,
}).send();
return this.init(mode, key, paramsec, secRnd);
}
};
//DO FINAL--------------------------------
cipher.doFinal.overload('[B').implementation = function(byteArray) {
cipher.doFinal.overload("[B").implementation = function (byteArray) {
var ret = this.doFinal(byteArray);
agPacket({in: byteArray, ret: ret}).send();
agPacket({
in: byteArraytoHexString(byteArray),
ret: byteArraytoHexString(ret),
}).send();
return ret;
}
};
cipher.doFinal.overload('[B', 'int').implementation = function(byteArray, outputOffset) {
cipher.doFinal.overload("[B", "int").implementation = function (
byteArray,
outputOffset,
) {
var ret = this.doFinal(byteArray, outputOffset);
agPacket({in: byteArray, outputOffset: outputOffset, ret: ret}).send();
agPacket({ in: byteArray, outputOffset: outputOffset, ret: ret }).send();
return ret;
}
};
cipher.doFinal.overload('[B', 'int', 'int').implementation = function(byteArray, outputOffset, inputlen) {
cipher.doFinal.overload("[B", "int", "int").implementation = function (
byteArray,
outputOffset,
inputlen,
) {
var ret = this.doFinal(byteArray, outputOffset, inputlen);
agPacket({in: byteArray, outputOffset: outputOffset, inputlen: inputlen, ret: ret}).send();
agPacket({
in: byteArray,
outputOffset: outputOffset,
inputlen: inputlen,
ret: ret,
}).send();
return ret;
}
};
cipher.doFinal.overload('[B', 'int', 'int', '[B').implementation = function(byteArray, outputOffset, inputlen, output) {
cipher.doFinal.overload("[B", "int", "int", "[B").implementation = function (
byteArray,
outputOffset,
inputlen,
output,
) {
var ret = this.doFinal(byteArray, outputOffset, inputlen, output);
agPacket({in: byteArray, out: output, outputOffset: outputOffset, inputlen: inputlen, ret: ret}).send();
agPacket({
in: byteArray,
out: output,
outputOffset: outputOffset,
inputlen: inputlen,
ret: ret,
}).send();
return ret;
}
};
cipher.doFinal.overload('[B', 'int', 'int', '[B', 'int').implementation = function(byteArray, outputOffset, inputlen, output, outoffset) {
var ret = this.doFinal(byteArray, outputOffset ,inputlen, output, outoffset);
agPacket({in: byteArray, out: output, outputOffset: outputOffset, inputlen: inputlen, outoffset: outoffset, ret: ret}).send();
cipher.doFinal.overload("[B", "int", "int", "[B", "int").implementation =
function (byteArray, outputOffset, inputlen, output, outoffset) {
var ret = this.doFinal(
byteArray,
outputOffset,
inputlen,
output,
outoffset,
);
agPacket({
in: byteArray,
out: output,
outputOffset: outputOffset,
inputlen: inputlen,
outoffset: outoffset,
ret: ret,
}).send();
return ret;
}
};

View File

@ -0,0 +1,57 @@
// Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets
colorLog("[+] LOADING ENCRYPTION/KEYSTORE.JS", { c: Color.Red });
var keystore = Java.use("java.security.KeyStore");
keystore.containsAlias.overload("java.lang.String").implementation = function (
alias,
) {
var ret = this.containsAlias(alias);
agPacket({
alias: alias,
ret: ret,
}).send();
return ret;
};
keystore.getKey.overload("java.lang.String", "[C").implementation = function (
alias,
password,
) {
var ret = this.getKey(alias, password);
agPacket({
alias: alias,
password: password,
algorithm: ret.getAlgorithm(),
encoded: ret.getEncoded(),
ret: ret,
}).send();
return ret;
};
keystore.load.overload("java.io.InputStream", "[C").implementation = function (
stream,
charArray,
) {
/* sometimes this happen, I have no idea why, tho... */
if (stream == null) {
/* just to avoid interfering with app's flow */
this.load(stream, charArray);
return;
}
var hexString = readStreamToHex(stream);
agPacket({
certType: this.getType(),
password: charArray,
cert: hexString,
}).send();
/* call the original implementation of 'load' */
this.load(stream, charArray);
/* no need to return anything */
};

View File

@ -0,0 +1,14 @@
// Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets
colorLog("[+] LOADING PREFERENCES/PREFERENCES.JS", { c: Color.Red });
var ContextWrapper = Java.use("android.content.ContextWrapper");
ContextWrapper.getSharedPreferences.overload(
"java.lang.String",
"int",
).implementation = function (var0, var1) {
var sharedPreferences = this.getSharedPreferences(var0, var1);
agPacket({ name: var0, mode: var1, ret: sharedPreferences }).send();
return sharedPreferences;
};