diff --git a/internal/literals/literals.go b/internal/literals/literals.go index 58bcbea..85b6e54 100644 --- a/internal/literals/literals.go +++ b/internal/literals/literals.go @@ -40,7 +40,7 @@ type NameProviderFunc func(rand *mathrand.Rand, baseName string) string // Obfuscate replaces literals with obfuscated anonymous functions. func Obfuscate(rand *mathrand.Rand, file *ast.File, info *types.Info, linkStrings map[*types.Var]string, nameFunc NameProviderFunc) *ast.File { - obfRand := newObfRand(rand, file, nameFunc) + or := newObfRand(rand, file, nameFunc) pre := func(cursor *astutil.Cursor) bool { switch node := cursor.Node().(type) { case *ast.FuncDecl: @@ -89,7 +89,7 @@ func Obfuscate(rand *mathrand.Rand, file *ast.File, info *types.Info, linkString return true } - cursor.Replace(withPos(obfuscateString(obfRand, value), node.Pos())) + cursor.Replace(withPos(obfuscateString(or, value), node.Pos())) return true } @@ -106,7 +106,7 @@ func Obfuscate(rand *mathrand.Rand, file *ast.File, info *types.Info, linkString } if child, ok := node.X.(*ast.CompositeLit); ok { - newnode := handleCompositeLiteral(obfRand, true, child, info) + newnode := handleCompositeLiteral(or, true, child, info) if newnode != nil { cursor.Replace(newnode) } @@ -125,7 +125,7 @@ func Obfuscate(rand *mathrand.Rand, file *ast.File, info *types.Info, linkString return true } - newnode := handleCompositeLiteral(obfRand, false, node, info) + newnode := handleCompositeLiteral(or, false, node, info) if newnode != nil { cursor.Replace(newnode) } @@ -135,7 +135,7 @@ func Obfuscate(rand *mathrand.Rand, file *ast.File, info *types.Info, linkString } newFile := astutil.Apply(file, pre, post).(*ast.File) - obfRand.proxyDispatcher.AddToFile(newFile) + or.proxyDispatcher.AddToFile(newFile) return newFile } @@ -144,7 +144,7 @@ func Obfuscate(rand *mathrand.Rand, file *ast.File, info *types.Info, linkString // be used to replace it. // // If the input node cannot be obfuscated nil is returned. -func handleCompositeLiteral(obfRand *obfRand, isPointer bool, node *ast.CompositeLit, info *types.Info) ast.Node { +func handleCompositeLiteral(or *obfRand, isPointer bool, node *ast.CompositeLit, info *types.Info) ast.Node { if len(node.Elts) < MinSize || len(node.Elts) > MaxSize { return nil } @@ -187,10 +187,10 @@ func handleCompositeLiteral(obfRand *obfRand, isPointer bool, node *ast.Composit } if arrayLen > 0 { - return withPos(obfuscateByteArray(obfRand, isPointer, data, arrayLen), node.Pos()) + return withPos(obfuscateByteArray(or, isPointer, data, arrayLen), node.Pos()) } - return withPos(obfuscateByteSlice(obfRand, isPointer, data), node.Pos()) + return withPos(obfuscateByteSlice(or, isPointer, data), node.Pos()) } // withPos sets any token.Pos fields under node which affect printing to pos. @@ -237,22 +237,22 @@ func withPos(node ast.Node, pos token.Pos) ast.Node { return node } -func obfuscateString(obfRand *obfRand, data string) *ast.CallExpr { - obf := getNextObfuscator(obfRand, len(data)) +func obfuscateString(or *obfRand, data string) *ast.CallExpr { + obf := or.pickObfuscator(len(data)) // Generate junk bytes to to prepend and append to the data. // This is to prevent the obfuscated string from being easily fingerprintable. - junkBytes := make([]byte, obfRand.Intn(maxStringJunkBytes-minStringJunkBytes)+minStringJunkBytes) - obfRand.Read(junkBytes) - splitIdx := obfRand.Intn(len(junkBytes)) + junkBytes := make([]byte, or.rnd.Intn(maxStringJunkBytes-minStringJunkBytes)+minStringJunkBytes) + or.rnd.Read(junkBytes) + splitIdx := or.rnd.Intn(len(junkBytes)) - extKeys := randExtKeys(obfRand.Rand) + extKeys := randExtKeys(or.rnd) plainData := []byte(data) plainDataWithJunkBytes := append(append(junkBytes[:splitIdx], plainData...), junkBytes[splitIdx:]...) - block := obf.obfuscate(obfRand.Rand, plainDataWithJunkBytes, extKeys) - params, args := extKeysToParams(obfRand, extKeys) + block := obf.obfuscate(or.rnd, plainDataWithJunkBytes, extKeys) + params, args := extKeysToParams(or, extKeys) // Generate unique cast bytes to string function and hide it using proxyDispatcher: // @@ -289,16 +289,16 @@ func obfuscateString(obfRand *obfRand, data string) *ast.CallExpr { ), ), } - block.List = append(block.List, ah.ReturnStmt(ah.CallExpr(obfRand.proxyDispatcher.HideValue(funcVal, funcTyp), ast.NewIdent("data")))) + block.List = append(block.List, ah.ReturnStmt(ah.CallExpr(or.proxyDispatcher.HideValue(funcVal, funcTyp), ast.NewIdent("data")))) return ah.LambdaCall(params, ast.NewIdent("string"), block, args) } -func obfuscateByteSlice(obfRand *obfRand, isPointer bool, data []byte) *ast.CallExpr { - obf := getNextObfuscator(obfRand, len(data)) +func obfuscateByteSlice(or *obfRand, isPointer bool, data []byte) *ast.CallExpr { + obf := or.pickObfuscator(len(data)) - extKeys := randExtKeys(obfRand.Rand) - block := obf.obfuscate(obfRand.Rand, data, extKeys) - params, args := extKeysToParams(obfRand, extKeys) + extKeys := randExtKeys(or.rnd) + block := obf.obfuscate(or.rnd, data, extKeys) + params, args := extKeysToParams(or, extKeys) if isPointer { block.List = append(block.List, ah.ReturnStmt( @@ -311,12 +311,12 @@ func obfuscateByteSlice(obfRand *obfRand, isPointer bool, data []byte) *ast.Call return ah.LambdaCall(params, ah.ByteSliceType(), block, args) } -func obfuscateByteArray(obfRand *obfRand, isPointer bool, data []byte, length int64) *ast.CallExpr { - obf := getNextObfuscator(obfRand, len(data)) +func obfuscateByteArray(or *obfRand, isPointer bool, data []byte, length int64) *ast.CallExpr { + obf := or.pickObfuscator(len(data)) - extKeys := randExtKeys(obfRand.Rand) - block := obf.obfuscate(obfRand.Rand, data, extKeys) - params, args := extKeysToParams(obfRand, extKeys) + extKeys := randExtKeys(or.rnd) + block := obf.obfuscate(or.rnd, data, extKeys) + params, args := extKeysToParams(or, extKeys) arrayType := ah.ByteArrayType(length) @@ -358,12 +358,15 @@ func obfuscateByteArray(obfRand *obfRand, isPointer bool, data []byte, length in return ah.LambdaCall(params, arrayType, block, args) } -func getNextObfuscator(obfRand *obfRand, size int) obfuscator { +func (or *obfRand) pickObfuscator(size int) obfuscator { if size < MinSize || size > MaxSize { - panic(fmt.Sprintf("getNextObfuscator called with size %d outside [%d, %d]", size, MinSize, MaxSize)) + panic(fmt.Sprintf("nextObfuscator called with size %d outside [%d, %d]", size, MinSize, MaxSize)) + } + if or.testObfuscator != nil { + return or.testObfuscator } if size <= MaxSizeExpensive { - return obfRand.nextObfuscator() + return Obfuscators[or.rnd.Intn(len(Obfuscators))] } - return obfRand.nextCheapObfuscator() + return CheapObfuscators[or.rnd.Intn(len(CheapObfuscators))] } diff --git a/internal/literals/obfuscators.go b/internal/literals/obfuscators.go index 368fc3a..c2f6a69 100644 --- a/internal/literals/obfuscators.go +++ b/internal/literals/obfuscators.go @@ -178,7 +178,7 @@ func extKeysToParams(objRand *obfRand, keys []*externalKey) (params *ast.FieldLi params.List = append(params.List, ah.Field(key.Type(), name)) var extKeyExpr ast.Expr = ah.UintLit(key.value) - if lowProb.Try(objRand.Rand) { + if lowProb.Try(objRand.rnd) { extKeyExpr = objRand.proxyDispatcher.HideValue(extKeyExpr, ast.NewIdent(key.typ)) } args = append(args, extKeyExpr) @@ -255,26 +255,12 @@ func byteLitWithExtKey(rand *mathrand.Rand, val byte, extKeys []*externalKey, ex } type obfRand struct { - *mathrand.Rand - testObfuscator obfuscator + rnd *mathrand.Rand + testObfuscator obfuscator proxyDispatcher *proxyDispatcher } -func (r *obfRand) nextObfuscator() obfuscator { - if r.testObfuscator != nil { - return r.testObfuscator - } - return Obfuscators[r.Intn(len(Obfuscators))] -} - -func (r *obfRand) nextCheapObfuscator() obfuscator { - if r.testObfuscator != nil { - return r.testObfuscator - } - return CheapObfuscators[r.Intn(len(CheapObfuscators))] -} - func newObfRand(rand *mathrand.Rand, file *ast.File, nameFunc NameProviderFunc) *obfRand { testObf := testPkgToObfuscatorMap[file.Name.Name] return &obfRand{rand, testObf, newProxyDispatcher(rand, nameFunc)}