Metadata-Version: 2.4
Name: jniq
Version: 0.1.0
Summary: JNIEnv (JNINativeInterface) function table lookup: index/offset/name for JNI reversing
Keywords: jni,jnienv,android,reverse-engineering,reversing,ndk,frida,binary-analysis
Author: yixinBC
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Disassemblers
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Project-URL: Homepage, https://github.com/yixinBC/jniq
Project-URL: Repository, https://github.com/yixinBC/jniq
Project-URL: Issues, https://github.com/yixinBC/jniq/issues
Description-Content-Type: text/markdown

# jniq

JNIEnv（`JNINativeInterface`）函数表离线查询工具，面向 Android JNI 逆向。

LLM/人脑都记不住 233 个槽位的顺序，从 index/offset 反查函数名时极易错位——
jniq 把真实 jni.h 解析成内置表，提供确定性的互查，不再靠记忆。

内置数据：**Android NDK** 的 `jni.h`。

## 安装

```sh
# 从 PyPI（发布后）
uv tool install jniq
# 或
pipx install jniq

# 从源码
git clone <repo> && cd jniq
uv tool install .
# 开发模式（改动即时生效）：
uv tool install -e .
```

要求 Python ≥ 3.9，无第三方依赖。

## 用法

```sh
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）：

```sh
# 临时查（不改内置表）
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`：

1. `JAVA_HOME` → `$JAVA_HOME/include/jni.h`
2. `ANDROID_NDK_HOME` / `ANDROID_NDK_ROOT` / `ANDROID_NDK` / `NDK_HOME`
   → NDK 根目录下 `toolchains/llvm/prebuilt/*/sysroot/usr/include/jni.h`
3. `ANDROID_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` 而不是凭记忆
回答：

```sh
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 规范）
```
