mirror of
https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
synced 2026-10-12 02:06:59 +00:00
Dynamic Analysis with Genymotion. Supports Android 4.1 -9.0 Static Analyzer Threaded baksmali Improved Recent Scan Browser PDF Generation Dynamic Analyzer Restructuring Dynamic Analyzer Code QA and Modularization Automatic MobSFy with Xposed and Frida Full pass on all versions of android with basic features Streaming logcat Live API Monitor Better SQlite DB View In line frida scripting + loading from frida code share basic frida env, ssl unpin, root check, debugger detection bypass. Custom Frida Scripts and integration Frida Log Viewer Frida scripts loader Frida custom user script loader
126 lines
4.4 KiB
JavaScript
126 lines
4.4 KiB
JavaScript
// https://github.com/iddoeldor/frida-snippets#trace-class
|
|
/**
|
|
*
|
|
* @param input.
|
|
* If an object is passed it will print as json
|
|
* @param kwargs options map {
|
|
* -l level: string; log/warn/error
|
|
* -i indent: boolean; print JSON prettify
|
|
* -c color: @see ColorMap
|
|
* }
|
|
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",
|
|
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"
|
|
}
|
|
};
|
|
|
|
var LOG = 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;
|
|
console[logLevel](input);
|
|
};
|
|
|
|
var printBacktrace = function () {
|
|
Java.perform(function() {
|
|
var android_util_Log = Java.use('android.util.Log'), java_lang_Exception = Java.use('java.lang.Exception');
|
|
// getting stacktrace by throwing an exception
|
|
LOG(android_util_Log.getStackTraceString(java_lang_Exception.$new()), { c: Color.Gray });
|
|
});
|
|
};
|
|
|
|
*/
|
|
|
|
function traceClass(targetClass) {
|
|
var hook;
|
|
try {
|
|
hook = Java.use(targetClass);
|
|
send('[AUXILIARY] [Class Trace] Tracing all methods implementations of : '+ targetClass)
|
|
} catch (e) {
|
|
send('[AUXILIARY] [Class Trace] Error - ' + e);
|
|
return;
|
|
}
|
|
|
|
var methods = hook.class.getDeclaredMethods();
|
|
hook.$dispose();
|
|
|
|
var parsedMethods = [];
|
|
methods.forEach(function (method) {
|
|
var methodStr = method.toString();
|
|
var methodReplace = methodStr.replace(targetClass + ".", "TOKEN").match(/\sTOKEN(.*)\(/)[1];
|
|
parsedMethods.push(methodReplace);
|
|
});
|
|
|
|
uniqBy(parsedMethods, JSON.stringify).forEach(function (targetMethod) {
|
|
traceMethod(targetClass + '.' + targetMethod);
|
|
});
|
|
}
|
|
|
|
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 hook = Java.use(targetClass);
|
|
var overloadCount = hook[targetMethod].overloads.length;
|
|
|
|
// LOG({ tracing: targetClassMethod, overloaded: overloadCount }, { c: Color.Green });
|
|
for (var i = 0; i < overloadCount; i++) {
|
|
hook[targetMethod].overloads[i].implementation = function () {
|
|
var log = { 'Class Trace': targetClassMethod, args: [] };
|
|
|
|
for (var j = 0; j < arguments.length; j++) {
|
|
var arg = arguments[j];
|
|
// quick&dirty fix for java.io.StringWriter char[].toString() impl because frida prints [object Object]
|
|
if (j === 0 && arguments[j]) {
|
|
if (arguments[j].toString() === '[object Object]') {
|
|
var s = [];
|
|
for (var k = 0, l = arguments[j].length; k < l; k++) {
|
|
s.push(arguments[j][k]);
|
|
}
|
|
arg = s.join('');
|
|
}
|
|
}
|
|
log.args.push({ i: j, o: arg, s: arg ? arg.toString(): 'null'});
|
|
}
|
|
|
|
var retval;
|
|
try {
|
|
retval = this[targetMethod].apply(this, arguments); // might crash (Frida bug?)
|
|
log.returns = { val: retval, str: retval ? retval.toString() : null };
|
|
} catch (e) {
|
|
send('[AUXILIARY] [Class Trace] Error - ' + e)
|
|
}
|
|
//LOG(log, { c: Color.Blue });
|
|
send(log)
|
|
return retval;
|
|
}
|
|
}
|
|
}
|
|
|
|
// remove duplicates from array
|
|
function uniqBy(array, key) {
|
|
var seen = {};
|
|
return array.filter(function (item) {
|
|
var k = key(item);
|
|
return seen.hasOwnProperty(k) ? false : (seen[k] = true);
|
|
});
|
|
}
|
|
|
|
|
|
Java.perform(function () { // avoid java.lang.ClassNotFoundException
|
|
{{CLASSES}}.forEach(traceClass);
|
|
|
|
/* Java.use('java.net.Socket').isConnected.overload().implementation = function () {
|
|
LOG('Socket.isConnected.overload', { c: Color.Light.Cyan });
|
|
printBacktrace();
|
|
return true;
|
|
} */
|
|
}); |