Class GoRttiMapper

java.lang.Object
ghidra.app.util.bin.format.golang.structmapping.DataTypeMapper
ghidra.app.util.bin.format.golang.rtti.GoRttiMapper
All Implemented Interfaces:
DataTypeMapperContext, AutoCloseable

public class GoRttiMapper extends DataTypeMapper implements DataTypeMapperContext
DataTypeMapper for golang binaries.

When bootstrapping golang binaries, the following steps are used:

  • Find the GoBuildInfo struct. This struct is the easiest to locate, even when the binary is stripped. This gives us the go pointerSize (probably same as ghidra pointer size) and the goVersion. This struct does not rely on StructureMapping, allowing its use before a DataTypeMapper is created.
  • Create DataTypeMapper
  • Find the runtime.firstmoduledata structure.
    • If there are symbols, just use the symbol or named memory block.
    • If stripped:
      • Find the pclntab. This has a magic signature, a pointerSize, and references to a couple of tables that are also referenced in the moduledata structure.
      • Search memory for a pointer to the pclntab struct. This should be the first field of the moduledata structure. The values that are duplicated between the two structures can be compared to ensure validity.
      • Different binary formats (Elf vs PE) will determine which memory blocks to search.
  • Field Details

    • SUPPORTED_MIN_VER

      public static final GoVer SUPPORTED_MIN_VER
    • SUPPORTED_MAX_VER

      public static final GoVer SUPPORTED_MAX_VER
    • ARTIFICIAL_RUNTIME_ZEROBASE_SYMBOLNAME

      public static final String ARTIFICIAL_RUNTIME_ZEROBASE_SYMBOLNAME
      See Also:
  • Constructor Details

    • GoRttiMapper

      public GoRttiMapper(Program program, int ptrSize, Endian endian, GoVer goVersion, ResourceFile archiveGDT) throws IOException, BootstrapInfoException
      Creates a GoRttiMapper using the specified bootstrap information.
      Parameters:
      program - Program containing the go binary
      ptrSize - size of pointers
      endian - Endian
      goVersion - version of go
      archiveGDT - path to the matching golang bootstrap gdt data type file, or null if not present and types recovered via DWARF should be used instead
      Throws:
      IOException - if error linking a structure mapped structure to its matching ghidra structure, which is a programming error or a corrupted bootstrap gdt
      BootstrapInfoException - if there is no matching bootstrap gdt for this specific type of golang binary
  • Method Details

    • getSharedGoBinary

      public static GoRttiMapper getSharedGoBinary(Program program, TaskMonitor monitor)
      Returns a shared GoRttiMapper for the specified program, or null if the binary is not a supported golang binary.

      The returned value will be cached and returned in any additional calls to this method, and automatically closed when the current analysis session is finished.

      NOTE: Only valid during an analysis session. If outside of an analysis session, use getGoBinary(Program) to create a new instance if you need to use this outside of an analyzer.

      Parameters:
      program - golang Program
      monitor - TaskMonitor
      Returns:
      a shared go binary instance, or null if unable to find valid golang info in the Program
    • getGoBinary

      public static GoRttiMapper getGoBinary(Program program) throws BootstrapInfoException, IOException
      Creates a GoRttiMapper representing the specified program.
      Parameters:
      program - Program
      Returns:
      new GoRttiMapper, or null if basic golang information is not found in the binary
      Throws:
      BootstrapInfoException - if it is a golang binary and has an unsupported or unparseable version number or if there was a missing golang bootstrap .gdt file
      IOException - if there was an error in the Ghidra golang rtti reading logic
    • getGDTFilename

      public static String getGDTFilename(GoVer goVer, int pointerSizeInBytes, String osName)
      Returns the name of the golang bootstrap gdt data type archive, using the specified version, pointer size and OS name.
      Parameters:
      goVer - GoVer
      pointerSizeInBytes - pointer size for this binary, or -1 to use wildcard "any"
      osName - name of the operating system, or "any"
      Returns:
      String, "golang_1.18_64bit_any.gdt"
    • getGolangOSString

      public static String getGolangOSString(Program program)
      Returns a golang OS string based on the Ghidra program.
      Parameters:
      program - Program
      Returns:
      String golang OS string such as "linux", "win"
    • findGolangBootstrapGDT

      public static ResourceFile findGolangBootstrapGDT(GoVer goVer, int ptrSize, String osName)
      Searches for a golang bootstrap gdt file that matches the specified Go version/size/OS.

      First looks for a gdt with an exact match, then for a gdt with version/size match and "any" OS, and finally, a gdt that matches the version and "any" size and "any" OS.

      Parameters:
      goVer - version of Go
      ptrSize - size of pointers
      osName - name of OS
      Returns:
      ResourceFile of matching bootstrap gdt, or null if nothing matches
    • isGolangProgram

      public static boolean isGolangProgram(Program program)
      Returns true if the specified Program is marked as "golang".
      Parameters:
      program - Program
      Returns:
      boolean true if program is marked as golang
    • hasGolangSections

      public static boolean hasGolangSections(List<String> sectionNames)
    • getGoSymbol

      public static Symbol getGoSymbol(Program program, String symbolName)
      Returns a matching symbol from the specified program, using golang specific logic.
      Parameters:
      program - Program
      symbolName - name of golang symbol
      Returns:
      Symbol, or null if not found
    • getGoSection

      public static MemoryBlock getGoSection(Program program, String sectionName)
    • getFirstGoSection

      public static MemoryBlock getFirstGoSection(Program program, String... blockNames)
    • getZerobaseAddress

      public static Address getZerobaseAddress(Program prog)
      Return the address of the golang zerobase symbol, or an artificial substitute.

      The zerobase symbol is used as the location of parameters that are zero-length.

      Parameters:
      prog - Program
      Returns:
      Address of the runtime.zerobase, or artificial substitute
    • getAllSupportedVersions

      public static List<GoVer> getAllSupportedVersions()
    • getType

      public <T extends DataType> T getType(String name, Class<T> clazz)
      Description copied from class: DataTypeMapper
      Returns a named DataType, searching the registered program and archive category paths.

      DataTypes that were found in the attached archive gdt manager will be copied into the program's data type manager before being returned.

      Overrides:
      getType in class DataTypeMapper
      Type Parameters:
      T - DataType or derived type
      Parameters:
      name - DataType name
      clazz - expected DataType class
      Returns:
      DataType or null if not found
    • getGolangVersion

      public GoVer getGolangVersion()
      Returns the golang version
      Returns:
      GoVer
    • getRegInfo

      public GoRegisterInfo getRegInfo()
      Returns a shared GoRegisterInfo instance
      Returns:
      GoRegisterInfo
    • init

      public void init(TaskMonitor monitor) throws IOException
      Finishes making this instance ready to be used.
      Parameters:
      monitor - TaskMonitor
      Throws:
      IOException - if error reading data
    • initMethodInfoIfNeeded

      public void initMethodInfoIfNeeded() throws IOException
      Initializes golang function / method lookup info
      Throws:
      IOException - if error reading data
    • getMinLC

      public byte getMinLC() throws IOException
      Returns the minLC (pcquantum) value found in the pcln header structure
      Returns:
      minLC value
      Throws:
      IOException - if value has not been initialized yet
    • getFirstModule

      public GoModuledata getFirstModule()
      Returns the first module data instance
      Returns:
      GoModuledata
    • addModule

      public void addModule(GoModuledata module)
      Adds a module data instance to the context
      Parameters:
      module - GoModuledata to add
    • newStorageAllocator

      public GoParamStorageAllocator newStorageAllocator()
      Returns a new param storage allocator instance.
      Returns:
      new GoParamStorageAllocator instance
    • isGolangAbi0Func

      public boolean isGolangAbi0Func(Function func)
      Returns true if the specified function uses the abi0 calling convention.
      Parameters:
      func - Function to test
      Returns:
      boolean true if function uses abi0 calling convention
    • hasCallingConvention

      public boolean hasCallingConvention(String ccName)
      Returns true if the specified calling convention is defined for the program.
      Parameters:
      ccName - calling convention name
      Returns:
      true if the specified calling convention is defined for the program
    • createMarkupSession

      public MarkupSession createMarkupSession(TaskMonitor monitor)
      Description copied from class: DataTypeMapper
      Creates a MarkupSession that is controlled by the specified TaskMonitor.
      Overrides:
      createMarkupSession in class DataTypeMapper
      Parameters:
      monitor - TaskMonitor
      Returns:
      new MarkupSession
    • findContainingModule

      public GoModuledata findContainingModule(long offset)
      Finds the GoModuledata that contains the specified offset.

      Useful for finding the GoModuledata to resolve a relative offset of the text, types or other area.

      Parameters:
      offset - absolute offset of a structure that a GoModuledata contains
      Returns:
      GoModuledata instance that contains the structure, or null if not found
    • findContainingModuleByFuncData

      public GoModuledata findContainingModuleByFuncData(long offset)
      Finds the GoModuledata that contains the specified func data offset.
      Parameters:
      offset - absolute offset of a func data structure
      Returns:
      GoModuledata instance that contains the specified func data, or null if not found
    • getDefaultVariableLengthStructCategoryPath

      public CategoryPath getDefaultVariableLengthStructCategoryPath()
      Description copied from class: DataTypeMapper
      CategoryPath location (in the program) where new data types will be created to represent variable length structures.
      Overrides:
      getDefaultVariableLengthStructCategoryPath in class DataTypeMapper
      Returns:
      CategoryPath, default is ROOT
    • getUintptrDT

      public DataType getUintptrDT()
      Returns the data type that represents a golang uintptr
      Returns:
      golang uinptr data type
    • getInt32DT

      public DataType getInt32DT()
      Returns the data type that represents a golang int32
      Returns:
      golang int32 data type
    • getUint32DT

      public DataType getUint32DT()
      Returns the data type that represents a golang uint32
      Returns:
      golang uint32 data type
    • getGenericSliceDT

      public Structure getGenericSliceDT()
      Returns the data type that represents a generic golang slice.
      Returns:
      golang generic slice data type
    • getMapGoType

      public GoType getMapGoType()
      Returns the ghidra data type that represents a golang built-in map type.
      Returns:
      golang map data type
    • getChanGoType

      public GoType getChanGoType()
      Returns the ghidra data type that represents the built-in golang channel type.
      Returns:
      golang channel type
    • createProgramReader

      protected BinaryReader createProgramReader()
      Description copied from class: DataTypeMapper
      Creates a new BinaryReader that reads bytes from the current program's memory image.

      Address offsets and index offsets in the BinaryReader should be synonymous.

      Overrides:
      createProgramReader in class DataTypeMapper
      Returns:
      new BinaryReader
    • getPtrSize

      public int getPtrSize()
      Returns the size of pointers in this binary.
      Returns:
      pointer size (ex. 4, or 8)
    • getGoType

      public GoType getGoType(long offset) throws IOException
      Returns a specialized GoType for the type that is located at the specified location.
      Parameters:
      offset - absolute position of a go type
      Returns:
      specialized GoType (example, GoStructType, GoArrayType, etc)
      Throws:
      IOException - if error reading
    • getCachedGoType

      public GoType getCachedGoType(long offset)
      Returns a previous read and cached GoType, based on its offset.
      Parameters:
      offset - offset of the GoType
      Returns:
      GoType, or null if not previously read and cached
    • getGoType

      public GoType getGoType(Address addr) throws IOException
      Returns a specialized GoType for the type that is located at the specified location.
      Parameters:
      addr - location of a go type
      Returns:
      specialized GoType (example, GoStructType, GoArrayType, etc)
      Throws:
      IOException - if error reading
    • findGoType

      public GoType findGoType(String typeName)
      Finds a go type by its go-type name, from the list of discovered go types.
      Parameters:
      typeName - name string
      Returns:
      GoType, or null if not found
    • getGhidraDataType

      public <T extends DataType> T getGhidraDataType(String goTypeName, Class<T> clazz)
      Returns the Ghidra DataType that is equivalent to the named golang type.
      Type Parameters:
      T - expected DataType
      Parameters:
      goTypeName - golang type name
      clazz - class of expected data type
      Returns:
      DataType representing the named golang type, or null if not found
    • exportTypesToGDT

      public void exportTypesToGDT(File gdtFile, boolean runtimeFuncSnapshot, TaskMonitor monitor) throws IOException, CancelledException
      Export the currently registered struct mapping types to a gdt file, producing a bootstrap GDT archive.

      The struct data types will either be from the current program's DWARF data, or from an earlier golang.gdt (if this binary doesn't have DWARF)

      Parameters:
      gdtFile - destination File to write the bootstrap types to
      runtimeFuncSnapshot - boolean flag, if true include function definitions
      monitor - TaskMonitor
      Throws:
      IOException - if error
      CancelledException - if cancelled
    • getRecoveredTypesCp

      public CategoryPath getRecoveredTypesCp(String packagePath)
      Returns category path that should be used to place recovered golang types.
      Parameters:
      packagePath - optional package path of the type (eg. "utf/utf8", or "runtime")
      Returns:
      CategoryPath to use when creating recovered golang types
    • getRecoveredType

      public DataType getRecoveredType(GoType typ) throws IOException
      Returns a Ghidra data type that represents the golang type, using a cache of already recovered types to eliminate extra work and self recursion.
      Parameters:
      typ - the GoType to convert
      Returns:
      Ghidra DataType
      Throws:
      IOException - if error converting type
    • getSpecializedMethodSignature

      public FunctionDefinition getSpecializedMethodSignature(String methodName, GoType methodType, DataType receiverDT, boolean allowPartial) throws IOException
      Returns a function definition for a method that is attached to a golang type.

      Parameters:
      methodName - name of method
      methodType - golang function def type
      receiverDT - data type of the go type that contains the method
      allowPartial - boolean flag, if true allows returning an artificial funcdef when the methodType parameter does not point to a function definition
      Returns:
      new FunctionDefinition using the function signature specified by the methodType function definition, with the containing goType's type inserted as the first parameter, similar to a c++ "this" parameter
      Throws:
      IOException - if error reading type info
    • cacheRecoveredDataType

      public void cacheRecoveredDataType(GoType typ, DataType dt) throws IOException
      Inserts a mapping between a golang type and a ghidra data type.

      Useful to prepopulate the data type mapping before recursing into contained/referenced types that might be self-referencing.

      Parameters:
      typ - golang type
      dt - Ghidra type
      Throws:
      IOException - if golang type struct is not a valid struct mapped instance
    • getCachedRecoveredDataType

      public DataType getCachedRecoveredDataType(GoType typ) throws IOException
      Returns a Ghidra data type that represents the golang type, using a cache of already recovered types to eliminate extra work and self recursion.
      Parameters:
      typ - the GoType to convert
      Returns:
      Ghidra DataType
      Throws:
      IOException - if golang type struct is not a valid struct mapped instance
    • recoverDataTypes

      public void recoverDataTypes(TaskMonitor monitor) throws IOException, CancelledException
      Converts all discovered golang rtti type records to Ghidra data types, placing them in the program's DTM in /golang-recovered
      Parameters:
      monitor - TaskMonitor
      Throws:
      IOException - error converting a golang type to a Ghidra type
      CancelledException - if the user cancelled the import
    • initTypeInfoIfNeeded

      public void initTypeInfoIfNeeded(TaskMonitor monitor) throws CancelledException, IOException
      Discovers available golang types if not already done.
      Parameters:
      monitor - TaskMonitor
      Throws:
      CancelledException - if cancelled
      IOException - if error reading data
    • discoverGoTypes

      public void discoverGoTypes(TaskMonitor monitor) throws IOException, CancelledException
      Iterates over all golang rtti types listed in the GoModuledata struct, and recurses into each type to discover any types they reference.

      The found types are accumulated in goTypes.

      Parameters:
      monitor - TaskMonitor
      Throws:
      IOException - if error
      CancelledException - if cancelled
    • getMethodInfoForFunction

      public List<MethodInfo> getMethodInfoForFunction(Address funcAddr)
      Returns a list of methods (either gotype methods or interface methods) that point to this function.
      Parameters:
      funcAddr - function address
      Returns:
      list of methods
    • getInterfacesImplementedByType

      public List<GoItab> getInterfacesImplementedByType(GoType type)
      Returns a list of interfaces that the specified type has implemented.
      Parameters:
      type - GoType
      Returns:
      list of itabs that map a GoType to the interfaces it was found to implement
    • getUniqueGoTypename

      public String getUniqueGoTypename(GoType goType)
      Returns a unique name for the specified go type.
      Parameters:
      goType - GoType
      Returns:
      unique string name
    • getSafeName

      public <T> GoName getSafeName(GoRttiMapper.GoNameSupplier supplier, T structInstance, String defaultValue)
      An exception handling wrapper around a "getName()" call that could throw an IOException.

      When there is an error fetching the GoName instance via the specified callback, a limited usage GoName instance will be created and returned that will provide a replacement name that is built using the calling structure's offset as the identifier.

      Type Parameters:
      T - struct mapped instance type
      Parameters:
      supplier - Supplier callback
      structInstance - reference to the caller's struct-mapped instance
      defaultValue - string value to return (wrapped in a GoName) if the GoName is simply missing
      Returns:
      GoName, either from the callback, or a limited-functionality instance created to hold a fallback name string
    • getGoTypeName

      public String getGoTypeName(long offset)
      Returns the name of a gotype.
      Parameters:
      offset - offset of the gotype RTTI record
      Returns:
      string name, with a fallback if the specified offset was invalid
    • resolveTypeOff

      public GoType resolveTypeOff(long ptrInModule, long off) throws IOException
      Returns the GoType corresponding to an offset that is relative to the controlling GoModuledata's typesOffset.
      Parameters:
      ptrInModule - the address of the structure that contains the offset that needs to be calculated. The containing-structure's address is important because it indicates which GoModuledata is the 'parent'
      off - offset
      Returns:
      GoType, or null if offset is special value 0 or -1
      Throws:
      IOException - if error
    • resolveTextOff

      public Address resolveTextOff(long ptrInModule, long off)
      Returns the Address to an offset that is relative to the controlling GoModuledata's text value.
      Parameters:
      ptrInModule - the address of the structure that contains the offset that needs to be calculated. The containing-structure's address is important because it indicates which GoModuledata is the 'parent'
      off - offset
      Returns:
      Address, or null if offset was special value -1
    • resolveNameOff

      public GoName resolveNameOff(long ptrInModule, long off) throws IOException
      Returns the GoName corresponding to an offset that is relative to the controlling GoModuledata's typesOffset.

      Parameters:
      ptrInModule - the address of the structure that contains the offset that needs to be calculated. The containing-structure's address is important because it indicates which GoModuledata is the 'parent'
      off - offset
      Returns:
      GoName, or null if offset was special value 0
      Throws:
      IOException - if error reading name or unable to find containing module
    • getGoName

      public GoName getGoName(long offset) throws IOException
      Returns the GoName instance at the specified offset.
      Parameters:
      offset - location to read
      Returns:
      GoName instance, or null if offset was special value 0
      Throws:
      IOException - if error reading
    • getFunctionData

      public GoFuncData getFunctionData(Address funcAddr)
      Returns metadata about a function
      Parameters:
      funcAddr - entry point of a function
      Returns:
      GoFuncData, or null if function not found in lookup tables
    • getFunctionByName

      public GoFuncData getFunctionByName(String funcName)
      Returns a function based on its name
      Parameters:
      funcName - name of function
      Returns:
      GoFuncData, or null if not found
    • getAllFunctions

      public List<GoFuncData> getAllFunctions()
      Return a list of all functions
      Returns:
      list of all functions contained in the golang func metadata table
    • getBootstrapFunctionDefintion

      public FunctionDefinition getBootstrapFunctionDefintion(String funcName)
      Returns a FunctionDefinition for a built-in golang runtime function.
      Parameters:
      funcName - name of function
      Returns:
      FunctionDefinition, or null if not found in bootstrap gdt
    • getStringStructRange

      public AddressSetView getStringStructRange()
      Returns the address range that is valid for string structs to be found in.
      Returns:
      AddressSetView of range that is valid to find string structs in
    • getStringDataRange

      public AddressSetView getStringDataRange()
      Returns the address range that is valid for string char[] data to be found in.
      Returns:
      AddressSetView of range that is valid for string char[] data
    • getTextAddresses

      public AddressSetView getTextAddresses()
    • getGoSymbol

      public Symbol getGoSymbol(String symbolName)
    • getGoSection

      public MemoryBlock getGoSection(String sectionName)
    • isFieldPresent

      public boolean isFieldPresent(String presentWhen)
      Description copied from interface: DataTypeMapperContext
      Tests if a field should be included when creating bindings between a structure and a class.
      Specified by:
      isFieldPresent in interface DataTypeMapperContext
      Parameters:
      presentWhen - free-form string that is interpreted by each DataTypeMapper
      Returns:
      boolean true if field should be bound, false if field should not be bound