fix shuffle obfuscation compiler optimization

In some cases, compiler could optimize the shuffle obfuscator,
causing exposing the obfuscated literal.
As a fix, added xor encryption of array indexes.
pull/822/head
pagran 7 months ago committed by Daniel Martí
parent 96d2d8b0de
commit 3a9c9aa3d4
No known key found for this signature in database

@ -20,6 +20,22 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte) *ast.BlockStmt {
key := make([]byte, len(data)) key := make([]byte, len(data))
obfRand.Read(key) 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)) fullData := make([]byte, len(data)+len(key))
operators := make([]token.Token, len(fullData)) operators := make([]token.Token, len(fullData))
for i := range operators { for i := range operators {
@ -39,10 +55,13 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte) *ast.BlockStmt {
args := []ast.Expr{ast.NewIdent("data")} args := []ast.Expr{ast.NewIdent("data")}
for i := range data { for i := range data {
keyIdx := obfRand.Intn(idxKeySize)
k := int(idxKey[keyIdx])
args = append(args, operatorToReversedBinaryExpr( args = append(args, operatorToReversedBinaryExpr(
operators[i], operators[i],
ah.IndexExpr("fullData", ah.IntLit(shuffledIdxs[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", ah.IntLit(shuffledIdxs[len(data)+i])), 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)))}),
)) ))
} }
@ -52,6 +71,11 @@ func (shuffle) obfuscate(obfRand *mathrand.Rand, data []byte) *ast.BlockStmt {
Tok: token.DEFINE, Tok: token.DEFINE,
Rhs: []ast.Expr{ah.DataToByteSlice(shuffledFullData)}, 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{ &ast.AssignStmt{
Lhs: []ast.Expr{ast.NewIdent("data")}, Lhs: []ast.Expr{ast.NewIdent("data")},
Tok: token.DEFINE, Tok: token.DEFINE,

@ -46,9 +46,9 @@ grep '^\s+\w+ := \[\.{3}\](byte|uint16|uint32|uint64)\{[0-9\s,]+\}$' debug1/test
# Split obfuscator. Detect decryptKey ^= i * counter # Split obfuscator. Detect decryptKey ^= i * counter
grep '^\s+\w+ \^= \w+ \* \w+$' debug1/test/main/extra_literals.go 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. # 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 # XorSeed obfuscator. Detect type decFunc func(byte) decFunc
grep '^\s+type \w+ func\(byte\) \w+$' debug1/test/main/extra_literals.go grep '^\s+type \w+ func\(byte\) \w+$' debug1/test/main/extra_literals.go

Loading…
Cancel
Save