Diff Binário (Binary Diff)
AÇÃO REQUERIDA (Execute imediatamente após a leitura)
AGORA: Leia../field-journal/precedent-reverse.md— confirme que a operação deste skill é uma operação regular autorizadaAGORA: Confirme se a tarefa atual se enquadra no escopo de aplicação deste skillPRÓXIMO: Leia../tool-index.md, verifique a disponibilidade das ferramentas e os caminhos reaisPRÓXIMO: Se faltar ferramentas, chame o bootstrap; não adivinhe caminhosAJA: Entre no primeiro passo do "fluxo de trabalho" e execute, não pare no estado de confirmação
Escopo de Aplicação
Use este skill quando a tarefa se enquadra nos seguintes cenários:
- Kernel/Driver sem PDB — Símbolos da versão antiga do ntoskrnl.exe disponíveis, PDB da nova versão removido pela Microsoft. Usar símbolos antigos para derivar endereços de funções não exportadas na nova versão.
- Migração de Símbolos após Atualização de Programa — Um programa foi engenharia reversa anteriormente e foi atualizado. Evite reverter tudo do zero migrando os resultados antigos em lote.
- Atualização de Mecanismo de Proteção — Resultados completos de engenharia reversa da versão antiga disponíveis; nova versão precisa de localização rápida do novo offset da mesma função.
- Qualquer cenário de comparação binária onde "versão antiga com símbolos + nova versão sem símbolos".
Divisão de Trabalho com Outros Skills
| Cenário | O que usar |
|---|---|
| Engenharia reversa de um binário do zero | ida-reverse/ ou radare2/ |
| Resultados antigos disponíveis, migrar para nova versão | Este skill |
| Comparar dois binários completamente diferentes | BinDiff / Diaphora (ferramentas tradicionais) |
Vantagens Principais
Comparado às soluções tradicionais:
| Solução | Custo para 200 funções | Tempo | Precisão |
|---|---|---|---|
| Comparação manual com duas janelas do IDA | Grátis, mas desgastante | Horas | Alta |
| Correspondência automática BinDiff | Grátis | Rápido | Média (falha com grandes mudanças estruturais) |
| Totalmente delegado ao Agente (CC/Codex) | 50-100 yuans | Lento | Alta |
| Este skill (Comparação em lote com LLM) | ~1 yuan | ~10 seg/função | Alta |
Princípio Central
Função da versão antiga (com símbolos) Função da nova versão (sem símbolos)
↓ ↓
Exportar desmontagem + pseudocódigo Exportar desmontagem + pseudocódigo
↓ ↓
└──────── Comparação Estruturada pelo LLM ────────┘
↓
Saída YAML (Tabela de mapeamento de símbolos)
↓
Análise programática → Aplicação em lote ao IDB da nova versão
Pontos-chave:
- O prompt é um modelo fixo, preenchido programaticamente
- Formato de entrada e saída determinístico, análise programática
- O LLM é responsável apenas por "olhar dois trechos de código e encontrar a correspondência"
- Custo de tempo e tokens extremamente baixos
Modelo de Prompt
Prompt Padrão de Comparação
I have disassembly outputs and procedure code of the same function.
This is the function for reference:
**Disassembly for Reference**
```c
{disasm_for_reference}
Procedure code for Reference
{procedure_for_reference}
This is the function you need to reverse-engineering:
Disassembly to reverse-engineering
{disasm_code}
Procedure code to reverse-engineering
{procedure}
What you need to do is to collect all references to "{symbol_name_list}" in the function you need to reverse-engineering and output those references as YAML.
Example:
found_vcall: # This is for indirect call to virtual function or virtual function pointer fetching.
- insn_va: '0x180777700' # Always be the instruction with displacement offset
insn_disasm: call [rax+68h] # Always be the instruction with displacement offset
vfunc_offset: '0x68'
func_name: ILoopMode_OnLoopActivate
- insn_va: '0x180777778' # Always be the instruction with displacement offset
insn_disasm: mov rax, [rax+80h] # Always be the instruction with displacement offset
vfunc_offset: '0x80'
func_name: INetworkMessages_GetNetworkGroupCount
found_call: # This is for direct call to non-virtual regular function.
- insn_va: '0x180888800'
insn_disasm: call sub_180999900
func_name: CLoopMode_RegisterEventMapInternal
- insn_va: '0x180888880'
insn_disasm: call sub_180555500
func_name: CLoopMode_SetSystemState
found_funcptr: # This is for non-virtual regular function pointer.
- insn_va: '0x180666600' # Must load/reference the function pointer target address
insn_disasm: lea rdx, sub_15BC910 # Must load/reference the function pointer target address
funcptr_name: CLoopMode_OnClientPollNetworking
found_gv: # This is for reference to global variable.
- insn_va: '0x180444400'
insn_disasm: mov rcx, cs:qword_180666600 # Must load/reference the global variable
gv_name: g_pNetworkMessages
- insn_va: '0x180333300'
insn_disasm: lea rax, unk_180222200 # Must load/reference the global variable
gv_name: s_EventManager
found_struct_offset: # This is for reference to struct offset. NOTE THAT virtual function pointer should not be here! virtual function pointer should ALWAYS be in found_vcall !
- insn_va: '0x1801BA12A' # Always be the instruction with displacement offset
insn_disasm: mov rcx, [r14+58h] # Always be the instruction with displacement offset
offset: '0x58'
size: 8
struct_name: CResourceService
member_name: m_pEntitySystem
If nothing found, output an empty YAML. DO NOT output anything other than the desired YAML. DO NOT collect unrelated symbols.
### Descrição das Variáveis
| Variável | Fonte | Descrição |
|----------|-------|-----------|
| `{disasm_for_reference}` | Exportação do IDA antigo | Desmontagem com símbolos |
| `{procedure_for_reference}` | Exportação do IDA antigo | Pseudocódigo com símbolos |
| `{disasm_code}` | Exportação do IDA novo | Desmontagem sem símbolos |
| `{procedure}` | Exportação do IDA novo | Pseudocódigo sem símbolos |
| `{symbol_name_list}` | Extraído da versão antiga | Lista de símbolos a serem localizados na nova versão |
## Fluxo de Trabalho
### Fluxo Completo
```text
Passo 1: Preparar Dados
- Carregar binário antigo no IDA (com PDB/símbolos)
- Carregar binário novo no IDA (sem símbolos)
- Encontrar funções âncora idênticas nas duas versões (funções exportadas, referências a strings etc.)
Passo 2: Exportar em Lote
- Exportar da versão antiga: desmontagem + pseudocódigo da função âncora (com nomes de símbolos)
- Exportar da versão nova: desmontagem + pseudocódigo da mesma função âncora (sem nomes de símbolos)
Passo 3: Comparação pelo LLM
- Preencher o modelo de prompt com os dados
- Chamar a API do LLM (recomendado: DeepSeek para grande volume e baixo custo; funções muito grandes usar GPT)
- Analisar o YAML retornado
Passo 4: Aplicar Resultados
- Aplicar o mapeamento de símbolos do YAML em lote ao IDB da nova versão
- Usar idapro_rename ou script IDAPython para renomear em lote
Passo 5: Iterar
- As funções migradas na primeira rodada tornam-se novas âncoras
- Entrar nessas funções e continuar comparando chamadas internas
- Repetir até cobrir todas as funções alvo
Estratégia de Seleção de Âncoras
| Tipo de Âncora | Confiabilidade | Descrição |
|---|---|---|
| Funções Exportadas | Mais alta | Nome inalterado, endereço pode mudar |
| Referências a Strings | Alta | Conteúdo da string inalterado, localização da referência pode mudar |
| Constantes/Magic Numbers | Média | Valor característico inalterado |
| Padrões de Código | Média | Estrutura da função semelhante, mas endereços totalmente alterados |
Recomendações para Processamento em Lote
- Comparar 1 função por vez (evitar explosão de contexto)
- Funções médias (<200 linhas) usar DeepSeek
- Funções muito grandes (>500 linhas) usar GPT-4o ou Claude
- Chamadas concorrentes para aumentar a velocidade (10-20 concorrências)
- Armazenar em cache resultados intermediários para evitar chamadas repetidas
Formato de Saída
5 Tipos de Símbolos na Saída YAML
| Tipo | Significado | Campos-chave |
|---|---|---|
found_vcall | Chamada de função virtual (call indireto) | vfunc_offset, func_name |
found_call | Chamada de função direta | insn_va, func_name |
found_funcptr | Referência a ponteiro de função | insn_va, funcptr_name |
found_gv | Referência a variável global | insn_va, gv_name |
found_struct_offset | Referência a offset de struct | offset, struct_name, member_name |
Ações de Aplicação após Análise
found_call → idapro_rename(addr=call_target, name=func_name)
found_vcall → idapro_set_comments(addr=insn_va, comment="vcall: {func_name} @ +{offset}")
found_funcptr → idapro_rename(addr=funcptr_target, name=funcptr_name)
found_gv → idapro_rename(addr=gv_addr, name=gv_name)
found_struct_offset → idapro_set_comments(addr=insn_va, comment="{struct_name}.{member_name}")
Exemplos de Cenários Típicos
Cenário 1: ntoskrnl.exe sem PDB
Já possui: ntoskrnl.exe 10.0.26100.2000 + PDB completo
Objetivo: ntoskrnl.exe 10.0.26100.2605 (PDB removido)
Necessidade: Localizar novo endereço de PspSetCreateProcessNotifyRoutine
Passos:
1. Carregar ambas as versões no IDA
2. Encontrar função exportada PsSetCreateProcessNotifyRoutine (ambas têm)
3. Na versão antiga, ela chama PspSetCreateProcessNotifyRoutine (com símbolo)
4. Na nova versão, ela chama sub_140822108 (sem símbolo)
5. LLM identifica rapidamente: sub_140822108 = PspSetCreateProcessNotifyRoutine
6. Aplicar em lote
Cenário 2: Migração após Atualização de Aplicativo
Já possui: Resultado completo de engenharia reversa do target.exe v1.0 (200+ funções nomeadas)
Objetivo: target.exe v1.1 (todos os símbolos perdidos)
Necessidade: Migrar 200 nomes de função em lote
Passos:
1. Exportar da versão antiga a desmontagem+pseudocódigo de todas as funções nomeadas
2. Na nova versão, encontrar âncoras correspondentes por funções exportadas/strings
3. Chamar LLM em lote para comparação
4. Analisar YAML, renomear em lote
5. Iterar aprofundadamente
Recomendações de Seleção de LLM
| Modelo | Cenário Adequado | Custo | Velocidade |
|---|---|---|---|
| DeepSeek V3 | Funções pequenas/médias (<200 linhas), processamento em lote | Muito baixo | Rápido |
| GPT-4o | Funções muito grandes, fluxo de controle complexo | Médio | Rápido |
| Claude Sonnet | Funções médias/grandes, necessidade de raciocínio | Médio | Rápido |
| Claude Opus | Funções extremamente complexas, necessidade de compreensão profunda | Alto | Lento |
Estratégia recomendada: Padrão DeepSeek, atualizar automaticamente quando houver estouro de contexto ou resultados imprecisos.
Observações
- Não jogue o binário inteiro para o LLM — Compare apenas uma função por vez
- Âncoras devem ser confiáveis — Se a âncora estiver errada, todo o resto será em vão
- Resultados precisam de verificação manual — O LLM não é 100% preciso; símbolos críticos devem ser validados
- Armazene resultados intermediários em cache — Evite chamadas repetidas desperdiçando tokens
- Atenção aos limites de contexto — Funções muito grandes (>1000 linhas de desmontagem) precisam ser divididas ou usar modelos de contexto grande
Bootstrap Sob Demanda (On-Demand Bootstrap)
Dependências de Ferramentas
| Ferramenta | Uso | Instalação Automática |
|---|---|---|
| IDA Pro | Exportar desmontagem/pseudocódigo | ✗ (Software comercial) |
| Python | Execução de scripts, chamadas de API | ✓ |
| PyYAML | Analisar YAML retornado pelo LLM | ✓ (pip install pyyaml) |
| LLM API | Executar comparação | Necessita chave de API |
Observação
Este skill não depende de instalação pesada de ferramentas; depende principalmente de:
- IDA Pro já existente (gerenciado pelo skill
ida-reverse/) - Python + requests/httpx (para chamar API)
- Um endpoint de API LLM
Contexto de Roteamento
Entrada a montante: skills/SKILL.md (controle principal), routing.md
Condição de disparo: Possui símbolos/resultados de engenharia reversa da versão antiga, necessidade de migrar para nova versão
Saída a jusante:
- Necessário abrir binário primeiro →
ida-reverse/ - Necessário reconhecimento rápido para confirmar diferenças de versão →
radare2/
Módulos associados no mesmo nível: ida-reverse/ (exportação de dados e aplicação de símbolos são feitos através do IDA)
Autoverificação de Conclusão da Tarefa (DEVE passar antes de afirmar conclusão)
- Executei cada passo do fluxo de trabalho (e não apenas li)?
- Usei caminhos reais de ferramentas com base no
tool-index? - Produzi evidências reproduzíveis (comandos/scripts/capturas de tela/relatórios)?
- Completei e registrei os itens da Checklist exigidos pelas REGRAS?