Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,9 @@
package windows

const (
// This process access rights are missing from Go's syscall package as of 1.10.3

// PROCESS_VM_READ right allows to read memory from the target process.
// Deprecated: use x/sys/windows
PROCESS_VM_READ = 0x10

// PROCESS_QUERY_LIMITED_INFORMATION right allows to access a subset of the
// information granted by PROCESS_QUERY_INFORMATION. Not available in XP
// and Server 2003.
// Deprecated: use x/sys/windows
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
)
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.18

require (
github.com/stretchr/testify v1.9.0
golang.org/x/sys v0.18.0
golang.org/x/sys v0.24.0
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
17 changes: 8 additions & 9 deletions kernel32.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ import (
"syscall"
"time"
"unsafe"

"golang.org/x/sys/windows"
)

// Syscalls
//sys _GetNativeSystemInfo(systemInfo *SystemInfo) = kernel32.GetNativeSystemInfo
//sys _GetTickCount64() (millis uint64, err error) = kernel32.GetTickCount64
//sys _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes
//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
//sys _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) = kernel32.ReadProcessMemory
//sys _GetProcessHandleCount(handle syscall.Handle, pdwHandleCount *uint32) (err error) = kernel32.GetProcessHandleCount

var (
Expand Down Expand Up @@ -224,18 +225,16 @@ func GlobalMemoryStatusEx() (MemoryStatusEx, error) {
return memoryStatusEx, nil
}

// ReadProcessMemory reads from another process memory. The Handle needs to have
// the PROCESS_VM_READ right.
// A zero-byte read is a no-op, no error is returned.
func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (numRead uintptr, err error) {
// Deprecated: use x/sys/windows
func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (uintptr, error) {
n := len(dest)
if n == 0 {
return 0, nil
}
if err = _ReadProcessMemory(handle, baseAddress, uintptr(unsafe.Pointer(&dest[0])), uintptr(n), &numRead); err != nil {
return 0, err
}
return numRead, nil

var numRead uintptr
err := windows.ReadProcessMemory(windows.Handle(handle), baseAddress, &dest[0], uintptr(n), &numRead)
return numRead, err
}

// GetProcessHandleCount retrieves the number of open handles of a process.
Expand Down
21 changes: 7 additions & 14 deletions ntdll.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"fmt"
"syscall"
"unsafe"

"golang.org/x/sys/windows"
)

const (
Expand Down Expand Up @@ -108,20 +110,11 @@ type RtlUserProcessParameters struct {
CommandLine UnicodeString
}

// Syscalls
// Warning: NtQueryInformationProcess is an unsupported API that can change
// in future versions of Windows. Available from XP to Windows 10.
//sys _NtQueryInformationProcess(handle syscall.Handle, infoClass uint32, info uintptr, infoLen uint32, returnLen *uint32) (ntStatus uint32) = ntdll.NtQueryInformationProcess

// NtQueryInformationProcess is a wrapper for ntdll.NtQueryInformationProcess.
// The handle must have the PROCESS_QUERY_INFORMATION access right.
// Returns an error of type NTStatus.
func NtQueryInformationProcess(handle syscall.Handle, infoClass ProcessInfoClass, info unsafe.Pointer, infoLen uint32) (returnedLen uint32, err error) {
status := _NtQueryInformationProcess(handle, uint32(infoClass), uintptr(info), infoLen, &returnedLen)
if status != 0 {
return returnedLen, NTStatus(status)
}
return returnedLen, nil
// Deprecated: use x/sys/windows
func NtQueryInformationProcess(handle syscall.Handle, infoClass ProcessInfoClass, info unsafe.Pointer, infoLen uint32) (uint32, error) {
var returnedLen uint32
err := windows.NtQueryInformationProcess(windows.Handle(handle), int32(infoClass), info, infoLen, &returnedLen)
return returnedLen, err
}

// Error prints the wrapped NTSTATUS in hex form.
Expand Down
5 changes: 3 additions & 2 deletions psapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import (
"fmt"
"syscall"
"unsafe"

"golang.org/x/sys/windows"
)

// Syscalls
//sys _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) = psapi.GetProcessMemoryInfo
//sys _GetProcessImageFileNameA(handle syscall.Handle, imageFileName *byte, nSize uint32) (len uint32, err error) = psapi.GetProcessImageFileNameA
//sys _EnumProcesses(lpidProcess *uint32, cb uint32, lpcbNeeded *uint32) (err error) = psapi.EnumProcesses

var (
sizeofProcessMemoryCountersEx = uint32(unsafe.Sizeof(ProcessMemoryCountersEx{}))
Expand Down Expand Up @@ -90,7 +91,7 @@ func GetProcessImageFileName(handle syscall.Handle) (string, error) {
func EnumProcesses() (pids []uint32, err error) {
for nAlloc, nGot := uint32(128), uint32(0); ; nAlloc *= 2 {
pids = make([]uint32, nAlloc)
if err = _EnumProcesses(&pids[0], nAlloc*4, &nGot); err != nil {
if err = windows.EnumProcesses(pids, &nGot); err != nil {
return nil, err
}
if nGot/4 < nAlloc {
Expand Down
48 changes: 16 additions & 32 deletions version.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ import (
"errors"
"fmt"
"unsafe"
)

// Syscalls
//sys _GetFileVersionInfo(filename string, reserved uint32, dataLen uint32, data *byte) (success bool, err error) [!success] = version.GetFileVersionInfoW
//sys _GetFileVersionInfoSize(filename string, handle uintptr) (size uint32, err error) = version.GetFileVersionInfoSizeW
//sys _VerQueryValueW(data *byte, subBlock string, pBuffer *uintptr, len *uint32) (success bool, err error) [!success] = version.VerQueryValueW
"golang.org/x/sys/windows"
)

// FixedFileInfo contains version information for a file. This information is
// language and code page independent. This is an equivalent representation of
Expand Down Expand Up @@ -83,25 +80,20 @@ func (d VersionData) QueryValue(key string) (string, error) {
CodePage uint16
}

var dataPtr uintptr
var size uint32
if _, err := _VerQueryValueW(&d[0], `\VarFileInfo\Translation`, &dataPtr, &size); err != nil || size == 0 {
var langCodePage *LangAndCodePage
langCodeLen := uint32(unsafe.Sizeof(*langCodePage))
if err := windows.VerQueryValue(unsafe.Pointer(&d[0]), `\VarFileInfo\Translation`, (unsafe.Pointer)(&langCodePage), &langCodeLen); err != nil || langCodeLen == 0 {
return "", fmt.Errorf("failed to get list of languages: %w", err)
}

offset := int(dataPtr - (uintptr)(unsafe.Pointer(&d[0])))
if offset <= 0 || offset > len(d)-1 {
return "", errors.New("invalid address")
}

l := *(*LangAndCodePage)(unsafe.Pointer(&d[offset]))

subBlock := fmt.Sprintf(`\StringFileInfo\%04x%04x\%v`, l.Language, l.CodePage, key)
if _, err := _VerQueryValueW(&d[0], subBlock, &dataPtr, &size); err != nil || size == 0 {
var dataPtr uintptr
var size uint32
subBlock := fmt.Sprintf(`\StringFileInfo\%04x%04x\%v`, langCodePage.Language, langCodePage.CodePage, key)
if err := windows.VerQueryValue(unsafe.Pointer(&d[0]), subBlock, (unsafe.Pointer)(&dataPtr), &size); err != nil || langCodeLen == 0 {
return "", fmt.Errorf("failed to query %v: %w", subBlock, err)
}

offset = int(dataPtr - (uintptr)(unsafe.Pointer(&d[0])))
offset := int(dataPtr - (uintptr)(unsafe.Pointer(&d[0])))
if offset <= 0 || offset > len(d)-1 {
return "", errors.New("invalid address")
}
Expand All @@ -123,33 +115,25 @@ func (d VersionData) FixedFileInfo() (*FixedFileInfo, error) {
return nil, errors.New("use GetFileVersionInfo to initialize VersionData")
}

var dataPtr uintptr
var size uint32
if _, err := _VerQueryValueW(&d[0], `\`, &dataPtr, &size); err != nil {
var fixedInfo *FixedFileInfo
fixedInfoLen := uint32(unsafe.Sizeof(*fixedInfo))
if err := windows.VerQueryValue(unsafe.Pointer(&d[0]), `\`, (unsafe.Pointer)(&fixedInfo), &fixedInfoLen); err != nil {
return nil, fmt.Errorf("VerQueryValue failed for \\: %w", err)
}

offset := int(dataPtr - (uintptr)(unsafe.Pointer(&d[0])))
if offset <= 0 || offset > len(d)-1 {
return nil, errors.New("invalid address")
}

// Make a copy of the struct.
ffi := *(*FixedFileInfo)(unsafe.Pointer(&d[offset]))

return &ffi, nil
return fixedInfo, nil
}

// GetFileVersionInfo retrieves version information for the specified file.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647003(v=vs.85).aspx
func GetFileVersionInfo(filename string) (VersionData, error) {
size, err := _GetFileVersionInfoSize(filename, 0)
size, err := windows.GetFileVersionInfoSize(filename, nil)
if err != nil {
return nil, fmt.Errorf("GetFileVersionInfoSize failed: %w", err)
}

data := make(VersionData, size)
_, err = _GetFileVersionInfo(filename, 0, uint32(len(data)), &data[0])
err = windows.GetFileVersionInfo(filename, 0, uint32(len(data)), unsafe.Pointer(&data[0]))
if err != nil {
return nil, fmt.Errorf("GetFileVersionInfo failed: %w", err)
}
Expand Down
100 changes: 8 additions & 92 deletions zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.