Kit de engenharia reversa com IA em primeiro lugar: análise estática, descompilador SSA, memória ao vivo, proveniência. Código-fonte disponível (PolyForm Noncommercial).
De um watchpoint de hardware em um processo em execução até a instrução descompilada exata que alterou o valor.
Scanners de memória encontram o endereço. Descompiladores explicam o código. N0xis conecta os dois.
$ 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
]
Esse é o hp -= 1; do código-fonte, recuperado de um processo em execução — o endereço
observado aparece na instrução. Verificado no Windows e no Linux.
Uma varredura "encontre o que acessa isto" normalmente para em uma linha de disassembly bruta, e um descompilador normalmente não tem nenhuma entrada de watchpoint ao vivo. Isto é as duas metades unidas: o acerto do watchpoint é resolvido através do mesmo pipeline SSA que descompila o arquivo.
Binários pré-compilados para Linux e Windows — última versão.
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
Ou compile: cargo build --workspace --release (Windows e Linux; sem necessidade de MSVC Build Tools
— rust-toolchain.toml fixa o host gnu).
Todo comando imprime um objeto JSON — erros de argumento incluídos: {"ok":true,"data":…,"meta":…} ou
{"ok":false,"error":…}. Adicione --pretty para lê-lo; o código de saída é diferente de zero em caso de falha.
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
Os mesmos comandos rodam em um --pid ao vivo, um --file estático, um --snapshot capturado, ou um
processo remoto via SSH. É encanamento Unix comum —
n0x function discover --file game.exe --pdata | jq -r '.data.functions[].va' alimenta o próximo
comando. n0x guide lista todos os 113 comandos, gerados a partir do binário para que nunca se desvie — e um teste
falha a compilação se esse número o fizer.
A partir de um agente: aponte qualquer cliente MCP para n0xis-mcp — 25 ferramentas retornando o idêntico
envelope {ok,data,meta}, JSON-RPC sobre stdio.
{ "mcpServers": { "n0xis": { "command": "/path/to/n0xis-mcp" } } }
--explain: qual sub-passe alterou o quê, em qual endereço), não uma resposta de caixa-preta..rdata do MSVC e símbolos
_ZTV do Itanium), .NET NativeAOT RVA ↔ Namespace.Type.Method, LuaJIT, Bitsquid, IL2CPP —
para que uma imagem sem símbolos seja lida como código-fonte, não como sub_XXXX..n0xt, anotações versionadas, cache endereçado por conteúdo,
comparação de funções/versões.Windows e Linux, PE e ELF, um pipeline — arquivos estáticos, processos ao vivo, snapshots e alvos remotos todos fluem pelos mesmos passes e pelo mesmo JSON versionado.
Não há não-determinismo de ML no núcleo, nunca. Uma GUI de desktop vive em um repositório separado: n0xis-gui.
Alpha. Toda afirmação abaixo é uma medição contra uma fonte externa à ferramenta — o kernel, as próprias tabelas da imagem, ou o próprio processo alvo. Onde não há tal fonte, ele diz isso, porque implementado e verificado não são a mesma afirmação.
Memória ao vivo, contra um alvo descartável que planta valores conhecidos:
/proc/<pid>/mem, um errado e corrigido. Os
outros dois são exclusivos do Windows e recusam dizendo isso. O único errado foi scan dissect, que
escolheu a largura de um campo antes do seu alinhamento e assim leu uma struct quatro bytes fora de fase desde
seu primeiro erro em diante: um campo de seis correto contra um layout conhecido de seu próprio código-fonte, cinco
de seis depois.ui focus corretamente não encontra nenhuma janela em um alvo de console; stack backtrace é
exclusivo do Linux — o único lugar onde o adaptador Linux está à frente.O decodificador, contra um disassembler independente — a base sobre a qual tudo o mais se apoia, e até agora verificado apenas pelos passes construídos sobre ele, que todos leem o mesmo fluxo:
objdump. Três formas construídas para o propósito exatas,
20 000 instruções de uma biblioteca compartilhada e 20 000 de uma DLL de sistema de 32 bits, zero
divergências e zero limites que qualquer um dos lados tinha sozinho. Ampliado para 60 000 instruções
de um binário de navegador sem símbolos de 334 MB: 2 divergências, ambas dentro de uma string ASCII embutida
em .text onde a própria referência decodifica (bad) — não é código, e nenhuma das leituras é
a correta.llvm-objdump (codificações de largura fixa tornam os limites
vazios). Veja a linha ARM64 abaixo.llvm-mc --mattr=+all e por n0xis. 241 ambos chamam de instrução, 304 ambos rejeitam —
e 48 (8,0%) são codificações reservadas que n0xis lê como instruções, com 7 (1,2%) instruções
reais que ele rejeita (principalmente atômicas LSE). Três das 48 foram decodificadas à mão e são
genuinamente UNALLOCATED. Essa lacuna é mantida por um limite que falha se ela crescer, e declarada
aqui em vez de omitida: uma palavra reservada lida como instrução transforma dados em um
programa plausível.Extensões de funções, contra a própria tabela de unwind da imagem e a lista de exportações do linker:
start..end de cada FDE de objdump --dwarf=frames igual à extensão recuperada —
3 787 comparados nesta máquina (10 + 3 777 da libc), início e fim, exatos; separadamente
medidos em 15 467 e 14 355 em duas bibliotecas grandes.