AI优先逆向工程工具包:静态分析、SSA反编译器、实时内存、溯源。源码可用(PolyForm Noncommercial)。
从活动进程中的硬件观察点,到改变该值的精确反编译语句。
内存扫描器找到的是地址。反编译器解释的是代码。N0xis 将两者连接起来。
$ n0x provenance trace --pid 9348 --addr 0x7ff68bef3010 --kind write
"function_va": "0x7ff68bef1580", // containing function, auto-resolved
"decompiled_context": [
"rax.2 = (*(uint32_t*)(0x7ff68bef3010) - 0x1);",
"*(uint32_t*)(0x7ff68bef3010) = rax.2;" // ← the statement that moved your value
]
这就是源码中的 hp -= 1;,从一个正在运行的进程中恢复出来——被观察的地址
出现在该语句中。已在 Windows 和 Linux 上验证。
“查找谁访问了这里”的扫描通常止步于一行原始反汇编,而反编译器通常 根本没有实时观察点输入。这里把两半拼在了一起:观察点命中通过 反编译该文件的同一条 SSA 流水线解析出来。
适用于 Linux 和 Windows 的预编译二进制文件——最新发布。
curl -LO https://github.com/Structio-labs/N0xis/releases/latest/download/n0xis-linux-x86_64
chmod +x n0xis-linux-x86_64 && ./n0xis-linux-x86_64 --version
或者自行构建:cargo build --workspace --release(Windows 和 Linux;无需 MSVC Build Tools
——rust-toolchain.toml 固定了 gnu host)。
每条命令都打印一个 JSON 对象——参数错误也不例外:{"ok":true,"data":…,"meta":…} 或
{"ok":false,"error":…}。加上 --pretty 以便阅读;失败时退出码非零。
n0x doctor # environment check
n0x profile --file game.exe # triage: sections, exports, engine hints
n0x function discover --file game.exe --pdata # exact .pdata discovery
n0x decomp pseudo --file game.exe --addr 0x140012a00 --style ssa --pretty
n0x provenance trace --pid 4821 --addr 0x1a2b3c40 --kind write --pretty
同样的命令可以作用于活动 --pid、静态 --file、捕获的 --snapshot,或通过 SSH 连接的
远程进程。这就是普通的 Unix 管道——
n0x function discover --file game.exe --pdata | jq -r '.data.functions[].va' 会喂给下一条
命令。n0x guide 列出全部 113 条命令,由二进制文件生成,因此永不漂移——并且有一个测试
会在此数字不一致时让构建失败。
从 agent 使用: 将任意 MCP 客户端指向 n0xis-mcp——25 个工具返回完全相同的
{ok,data,meta} 信封,基于 stdio 的 JSON-RPC。
{ "mcpServers": { "n0xis": { "command": "/path/to/n0xis-mcp" } } }
--explain:哪个子 pass 在哪个地址改了什么),而不是黑盒答案。.rdata 链和 Itanium
的 _ZTV 符号)、.NET NativeAOT 的 RVA ↔ Namespace.Type.Method、LuaJIT、Bitsquid、IL2CPP——
这样被剥离符号的映像读起来就像源码,而不是 sub_XXXX。.n0xt 表、带版本的注解、内容寻址缓存、
函数/版本差异比较。Windows 和 Linux,PE 和 ELF,同一条流水线——静态文件、活动进程、快照 和远程目标都流经相同的 pass 和相同的带版本 JSON。
核心中永远没有 ML 的不确定性。桌面 GUI 位于单独的仓库: n0xis-gui。
Alpha。 以下每一项声明都是针对工具之外的来源进行的测量——内核、 映像自身的表,或目标进程本身。在没有此类来源的地方,会明确说明, 因为已实现和已验证不是同一种声明。
活动内存,针对一个植入已知值的一次性目标:
/proc/<pid>/mem 进行了测量,一条错误并已修复。 另外
两条是 Windows 专属的,并会明确说明这一点而拒绝执行。那一条错误的是 scan dissect,它
在字段的对齐之前就选定了字段宽度,因此从它的第一个错误开始,读取结构体时就偏移了四个字节:
针对从其自身源码已知的布局,六个字段中只有一个正确,修复后六个中五个正确。ui focus 在控制台目标上正确地找不到窗口;stack backtrace 是
Linux 专属的——这是 Linux 适配器领先的唯一一处。解码器,针对一个独立的反汇编器——这是其他一切所立足的基础, 而在此之前仅由构建于其上的 pass 检查过,而这些 pass 读取的都是同一条流:
objdump 比较。三种专门构造的形状完全精确,
一个共享库的 20 000 条指令和一个 32 位系统 DLL 的 20 000 条指令,零
分歧,且双方各自单独发现的边界也为零。扩大到一个 334 MB 剥离符号的浏览器二进制的 60 000 条
指令:2 处分歧,均位于嵌入 .text 的 ASCII 字符串内部,在那里参考实现自身也解码为
(bad)——那不是代码,且两种读法都不正确。llvm-objdump 比较(定宽编码使边界问题变得无意义)。见下方 ARM64 一行。llvm-mc --mattr=+all 和
n0xis 判定。241 个双方都判定为指令,304 个双方都拒绝——
而 48 个(8.0%)是保留编码,n0xis 却将其读作指令,另有 7 个(1.2%)是真实
指令却被它拒绝(主要是 LSE 原子操作)。那 48 个中有三个经手工解码,确实是
UNALLOCATED。这一差距由一个在它扩大时就会失败的界限所约束,并在此处
说明而非略去:一个被读作指令的保留字会把数据变成一段看似合理的程序。函数范围,针对映像自身的展开表和链接器的导出列表:
objdump --dwarf=frames 的每个 FDE 的 start..end 都等于恢复出的范围——
在本机上比较了 3 787 个(10 + libc 的 3 777),起点和终点,精确;另外
在两个大型库上分别测得 15 467 和 14 355。交叉引用和调用图,针对一个并非本工具的来源的反汇编:
call、尾调用 jmp 和 RIP 相对数据引用各自按 kind 标注,
且每一项都与 objdump 所显示的内容进行了比较。恢复的结构体字段,针对布局该结构体的编译器:
gcc -g 声明了每个成员的偏移;跨 10 个函数恢复了 15 个字段偏移,
每一个都是真实成员——无一虚构。 有意为之的单向性:优化器会折叠
并丢弃字段访问,因此从未出现的成员是编译器所为,而非遗漏。静态分析,针对映像所声明的范围和表:
oracle/arm64.c 以 -O2 编译):147 条指令,147 个共享地址,0 次解码失败,
且全部 28 处名称差异都是已记录的架构别名(mov/orr、
cmp/subs、b.hs/b.cs……),每一处都在测试中列出,而非笼统地宽恕。AArch64 的
lift/SSA 仍未构建,因此 decomp pseudo 报告 quality: 0.0 并回退
到 asm 节点。优化型反编译器仅支持 x64。.eh_frame
FDE 进行了检查:0 遗漏,每个范围都精确,0 个条目位于已知函数内部。 该规则是针对 x64 异常表编写的,却在一个没有异常表的
架构上成立。恢复的签名,针对在此处编译、其答案在提问之前就已知的目标(oracle/):
cdecl 在返回时不声明参数个数,也不通过寄存器传递任何东西,因此
参数列表读作 ()——C 语言中表示未指定——而非 (void),后者会是一个
声称没有参数的断言。此 lift 未建模的 x87 返回读作 /*unknown*/,而非 void。
两处缺口都连同其原因记录在 oracle/expect.json 中,且测试会在其中一处
悄然闭合时失败,因此已记录的限制不会腐烂成民间传说。恢复的 C++ 类,针对映像自身的类型描述符字符串:
oracle/rtti32.c、oracle/rtti64.S),因为此处没有编译器会生成 MSVC RTTI。未验证,且未声称: il2cpp import / symbols 需要外部 dumper 的索引;
il2cpp obj / classes 需要一个活动的托管进程。带版本的 JSON 契约尚未经过
外部用户的实际检验——预计其形状会变动。
n0x guide 和
--help 中,它们也是生成的。N0xis 是源码可用软件,以 Structio 名义开发。
截至并包括 0.2.1 的版本曾依据 AGPL-3.0 发布,并仍可按 那些条款获取。本许可证适用于 0.3.0 及更高版本。
不确定你的用例是否属于商业用途?开一个 issue 或发邮件至 [email protected]—— 我宁愿回答问题,也不愿追究违规。