From e3bc1884ad229b47bf87b50ef31c9972bb135265 Mon Sep 17 00:00:00 2001 From: Philippe Ombredanne Date: Fri, 2 Aug 2024 16:26:59 +0200 Subject: [PATCH] Optionally skip printing the function sections (#60) * Optionally skip printing the function sections Add a new -no-functions command line flag to skip printing the UserFunctions and StdFunctions detailed sections. This is useful to get a quick summary of what is in a Go binary. The default is to always print the function sections. Reference: https://github.com/mandiant/GoReSym/issues/49 Signed-off-by: Philippe Ombredanne * Optionally skip printing the function sections Use -nofuncs command line flag instead. Reorder main_impl() function arguments. Reference: https://github.com/mandiant/GoReSym/issues/49 Signed-off-by: Philippe Ombredanne --------- Signed-off-by: Philippe Ombredanne --- main.go | 33 ++++++++++++++++++--------------- main_test.go | 8 ++++---- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/main.go b/main.go index b241c24..7eac803 100644 --- a/main.go +++ b/main.go @@ -66,7 +66,7 @@ type ExtractMetadata struct { StdFunctions []FuncMetadata } -func main_impl_tmpfile(fileBytes []byte, printStdPkgs bool, printFilePaths bool, printTypes bool, manualTypeAddress int, versionOverride string) (metadata ExtractMetadata, err error) { +func main_impl_tmpfile(fileBytes []byte, printStdPkgs bool, printFilePaths bool, printTypes bool, noPrintFunctions bool, manualTypeAddress int, versionOverride string) (metadata ExtractMetadata, err error) { tmpFile, err := os.CreateTemp(os.TempDir(), "goresym_tmp-") if err != nil { return ExtractMetadata{}, fmt.Errorf("failed to create temporary file: %s", err) @@ -81,10 +81,10 @@ func main_impl_tmpfile(fileBytes []byte, printStdPkgs bool, printFilePaths bool, return ExtractMetadata{}, fmt.Errorf("failed to close temporary file: %s", err) } - return main_impl(tmpFile.Name(), printStdPkgs, printFilePaths, printTypes, manualTypeAddress, versionOverride) + return main_impl(tmpFile.Name(), printStdPkgs, printFilePaths, printTypes, noPrintFunctions, manualTypeAddress, versionOverride) } -func main_impl(fileName string, printStdPkgs bool, printFilePaths bool, printTypes bool, manualTypeAddress int, versionOverride string) (metadata ExtractMetadata, err error) { +func main_impl(fileName string, printStdPkgs bool, printFilePaths bool, printTypes bool, noPrintFunctions bool, manualTypeAddress int, versionOverride string) (metadata ExtractMetadata, err error) { extractMetadata := ExtractMetadata{} file, err := objfile.Open(fileName) @@ -286,23 +286,25 @@ restartParseWithRealTextBase: } } - for _, elem := range finalTab.ParsedPclntab.Funcs { - if isStdPackage(elem.PackageName()) { - if printStdPkgs { - extractMetadata.StdFunctions = append(extractMetadata.StdFunctions, FuncMetadata{ + if !noPrintFunctions { + for _, elem := range finalTab.ParsedPclntab.Funcs { + if isStdPackage(elem.PackageName()) { + if printStdPkgs { + extractMetadata.StdFunctions = append(extractMetadata.StdFunctions, FuncMetadata{ + Start: elem.Entry, + End: elem.End, + PackageName: elem.PackageName(), + FullName: elem.Name, + }) + } + } else { + extractMetadata.UserFunctions = append(extractMetadata.UserFunctions, FuncMetadata{ Start: elem.Entry, End: elem.End, PackageName: elem.PackageName(), FullName: elem.Name, }) } - } else { - extractMetadata.UserFunctions = append(extractMetadata.UserFunctions, FuncMetadata{ - Start: elem.Entry, - End: elem.End, - PackageName: elem.PackageName(), - FullName: elem.Name, - }) } } @@ -422,6 +424,7 @@ func main() { printStdPkgs := flag.Bool("d", false, "Print Default Packages") printFilePaths := flag.Bool("p", false, "Print File Paths") printTypes := flag.Bool("t", false, "Print types automatically, enumerate typelinks and itablinks") + noPrintFunctions := flag.Bool("nofuncs", false, "Do not print user and standard function sections") typeAddress := flag.Int("m", 0, "Manually parse the RTYPE at the provided virtual address, disables automated enumeration of moduledata typelinks itablinks") versionOverride := flag.String("v", "", "Override the automated version detection, ex: 1.17. If this is wrong, parsing may fail or produce nonsense") humanView := flag.Bool("human", false, "Human view, print information flat rather than json, some information is omitted for clarity") @@ -442,7 +445,7 @@ func main() { os.Exit(1) } - metadata, err := main_impl(flag.Arg(0), *printStdPkgs, *printFilePaths, *printTypes, *typeAddress, *versionOverride) + metadata, err := main_impl(flag.Arg(0), *printStdPkgs, *printFilePaths, *printTypes, *noPrintFunctions, *typeAddress, *versionOverride) if err != nil { fmt.Println(TextToJson("error", fmt.Sprintf("Failed to parse file: %s", err))) os.Exit(1) diff --git a/main_test.go b/main_test.go index 0878db6..d917bfe 100644 --- a/main_test.go +++ b/main_test.go @@ -30,7 +30,7 @@ func TestAllVersions(t *testing.T) { } t.Run(versionPath, func(t *testing.T) { - data, err := main_impl(filePath, true, true, true, 0, "") + data, err := main_impl(filePath, true, true, true, true, 0, "") if err != nil { t.Errorf("Go %s failed on %s: %s", v, file, err) } @@ -119,7 +119,7 @@ func testSymbolRecovery(t *testing.T, workingDirectory string, binaryName string return } - data, err := main_impl(filePath, true, true, true, 0, "") + data, err := main_impl(filePath, true, true, true, true, 0, "") if err != nil { t.Errorf("GoReSym failed: %s", err) } @@ -214,7 +214,7 @@ func TestWeirdBins(t *testing.T) { return } - _, err := main_impl(filePath, true, true, true, 0, "") + _, err := main_impl(filePath, true, true, true, true, 0, "") if err == nil { t.Errorf("GoReSym found pclntab in a non-go binary, this is not possible.") } @@ -228,7 +228,7 @@ func TestWeirdBins(t *testing.T) { return } - _, err := main_impl(filePath, true, true, true, 0, "") + _, err := main_impl(filePath, true, true, true, true, 0, "") if err == nil { t.Errorf("GoReSym found pclntab in a non-go binary, this is not possible.") }