split code to inject into internal/abi into a separate file

This way we can edit it as regular Go code, with the help of an LSP,
and we can also test and benchmark it.
This commit is contained in:
Daniel Martí
2024-11-30 23:27:32 +00:00
parent 926f3de60d
commit 78a6a42ecf
2 changed files with 56 additions and 45 deletions

50
reflect_abi_code.go Normal file
View File

@@ -0,0 +1,50 @@
package main
// The "name" internal/abi passes to this function doesn't have to be a simple "someName"
// it can also be for function names:
// "*pkgName.FuncName" (obfuscated)
// or for structs the entire struct definition:
// "*struct { AQ45rr68K string; ipq5aQSIqN string; hNfiW5O5LVq struct { gPTbGR00hu string } }"
//
// Therefore all obfuscated names which occur within name need to be replaced with their "real" equivalents.
//
// The code below does a more efficient version of:
//
// func _realName(name string) string {
// for obfName, real := range _nameMap {
// name = strings.ReplaceAll(name, obfName, real)
// }
//
// return name
// }
//
// The linknames below are only turned on when the code is injected,
// so that we can test and benchmark this code normally.
// Injected code below this line.
//disabledgo:linkname _realName internal/abi._realName
func _realName(name string) string {
for i := 0; i < len(name); {
remLen := len(name[i:])
found := false
for obfName, real := range _nameMap {
keyLen := len(obfName)
if keyLen > remLen {
continue
}
if name[i:i+keyLen] == obfName {
name = name[:i] + real + name[i+keyLen:]
found = true
i += len(real)
break
}
}
if !found {
i++
}
}
return name
}
var _nameMap = map[string]string{}

View File

@@ -2,6 +2,7 @@ package main
import (
"bytes"
_ "embed"
"fmt"
"maps"
"os"
@@ -46,10 +47,9 @@ func reflectMainPrePatch(path string) ([]byte, error) {
if err != nil {
return nil, err
}
nameMap := "\nvar _nameMap = map[string]string{}"
return append(content, []byte(realNameCode+nameMap)...), nil
_, code, _ := strings.Cut(reflectAbiCode, "// Injected code below this line.")
code = strings.ReplaceAll(code, "//disabledgo:", "//go:")
return append(content, []byte(code)...), nil
}
// reflectMainPostPatch populates the name mapping with the final obfuscated->real name
@@ -67,44 +67,5 @@ func reflectMainPostPatch(file []byte, lpkg *listedPackage, pkg pkgCache) []byte
return bytes.Replace(file, []byte(nameMap), []byte(nameMap+b.String()), 1)
}
// The "name" internal/abi passes to this function doesn't have to be a simple "someName"
// it can also be for function names:
// "*pkgName.FuncName" (obfuscated)
// or for structs the entire struct definition:
// "*struct { AQ45rr68K string; ipq5aQSIqN string; hNfiW5O5LVq struct { gPTbGR00hu string } }"
//
// Therefore all obfuscated names which occur within name need to be replaced with their "real" equivalents.
//
// The code below does a more efficient version of:
//
// func _realName(name string) string {
// for obfName, real := range _nameMap {
// name = strings.ReplaceAll(name, obfName, real)
// }
//
// return name
// }
const realNameCode = `
//go:linkname _realName internal/abi._realName
func _realName(name string) string {
for i := 0; i < len(name); {
remLen := len(name[i:])
found := false
for obfName, real := range _nameMap {
keyLen := len(obfName)
if keyLen > remLen {
continue
}
if name[i:i+keyLen] == obfName {
name = name[:i] + real + name[i+keyLen:]
found = true
i += len(real)
break
}
}
if !found {
i++
}
}
return name
}`
//go:embed reflect_abi_code.go
var reflectAbiCode string