github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/system/process/process_windows_arm64.go (about)

     1  //go:build windows && arm64
     2  
     3  package process
     4  
     5  import (
     6  	"errors"
     7  	"github.com/isyscore/isc-gobase/system/common"
     8  	"syscall"
     9  	"unsafe"
    10  )
    11  
    12  type PROCESS_MEMORY_COUNTERS struct {
    13  	CB                         uint32
    14  	PageFaultCount             uint32
    15  	PeakWorkingSetSize         uint32
    16  	WorkingSetSize             uint32
    17  	QuotaPeakPagedPoolUsage    uint32
    18  	QuotaPagedPoolUsage        uint32
    19  	QuotaPeakNonPagedPoolUsage uint32
    20  	QuotaNonPagedPoolUsage     uint32
    21  	PagefileUsage              uint32
    22  	PeakPagefileUsage          uint32
    23  }
    24  
    25  func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) {
    26  	if is32BitProcess {
    27  		//we are on a 32-bit process reading an external 32-bit process
    28  		var info processBasicInformation32
    29  
    30  		ret, _, _ := common.ProcNtQueryInformationProcess.Call(
    31  			uintptr(procHandle),
    32  			uintptr(common.ProcessBasicInformation),
    33  			uintptr(unsafe.Pointer(&info)),
    34  			uintptr(unsafe.Sizeof(info)),
    35  			uintptr(0),
    36  		)
    37  		if int(ret) >= 0 {
    38  			return uint64(info.PebBaseAddress), nil
    39  		}
    40  	} else {
    41  		//we are on a 32-bit process reading an external 64-bit process
    42  		if common.ProcNtWow64QueryInformationProcess64.Find() == nil { //avoid panic
    43  			var info processBasicInformation64
    44  
    45  			ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call(
    46  				uintptr(procHandle),
    47  				uintptr(common.ProcessBasicInformation),
    48  				uintptr(unsafe.Pointer(&info)),
    49  				uintptr(unsafe.Sizeof(info)),
    50  				uintptr(0),
    51  			)
    52  			if int(ret) >= 0 {
    53  				return info.PebBaseAddress, nil
    54  			}
    55  		}
    56  	}
    57  
    58  	//return 0 on error
    59  	return 0, errors.New("could not query PEB address")
    60  }
    61  
    62  func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, size uint) []byte {
    63  	if is32BitProcess {
    64  		var read uint
    65  
    66  		buffer := make([]byte, size)
    67  
    68  		ret, _, _ := common.ProcNtReadVirtualMemory.Call(
    69  			uintptr(h),
    70  			uintptr(address),
    71  			uintptr(unsafe.Pointer(&buffer[0])),
    72  			uintptr(size),
    73  			uintptr(unsafe.Pointer(&read)),
    74  		)
    75  		if int(ret) >= 0 && read > 0 {
    76  			return buffer[:read]
    77  		}
    78  	} else {
    79  		//reading a 64-bit process from a 32-bit one
    80  		if common.ProcNtWow64ReadVirtualMemory64.Find() == nil { //avoid panic
    81  			var read uint64
    82  
    83  			buffer := make([]byte, size)
    84  
    85  			ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call(
    86  				uintptr(h),
    87  				uintptr(address&0xFFFFFFFF), //the call expects a 64-bit value
    88  				uintptr(address>>32),
    89  				uintptr(unsafe.Pointer(&buffer[0])),
    90  				uintptr(size), //the call expects a 64-bit value
    91  				uintptr(0),    //but size is 32-bit so pass zero as the high dword
    92  				uintptr(unsafe.Pointer(&read)),
    93  			)
    94  			if int(ret) >= 0 && read > 0 {
    95  				return buffer[:uint(read)]
    96  			}
    97  		}
    98  	}
    99  
   100  	//if we reach here, an error happened
   101  	return nil
   102  }