add trash block generator docs

pull/834/head
pagran 3 months ago committed by Daniel Martí
parent f3f57e361d
commit d76bc2eb47

@ -13,7 +13,8 @@ Control flow obfuscation works in several stages:
4) Generates [junk jumps](#junk-jumps)
5) Applies [control flow flattening](#control-flow-flattening)
6) Applies (if enabled) [control flow hardening](#control-flow-hardening)
7) Converts go/ssa back into go/ast
7) Generates [trash blocks](#trash-blocks)
8) Converts go/ssa back into go/ast
### Example usage
@ -272,6 +273,7 @@ _s2a_l12:
```
#### Control flow hardening
Parameter: `flatten_hardening` (default: empty, supported: `xor,delegate_table`)
Dispatcher is the main and most vulnerable part of control flow flattening. By static analysis of the dispatcher, it is possible to reconstruct the original control flow ([example](https://research.openanalysis.net/angr/symbolic%20execution/deobfuscation/research/2022/03/26/angr_notes.html)). Hardening can be used to make this analysis more difficult by adding an extra layer of obfuscation and moving some of the computation to runtime
@ -299,6 +301,7 @@ func main() {
}
```
Result:
```go
var _garble2ec9r7n6t4d7f = (func(key [15]byte) [4]func(int) int {
@ -501,6 +504,95 @@ func main() {
```
#### Trash blocks
Parameter: `trash_blocks` (default: `0`, maximum: `1024`)
> Warning: this param affects resulting binary only when used in combination with [flattening](#control-flow-flattening)
Trash blocks generator generates blocks that will never be called. Trash blocks contain random function calls and random variable assignments. The purpose of this is to create a large number of references to different methods and local variables and in combination with other controlflow obfuscation parameters it helps to effectively hide the real code.
The generator does not add new dependencies to the project, it uses only existing direct or indirect dependencies. In the following example, the `fmt` package implicitly imports the `io` and `os` packages
Input:
```go
package main
import "fmt"
//garble:controlflow block_splits=0 junk_jumps=0 flatten_passes=0 trash_blocks=1
func main() {
if true {
fmt.Println("hello world")
}
}
```
Result:
```go
package main
import (
"fmt"
"io"
"os"
)
func main() {
var (
_s2a_4 int
_s2a_5 bool
)
{
if true {
goto _s2a_l1
} else {
goto _s2a_l2
}
}
_s2a_l1:
{
_s2a_0 := new([1]interface {
})
_s2a_1 := &_s2a_0[(int)(0)]
_s2a_2 := (interface {
})("hello world")
*_s2a_1 = _s2a_2
_s2a_3 := _s2a_0[:]
_, _ = fmt.Println(_s2a_3...)
_s2a_4 = (int)(1375793722)
goto _s2a_l3
}
_s2a_l2:
{
return
}
_s2a_l3:
{
_s2a_5 = _s2a_4 == (int)(1414729372)
if _s2a_5 {
goto _s2a_l4
} else {
goto _s2a_l2
}
}
_s2a_l4:
{
_s2a_5, _s2a_4 = true, _s2a_4
_garble1v7i062eba5j0, _ := fmt.Printf((string)(_s2a_4), _s2a_4, _s2a_5)
_garble27oahvink0hig, _ := fmt.Println(_garble1v7i062eba5j0)
_ = fmt.Errorf((string)(_garble27oahvink0hig), os.Stdout, 714272279, _garble27oahvink0hig, io.EOF)
_garble27oahvink0hig, _s2a_4, _garble1v7i062eba5j0, _s2a_5 = _s2a_4, (int)(77), _s2a_4, _s2a_5
_, _garble6oknljnlggutn := fmt.Printf((string)(_garble1v7i062eba5j0))
_, _garble8ne429queuq8n := fmt.Scanf((string)(751648516), os.Stdin, 0.17251639929485216, "UAN4E===")
_garble1qt8quedh1fo9, _ := fmt.Scanf((string)(_s2a_4), _garble8ne429queuq8n, _s2a_5, _garble6oknljnlggutn)
_, _ = fmt.Scanf((string)(_garble1qt8quedh1fo9))
goto _s2a_l4
}
}
```
### Caveats
* Obfuscation breaks the lazy iteration over maps. See: [ssa2ast/polyfill.go](../internal/ssa2ast/polyfill.go)

Loading…
Cancel
Save