Randomize operator (xor, add, subtract) on all obfuscators (#90)

Co-authored-by: lu4p <lu4p@pm.me>
pull/91/head
pagran 4 years ago committed by GitHub
parent 2eba744530
commit 28adbaa73b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,6 +4,7 @@ import (
cryptrand "crypto/rand" cryptrand "crypto/rand"
"fmt" "fmt"
"go/ast" "go/ast"
"go/token"
mathrand "math/rand" mathrand "math/rand"
"os" "os"
"strings" "strings"
@ -44,6 +45,12 @@ func genRandBytes(buffer []byte) {
} }
} }
func genRandByte() byte {
bytes := make([]byte, 1)
genRandBytes(bytes)
return bytes[0]
}
func genRandIntSlice(max, count int) []int { func genRandIntSlice(max, count int) []int {
indexes := make([]int, count) indexes := make([]int, count)
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
@ -51,3 +58,38 @@ func genRandIntSlice(max, count int) []int {
} }
return indexes return indexes
} }
func randOperator() token.Token {
operatorTokens := [...]token.Token{token.XOR, token.ADD, token.SUB}
return operatorTokens[mathrand.Intn(len(operatorTokens))]
}
func evalOperator(t token.Token, x, y byte) byte {
switch t {
case token.XOR:
return x ^ y
case token.ADD:
return x + y
case token.SUB:
return x - y
default:
panic(fmt.Sprintf("unknown operator: %s", t))
}
}
func operatorToReversedBinaryExpr(t token.Token, x, y ast.Expr) *ast.BinaryExpr {
expr := &ast.BinaryExpr{X: x, Y: y}
switch t {
case token.XOR:
expr.Op = token.XOR
case token.ADD:
expr.Op = token.SUB
case token.SUB:
expr.Op = token.ADD
default:
panic(fmt.Sprintf("unknown operator: %s", t))
}
return expr
}

@ -55,14 +55,13 @@ func shuffleStmts(stmts ...ast.Stmt) []ast.Stmt {
return stmts return stmts
} }
// Xor encrypt chunks based on key and position // Encrypt chunks based on key and position
func encryptChunks(chunks [][]byte, key int) { func encryptChunks(chunks [][]byte, op token.Token, key byte) {
idx := 0 byteOffset := 0
for chunkIdx := range chunks { for _, chunk := range chunks {
chunk := chunks[chunkIdx] for i, b := range chunk {
for i := range chunk { chunk[i] = evalOperator(op, b, key^byte(byteOffset))
chunk[i] ^= byte(key ^ idx) byteOffset++
idx++
} }
} }
} }
@ -79,13 +78,15 @@ func (x split) obfuscate(data []byte) *ast.BlockStmt {
// Generate indexes for cases chunk count + 1 decrypt case + 1 exit case // Generate indexes for cases chunk count + 1 decrypt case + 1 exit case
indexes := mathrand.Perm(len(chunks) + 2) indexes := mathrand.Perm(len(chunks) + 2)
decryptKeyInitial := mathrand.Int() decryptKeyInitial := genRandByte()
decryptKey := decryptKeyInitial decryptKey := decryptKeyInitial
// Calculate decrypt key based on indexes and position. Ignore exit index // Calculate decrypt key based on indexes and position. Ignore exit index
for i, index := range indexes[:len(indexes)-1] { for i, index := range indexes[:len(indexes)-1] {
decryptKey ^= index * i decryptKey ^= byte(index * i)
} }
encryptChunks(chunks, decryptKey)
op := randOperator()
encryptChunks(chunks, op, decryptKey)
decryptIndex := indexes[len(indexes)-2] decryptIndex := indexes[len(indexes)-2]
exitIndex := indexes[len(indexes)-1] exitIndex := indexes[len(indexes)-1]
@ -103,12 +104,18 @@ func (x split) obfuscate(data []byte) *ast.BlockStmt {
X: ah.Ident("data"), X: ah.Ident("data"),
Body: ah.BlockStmt(&ast.AssignStmt{ Body: ah.BlockStmt(&ast.AssignStmt{
Lhs: []ast.Expr{ah.IndexExpr("data", ah.Ident("y"))}, Lhs: []ast.Expr{ah.IndexExpr("data", ah.Ident("y"))},
Tok: token.XOR_ASSIGN, Tok: token.ASSIGN,
Rhs: []ast.Expr{ah.CallExpr(ah.Ident("byte"), &ast.BinaryExpr{ Rhs: []ast.Expr{
X: ah.Ident("decryptKey"), operatorToReversedBinaryExpr(
Op: token.XOR, op,
Y: ah.Ident("y"), ah.IndexExpr("data", ah.Ident("y")),
})}, ah.CallExpr(ah.Ident("byte"), &ast.BinaryExpr{
X: ah.Ident("decryptKey"),
Op: token.XOR,
Y: ah.Ident("y"),
}),
),
},
}), }),
}, },
), ),
@ -165,7 +172,7 @@ func (x split) obfuscate(data []byte) *ast.BlockStmt {
&ast.AssignStmt{ &ast.AssignStmt{
Lhs: []ast.Expr{ah.Ident("decryptKey")}, Lhs: []ast.Expr{ah.Ident("decryptKey")},
Tok: token.DEFINE, Tok: token.DEFINE,
Rhs: []ast.Expr{ah.IntLit(decryptKeyInitial)}, Rhs: []ast.Expr{ah.IntLit(int(decryptKeyInitial))},
}, },
&ast.ForStmt{ &ast.ForStmt{
Init: &ast.AssignStmt{ Init: &ast.AssignStmt{

@ -57,14 +57,16 @@ func generateSwapCount(dataLen int) int {
func (x swap) obfuscate(data []byte) *ast.BlockStmt { func (x swap) obfuscate(data []byte) *ast.BlockStmt {
swapCount := generateSwapCount(len(data)) swapCount := generateSwapCount(len(data))
shiftKey := byte(mathrand.Intn(math.MaxUint8)) shiftKey := genRandByte()
op := randOperator()
positions := genRandIntSlice(len(data), swapCount) positions := genRandIntSlice(len(data), swapCount)
for i := len(positions) - 2; i >= 0; i -= 2 { for i := len(positions) - 2; i >= 0; i -= 2 {
// Generate local key for xor based on random key and byte position // Generate local key for xor based on random key and byte position
localKey := byte(i) + byte(positions[i]^positions[i+1]) + shiftKey localKey := byte(i) + byte(positions[i]^positions[i+1]) + shiftKey
// Swap bytes from i+1 to i and xor using local key // Swap bytes from i+1 to i and encrypt using operator and local key
data[positions[i]], data[positions[i+1]] = data[positions[i+1]]^localKey, data[positions[i]]^localKey data[positions[i]], data[positions[i+1]] = evalOperator(op, data[positions[i+1]], localKey), evalOperator(op, data[positions[i]], localKey)
} }
return ah.BlockStmt( return ah.BlockStmt(
@ -127,20 +129,22 @@ func (x swap) obfuscate(data []byte) *ast.BlockStmt {
}, },
Tok: token.ASSIGN, Tok: token.ASSIGN,
Rhs: []ast.Expr{ Rhs: []ast.Expr{
&ast.BinaryExpr{ operatorToReversedBinaryExpr(
X: ah.IndexExpr("data", ah.IndexExpr("positions", &ast.BinaryExpr{ op,
X: ah.Ident("i"), ah.IndexExpr("data",
Op: token.ADD, ah.IndexExpr("positions", &ast.BinaryExpr{
Y: ah.IntLit(1), X: ah.Ident("i"),
})), Op: token.ADD,
Op: token.XOR, Y: ah.IntLit(1),
Y: ah.Ident("localKey"), }),
}, ),
&ast.BinaryExpr{ ah.Ident("localKey"),
X: ah.IndexExpr("data", ah.IndexExpr("positions", ah.Ident("i"))), ),
Op: token.XOR, operatorToReversedBinaryExpr(
Y: ah.Ident("localKey"), op,
}, ah.IndexExpr("data", ah.IndexExpr("positions", ah.Ident("i"))),
ah.Ident("localKey"),
),
}, },
}, },
), ),

@ -16,8 +16,9 @@ func (x xor) obfuscate(data []byte) *ast.BlockStmt {
key := make([]byte, len(data)) key := make([]byte, len(data))
genRandBytes(key) genRandBytes(key)
op := randOperator()
for i, b := range key { for i, b := range key {
data[i] = data[i] ^ b data[i] = evalOperator(op, data[i], b)
} }
return &ast.BlockStmt{List: []ast.Stmt{ return &ast.BlockStmt{List: []ast.Stmt{
@ -40,11 +41,7 @@ func (x xor) obfuscate(data []byte) *ast.BlockStmt {
&ast.AssignStmt{ &ast.AssignStmt{
Lhs: []ast.Expr{ah.IndexExpr("data", ah.Ident("i"))}, Lhs: []ast.Expr{ah.IndexExpr("data", ah.Ident("i"))},
Tok: token.ASSIGN, Tok: token.ASSIGN,
Rhs: []ast.Expr{&ast.BinaryExpr{ Rhs: []ast.Expr{operatorToReversedBinaryExpr(op, ah.IndexExpr("data", ah.Ident("i")), ah.Ident("b"))},
X: ah.IndexExpr("data", ah.Ident("i")),
Op: token.XOR,
Y: ah.Ident("b"),
}},
}, },
}}, }},
}, },

@ -13,15 +13,14 @@ type xorSeed struct{}
var _ obfuscator = xorSeed{} var _ obfuscator = xorSeed{}
func (x xorSeed) obfuscate(data []byte) *ast.BlockStmt { func (x xorSeed) obfuscate(data []byte) *ast.BlockStmt {
preSeed := make([]byte, 1) seed := genRandByte()
genRandBytes(preSeed)
seed := preSeed[0]
originalSeed := seed originalSeed := seed
op := randOperator()
var callExpr *ast.CallExpr var callExpr *ast.CallExpr
for i, b := range data { for i, b := range data {
encB := b ^ seed encB := evalOperator(op, b, seed)
seed += encB seed += encB
if i == 0 { if i == 0 {
@ -95,11 +94,7 @@ func (x xorSeed) obfuscate(data []byte) *ast.BlockStmt {
Lhs: []ast.Expr{ah.Ident("data")}, Lhs: []ast.Expr{ah.Ident("data")},
Tok: token.ASSIGN, Tok: token.ASSIGN,
Rhs: []ast.Expr{ Rhs: []ast.Expr{
ah.CallExpr(ah.Ident("append"), ah.Ident("data"), &ast.BinaryExpr{ ah.CallExpr(ah.Ident("append"), ah.Ident("data"), operatorToReversedBinaryExpr(op, ah.Ident("x"), ah.Ident("seed"))),
X: ah.Ident("x"),
Op: token.XOR,
Y: ah.Ident("seed"),
}),
}, },
}, },
&ast.AssignStmt{ &ast.AssignStmt{

@ -18,8 +18,13 @@ func (x xorShuffle) obfuscate(data []byte) *ast.BlockStmt {
genRandBytes(key) genRandBytes(key)
fullData := make([]byte, len(data)+len(key)) fullData := make([]byte, len(data)+len(key))
operators := make([]token.Token, len(fullData))
for i := range operators {
operators[i] = randOperator()
}
for i, b := range key { for i, b := range key {
fullData[i], fullData[i+len(data)] = data[i]^b, b fullData[i], fullData[i+len(data)] = evalOperator(operators[i], data[i], b), b
} }
shuffledIdxs := mathrand.Perm(len(fullData)) shuffledIdxs := mathrand.Perm(len(fullData))
@ -31,11 +36,11 @@ func (x xorShuffle) obfuscate(data []byte) *ast.BlockStmt {
args := []ast.Expr{ah.Ident("data")} args := []ast.Expr{ah.Ident("data")}
for i := range data { for i := range data {
args = append(args, &ast.BinaryExpr{ args = append(args, operatorToReversedBinaryExpr(
X: ah.IndexExpr("fullData", ah.IntLit(shuffledIdxs[i])), operators[i],
Op: token.XOR, ah.IndexExpr("fullData", ah.IntLit(shuffledIdxs[i])),
Y: ah.IndexExpr("fullData", ah.IntLit(shuffledIdxs[len(data)+i])), ah.IndexExpr("fullData", ah.IntLit(shuffledIdxs[len(data)+i])),
}) ))
} }
return ah.BlockStmt( return ah.BlockStmt(

@ -36,8 +36,8 @@ cmp stderr normal.stderr
# Check obfuscators # Check obfuscators
# Xor obfuscator. Detect a[i] = a[i] ^ b[i] # Xor obfuscator. Detect a[i] = a[i] (^|-|+) b[i]
grep '^\s+\w+\[\w+\] = \w+\[\w+\] \^ \w+$' .obf-src/main/z0.go grep '^\s+\w+\[\w+\] = \w+\[\w+\] [\^\-+] \w+$' .obf-src/main/z0.go
# Swap obfuscator. Detect [...]byte|uint16|uint32|uint64{...} # Swap obfuscator. Detect [...]byte|uint16|uint32|uint64{...}
grep '^\s+\w+ := \[\.{3}\](byte|uint16|uint32|uint64)\{[0-9\s,]+\}$' .obf-src/main/z0.go grep '^\s+\w+ := \[\.{3}\](byte|uint16|uint32|uint64)\{[0-9\s,]+\}$' .obf-src/main/z0.go
@ -45,8 +45,8 @@ grep '^\s+\w+ := \[\.{3}\](byte|uint16|uint32|uint64)\{[0-9\s,]+\}$' .obf-src/ma
# Split obfuscator. Detect decryptKey ^= i * counter # Split obfuscator. Detect decryptKey ^= i * counter
grep '^\s+\w+ \^= \w+ \* \w+$' .obf-src/main/z0.go grep '^\s+\w+ \^= \w+ \* \w+$' .obf-src/main/z0.go
# XorShuffle obfuscator. Detect data = append(data, x ^ y...) # XorShuffle obfuscator. Detect data = append(data, x (^|-|+) y...)
grep '^\s+\w+ = append\(\w+,(\s+\w+\[\d+\]\^\w+\[\d+\],?)+\)$' .obf-src/main/z0.go grep '^\s+\w+ = append\(\w+,(\s+\w+\[\d+\][\^\-+]\w+\[\d+\],?)+\)$' .obf-src/main/z0.go
# XorSeed obfuscator. Detect type decFunc func(byte) decFunc # XorSeed obfuscator. Detect type decFunc func(byte) decFunc
grep '^\s+type \w+ func\(byte\) \w+$' .obf-src/main/z0.go grep '^\s+type \w+ func\(byte\) \w+$' .obf-src/main/z0.go

Loading…
Cancel
Save