From 082f53429af8eea2b06275e9e8fbdcb3ffdd90bc Mon Sep 17 00:00:00 2001 From: Pagran <67878280+pagran@users.noreply.github.com> Date: Mon, 27 Jul 2020 15:09:59 +0300 Subject: [PATCH] Implement swap obfuscator --- internal/literals/obfuscators.go | 13 ++++ internal/literals/swap.go | 108 +++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 internal/literals/swap.go diff --git a/internal/literals/obfuscators.go b/internal/literals/obfuscators.go index bd86bf6..80a8747 100644 --- a/internal/literals/obfuscators.go +++ b/internal/literals/obfuscators.go @@ -19,6 +19,7 @@ var ( // obfuscators contains all types which implement the obfuscator Interface obfuscators = []obfuscator{ xor{}, + swap{}, } envGarbleSeed = os.Getenv("GARBLE_SEED") ) @@ -58,3 +59,15 @@ func genRandBytes(buffer []byte) { func genRandInt() int { return mathrand.Int() } + +func genRandIntn(max int) int { + return mathrand.Intn(max) +} + +func generateIntSlice(max, count int) []int { + indexes := make([]int, count) + for i := 0; i < count; i++ { + indexes[i] = genRandIntn(max) + } + return indexes +} diff --git a/internal/literals/swap.go b/internal/literals/swap.go new file mode 100644 index 0000000..fde773e --- /dev/null +++ b/internal/literals/swap.go @@ -0,0 +1,108 @@ +package literals + +import ( + "go/ast" + "go/token" + "strconv" +) + +type swap struct{} + +// check that the obfuscator interface is implemented +var _ obfuscator = swap{} + +func dataToIntSlice(data []int) *ast.CompositeLit { + arr := &ast.CompositeLit{ + Type: &ast.ArrayType{ + Len: &ast.Ellipsis{}, // Performance optimization + Elt: &ast.Ident{ + Name: "int", + }, + }, + Elts: []ast.Expr{}, + } + for _, data := range data { + arr.Elts = append(arr.Elts, intLiteral(strconv.Itoa(data))) + } + return arr +} + +func (x swap) obfuscate(data []byte) *ast.BlockStmt { + maxJunkIdxCount := len(data) / 2 + if maxJunkIdxCount == 0 { + maxJunkIdxCount = 1 + } + count := len(data) + genRandIntn(maxJunkIdxCount) + if count%2 != 0 { + count++ + } + indexes := generateIntSlice(len(data), count) + for i := len(indexes) - 2; i >= 0; i -= 2 { + data[indexes[i]], data[indexes[i+1]] = data[indexes[i+1]], data[indexes[i]] + } + + return &ast.BlockStmt{List: []ast.Stmt{ + &ast.AssignStmt{ + Lhs: []ast.Expr{ident("data")}, + Tok: token.DEFINE, + Rhs: []ast.Expr{dataToByteSlice(data)}, + }, + &ast.AssignStmt{ + Lhs: []ast.Expr{ + ident("indexes"), + }, + Tok: token.DEFINE, + Rhs: []ast.Expr{ + dataToIntSlice(indexes), + }, + }, + &ast.ForStmt{ + Init: &ast.AssignStmt{ + Lhs: []ast.Expr{ + ident("i"), + }, + Tok: token.DEFINE, + Rhs: []ast.Expr{ + intLiteral("0"), + }, + }, + Cond: &ast.BinaryExpr{ + X: ident("i"), + Op: token.LSS, + Y: intLiteral(strconv.Itoa(len(indexes))), + }, + Post: &ast.AssignStmt{ + Lhs: []ast.Expr{ + ident("i"), + }, + Tok: token.ADD_ASSIGN, + Rhs: []ast.Expr{ + intLiteral("2"), + }, + }, + Body: &ast.BlockStmt{ + List: []ast.Stmt{ + &ast.AssignStmt{ + Lhs: []ast.Expr{ + indexExpr("data", indexExpr("indexes", ident("i"))), + indexExpr("data", indexExpr("indexes", &ast.BinaryExpr{ + X: ident("i"), + Op: token.ADD, + Y: intLiteral("1"), + })), + }, + Tok: token.ASSIGN, + Rhs: []ast.Expr{ + indexExpr("data", indexExpr("indexes", &ast.BinaryExpr{ + X: ident("i"), + Op: token.ADD, + Y: intLiteral("1"), + })), + indexExpr("data", indexExpr("indexes", ident("i"))), + }, + }, + }, + }, + }, + }} +}