jniq
JNIEnv(JNINativeInterface)函数表离线查询工具,面向 Android JNI 逆向。
LLM/人脑都记不住 233 个槽位的顺序,从 index/offset 反查函数名时极易错位—— jniq 把真实 jni.h 解析成内置表,提供确定性的互查,不再靠记忆。
内置数据:Android NDK 的 jni.h。
安装
# 从 PyPI(发布后)
uv tool install jniq
# 或
pipx install jniq
# 从源码
git clone <repo> && cd jniq
uv tool install .
# 开发模式(改动即时生效):
uv tool install -e .
要求 Python ≥ 3.9,无第三方依赖。
用法
jniq 164 # vtable index 正查 → GetStringLength
jniq 0x520 # 64 位字节偏移反查(hex)→ GetStringLength
jniq 0x298 -b 32 # 32 位字节偏移反查 → ReleaseStringChars
jniq FindClass # 名字正查(精确,大小写不敏感)
jniq call int # 模糊查:命中 Call*IntMethod*/CallNonvirtualIntMethod*/CallStaticIntMethod*
jniq RegisterNatives --json # JSON 输出,方便喂给脚本/AI
jniq # dump 全表(index / 64位偏移 / 32位偏移 / 名字)
jniq --json # 全表 JSON
jniq --source # 打印内置表的数据来源
数字查询的判定规则:
0x开头一律按字节偏移(当前-b位宽,默认 64)- 纯十进制先按 index,越界再回落到偏移
- 可用
--index/--offset强制指定
换一份 jni.h
Android 的 JNIEnv 表基本不变,但若需查其他平台(如带 GetModule、
IsVirtualThread 的 JDK 21):
# 临时查(不改内置表)
jniq --jni-h /path/to/other/jni.h 0x750
# 重新生成内置表(会改写 src/jniq/table.py)
uv run python tools/gen_table.py /path/to/jni.h
不显式给路径时,gen_table.py 按以下顺序从环境变量推断 jni.h:
JAVA_HOME→$JAVA_HOME/include/jni.hANDROID_NDK_HOME/ANDROID_NDK_ROOT/ANDROID_NDK/NDK_HOME→ NDK 根目录下toolchains/llvm/prebuilt/*/sysroot/usr/include/jni.hANDROID_HOME/ANDROID_SDK_ROOT→ 扫描其下ndk/*
跨平台可用(macOS / Linux / Windows),路径全部用 os.path.join 拼接,
NDK prebuilt 宿主目录用 glob 匹配。
给 AI agent 用
skill/SKILL.md 是一个符合 Claude Code skill 规范的说明文件。把它
链接/复制到 agent 的 skill 目录(如 ~/.claude/skills/jniq/),agent
在遇到 JNIEnv index/offset/函数名互查时就会调用 jniq 而不是凭记忆
回答:
mkdir -p ~/.claude/skills
ln -s "$PWD/skill" ~/.claude/skills/jniq
结构
src/jniq/
parser.py # 通用 jni.h 解析器(兼容 OpenJDK / NDK 两种声明风格)
table.py # 生成的内置表(勿手改)
cli.py # 命令行入口
tools/
gen_table.py
skill/
SKILL.md # agent skill(Claude Code 规范)
Metadata
Release files for jniq 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jniq-0.1.0.tar.gz | 10.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jniq-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.6 kB
Release files / jniq-0.1.0.tar.gz
| Download URL | jniq-0.1.0.tar.gz |
|---|---|
| Size | 10.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e66a18f76d4decce86b57fd3ec0a4b397cd3ad0702b29b1e03391d6b6b0ea9b8
|
|
BLAKE2b-256 checksum How to use checksums |
0c298594d5b7bd28cbdbbf74069bcdc6e56feb29e681415dbd1e4f750506971d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 27, 2026.
Transparency logRelease files / jniq-0.1.0-py3-none-any.whl
| Download URL | jniq-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0dc38f574919e0b8c72187c835fc2046e6c7910e00a63ef6f75fd240fbc6593b
|
|
BLAKE2b-256 checksum How to use checksums |
7865aa962b76538ea8c3394f060fa100c69efc4a0298d957af6df363f58ba7a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 27, 2026.
Transparency log