mirror of
https://github.com/burrowers/garble.git
synced 2025-10-05 15:56:55 +08:00

add trash block generator For making static code analysis even more difficult, added feature for generating trash blocks that will never be executed. In combination with control flow flattening makes it hard to separate trash code from the real one, plus it causes a large number of trash references to different methods. Trash blocks contain 2 types of statements: 1. Function/method call with writing the results into local variables and passing them to other calls 2. Shuffling or assigning random values to local variables
177 lines
4.3 KiB
Go
177 lines
4.3 KiB
Go
package ssa2ast
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/token"
|
|
"go/types"
|
|
)
|
|
|
|
func makeMapIteratorPolyfill(tc *TypeConverter, mapType *types.Map) (ast.Expr, types.Type, error) {
|
|
keyTypeExpr, err := tc.Convert(mapType.Key())
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
valueTypeExpr, err := tc.Convert(mapType.Elem())
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
nextType := types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(
|
|
types.NewVar(token.NoPos, nil, "", types.Typ[types.Bool]),
|
|
types.NewVar(token.NoPos, nil, "", mapType.Key()),
|
|
types.NewVar(token.NoPos, nil, "", mapType.Elem()),
|
|
), false)
|
|
|
|
// Generated using https://github.com/lu4p/astextract from snippet:
|
|
/*
|
|
func(m map[<key type>]<value type>) func() (bool, <key type>, <value type>) {
|
|
keys := make([]<key type>, 0, len(m))
|
|
for k := range m {
|
|
keys = append(keys, k)
|
|
}
|
|
i := 0
|
|
return func() (ok bool, k <key type>, r <value type>) {
|
|
if i < len(keys) {
|
|
k = keys[i]
|
|
ok, r = true, m[k]
|
|
i++
|
|
}
|
|
return
|
|
}
|
|
}
|
|
*/
|
|
return &ast.FuncLit{
|
|
Type: &ast.FuncType{
|
|
Params: &ast.FieldList{List: []*ast.Field{{
|
|
Names: []*ast.Ident{{Name: "m"}},
|
|
Type: &ast.MapType{
|
|
Key: keyTypeExpr,
|
|
Value: valueTypeExpr,
|
|
},
|
|
}}},
|
|
Results: &ast.FieldList{List: []*ast.Field{{
|
|
Type: &ast.FuncType{
|
|
Params: &ast.FieldList{},
|
|
Results: &ast.FieldList{List: []*ast.Field{
|
|
{Type: &ast.Ident{Name: "bool"}},
|
|
{Type: keyTypeExpr},
|
|
{Type: valueTypeExpr},
|
|
}},
|
|
},
|
|
}}},
|
|
},
|
|
Body: &ast.BlockStmt{
|
|
List: []ast.Stmt{
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{&ast.Ident{Name: "keys"}},
|
|
Tok: token.DEFINE,
|
|
Rhs: []ast.Expr{
|
|
&ast.CallExpr{
|
|
Fun: &ast.Ident{Name: "make"},
|
|
Args: []ast.Expr{
|
|
&ast.ArrayType{Elt: keyTypeExpr},
|
|
&ast.BasicLit{Kind: token.INT, Value: "0"},
|
|
&ast.CallExpr{
|
|
Fun: &ast.Ident{Name: "len"},
|
|
Args: []ast.Expr{&ast.Ident{Name: "m"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
&ast.RangeStmt{
|
|
Key: &ast.Ident{Name: "k"},
|
|
Tok: token.DEFINE,
|
|
X: &ast.Ident{Name: "m"},
|
|
Body: &ast.BlockStmt{
|
|
List: []ast.Stmt{
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{&ast.Ident{Name: "keys"}},
|
|
Tok: token.ASSIGN,
|
|
Rhs: []ast.Expr{
|
|
&ast.CallExpr{
|
|
Fun: &ast.Ident{Name: "append"},
|
|
Args: []ast.Expr{
|
|
&ast.Ident{Name: "keys"},
|
|
&ast.Ident{Name: "k"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{&ast.Ident{Name: "i"}},
|
|
Tok: token.DEFINE,
|
|
Rhs: []ast.Expr{&ast.BasicLit{Kind: token.INT, Value: "0"}},
|
|
},
|
|
&ast.ReturnStmt{Results: []ast.Expr{
|
|
&ast.FuncLit{
|
|
Type: &ast.FuncType{
|
|
Params: &ast.FieldList{},
|
|
Results: &ast.FieldList{List: []*ast.Field{
|
|
{
|
|
Names: []*ast.Ident{{Name: "ok"}},
|
|
Type: &ast.Ident{Name: "bool"},
|
|
},
|
|
{
|
|
Names: []*ast.Ident{{Name: "k"}},
|
|
Type: keyTypeExpr,
|
|
},
|
|
{
|
|
Names: []*ast.Ident{{Name: "r"}},
|
|
Type: valueTypeExpr,
|
|
},
|
|
}},
|
|
},
|
|
Body: &ast.BlockStmt{
|
|
List: []ast.Stmt{
|
|
&ast.IfStmt{
|
|
Cond: &ast.BinaryExpr{
|
|
X: &ast.Ident{Name: "i"},
|
|
Op: token.LSS,
|
|
Y: &ast.CallExpr{
|
|
Fun: &ast.Ident{Name: "len"},
|
|
Args: []ast.Expr{&ast.Ident{Name: "keys"}},
|
|
},
|
|
},
|
|
Body: &ast.BlockStmt{List: []ast.Stmt{
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{&ast.Ident{Name: "k"}},
|
|
Tok: token.ASSIGN,
|
|
Rhs: []ast.Expr{&ast.IndexExpr{
|
|
X: &ast.Ident{Name: "keys"},
|
|
Index: &ast.Ident{Name: "i"},
|
|
}},
|
|
},
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{
|
|
&ast.Ident{Name: "ok"},
|
|
&ast.Ident{Name: "r"},
|
|
},
|
|
Tok: token.ASSIGN,
|
|
Rhs: []ast.Expr{
|
|
&ast.Ident{Name: "true"},
|
|
&ast.IndexExpr{
|
|
X: &ast.Ident{Name: "m"},
|
|
Index: &ast.Ident{Name: "k"},
|
|
},
|
|
},
|
|
},
|
|
&ast.IncDecStmt{
|
|
X: &ast.Ident{Name: "i"},
|
|
Tok: token.INC,
|
|
},
|
|
}},
|
|
},
|
|
&ast.ReturnStmt{},
|
|
},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
}, nextType, nil
|
|
}
|