From edcdaf3e35896859ee4c4df5c7223682ba6dcdff Mon Sep 17 00:00:00 2001 From: Paul Scheduikat Date: Tue, 3 Jun 2025 02:03:16 +0200 Subject: [PATCH] cleanup --- internal/asthelper/asthelper.go | 57 +++++++++++++++ internal/literals/literals.go | 65 ++++++++--------- internal/literals/obfuscators.go | 115 ++++++++++++++----------------- internal/literals/seed.go | 8 +-- internal/literals/shuffle.go | 18 ++--- internal/literals/simple.go | 11 +-- internal/literals/split.go | 22 +++--- internal/literals/swap.go | 14 ++-- 8 files changed, 172 insertions(+), 138 deletions(-) diff --git a/internal/asthelper/asthelper.go b/internal/asthelper/asthelper.go index 2198f57..31df657 100644 --- a/internal/asthelper/asthelper.go +++ b/internal/asthelper/asthelper.go @@ -140,6 +140,63 @@ func IndexExprByExpr(xExpr, indexExpr ast.Expr) *ast.IndexExpr { return &ast.IndexExpr{X: xExpr, Index: indexExpr} } +// UnaryExpr creates a unary expression with the given operator and operand +func UnaryExpr(op token.Token, x ast.Expr) *ast.UnaryExpr { + return &ast.UnaryExpr{ + Op: op, + X: x, + } +} + +// StarExpr creates a pointer type expression "*x" +func StarExpr(x ast.Expr) *ast.StarExpr { + return &ast.StarExpr{X: x} +} + +// ArrayType creates an array type expression "[len]eltType" +func ArrayType(len ast.Expr, eltType ast.Expr) *ast.ArrayType { + return &ast.ArrayType{ + Len: len, + Elt: eltType, + } +} + +// ByteArrayType creates a byte array type "[len]byte" +func ByteArrayType(len int64) *ast.ArrayType { + lenLit := IntLit(int(len)) + return ArrayType(lenLit, ast.NewIdent("byte")) +} + +// ByteSliceType creates a byte slice type "[]byte" +func ByteSliceType() *ast.ArrayType { + return &ast.ArrayType{Elt: ast.NewIdent("byte")} +} + +// BinaryExpr creates a binary expression "x op y" +func BinaryExpr(x ast.Expr, op token.Token, y ast.Expr) *ast.BinaryExpr { + return &ast.BinaryExpr{ + X: x, + Op: op, + Y: y, + } +} + +// UintLit returns an ast.BasicLit of kind INT for uint64 values +func UintLit(value uint64) *ast.BasicLit { + return &ast.BasicLit{ + Kind: token.INT, + Value: fmt.Sprint(value), + } +} + +// Field creates a field with names and type for function parameters or struct fields +func Field(typ ast.Expr, names ...*ast.Ident) *ast.Field { + return &ast.Field{ + Names: names, + Type: typ, + } +} + func ConstToAst(val constant.Value) ast.Expr { switch val.Kind() { case constant.Bool: diff --git a/internal/literals/literals.go b/internal/literals/literals.go index 2c68ef24..c664989 100644 --- a/internal/literals/literals.go +++ b/internal/literals/literals.go @@ -226,9 +226,10 @@ func withPos(node ast.Node, pos token.Pos) ast.Node { func obfuscateString(obfRand *obfRand, data string) *ast.CallExpr { obf := getNextObfuscator(obfRand, 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)) extKeys := randExtKeys(obfRand.Rand) @@ -246,7 +247,7 @@ func obfuscateString(obfRand *obfRand, data string) *ast.CallExpr { // } funcTyp := &ast.FuncType{ Params: &ast.FieldList{List: []*ast.Field{{ - Type: &ast.ArrayType{Elt: ast.NewIdent("byte")}, + Type: ah.ByteSliceType(), }}}, Results: &ast.FieldList{List: []*ast.Field{{ Type: ast.NewIdent("string"), @@ -256,26 +257,23 @@ func obfuscateString(obfRand *obfRand, data string) *ast.CallExpr { Type: &ast.FuncType{ Params: &ast.FieldList{List: []*ast.Field{{ Names: []*ast.Ident{ast.NewIdent("x")}, - Type: &ast.ArrayType{Elt: ast.NewIdent("byte")}, + Type: ah.ByteSliceType(), }}}, Results: &ast.FieldList{List: []*ast.Field{{ Type: ast.NewIdent("string"), }}}, }, - Body: &ast.BlockStmt{List: []ast.Stmt{ - &ast.ReturnStmt{Results: []ast.Expr{ - &ast.CallExpr{ - Fun: ast.NewIdent("string"), - Args: []ast.Expr{ - &ast.SliceExpr{ - X: ast.NewIdent("x"), - Low: ah.IntLit(splitIdx), - High: ah.IntLit(splitIdx + len(plainData)), - }, + Body: ah.BlockStmt( + ah.ReturnStmt( + ah.CallExprByName("string", + &ast.SliceExpr{ + X: ast.NewIdent("x"), + Low: ah.IntLit(splitIdx), + High: ah.IntLit(splitIdx + len(plainData)), }, - }, - }}, - }}, + ), + ), + ), } block.List = append(block.List, ah.ReturnStmt(ah.CallExpr(obfRand.proxyDispatcher.HideValue(funcVal, funcTyp), ast.NewIdent("data")))) return ah.LambdaCall(params, ast.NewIdent("string"), block, args) @@ -289,17 +287,14 @@ func obfuscateByteSlice(obfRand *obfRand, isPointer bool, data []byte) *ast.Call params, args := extKeysToParams(obfRand, extKeys) if isPointer { - block.List = append(block.List, ah.ReturnStmt(&ast.UnaryExpr{ - Op: token.AND, - X: ast.NewIdent("data"), - })) - return ah.LambdaCall(params, &ast.StarExpr{ - X: &ast.ArrayType{Elt: ast.NewIdent("byte")}, - }, block, args) + block.List = append(block.List, ah.ReturnStmt( + ah.UnaryExpr(token.AND, ast.NewIdent("data")), + )) + return ah.LambdaCall(params, ah.StarExpr(ah.ByteSliceType()), block, args) } block.List = append(block.List, ah.ReturnStmt(ast.NewIdent("data"))) - return ah.LambdaCall(params, &ast.ArrayType{Elt: ast.NewIdent("byte")}, block, args) + return ah.LambdaCall(params, ah.ByteSliceType(), block, args) } func obfuscateByteArray(obfRand *obfRand, isPointer bool, data []byte, length int64) *ast.CallExpr { @@ -309,10 +304,7 @@ func obfuscateByteArray(obfRand *obfRand, isPointer bool, data []byte, length in block := obf.obfuscate(obfRand.Rand, data, extKeys) params, args := extKeysToParams(obfRand, extKeys) - arrayType := &ast.ArrayType{ - Len: ah.IntLit(int(length)), - Elt: ast.NewIdent("byte"), - } + arrayType := ah.ByteArrayType(length) sliceToArray := []ast.Stmt{ &ast.DeclStmt{ @@ -328,26 +320,25 @@ func obfuscateByteArray(obfRand *obfRand, isPointer bool, data []byte, length in Key: ast.NewIdent("i"), Tok: token.DEFINE, X: ast.NewIdent("data"), - Body: &ast.BlockStmt{List: []ast.Stmt{ - &ast.AssignStmt{ - Lhs: []ast.Expr{ah.IndexExpr("newdata", ast.NewIdent("i"))}, - Tok: token.ASSIGN, - Rhs: []ast.Expr{ah.IndexExpr("data", ast.NewIdent("i"))}, - }, - }}, + Body: ah.BlockStmt( + ah.AssignStmt( + ah.IndexExprByExpr(ast.NewIdent("newdata"), ast.NewIdent("i")), + ah.IndexExprByExpr(ast.NewIdent("data"), ast.NewIdent("i")), + ), + ), }, } var retexpr ast.Expr = ast.NewIdent("newdata") if isPointer { - retexpr = &ast.UnaryExpr{X: retexpr, Op: token.AND} + retexpr = ah.UnaryExpr(token.AND, retexpr) } sliceToArray = append(sliceToArray, ah.ReturnStmt(retexpr)) block.List = append(block.List, sliceToArray...) if isPointer { - return ah.LambdaCall(params, &ast.StarExpr{X: arrayType}, block, args) + return ah.LambdaCall(params, ah.StarExpr(arrayType), block, args) } return ah.LambdaCall(params, arrayType, block, args) diff --git a/internal/literals/obfuscators.go b/internal/literals/obfuscators.go index 1bf536b..1920979 100644 --- a/internal/literals/obfuscators.go +++ b/internal/literals/obfuscators.go @@ -15,48 +15,48 @@ import ( ah "mvdan.cc/garble/internal/asthelper" ) -// extKeyRarity probability of using an external key. +// externalKeyProbability probability of using an external key. // Larger value, greater probability of using an external key. // Must be between 0 and 1 -type extKeyRarity float32 +type externalKeyProbability float32 const ( - rareRarity extKeyRarity = 0.4 - normalRarity extKeyRarity = 0.6 - commonRarity extKeyRarity = 0.8 + lowProb externalKeyProbability = 0.4 + normalProb externalKeyProbability = 0.6 + highProb externalKeyProbability = 0.8 ) -func (r extKeyRarity) Try(rand *mathrand.Rand) bool { +func (r externalKeyProbability) Try(rand *mathrand.Rand) bool { return rand.Float32() < float32(r) } -// extKey contains all information about the external key -type extKey struct { +// externalKey contains all information about the external key +type externalKey struct { name, typ string value uint64 bits int refs int } -func (k *extKey) Type() *ast.Ident { +func (k *externalKey) Type() *ast.Ident { return ast.NewIdent(k.typ) } -func (k *extKey) Name() *ast.Ident { +func (k *externalKey) Name() *ast.Ident { return ast.NewIdent(k.name) } -func (k *extKey) AddRef() { +func (k *externalKey) AddRef() { k.refs++ } -func (k *extKey) IsUsed() bool { +func (k *externalKey) IsUsed() bool { return k.refs > 0 } // obfuscator takes a byte slice and converts it to a ast.BlockStmt type obfuscator interface { - obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *ast.BlockStmt + obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*externalKey) *ast.BlockStmt } var ( @@ -107,20 +107,18 @@ func evalOperator(t token.Token, x, y byte) byte { } func operatorToReversedBinaryExpr(t token.Token, x, y ast.Expr) *ast.BinaryExpr { - expr := &ast.BinaryExpr{X: x, Y: y} - + var op token.Token switch t { case token.XOR: - expr.Op = token.XOR + op = token.XOR case token.ADD: - expr.Op = token.SUB + op = token.SUB case token.SUB: - expr.Op = token.ADD + op = token.ADD default: panic(fmt.Sprintf("unknown operator: %s", t)) } - - return expr + return ah.BinaryExpr(x, op, y) } const ( @@ -149,44 +147,38 @@ var extKeyRanges = []struct { } // randExtKey generates a random external key with a unique name, type, value, and bitnesses -func randExtKey(obfRand *mathrand.Rand, idx int) *extKey { - r := extKeyRanges[obfRand.Intn(len(extKeyRanges))] - return &extKey{ +func randExtKey(rand *mathrand.Rand, idx int) *externalKey { + r := extKeyRanges[rand.Intn(len(extKeyRanges))] + return &externalKey{ name: "garbleExternalKey" + strconv.Itoa(idx), typ: r.typ, - value: obfRand.Uint64() & r.max, + value: rand.Uint64() & r.max, bits: r.bits, } } -func randExtKeys(obfRand *mathrand.Rand) []*extKey { - count := minExtKeyCount + obfRand.Intn(maxExtKeyCount-minExtKeyCount) - keys := make([]*extKey, count) +func randExtKeys(rand *mathrand.Rand) []*externalKey { + count := minExtKeyCount + rand.Intn(maxExtKeyCount-minExtKeyCount) + keys := make([]*externalKey, count) for i := 0; i < count; i++ { - keys[i] = randExtKey(obfRand, i) + keys[i] = randExtKey(rand, i) } return keys } // extKeysToParams converts a list of extKeys into a parameter list and argument expressions for function calls. // It ensures unused keys have placeholder names and sometimes use proxyDispatcher.HideValue for key values -func extKeysToParams(objRand *obfRand, keys []*extKey) (params *ast.FieldList, args []ast.Expr) { +func extKeysToParams(objRand *obfRand, keys []*externalKey) (params *ast.FieldList, args []ast.Expr) { params = &ast.FieldList{} for _, key := range keys { name := key.Name() if !key.IsUsed() { name.Name = "_" } - params.List = append(params.List, &ast.Field{ - Names: []*ast.Ident{name}, - Type: key.Type(), - }) + params.List = append(params.List, ah.Field(key.Type(), name)) - var extKeyExpr ast.Expr = &ast.BasicLit{ - Kind: token.INT, - Value: fmt.Sprint(key.value), - } - if rareRarity.Try(objRand.Rand) { + var extKeyExpr ast.Expr = ah.UintLit(key.value) + if lowProb.Try(objRand.Rand) { extKeyExpr = objRand.proxyDispatcher.HideValue(extKeyExpr, ast.NewIdent(key.typ)) } args = append(args, extKeyExpr) @@ -196,15 +188,11 @@ func extKeysToParams(objRand *obfRand, keys []*extKey) (params *ast.FieldList, a // extKeyToExpr converts an external key into an AST expression like: // -// uint8(key >> b) -func extKeyToExpr(key *extKey, b int) ast.Expr { +// uint8(key >> b) +func (key *externalKey) ToExpr(b int) ast.Expr { var x ast.Expr = key.Name() if b > 0 { - x = &ast.BinaryExpr{ - X: x, - Op: token.SHR, - Y: ah.IntLit(b * 8), - } + x = ah.BinaryExpr(x, token.SHR, ah.IntLit(b*8)) } if key.typ != "uint8" { x = ah.CallExprByName("byte", x) @@ -219,26 +207,23 @@ func extKeyToExpr(key *extKey, b int) ast.Expr { // data[] = data[] byte( >> ) // repeated random times // return data // }() -func dataToByteSliceWithExtKeys(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) ast.Expr { - extKeyOpCount := minByteSliceExtKeyOps + obfRand.Intn(maxByteSliceExtKeyOps-minByteSliceExtKeyOps) +func dataToByteSliceWithExtKeys(rand *mathrand.Rand, data []byte, extKeys []*externalKey) ast.Expr { + extKeyOpCount := minByteSliceExtKeyOps + rand.Intn(maxByteSliceExtKeyOps-minByteSliceExtKeyOps) var stmts []ast.Stmt for i := 0; i < extKeyOpCount; i++ { - key := extKeys[obfRand.Intn(len(extKeys))] + key := extKeys[rand.Intn(len(extKeys))] key.AddRef() - idx, op, b := obfRand.Intn(len(data)), randOperator(obfRand), obfRand.Intn(key.bits/8) + idx, op, b := rand.Intn(len(data)), randOperator(rand), rand.Intn(key.bits/8) data[idx] = evalOperator(op, data[idx], byte(key.value>>(b*8))) - stmts = append(stmts, &ast.AssignStmt{ - Lhs: []ast.Expr{ah.IndexExpr("data", ah.IntLit(idx))}, - Tok: token.ASSIGN, - Rhs: []ast.Expr{ - operatorToReversedBinaryExpr(op, - ah.IndexExpr("data", ah.IntLit(idx)), - extKeyToExpr(key, b), - ), - }, - }) + stmts = append(stmts, ah.AssignStmt( + ah.IndexExpr("data", ah.IntLit(idx)), + operatorToReversedBinaryExpr(op, + ah.IndexExpr("data", ah.IntLit(idx)), + key.ToExpr(b), + ), + )) } // External keys can be applied several times to the same array element, @@ -246,26 +231,26 @@ func dataToByteSliceWithExtKeys(obfRand *mathrand.Rand, data []byte, extKeys []* slices.Reverse(stmts) stmts = append([]ast.Stmt{ah.AssignDefineStmt(ast.NewIdent("data"), ah.DataToByteSlice(data))}, append(stmts, ah.ReturnStmt(ast.NewIdent("data")))...) - return ah.LambdaCall(nil, &ast.ArrayType{Elt: ast.NewIdent("byte")}, ah.BlockStmt(stmts...), nil) + return ah.LambdaCall(nil, ah.ByteSliceType(), ah.BlockStmt(stmts...), nil) } // dataToByteSliceWithExtKeys scramble and turns a byte into an AST expression like: // // byte() byte( >> ) -func byteLitWithExtKey(obfRand *mathrand.Rand, val byte, extKeys []*extKey, rarity extKeyRarity) ast.Expr { - if !rarity.Try(obfRand) { +func byteLitWithExtKey(rand *mathrand.Rand, val byte, extKeys []*externalKey, extKeyProb externalKeyProbability) ast.Expr { + if !extKeyProb.Try(rand) { return ah.IntLit(int(val)) } - key := extKeys[obfRand.Intn(len(extKeys))] + key := extKeys[rand.Intn(len(extKeys))] key.AddRef() - op, b := randOperator(obfRand), obfRand.Intn(key.bits/8) + op, b := randOperator(rand), rand.Intn(key.bits/8) newVal := evalOperator(op, val, byte(key.value>>(b*8))) return operatorToReversedBinaryExpr(op, ah.CallExprByName("byte", ah.IntLit(int(newVal))), - extKeyToExpr(key, b), + key.ToExpr(b), ) } diff --git a/internal/literals/seed.go b/internal/literals/seed.go index f260cf8..6c7b6af 100644 --- a/internal/literals/seed.go +++ b/internal/literals/seed.go @@ -16,7 +16,7 @@ type seed struct{} // check that the obfuscator interface is implemented var _ obfuscator = seed{} -func (seed) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *ast.BlockStmt { +func (seed) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*externalKey) *ast.BlockStmt { seed := byte(obfRand.Uint32()) originalSeed := seed @@ -27,18 +27,18 @@ func (seed) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *a seed += encB if i == 0 { - callExpr = ah.CallExpr(ast.NewIdent("fnc"), byteLitWithExtKey(obfRand, encB, extKeys, commonRarity)) + callExpr = ah.CallExpr(ast.NewIdent("fnc"), byteLitWithExtKey(obfRand, encB, extKeys, highProb)) continue } - callExpr = ah.CallExpr(callExpr, byteLitWithExtKey(obfRand, encB, extKeys, rareRarity)) + callExpr = ah.CallExpr(callExpr, byteLitWithExtKey(obfRand, encB, extKeys, lowProb)) } return ah.BlockStmt( &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("seed")}, Tok: token.DEFINE, - Rhs: []ast.Expr{ah.CallExprByName("byte", byteLitWithExtKey(obfRand, originalSeed, extKeys, commonRarity))}, + Rhs: []ast.Expr{ah.CallExprByName("byte", byteLitWithExtKey(obfRand, originalSeed, extKeys, highProb))}, }, &ast.DeclStmt{ Decl: &ast.GenDecl{ diff --git a/internal/literals/shuffle.go b/internal/literals/shuffle.go index 17ee071..dfeee4f 100644 --- a/internal/literals/shuffle.go +++ b/internal/literals/shuffle.go @@ -16,9 +16,9 @@ type shuffle struct{} // check that the obfuscator interface is implemented var _ obfuscator = shuffle{} -func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *ast.BlockStmt { +func (shuffle) obfuscate(rand *mathrand.Rand, data []byte, extKeys []*externalKey) *ast.BlockStmt { key := make([]byte, len(data)) - obfRand.Read(key) + rand.Read(key) const ( minIdxKeySize = 2 @@ -26,7 +26,7 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) ) idxKeySize := minIdxKeySize - if tmp := obfRand.Intn(len(data)); tmp > idxKeySize { + if tmp := rand.Intn(len(data)); tmp > idxKeySize { idxKeySize = tmp } if idxKeySize > maxIdxKeySize { @@ -34,19 +34,19 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) } idxKey := make([]byte, idxKeySize) - obfRand.Read(idxKey) + rand.Read(idxKey) fullData := make([]byte, len(data)+len(key)) operators := make([]token.Token, len(fullData)) for i := range operators { - operators[i] = randOperator(obfRand) + operators[i] = randOperator(rand) } for i, b := range key { fullData[i], fullData[i+len(data)] = evalOperator(operators[i], data[i], b), b } - shuffledIdxs := obfRand.Perm(len(fullData)) + shuffledIdxs := rand.Perm(len(fullData)) shuffledFullData := make([]byte, len(fullData)) for i, b := range fullData { @@ -55,7 +55,7 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) args := []ast.Expr{ast.NewIdent("data")} for i := range data { - keyIdx := obfRand.Intn(idxKeySize) + keyIdx := rand.Intn(idxKeySize) k := int(idxKey[keyIdx]) args = append(args, operatorToReversedBinaryExpr( @@ -69,12 +69,12 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("fullData")}, Tok: token.DEFINE, - Rhs: []ast.Expr{dataToByteSliceWithExtKeys(obfRand, shuffledFullData, extKeys)}, + Rhs: []ast.Expr{dataToByteSliceWithExtKeys(rand, shuffledFullData, extKeys)}, }, &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("idxKey")}, Tok: token.DEFINE, - Rhs: []ast.Expr{dataToByteSliceWithExtKeys(obfRand, idxKey, extKeys)}, + Rhs: []ast.Expr{dataToByteSliceWithExtKeys(rand, idxKey, extKeys)}, }, &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("data")}, diff --git a/internal/literals/simple.go b/internal/literals/simple.go index 4c40cd4..6543ac3 100644 --- a/internal/literals/simple.go +++ b/internal/literals/simple.go @@ -7,6 +7,7 @@ import ( "go/ast" "go/token" mathrand "math/rand" + ah "mvdan.cc/garble/internal/asthelper" ) @@ -15,11 +16,11 @@ type simple struct{} // check that the obfuscator interface is implemented var _ obfuscator = simple{} -func (simple) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *ast.BlockStmt { +func (simple) obfuscate(rand *mathrand.Rand, data []byte, extKeys []*externalKey) *ast.BlockStmt { key := make([]byte, len(data)) - obfRand.Read(key) + rand.Read(key) - op := randOperator(obfRand) + op := randOperator(rand) for i, b := range key { data[i] = evalOperator(op, data[i], b) } @@ -28,12 +29,12 @@ func (simple) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("key")}, Tok: token.DEFINE, - Rhs: []ast.Expr{dataToByteSliceWithExtKeys(obfRand, key, extKeys)}, + Rhs: []ast.Expr{dataToByteSliceWithExtKeys(rand, key, extKeys)}, }, &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("data")}, Tok: token.DEFINE, - Rhs: []ast.Expr{dataToByteSliceWithExtKeys(obfRand, data, extKeys)}, + Rhs: []ast.Expr{dataToByteSliceWithExtKeys(rand, data, extKeys)}, }, &ast.RangeStmt{ Key: ast.NewIdent("i"), diff --git a/internal/literals/split.go b/internal/literals/split.go index 4845860..14a9df9 100644 --- a/internal/literals/split.go +++ b/internal/literals/split.go @@ -66,33 +66,33 @@ func encryptChunks(chunks [][]byte, op token.Token, key byte) { } } -func (split) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *ast.BlockStmt { +func (split) obfuscate(rand *mathrand.Rand, data []byte, extKeys []*externalKey) *ast.BlockStmt { var chunks [][]byte // Short arrays should be divided into single-byte fragments if len(data)/maxChunkSize < minCaseCount { chunks = splitIntoOneByteChunks(data) } else { - chunks = splitIntoRandomChunks(obfRand, data) + chunks = splitIntoRandomChunks(rand, data) } // Generate indexes for cases chunk count + 1 decrypt case + 1 exit case - indexes := obfRand.Perm(len(chunks) + 2) + indexes := rand.Perm(len(chunks) + 2) - decryptKeyInitial := byte(obfRand.Uint32()) + decryptKeyInitial := byte(rand.Uint32()) decryptKey := decryptKeyInitial // Calculate decrypt key based on indexes and position. Ignore exit index for i, index := range indexes[:len(indexes)-1] { decryptKey ^= byte(index * i) } - op := randOperator(obfRand) + op := randOperator(rand) encryptChunks(chunks, op, decryptKey) decryptIndex := indexes[len(indexes)-2] exitIndex := indexes[len(indexes)-1] switchCases := []ast.Stmt{&ast.CaseClause{ List: []ast.Expr{ah.IntLit(decryptIndex)}, - Body: shuffleStmts(obfRand, + Body: shuffleStmts(rand, &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("i")}, Tok: token.ASSIGN, @@ -131,15 +131,15 @@ func (split) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) * } if len(chunk) != 1 { - appendCallExpr.Args = append(appendCallExpr.Args, dataToByteSliceWithExtKeys(obfRand, chunk, extKeys)) + appendCallExpr.Args = append(appendCallExpr.Args, dataToByteSliceWithExtKeys(rand, chunk, extKeys)) appendCallExpr.Ellipsis = 1 } else { - appendCallExpr.Args = append(appendCallExpr.Args, byteLitWithExtKey(obfRand, chunk[0], extKeys, rareRarity)) + appendCallExpr.Args = append(appendCallExpr.Args, byteLitWithExtKey(rand, chunk[0], extKeys, lowProb)) } switchCases = append(switchCases, &ast.CaseClause{ List: []ast.Expr{ah.IntLit(index)}, - Body: shuffleStmts(obfRand, + Body: shuffleStmts(rand, &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("i")}, Tok: token.ASSIGN, @@ -168,7 +168,7 @@ func (split) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) * &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("decryptKey")}, Tok: token.DEFINE, - Rhs: []ast.Expr{ah.CallExprByName("int", byteLitWithExtKey(obfRand, decryptKeyInitial, extKeys, normalRarity))}, + Rhs: []ast.Expr{ah.CallExprByName("int", byteLitWithExtKey(rand, decryptKeyInitial, extKeys, normalProb))}, }, &ast.ForStmt{ Init: &ast.AssignStmt{ @@ -199,7 +199,7 @@ func (split) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) * }, &ast.SwitchStmt{ Tag: ast.NewIdent("i"), - Body: ah.BlockStmt(shuffleStmts(obfRand, switchCases...)...), + Body: ah.BlockStmt(shuffleStmts(rand, switchCases...)...), }), }, ) diff --git a/internal/literals/swap.go b/internal/literals/swap.go index 555003a..7beeb7e 100644 --- a/internal/literals/swap.go +++ b/internal/literals/swap.go @@ -58,13 +58,13 @@ func generateSwapCount(obfRand *mathrand.Rand, dataLen int) int { return swapCount } -func (swap) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *ast.BlockStmt { - swapCount := generateSwapCount(obfRand, len(data)) - shiftKey := byte(obfRand.Uint32()) +func (swap) obfuscate(rand *mathrand.Rand, data []byte, extKeys []*externalKey) *ast.BlockStmt { + swapCount := generateSwapCount(rand, len(data)) + shiftKey := byte(rand.Uint32()) - op := randOperator(obfRand) + op := randOperator(rand) - positions := genRandIntSlice(obfRand, len(data), swapCount) + positions := genRandIntSlice(rand, len(data), swapCount) for i := len(positions) - 2; i >= 0; i -= 2 { // Generate local key for xor based on random key and byte position localKey := byte(i) + byte(positions[i]^positions[i+1]) + shiftKey @@ -76,7 +76,7 @@ func (swap) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *a &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("data")}, Tok: token.DEFINE, - Rhs: []ast.Expr{dataToByteSliceWithExtKeys(obfRand, data, extKeys)}, + Rhs: []ast.Expr{dataToByteSliceWithExtKeys(rand, data, extKeys)}, }, &ast.AssignStmt{ Lhs: []ast.Expr{ast.NewIdent("positions")}, @@ -118,7 +118,7 @@ func (swap) obfuscate(obfRand *mathrand.Rand, data []byte, extKeys []*extKey) *a }), }, Op: token.ADD, - Y: byteLitWithExtKey(obfRand, shiftKey, extKeys, commonRarity), + Y: byteLitWithExtKey(rand, shiftKey, extKeys, highProb), }}, }, &ast.AssignStmt{