Skip to content

Instantly share code, notes, and snippets.

@Romern
Created June 16, 2026 20:29
Show Gist options
  • Select an option

  • Save Romern/01bc46fc9423143cc20044d0a831f963 to your computer and use it in GitHub Desktop.

Select an option

Save Romern/01bc46fc9423143cc20044d0a831f963 to your computer and use it in GitHub Desktop.
go mod init
go get golang.org/x/sys/windows
go get golang.org/x/sys/windows/svc
GOOS=windows GOARCH=amd64 go build -o uishell.exe
sc create UiShellSvc binPath="C:\path\uishell.exe" start=demand
sc start UiShellSvc
package main
import (
"unsafe"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"
)
const svcName = "UiShellSvc"
var (
modwtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
moduserenv = windows.NewLazySystemDLL("userenv.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId")
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
procCreateProcessAsUser = modadvapi32.NewProc("CreateProcessAsUserW")
)
const (
createNewConsole = 0x00000010
createUnicodeEnvironment = 0x00000400
tokenSessionId = 12 // TokenSessionId enum value
)
func activeConsoleSession() uint32 {
r, _, _ := procWTSGetActiveConsoleSessionId.Call()
return uint32(r)
}
// launchShellInSession duplicates the SYSTEM token, retargets it to the given
// session, and spawns cmd.exe on the interactive desktop.
func launchShellInSession(sessionId uint32) error {
var self windows.Token
err := windows.OpenProcessToken(
windows.CurrentProcess(),
windows.TOKEN_DUPLICATE|windows.TOKEN_QUERY|
windows.TOKEN_ASSIGN_PRIMARY|windows.TOKEN_ADJUST_DEFAULT|
windows.TOKEN_ADJUST_SESSIONID,
&self,
)
if err != nil {
return err
}
defer self.Close()
var dup windows.Token
err = windows.DuplicateTokenEx(
self,
windows.MAXIMUM_ALLOWED,
nil,
windows.SecurityImpersonation,
windows.TokenPrimary,
&dup,
)
if err != nil {
return err
}
defer dup.Close()
// Retarget the token to the interactive session.
if err := windows.SetTokenInformation(
dup,
tokenSessionId,
(*byte)(unsafe.Pointer(&sessionId)),
uint32(unsafe.Sizeof(sessionId)),
); err != nil {
return err
}
// Build an environment block for the duplicated token.
var env uintptr
procCreateEnvironmentBlock.Call(uintptr(unsafe.Pointer(&env)), uintptr(dup), 0)
if env != 0 {
defer procDestroyEnvironmentBlock.Call(env)
}
desktop, _ := windows.UTF16PtrFromString(`winsta0\default`)
cmdline, _ := windows.UTF16PtrFromString(`cmd.exe`)
si := windows.StartupInfo{
Cb: uint32(unsafe.Sizeof(windows.StartupInfo{})),
Desktop: desktop,
}
var pi windows.ProcessInformation
r, _, e := procCreateProcessAsUser.Call(
uintptr(dup),
0,
uintptr(unsafe.Pointer(cmdline)),
0,
0,
0,
uintptr(createNewConsole|createUnicodeEnvironment),
env,
0,
uintptr(unsafe.Pointer(&si)),
uintptr(unsafe.Pointer(&pi)),
)
if r == 0 {
return e
}
windows.CloseHandle(pi.Thread)
windows.CloseHandle(pi.Process)
return nil
}
type uiShellService struct{}
func (uiShellService) Execute(args []string, r <-chan svc.ChangeRequest, s chan<- svc.Status) (bool, uint32) {
s <- svc.Status{State: svc.StartPending}
s <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown}
if sid := activeConsoleSession(); sid != 0xFFFFFFFF {
launchShellInSession(sid)
}
// One-shot: stop after spawning. Drain any stop request in the meantime.
for {
select {
case c := <-r:
switch c.Cmd {
case svc.Stop, svc.Shutdown:
s <- svc.Status{State: svc.StopPending}
return false, 0
case svc.Interrogate:
s <- c.CurrentStatus
}
default:
s <- svc.Status{State: svc.StopPending}
return false, 0
}
}
}
func main() {
svc.Run(svcName, uiShellService{})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment