DynamicHooks
5 views
0d987241...
Description
[Android] Dynamic Hooks (Creating Function Hooks Was Never Easier)
How to Use
Download the script and run it with Frida CLI:
Download ScriptThen run with Frida:
frida -U -f YOUR_PACKAGE_NAME -l dynamichooks.js
Replace YOUR_PACKAGE_NAME with the target app's package name.
Source Code
JavaScript
// https://github.com/realgam3/ReversingAutomation/edit/master/Frida/Android-DynamicHooks/DynamicHooks.js
// runtime-engine: v8
// version: 2
const LogLevel = {
None: 0,
Informational: 1,
Debug: 2
}
function hook(func, options) {
let klass, funk;
let Exception = Java.use("java.lang.Exception");
function getClassAndFunction(classFuncName) {
let klass = classFuncName.split(".");
let funk = klass.pop();
klass = klass.join(".");
return [klass, funk]
}
function defaultFunction(funcArgs, context, originalResult) {
return originalResult;
}
options = options || {
logLevel: LogLevel.None,
callOriginal: true,
stackTrace: false,
callback: defaultFunction,
stringifyArguments: {},
stringifyResult: null,
};
let logLevel = options.logLevel || LogLevel.None;
let stackTrace = options.stackTrace || false;
let callOriginal = options.callOriginal || true;
let stringifyArguments = options.stringifyArguments || {};
let stringifyResult = options.stringifyResult || null;
let args = options.arguments || [];
let callback = options.callback || defaultFunction;
try {
[klass, funk] = getClassAndFunction(func);
} catch (error) {
func += ".$init";
[klass, funk] = getClassAndFunction(func);
}
try {
let functionSignature = Java.use(klass)[funk];
functionSignature.overload.apply(functionSignature, args).implementation = function () {
let context = this;
let funcArgs = [].slice.call(arguments);
let result = null, originalResult = null;
let toStringArguments = [];
for (let i = 0; i < funcArgs.length; i++) {
let argType = args[i];
let toStringFunc = stringifyArguments[argType];
toStringArguments.push(toStringFunc ? toStringFunc(funcArgs[i]) : funcArgs[i]);
}
let message = {
stage: "calling",
function: func,
argumentTypes: args,
arguments: toStringArguments,
};
if (stackTrace) {
message.stackTrace = Exception.$new().getStackTrace().toString().split(",").slice(1);
}
if (logLevel >= LogLevel.Debug) {
console.log(JSON.stringify(message));
}
if (callOriginal) {
originalResult = functionSignature.overload.apply(functionSignature, args).apply(context, funcArgs);
}
result = callback(funcArgs, context, originalResult);
message.stage = "return"
if (callOriginal && callback !== defaultFunction) {
message.originalResult = stringifyResult ? stringifyResult(originalResult, context) : originalResult;
}
message.result = stringifyResult ? stringifyResult(result, context) : result;
if (logLevel >= LogLevel.Informational) {
console.log(JSON.stringify(message));
}
return result;
};
} catch (error) {
if (logLevel >= LogLevel.Informational) {
console.error(JSON.stringify({
stage: "error",
function: func,
argumentTypes: args,
error: error.toString(),
}));
}
}
}
Java.perform(function () {
hook("java.security.MessageDigest.update", {
logLevel: 1,
arguments: ["[B"],
stringifyArguments: {
"[B": function (arg) {
let byteArray = Java.array("byte", arg);
return Array.from(byteArray).map(byte => (byte & 0xFF).toString(16).padStart(2, "0")).join("");
}
},
stackTrace: true,
callOriginal: true,
});
});
Comments