small improvements towards obfuscating the runtime

I spent a couple of days trying to obfuscate all of std.
Ultimately I failed at making it fully work,
especially when it comes to the runtime package,
but I did fix a few problems along the way, as seen here.

First, fix the TODO to allow handleDirectives and transformGo to run on
runtime packages as well, if they are considered private. Note that this
is never true right now, but it matters once we remove runtimeRelated.

Second, modify parsedebugvars in a way that doesn't break typechecking.
We can remove AST nodes or even modify them in simple ways,
but if we add new AST nodes after typechecking,
those will lack type information.

We were replacing the entire body, running into that problem.
Instead, carefully cut the body to set some defaults,
but remove everything from the point GODEBUG is read.

Finally, add commented-out debug prints of transformed asm files.

For #193.
pull/371/head
Daniel Martí 4 years ago committed by lu4p
parent 691a44cecb
commit 5f8bae06b7

@ -583,6 +583,11 @@ func transformAsm(args []string) ([]string, error) {
buf.WriteString(newName)
}
// Uncomment for some quick debugging. Do not delete.
// if curPkg.Private {
// fmt.Fprintf(os.Stderr, "\n-- %s --\n%s", path, buf.Bytes())
// }
name := filepath.Base(path)
if path, err := writeTemp(name, buf.Bytes()); err != nil {
return nil, err
@ -681,13 +686,11 @@ func transformCompile(args []string) ([]string, error) {
for i, file := range files {
name := filepath.Base(paths[i])
// TODO(mvdan): allow running handleDirectives and transformGo
// on runtime too, by splitting the conditionals here.
switch {
case curPkg.ImportPath == "runtime":
switch curPkg.ImportPath {
case "runtime":
// strip unneeded runtime code
stripRuntime(name, file)
case curPkg.ImportPath == "runtime/internal/sys":
case "runtime/internal/sys":
// The first declaration in zversion.go contains the Go
// version as follows. Replace it here, since the
// linker's -X does not work with constants.
@ -706,9 +709,10 @@ func transformCompile(args []string) ([]string, error) {
}
lit := spec.Values[0].(*ast.BasicLit)
lit.Value = "`unknown`"
case strings.HasPrefix(name, "_cgo_"):
}
if strings.HasPrefix(name, "_cgo_") {
// Don't obfuscate cgo code, since it's generated and it gets messy.
default:
} else {
tf.handleDirectives(file.Comments)
file = tf.transformGo(file)
}

@ -75,12 +75,30 @@ func stripRuntime(filename string, file *ast.File) {
break
}
case "runtime1.go":
usesEnv := func(node ast.Node) bool {
seen := false
ast.Inspect(node, func(node ast.Node) bool {
ident, ok := node.(*ast.Ident)
if ok && ident.Name == "gogetenv" {
seen = true
return false
}
return true
})
return seen
}
filenames:
switch x.Name.Name {
case "parsedebugvars":
// set defaults for GODEBUG cgocheck and
// invalidptr, remove code that reads in
// GODEBUG
x.Body = parsedebugvarsStmts
// keep defaults for GODEBUG cgocheck and invalidptr,
// remove code that reads GODEBUG via gogetenv
for i, stmt := range x.Body.List {
if usesEnv(stmt) {
x.Body.List = x.Body.List[:i]
break filenames
}
}
panic("did not see any gogetenv call in parsedebugvars")
case "setTraceback":
// tracebacks are completely hidden, no
// sense keeping this function
@ -127,7 +145,7 @@ func stripRuntime(filename string, file *ast.File) {
// generic solution like x/tools/imports.
for _, imp := range file.Imports {
if imp.Path.Value == `"internal/bytealg"` {
file.Decls = append(file.Decls, markUsedBytealg)
imp.Name = &ast.Ident{Name: "_"}
break
}
}
@ -154,17 +172,6 @@ func removeImport(importPath string, specs []ast.Spec) []ast.Spec {
return specs
}
var markUsedBytealg = &ast.GenDecl{
Tok: token.VAR,
Specs: []ast.Spec{&ast.ValueSpec{
Names: []*ast.Ident{{Name: "_"}},
Values: []ast.Expr{&ast.SelectorExpr{
X: &ast.Ident{Name: "bytealg"},
Sel: &ast.Ident{Name: "IndexByteString"},
}},
}},
}
var hidePrintDecl = &ast.FuncDecl{
Name: ast.NewIdent("hidePrint"),
Type: &ast.FuncType{Params: &ast.FieldList{
@ -177,22 +184,3 @@ var hidePrintDecl = &ast.FuncDecl{
}},
Body: &ast.BlockStmt{},
}
var parsedebugvarsStmts = ah.BlockStmt(
&ast.AssignStmt{
Lhs: []ast.Expr{&ast.SelectorExpr{
X: ast.NewIdent("debug"),
Sel: ast.NewIdent("cgocheck"),
}},
Tok: token.ASSIGN,
Rhs: []ast.Expr{ah.IntLit(1)},
},
&ast.AssignStmt{
Lhs: []ast.Expr{&ast.SelectorExpr{
X: ast.NewIdent("debug"),
Sel: ast.NewIdent("invalidptr"),
}},
Tok: token.ASSIGN,
Rhs: []ast.Expr{ah.IntLit(1)},
},
)

Loading…
Cancel
Save