Skip to content

Instantly share code, notes, and snippets.

@rolandshoemaker
Last active November 20, 2021 11:17
Show Gist options
  • Save rolandshoemaker/1ac463a589f24830940e89ab2333280c to your computer and use it in GitHub Desktop.
Save rolandshoemaker/1ac463a589f24830940e89ab2333280c to your computer and use it in GitHub Desktop.
# Ghidra script for re-populating (naively) stripped function names from
# Go >1.2 binaries using the pclntab. Should work with both the initial
# 1.2 format pclntab as well as the 1.16 format.
#
# Author: roland@golang.org
from ghidra.program.model.symbol.SourceType import *
start = None
for section in getMemoryBlocks():
if section.getName() == ".gopclntab":
start = section.getStart()
end = section.getEnd()
break
if start == None:
raise Exception(".gopclntab section missing")
# pointer size and number of entries in the function table
# are the same for 1.2 and 1.16 binaries
ptr_size_address = start.add(7)
ptr_size = getByte(ptr_size_address)
functab_num_addr = start.add(8)
functab_num = getInt(functab_num_addr)
# my memories of python are quite stale, there is probably a more
# idiomatic way of doing this
go12magic = bytearray(b'\xfb\xff\xff\xff')
go116magic = bytearray(b'\xfa\xff\xff\xff')
magic = bytearray(getBytes(start, 4))
# find the function table, function data table, and function name table
# addresses for 1.2 and 1.16 binaries
funcnametab_addr, functab_addr, funcdata_addr = None, None, None
if magic == go116magic:
funcnametab_offset_addr = start.add(8 + 2 * ptr_size)
funcnametab_offset = getInt(funcnametab_offset_addr)
funcnametab_addr = start.add(funcnametab_offset)
functab_offset_addr = start.add(8 + 6 * ptr_size)
functab_offset = getInt(functab_offset_addr)
functab_addr = funcdata_addr = start.add(functab_offset)
elif magic == go12magic:
funcnametab_addr = start
functab_addr = start.add(8 + ptr_size)
funcdata_addr = start
else:
raise Exception("magic bytes are neither 1.2 nor 1.16")
# iterate through the function table
for i in range(functab_num):
offset = 2 * ptr_size * i
func_addr = currentProgram.getAddressFactory().getDefaultAddressSpace(
).getAddress(hex(getInt(functab_addr.add(offset))))
info_offset = getInt(functab_addr.add(offset+ptr_size))
name_offset = getInt(funcdata_addr.add(info_offset).add(ptr_size))
name_addr = funcnametab_addr.add(name_offset)
name = getDataAt(name_addr)
if name is not None:
func = getFunctionAt(func_addr)
if func is not None:
func.setName(name.getValue().replace(" ", ""), USER_DEFINED)
else:
func = createFunction(func_addr, name.getValue())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment