Loading...
Loading...
Generate Frida hook scripts using modern Frida API. Activate when the user wants to write Frida scripts, hook functions at runtime, trace calls/arguments/return values, intercept native or ObjC/Java methods, or dump memory and exports.
npx skill4agent add p4nda0s/reverse-skills rev-frida--no-pause# Spawn and hook (process starts after script loads)
frida -U -f com.example.app -l hook.js
# Attach to running process
frida -U com.example.app -l hook.js
# Attach by PID
frida -U -p 1234 -l hook.js// Get a loaded module by name
var mod = Process.getModuleByName("libssl.so");
// Module properties
mod.name // "libssl.so"
mod.base // NativePointer - base address
mod.size // module size in bytes
mod.path // full filesystem path
// Get export address directly
var ptr = mod.getExportByName("SSL_read");
// Enumerate all loaded modules
Process.enumerateModules()
// Returns: [{ name, base, size, path }, ...]
// Enumerate exports of a module
mod.enumerateExports()
// Returns: [{ type, name, address }, ...]
// Enumerate imports of a module
mod.enumerateImports()
// Returns: [{ type, name, module, address }, ...]
// Find export across all modules
var addr = Module.getExportByName(null, "open");Interceptor.attach(ptr, {
onEnter(args) {
// args[0], args[1], ... are NativePointer
console.log("arg0:", args[0].toInt32());
console.log("arg1 str:", args[1].readUtf8String());
},
onLeave(retval) {
console.log("ret:", retval.toInt32());
// retval.replace(ptr(0x1)); // modify return value
}
});
// Replace function implementation entirely
Interceptor.replace(ptr, new NativeCallback(function (a0, a1) {
console.log("replaced!");
return 0;
}, 'int', ['pointer', 'int']));// Call a native function from JS
var open = new NativeFunction(
Module.getExportByName(null, "open"),
'int', ['pointer', 'int']
);
var fd = open(Memory.allocUtf8String("/etc/hosts"), 0);
// Create a callback for native code to call
var cb = new NativeCallback(function (arg) {
console.log("called with:", arg);
return 0;
}, 'int', ['int']);// Read
ptr(addr).readByteArray(size) // ArrayBuffer
ptr(addr).readUtf8String() // string
ptr(addr).readU32() // number
ptr(addr).readPointer() // NativePointer
// Write
ptr(addr).writeByteArray(bytes)
ptr(addr).writeUtf8String("hello")
ptr(addr).writeU32(0x41414141)
// Allocate
var buf = Memory.alloc(256);
var str = Memory.allocUtf8String("hello");
// Scan memory for pattern
Memory.scan(mod.base, mod.size, "48 89 5C 24 ?? 48 89 6C", {
onMatch(address, size) {
console.log("found at:", address);
},
onComplete() {}
});if (ObjC.available) {
var NSString = ObjC.classes.NSString;
// Hook ObjC method
var hook = ObjC.classes.ClassName["- methodName:"];
Interceptor.attach(hook.implementation, {
onEnter(args) {
// args[0] = self, args[1] = _cmd, args[2] = first param
var self = new ObjC.Object(args[0]);
var param = new ObjC.Object(args[2]);
console.log("self:", self.toString());
console.log("param:", param.toString());
}
});
// Enumerate classes
Object.keys(ObjC.classes).filter(c => c.includes("KeyChain"));
}if (Java.available) {
Java.perform(function () {
var Activity = Java.use("android.app.Activity");
Activity.onCreate.implementation = function (bundle) {
console.log("onCreate called");
this.onCreate(bundle);
};
// Enumerate loaded classes
Java.enumerateLoadedClasses({
onMatch(name) {
if (name.includes("crypto")) console.log(name);
},
onComplete() {}
});
});
}Process.getModuleByName()mod.getExportByName()Module.findBaseAddress()--no-pausefunction hookWhenReady(moduleName, exportName, callbacks) {
var mod = Process.findModuleByName(moduleName);
if (mod) {
Interceptor.attach(mod.getExportByName(exportName), callbacks);
} else {
var interval = setInterval(function () {
mod = Process.findModuleByName(moduleName);
if (mod) {
clearInterval(interval);
Interceptor.attach(mod.getExportByName(exportName), callbacks);
}
}, 100);
}
}ptr.toString(16)hexdump(ptr, { length: 64 })hexdump()console.log(hexdump(args[0], { offset: 0, length: 64, header: true, ansi: false }));