From 8d8ba00515fc3c6826989c2338fef2d8a81660c7 Mon Sep 17 00:00:00 2001 From: Paul Scheduikat Date: Thu, 12 Jun 2025 14:25:09 +0200 Subject: [PATCH] properly handle controlflow obfuscation in code that uses unsafe Due to unsafe not being a real dependency, type checking during control-flow obfuscation was performed incorrectly. This is fixed by excluding unsafe from the dependency checks. Fixes #903 --- main.go | 7 +++++++ testdata/script/ctrlflow.txtar | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 1b8143a..998664e 100644 --- a/main.go +++ b/main.go @@ -1248,6 +1248,11 @@ func (tf *transformer) processImportCfg(flags []string, requiredPkgs []string) ( if requiredPkgs != nil { newIndirectImports = make(map[string]bool) for _, pkg := range requiredPkgs { + // unsafe is a special case, it's not a real dependency + if pkg == "unsafe" { + continue + } + newIndirectImports[pkg] = true } } @@ -1727,6 +1732,8 @@ func recordType(used, origin types.Type, done map[*types.Named]bool, fieldToStru // Unsafe types: generic types and non-method interfaces. func isSafeForInstanceType(t types.Type) bool { switch t := types.Unalias(t).(type) { + case *types.Basic: + return t.Kind() != types.Invalid case *types.Named: if t.TypeParams().Len() > 0 { return false diff --git a/testdata/script/ctrlflow.txtar b/testdata/script/ctrlflow.txtar index 57800d6..ed31589 100644 --- a/testdata/script/ctrlflow.txtar +++ b/testdata/script/ctrlflow.txtar @@ -38,6 +38,7 @@ import ( "encoding/binary" "encoding/hex" "hash/crc32" + "unsafe" ) //garble:controlflow flatten_passes=0 junk_jumps=max block_splits=max @@ -78,6 +79,22 @@ func multiHardeningTest(i int) int { return multiply(i); } +//garble:controlflow +func ModifyValue() { + var a int = 42 + var p *int = &a + + println("Value of a:", a) + + var up unsafe.Pointer = unsafe.Pointer(p) + + var p2 *int = (*int)(up) + + *p2 = 100 + + println("New value of a:", a) +} + //garble:controlflow flatten_passes=1 junk_jumps=10 block_splits=10 trash_blocks=32 func main() { // Reference to the unexported interface triggers creation of a new interface @@ -106,6 +123,7 @@ func main() { println(xorHardeningTest(0)) println(delegateHardeningTest(0)) println(multiHardeningTest(0)) + ModifyValue() } -- main.stderr -- @@ -116,4 +134,6 @@ correct name 884863d2 1 1 -1 \ No newline at end of file +1 +Value of a: 42 +New value of a: 100