-
-
Notifications
You must be signed in to change notification settings - Fork 284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
String pattern mitigation #930
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commit message shouldn't say "fixes" (as we want to do more) but "updates"
@@ -59,6 +59,22 @@ func LambdaCall(resultType ast.Expr, block *ast.BlockStmt) *ast.CallExpr { | |||
return CallExpr(funcLit) | |||
} | |||
|
|||
// LambdaCallParams "func(params) resultType {block}(args)" | |||
func LambdaCallParams(params *ast.FieldList, resultType ast.Expr, block *ast.BlockStmt, args []ast.Expr) *ast.CallExpr { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lambda call should just use this with nil params
internal/literals/obfuscators.go
Outdated
type extKeyRarity int | ||
|
||
const ( | ||
Rare extKeyRarity = 40 | ||
Normal = 60 | ||
Common = 80 | ||
) | ||
|
||
func (r extKeyRarity) Try(rand *mathrand.Rand) bool { | ||
return rand.Intn(100) < int(r) | ||
} | ||
|
||
type extKey struct { | ||
name, typ string | ||
value uint64 | ||
bits int | ||
refs int | ||
} | ||
|
||
func (k *extKey) Byte() byte { | ||
return byte(k.value) | ||
} | ||
|
||
func (k *extKey) Type() *ast.Ident { | ||
return ast.NewIdent(k.typ) | ||
} | ||
|
||
func (k *extKey) Name() *ast.Ident { | ||
return ast.NewIdent(k.name) | ||
} | ||
|
||
func (k *extKey) AddRef() { | ||
k.refs++ | ||
} | ||
|
||
func (k *extKey) Used() bool { | ||
return k.refs > 0 | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs more docs
internal/literals/obfuscators.go
Outdated
return keys | ||
} | ||
|
||
func addTrashExternalKeys(obfRand *mathrand.Rand, keys []*extKey) []*extKey { | ||
if len(keys) >= maxExternalKeyCount { | ||
return keys | ||
} | ||
|
||
trashCount := maxExternalKeyCount - len(keys) | ||
if trashCount > 1 { | ||
trashCount = 1 + obfRand.Intn(trashCount) | ||
} | ||
for i := 0; i < trashCount; i++ { | ||
keys = append(keys, randExternalKey(obfRand)) | ||
} | ||
|
||
obfRand.Shuffle(len(keys), func(i, j int) { | ||
keys[i], keys[j] = keys[j], keys[i] | ||
}) | ||
|
||
return keys | ||
} | ||
|
||
func externalKeysToParams(obfRand *mathrand.Rand, keys []*extKey) (params *ast.FieldList, args []ast.Expr) { | ||
params = &ast.FieldList{} | ||
for _, key := range addTrashExternalKeys(obfRand, keys) { | ||
name := key.Name() | ||
if !key.Used() { | ||
name.Name = "_" | ||
} | ||
params.List = append(params.List, &ast.Field{ | ||
Names: []*ast.Ident{name}, | ||
Type: key.Type(), | ||
}) | ||
args = append(args, &ast.BasicLit{ | ||
Kind: token.INT, | ||
Value: fmt.Sprint(key.value), | ||
}) | ||
} | ||
return | ||
} | ||
|
||
func dataToByteSliceWithExternalKeys(obfRand *mathrand.Rand, data []byte, externalKeys []*extKey, rarity extKeyRarity) ast.Expr { | ||
if !rarity.Try(obfRand) { | ||
return ah.DataToByteSlice(data) | ||
} | ||
|
||
count := len(data) / 2 | ||
if count > maxExternalKeyCount*2 { | ||
count = maxExternalKeyCount * 2 | ||
} | ||
|
||
var stmts []ast.Stmt | ||
for i := 0; i < count; i++ { | ||
key := externalKeys[obfRand.Intn(len(externalKeys))] | ||
key.AddRef() | ||
idx, op, b := obfRand.Intn(len(data)), randOperator(obfRand), obfRand.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)), | ||
ah.CallExprByName("byte", &ast.BinaryExpr{ | ||
X: key.Name(), | ||
Op: token.SHR, | ||
Y: ah.IntLit(b * 8), | ||
}), | ||
), | ||
}, | ||
}) | ||
} | ||
|
||
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(&ast.ArrayType{Elt: ast.NewIdent("byte")}, ah.BlockStmt(stmts...)) | ||
} | ||
|
||
func byteLitWithExternalKeys(obfRand *mathrand.Rand, val byte, externalKeys []*extKey, rarity extKeyRarity) ast.Expr { | ||
if !rarity.Try(obfRand) { | ||
return ah.IntLit(int(val)) | ||
} | ||
|
||
key := externalKeys[obfRand.Intn(len(externalKeyRanges))] | ||
key.AddRef() | ||
|
||
op, b := randOperator(obfRand), obfRand.Intn(key.bits/8) | ||
newVal := evalOperator(op, val, byte(key.value>>(b*8))) | ||
return operatorToReversedBinaryExpr(op, | ||
ah.CallExprByName("byte", ah.IntLit(int(newVal))), | ||
ah.CallExprByName("byte", &ast.BinaryExpr{ | ||
X: key.Name(), | ||
Op: token.SHR, | ||
Y: ah.IntLit(b * 8), | ||
}), | ||
) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs more docs, whenever you generate code please add a comment with how the generated code looks like.
WIP
Now implemented “external keys”, with random bit count (8/16/32/64). One key can be used many times and using bit shifting each key can be used differently
Roadmap:
string([]byte(""))
pattern hiding (via proxy)Code examples
Closes #926