Example #1
0
func listLoadedLibraries(p process.Process) (libraries []string, harderror error, softerrors []error) {

	mapsFile, harderror := os.Open(common.MapsFilePathFromPid(p.Pid()))
	if harderror != nil {
		return
	}
	defer mapsFile.Close()

	scanner := bufio.NewScanner(mapsFile)
	processName, harderror, softerrors := p.Name()
	if harderror != nil {
		return
	}

	libs := make([]string, 0, 10)
	for scanner.Scan() {
		line := scanner.Text()
		items := common.SplitMapsFileEntry(line)

		if len(items) != 6 {
			return libs, fmt.Errorf("Unrecognised maps line: %s", line), softerrors
		}

		path := items[5]
		if path == processName {
			continue
		}

		if path == "/dev/zero" || path == "/dev/zero (deleted)" {
			continue
		}

		if path == "" {
			continue
		}

		if path[0] == '[' {
			continue
		}

		if inSlice(path, libs) {
			continue
		}

		libs = append(libs, path)
	}

	return libs, nil, nil
}
Example #2
0
func nextReadableMemoryRegion(p process.Process, address uintptr) (region MemoryRegion, harderror error,
	softerrors []error) {

	mapsFile, harderror := os.Open(common.MapsFilePathFromPid(p.Pid()))
	if harderror != nil {
		return
	}
	defer mapsFile.Close()

	region = MemoryRegion{}
	scanner := bufio.NewScanner(mapsFile)

	for scanner.Scan() {
		line := scanner.Text()
		items := common.SplitMapsFileEntry(line)

		if len(items) != 6 {
			return region, fmt.Errorf("Unrecognised maps line: %s", line), softerrors
		}

		start, end, err := common.ParseMapsFileMemoryLimits(items[0])
		if err != nil {
			return region, err, softerrors
		}

		if end <= address {
			continue
		}

		// Skip vsyscall as it can't be read. It's a special page mapped by the kernel to accelerate some syscalls.
		if items[5] == "[vsyscall]" {
			continue
		}

		// Check if memory is unreadable
		if items[1][0] == '-' {

			// If we were already reading a region this will just finish it. We only report the softerror when we
			// were actually trying to read it.
			if region.Address != 0 {
				return region, nil, softerrors
			}

			softerrors = append(softerrors, fmt.Errorf("Unreadable memory %s", items[0]))
			continue
		}

		size := uint(end - start)

		// Begenning of a region
		if region.Address == 0 {
			region = MemoryRegion{Address: start, Size: size}
			continue
		}

		// Continuation of a region
		if region.Address+uintptr(region.Size) == start {
			region.Size += size
			continue
		}

		// This map is outside the current region, so we are ready
		return region, nil, softerrors
	}

	// No region left
	if err := scanner.Err(); err != nil {
		return NoRegionAvailable, err, softerrors
	}

	// The last map was a valid region, so it was not closed by an invalid/non-contiguous one and we have to return it
	if region.Address > 0 {
		return region, harderror, softerrors
	}

	return NoRegionAvailable, nil, softerrors
}