Skip to content

Commit

Permalink
teach -debugdir to produce assembly files too
Browse files Browse the repository at this point in the history
Up to this point, -debugdir only included obfuscated Go files.
Include assembly files and their headers as well.
While here, ensure that -debugdir supports the standard library too,
and that it behaves correctly with build tags as well.

Also use more consistent names for path strings, to clarify which are
only the basename, and which are the obfuscated version.
  • Loading branch information
mvdan committed Nov 14, 2022
1 parent 12bc034 commit 7d59183
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 35 deletions.
60 changes: 28 additions & 32 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -778,20 +774,33 @@ 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.
pkgDir := filepath.Join(sharedTempDir, curPkg.obfuscatedImportPath())
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
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand Down
6 changes: 3 additions & 3 deletions runtime_strip.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down
3 changes: 3 additions & 0 deletions testdata/script/debugdir.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7d59183

Please sign in to comment.