Go version

go1.20.14.windows、go1.22.3.windows and so on

Output of go env in your module/workspace:

set GO111MODULE=
set GOARCH=386
set GOBIN=
set GOCACHE=C:\Users\user\AppData\Local\go-build
set GOENV=C:\Users\user\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\user\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\user\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.20.14
set GCCGO=gccgo
set GO386=sse2
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=0
set GOMOD=C:\Program Files\go\bin\go.mod
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m32 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=C:\Users\user\AppData\Local\Temp\go-build283101179=/tmp/go-build -gno-record-gcc-switches

What did you do?

I've encountered an unusual issue while developing with Go on Windows systems. When I compile a very simple program, if the resulting executable's filename contains the word "update", it requires administrator privileges to run. However, if I rename the same file, it runs normally without requiring elevated permissions.

Project structure: The test project consists of only two files:

go.mod:

module update
go 1.20

main.go:

package main

import "fmt"

func main() {
    fmt.Println("hello")
}

What did you see happen?

Specific observations:

1、The issue occurs with multiple Go versions:
    Go 1.20.14 (both amd64 and 386 versions)
    Go 1.22.3 (amd64 version)
2、The problem persists whether cross-compiling for 32-bit on a 64-bit system or compiling directly on a 32-bit system.
3、The code is extremely simple, containing only a fmt.Println statement.
4、When the executable is named "EasyUpdate.exe", it requires admin rights to run.
5、Renaming the same executable to a name without "update" allows it to run normally without elevation.

Using Process Monitor, I found that the program with "update" in its name performs these additional operations:

1、Extra thread creation and exit.
2、Loading both 32-bit and 64-bit versions of ntdll.dll.
3、Attempting to access registry keys under HKLM.
4、Quick program exit with status code 0xC0000002 (privileged instruction).

This behavior seems to be related to the Go runtime or compiler, as programs compiled with other languages (e.g., C#) don't exhibit this issue.

What did you expect to see?

Questions:

1、Is this a known behavior of Go?
2、If so, what's the rationale behind it?
3、If not, could this be an issue worth investigating?
4、Is there any way to prevent this behavior while still using "update" in the filename?

I appreciate any insights or guidance on this matter. Thank you for your time and attention.

Comment From: seankhliao

cc @golang/windows

Comment From: dagood

This is caused by UAC's "Installer detection technology":

Before a 32-bit process is created, the following attributes are checked to determine whether it's an installer:

  • The file name includes keywords such as "install," "setup," or "update."
  • [...]

This happens for people using other languages as well when there isn't a manifest (or a manifest doesn't include an requestedExecutionLevel):

  • VB6 https://stackoverflow.com/q/20096706
  • Delphi https://stackoverflow.com/q/4133337

I believe this issue tracks Go generating manifests for exe files that could include this info:

  • https://github.com/golang/go/issues/17835

(I haven't looked through the alternatives mentioned there, but there might already be a tool listed in that issue that you could use to create a manifest now that ensures your exe won't request/have privileges.)

Comment From: seankhliao

Duplicate of #17835