...
1
2
3 package process
4
5 import (
6 "errors"
7 "syscall"
8 "unsafe"
9
10 "github.com/shirou/gopsutil/internal/common"
11 "golang.org/x/sys/windows"
12 )
13
14 type PROCESS_MEMORY_COUNTERS struct {
15 CB uint32
16 PageFaultCount uint32
17 PeakWorkingSetSize uint32
18 WorkingSetSize uint32
19 QuotaPeakPagedPoolUsage uint32
20 QuotaPagedPoolUsage uint32
21 QuotaPeakNonPagedPoolUsage uint32
22 QuotaNonPagedPoolUsage uint32
23 PagefileUsage uint32
24 PeakPagefileUsage uint32
25 }
26
27 func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) {
28 if is32BitProcess {
29
30 var info processBasicInformation32
31
32 ret, _, _ := common.ProcNtQueryInformationProcess.Call(
33 uintptr(procHandle),
34 uintptr(common.ProcessBasicInformation),
35 uintptr(unsafe.Pointer(&info)),
36 uintptr(unsafe.Sizeof(info)),
37 uintptr(0),
38 )
39 if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS {
40 return uint64(info.PebBaseAddress), nil
41 } else {
42 return 0, windows.NTStatus(ret)
43 }
44 } else {
45
46 if common.ProcNtWow64QueryInformationProcess64.Find() == nil {
47 var info processBasicInformation64
48
49 ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call(
50 uintptr(procHandle),
51 uintptr(common.ProcessBasicInformation),
52 uintptr(unsafe.Pointer(&info)),
53 uintptr(unsafe.Sizeof(info)),
54 uintptr(0),
55 )
56 if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS {
57 return info.PebBaseAddress, nil
58 } else {
59 return 0, windows.NTStatus(ret)
60 }
61 } else {
62 return 0, errors.New("can't find API to query 64 bit process from 32 bit")
63 }
64 }
65 }
66
67 func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, size uint) []byte {
68 if is32BitProcess {
69 var read uint
70
71 buffer := make([]byte, size)
72
73 ret, _, _ := common.ProcNtReadVirtualMemory.Call(
74 uintptr(h),
75 uintptr(address),
76 uintptr(unsafe.Pointer(&buffer[0])),
77 uintptr(size),
78 uintptr(unsafe.Pointer(&read)),
79 )
80 if int(ret) >= 0 && read > 0 {
81 return buffer[:read]
82 }
83 } else {
84
85 if common.ProcNtWow64ReadVirtualMemory64.Find() == nil {
86 var read uint64
87
88 buffer := make([]byte, size)
89
90 ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call(
91 uintptr(h),
92 uintptr(address & 0xFFFFFFFF),
93 uintptr(address >> 32),
94 uintptr(unsafe.Pointer(&buffer[0])),
95 uintptr(size),
96 uintptr(0),
97 uintptr(unsafe.Pointer(&read)),
98 )
99 if int(ret) >= 0 && read > 0 {
100 return buffer[:uint(read)]
101 }
102 }
103 }
104
105
106 return nil
107 }
108
View as plain text