Go Standard Library: debug/*

Brief Review

Previously, we introduced the structure and purpose of ELF file headers, program header tables, section header tables, and common sections. We also covered the structure and purpose of symbols, symbol tables (.symtab), and string tables (.strtab). Building on this foundation, rather than getting bogged down in the complex details of linking, relocation, and loading, we systematically organized these topics by drawing from numerous technical resources to explain the intricacies of linkers, relocation, and loaders.

I firmly believe that clearly explaining this information and deepening everyone's understanding will help us avoid pitfalls when developing debuggers.

At this point, I trust readers no longer feel intimidated by ELF files. We've covered so much ground partly to address your concerns and deepen understanding, but also to build confidence in binary analysis and debugger development. In fact, I place more emphasis on building confidence - we are like armored warriors, full of confidence and ready for battle.

Go Standard Library

We are developing a debugger for Go programs using Go language. After covering many system principles, technical details, and examples from other languages, we ultimately return to the question of how to implement this in Go.

The first challenge is how to parse ELF files, including parsing ELF headers, program/section header tables, and data in common sections like debugging information in .debug_* sections.

The Go standard library provides tools to simplify these tasks, which we'll examine next.

The Go standard library package debug/* is specifically designed for reading and parsing ELF file information generated by the Go compilation toolchain:

  • debug/elf supports reading and parsing ELF files, providing methods to locate sections by name
  • debug/gosym supports parsing .gosymtab symbol tables and .gopclntab line number tables. By design, .gopclntab records stack frame sizes corresponding to PC values through pcsp, making it easy to locate return addresses and further determine callers. Repeating this process allows tracking goroutine call stack information, like stacktrace information printed during panics
  • debug/dwarf supports reading and parsing DWARF data in both compressed (.debug*) and uncompressed (.zdebug) formats

Notes on non-ELF related packages under debug:

  • macOS executables and object files don't use the common Unix/Linux ELF format, but rather the Mach-O format. Package debug/macho is for parsing Mach-O format
  • Windows executables and object files use the PE format, with debug/pe for parsing PE format
  • The plan9obj format is special, originating from the Plan 9 distributed operating system project. debug/plan9obj parses this plan9obj format

It's worth noting that while Go's final output on Linux is in ELF format, the intermediate .o object files don't use ELF but rather a modified version of the plan9obj format. If readers want to examine Go's object file format, its definition and parsing implementation can be found in "cmd/internal/goobj/objfile.go". However, since this package is under internal directory and only accessible to packages under cmd/, you'll need to write your own tools to properly read Go's .o object file format. There are similar projects on GitHub for reference, see hitzhangjie/codemaster/debug.

In the following sections, we'll introduce the usage of these packages and understand how they help in developing symbolic debuggers.

References:

  1. How to Fool Analysis Tools, https://tuanlinh.gitbook.io/ctf/golang-function-name-obfuscation-how-to-fool-analysis-tools
  2. Go 1.2 Runtime Symbol Information, Russ Cox, https://docs.google.com/document/d/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o/pub
  3. Some notes on the structure of Go Binaries, https://utcc.utoronto.ca/~cks/space/blog/programming/GoBinaryStructureNotes
  4. Building a better Go Linker, Austin Clements, https://docs.google.com/document/d/1D13QhciikbdLtaI67U6Ble5d_1nsI4befEd6_k1z91U/view
  5. Time for Some Function Recovery, https://www.mdeditor.tw/pl/2DRS/zh-hk

results matching ""

    No results matching ""