Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
r2gopclntabParser — A radare2 script to parse the gopclntab to facilitate Reverse Engineering Go binaries. | Kitploit
Tools/GitHubGitHub/asherdll/r2gopclntabparser
Static AnalysisReverse EngineeringDebuggersForensicsMalware AnalysisBinary Analysis
GitHubasherdll/r2gopclntabparser

r2gopclntabParser

A radare2 script to parse the gopclntab to facilitate Reverse Engineering Go binaries.

View Repository
17316 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

r2gopclntabParser

Note: This feature has been implemented directly to radare2's core as gopc analysis plugin

A radare2-based Go gopclntab parser for recovering function symbols from Go binaries, including fully stripped ones. Supports ELF, Mach-O, and PE binaries across Go versions 1.2, 1.16, 1.18, and 1.20+.

Every Go 1.2+ binary embeds a data region called gopclntab (Program Counter Line Table) that the Go runtime uses for stack traces, panic messages, garbage collection, and debugger support. It is one of the most valuable source of symbol information in Go binaries.

r2gopclntabParser reads this region through radare2, parses the version-specific structures, and either prints the recovered function list (with addresses, source files, and line numbers) or applies the recovered names back into the open radare2 session as function definitions, flags, and comments.


Table of Contents

  • Prerequisites
  • Quick Start
  • CLI Reference
  • Output Modes and Examples
    • Default Mode (Header + Function List)
    • Verbose Mode (-v)
    • Search Mode (-n)
    • JSON Output (--json)
    • Source File Listing (--files)
    • Apply Mode (--apply)
  • Results Summary: Mach-O (Stripped Test Binary)
  • PE Test: Greenblood, a Go Ransomware Binary
  • Use Cases for Reverse Engineering
  • Supported Platforms and Go Versions
  • Methodology
    • Section Location Strategy
    • textStart vs .text Section
    • Version-Aware Struct Parsing
    • PC Data Decoding
  • Limitations
  • Additional Documentation
  • References

Prerequisites

| Dependency | Minimum Version | |---|---|---| | Python 3 | 3.8+ | | radare2 | 5.0+ (tested on 6.0.9) | | r2pipe | any |

No other Python packages are required. The script uses only the standard library (struct, json, argparse, os, sys) plus r2pipe.


Quick Start

# List all functions recovered from a Go binary
python3 r2_gopclntab.py -f ./mybinary -l

# Search for a specific function (substring match)
python3 r2_gopclntab.py -f ./mybinary -n main.main

# Verbose header + function list
python3 r2_gopclntab.py -f ./mybinary -v -l

# Apply recovered names into an r2 session
python3 r2_gopclntab.py -f ./mybinary --apply

# JSON output
python3 r2_gopclntab.py -f ./mybinary --json

# From within r2 (attach to running session)
#!pipe python3 r2_gopclntab.py --r2pipe --apply -v

CLI Reference

usage: r2_gopclntab.py [-h] [-f FILE] [-n FUNCNAME] [-v] [-l]
                       [--apply] [--json] [--files] [--r2pipe]

Required (one of)

FlagDescription
-f FILE, --file FILEPath to the Go binary to analyze. The script spawns its own r2 instance.
--r2pipeAttach to an already-running r2 session (for use inside the r2 console).

Optional

FlagDescription
-l, --listPrint every recovered function with its address.
-n NAME, --funcname NAMEPrint only functions whose name contains NAME (substring match). If an exact match exists, its address is printed separately.
-v, --verbosePrint progress messages, parsed header fields, and internal offsets.
--applyWrite recovered function names into the radare2 session as function definitions (af+), flags in the go. flagspace, and comments with the original Go name and source location.
--jsonOutput the header and full function list as JSON to stdout.
--filesPrint the list of source file paths extracted from the file table.
-h, --helpShow the help message.

Flags can be combined freely. When no output flag is given, the default behavior is to print the header and the full function list.


Output Modes and Examples

All examples below were run against a stripped Go 1.26 Mach-O arm64 binary (built with -ldflags="-s -w"). The test program defines main.main, main.fibonacci, main.helloWorld, and main.addNumbers. The compiler inlined helloWorld and addNumbers, so they do not appear in the gopclntab.

Default Mode (Header + Function List)

Running with no flags (or just -f) prints the parsed header followed by the full function table:

$ python3 r2_gopclntab.py -f ./gotest_stripped
============================================================
  Go pclntab Header
============================================================
  Magic:           0xFFFFFFF1
  Go version:      1.20+
  Pointer size:    8
  Min LC (quantum):4
  Num functions:   2030
  Num files:       261
  funcnameOffset:  0x48
  cuOffset:        0x14D20
  filetabOffset:   0x158D8
  pctabOffset:     0x19A98
  pclnOffset:      0x55E40
============================================================

ADDRESS       FUNCTION NAME
----------------------------------------------------------------------
0x100001000   go:buildid
0x100001070   internal/abi.BoundsDecode  (/opt/homebrew/Cellar/go/1.26.1/libexec/src/internal/abi/bounds.go:86)
0x100001150   internal/abi.NoEscape  (/opt/homebrew/Cellar/go/1.26.1/libexec/src/internal/abi/escape.go:19)
0x100001160   internal/abi.Kind.String  (/opt/homebrew/Cellar/go/1.26.1/libexec/src/internal/abi/type.go:143)
0x1000011E0   internal/abi.TypeOf  (/opt/homebrew/Cellar/go/1.26.1/libexec/src/internal/abi/type.go:181)
0x1000011F0   internal/abi.(*Type).ExportedMethods  (/opt/homebrew/Cellar/go/1.26.1/libexec/src/internal/abi/type.go:453)
...
0x1000A0BB0   main.fibonacci  (/tmp/gotest/main.go:13)
0x1000A0C20   main.main  (/tmp/gotest/main.go:20)
0x1000A0D20   go:textfipsstart
0x1000A0D30   go:textfipsend

[+] 2030 function(s) shown

Verbose Mode (-v)

Adds section scanning progress, textStart resolution details, and internal offset information:

$ python3 r2_gopclntab.py -f ./gotest_stripped -v
[*] Running radare2 analysis...
[*] Binary format: mach0, endian: little, arch: arm, bits: 64
[*] Scanning binary for gopclntab magic bytes...
[*]   Scanning section '0.__TEXT.__text' (0x100001000, 0x9FD44)...
[*]   Scanning section '1.__TEXT.__symbol_stub1' (0x1000A0D60, 0x2B8)...
[*]   Scanning section '2.__TEXT.__rodata' (0x1000A1020, 0xACC2)...
[*]   Scanning section '3.__TEXT.__gopclntab' (0x1000ABCE8, 0xA48AE)...
[*]   Found magic at vaddr=0x1000ABCE8
[*] Parsed header: PcHeader(magic=0xFFFFFFF1, version=1.20+, ptrSize=8, minLC=4,
    nfunc=2030, nfiles=261, textStart=0x0)
[*] textStart is 0, using .text section vaddr: 0x100001000
[*] Parsed 2030 functions

============================================================
  Go pclntab Header
============================================================
  Magic:           0xFFFFFFF1
  Go version:      1.20+
  ...

Search Mode (-n)

Filters the function list by substring match. If an exact match exists, its address is printed separately.

Substring search for all functions containing main.:

$ python3 r2_gopclntab.py -f ./gotest_stripped -n "main."
ADDRESS       FUNCTION NAME
----------------------------------------------------------------------
0x100041920   runtime.main.func2  (/opt/homebrew/Cellar/go/1.26.1/libexec/src/runtime/proc.go:207)
0x10006CE30   runtime.main.func1  (/opt/homebrew/Cellar/go/1.26.1/libexec/src/runtime/proc.go:174)
0x1000A0BB0   main.fibonacci  (/tmp/gotest/main.go:13)
0x1000A0C20   main.main  (/tmp/gotest/main.go:20)

[+] 4 function(s) shown (filtered from 2030 total)

Exact match search:

Download Tool