diff --git a/main.go b/main.go index 7865b30a..7a37d144 100644 --- a/main.go +++ b/main.go @@ -649,12 +649,10 @@ func transformAsm(args []string) ([]string, error) { // The different name ensures we don't use the unobfuscated file. // This is far from perfect, but does the job for the time being. // In the future, use a randomized name. - newPath = "garbled_" + filepath.Base(path) + basename := filepath.Base(path) + newPath = "garbled_" + basename - // Uncomment for some quick debugging. Do not delete. - // fmt.Fprintf(os.Stderr, "\n-- %s --\n%s", path, buf.Bytes()) - - if _, err := writeTemp(newPath, buf.Bytes()); err != nil { + if _, err := writeSourceFile(basename, newPath, buf.Bytes()); err != nil { return nil, err } newHeaderPaths[path] = newPath @@ -670,13 +668,11 @@ func transformAsm(args []string) ([]string, error) { buf.Reset() replaceAsmNames(&buf, content) - // Uncomment for some quick debugging. Do not delete. - // fmt.Fprintf(os.Stderr, "\n-- %s --\n%s", path, buf.Bytes()) - // With assembly files, we obfuscate the filename in the temporary // directory, as assembly files do not support `/*line` directives. - name := hashWithPackage(curPkg, filepath.Base(path)) - if path, err := writeTemp(name, buf.Bytes()); err != nil { + basename := filepath.Base(path) + newName := hashWithPackage(curPkg, basename) + if path, err := writeSourceFile(basename, newName, buf.Bytes()); err != nil { return nil, err } else { newPaths = append(newPaths, path) @@ -778,12 +774,25 @@ func replaceAsmNames(buf *bytes.Buffer, remaining []byte) { } } -// writeTemp is a mix between os.CreateTemp and os.WriteFile, as it writes a +// writeSourceFile is a mix between os.CreateTemp and os.WriteFile, as it writes a // named source file in sharedTempDir given an input buffer. // // Note that the file is created under a directory tree following curPkg's // import path, mimicking how files are laid out in modules and GOROOT. -func writeTemp(name string, content []byte) (string, error) { +func writeSourceFile(basename, obfuscated string, content []byte) (string, error) { + // Uncomment for some quick debugging. Do not delete. + // fmt.Fprintf(os.Stderr, "\n-- %s/%s --\n%s", curPkg.ImportPath, basename, content) + + if flagDebugDir != "" { + pkgDir := filepath.Join(flagDebugDir, filepath.FromSlash(curPkg.ImportPath)) + if err := os.MkdirAll(pkgDir, 0o755); err != nil { + return "", err + } + dstPath := filepath.Join(pkgDir, basename) + if err := os.WriteFile(dstPath, content, 0o666); err != nil { + return "", err + } + } // We use the obfuscated import path to hold the temporary files. // Assembly files do not support line directives to set positions, // so the only way to not leak the import path is to replace it. @@ -791,7 +800,7 @@ func writeTemp(name string, content []byte) (string, error) { if err := os.MkdirAll(pkgDir, 0o777); err != nil { return "", err } - dstPath := filepath.Join(pkgDir, name) + dstPath := filepath.Join(pkgDir, obfuscated) if err := writeFileExclusive(dstPath, content); err != nil { return "", err } @@ -859,11 +868,11 @@ func transformCompile(args []string) ([]string, error) { newPaths := make([]string, 0, len(files)) for i, file := range files { - filename := filepath.Base(paths[i]) - log.Printf("obfuscating %s", filename) + basename := filepath.Base(paths[i]) + log.Printf("obfuscating %s", basename) if curPkg.ImportPath == "runtime" && flagTiny { // strip unneeded runtime code - stripRuntime(filename, file) + stripRuntime(basename, file) tf.removeUnnecessaryImports(file) } tf.handleDirectives(file.Comments) @@ -897,26 +906,13 @@ func transformCompile(args []string) ([]string, error) { )...) } - // Uncomment for some quick debugging. Do not delete. - // fmt.Fprintf(os.Stderr, "\n-- %s/%s --\n%s", curPkg.ImportPath, filename, src) - - if path, err := writeTemp(filename, src); err != nil { + // We hide Go source filenames via "//line" directives, + // so there is no need to use obfuscated filenames here. + if path, err := writeSourceFile(basename, basename, src); err != nil { return nil, err } else { newPaths = append(newPaths, path) } - if flagDebugDir != "" { - osPkgPath := filepath.FromSlash(curPkg.ImportPath) - pkgDebugDir := filepath.Join(flagDebugDir, osPkgPath) - if err := os.MkdirAll(pkgDebugDir, 0o755); err != nil { - return nil, err - } - - debugFilePath := filepath.Join(pkgDebugDir, filename) - if err := os.WriteFile(debugFilePath, src, 0o666); err != nil { - return nil, err - } - } } flags = flagSetValue(flags, "-importcfg", newImportCfg) diff --git a/runtime_strip.go b/runtime_strip.go index c3f04994..9ed58257 100644 --- a/runtime_strip.go +++ b/runtime_strip.go @@ -13,7 +13,7 @@ import ( // stripRuntime removes unnecessary code from the runtime, // such as panic and fatal error printing, and code that // prints trace/debug info of the runtime. -func stripRuntime(filename string, file *ast.File) { +func stripRuntime(basename string, file *ast.File) { stripPrints := func(node ast.Node) bool { call, ok := node.(*ast.CallExpr) if !ok { @@ -39,7 +39,7 @@ func stripRuntime(filename string, file *ast.File) { continue } - switch filename { + switch basename { case "error.go": // only used in panics switch funcDecl.Name.Name { @@ -120,7 +120,7 @@ func stripRuntime(filename string, file *ast.File) { } - if filename == "print.go" { + if basename == "print.go" { file.Decls = append(file.Decls, hidePrintDecl) return } diff --git a/testdata/script/debugdir.txtar b/testdata/script/debugdir.txtar index c29b7528..40f4ac93 100644 --- a/testdata/script/debugdir.txtar +++ b/testdata/script/debugdir.txtar @@ -2,6 +2,9 @@ env GOGARBLE=* garble -debugdir ./debug1 build exists 'debug1/test/main/imported/imported.go' 'debug1/test/main/main.go' 'debug1/reflect/type.go' +exists 'debug1/runtime/map.go' 'debug1/runtime/funcdata.h' 'debug1/runtime/asm.s' +[amd64] exists 'debug1/runtime/cpuflags_amd64.go' 'debug1/runtime/asm_amd64.s' +[!amd64] ! exists 'debug1/runtime/cpuflags_amd64.go' 'debug1/runtime/asm_amd64.s' ! grep ImportedFunc $WORK/debug1/test/main/imported/imported.go ! grep ImportedFunc $WORK/debug1/test/main/main.go ! grep 'some comment' $WORK/debug1/test/main/main.go