gore

package module
v0.13.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2024 License: AGPL-3.0 Imports: 29 Imported by: 5

README

Build Status GitHub tag (latest SemVer) codecov Go Report Card Go Reference

GoRE - Package gore is a library for analyzing Go binaries

How to use

  1. Use go get to download the library.
  2. Import it into your project.
  3. Write a new cool tool.

For an example use case, please check out redress.

Sample code

Extract the main package, child packages, and sibling packages:

f, err := gore.Open(fileStr)
pkgs, err := f.GetPackages()

Extract all the types in the binary:

f, err := gore.Open(fileStr)
typs, err := f.GetTypes()

Update get new Go release information

Instead of downloading new release of the library to get detection for new Go releases, it is possible to do a local pull.

Run go generate and new compiler releases will be generated from the git tags.

Functionality

Go compiler

The library has functionality for guessing the compiler version used. It searches the binary for the identifiable string left by the compiler. It is not perfect, so functionality for assuming a specific version is also provided. The version strings used are identical to the identifiers. For example version "1.10.1" is represented as "go1.10.1" and version "1.10" is represented as "go1.10"

Function recovery

Function information is recovered from the pclntab. Information that is recovered includes: function start and end location in the text section, source file. The library also tries to estimate the first and last line number in the source file for the function. The methods recovered includes the receiver. All functions and methods belong to a package. The library tries to classify the type of package. If it is a standard library package, 3rd-party package, or part of the main application. If it unable to classify the package, it is classified as unknown.

Type recovery

The types in the binary are parsed from the "typelink" list. Not all versions of Go are supported equally. Versions 1.7 and later are fully supported. Versions 1.5 and 1.6 are partially supported. Version prior to 1.5 are not supported at all at the moment.

Documentation

Overview

Package gore is a library for analyzing Go binaries.

Only little endian architectures are supported.

Go compiler

The library has functionality for guessing the compiler version used. It searches the binary for the identifiable string left by the compiler. It is not perfect, so functionality for assuming a specific version is also provided. The version strings used are identical to the identifiers. For example version "1.10.1" is represented as "go1.10.1" and version "1.10" is represented as "go1.10"

Function recovery

Function information is recovered from the pclntab. Information that is recovered includes: function start and end location in the text section, source file. The library also tries to estimate the first and last line number in the source file for the function. The methods recovered includes the receiver. All functions and methods belong to a package. The library tries to classify the type of package. If it is a standard library package, 3rd-party package, or part of the main application. If it unable to classify the package, it is classified as unknown.

Type recovery

The types in the binary are parsed from the "typelink" list. Not all versions of Go are supported equally. Versions 1.7 and later are fully supported. Versions 1.5 and 1.6 are partially supported. Version prior to 1.5 are not supported at all at the moment.

Example code

Extract the main package, child packages, and sibling packages:

f, err := gore.Open(fileStr)
pkgs, err := f.GetPackages()

Extract all the types in the binary:

f, err := gore.Open(fileStr)
typs, err := f.GetTypes()

Index

Constants

View Source
const (
	ArchAMD64 = "amd64"
	ArchARM   = "arm"
	ArchARM64 = "arm64"
	Arch386   = "i386"
	ArchMIPS  = "mips"
)

Variables

View Source
var (
	// ErrNotEnoughBytesRead is returned if read call returned less bytes than what is needed.
	ErrNotEnoughBytesRead = errors.New("not enough bytes read")
	// ErrUnsupportedFile is returned if the file process is unsupported.
	ErrUnsupportedFile = errors.New("unsupported file")
	// ErrSectionDoesNotExist is returned when accessing a section that does not exist.
	ErrSectionDoesNotExist = errors.New("section does not exist")
	// ErrNoGoVersionFound is returned if no goversion was found in the binary.
	ErrNoGoVersionFound = errors.New("no goversion found")
	// ErrNoPCLNTab is returned if no PCLN table can be located.
	ErrNoPCLNTab = errors.New("no pclntab located")
	// ErrInvalidGoVersion is returned if the go version set for the file is either invalid
	// or does not match a known version by the library.
	ErrInvalidGoVersion = errors.New("invalid go version")
	// ErrNoGoRootFound is returned if no goroot was found in the binary.
	ErrNoGoRootFound = errors.New("no goroot found")
)
View Source
var (
	// ErrNoBuildInfo is returned if the file has no build information available.
	ErrNoBuildInfo = errors.New("no build info available")
)
View Source
var ErrSymbolNotFound = errors.New("symbol not found")

Functions

func GoVersionCompare

func GoVersionCompare(a, b string) int

GoVersionCompare compares two version strings. If a < b, -1 is returned. If a == b, 0 is returned. If a > b, 1 is returned.

func InterfaceDef

func InterfaceDef(typ *GoType) string

InterfaceDef reconstructs the type definition code for the interface. If the type is not an interface, an empty string is returned.

func IsStandardLibrary

func IsStandardLibrary(pkg string) bool

IsStandardLibrary returns true if the package is from the standard library. Otherwise, false is retuned.

func MethodDef

func MethodDef(typ *GoType) string

MethodDef constructs a string summary of all methods for the type. If type information exists for the methods, it is used to determine function parameters. If the type does not have any methods, an empty string is returned.

func StructDef

func StructDef(typ *GoType) string

StructDef reconstructs the type definition code for the struct. If the type is not a struct, an empty string is returned.

Types

type BuildInfo added in v0.10.0

type BuildInfo struct {
	// Compiler version. Can be nil.
	Compiler *GoVersion
	// ModInfo holds information about the Go modules in this file.
	// Can be nil.
	ModInfo *debug.BuildInfo
}

BuildInfo that was extracted from the file.

type ChanDir

type ChanDir int

ChanDir is a channel direction.

const (
	// ChanRecv is a receive only chan (<-chan)
	ChanRecv ChanDir = 1 << iota
	// ChanSend is a send only chan (chan<-)
	ChanSend
	// ChanBoth is a send and receive chan (chan)
	ChanBoth = ChanRecv | ChanSend
)

type FileEntry

type FileEntry struct {
	// Name of the function or method.
	Name string
	// Start is the source line where the code starts.
	Start int
	// End is the source line where the code ends.
	End int
}

FileEntry is a representation of an entry in a source code file. This can for example be a function or a method.

func (FileEntry) String added in v0.10.0

func (f FileEntry) String() string

String returns a string representation of the entry.

type FileInfo

type FileInfo struct {
	// Arch is the architecture the binary is compiled for.
	Arch string
	// OS is the operating system the binary is compiled for.
	OS string
	// ByteOrder is the byte order.
	ByteOrder binary.ByteOrder
	// WordSize is the natural integer size used by the file.
	WordSize int
	// contains filtered or unexported fields
}

FileInfo holds information about the file.

type Function

type Function struct {
	// Name is the extracted function name.
	Name string `json:"name"`
	// Offset is the starting location for the subroutine in the binary.
	Offset uint64 `json:"offset"`
	// End is the end location for the subroutine in the binary.
	End uint64 `json:"end"`
	// PackageName is the name of the Go package the function belongs to.
	PackageName string `json:"packageName"`
}

Function is a representation of a Go function.

func (*Function) String

func (f *Function) String() string

String returns a string representation of the function.

type GoFile

type GoFile struct {
	// BuildInfo holds the data from the buildinfo structure.
	// This can be a nil because it's not always available.
	BuildInfo *BuildInfo
	// FileInfo holds information about the file.
	FileInfo *FileInfo
	// BuildID is the Go build ID hash extracted from the binary.
	BuildID string
	// contains filtered or unexported fields
}

GoFile is a structure representing a go binary file.

func Open

func Open(filePath string) (*GoFile, error)

Open opens a file and returns a handler to the file.

func OpenReader added in v0.13.0

func OpenReader(f io.ReaderAt) (*GoFile, error)

OpenReader opens a reader and returns a handler to the file.

func (*GoFile) Bytes added in v0.8.0

func (f *GoFile) Bytes(address uint64, length uint64) ([]byte, error)

Bytes return a slice of raw bytes with the length in the file from the address.

func (*GoFile) Close

func (f *GoFile) Close() error

Close releases the file handler.

func (*GoFile) GetCompilerVersion

func (f *GoFile) GetCompilerVersion() (*GoVersion, error)

GetCompilerVersion returns the Go compiler version of the compiler that was used to compile the binary.

func (*GoFile) GetGeneratedPackages added in v0.9.0

func (f *GoFile) GetGeneratedPackages() ([]*Package, error)

GetGeneratedPackages returns the compiler generated packages used by the binary.

func (*GoFile) GetGoRoot added in v0.9.0

func (f *GoFile) GetGoRoot() (string, error)

GetGoRoot returns the Go Root path used to compile the binary.

func (*GoFile) GetPackages

func (f *GoFile) GetPackages() ([]*Package, error)

GetPackages returns the go packages that have been classified as part of the main project.

func (*GoFile) GetParsedFile added in v0.11.5

func (f *GoFile) GetParsedFile() any

GetParsedFile returns the parsed file, should be cast based on the file type. Possible types are:

  • *elf.File
  • *pe.File
  • *github.com/blacktop/go-macho.File

all from the debug package.

func (*GoFile) GetReader added in v0.13.0

func (f *GoFile) GetReader() io.ReaderAt

GetReader returns the reader passed to the file handler.

func (*GoFile) GetSTDLib

func (f *GoFile) GetSTDLib() ([]*Package, error)

GetSTDLib returns the standard library packages used by the binary.

func (*GoFile) GetSourceFiles added in v0.10.0

func (f *GoFile) GetSourceFiles(p *Package) []*SourceFile

GetSourceFiles returns a slice of source files within the package. The source files are a representations of the source code files in the package.

func (*GoFile) GetSymbol added in v0.12.0

func (f *GoFile) GetSymbol(name string) (Symbol, error)

GetSymbol returns the symbol with the given name.

func (*GoFile) GetTypes

func (f *GoFile) GetTypes() ([]*GoType, error)

GetTypes returns a map of all types found in the binary file.

func (*GoFile) GetUnknown

func (f *GoFile) GetUnknown() ([]*Package, error)

GetUnknown returns unclassified packages used by the binary. This is a catch-all category when the classification could not be determined.

func (*GoFile) GetVendors

func (f *GoFile) GetVendors() ([]*Package, error)

GetVendors returns the third party packages used by the binary.

func (*GoFile) Moduledata added in v0.11.0

func (f *GoFile) Moduledata() (Moduledata, error)

Moduledata extracts the file's moduledata.

func (*GoFile) PCLNTab

func (f *GoFile) PCLNTab() (*gosym.Table, error)

PCLNTab returns the PCLN table.

func (*GoFile) SetGoVersion

func (f *GoFile) SetGoVersion(version string) error

SetGoVersion sets the assumed compiler version that was used. This can be used to force a version if gore is not able to determine the compiler version used. The version string must match one of the strings normally extracted from the binary. For example, to set the version to go 1.12.0, use "go1.12". For 1.7.2, use "go1.7.2". If an incorrect version string or version not known to the library, ErrInvalidGoVersion is returned.

func (*GoFile) SourceInfo added in v0.10.0

func (f *GoFile) SourceInfo(fn *Function) (string, int, int)

SourceInfo returns the source code filename, starting line number and ending line number for the function.

type GoType

type GoType struct {
	// Kind indicates the specific kind of type the GoType
	Kind reflect.Kind
	// Name is the name of the type.
	Name string
	// Addr is the virtual address to where the type struct is defined.
	Addr uint64
	// PtrResolvAddr is the address to where the resolved structure is located
	// if the GoType is of pointer kind.
	PtrResolvAddr uint64
	// PackagePath is the name of the package import path for the GoType.
	PackagePath string
	// Fields is a slice of the struct fields if the GoType is of kind struct.
	Fields []*GoType
	// FieldName is the name of the field if the GoType is a struct field.
	FieldName string
	// FieldTag holds the extracted tag for the field.
	FieldTag string
	// FieldAnon is true if the field does not have a name and is an embedded type.
	FieldAnon bool
	// Element is the element type for arrays, slices channels or the resolved type for
	// a pointer type. For example int if the slice is a []int.
	Element *GoType
	// Length is the array or slice length.
	Length int
	// ChanDir is the channel direction
	ChanDir ChanDir
	// Key is the key type for a map.
	Key *GoType
	// FuncArgs holds the argument types for the function if the type is a function kind.
	FuncArgs []*GoType
	// FuncReturnVals holds the return types for the function if the type is a function kind.
	FuncReturnVals []*GoType
	// IsVariadic is true if the last argument type is variadic. For example "func(s string, n ...int)"
	IsVariadic bool
	// Methods holds information of the types methods.
	Methods []*TypeMethod
	// contains filtered or unexported fields
}

GoType is a representation of all types in Go.

func (*GoType) String

func (t *GoType) String() string

String implements the fmt.Stringer interface.

type GoVersion

type GoVersion struct {
	// Name is a string representation of the version.
	Name string
	// SHA is a digest of the git commit for the release.
	SHA string
	// Timestamp is a string of the timestamp when the commit was created.
	Timestamp string
}

GoVersion holds information about the compiler version.

func ResolveGoVersion

func ResolveGoVersion(tag string) *GoVersion

ResolveGoVersion tries to return the GoVersion for the given tag. For example the tag: go1 will return a GoVersion struct representing version 1.0 of the compiler. If no goversion for the given tag is found, nil is returned.

type Method

type Method struct {
	// Receiver is the name of the method receiver.
	Receiver string `json:"receiver"`
	*Function
}

Method is a representation of a Go method.

func (*Method) String

func (m *Method) String() string

String returns a string summary of the function.

type ModPackageClassifier added in v0.10.0

type ModPackageClassifier struct {
	// contains filtered or unexported fields
}

ModPackageClassifier uses the mod info extracted from the binary to classify packages.

func NewModPackageClassifier added in v0.10.0

func NewModPackageClassifier(buildInfo *debug.BuildInfo) *ModPackageClassifier

NewModPackageClassifier creates a new mod based package classifier.

func (*ModPackageClassifier) Classify added in v0.10.0

func (c *ModPackageClassifier) Classify(pkg *Package) PackageClass

Classify performs the classification.

type ModuleDataSection added in v0.11.0

type ModuleDataSection struct {
	// Address is the virtual address where the section starts.
	Address uint64
	// Length is the byte length for the data in this section.
	Length uint64
	// contains filtered or unexported fields
}

ModuleDataSection is a section defined in the Moduledata structure.

func (ModuleDataSection) Data added in v0.11.0

func (m ModuleDataSection) Data() ([]byte, error)

Data returns the data in the section.

type Moduledata added in v0.11.0

type Moduledata interface {
	// Text returns the text secion.
	Text() ModuleDataSection
	// NoPtrData returns the noptrdata section.
	NoPtrData() ModuleDataSection
	// Data returns the data section.
	Data() ModuleDataSection
	// Bss returns the bss section.
	Bss() ModuleDataSection
	// NoPtrBss returns the noptrbss section.
	NoPtrBss() ModuleDataSection
	// Types returns the types section.
	Types() ModuleDataSection
	// PCLNTab returns the pclntab section.
	PCLNTab() ModuleDataSection
	// FuncTab returns the functab section.
	FuncTab() ModuleDataSection
	// ITabLinks returns the itablinks section.
	ITabLinks() ModuleDataSection
	// TypeLink returns the typelink section.
	TypeLink() ModuleDataSection
	// TypeLinkData returns the typelink section data.
	TypeLinkData() ([]int32, error)
	// GoFuncValue returns the value of the 'go:func.*' symbol.
	GoFuncValue() uint64
}

Moduledata holds information about the layout of the executable image in memory.

type Package

type Package struct {
	// Name is the name of the package.
	Name string `json:"name"`
	// Filepath is the extracted file path for the package.
	Filepath string `json:"path"`
	// Functions is a list of functions that are part of the package.
	Functions []*Function `json:"functions"`
	// Methods a list of methods that are part of the package.
	Methods []*Method `json:"methods"`
}

Package is a representation of a Go package.

type PackageClass

type PackageClass uint8

PackageClass is a type used to indicate the package kind.

const (
	// ClassUnknown is used for packages that could not be classified.
	ClassUnknown PackageClass = iota
	// ClassSTD is used for packages that are part of the standard library.
	ClassSTD
	// ClassMain is used for the main package and its subpackages.
	ClassMain
	// ClassVendor is used for vendor packages.
	ClassVendor
	// ClassGenerated are used for packages generated by the compiler.
	ClassGenerated
)

type PackageClassifier

type PackageClassifier interface {
	// Classify performs the classification.
	Classify(pkg *Package) PackageClass
}

PackageClassifier classifies a package to the correct class type.

type PathPackageClassifier added in v0.10.0

type PathPackageClassifier struct {
	// contains filtered or unexported fields
}

PathPackageClassifier can classify the class of a go package.

func NewPathPackageClassifier added in v0.10.0

func NewPathPackageClassifier(mainPkgFilepath string) *PathPackageClassifier

NewPathPackageClassifier constructs a new classifier based on the main package's filepath.

func (*PathPackageClassifier) Classify added in v0.10.0

func (c *PathPackageClassifier) Classify(pkg *Package) PackageClass

Classify returns the package class for the package.

type SourceFile

type SourceFile struct {
	// Name of the file.
	Name string
	// Prefix that should be added to each line.
	Prefix string
	// Postfix that should be added to each line.
	Postfix string
	// contains filtered or unexported fields
}

SourceFile is a representation of a source code file.

func (*SourceFile) String

func (s *SourceFile) String() string

String produces a string representation of a source code file. The multi-line string has this format:

File: simple.go
	main Lines: 5 to 8 (3)
	setup Lines: 9 to 11 (2)

The prefix and postfix string is added to each line.

type Symbol added in v0.12.0

type Symbol struct {
	// Name of the symbol.
	Name string
	// Value of the symbol.
	Value uint64
	// Size of the symbol. Only accurate on ELF files. For Mach-O and PE files, it was inferred by looking at the next symbol.
	Size uint64
}

Symbol A generic representation of debug/elf.Symbol, debug/pe.Symbol, and github.com/blacktop/go-macho.Symbol.

type TypeMethod

type TypeMethod struct {
	// Name is the string name for the method.
	Name string
	// Type is the specific function type for the method.
	// This can be nil. If it is nil, the method is not part of an
	// implementation of a interface or it is not exported.
	Type *GoType
	// IfaceCallOffset is the offset from the beginning of the .text section
	// where the function code starts. According to code comments in the
	// standard library, it is used for interface calls.
	// Can be 0 if the code is not called in the binary and was optimized out
	// by the compiler or linker.
	IfaceCallOffset uint64
	// FuncCallOffset is the offset from the beginning of the .text section
	// where the function code starts. According to code comments in the
	// standard library, it is used for normal method calls.
	// Can be 0 if the code is not called in the binary and was optimized out
	// by the compiler or linker.
	FuncCallOffset uint64
}

TypeMethod is description of a method owned by the GoType.

Directories

Path Synopsis
Package extern Copied from src/go/version
Package extern Copied from src/go/version
gover
Package gover implements support for Go toolchain versions like 1.21.0 and 1.21rc1.
Package gover implements support for Go toolchain versions like 1.21.0 and 1.21rc1.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL