add "max" flag value and limits for control flow obfuscation parameters

pull/780/head
pagran 11 months ago committed by GitHub
parent 8fd5f10d1d
commit 260cad2a3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -22,6 +22,13 @@ Control flow obfuscation works in several stages:
func main() {
println("Hello world!")
}
// Obfuscate with maximum parameters
//garble:controlflow block_splits=max junk_jumps=max flatten_passes=max
func main() {
println("Hello world!")
}
```
### Parameter explanation
@ -45,8 +52,8 @@ Input:
```go
package main
// Note that the block_splits value is very large, so code blocks are split into the smallest possible blocks.
//garble:controlflow flatten_passes=0 junk_jumps=0 block_splits=1024
// Note that the block_splits value is "max", so code blocks are split into the smallest possible blocks.
//garble:controlflow flatten_passes=0 junk_jumps=0 block_splits=max
func main() {
println("1")
println("2")
@ -91,7 +98,7 @@ _s2a_l4:
#### Junk jumps
Parameter: `junk_jumps` (default: `0`)
Parameter: `junk_jumps` (default: `0`, maximum: `1024`)
> Warning: this param affects resulting binary only when used in combination with [flattening](#control-flow-flattening)
@ -152,7 +159,7 @@ _s2a_l7:
#### Control flow flattening
Parameter: `flatten_passes` (default: `1`)
Parameter: `flatten_passes` (default: `1`, maximum: `4`)
This parameter completely [flattens the control flow](https://github.com/obfuscator-llvm/obfuscator/wiki/Control-Flow-Flattening) `flatten_passes` times, which makes analysing the logic of the function very difficult

@ -6,7 +6,9 @@ import (
"go/token"
"go/types"
"log"
"math"
mathrand "math/rand"
"os"
"strconv"
"strings"
@ -24,19 +26,30 @@ const (
defaultBlockSplits = 0
defaultJunkJumps = 0
defaultFlattenPasses = 1
maxBlockSplits = math.MaxInt32
maxJunkJumps = 256
maxFlattenPasses = 4
)
type directiveParamMap map[string]string
func (m directiveParamMap) GetInt(name string, def int) int {
func (m directiveParamMap) GetInt(name string, def, max int) int {
rawVal, ok := m[name]
if !ok {
return def
}
if rawVal == "max" {
return max
}
val, err := strconv.Atoi(rawVal)
if err != nil {
panic(fmt.Errorf("invalid flag %s format: %v", name, err))
panic(fmt.Errorf("invalid flag %q format: %v", name, err))
}
if val > max {
panic(fmt.Errorf("too big flag %q value: %d (max: %d)", name, val, max))
}
return val
}
@ -150,9 +163,12 @@ func Obfuscate(fset *token.FileSet, ssaPkg *ssa.Package, files []*ast.File, obfR
for idx, ssaFunc := range ssaFuncs {
params := ssaParams[idx]
split := params.GetInt("block_splits", defaultBlockSplits)
junkCount := params.GetInt("junk_jumps", defaultJunkJumps)
passes := params.GetInt("flatten_passes", defaultFlattenPasses)
split := params.GetInt("block_splits", defaultBlockSplits, maxBlockSplits)
junkCount := params.GetInt("junk_jumps", defaultJunkJumps, maxJunkJumps)
passes := params.GetInt("flatten_passes", defaultFlattenPasses, maxFlattenPasses)
if passes == 0 {
fmt.Fprintf(os.Stderr, "control flow obfuscation for %q function has no effect on the resulting binary, to fix this flatten_passes must be greater than zero", ssaFunc)
}
applyObfuscation := func(ssaFunc *ssa.Function) {
for i := 0; i < split; i++ {

@ -1,5 +1,8 @@
env GARBLE_EXPERIMENTAL_CONTROLFLOW=1
exec garble -literals -debugdir=debug -seed=0002deadbeef build -o=main$exe
stderr '"test/main.func1" function has no effect on the resulting binary'
exec ./main
cmp stderr main.stderr
@ -34,6 +37,9 @@ import (
"hash/crc32"
)
//garble:controlflow flatten_passes=0 junk_jumps=max block_splits=max
func func1() {}
//garble:controlflow flatten_passes=1 junk_jumps=10 block_splits=10
func main() {
// Reference to the unexported interface triggers creation of a new interface

Loading…
Cancel
Save