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.
		
		
		
		
		
			
		
			
				
	
	
		
			172 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Plaintext
		
	
			
		
		
	
	
			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.20
 | 
						|
 | 
						|
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.20
 | 
						|
-- 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
 |