
Analisa binários Go para recuperar símbolos, metadados de funções, tipos, caminhos de ficheiros e strings incorporadas, incluindo amostras stripped ou empacotadas com UPX, com suporte de importação para o IDA Pro.

GoReSym é um analisador de símbolos Go que extrai metadados do programa (como arquitetura de CPU, SO, endianness, versão do compilador, etc.), metadados de funções (endereços de início e fim, nomes, fontes), metadados de nome de arquivo e número de linha, e estruturas e tipos incorporados. Este programa multiplataforma é baseado diretamente no compilador Go de código aberto e no código do runtime.
O código do runtime Go upstream é estendido para lidar com:
moduledataConsulte https://www.mandiant.com/resources/blog/golang-internals-symbol-recovery para detalhes de engenharia reversa e exemplos de uso.
Você pode baixar binários GoReSym pré-compilados para linux, macos e windows na aba Releases.
Para compilar a partir do código-fonte com um compilador Go recente, invoque o compilador Go:
go build
Uma vez compilado, invoque o GoReSym assim:
GoReSym.exe -t -d -p /path/to/input.exe
Neste exemplo, pedimos ao GoReSym para recuperar nomes de tipos (-t), nomes de pacotes do usuário, nomes de pacotes padrão do Go (-d) e caminhos de arquivos de entrada (-p) incorporados no arquivo /path/to/input.exe. A saída é semelhante a esta:
{
"Version": "1.14.15",
"BuildId": "Zb9QmokKTiOUgHKmaIwz/wd2rtE3W9PN-um1Ocdzh/qTdqcTY_jVajHy_-TtYv/Z_kJu9M77OjfijEiHMcF",
"Arch": "amd64",
"TabMeta": {
"VA": 5174784,
"Version": "1.2",
"Endianess": "LittleEndian",
"CpuQuantum": 1,
"CpuQuantumStr": "x86/x64",
"PointerSize": 8
},
"ModuleMeta": {
"VA": 5678816,
"Types": 4845568,
"ETypes": 5171904,
"Typelinks": {
"Data": 5171904,
"Len": 695,
"Capacity": 695
},
"ITablinks": {
"Data": 5174688,
"Len": 11,
"Capacity": 11
},
"LegacyTypes": {
"Data": 0,
"Len": 0,
"Capacity": 0
}
},
"Types": [ ... ],
"Files": [ ... ],
"Strings": [ ... ],
"UserFunctions": [ ... ],
"StdFunctions": [ ... ]
}
Aqui estão todas as flags disponíveis:
-d ("default", opcional) imprimirá os pacotes Go padrão, além dos pacotes do usuário.-p ("paths", opcional) imprimirá quaisquer caminhos de arquivo incorporados no pclntab.-t ("types", opcional) imprimirá os nomes dos tipos Go.-strings (opcional) extrairá strings Go incorporadas do binário analisando a tabela de internamento de strings.-m <virtual address> ("manual", opcional) despejará a estrutura RTYPE recursivamente no endereço virtual fornecido-v <version string> ("version", opcional) substituirá a detecção automatizada de versão e usará a versão fornecida. Isso é necessário para alguns binários removidos (stripped). A análise de tipos falhará se a versão não for precisa.-human (opcional) imprimirá uma listagem em texto simples em vez de JSON. Especialmente útil ao imprimir tipos de estrutura e interface.-about (opcional) imprimirá as informações de licençaPara importar essas informações para o IDA Pro, você pode executar o script encontrado em https://github.com/mandiant/GoReSym/blob/master/IDAPython/goresym_rename.py. Ele lerá um arquivo json produzido pelo GoReSym e definirá símbolos/rótulos no IDA.
Como o compilador e o runtime do Go mudaram, as estruturas de metadados incorporadas também mudaram. O GoReSym suporta as seguintes combinações de versões do Go e metadados:
pclntab: >= Go 1.2moduledata: >= Go 1.2moduledata: >= Go 1.5A tabela moduledata usada para extrair tipos não existe antes do Go 1.5, portanto esta biblioteca nunca suportará a extração de tipos de versões muito antigas do Go.
Esta biblioteca atualmente lida com os layouts de pclntab anteriores a 1.2, 1.2, 1.16, 1.18 e 1.20. Observe que a versão do pclntab é sempre <= a versão do runtime do Go (ex: o runtime Go 1.19 usa o layout de pclntab 1.18); nosso objetivo é sempre suportar as versões mais recentes do runtime.
Grande parte do código-fonte do GoReSym é copiado do diretório de código-fonte do compilador Go upstream /internal. Para que isso funcionasse, tivemos que ajustar um pouco o código-fonte. Se você quiser contribuir com o GoReSym, continue lendo para que possamos explicar esse processo de importação.
Devido à forma como os pacotes Go funcionam, precisamos remover o caminho /internal da árvore de arquivos de origem. Isso resultou em muita cópia de arquivos internos do Go, onde a árvore de diretórios permanece em grande parte intacta, mas com pequenas alterações nas importações de muitos arquivos: referências a caminhos /internal foram substituídas por github.com/mandiant/GoReSym/.
Também modificamos muitas estruturas internas para exportar campos e métodos. Estes não são exportados pelo Go upstream porque os usuários não devem depender deles. No entanto, o propósito desta ferramenta é extrair informações internas, então estamos assumindo a tarefa de manter essas estruturas. Não é uma situação ideal, mas não é facilmente evitável. Se você atualizar este repositório, deve tomar cuidado para manter essas modificações intactas. Provavelmente é melhor mesclar manualmente os commits do upstream em vez de copiar os arquivos do upstream integralmente.
Estou aberto a sugestões sobre como estruturar melhor este projeto para evitar esses problemas enquanto ainda compila com o típico go build. Há uma discussão anterior envolvendo os mantenedores do Go aqui.
Ignorando algumas alterações triviais, a maior parte da nova lógica existe em /objfile. Por exemplo, o arquivo objfile/internals define as estruturas internas reversas do Go que o GoReSym analisa.
pclntab: golang.org/s/go12symtabpclntab: pclntab.go#L169objfile:
buildID: golang/go#50809