diff --git a/main.go b/main.go index d9405d51..29037456 100644 --- a/main.go +++ b/main.go @@ -1283,11 +1283,28 @@ func (tf *transformer) transformGo(file *ast.File) *ast.File { } obj := tf.info.ObjectOf(node) if obj == nil { - return true + _, isImplicit := tf.info.Defs[node] + _, parentIsFile := cursor.Parent().(*ast.File) + if isImplicit && !parentIsFile { + // In a type switch like "switch foo := bar.(type) {", + // "foo" is being declared as a symbolic variable, + // as it is only actually declared in each "case SomeType:". + // + // As such, the symbolic "foo" in the syntax tree has no object, + // but it is still recorded under Defs with a nil value. + // We still want to obfuscate that syntax tree identifier, + // so if we detect the case, create a dummy types.Var for it. + // + // Note that "package mypkg" also denotes a nil object in Defs, + // and we don't want to treat that "mypkg" as a variable, + // so avoid that case by checking the type of cursor.Parent. + obj = types.NewVar(node.Pos(), tf.pkg, node.Name, nil) + } else { + return true + } } pkg := obj.Pkg() if vr, ok := obj.(*types.Var); ok && vr.Embedded() { - // The docs for ObjectOf say: // // If id is an embedded struct field, ObjectOf returns the @@ -1364,16 +1381,10 @@ func (tf *transformer) transformGo(file *ast.File) *ast.File { hashToUse := lpkg.GarbleActionID // log.Printf("%s: %#v %T", fset.Position(node.Pos()), node, obj) - parentScope := obj.Parent() switch obj := obj.(type) { case *types.Var: - if parentScope != nil && parentScope != pkg.Scope() { - // Identifiers of non-global variables never show up in the binary. - return true - } - if !obj.IsField() { - // Identifiers of global variables are always obfuscated. + // Identifiers denoting variables are always obfuscated. break } // From this point on, we deal with struct fields. @@ -1423,11 +1434,6 @@ func (tf *transformer) transformGo(file *ast.File) *ast.File { } } case *types.TypeName: - if parentScope != pkg.Scope() { - // Identifiers of non-global types never show up in the binary. - return true - } - // If the type was not obfuscated in the package were it was defined, // do not obfuscate it here. if path != curPkg.ImportPath { diff --git a/testdata/scripts/literals.txt b/testdata/scripts/literals.txt index 9fb8b631..178c3b34 100644 --- a/testdata/scripts/literals.txt +++ b/testdata/scripts/literals.txt @@ -5,7 +5,7 @@ exec ./main$exe cmp stderr main.stderr binsubstr main$exe 'Skip this block' 'also skip this' 'skip typed const' 'skip typed var' 'skip typed var assign' 'stringTypeField strType' 'stringType lambda func return' 'testMap1 key' 'testMap2 key' 'testMap3 key' 'testMap1 value' 'testMap3 value' 'testMap1 new value' 'testMap3 new value' 'stringType func param' 'stringType return' 'skip untyped const' -! binsubstr main$exe 'garbleDecrypt' 'Lorem' 'dolor' 'first assign' 'second assign' 'First Line' 'Second Line' 'map value' '1: literal in' 'an array' '2: literal in' 'a slice' 'to obfuscate' 'also obfuscate' 'stringTypeField String' +! binsubstr main$exe 'garbleDecrypt' 'Lorem' 'dolor' 'first assign' 'second assign' 'First Line' 'Second Line' 'map value' 'obfuscated with shadowed builtins' '1: literal in' 'an array' '2: literal in' 'a slice' 'to obfuscate' 'also obfuscate' 'stringTypeField String' [short] stop # checking that the build is reproducible is slow @@ -136,6 +136,7 @@ func main() { typedTest() constantTest() byteTest() + shadowTest() strArray := [2]string{"1: literal in", "an array"} println(strArray[0], strArray[1]) @@ -266,11 +267,31 @@ func stringTypeFunc(s stringType) stringType { return "stringType return" // skip } + // obfuscating this broke before const ( iota0 uint8 = iota iota1 ) + +// Our inserted code used to break due to the shadowed builtins. +// The name "fnc" is used as a func var name in garble's inserted code. +func shadowTest() { + { + var append, bool, string, fnc int + _, _, _, _ = append, bool, string, fnc + + println("obfuscated with shadowed builtins (vars)") + } + { + type append int + type bool int + type string int + type fnc int + + println("obfuscated with shadowed builtins (types)") + } +} -- imported/imported.go -- package imported @@ -352,5 +373,7 @@ foo 12,13, 12,13,0,0, Complex +obfuscated with shadowed builtins (vars) +obfuscated with shadowed builtins (types) 1: literal in an array 2: literal in a slice