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_VERSIONS

      public static final GoVerRange SUPPORTED_VERSIONS
    • ARTIFICIAL_RUNTIME_ZEROBASE_SYMBOLNAME

      public static final String ARTIFICIAL_RUNTIME_ZEROBASE_SYMBOLNAME
      See Also:
  • Constructor Details

    • GoRttiMapper

      public GoRttiMapper(Program program, GoBuildInfo buildInfo, int ptrSize, GoVer goVer, ResourceFile archiveGDT, GoApiSnapshot apiSnapshot) throws IOException, BootstrapInfoException
      Creates a GoRttiMapper using the specified bootstrap information.
      Parameters:
      program - Program containing the go binary
      buildInfo - GoBuildInfo
      ptrSize - size of pointers
      goVer - 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
      apiSnapshot - json func signatures and data types
      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, TaskMonitor) 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, TaskMonitor monitor) throws BootstrapInfoException, IOException
      Creates a GoRttiMapper representing the specified program.
      Parameters:
      program - Program
      monitor - TaskMonitor
      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"
    • 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()
    • close

      public void close()
      Specified by:
      close in interface AutoCloseable
      Overrides:
      close in class DataTypeMapper
    • 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
    • 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
    • getGoVer

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

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

      public GoBuildInfo getBuildInfo()
    • 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
    • getGoTypes

      public GoTypeManager getGoTypes()
    • 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
    • getModules

      public List<GoModuledata> getModules()
    • 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
    • isAbi0Func

      public static boolean isAbi0Func(Address funcEntry, Program program)
    • getCallingConventionFor

      public String getCallingConventionFor(GoFuncData func)
    • 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
    • getDefaultCallingConventionName

      public String getDefaultCallingConventionName()
    • 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
    • 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)
    • 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
    • getFuncDefFor

      public GoRttiMapper.FuncDefResult getFuncDefFor(GoFuncData funcData) throws IOException
      Returns function definition information for a func.
      Parameters:
      funcData - GoFuncData representing a go func
      Returns:
      GoRttiMapper.FuncDefResult record, or null if no information could be found or generated
      Throws:
      IOException - if error reading type info
    • createFuncDef

      public FunctionDefinitionDataType createFuncDef(List<ParameterDefinition> params, List<ParameterDefinition> returnParams, GoSymbolName symbolName, boolean noReturn)
    • createFuncDef

      public FunctionDefinitionDataType createFuncDef(List<ParameterDefinition> params, DataType returnDT, GoSymbolName symbolName, boolean noReturn)
    • getMethodInfoForFunction

      public GoMethod.GoMethodInfo getMethodInfoForFunction(Address funcAddr)
      Returns method info about the specified function.
      Parameters:
      funcAddr - function address
      Returns:
      GoMethod.GoMethodInfo, or null
    • 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
    • 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
    • getFunctionsByNamePattern

      public List<GoFuncData> getFunctionsByNamePattern(Pattern pattern)
    • 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()
    • getUninitializedNoPtrDataRange

      public AddressSetView getUninitializedNoPtrDataRange()
    • getGoSymbol

      public Symbol getGoSymbol(String symbolName)
    • getGoSection

      public MemoryBlock getGoSection(String sectionName)