mirror of
https://github.com/burrowers/garble.git
synced 2026-04-22 15:47:04 +08:00
internal/literals: simplify the obfuscator selection code
The "next obfuscator" logic was split into three funcs for no reason; it all fits into a single function in less than a dozen lines. While here, avoid calling the obfRand variables the same as the type itself, as that leads to significant confusion.
This commit is contained in:
@@ -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))]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
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)}
|
||||
|
||||
Reference in New Issue
Block a user