Пример #1
0
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)
		}
	}
}
Пример #2
0
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
}
Пример #3
0
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)
		}
	}
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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(&params)),
		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
}
Пример #7
0
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
}
Пример #8
0
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
}
Пример #9
0
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
}
Пример #10
0
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
}
Пример #11
0
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
}
Пример #12
0
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
}
Пример #13
0
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
}
Пример #14
0
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
}