[sys] windows/svc: use NtQuerySystemInformation in IsWindowsService

171 views
Skip to first unread message

Jason Donenfeld (Gerrit)

unread,
Dec 15, 2021, 6:04:11 PM12/15/21
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Jason Donenfeld has uploaded this change for review.

View Change

windows/svc: use NtQuerySystemInformation in IsWindowsService

This brings the algorithm more exactly in line with what .NET does for
the identically named function. Specifically, instead of using
OpenProcess, which requires rights that restricted services might not
have, we use NtQuerySystemInformation(SYSTEM_PROCESS_INFORMATION) to
find the parent process image name and session ID.

Fixes golang/go#44921.

Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
---
M windows/svc/security.go
M windows/types_windows.go
2 files changed, 74 insertions(+), 28 deletions(-)

diff --git a/windows/svc/security.go b/windows/svc/security.go
index 351d286..7a096ca 100644
--- a/windows/svc/security.go
+++ b/windows/svc/security.go
@@ -8,7 +8,6 @@
package svc

import (
- "path/filepath"
"strings"
"unsafe"

@@ -74,36 +73,29 @@
// Specifically, it looks up whether the parent process has session ID zero
// and is called "services".

- var pbi windows.PROCESS_BASIC_INFORMATION
- pbiLen := uint32(unsafe.Sizeof(pbi))
- err := windows.NtQueryInformationProcess(windows.CurrentProcess(), windows.ProcessBasicInformation, unsafe.Pointer(&pbi), pbiLen, &pbiLen)
+ var currentProcess windows.PROCESS_BASIC_INFORMATION
+ infoSize := uint32(unsafe.Sizeof(currentProcess))
+ err := windows.NtQueryInformationProcess(windows.CurrentProcess(), windows.ProcessBasicInformation, unsafe.Pointer(&currentProcess), infoSize, &infoSize)
if err != nil {
return false, err
}
- var psid uint32
- err = windows.ProcessIdToSessionId(uint32(pbi.InheritedFromUniqueProcessId), &psid)
- if err != nil || psid != 0 {
- return false, nil
+ var parentProcess *windows.SYSTEM_PROCESS_INFORMATION
+ for infoSize = uint32((unsafe.Sizeof(*parentProcess) + unsafe.Sizeof(uintptr(0))) * 1024); ; {
+ parentProcess = (*windows.SYSTEM_PROCESS_INFORMATION)(unsafe.Pointer(&make([]byte, infoSize)[0]))
+ err := windows.NtQuerySystemInformation(windows.SystemProcessInformation, unsafe.Pointer(parentProcess), infoSize, &infoSize)
+ if err == nil {
+ break
+ } else if err != windows.STATUS_INFO_LENGTH_MISMATCH {
+ return false, err
+ }
}
- pproc, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pbi.InheritedFromUniqueProcessId))
- if err != nil {
- return false, err
+ for ; ; parentProcess = (*windows.SYSTEM_PROCESS_INFORMATION)(unsafe.Pointer(uintptr(unsafe.Pointer(parentProcess)) + uintptr(parentProcess.NextEntryOffset))) {
+ if parentProcess.UniqueProcessID == currentProcess.InheritedFromUniqueProcessId {
+ return parentProcess.SessionID == 0 && strings.EqualFold("services.exe", parentProcess.ImageName.String()), nil
+ }
+ if parentProcess.NextEntryOffset == 0 {
+ break
+ }
}
- defer windows.CloseHandle(pproc)
- var exeNameBuf [261]uint16
- exeNameLen := uint32(len(exeNameBuf) - 1)
- err = windows.QueryFullProcessImageName(pproc, 0, &exeNameBuf[0], &exeNameLen)
- if err != nil {
- return false, err
- }
- exeName := windows.UTF16ToString(exeNameBuf[:exeNameLen])
- if !strings.EqualFold(filepath.Base(exeName), "services.exe") {
- return false, nil
- }
- system32, err := windows.GetSystemDirectory()
- if err != nil {
- return false, err
- }
- targetExeName := filepath.Join(system32, "services.exe")
- return strings.EqualFold(exeName, targetExeName), nil
+ return false, nil
}
diff --git a/windows/types_windows.go b/windows/types_windows.go
index 73087bf..68b2576 100644
--- a/windows/types_windows.go
+++ b/windows/types_windows.go
@@ -2749,6 +2749,43 @@
InheritedFromUniqueProcessId uintptr
}

+type SYSTEM_PROCESS_INFORMATION struct {
+ NextEntryOffset uint32
+ NumberOfThreads uint32
+ WorkingSetPrivateSize int64
+ HardFaultCount uint32
+ NumberOfThreadsHighWatermark uint32
+ CycleTime uint64
+ CreateTime int64
+ UserTime int64
+ KernelTime int64
+ ImageName NTUnicodeString
+ BasePriority int32
+ UniqueProcessID uintptr
+ InheritedFromUniqueProcessID uintptr
+ HandleCount uint32
+ SessionID uint32
+ UniqueProcessKey *uint32
+ PeakVirtualSize uintptr
+ VirtualSize uintptr
+ PageFaultCount uint32
+ PeakWorkingSetSize uintptr
+ WorkingSetSize uintptr
+ QuotaPeakPagedPoolUsage uintptr
+ QuotaPagedPoolUsage uintptr
+ QuotaPeakNonPagedPoolUsage uintptr
+ QuotaNonPagedPoolUsage uintptr
+ PagefileUsage uintptr
+ PeakPagefileUsage uintptr
+ PrivatePageCount uintptr
+ ReadOperationCount int64
+ WriteOperationCount int64
+ OtherOperationCount int64
+ ReadTransferCount int64
+ WriteTransferCount int64
+ OtherTransferCount int64
+}
+
// SystemInformationClasses for NtQuerySystemInformation and NtSetSystemInformation
const (
SystemBasicInformation = iota

To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: sys
Gerrit-Branch: master
Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
Gerrit-Change-Number: 372554
Gerrit-PatchSet: 1
Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
Gerrit-MessageType: newchange

Jason Donenfeld (Gerrit)

unread,
Dec 15, 2021, 6:04:41 PM12/15/21
to goph...@pubsubhelper.golang.org, Patrik Nyblom, golang-co...@googlegroups.com

Attention is currently required from: Patrik Nyblom.

Patch set 1:Run-TryBot +1Trust +1

View Change

    To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: sys
    Gerrit-Branch: master
    Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
    Gerrit-Change-Number: 372554
    Gerrit-PatchSet: 1
    Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
    Gerrit-Reviewer: Jason Donenfeld <Ja...@zx2c4.com>
    Gerrit-Reviewer: Patrik Nyblom <pn...@google.com>
    Gerrit-Attention: Patrik Nyblom <pn...@google.com>
    Gerrit-Comment-Date: Wed, 15 Dec 2021 23:04:37 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Jason Donenfeld (Gerrit)

    unread,
    Dec 15, 2021, 6:06:12 PM12/15/21
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Patrik Nyblom.

    Jason Donenfeld uploaded patch set #2 to this change.

    View Change

    windows/svc: use NtQuerySystemInformation in IsWindowsService

    This brings the algorithm more exactly in line with what .NET does for
    the identically named function. Specifically, instead of using
    OpenProcess, which requires rights that restricted services might not
    have, we use NtQuerySystemInformation(SYSTEM_PROCESS_INFORMATION) to
    find the parent process image name and session ID.

    Fixes golang/go#44921.

    Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
    ---
    M windows/svc/security.go
    M windows/types_windows.go
    2 files changed, 74 insertions(+), 28 deletions(-)

    To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: sys
    Gerrit-Branch: master
    Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
    Gerrit-Change-Number: 372554
    Gerrit-PatchSet: 2
    Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
    Gerrit-Reviewer: Jason Donenfeld <Ja...@zx2c4.com>
    Gerrit-Reviewer: Patrik Nyblom <pn...@google.com>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Patrik Nyblom <pn...@google.com>
    Gerrit-MessageType: newpatchset

    Jason Donenfeld (Gerrit)

    unread,
    Dec 15, 2021, 6:06:40 PM12/15/21
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Patrik Nyblom.

    Jason Donenfeld uploaded patch set #3 to this change.

    View Change

    windows/svc: use NtQuerySystemInformation in IsWindowsService

    This brings the algorithm more exactly in line with what .NET does for
    the identically named function. Specifically, instead of using
    OpenProcess, which requires rights that restricted services might not
    have, we use NtQuerySystemInformation(SYSTEM_PROCESS_INFORMATION) to
    find the parent process image name and session ID.

    Fixes golang/go#44921.

    Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
    ---
    M windows/svc/security.go
    M windows/types_windows.go
    2 files changed, 74 insertions(+), 28 deletions(-)

    To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: sys
    Gerrit-Branch: master
    Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
    Gerrit-Change-Number: 372554
    Gerrit-PatchSet: 3

    Jason Donenfeld (Gerrit)

    unread,
    Dec 15, 2021, 6:08:06 PM12/15/21
    to goph...@pubsubhelper.golang.org, Gopher Robot, Patrik Nyblom, golang-co...@googlegroups.com

    Attention is currently required from: Patrik Nyblom.

    Patch set 3:Run-TryBot +1Trust +1

    View Change

      To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sys
      Gerrit-Branch: master
      Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
      Gerrit-Change-Number: 372554
      Gerrit-PatchSet: 3
      Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
      Gerrit-Reviewer: Jason Donenfeld <Ja...@zx2c4.com>
      Gerrit-Reviewer: Patrik Nyblom <pn...@google.com>
      Gerrit-CC: Gopher Robot <go...@golang.org>
      Gerrit-Attention: Patrik Nyblom <pn...@google.com>
      Gerrit-Comment-Date: Wed, 15 Dec 2021 23:08:00 +0000

      Jason Donenfeld (Gerrit)

      unread,
      Dec 15, 2021, 6:11:29 PM12/15/21
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

      Attention is currently required from: Jason Donenfeld, Patrik Nyblom.

      Jason Donenfeld uploaded patch set #4 to this change.

      View Change

      windows/svc: use NtQuerySystemInformation in IsWindowsService

      This brings the algorithm more exactly in line with what .NET does for
      the identically named function. Specifically, instead of using
      OpenProcess, which requires rights that restricted services might not
      have, we use NtQuerySystemInformation(SYSTEM_PROCESS_INFORMATION) to
      find the parent process image name and session ID.

      Fixes golang/go#44921.

      Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
      ---
      M windows/svc/security.go
      M windows/types_windows.go
      2 files changed, 74 insertions(+), 28 deletions(-)

      To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sys
      Gerrit-Branch: master
      Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
      Gerrit-Change-Number: 372554
      Gerrit-PatchSet: 4
      Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
      Gerrit-Reviewer: Gopher Robot <go...@golang.org>
      Gerrit-Reviewer: Jason Donenfeld <Ja...@zx2c4.com>
      Gerrit-Reviewer: Patrik Nyblom <pn...@google.com>
      Gerrit-Attention: Jason Donenfeld <Ja...@zx2c4.com>

      Jason Donenfeld (Gerrit)

      unread,
      Dec 15, 2021, 6:12:11 PM12/15/21
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

      Attention is currently required from: Jason Donenfeld, Patrik Nyblom.

      Jason Donenfeld uploaded patch set #5 to this change.

      View Change

      windows/svc: use NtQuerySystemInformation in IsWindowsService

      This brings the algorithm more exactly in line with what .NET does for
      the identically named function. Specifically, instead of using
      OpenProcess, which requires rights that restricted services might not
      have, we use NtQuerySystemInformation(SYSTEM_PROCESS_INFORMATION) to
      find the parent process image name and session ID.

      Fixes golang/go#44921.

      Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
      ---
      M windows/svc/security.go
      M windows/types_windows.go
      2 files changed, 74 insertions(+), 28 deletions(-)

      To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: sys
      Gerrit-Branch: master
      Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
      Gerrit-Change-Number: 372554
      Gerrit-PatchSet: 5

      Jason Donenfeld (Gerrit)

      unread,
      Dec 15, 2021, 6:12:20 PM12/15/21
      to goph...@pubsubhelper.golang.org, Gopher Robot, Patrik Nyblom, golang-co...@googlegroups.com

      Attention is currently required from: Patrik Nyblom.

      Patch set 5:Run-TryBot +1Trust +1

      View Change

        To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: sys
        Gerrit-Branch: master
        Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
        Gerrit-Change-Number: 372554
        Gerrit-PatchSet: 5
        Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
        Gerrit-Reviewer: Gopher Robot <go...@golang.org>
        Gerrit-Reviewer: Jason Donenfeld <Ja...@zx2c4.com>
        Gerrit-Reviewer: Patrik Nyblom <pn...@google.com>
        Gerrit-Attention: Patrik Nyblom <pn...@google.com>
        Gerrit-Comment-Date: Wed, 15 Dec 2021 23:12:15 +0000

        Patrik Nyblom (Gerrit)

        unread,
        Dec 15, 2021, 9:01:39 PM12/15/21
        to Jason Donenfeld, goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

        Attention is currently required from: Jason Donenfeld.

        Patch set 5:Run-TryBot +1Code-Review +2Trust +1

        View Change

          To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: sys
          Gerrit-Branch: master
          Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
          Gerrit-Change-Number: 372554
          Gerrit-PatchSet: 5
          Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
          Gerrit-Reviewer: Gopher Robot <go...@golang.org>
          Gerrit-Reviewer: Jason Donenfeld <Ja...@zx2c4.com>
          Gerrit-Reviewer: Patrik Nyblom <pn...@google.com>
          Gerrit-Attention: Jason Donenfeld <Ja...@zx2c4.com>
          Gerrit-Comment-Date: Thu, 16 Dec 2021 02:01:33 +0000

          Jason Donenfeld (Gerrit)

          unread,
          Dec 15, 2021, 9:10:21 PM12/15/21
          to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Patrik Nyblom, Gopher Robot, golang-co...@googlegroups.com

          Jason Donenfeld submitted this change.

          View Change


          Approvals: Patrik Nyblom: Looks good to me, approved; Trusted; Run TryBots Jason Donenfeld: Trusted; Run TryBots Gopher Robot: TryBots succeeded
          windows/svc: use NtQuerySystemInformation in IsWindowsService

          This brings the algorithm more exactly in line with what .NET does for
          the identically named function. Specifically, instead of using
          OpenProcess, which requires rights that restricted services might not
          have, we use NtQuerySystemInformation(SYSTEM_PROCESS_INFORMATION) to
          find the parent process image name and session ID.

          Fixes golang/go#44921.

          Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
          Reviewed-on: https://go-review.googlesource.com/c/sys/+/372554
          Trust: Jason Donenfeld <Ja...@zx2c4.com>
          Run-TryBot: Jason Donenfeld <Ja...@zx2c4.com>
          TryBot-Result: Gopher Robot <go...@golang.org>
          Reviewed-by: Patrik Nyblom <pn...@google.com>
          Trust: Patrik Nyblom <pn...@google.com>
          Run-TryBot: Patrik Nyblom <pn...@google.com>

          ---
          M windows/svc/security.go
          M windows/types_windows.go
          2 files changed, 81 insertions(+), 28 deletions(-)

          diff --git a/windows/svc/security.go b/windows/svc/security.go
          index 351d286..1c51006 100644
          index 655447e..bb31abd 100644

          To view, visit change 372554. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: sys
          Gerrit-Branch: master
          Gerrit-Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
          Gerrit-Change-Number: 372554
          Gerrit-PatchSet: 6
          Gerrit-Owner: Jason Donenfeld <Ja...@zx2c4.com>
          Gerrit-Reviewer: Gopher Robot <go...@golang.org>
          Gerrit-Reviewer: Jason Donenfeld <Ja...@zx2c4.com>
          Gerrit-Reviewer: Patrik Nyblom <pn...@google.com>
          Gerrit-MessageType: merged
          Reply all
          Reply to author
          Forward
          0 new messages