From b3db7d6fa721dd6f7d1755ff7b1757d78d7a25c8 Mon Sep 17 00:00:00 2001 From: Andrew LeFevre Date: Tue, 20 Apr 2021 18:05:49 -0400 Subject: [PATCH] fix obfuscating linkname directives that where the package name contained a dot --- main.go | 21 ++++++++++++++++++--- testdata/scripts/linkname.txt | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index b75fb50..a6eba5d 100644 --- a/main.go +++ b/main.go @@ -727,6 +727,7 @@ func (tf *transformer) handleDirectives(comments []*ast.CommentGroup) { } fields := strings.Fields(comment.Text) if len(fields) != 3 { + // TODO: the 2nd argument is optional, handle when it's not present continue } // This directive has two arguments: "go:linkname localName newName" @@ -737,11 +738,25 @@ func (tf *transformer) handleDirectives(comments []*ast.CommentGroup) { // If the new name is of the form "pkgpath.Name", and // we've obfuscated "Name" in that package, rewrite the // directive to use the obfuscated name. - target := strings.Split(fields[2], ".") - if len(target) != 2 { + newName := fields[2] + dotCnt := strings.Count(newName, ".") + if dotCnt < 1 { + // probably a malformed linkname directive continue } - pkgPath, name := target[0], target[1] + + // If the package path has multiple dots, split on the + // last one. + var pkgPath, name string + if dotCnt == 1 { + target := strings.Split(newName, ".") + pkgPath, name = target[0], target[1] + } else { + lastDotIdx := strings.LastIndex(newName, ".") + target := strings.Split(newName[lastDotIdx-1:], ".") + pkgPath, name = target[0], target[1] + } + if pkgPath == "runtime" && strings.HasPrefix(name, "cgo") { continue // ignore cgo-generated linknames } diff --git a/testdata/scripts/linkname.txt b/testdata/scripts/linkname.txt index 60cde4b..d6cc144 100644 --- a/testdata/scripts/linkname.txt +++ b/testdata/scripts/linkname.txt @@ -17,6 +17,12 @@ module test/main go 1.16 +replace big.chungus/meme => ./big.chungus/meme + +require ( + big.chungus/meme v0.0.0 +) + -- a.go -- package main @@ -36,6 +42,7 @@ import ( _ "strings" _ "unsafe" + _ "big.chungus/meme" "test/main/imported" ) @@ -55,11 +62,17 @@ func obfuscatedFunc() string //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()) println(renamedFunc()) + println(tagline()) println(imported.ByteIndex("01234", '3')) linknameCalledInPkg() } @@ -83,10 +96,22 @@ func renamedFunc() string { // 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.16 + +-- 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 renamed func +featuring Dante from the Devil May Cry series 3 obfuscated func