Skip to main content

JNITrace EX

An updated JNITrace that works with the latest Frida (16.x and 17.x).

JNITrace EX is a maintained fork of chame1eon/jnitrace, modernized to run on current Frida and Python versions. It traces use of the JNI API in Android apps—similar to frida-trace or strace, but for the JNI.


Why JNITrace EX?

The original jnitrace targeted older Frida (e.g. 14.x) and Python 2/3.4–3.7. This version was created so you can use JNI tracing with:

  • Frida 16 and 17 – Updated Python API usage and a patch for jnitrace-engine so Module.findExportByName(null, …) is replaced with Module.findGlobalExportByName(…) (Frida 17 breaking change).
  • Python 3.7+ – Version and script loading use importlib_metadata / importlib_resources (with fallbacks) instead of deprecated pkg_resources.
  • Stable terminal output – Unbuffered stdout and flushes so trace output appears in the terminal without needing adb logcat.
  • Easy run-from-source – ./scripts/jnitrace.sh runs jnitrace from the repo using the project’s venv and PYTHONPATH, so you don’t depend on a global pip install jnitrace.

Repository: https://github.com/L0WK3Y-IAAN/jnitrace-ex


Installation

From PyPI:

pip install jnitrace-ex

After install, run the CLI with jnitrace (same as before).

From source:

Use a Python that has Frida installed (e.g. 3.12). Create a venv with a stable Python path, then install:

cd /path/to/jnitrace-ex
/path/to/python3 -m venv .venv   # e.g. /Library/Frameworks/Python.framework/Versions/3.12/bin/python3
.venv/bin/pip install -e .
.venv/bin/pip install -r requirements.txt

Run without installing the CLI (script uses repo + venv):

./scripts/jnitrace.sh -l libnative-lib.so -b none com.example.myapplication

Troubleshooting:

  • bad interpreter: ... python3.14: no such file or directory – Recreate the venv with a Python that stays in the same place, or run: .venv/bin/python3 -m jnitrace.jnitrace ...
  • ModuleNotFoundError: No module named 'frida' – Install Frida for that interpreter: pip install frida, or use the same Python as frida-tools.
  • ModuleNotFoundError: No module named 'jnitrace' – From repo root run .venv/bin/pip install -e ., or use ./scripts/jnitrace.sh (no install needed).
  • TypeError: not a function in jnitrace-engine – Try running from source so the Frida script is built with your environment: clone the repo, then ./scripts/jnitrace.sh -l lib.so -b none com.example.app. If that works, reinstall from PyPI (pip install --force-reinstall jnitrace-ex) to get a fresh build, or use the run-from-source method.

Dependencies:

  • Android device (arm, arm64, x86, or x64) with frida-server (16.x or 17.x)
  • Host: Python 3.7+, Frida 16+, colorama, hexdump, importlib_resources

Running

Start frida-server on the device, then:

# Spawn app and trace (recommended)
./scripts/jnitrace.sh -l libnative-lib.so -b none com.example.myapplication

# Or after pip install
jnitrace -l libnative-lib.so com.example.myapplication

Required:

  • -l libnative-lib.so – Library to trace. Use multiple -l for several libs, or -l * for all.
  • com.example.myapplication – Package name (must be installed on the device).

Useful options:

  • -b none – Disable backtrace (reduces overhead; often needed so the app doesn’t crash under tracing).
  • -m attach – Attach to an already running process by name (e.g. -m attach "AppName").
  • -R [host:port] – Remote Frida server (default 127.0.0.1:27042).
  • -i <regex> – Include only JNI methods matching the regex (e.g. -i "NewStringUTF|CallIntMethod").
  • -e <regex> – Exclude JNI methods matching the regex.
  • -o path/output.json – Save trace to JSON.
  • -p path/to/script.js – Load a Frida script before jnitrace (e.g. anti-Frida bypass).
  • -a path/to/script.js – Load a Frida script after jnitrace.
  • --hide-data – Hide hexdumps and extra data.
  • --ignore-env / --ignore-vm – Skip JNIEnv or JavaVM calls.

Start frida-server:

adb shell /data/local/tmp/frida-server

Optional arguments (reference)

Option Description
-b <fuzzy|accurate|none> Backtrace mode. Default accurate; use none to avoid crashes on some apps.
-i <regex> Include only JNI methods whose names match (can be used multiple times).
-e <regex> Exclude JNI methods whose names match.
-I <string> Include only these library exports (e.g. Java_... or RegisterNatives methods).
-E <string> Exclude these library exports.
--aux name=(string|bool|int)value Aux options when spawning (e.g. --aux='uid=(int)10').

Building from source

Build the Frida script (needed for run-from-source or custom changes):

npm install
npm run build

npm run watch compiles on change. The built script is jnitrace/build/jnitrace.js. A patch is applied to jnitrace-engine (via patch-package) for Frida 17 compatibility.


Output

Output is colored by thread. Each JNI call shows:

  • Thread ID
  • Timestamp (ms)
  • Method name (e.g. JNIEnv->NewStringUTF)
  • Arguments (|-) and return value (|=)
  • Optional backtrace when -b is not none

String arguments and return values (e.g. from NewStringUTF) are shown in braces. With -b none, trace is lighter and less likely to destabilize the app.


API (jnitrace-engine)

The engine is available as a separate npm package for custom Frida scripts:

import { JNIInterceptor } from "jnitrace-engine";

JNIInterceptor.attach("FindClass", {
    onEnter(args) {
        console.log("FindClass method called");
        this.className = Memory.readCString(args[1]);
    },
    onLeave(retval) {
        console.log("\tLoading Class:", this.className);
        console.log("\tClass ID:", retval.get());
    }
});

More: jnitrace-engine


How it works (summary)

jnitrace injects a Frida script that hooks library loading (dlopen/dlsym). For libraries you choose with -l, it builds a shadow JNIEnv and replaces the real one so only those libs’ JNI calls go through trampolines. Arguments and return values are captured and sent to the Python host, which formats and prints them. Variadic JNI calls are handled by tracking GetMethodID/GetStaticMethodID and building method signatures so the correct NativeCallbacks can be created per call.


Issues

For bugs or questions about JNITrace EX, open an issue at:

https://github.com/L0WK3Y-IAAN/jnitrace-ex/issues

Please include:

  • Device and Android version
  • Frida version (host and frida-server)
  • Target app (package name)
  • Exact command and any error output

For the original jnitrace or the engine, see chame1eon/jnitrace and chame1eon/jnitrace-engine.

Metadata

Release files for jnitrace-ex 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jnitrace-ex 1.0.1
File Size Uploaded
jnitrace_ex-1.0.1.tar.gz 33.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jnitrace-ex 1.0.1
File Interpreter ABI Platform
jnitrace_ex-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 63.7 kB

Release files / jnitrace_ex-1.0.1.tar.gz

Download URL jnitrace_ex-1.0.1.tar.gz
Size 33.2 kB
Tags Source
SHA-256 checksum
How to use checksums
efc5449db1927ea27761bb2f305930ea8d01be1b7b13bba7c34e31d6e2a59601
BLAKE2b-256 checksum
How to use checksums
5e590d85d546207584f0622d626546c8bbd79134fcf76b1cd38b564b06868611
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 22, 2026.

Transparency log

Release files / jnitrace_ex-1.0.1-py3-none-any.whl

Download URL jnitrace_ex-1.0.1-py3-none-any.whl
Size 30.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5fba3ced9e082d0908605187b8f0d44a48e1268c710cd1042bf0aa61c54ea4a3
BLAKE2b-256 checksum
How to use checksums
e60bce7edb4f43ab25b03f79488f1b3a41da8bb5ea98d20c0ea0c00a1759505c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page