Some notes, tools, and techniques for reverse engineering Golang binaries.
- https://go-re.tk/
-
A Reverse Engineering Tool Kit for Go, Written in Go.
-
The Go Reverse Engineering Tool Kit (go-re.tk) is a new open-source toolset for analyzing Go binaries. The tool is designed to extract as much metadata as possible from stripped binaries to assist in both reverse engineering and malware analysis.
- https://go-re.tk/gore/
-
GoRE is the core of Go Reverse Engineering Tool Kit. It is a library written in Go that provides functionality to analyze binaries produced by the Go compiler.
- https://github.com/goretk/gore
-
GoRE - Package gore is a library for analyzing Go binaries
-
-
- https://go-re.tk/libgore/
-
Libgore
-
Libgore is a dynamic C-library for interacting with GoRE. It is using cgo to produce a translation layer between the code written in Go and the exported C functions. With this library, it is possible to write bindings for other languages that have C foreign function interface (FFI) support. PyGoRE uses this dynamic library to provide a Python library that can be used to write tools in Python.
- https://github.com/goretk/libgore
-
Libgore - Open up GoRE to other languages
-
-
- https://go-re.tk/pygore/
-
PyGoRE
-
Python library for analyzing Go binaries
-
PyGoRE is a simple to use Python library for analyzing Go binaries compiled with Go compiler.
- https://github.com/goretk/pygore
-
pyGoRE - Python library for analyzing Go binaries
-
-
- https://go-re.tk/redress/
-
Redress
-
A tool for analyzing stripped binaries
-
The redress software is a tool for analyzing stripped Go binaries compiled with the Go compiler. It extracts data from the binary and uses it to reconstruct symbols and performs analysis. It essentially tries to “re-dress” a “stripped” binary.
- https://github.com/goretk/redress
-
Redress - A tool for analyzing stripped Go binaries
- goretk/redress#32
-
add to homebrew package manager (macOS)
- Homebrew/homebrew-core#155724
-
redress 1.1.1 (new formula)
-
-
- goretk/redress#33
-
add a 'strings' command
-
-
-
-
- https://github.com/mandiant/GoReSym
-
GoReSym is a Go symbol parser that extracts program metadata (such as CPU architecture, OS, endianness, compiler version, etc), function metadata (start & end addresses, names, sources), filename and line number metadata, and embedded structures and types. This cross platform program is based directly on the open source Go compiler and runtime code.
The upstream Go runtime code is extended to handle:
- stripped binaries
- malformed unpacked binaries, such as from UPX
- binaries that split single data ranges across multiple sections
- the location of the
moduledata
structure
- mandiant/GoReSym#44
-
Build release packages for linux/windows/macOS + add to homebrew package manager (macOS)
- Homebrew/homebrew-core#155716
-
goresym 2.6.3 (new formula)
-
-
- mandiant/GoReSym#45
-
add a 'strings' command
-
-
- https://www.mandiant.com/resources/blog/golang-internals-symbol-recovery
-
Ready, Set, Go — Golang Internals and Symbol Recovery
-
Golang (Go) is a compiled language introduced by Google in 2009. The language, runtime, and tooling has evolved significantly since then. In recent years, Go features such as easy-to-use cross-compilation, self-contained executables, and excellent tooling have provided malware authors with a powerful new language to design cross-platform malware. Unfortunately for reverse engineers, the tooling to separate malware author code from Go runtime code has fallen behind.
Today, Mandiant is releasing a tool named GoReSym to parse Go symbol information and other embedded metadata. This blog post will discuss the internals of relevant structures and their evolution with each language version. It will also highlight challenges faced when analyzing packed, obfuscated, and stripped binaries.
-
In addition to the runtime code, the compiler also embeds metadata about the source code and its binary layout to support language features, the runtime, and debug tooling.
Some of this embedded information has been thoroughly documented, namely the pclntab, moduledata, and buildinfo structures. Each of these structures has seen major changes as Go has evolved. This evolution, combined with common obfuscator or packing tricks, can make type recovery trickier than expected. To effectively handle ever-changing runtime structures, GoReSym is based on the Go runtime source code to transparently handle all runtime versions. This makes supporting new Go versions trivial. We can also be more confident in edge cases since GoReSym uses the same parsers as the runtime.
-
The
pclntab
structure is short for “Program Counter Line Table”. The table is used to map a virtual memory address back to the nearest symbol name to generate stack traces with function and file names. For symbol recovery purposes, the pclntab is important because it stores function names, function start and end addresses, file names, and more. -
When a Go binary is stripped, the
.symtab
symbol table is zeroed out or not present. This removes the ability to find symbols such as runtime.pclntab. However, the data those symbols point to, such as thepclntab
itself, is still present in the binary. For ELF and Mach-O files, the named sections (e.g.,.gopclntab
) are also still present and can be used to locate thepclntab. Therefore, manual location of the
pclntab` for both stripped and unstripped binaries can be performed -
The moduledata structure is an internal runtime table that stores information about the layout of the file as well as runtime information used to support core features such as garbage collection and reflection. Unlike the
pclntab
, this structure cannot be found via symbols. Its layout also changes much more frequently. -
Starting in Go 1.18, additional metadata is provided in a table named buildinfo. This table is emitted by default but can be easily omitted with compiler flags. When present, the table can provide the following: compiler and linker flags, values of the environment variables
GOOS
andGOARCH
, git information, and information about the package name of both the main and dependency packages. -
GoReSym is a standalone application that can be executed on the command line or incorporated into a larger batch processing script. It doesn’t perform additional binary analysis outside of Go’s symbols. As a result, data extraction typically finishes in 1-5 seconds for even the most complex binaries.
By default, GoReSym prints concise output instead of all extracted information. Various flags can be used to alter GoReSym's behavior. The
-t
flag instructs GoReSym to emit type and interface lists, which are useful when reversing channels and other routines that accept types. -
There are public and commercial tools that support some, or perhaps all, of the type parsing logic addressed in GoReSym. Prior works such as Redress and IDAGolangHelper are excellent and should be celebrated. The primary difference between GoReSym and existing tools is that GoReSym is based on the Go runtime source code. This helps counter the rapid pace of Go internal structure evolution. Additionally, because the runtime is already cross-architecture, GoReSym is too. All new parsing logic takes care to correctly support 32 and 64-bit big and little-endian architectures. Care was also taken to handle unpacked or partially corrupted samples where possible, something other tools may struggle with. Overall, GoReSym is designed to work in cases where other tools fail and offers a way to ease tool maintenance as Go evolves.
-
- https://vik0t0r.github.io/posts/Gopherjs-reverse-engineering/
-
Gopherjs reverse engineering
- https://vik0t0r.github.io/posts/Gopherjs-reverse-engineering/#vscode-extension
- https://github.com/vik0t0r/gopherjsre
-
gopherjsRE
is an attempt to make analysis of gopherjs produced files easier - vik0t0r/gopherjsre#1
-
Consider using wakaru and/or webcrack to help with unminifying
-
-
- https://github.com/vik0t0r/gopherjsre
- https://github.com/gopherjs/gopherjs
-
A compiler from Go to JavaScript for running Go code in a browser
- https://gopherjs.github.io/playground/
-
- pionxzh/wakaru#92
-
support GopherJS bundles
-
- j4k0xb/webcrack#39
-
support GopherJS bundles
-
-
- https://github.com/ivision-research/gostringsr2
-
Find strings in Go binaries
-
gostringsr2
gostringsr2
extracts strings from a Go binary usingradare2
-
- https://github.com/W3ndige/binjago
-
Set of tools aiding in analysis of stripped Golang binaries with Binary Ninja
-
- https://github.com/d-we/binja-golang-symbol-restore
-
Golang Symbol Restore (v1.2) Binary Ninja plugin for restoring function names from stripped Golang binaries.
-
The plugin parses the section
.gopclntab
where Golang stores debug symbols and restores the function names. If there is no section named.gopclntab
it will try to search for the section.
-
- https://github.com/f0rki/bn-goloader
-
GO Loader Assist (v1.1) go reversing helpers for binaryninja
-
Basically this is some stuff ported from the IDA pro script
golang_load_assist
-
- https://github.com/felberj/gotools
-
Go Plugin for Ghidra Plugin to assist reversing Golang binaries with Ghidra. This is in a VERY early stage and for now only handles linux/x86_64 binaries.
-
- https://github.com/strazzere/golang_loader_assist
-
Making GO reversing easier in IDA Pro
-
golang_loader_assist.py
This is the golang_loader_assist.py code to accompany the blog I wrote, Reversing GO binaries like a pro (in IDA Pro). There is also the hello-go directory which contains the simple hello world code I used as an example.
-
- https://github.com/sibears/IDAGolangHelper
-
Set of IDA Pro scripts for parsing GoLang types information stored in compiled binary
-
This is update for https://gitlab.com/zaytsevgu/GoUtils2.0
-
- https://gitlab.com/zaytsevgu/goutils
-
A set of useful scripts for reversing golang binaries in IDA
-
renamer.py
This script is used to restore function names in stripped go binary -
typeinfo.py
Script for restoring information about types used in binary. - https://gitlab.com/zaytsevgu/GoUtils2.0
-
Rewriting https://gitlab.com/zaytsevgu/goutils for easier use Moved to https://github.com/sibears/IDAGolangHelper
-
-
- https://binary.ninja/2020/12/02/deobfuscation-of-gobfuscate-golang-binaries.html
-
Deobfuscation of
gobfuscate
Golang binaries across multiple architectures - https://www.kryptoslogic.com/blog/2020/12/automated-string-de-gobfuscation/
-
Automated string de-gobfuscation
-
- https://github.com/unixpickle/gobfuscate
-
Obfuscate Go binaries and packages
-
-
- https://gist.github.com/alexander-hanel/59af86b0154df44a2c9cebfba4996073
-
Go Lang Reverse Engineering Resources/Links
-
- https://www.grant.pizza/dissecting-go-binaries/
-
Dissecting Go Binaries
-
- https://medium.com/a-journey-with-go/go-overview-of-the-compiler-4e5a153ca889
-
Go: Overview of the Compiler
-
- https://eli.thegreenplace.net/2019/go-compiler-internals-adding-a-new-statement-to-go-part-1/
-
Go compiler internals: adding a new statement to Go - Part 1
-
- https://eli.thegreenplace.net/2019/go-compiler-internals-adding-a-new-statement-to-go-part-2/
-
Go compiler internals: adding a new statement to Go - Part 2
-
- https://rednaga.io/2016/09/21/reversing_go_binaries_like_a_pro/
-
Reversing GO binaries like a pro
- https://github.com/strazzere/golang_loader_assist
-
Making GO reversing easier in IDA Pro
-
golang_loader_assist.py
This is the golang_loader_assist.py code to accompany the blog I wrote, Reversing GO binaries like a pro (in IDA Pro). There is also the hello-go directory which contains the simple hello world code I used as an example.
-
-
- https://getstream.io/blog/how-a-go-program-compiles-down-to-machine-code/
-
How a Go Program Compiles down to Machine Code
-
- https://www.pnfsoftware.com/blog/analyzing-golang-executables/
-
Analyzing Golang Executables
-
In this blog post, we dive into Golang executables reverse engineering, and present a Python extension for JEB decompiler to ease Golang analysis
- https://github.com/pnfsoftware/jeb-golang-analyzer
-
JEB scripts for Golang executables analysis
- https://www.pnfsoftware.com/jeb/manual/dev/introducing-jeb-extensions/#executing-scripts
-
-
- https://go-re.tk/
-
Go Reverse Engineering Tool Kit
-
- https://cmc.gitbook.io/go-internals/
-
go-internals book
-
- http://home.in.tum.de/~engelke/pubs/1709-ma.pdf
-
Reconstructing Program Semantics from Go Binaries
-
Department of Informatics Technical University of Munich Master’s Thesis in Informatics Reconstructing Program Semantics from Go Binaries Alexis Engelke
-
- https://dr-knz.net/go-calling-convention-x86-64.html
-
The Go low-level calling convention on x86-64
-
- https://www.altoros.com/blog/golang-internals-part-1-main-concepts-and-project-structure/
-
Golang Internals (1 of 6)
-
- https://lekstu.ga/tags/go/
-
Go Series by Joakim Kennedy
-
- https://web.archive.org/web/20211129024951/https://lekstu.ga/tags/go/
-
- https://web.archive.org/web/20211129034538/https://lekstu.ga/posts/redress-v1/
-
Redress v1.0.0 Released (October 25, 2021)
-
It’s been over two years since the first public release of redress and a lot has changed since then. Redress has finally reached version 1.0. This release includes many surface and under the hood changes. One of the obvious changes is the user interface which has been rewritten to make it easier to use.
The Go Reverse Engineering Tool Kit (GoRE) has had a lot of improvements during the last few months and redress is taking advantage of these improvements.
- https://github.com/goretk/redress
-
Redress - A tool for analyzing stripped Go binaries
-
The redress software is a tool for analyzing stripped Go binaries compiled with the Go compiler. It extracts data from the binary and uses it to reconstruct symbols and performs analysis. It essentially tries to "re-dress" a "stripped" binary.
-
- https://github.com/goretk/redress
-
- https://web.archive.org/web/20210422112349/https://lekstu.ga/posts/go-inline-code/
-
Tackle Inline Go Functions (January 2, 2021)
-
- https://web.archive.org/web/20230604010044/https://lekstu.ga/posts/go-under-the-hood-orthrus/
-
Go Under the Hood: Orthrus (March 23, 2020)
-
- https://web.archive.org/web/20220120014138/https://lekstu.ga/posts/go-under-the-hood-eris/
-
Go Under the Hood: Eris Ransomware (October 6, 2019)
-
- https://web.archive.org/web/20211129031530/https://lekstu.ga/posts/pclntab-function-recovery/
-
Time For Some Function Recovery (June 23, 2019)
-
Binaries compiled with the Go compiler includes a large set of metadata. This metadata can be used to assist static analysis of stripped binaries. Stripped binaries, especially statically compiled, are hard to analyze. Since the symbols have been removed and the huge number of subroutines, hello world binary in Go have thousands of subroutines, it can be very time-consuming. Fortunately, the metadata in the binary can be used to reconstruct symbols and also recover information about the source code layout. One of the things that can be recovered is function information.
-
The
pclntab
has many uses in a Go binary. One of its uses is for the runtime to produce meaning full stack traces in the case of a panic. The table holds valuable information about functions that can be used to analyze unknown stripped binaries compiled by the Go compiler. For ELF binaries, the table is located in its own sections while for PE files it needs to be searched for. Once it has been located, the Go standard library provides functions to process and extract the data from the table. With this data, it is possible to reconstruct an overview of the source code tree structure. This information can be used to group binaries that have been compiled from the same source code but to different architectures and operating systems since this data should be identical.
-
- https://web.archive.org/web/20211129024919/https://lekstu.ga/posts/hello-moduledata/
-
Say Hello to Moduledata (June 16, 2019)
-
The
moduledata
structure is a data table that was first introduced in version 1.5 of Go. It is a structure that holds important information that is needed when you statically analyzing Go binaries. It records information about the layout of the executable. For ELF binaries, the structure can be found in the.noptrdata
section. In PE files it is much harder to find. Sometimes it is located in the.text
section and sometimes it is in the.data
section. If the binary has been stripped there is no symbol pointing to the structure. In these scenarios, a brute-force search is needed. To know what we should search for, we need first know what the structure looks like.
-
- https://web.archive.org/web/20211129034538/https://lekstu.ga/posts/redress-v1/
-
- https://www.grant.pizza/dissecting-go-binaries/
-
I add some of my resources:
- https://pkg.go.dev/
- goroutine functions refer here
- https://www.sentinelone.com/labs/alphagolang-a-step-by-step-go-malware-reversing-methodology-for-ida-pro/
-
AlphaGolang | A Step-by-Step Go Malware Reversing Methodology for IDA Pro
- https://github.com/SentineLabs/AlphaGolang
-
AlphaGolang IDApython Scripts for Analyzing Golang Binaries
-
AlphaGolang is a collection of IDAPython scripts to help malware reverse engineers master Go binaries. The idea is to break the scripts into concrete steps, thus avoiding brittle monolithic scripts, and mimicking the methodology an analyst might follow when tackling a Go binary.
Scripts are released under GPL license (honoring Tim Strazzere's original GolangLoaderAssist which we refactored and updated for python3, props to Tim :) ). Contributions are welcome and encouraged!
Requirements: IDA Pro (ideally v7.6+) and Python3 (ew) The first two steps (
recreate_pclntab
andfunction_discovery_and_renaming
) will work on IDA v7.5- but scripts beyond that require IDAv7.6+. Newer versions are the ideal target for newer scripts going forward.
-
-
- https://cujo.com/blog/reverse-engineering-go-binaries-with-ghidra/
-
Reverse Engineering Go Binaries with Ghidra
- https://github.com/getCUJO/ThreatIntel/tree/master/Scripts/Ghidra
-
Ghidra Scripts A set of Ghidra scripts for reverse engineering.
-
- https://github.com/getCUJO/ThreatIntel/tree/master/Research_materials/Golang_reversing
-
Golang_reversing Repository for files related to our research on reverse engineering Go binaries
-
-
- https://www.youtube.com/watch?v=wWNbnEp_4ZE
-
Anatomy of a Gopher: Binary Analysis of Go Binaries w/ Alex Useche - SANS HackFest Summit 2020
-
- https://www.youtube.com/watch?v=J2svN8h21oo
-
Reversing GO Binaries With Ghidra - Albert Zsigovits and Dorka Palotay
-
- https://www.youtube.com/watch?v=_cL-OwU9pFQ
-
Reversing in action: Golang malware used in the SolarWinds attack. Part 1
-
- https://www.youtube.com/watch?v=YRqTrq11ebg
-
Reversing in action: Golang malware used in the SolarWinds attack. Part 2
-
- https://medium.com/@nishanmaharjan17/reversing-golang-binaries-part-1-c273b2ca5333
-
Reversing Golang Binaries: Part-1
-
In this blog I will attempt to understand and share my understanding of how go binaries look when compiled and then disassembled. I used x64 i5 and windows 10 as my platform and used IDA as disassembler. I will attempt to look at how the functionality of the compiled go programs look like and will not dwell in the functions added by the compiler itself.
-
- https://medium.com/@nishanmaharjan17/reversing-golang-binaries-part-2-26f522264d01
-
Reversing Golang Binaries: Part-2
-
In the previous article I Disassembled a simple password validator go program. In this one lets go a big bigger. I will try to reverse a simple golang server using IDA.
-
- https://medium.com/@nishanmaharjan17/reversing-golang-binaries-part-3-how-to-run-a-golang-ransomware-613f5369cbaa
-
Reversing Golang Binaries: Part-3 (How to run a golang ransomware :)
-
- https://blog.osiris.cyber.nyu.edu/2019/12/19/go-deepdive/
-
Reverse Engineering Go, Part I
-
This will be part of a multi-part post on Go binaries and reverse engineering them.
-
- https://blog.osiris.cyber.nyu.edu/2019/12/19/ugo-ghidra-plugin/
-
Reverse Engineering Go, Part II
-
This post is on how the Ghidra decompiler works, and how to make it work for Go.
-
- https://pkg.go.dev/
-
- GitHub Copilot CLI API (0xdevalias' gist)
- Reverse Engineering on macOS (0xdevalias' gist)
- https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts.
- Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias' gist)
- Reverse Engineering Webpack Apps (0xdevalias' gist)
- Reverse Engineered Webpack Tailwind-Styled-Component (0xdevalias' gist)
- React Server Components, Next.js v13+, and Webpack: Notes on Streaming Wire Format (
__next_f
, etc) (0xdevalias' gist)) - Fingerprinting Minified JavaScript Libraries / AST Fingerprinting / Source Code Similarity / Etc (0xdevalias' gist)
- Bypassing Cloudflare, Akamai, etc (0xdevalias' gist)
- Debugging Electron Apps (and related memory issues) (0xdevalias gist)
- devalias' Beeper CSS Hacks (0xdevalias' gist)