Added retrieval of OS platform to determine better a process platform.

pull/862/head
Mauro Leggieri 5 years ago
parent 00957cfedc
commit 7783e1d58e

@ -29,6 +29,9 @@ var (
procQueryFullProcessImageNameW = common.Modkernel32.NewProc("QueryFullProcessImageNameW")
procGetPriorityClass = common.Modkernel32.NewProc("GetPriorityClass")
procGetProcessIoCounters = common.Modkernel32.NewProc("GetProcessIoCounters")
procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo")
processorArchitecture uint
)
type SystemProcessInformation struct {
@ -46,7 +49,7 @@ type SystemProcessInformation struct {
Reserved6 [6]uint64
}
type SystemProcessorInformation struct {
type systemProcessorInformation struct {
ProcessorArchitecture uint16
ProcessorLevel uint16
ProcessorRevision uint16
@ -54,6 +57,20 @@ type SystemProcessorInformation struct {
ProcessorFeatureBits uint16
}
type systemInfo struct {
wProcessorArchitecture uint16
wReserved uint16
dwPageSize uint32
lpMinimumApplicationAddress uintptr
lpMaximumApplicationAddress uintptr
dwActiveProcessorMask uintptr
dwNumberOfProcessors uint32
dwProcessorType uint32
dwAllocationGranularity uint32
wProcessorLevel uint16
wProcessorRevision uint16
}
// Memory_info_ex is different between OSes
type MemoryInfoExStat struct {
}
@ -72,7 +89,7 @@ type ioCounters struct {
OtherTransferCount uint64
}
type PROCESS_BASIC_INFORMATION32 struct {
type processBasicInformation32 struct {
Reserved1 uint32
PebBaseAddress uint32
Reserved2 uint32
@ -81,7 +98,7 @@ type PROCESS_BASIC_INFORMATION32 struct {
Reserved4 uint32
}
type PROCESS_BASIC_INFORMATION64 struct {
type processBasicInformation64 struct {
Reserved1 uint64
PebBaseAddress uint64
Reserved2 uint64
@ -111,6 +128,11 @@ type winLong int32
type winDWord uint32
func init() {
var systemInfo systemInfo
procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo)))
processorArchitecture = uint(systemInfo.wProcessorArchitecture)
// enable SeDebugPrivilege https://github.com/midstar/proci/blob/6ec79f57b90ba3d9efa2a7b16ef9c9369d4be875/proci_windows.go#L80-L119
handle, err := syscall.GetCurrentProcess()
if err != nil {
@ -272,8 +294,8 @@ func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
cmdline, err := getProcessCommandLine(ctx, p.Pid)
func (p *Process) CmdlineWithContext(_ context.Context) (string, error) {
cmdline, err := getProcessCommandLine(p.Pid)
if err != nil {
return "", fmt.Errorf("could not get CommandLine: %s", err)
}
@ -830,7 +852,7 @@ func is32BitProcess(procHandle syscall.Handle) bool {
return false
}
func getProcessCommandLine(_ context.Context, pid int32) (string, error) {
func getProcessCommandLine(pid int32) (string, error) {
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION | windows.PROCESS_VM_READ, false, uint32(pid))
if err == windows.ERROR_ACCESS_DENIED || err == windows.ERROR_INVALID_PARAMETER {
return "", nil
@ -840,14 +862,41 @@ func getProcessCommandLine(_ context.Context, pid int32) (string, error) {
}
defer syscall.CloseHandle(syscall.Handle(h))
procIs32Bits := is32BitProcess(syscall.Handle(h))
const (
PROCESSOR_ARCHITECTURE_INTEL = 0
PROCESSOR_ARCHITECTURE_ARM = 5
PROCESSOR_ARCHITECTURE_ARM64 = 12
PROCESSOR_ARCHITECTURE_IA64 = 6
PROCESSOR_ARCHITECTURE_AMD64 = 9
)
procIs32Bits := true
switch processorArchitecture {
case PROCESSOR_ARCHITECTURE_INTEL:
fallthrough
case PROCESSOR_ARCHITECTURE_ARM:
procIs32Bits = true
case PROCESSOR_ARCHITECTURE_ARM64:
fallthrough
case PROCESSOR_ARCHITECTURE_IA64:
fallthrough
case PROCESSOR_ARCHITECTURE_AMD64:
procIs32Bits = is32BitProcess(syscall.Handle(h))
default:
//for other unknown platforms, we rely on process platform
if unsafe.Sizeof(processorArchitecture) == 8 {
procIs32Bits = false
}
}
pebAddress := queryPebAddress(syscall.Handle(h), procIs32Bits)
if pebAddress == 0 {
return "", errors.New("cannot locate process PEB")
}
if is32BitProcess(syscall.Handle(h)) {
if procIs32Bits {
buf := readProcessMemory(syscall.Handle(h), procIs32Bits, pebAddress + uint64(16), 4)
if len(buf) != 4 {
return "", errors.New("cannot locate process user parameters")

@ -3,9 +3,10 @@
package process
import (
"github.com/shirou/gopsutil/internal/common"
"syscall"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
)
type PROCESS_MEMORY_COUNTERS struct {
@ -24,7 +25,7 @@ type PROCESS_MEMORY_COUNTERS struct {
func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) uint64 {
if is32BitProcess {
//we are on a 32-bit process reading an external 32-bit process
var info PROCESS_BASIC_INFORMATION32
var info processBasicInformation32
ret, _, _ := common.ProcNtQueryInformationProcess.Call(
uintptr(procHandle),
@ -39,7 +40,7 @@ func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) uint64 {
} else {
//we are on a 32-bit process reading an external 64-bit process
if common.ProcNtWow64QueryInformationProcess64.Find() == nil { //avoid panic
var info PROCESS_BASIC_INFORMATION64
var info processBasicInformation64
ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call(
uintptr(procHandle),

@ -3,9 +3,10 @@
package process
import (
"github.com/shirou/gopsutil/internal/common"
"syscall"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
)
type PROCESS_MEMORY_COUNTERS struct {
@ -38,7 +39,7 @@ func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) uint64 {
}
} else {
//we are on a 64-bit process reading an external 64-bit process
var info PROCESS_BASIC_INFORMATION64
var info processBasicInformation64
ret, _, _ := common.ProcNtQueryInformationProcess.Call(
uintptr(procHandle),

Loading…
Cancel
Save