From c1672cdc0d1e3956b42a8558eb9110a2e380bdbb Mon Sep 17 00:00:00 2001 From: lu4p Date: Tue, 1 Jun 2021 18:29:28 +0200 Subject: [PATCH] Obfuscate more byte slice literals Slices with hex, octal, binary and rune elements are now obfuscated. --- internal/literals/literals.go | 62 +++++++++++++++++------------------ testdata/scripts/literals.txt | 7 ++++ 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/internal/literals/literals.go b/internal/literals/literals.go index df41c25..9ed5bdc 100644 --- a/internal/literals/literals.go +++ b/internal/literals/literals.go @@ -81,63 +81,63 @@ func Obfuscate(file *ast.File, info *types.Info, fset *token.FileSet, ignoreObj case *ast.CompositeLit: byteType := types.Universe.Lookup("byte").Type() - if len(x.Elts) == 0 { + if len(x.Elts) == 0 || len(x.Elts) > maxSizeBytes { return true } + var arrayLen int64 switch y := info.TypeOf(x.Type).(type) { case *types.Array: if y.Elem() != byteType { return true } - if y.Len() > maxSizeBytes { - return true - } - - data := make([]byte, y.Len()) - - for i, el := range x.Elts { - lit, ok := el.(*ast.BasicLit) - if !ok { - return true - } - value, err := strconv.Atoi(lit.Value) - if err != nil { - return true - } - - data[i] = byte(value) - } - cursor.Replace(withPos(obfuscateByteArray(data, y.Len()), x.Pos())) + arrayLen = y.Len() case *types.Slice: if y.Elem() != byteType { return true } - if len(x.Elts) > maxSizeBytes { - return true - } - data := make([]byte, 0, len(x.Elts)) + default: + return true + } - for _, el := range x.Elts { - lit, ok := el.(*ast.BasicLit) - if !ok { + data := make([]byte, 0, len(x.Elts)) + + for _, el := range x.Elts { + lit, ok := el.(*ast.BasicLit) + if !ok { + return true + } + var value byte + if lit.Kind == token.CHAR { + val, _, _, err := strconv.UnquoteChar(lit.Value, '\'') + if err != nil { return true } - value, err := strconv.Atoi(lit.Value) + value = byte(val) + } else { + val, err := strconv.ParseUint(lit.Value, 0, 8) if err != nil { return true } - data = append(data, byte(value)) + value = byte(val) } - cursor.Replace(withPos(obfuscateByteSlice(data), x.Pos())) + data = append(data, value) } + if arrayLen > 0 { + cursor.Replace(withPos(obfuscateByteArray(data, arrayLen), x.Pos())) + } else { + cursor.Replace(withPos(obfuscateByteSlice(data), x.Pos())) + } + + return true + case *ast.BasicLit: switch cursor.Name() { case "Values", "Rhs", "Value", "Args", "X", "Y", "Results", "Elts": @@ -256,7 +256,7 @@ func obfuscateByteArray(data []byte, length int64) *ast.CallExpr { &ast.RangeStmt{ Key: ast.NewIdent("i"), Tok: token.DEFINE, - X: ast.NewIdent("newdata"), + X: ast.NewIdent("data"), Body: &ast.BlockStmt{List: []ast.Stmt{ &ast.AssignStmt{ Lhs: []ast.Expr{ah.IndexExpr("newdata", ast.NewIdent("i"))}, diff --git a/testdata/scripts/literals.txt b/testdata/scripts/literals.txt index e2e8a06..fcc3b08 100644 --- a/testdata/scripts/literals.txt +++ b/testdata/scripts/literals.txt @@ -220,6 +220,9 @@ func constantTest() { const impType = imported.ImportedType(3) } +// TODO: this only tests, that we don't break byte slices +// it was verified manually that these actually get obfuscated, +// however we should add regression tests func byteTest() { a := []byte{12, 13} for _, elm := range a { @@ -245,6 +248,9 @@ func byteTest() { print(elm, ",") } println() + + e := []byte{0x43, 11_1, 0b01101101, 'p', 'l', 'e', 'x'} + println(string(e)) } func stringTypeFunc(s stringType) stringType { @@ -337,5 +343,6 @@ foo 12,13, 12,13, 12,13,0,0, +Complex 1: literal in an array 2: literal in a slice