This commit is contained in:
Paul Scheduikat
2025-06-03 02:03:16 +02:00
parent 0b8de06a09
commit edcdaf3e35
8 changed files with 172 additions and 138 deletions

View File

@@ -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:

View File

@@ -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)

View File

@@ -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[<index>] = data[<index>] <random operator> byte(<external key> >> <random shift>) // 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(<obfuscated value>) <random operator> byte(<external key> >> <random shift>)
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),
)
}

View File

@@ -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{

View File

@@ -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")},

View File

@@ -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"),

View File

@@ -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...)...),
}),
},
)

View File

@@ -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{