Comprehensive documentation for the AI module covering architecture, API design, data model, RAG pipeline, configuration, integration points, and frontend integration guide. Includes IDA5 extraction points reference and AGENTS.md with project conventions and coding standards.
16 KiB
Pontos de Extração — IDA 5, IDA 7 e Ghidra
Documento de referência sobre quais dados de análise estática são extraíveis via script de cada engine, com a utilidade de cada ponto e grau de dificuldade.
Tabela Resumo
| # | Dado | Utilidade | IDA 5 (IDC) | IDA 7+ (IDAPython) | Ghidra (Java/Python) |
|---|---|---|---|---|---|
| 1 | Funções (nome, endereço, assembly) | Navegação básica do binário | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 2 | Code references / Labels | Resolver alvos de jump/call | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 3 | Xrefs de entrada (callers) | Grafo de chamadas reverso | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 4 | Entry point | Saber onde o binário inicia | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 5 | Tipo de xref (CALL vs JUMP vs DATA) | Diferencia saltos de chamadas | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 6 | Flags da função (library, thunk, far) | Classificar tipo de função | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 7 | Segmentos (.text, .data, .rdata) | Mapa de memória do binário | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 8 | Tamanho/fim da função | Delimitar escopo da função | ✅ Fácil | ✅ Fácil | ✅ Fácil |
| 9 | Strings referenciadas | Entender mensagens, nomes, paths | ✅ Médio | ✅ Fácil | ✅ Fácil |
| 10 | Imports / APIs externas (DLLs) | Saber quais libs externas são usadas | ✅ Médio | ✅ Fácil | ✅ Fácil |
| 11 | Frame da função (vars locais, args) | Estrutura da stack frame | ✅ Médio | ✅ Fácil | ✅ Fácil |
| 12 | Comentários do IDA/Ghidra | Anotações automáticas do disassembler | ✅ Médio | ✅ Fácil | ✅ Fácil |
| 13 | Data xrefs (leitura/escrita em globais) | Quem acessa cada variável global | ⚠️ Limitado | ✅ Médio | ✅ Médio |
| 14 | Tipos e assinaturas de funções | Parâmetros, retorno, calling convention | ❌ Não viável | ✅ Médio | ✅ Fácil |
| 15 | Estruturas e enums | Layout de structs usadas pelo binário | ❌ Não viável | ⚠️ Limitado | ✅ Médio |
| 16 | Decompilação (pseudocódigo) | Código de alto nível reconstruído | ❌ Não existe | ✅ Fácil | ✅ Fácil |
| 17 | Call graph / Fluxo de controle (CFG) | Visualização de blocos e branches | ⚠️ Limitado | ✅ Médio | ✅ Médio |
| 18 | Nomes de variáveis globais | Labels simbólicos de dados | ✅ Médio | ✅ Fácil | ✅ Fácil |
1. Funções (nome, endereço, assembly)
O que é: Lista de todas as funções reconhecidas pelo disassembler, com nome, endereço de início e o texto do assembly.
Para que serve: É a base de toda navegação. Permite listar funções, buscar por nome, e exibir o código de cada uma.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | NextFunction(), GetFunctionName(), GetDisasm(), ItemSize() |
✅ Já implementado |
| IDA 7 | ida_funcs.get_funcs(), ida_lines.generate_disasm_line() |
✅ Trivial |
| Ghidra | currentProgram.getFunctionManager().getFunctions(), listing.getInstructions() |
✅ Trivial |
2. Code References / Labels
O que é: Para cada instrução de jump/call, o endereço de destino e o nome (label) associado a ele.
Para que serve: Permite que o frontend resolva labels (loc_28D, sub_402000) para endereços reais e ofereça navegação por clique.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | Rfirst(ea), Rnext(ea, ref), Name(ref) |
✅ Já implementado |
| IDA 7 | ida_xref.xrefblk_t() com iscode=True |
✅ Trivial |
| Ghidra | instruction.getReferencesFrom(), ref.getToAddress() |
✅ Trivial |
3. Xrefs de entrada (callers)
O que é: Lista de funções que chamam/referenciam a função atual.
Para que serve: Constrói o grafo reverso de chamadas — "quem me chama". Essencial para entender o fluxo do programa.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | RfirstB(ea), RnextB(ea, xref) |
✅ Já implementado |
| IDA 7 | ida_xref.xrefs_to(ea) |
✅ Trivial |
| Ghidra | function.getCallingFunctions(TaskMonitor.DUMMY) ou via reference manager |
✅ Trivial |
4. Entry Point
O que é: O endereço onde a execução do binário começa. Pode ser o stub da CRT (start) ou diretamente main/WinMain.
Para que serve: Ponto de partida da análise. O analista sabe por onde começar a ler o código. Em modo headless do frontend, pode ser usado como âncora inicial.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | BeginEA() retorna o entry point; Name() dá o label |
✅ Trivial (testado, funciona) |
| IDA 7 | ida_loader.get_entry_point() ou ida_entry.get_entry_ordinals() |
✅ Trivial |
| Ghidra | program.getListing().getInstructionAt(program.getImageBase().add(entryOffset)); entry offset via program.getExecutableFormat() ou metadados do importador |
✅ Trivial |
5. Tipo de Xref (CALL vs JUMP vs DATA)
O que é: Classifica cada code reference como CALL (chamada de função), JUMP (salto condicional/incondicional) ou referência a dados.
Para que serve: Permite que o frontend diferencie visualmente chamadas de função de saltos locais. Essencial para coloração de syntax e navegação contextual.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | XrefType() retorna fl_CF (far call), fl_CN (near call), fl_JF (far jump), fl_JN (near jump) |
✅ Fácil (1 enum switch) |
| IDA 7 | ida_xref.xrefblk_t().type retorna fl_CF/fl_CN/fl_JF/fl_JN |
✅ Fácil |
| Ghidra | ref.getReferenceType() retorna CALL, JUMP, DATA, etc. |
✅ Fácil |
6. Flags da Função
O que é: Atributos da função como: é library function? é thunk? usa far calling convention? tem frame pointer?
Para que serve: Classificação automática de funções. Ex: marcar funções importadas de DLL como "library", diferenciar funções far/near em binários 16-bit, etc.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | GetFunctionFlags(ea) retorna bits: FUNC_LIB, FUNC_THUNK, FUNC_FAR, FUNC_FRAME, etc. |
✅ Fácil (bitmask) |
| IDA 7 | ida_funcs.get_func(ea).flags |
✅ Fácil |
| Ghidra | function.isThunk(), function.isLibrary(), function.getCallingConvention() |
✅ Fácil |
7. Segmentos (.text, .data, .rdata, etc.)
O que é: Mapa de memória do binário — cada segmento com nome, endereço inicial, endereço final e classe (CODE, DATA, BSS, etc.).
Para que serve: Contexto para o frontend mostrar em qual região de memória cada função/string está. Permite filtrar funções por segmento (ex: "só .text").
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | SegByName(), SegStart(), SegEnd(), SegName(), iteração com FirstSeg()/NextSeg() |
✅ Fácil (loop de segmentos) |
| IDA 7 | ida_segment.get_segm_list(), ida_segment.get_segm_by_name() |
✅ Fácil |
| Ghidra | program.getMemory().getBlocks() |
✅ Fácil |
8. Tamanho / Fim da Função
O que é: Endereço final da função (FindFuncEnd), permitindo calcular tamanho em bytes e delimitar o escopo.
Para que serve: Já usado internamente no extract.idc. Expor no JSON permite ao frontend mostrar "tamanho: 245 bytes" ou destacar o range da função no mapa de memória.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | FindFuncEnd(ea) |
✅ Já usado internamente |
| IDA 7 | ida_funcs.get_func(ea).end_ea |
✅ Trivial |
| Ghidra | function.getBody().getMaxAddress() |
✅ Trivial |
9. Strings
O que é: Todas as strings contidas no binário (mensagens, nomes de arquivo, paths, nomes de classes, etc.) com endereço, conteúdo e tipo (ASCII, Unicode).
Para que serve: Essencial para entender o que o programa faz. Strings geralmente revelam funcionalidades, mensagens de erro, comandos, paths de arquivo. O frontend pode oferecer busca e filtro por strings.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | Iterar sobre segmentos de dados com isLoaded(ea) e GetString(ea, -1, ASCSTR_C). Também é possível buscar "string literals" no segmento .data/.rdata com GetStringType(). |
✅ Médio (iteração manual sobre bytes) |
| IDA 7 | ida_bytes.get_strlit_contents(), ida_strlist.string_info_t() — API nativa de strings |
✅ Fácil |
| Ghidra | program.getListing().getDefinedData(true) filtrado por StringDataInstance |
✅ Fácil |
10. Imports / APIs Externas (DLLs)
O que é: Lista de funções externas importadas de DLLs (ex: KERNEL32.CreateFileA, USER32.MessageBoxA) com nome da DLL, nome da função e endereço na IAT.
Para que serve: Saber quais APIs do sistema operacional o binário usa. Permite inferir capacidades (ex: se importa WS2_32, usa rede; se importa CRYPT32, usa criptografia).
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | Iterar segmentos externos (SegByName(".idata")) e usar Name(ea) nos endereços da IAT. Alternativa: parse da tabela de imports manualmente. |
✅ Médio (requer lógica de parse) |
| IDA 7 | ida_nalt.get_import_module_name(), idaapi.enum_import_names() |
✅ Fácil |
| Ghidra | program.getExternalManager().getExternalLibraryNames(), getExternalLibraryFunctions() |
✅ Fácil |
11. Frame da Função (variáveis locais, argumentos)
O que é: Estrutura da stack frame: variáveis locais (com nome e offset negativo do bp), argumentos (offset positivo), saved registers, tamanho total do frame.
Para que serve: Entender a assinatura implícita da função (quantos args, quantas vars locais). O frontend pode exibir uma tabela de variáveis locais junto com o assembly.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | GetFrame(ea) retorna o id da estrutura, GetStrucSize(id), iterar membros com GetStrucMember()/GetMemberName() |
✅ Médio (API de estruturas frágil no IDA 5) |
| IDA 7 | ida_frame.get_frame(ea), ida_struct.get_struc_members() |
✅ Fácil |
| Ghidra | function.getStackFrame(), stackFrame.getStackVariables() |
✅ Fácil |
12. Comentários do Disassembler
O que é: Comentários gerados automaticamente pelo disassembler (ex: ; CODE XREF: sub_1000+5A, ; char em loads de strings) e comentários manuais do analista.
Para que serve: Enriquece a exibição do assembly. Comentários automáticos do IDA/Ghidra dão dicas de tipos e cross-references que ajudam na leitura.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | GetCommentEx(ea, 0) para comentários regulares, GetRptCmt(ea) para comentários repetíveis |
✅ Médio (precisa testar quais flags funcionam) |
| IDA 7 | ida_bytes.get_cmt(ea, False), ida_bytes.get_cmt(ea, True) |
✅ Fácil |
| Ghidra | listing.getComment(CodeUnit.EOL_COMMENT, address) e PRE_COMMENT, POST_COMMENT |
✅ Fácil |
13. Data Xrefs (leitura/escrita em globais)
O que é: Referências de instruções para endereços de dados — quem lê e quem escreve cada variável global.
Para que serve: Entender o fluxo de dados. Ex: "a variável global g_score é escrita por addPoints() e lida por drawHUD()".
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | Dfirst(ea) e Dnext(ea, ref) retornam data xrefs. API existe mas suporte pode ser limitado. |
⚠️ Limitado (testar viabilidade) |
| IDA 7 | ida_xref.xrefs_to(ea) com filtro data, ou ida_xref.xrefblk_t() |
✅ Médio |
| Ghidra | referenceManager.getReferencesTo(address) e filtrar por tipo DATA |
✅ Médio |
14. Tipos e Assinaturas de Funções
O que é: Tipo de retorno, parâmetros com nome e tipo, calling convention (__cdecl, __stdcall, __fastcall), tipo void*, tamanho de cada parâmetro.
Para que serve: Assinatura completa da função. Permite ao frontend mostrar "int sub_1000(HWND hWnd, LPCSTR lpText)" em vez de só o nome.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | Suporte a tipos muito limitado. GetType() pode retornar string, mas raramente populado. |
❌ Não viável |
| IDA 7 | ida_typeinf.get_tinfo(ea), ida_typeinf.print_tinfo() |
✅ Médio |
| Ghidra | function.getReturnType(), function.getParameters(), function.getSignature() |
✅ Fácil |
15. Estruturas e Enums
O que é: Layout de structs e enums reconhecidos pelo disassembler, com nomes de campos e tipos.
Para que serve: Entender estruturas de dados usadas pelo binário. Ex: mostrar que [ebp+8] acessa struct Player.name.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | GetStrucId(), GetStrucName() — API existe mas tipos raramente aplicados pelo IDA 5 |
❌ Não viável |
| IDA 7 | ida_struct.get_struc_list(), ida_typeinf para tipos locais |
⚠️ Limitado (depende da análise do IDA) |
| Ghidra | program.getDataTypeManager().getAllStructures() |
✅ Médio |
16. Decompilação (Pseudocódigo)
O que é: Código de alto nível reconstruído a partir do assembly — if/else, while, chamadas de função com nomes de parâmetros.
Para que serve: Leitura muito mais rápida do que assembly. É o principal diferencial do Ghidra e IDA 7+ sobre o IDA 5.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | Não tem decompiler (Hex-Rays só a partir do IDA 6.6+) | ❌ Não existe |
| IDA 7 | ida_hexrays.decompile(ea) retorna AST, cfunc.print() gera string |
✅ Fácil (requer licença Hex-Rays) |
| Ghidra | decompInterface.decompileFunction(function, timeout, monitor) → decompResults.getDecompiledFunction().getC() |
✅ Fácil (nativo e gratuito) |
17. Call Graph / Control Flow Graph (CFG)
O que é: Grafo direcionado de chamadas entre funções (call graph) e blocos básicos dentro de cada função (CFG) com arestas representando branches condicionais.
Para que serve: Visualização gráfica do fluxo do programa. O frontend pode renderizar um grafo interativo de chamadas e blocos.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | GetFchunkAttr(ea, FUNCATTR_START) e iteração sobre chunks. FlowChart não disponível no IDC 5. |
⚠️ Limitado (possível via chunks) |
| IDA 7 | ida_gdl.FlowChart(f) retorna nós e arestas; ida_gdl.gen_flow_graph() |
✅ Médio |
| Ghidra | BasicBlockModel + iteração sobre function.getBody() → blocos, function.getCalledFunctions() → call graph |
✅ Médio |
18. Nomes de Variáveis Globais
O que é: Labels/names atribuídos a endereços de dados globais (ex: g_score, aHelloWorld).
Para que serve: Dar significado a acessos de memória. Transforma mov eax, dword_403000 em mov eax, g_score.
| Engine | API | Viabilidade |
|---|---|---|
| IDA 5 | Iterar segmentos de dados e usar Name(ea) + isData(GetFlags(ea)) |
✅ Médio |
| IDA 7 | ida_name.get_name_list(), ida_bytes.is_data() |
✅ Fácil |
| Ghidra | program.getSymbolTable().getGlobalSymbols(), listing.getDataAt() |
✅ Fácil |
Prioridades Recomendadas
- Entry point + Tipo de xref + Flags — baixo esforço, alto valor, fecha o básico
- Strings + Imports — esforço médio, altíssimo valor para entendimento do binário
- Segmentos + Tamanho da função — baixo esforço, enriquece o contexto
- Decompilação (Ghidra/IDA 7) — esforço médio, é o grande diferencial vs IDA 5
- Frame + Variáveis globais — enriquece a visualização de cada função
- Call graph / CFG — habilita visualização gráfica no frontend
- Tipos + Estruturas — depende muito da engine, menor prioridade