Skip to content

Commit

Permalink
In some cases, compiler could optimize the shuffle obfuscator, causin…
Browse files Browse the repository at this point in the history
…g exposing the obfuscated literal. As a fix, added xor encryption of array indexes
  • Loading branch information
pagran committed Dec 6, 2023
1 parent 9378ec9 commit 34cb273
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
28 changes: 26 additions & 2 deletions internal/literals/shuffle.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte) *ast.BlockStmt {
key := make([]byte, len(data))
obfRand.Read(key)

const (
minIdxKeySize = 2
maxIdxKeySize = 16
)

idxKeySize := minIdxKeySize
if tmp := obfRand.Intn(len(data)); tmp > idxKeySize {
idxKeySize = tmp
}
if idxKeySize > maxIdxKeySize {
idxKeySize = maxIdxKeySize
}

idxKey := make([]byte, idxKeySize)
obfRand.Read(idxKey)

fullData := make([]byte, len(data)+len(key))
operators := make([]token.Token, len(fullData))
for i := range operators {
Expand All @@ -39,10 +55,13 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte) *ast.BlockStmt {

args := []ast.Expr{ast.NewIdent("data")}
for i := range data {
keyIdx := obfRand.Intn(idxKeySize)
k := int(idxKey[keyIdx])

args = append(args, operatorToReversedBinaryExpr(
operators[i],
ah.IndexExpr("fullData", ah.IntLit(shuffledIdxs[i])),
ah.IndexExpr("fullData", ah.IntLit(shuffledIdxs[len(data)+i])),
ah.IndexExpr("fullData", &ast.BinaryExpr{X: ah.IntLit(shuffledIdxs[i] ^ k), Op: token.XOR, Y: ah.CallExprByName("int", ah.IndexExpr("idxKey", ah.IntLit(keyIdx)))}),
ah.IndexExpr("fullData", &ast.BinaryExpr{X: ah.IntLit(shuffledIdxs[len(data)+i] ^ k), Op: token.XOR, Y: ah.CallExprByName("int", ah.IndexExpr("idxKey", ah.IntLit(keyIdx)))}),
))
}

Expand All @@ -52,6 +71,11 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte) *ast.BlockStmt {
Tok: token.DEFINE,
Rhs: []ast.Expr{ah.DataToByteSlice(shuffledFullData)},
},
&ast.AssignStmt{
Lhs: []ast.Expr{ast.NewIdent("idxKey")},
Tok: token.DEFINE,
Rhs: []ast.Expr{ah.DataToByteSlice(idxKey)},
},
&ast.AssignStmt{
Lhs: []ast.Expr{ast.NewIdent("data")},
Tok: token.DEFINE,
Expand Down
4 changes: 2 additions & 2 deletions testdata/script/literals.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ grep '^\s+\w+ := \[\.{3}\](byte|uint16|uint32|uint64)\{[0-9\s,]+\}$' debug1/test
# Split obfuscator. Detect decryptKey ^= i * counter
grep '^\s+\w+ \^= \w+ \* \w+$' debug1/test/main/extra_literals.go

# XorShuffle obfuscator. Detect data = append(data, x (^|-|+) y...).
# XorShuffle obfuscator. Detect data = append(data, x[? ^ idxKey[?]] (^|-|+) y[? ^ idxKey[?]]...).
# Note that the line obfuscator adds an inline comment before the call.
grep '^\s+\w+ = .*\bappend\(\w+,(\s+\w+\[\d+\][\^\-+]\w+\[\d+\],?)+\)$' debug1/test/main/extra_literals.go
grep '^(\s+)?\w+ = .*\bappend\(\w+,(\s+\w+\[\d+\^\s.+\][\^\-+]\w+\[\d+\^\s.+\],?)+\)$' debug1/test/main/extra_literals.go

# XorSeed obfuscator. Detect type decFunc func(byte) decFunc
grep '^\s+type \w+ func\(byte\) \w+$' debug1/test/main/extra_literals.go
Expand Down

0 comments on commit 34cb273

Please sign in to comment.