From 3970bb98cca4deb203c3928b83cde10d1ce49633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Thu, 24 Sep 2020 12:15:04 +0100 Subject: [PATCH] clean up global buildInfo a bit, fix up godocs The struct type for buildInfo doesn't need to be named. Plus, the "packageInfo" name was actually pretty misleading, because buildInfo contains data from many packages. Add an importCfg field, so that we don't need to fetch the flag value many times. Simplify reading the importCfg file; we used to also write to it, but that's no longer the case, so we can just use ioutil.ReadFile. Finally, give the function that fills buildInfo a better name, a godoc, and fix the origTypesConfig godoc. We also add a TODO to reuse goobj.ParseImportCfg in the future. --- main.go | 58 +++++++++++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/main.go b/main.go index 8edfa8b..eb27339 100644 --- a/main.go +++ b/main.go @@ -87,10 +87,9 @@ var ( b64 = base64.NewEncoding(nameCharset) printConfig = printer.Config{Mode: printer.RawFormat} - // listPackage helps implement a types.Importer which finds the export - // data for the original dependencies, not their garbled counterparts. - // This is useful to typecheck a package before it's garbled, so we can - // make decisions on how to garble it. + // origTypesConfig configures a go/types typechecker which uses the + // original versions of packages, without any obfuscation. This is + // helpful to make decisions on how to obfuscate our input code. origTypesConfig = types.Config{Importer: importer.ForCompiler(fset, "gc", func(path string) (io.ReadCloser, error) { pkg, err := listPackage(path) if err != nil { @@ -99,7 +98,18 @@ var ( return os.Open(pkg.Export) })} - buildInfo = packageInfo{imports: make(map[string]importedPkg)} + buildInfo = struct { + buildID string // from -buildid + importCfg string // from -importcfg + + // TODO: replace part of this with goobj.ParseImportCfg, so that + // we can also reuse it. For now, parsing ourselves is still + // necessary so that we can set firstImport. + imports map[string]importedPkg // parsed importCfg plus cached info + + firstImport string // first from -importcfg; the main package when linking + }{imports: make(map[string]importedPkg)} + garbledImporter = importer.ForCompiler(fset, "gc", func(path string) (io.ReadCloser, error) { return os.Open(buildInfo.imports[path].packagefile) }).(types.ImporterFrom) @@ -206,13 +216,6 @@ func garbledImport(path string) (*types.Package, error) { return pkg, nil } -type packageInfo struct { - buildID string // from -buildid - - imports map[string]importedPkg // from -importcfg - firstImport string // first from -importcfg; the main package when linking -} - type importedPkg struct { packagefile string buildID string @@ -517,7 +520,7 @@ func transformCompile(args []string) ([]string, error) { if !strings.Contains(trimpath, ";") { return nil, fmt.Errorf("-toolexec=garble should be used alongside -trimpath") } - if err := readBuildIDs(flags); err != nil { + if err := fillBuildInfo(flags); err != nil { return nil, err } @@ -666,9 +669,8 @@ func transformCompile(args []string) ([]string, error) { if len(privateNameMap) > 0 { objPath := flagValue(flags, "-o") - importcfg := flagValue(flags, "-importcfg") deferred = append(deferred, func() error { - importCfg, err := goobj2.ParseImportCfg(importcfg) + importCfg, err := goobj2.ParseImportCfg(buildInfo.importCfg) if err != nil { return err } @@ -719,23 +721,19 @@ func isPrivate(path string) bool { return module.MatchPrefixPatterns(envGoPrivate, path) } -func readBuildIDs(flags []string) error { +// fillBuildInfo initializes the global buildInfo struct via the supplied flags. +func fillBuildInfo(flags []string) error { buildInfo.buildID = flagValue(flags, "-buildid") switch buildInfo.buildID { case "", "true": return fmt.Errorf("could not find -buildid argument") } buildInfo.buildID = trimBuildID(buildInfo.buildID) - importcfg := flagValue(flags, "-importcfg") - if importcfg == "" { + buildInfo.importCfg = flagValue(flags, "-importcfg") + if buildInfo.importCfg == "" { return fmt.Errorf("could not find -importcfg argument") } - f, err := os.OpenFile(importcfg, os.O_RDWR, 0) - if err != nil { - return err - } - defer f.Close() - data, err := ioutil.ReadAll(f) + data, err := ioutil.ReadFile(buildInfo.importCfg) if err != nil { return err } @@ -772,10 +770,6 @@ func readBuildIDs(flags []string) error { } } // log.Printf("%#v", buildInfo) - - if err := f.Close(); err != nil { - return err - } return nil } @@ -1013,8 +1007,7 @@ func transformGo(file *ast.File, info *types.Info, blacklist map[types.Object]st if err != nil { panic(err) // shouldn't happen } - // Check if the imported name wasn't - // garbled, e.g. if it's assembly. + // Check if the imported name wasn't garbled, e.g. if it's assembly. if garbledPkg.Scope().Lookup(obj.Name()) != nil { return true } @@ -1090,14 +1083,13 @@ func transformLink(args []string) ([]string, error) { return args, nil } - if err := readBuildIDs(flags); err != nil { + if err := fillBuildInfo(flags); err != nil { return nil, err } - importCfgPath := flagValue(flags, "-importcfg") // there should only ever be one archive/object file passed to the linker, // the file for the main package or entrypoint - garbledImports, privateNameMap, err := obfuscateImports(paths[0], importCfgPath) + garbledImports, privateNameMap, err := obfuscateImports(paths[0], buildInfo.importCfg) if err != nil { return nil, err }