mirror of
https://github.com/burrowers/garble
synced 2026-06-06 15:24:28 +00:00
30357af923
This lets us start taking advantage of featurs from Go 1.23, particularly tracking aliases in go/types and iterators. Note that we need to add code to properly handle or skip over the new *types.Alias type which go/types produces for Go type aliases. Also note that we actually turn this mode off entirely for now, due to the bug reported at https://go.dev/issue/70394. We don't yet remove our own alias tracking code yet due to the above. We hope to be able to remove it very soon.
193 lines
4.7 KiB
Plaintext
193 lines
4.7 KiB
Plaintext
exec garble build
|
|
exec ./main
|
|
cmp stderr main.stderr
|
|
|
|
# TODO: why is 'obfuscatedMethod' present?
|
|
! binsubstr main$exe 'obfuscatedFunc' 'ObfuscatedFunc'
|
|
binsubstr main$exe 'UnobfuscatedMethod'
|
|
|
|
[short] stop # no need to verify this with -short
|
|
|
|
go build
|
|
exec ./main
|
|
cmp stderr main.stderr
|
|
-- go.mod --
|
|
module test/main
|
|
|
|
go 1.23
|
|
|
|
replace big.chungus/meme => ./big.chungus/meme
|
|
require big.chungus/meme v0.0.0
|
|
-- a.go --
|
|
package main
|
|
|
|
// Call a function which is linknamed to another symbol.
|
|
// What's special here is that we obfuscate this call before the function declaration.
|
|
// If we decide not to obfuscate the name in the function declaration,
|
|
// we shouldn't obfuscate the name here either.
|
|
func linknameCalledInPkg() {
|
|
println(obfuscatedFunc())
|
|
}
|
|
|
|
-- main.go --
|
|
package main
|
|
|
|
import (
|
|
_ "os/exec"
|
|
"reflect"
|
|
_ "strings"
|
|
"unsafe"
|
|
|
|
_ "big.chungus/meme"
|
|
"test/main/imported"
|
|
)
|
|
|
|
// A linkname to an external obfuscated func.
|
|
//go:linkname obfuscatedFunc test/main/imported.ObfuscatedFuncImpl
|
|
func obfuscatedFunc() string
|
|
|
|
// A linkname to an external obfuscated method.
|
|
//go:linkname obfuscatedMethod test/main/imported.Receiver.obfuscatedMethod
|
|
func obfuscatedMethod(imported.Receiver) string
|
|
|
|
// A linkname to an external unobfuscated method.
|
|
//go:linkname unobfuscatedMethod test/main/imported.Receiver.UnobfuscatedMethod
|
|
func unobfuscatedMethod(imported.Receiver) string
|
|
|
|
// A linkname to an external obfuscated pointer method, with an extra parameter.
|
|
//go:linkname obfuscatedPointerMethod test/main/imported.(*Receiver).obfuscatedPointerMethod
|
|
func obfuscatedPointerMethod(*imported.Receiver, string) string
|
|
|
|
// Similar to the above, but for std, plus having to define a type.
|
|
// Some libraries do abuse reflect in this way, unfortunately.
|
|
type rtype struct{}
|
|
//go:linkname rtype_ptrTo reflect.(*rtype).ptrTo
|
|
func rtype_ptrTo(*rtype) *rtype
|
|
//go:linkname rtype_NumMethod reflect.(*rtype).NumMethod
|
|
func rtype_NumMethod(*rtype) int
|
|
|
|
// A linkname to an entirely made up name, implemented elsewhere.
|
|
//go:linkname renamedFunc madeup.newName
|
|
func renamedFunc() string
|
|
|
|
// A linkname to an external non-obfuscated func in another
|
|
// module whose package path has a dot in it.
|
|
//go:linkname tagline big.chungus/meme.chungify
|
|
func tagline() string
|
|
|
|
// A linkname to an external non-obfuscated func with receiver which is also non-obfuscated
|
|
//go:linkname changeThing test/main/imported.(*channel).changeThing
|
|
func changeThing(c unsafe.Pointer, to string)
|
|
|
|
func main() {
|
|
println(obfuscatedFunc())
|
|
|
|
r := imported.Receiver{Field: "field value"}
|
|
println(obfuscatedMethod(r))
|
|
println(unobfuscatedMethod(r))
|
|
println(obfuscatedPointerMethod(&r, "another value"))
|
|
|
|
typ := reflect.TypeOf(new(error)).Elem()
|
|
type emptyInterface struct {
|
|
_ *rtype
|
|
ptr unsafe.Pointer
|
|
}
|
|
rtyp := (*rtype)(((*emptyInterface)(unsafe.Pointer(&typ))).ptr)
|
|
println("rtype_ptrTo non-nil", rtype_ptrTo(rtyp) != nil)
|
|
println("rtype_NumMethod", rtype_NumMethod(rtyp))
|
|
|
|
println(renamedFunc())
|
|
println(tagline())
|
|
println(imported.ByteIndex("01234", '3'))
|
|
linknameCalledInPkg()
|
|
|
|
a := imported.Return("initial_text")
|
|
|
|
val := reflect.ValueOf(a)
|
|
changeThing(val.UnsafePointer(), "to this")
|
|
println(a.DoThing())
|
|
|
|
}
|
|
-- imported/imported.go --
|
|
package imported
|
|
|
|
import (
|
|
_ "strings"
|
|
_ "unsafe"
|
|
|
|
"reflect"
|
|
)
|
|
|
|
type Test interface {
|
|
DoThing() string
|
|
}
|
|
|
|
func Return(c string) Test {
|
|
return &channel{dummy: c}
|
|
}
|
|
|
|
type channel struct {
|
|
dummy string
|
|
}
|
|
|
|
var _ = reflect.TypeOf(channel{})
|
|
|
|
func (c *channel) DoThing() string {
|
|
return c.dummy
|
|
}
|
|
|
|
func (c *channel) changeThing(to string) {
|
|
c.dummy = to
|
|
}
|
|
|
|
func ObfuscatedFuncImpl() string {
|
|
return "obfuscated func"
|
|
}
|
|
|
|
type Receiver struct{
|
|
Field string
|
|
}
|
|
|
|
func (r Receiver) obfuscatedMethod() string {
|
|
return "obfuscated method: " + r.Field
|
|
}
|
|
|
|
func (r *Receiver) obfuscatedPointerMethod(extra string) string {
|
|
return "obfuscated pointer method: " + r.Field + " plus " + extra
|
|
}
|
|
|
|
func (r Receiver) UnobfuscatedMethod() string {
|
|
return "unobfuscated method: " + r.Field
|
|
}
|
|
|
|
//go:linkname renamedFunc madeup.newName
|
|
func renamedFunc() string {
|
|
return "renamed func"
|
|
}
|
|
|
|
// A linkname to an external non-obfuscated func.
|
|
// Different from byteIndex, as we call this from an importer package.
|
|
//go:linkname ByteIndex strings.IndexByte
|
|
func ByteIndex(s string, c byte) int
|
|
-- big.chungus/meme/go.mod --
|
|
module test/main
|
|
|
|
go 1.23
|
|
-- big.chungus/meme/dante.go --
|
|
package meme
|
|
|
|
func chungify() string {
|
|
return "featuring Dante from the Devil May Cry series"
|
|
}
|
|
-- main.stderr --
|
|
obfuscated func
|
|
obfuscated method: field value
|
|
unobfuscated method: field value
|
|
obfuscated pointer method: field value plus another value
|
|
rtype_ptrTo non-nil true
|
|
rtype_NumMethod 1
|
|
renamed func
|
|
featuring Dante from the Devil May Cry series
|
|
3
|
|
obfuscated func
|
|
to this |