func GetProcessModules(pid uint32) ([]ModuleInfo, error) { hSnapshot, err := wrappers.CreateToolhelp32Snapshot(wrappers.TH32CS_SNAPMODULE, pid) if err != nil { return nil, NewWindowsError("CreateToolhelp32Snapshot", err) } defer wrappers.CloseHandle(hSnapshot) me := wrappers.MODULEENTRY32{} me.Size = uint32(unsafe.Sizeof(me)) if err := wrappers.Module32First(hSnapshot, &me); err != nil { return nil, NewWindowsError("Module32First", err) } mi := []ModuleInfo{} for { mi = append(mi, ModuleInfo{ ProcessID: uint(me.ProcessID), ModuleBaseAddress: me.ModBaseAddr, ModuleBaseSize: uint(me.ModBaseSize), ModuleHandle: me.Module, ModuleName: syscall.UTF16ToString((&me.ModuleName)[:]), ExePath: syscall.UTF16ToString((&me.ExePath)[:]), }) err := wrappers.Module32Next(hSnapshot, &me) if err == wrappers.ERROR_NO_MORE_FILES { return mi, nil } else if err != nil { return nil, NewWindowsError("Module32Next", err) } } }
func ReadFileContents(fileName string) (string, error) { file, err := wrappers.CreateFile( syscall.StringToUTF16Ptr(fileName), wrappers.GENERIC_READ, wrappers.FILE_SHARE_READ|wrappers.FILE_SHARE_WRITE|wrappers.FILE_SHARE_DELETE, nil, wrappers.OPEN_EXISTING, 0, 0) if err != nil { return "", NewWindowsError("CreateFile", err) } defer wrappers.CloseHandle(file) size, err := wrappers.GetFileSize(file, nil) if err != nil { return "", NewWindowsError("GetFileSize", err) } if size == 0 { return "", nil } buf := make([]byte, size) var bytesRead uint32 if err := wrappers.ReadFile(file, &buf[0], size, &bytesRead, nil); err != nil { return "", NewWindowsError("ReadFile", err) } return string(buf[0:bytesRead]), nil }
func GetProcesses() ([]ProcessInfo, error) { hSnapshot, err := wrappers.CreateToolhelp32Snapshot(wrappers.TH32CS_SNAPPROCESS, 0) if err != nil { return nil, NewWindowsError("CreateToolhelp32Snapshot", err) } defer wrappers.CloseHandle(hSnapshot) pe := wrappers.PROCESSENTRY32{} pe.Size = uint32(unsafe.Sizeof(pe)) if err := wrappers.Process32First(hSnapshot, &pe); err != nil { return nil, NewWindowsError("Process32First", err) } pi := []ProcessInfo{} for { pi = append(pi, ProcessInfo{ ProcessID: uint(pe.ProcessID), Threads: uint(pe.Threads), ParentProcessID: uint(pe.ParentProcessID), BasePriority: int(pe.PriClassBase), ExeFile: syscall.UTF16ToString((&pe.ExeFile)[:]), }) err := wrappers.Process32Next(hSnapshot, &pe) if err == wrappers.ERROR_NO_MORE_FILES { return pi, nil } else if err != nil { return nil, NewWindowsError("Process32Next", err) } } }
func (self *Job) Close() error { if self.handle != 0 { if err := wrappers.CloseHandle(self.handle); err != nil { return NewWindowsError("CloseHandle", err) } self.handle = 0 } return nil }
func (self *Job) ProcessInJob(pid uint) (bool, error) { hProcess, err := wrappers.OpenProcess(wrappers.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid)) if err != nil { return false, NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) var result bool if err := wrappers.IsProcessInJob(hProcess, self.handle, &result); err != nil { return false, NewWindowsError("IsProcessInJob", err) } return result, nil }
func GetProcessCommandLine(pid uint) (string, error) { hProcess, err := wrappers.OpenProcess( wrappers.PROCESS_QUERY_INFORMATION|wrappers.PROCESS_VM_READ, false, uint32(pid)) if err != nil { return "", NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) var basicInfo wrappers.PROCESS_BASIC_INFORMATION status := wrappers.NtQueryInformationProcess( hProcess, wrappers.ProcessBasicInformation, (*byte)(unsafe.Pointer(&basicInfo)), uint32(unsafe.Sizeof(basicInfo)), nil) if !wrappers.NT_SUCCESS(status) { return "", NewWindowsError("NtQueryInformationProcess", NTError(status)) } var peb wrappers.PEB err = wrappers.ReadProcessMemory( hProcess, basicInfo.PebBaseAddress, (*byte)(unsafe.Pointer(&peb)), uint32(unsafe.Sizeof(peb)), nil) if err != nil { return "", NewWindowsError("ReadProcessMemory", err) } var params wrappers.RTL_USER_PROCESS_PARAMETERS err = wrappers.ReadProcessMemory( hProcess, peb.ProcessParameters, (*byte)(unsafe.Pointer(¶ms)), uint32(unsafe.Sizeof(params)), nil) if err != nil { return "", NewWindowsError("ReadProcessMemory", err) } commandLine := make([]uint16, params.CommandLine.Length) err = wrappers.ReadProcessMemory( hProcess, params.CommandLine.Buffer, (*byte)(unsafe.Pointer(&commandLine[0])), uint32(params.CommandLine.Length), nil) if err != nil { return "", NewWindowsError("ReadProcessMemory", err) } return syscall.UTF16ToString(commandLine), nil }
func (self *Job) AssignProcess(pid uint) error { hProcess, err := wrappers.OpenProcess( wrappers.PROCESS_SET_QUOTA|wrappers.PROCESS_TERMINATE, false, uint32(pid)) if err != nil { return NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) if err := wrappers.AssignProcessToJobObject(self.handle, hProcess); err != nil { return NewWindowsError("AssignProcessToJobObject", err) } return nil }
func KillProcess(pid uint, exitCode uint) error { hProcess, err := wrappers.OpenProcess(wrappers.PROCESS_TERMINATE, false, uint32(pid)) if err == wrappers.ERROR_INVALID_PARAMETER { // the process terminated on its own return nil } else if err != nil { return NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) if err := wrappers.TerminateProcess(hProcess, uint32(exitCode)); err != nil { return NewWindowsError("TerminateProcess", err) } return nil }
func GetSymbolicLink(symlinkPath string) (*SymbolicLinkData, error) { file, err := wrappers.CreateFile( syscall.StringToUTF16Ptr(symlinkPath), wrappers.FILE_READ_EA, wrappers.FILE_SHARE_READ|wrappers.FILE_SHARE_WRITE|wrappers.FILE_SHARE_DELETE, nil, wrappers.OPEN_EXISTING, wrappers.FILE_FLAG_OPEN_REPARSE_POINT|wrappers.FILE_FLAG_BACKUP_SEMANTICS, 0) if err != nil { return nil, NewWindowsError("CreateFile", err) } defer wrappers.CloseHandle(file) buf := make([]byte, wrappers.MAXIMUM_REPARSE_DATA_BUFFER_SIZE) var bytesReturned uint32 err = wrappers.DeviceIoControl( file, wrappers.FSCTL_GET_REPARSE_POINT, nil, 0, &buf[0], wrappers.MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, nil) if err != nil { return nil, NewWindowsError("DeviceIoControl", err) } data := (*wrappers.REPARSE_DATA_BUFFER)(unsafe.Pointer(&buf[0])) if data.ReparseTag != wrappers.IO_REPARSE_TAG_SYMLINK { return nil, nil } substituteNameBuf := make([]uint16, data.SubstituteNameLength/2) printNameBuf := make([]uint16, data.PrintNameLength/2) wrappers.RtlMoveMemory( (*byte)(unsafe.Pointer(&substituteNameBuf[0])), &buf[unsafe.Sizeof(*data)+uintptr(data.SubstituteNameOffset)], uintptr(data.SubstituteNameLength)) wrappers.RtlMoveMemory( (*byte)(unsafe.Pointer(&printNameBuf[0])), &buf[unsafe.Sizeof(*data)+uintptr(data.PrintNameOffset)], uintptr(data.PrintNameLength)) return &SymbolicLinkData{ SubstituteName: syscall.UTF16ToString(substituteNameBuf), PrintName: syscall.UTF16ToString(printNameBuf), Relative: (data.Flags & wrappers.SYMLINK_FLAG_RELATIVE) != 0, }, nil }
func IsProcessRunning(pid uint) (bool, error) { hProcess, err := wrappers.OpenProcess(wrappers.SYNCHRONIZE, false, uint32(pid)) if err == wrappers.ERROR_INVALID_PARAMETER { // the process no longer exists return false, nil } else if err != nil { return false, NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) // wait with a timeout of 0 to check the process's status and make sure it's not a zombie event, err := wrappers.WaitForSingleObject(hProcess, 0) if err != nil { return false, NewWindowsError("WaitForSingleObject", err) } return event != wrappers.WAIT_OBJECT_0, nil }
func GetProcessTimeCounters(pid uint) (*ProcessTimeCounters, error) { hProcess, err := wrappers.OpenProcess(wrappers.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid)) if err != nil { return nil, NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) var creationTime, exitTime, kernelTime, userTime wrappers.FILETIME err = wrappers.GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime) if err != nil { return nil, NewWindowsError("GetProcessTimes", err) } return &ProcessTimeCounters{ Creation: fileTimeToUint64(creationTime), Exit: fileTimeToUint64(exitTime), Kernel: fileTimeToUint64(kernelTime), User: fileTimeToUint64(userTime), }, nil }
func GetDiskPerformanceInfo(rootPathName string) (*DiskPerformanceInfo, error) { hFile, err := wrappers.CreateFile( syscall.StringToUTF16Ptr(rootPathName), 0, wrappers.FILE_SHARE_READ|wrappers.FILE_SHARE_WRITE, nil, wrappers.OPEN_EXISTING, 0, 0) if err != nil { return nil, NewWindowsError("CreateFile", err) } defer wrappers.CloseHandle(hFile) var diskPerformance wrappers.DISK_PERFORMANCE var diskPerformanceSize uint32 err = wrappers.DeviceIoControl( hFile, wrappers.IOCTL_DISK_PERFORMANCE, nil, 0, (*byte)(unsafe.Pointer(&diskPerformance)), uint32(unsafe.Sizeof(diskPerformance)), &diskPerformanceSize, nil) if err != nil { return nil, NewWindowsError("DeviceIoControl", err) } return &DiskPerformanceInfo{ BytesRead: diskPerformance.BytesRead, BytesWritten: diskPerformance.BytesWritten, ReadTime: diskPerformance.ReadTime, WriteTime: diskPerformance.WriteTime, IdleTime: diskPerformance.IdleTime, ReadCount: uint(diskPerformance.ReadCount), WriteCount: uint(diskPerformance.WriteCount), QueueDepth: uint(diskPerformance.QueueDepth), SplitCount: uint(diskPerformance.SplitCount), QueryTime: diskPerformance.QueryTime, StorageDeviceNumber: uint(diskPerformance.StorageDeviceNumber), StorageManagerName: syscall.UTF16ToString(diskPerformance.StorageManagerName[:]), }, nil }
func GetProcessFullPathName(pid uint, flags ProcessNameFlags) (string, error) { hProcess, err := wrappers.OpenProcess(wrappers.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid)) if err != nil { return "", NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) buf := make([]uint16, wrappers.MAX_PATH) size := uint32(wrappers.MAX_PATH) if err := wrappers.QueryFullProcessImageName(hProcess, uint32(flags), &buf[0], &size); err != nil { if err == wrappers.ERROR_INSUFFICIENT_BUFFER { buf = make([]uint16, syscall.MAX_LONG_PATH) size = syscall.MAX_LONG_PATH if err := wrappers.QueryFullProcessImageName(hProcess, uint32(flags), &buf[0], &size); err != nil { return "", NewWindowsError("QueryFullProcessImageName", err) } } else { return "", NewWindowsError("QueryFullProcessImageName", err) } } return syscall.UTF16ToString(buf[0:size]), nil }
func SignalProcessAndWait(pid uint, timeout time.Duration) error { milliseconds := uint32(timeout / time.Millisecond) if timeout < 0 { milliseconds = wrappers.INFINITE } hProcess, err := wrappers.OpenProcess(wrappers.SYNCHRONIZE, false, uint32(pid)) if err == wrappers.ERROR_INVALID_PARAMETER { // the process terminated on its own return nil } else if err != nil { return NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) if err := wrappers.GenerateConsoleCtrlEvent(wrappers.CTRL_BREAK_EVENT, uint32(pid)); err == wrappers.ERROR_INVALID_PARAMETER { // the process terminated on its own return nil } else if err != nil { return NewWindowsError("GenerateConsoleCtrlEvent", err) } if _, err := wrappers.WaitForSingleObject(hProcess, milliseconds); err != nil { return NewWindowsError("WaitForSingleObject", err) } return nil }