Last active
November 20, 2021 11:17
-
-
Save rolandshoemaker/1ac463a589f24830940e89ab2333280c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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