github.com/HACKERALERT/Picocrypt/src/external/sys@v0.0.0-20210609020157-e519952f829f/windows/svc/security.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build windows
     6  
     7  package svc
     8  
     9  import (
    10  	"path/filepath"
    11  	"strings"
    12  	"unsafe"
    13  
    14  	"golang.org/x/sys/windows"
    15  )
    16  
    17  func allocSid(subAuth0 uint32) (*windows.SID, error) {
    18  	var sid *windows.SID
    19  	err := windows.AllocateAndInitializeSid(&windows.SECURITY_NT_AUTHORITY,
    20  		1, subAuth0, 0, 0, 0, 0, 0, 0, 0, &sid)
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  	return sid, nil
    25  }
    26  
    27  // IsAnInteractiveSession determines if calling process is running interactively.
    28  // It queries the process token for membership in the Interactive group.
    29  // http://stackoverflow.com/questions/2668851/how-do-i-detect-that-my-application-is-running-as-service-or-in-an-interactive-s
    30  //
    31  // Deprecated: Use IsWindowsService instead.
    32  func IsAnInteractiveSession() (bool, error) {
    33  	interSid, err := allocSid(windows.SECURITY_INTERACTIVE_RID)
    34  	if err != nil {
    35  		return false, err
    36  	}
    37  	defer windows.FreeSid(interSid)
    38  
    39  	serviceSid, err := allocSid(windows.SECURITY_SERVICE_RID)
    40  	if err != nil {
    41  		return false, err
    42  	}
    43  	defer windows.FreeSid(serviceSid)
    44  
    45  	t, err := windows.OpenCurrentProcessToken()
    46  	if err != nil {
    47  		return false, err
    48  	}
    49  	defer t.Close()
    50  
    51  	gs, err := t.GetTokenGroups()
    52  	if err != nil {
    53  		return false, err
    54  	}
    55  
    56  	for _, g := range gs.AllGroups() {
    57  		if windows.EqualSid(g.Sid, interSid) {
    58  			return true, nil
    59  		}
    60  		if windows.EqualSid(g.Sid, serviceSid) {
    61  			return false, nil
    62  		}
    63  	}
    64  	return false, nil
    65  }
    66  
    67  // IsWindowsService reports whether the process is currently executing
    68  // as a Windows service.
    69  func IsWindowsService() (bool, error) {
    70  	// The below technique looks a bit hairy, but it's actually
    71  	// exactly what the .NET framework does for the similarly named function:
    72  	// https://github.com/dotnet/extensions/blob/f4066026ca06984b07e90e61a6390ac38152ba93/src/Hosting/WindowsServices/src/WindowsServiceHelpers.cs#L26-L31
    73  	// Specifically, it looks up whether the parent process has session ID zero
    74  	// and is called "services".
    75  
    76  	var pbi windows.PROCESS_BASIC_INFORMATION
    77  	pbiLen := uint32(unsafe.Sizeof(pbi))
    78  	err := windows.NtQueryInformationProcess(windows.CurrentProcess(), windows.ProcessBasicInformation, unsafe.Pointer(&pbi), pbiLen, &pbiLen)
    79  	if err != nil {
    80  		return false, err
    81  	}
    82  	var psid uint32
    83  	err = windows.ProcessIdToSessionId(uint32(pbi.InheritedFromUniqueProcessId), &psid)
    84  	if err != nil || psid != 0 {
    85  		return false, nil
    86  	}
    87  	pproc, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pbi.InheritedFromUniqueProcessId))
    88  	if err != nil {
    89  		return false, err
    90  	}
    91  	defer windows.CloseHandle(pproc)
    92  	var exeNameBuf [261]uint16
    93  	exeNameLen := uint32(len(exeNameBuf) - 1)
    94  	err = windows.QueryFullProcessImageName(pproc, 0, &exeNameBuf[0], &exeNameLen)
    95  	if err != nil {
    96  		return false, err
    97  	}
    98  	exeName := windows.UTF16ToString(exeNameBuf[:exeNameLen])
    99  	if !strings.EqualFold(filepath.Base(exeName), "services.exe") {
   100  		return false, nil
   101  	}
   102  	system32, err := windows.GetSystemDirectory()
   103  	if err != nil {
   104  		return false, err
   105  	}
   106  	targetExeName := filepath.Join(system32, "services.exe")
   107  	return strings.EqualFold(exeName, targetExeName), nil
   108  }