gopep: extracting attributes from PE executables compiled in Go
gopep
gopep (Go Lang Portable Executable Parser) is a Python script for extracting attributes from PE executables compiled in Go. This repo is part of a personal project for learning about executables compiled Go. For anyone else wanting to learn about executables compiled in Go, I would recommend reading through the links in the resources section.
gopep can be viewed for viewing contents of fields/structures extracted from Go’s ModuleData.
functab
functab contains function symbol names and their start offset.
- instance.functab
- instance.symbols (easier to remember)
Example Output
(4198400, b'go.buildid'), (4198512, b'internal/cpu.Initialize')
filetab
filetab contains all of the file paths for the source code (path/foo.go).
- instance.filetab
Example Output
[b'<autogenerated>’, b’/usr/local/go/src/runtime/internal/sys/intrinsics_386.s’, b’/usr/local/go/test/helloworld.go’]
The last file path is commonly a path that is not associated with Go libraries but the path of the developers source code. For example, /usr/local/go/test/helloworld.go is the source path for a “hello, world” Go binary. Other source files likely from the same source path are found using the difflib library and the SequenceMatcher function. These can be found by using the following.
- instance.go_base_paths
Example Output
[b'/usr/local/go/test/helloworld.go']
itabs
- instance.itab_sym
Not present if the binary is stripped.
Example Output
[b’go.itab.*os.File,io.Writer’, b’go.itab.*errors.errorString,error’, b’go.itab.*reflect.rtype,reflect.Type’, b’go.itab.*fmt.pp,fmt.State’, b’go.itab.*internal/reflectlite.rtype,internal/reflectlite.Type’, b’go.itab.*internal/fmtsort.SortedMap,sort.Interface’, b’go.itab.*os.PathError,error’, b’go.itab.syscall.Errno,error’, b’go.itab.runtime.errorString,error’, b’go.itab.*syscall.DLLError,error’, b’go.itab.*internal/poll.TimeoutError,error’]
.symtab symbols
- instance.symtab_symbols
Example Output
[b'runtime.text', b'runtime.etext', b'main..inittask', b'internal/cpu.X86',
stripped
- instance.stripped
- True or False
packed
- instance.packeed
- True or False
- Only checks for UPX by comparing section names.
- yeah, it sucks but I’m not caring much about packers detection right now.
Hashes
- instance.hash_sys_all
- instance.hash_sys_main
- instance.hash_sys_nomain
- instance.hash_itabs
- instance.hash_file_paths
Clustering
Attributes from Go binaries can be hashed and used for clustering. This technique is the same as Imphash (Import Hashing), which hashes blocks of string using MD5. This form of hashing is trivial to break but is still interesting to experiment with. GoPeP hashes based off the following
- all symbol/function names
- main symbols/functions
- non-main symbols/functions
- source code paths (functab)
- /usr/local/go/test/helloworld.go
- itabs (if present)
Download & Use
Copyright (c) 2021, Alexander Hanel