___ ____
/ __\ / _ | _ _ _ _ _ _
/ _\ | (_) | / _ \ / _ \ | / / | | | |
/ / / / | | | (_) | (_) || < | |_| |
\/ /_/ |_| \___/ \___/ |_|\_\ \__, |
|___/frooky is a Frida-based dynamic analysis tool for Android and iOS apps based on YAML hook files.
- Hook Java/Kotlin methods and native C/C++ functions
- Simple YAML hook file format
- Support for method overloads and stack trace capture
- Argument capture with various data types
- Return value capture with various data types
- Filter hooks by argument values or stack trace patterns
- Output events in JSON Lines format for easy processing
Use it, if you know what you want to hook but you don't want to write custom Frida scripts or copy and paste them together. For example you can use it to quickly hook functions or methods based on public API documentation and quickly get insight about them.
Note
This documentation describes the intended feature set for frooky 1.0. At the time of writing this document, not all described features may have been fully implemented and there may be breaking changes to the hook file API until the release of frooky 1.0.
Feedback is always welcome.
Simply install via pip to get the frooky CLI tool:
pip3 install frookyCreate a hook file (e.g., hooks.yaml) with the functions and/or methods you want to hook.
If you are already familiar with Frida and function hooking, we recommend using the documented examples as a quick starting point. You find them in the folder docs/examples/.
For more information, read all about the structure in chapter Structure of a Hook File.
After you created the desired hook file, run frooky:
# Attach by app name
frooky android -U -n org.owasp.mastestapp hooks.yaml
# Spawn and add multiple hook files (hooks are merged)
frooky android -U -f org.owasp.mastestapp storage.yaml crypto.yaml
# Spawn and add multiple hook files using globs (hooks are merged)
frooky android -U -f org.owasp.mastestapp hooks_*.yamlSee frooky -h for more options.
frooky uses hook files, which are structured YAML files including declarations of methods or functions to be hooked.
A hook file consists of optional metadata and a list of hook declarations. The following YAML file describes the basic structure:
metadata: # All metadata is optional
name: <name> # Name of the hook collection
platform: Android|iOS # Target platform (hooks must be platform-specific)
description: <description> # Description of what the hook collection does
category: <category> # Category of the hook collection
author: <author> # Your name or organization
version: <version> # Semantic version (e.g., v1)
hooks: # Collection of hook declarations
- <hook_declaration>Example:
The following hook file hooks all RNG initialization methods and functions on an Android device, capturing their arguments, return values, and stack trace. This information can be used to detect insecure RNG.
metadata:
name: RNG initialization
platform: Android
description: Hooks all RNG initialization methods on Android (Java, kotlin, native)
masCategory: CRYPTOGRAPHY
author: frooky dev team
version: v1
hooks:
- <hook_declaration> Depending on the platform, the <hook_declaration> may look different. Please read the linked platform-specific documentation for more information.
frooky supports these types of hooks:
| Hook Type | Platform | Description | Documentation |
|---|---|---|---|
JavaHook |
Android | Hook for Java/Kotlin methods | JavaHook-Declaration |
ObjcHook |
iOS | Hook for Objective-C methods | ObjcHook-Declaration |
NativeHook |
Android/iOS | Hook for native functions (C/C++/Rust etc.) | NativeHook-Declaration |
Important
When loading a hook declaration, frooky will validate it and to detect invalid declarations. For example, it is not possible to declare a JavaHook and a ObjcHook hook in one hook file.
frooky can decode data passed to functions or methods via arguments, including their return values.
Depending on the value types, this can be simple or more complex. frooky tries to decode arguments and return values by itself if possible. But in some cases, e.g. when the value is simply a pointer, it is necessary to provide information about the types used. Before writing a hook declaration, it is therefore recommended to read the following documentation:
We'll use the OWASP MAS MASTG-DEMO-0072 app to demonstrate hooking a cryptographic key generation method.
First you need to create a hook file, e.g., keygen.yaml:
metadata:
name: Android Key Generator Specifications
platform: Android
description: Captures the initialization of a KeyGenParameterSpec Builder
category: CRYPTO
author: frooky dev team
version: v1
hooks:
- javaClass: android.security.keystore.KeyGenParameterSpec$Builder
methods:
- $initThen run frooky with the hook file against your target app:
frooky android -U -n org.owasp.mastestapp keygen.yamlEvents are written to the output file in JSON Lines format (one JSON object per line, known as NDJSON).
Example Output (pretty-printed for readability):
{
"id": "14535033-08ea-4063-897c-eacd4a885d8b",
"type": "hook",
"category": "CRYPTO",
"time": "2026-01-14T16:02:21.782Z",
"class": "android.security.keystore.KeyGenParameterSpec$Builder",
"method": "$init",
"instanceId": 35486102,
"stackTrace": [
"android.security.keystore.KeyGenParameterSpec$Builder.<init>(Native Method)",
"org.owasp.mastestapp.MastgTest.generateKey(MastgTest.kt:97)",
"org.owasp.mastestapp.MastgTest.mastgTest(MastgTest.kt:41)",
"org.owasp.mastestapp.MainActivityKt.MainScreen$lambda$12$lambda$11(MainActivity.kt:101)",
"org.owasp.mastestapp.MainActivityKt.$r8$lambda$Pm6AsbKBmypP53K-UABM21E_Xxk(Unknown Source:0)",
"org.owasp.mastestapp.MainActivityKt$$ExternalSyntheticLambda3.run(D8$$SyntheticClass:0)",
"java.lang.Thread.run(Thread.java:1012)"
],
"inputParameters": [
{
"declaredType": "java.lang.String",
"value": "MultiPurposeKey"
},
{
"declaredType": "int",
"value": 15
}
],
"returnValue": [
{
"declaredType": "void",
"value": "void"
}
]
}Please refer to the following documentation for more information about various topics: