You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
garble/testdata/script/linkname.txtar

172 lines
4.4 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.22
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 non-obfuscated func.
//go:linkname byteIndex strings.IndexByte
func byteIndex(s string, c byte) int
// A linkname to an external non-obfuscated non-exported func.
//go:linkname interfaceEqual os/exec.interfaceEqual
func interfaceEqual(a, b any) bool
// 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
func main() {
println(byteIndex("01234", '3'))
println(interfaceEqual("Sephiroth", 7))
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()
}
-- imported/imported.go --
package imported
import (
_ "strings"
_ "unsafe"
)
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.22
-- big.chungus/meme/dante.go --
package meme
func chungify() string {
return "featuring Dante from the Devil May Cry series"
}
-- main.stderr --
3
false
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