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") procQueryFullProcessImageNameW = common.Modkernel32.NewProc("QueryFullProcessImageNameW")
procGetPriorityClass = common.Modkernel32.NewProc("GetPriorityClass") procGetPriorityClass = common.Modkernel32.NewProc("GetPriorityClass")
procGetProcessIoCounters = common.Modkernel32.NewProc("GetProcessIoCounters") procGetProcessIoCounters = common.Modkernel32.NewProc("GetProcessIoCounters")
procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo")
processorArchitecture uint
) )
type SystemProcessInformation struct { type SystemProcessInformation struct {
@ -46,7 +49,7 @@ type SystemProcessInformation struct {
Reserved6 [6]uint64 Reserved6 [6]uint64
} }
type SystemProcessorInformation struct { type systemProcessorInformation struct {
ProcessorArchitecture uint16 ProcessorArchitecture uint16
ProcessorLevel uint16 ProcessorLevel uint16
ProcessorRevision uint16 ProcessorRevision uint16
@ -54,6 +57,20 @@ type SystemProcessorInformation struct {
ProcessorFeatureBits uint16 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 // Memory_info_ex is different between OSes
type MemoryInfoExStat struct { type MemoryInfoExStat struct {
} }
@ -72,7 +89,7 @@ type ioCounters struct {
OtherTransferCount uint64 OtherTransferCount uint64
} }
type PROCESS_BASIC_INFORMATION32 struct { type processBasicInformation32 struct {
Reserved1 uint32 Reserved1 uint32
PebBaseAddress uint32 PebBaseAddress uint32
Reserved2 uint32 Reserved2 uint32
@ -81,7 +98,7 @@ type PROCESS_BASIC_INFORMATION32 struct {
Reserved4 uint32 Reserved4 uint32
} }
type PROCESS_BASIC_INFORMATION64 struct { type processBasicInformation64 struct {
Reserved1 uint64 Reserved1 uint64
PebBaseAddress uint64 PebBaseAddress uint64
Reserved2 uint64 Reserved2 uint64
@ -111,6 +128,11 @@ type winLong int32
type winDWord uint32 type winDWord uint32
func init() { 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 // enable SeDebugPrivilege https://github.com/midstar/proci/blob/6ec79f57b90ba3d9efa2a7b16ef9c9369d4be875/proci_windows.go#L80-L119
handle, err := syscall.GetCurrentProcess() handle, err := syscall.GetCurrentProcess()
if err != nil { if err != nil {
@ -272,8 +294,8 @@ func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background()) return p.CmdlineWithContext(context.Background())
} }
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { func (p *Process) CmdlineWithContext(_ context.Context) (string, error) {
cmdline, err := getProcessCommandLine(ctx, p.Pid) cmdline, err := getProcessCommandLine(p.Pid)
if err != nil { if err != nil {
return "", fmt.Errorf("could not get CommandLine: %s", err) return "", fmt.Errorf("could not get CommandLine: %s", err)
} }
@ -830,7 +852,7 @@ func is32BitProcess(procHandle syscall.Handle) bool {
return false 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)) 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 { if err == windows.ERROR_ACCESS_DENIED || err == windows.ERROR_INVALID_PARAMETER {
return "", nil return "", nil
@ -840,14 +862,41 @@ func getProcessCommandLine(_ context.Context, pid int32) (string, error) {
} }
defer syscall.CloseHandle(syscall.Handle(h)) 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) pebAddress := queryPebAddress(syscall.Handle(h), procIs32Bits)
if pebAddress == 0 { if pebAddress == 0 {
return "", errors.New("cannot locate process PEB") return "", errors.New("cannot locate process PEB")
} }
if is32BitProcess(syscall.Handle(h)) { if procIs32Bits {
buf := readProcessMemory(syscall.Handle(h), procIs32Bits, pebAddress + uint64(16), 4) buf := readProcessMemory(syscall.Handle(h), procIs32Bits, pebAddress + uint64(16), 4)
if len(buf) != 4 { if len(buf) != 4 {
return "", errors.New("cannot locate process user parameters") return "", errors.New("cannot locate process user parameters")

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

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

Loading…
Cancel
Save