start hashing identifiers

pull/22/head
Daniel Martí 5 years ago
parent f47c12caba
commit f4e356ab13

@ -4,8 +4,16 @@
package main
import (
"crypto/sha256"
"encoding/base64"
"flag"
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
@ -29,7 +37,14 @@ Usage of garble:
func main() { os.Exit(main1()) }
var workingDir string
var (
workingDir string
deferred []func() error
fset = token.NewFileSet()
b64 = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_z")
printerConfig = printer.Config{Mode: printer.RawFormat}
)
func main1() int {
if err := flagSet.Parse(os.Args[1:]); err != nil {
@ -57,6 +72,13 @@ func main1() int {
return 1
}
}
defer func() {
for _, fn := range deferred {
if err := fn(); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
}()
cmd := exec.Command(args[0], transformed...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -83,9 +105,74 @@ func transformCompile(args []string) ([]string, error) {
if !strings.Contains(trimpath, workingDir) {
return nil, fmt.Errorf("-toolexec=garble should be used alongside -trimpath")
}
std := flagValue(flags, "-std") == "true"
buildid := flagValue(flags, "-buildid")
for i, file := range files {
if std {
continue
}
var err error
files[i], err = transformGoFile(buildid, file)
if err != nil {
return nil, err
}
}
return append(flags, files...), nil
}
func hashWith(salt, value string) string {
const length = 8
d := sha256.New()
io.WriteString(d, salt)
io.WriteString(d, value)
sum := b64.EncodeToString(d.Sum(nil))
for i := 0; i < len(sum)-length; i++ {
if '0' <= sum[i] && sum[i] <= '9' {
continue
}
return sum[i : i+length]
}
return "_" + sum[:length-1]
}
// transformGoFile creates a garbled copy of the Go file at path, and returns
// the path to the copy.
func transformGoFile(buildid, path string) (string, error) {
file, err := parser.ParseFile(fset, path, nil, 0)
if err != nil {
return "", err
}
ast.Inspect(file, func(node ast.Node) bool {
switch node := node.(type) {
case *ast.Ident:
switch {
case node.Obj == nil:
// a builtin name, or the package name
case node.Name == "main":
// possibly the main func
default:
node.Name = hashWith(buildid, node.Name)
}
}
return true
})
f, err := ioutil.TempFile("", "garble")
if err != nil {
return "", err
}
defer f.Close()
printerConfig.Fprint(os.Stderr, fset, file)
if err := printerConfig.Fprint(f, fset, file); err != nil {
return "", err
}
if err := f.Close(); err != nil {
return "", err
}
return f.Name(), nil
}
func transformLink(args []string) ([]string, error) {
flags, files := splitFlagsFromFiles(args, ".a")
if len(files) == 0 {
@ -117,9 +204,15 @@ func flagValue(flags []string, name string) string {
// -name=value
return val
}
if arg == name && i+1 < len(flags) {
// -name value
return flags[i+1]
if arg == name {
if i+1 < len(flags) {
if val := flags[i+1]; !strings.HasPrefix(val, "-") {
// -name value
return flags[i+1]
}
}
// -name, equivalent to -name=true
return "true"
}
}
return ""

@ -40,9 +40,8 @@ exec readelf --section-details --symbols main
! grep $WORK main
# TODO
# ! grep 'globalVar' main
# ! grep 'globalFunc' main
! grep 'globalVar' main
! grep 'globalFunc' main
-- main.go --
package main

Loading…
Cancel
Save