Esempio n. 1
0
func TestWalkMemoryDoesntOverlapTheBuffer(t *testing.T) {
	cmd, err := test.LaunchTestCaseAndWaitForInitialization()
	if err != nil {
		t.Fatal(err)
	}
	defer cmd.Process.Kill()

	pid := uint(cmd.Process.Pid)
	proc, err, softerrors := process.OpenFromPid(pid)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	pageSize := uint(os.Getpagesize())
	bufferSizes := []uint{1024, pageSize, pageSize + 100, pageSize * 2, pageSize*2 + 123}
	for _, size := range bufferSizes {

		lastRegion := MemoryRegion{}
		err, softerrors = WalkMemory(proc, 0, size, func(address uintptr, buffer []byte) (keepSearching bool) {
			currentRegion := MemoryRegion{Address: address, Size: uint(len(buffer))}
			if memoryRegionsOverlap(lastRegion, currentRegion) {
				t.Errorf("Regions overlap while reading %d at a time: %v %v", size, lastRegion, currentRegion)
				return false
			}

			lastRegion = currentRegion
			return true
		})
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		}
	}
}
Esempio n. 2
0
func TestSearchInOtherProcess(t *testing.T) {
	cmd, err := test.LaunchTestCaseAndWaitForInitialization()
	if err != nil {
		t.Fatal(err)
	}
	defer cmd.Process.Kill()

	pid := uint(cmd.Process.Pid)
	proc, err, softerrors := process.OpenFromPid(pid)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}
	defer proc.Close()

	for i, buf := range buffersToFind {
		found, _, err, softerrors := FindBytesSequence(proc, 0, buf)
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		} else if !found {
			t.Fatalf("memoryGrep failed for case %d, the following buffer should be found: %+v", i, buf)
		}
	}

	// This must not be present
	found, _, err, softerrors := FindBytesSequence(proc, 0, notPresent)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	} else if found {
		t.Fatalf("memoryGrep failed, it found a sequense of bytes that it shouldn't")
	}
}
Esempio n. 3
0
func main() {
	flag.Parse()

	proc, harderror, softerrors := process.OpenFromPid(uint(*pid))
	logErrors(harderror, softerrors)

	switch *action {

	case "<nil>":
		log.Fatal("Missing action flag.")
	case "file-search":
		data, err := ioutil.ReadFile(*fileneedle)
		if err != nil {
			log.Fatal(err)
		}
		encoded := strings.Replace(strings.Replace(strings.TrimSpace(string(data)), " ", "", -1), "\n", "", -1)
		data, err = hex.DecodeString(encoded)
		if err != nil {
			log.Fatal(err)
		}
		found, address, harderror, softerrors := memsearch.FindBytesSequence(proc, uintptr(*addr), data)
		logErrors(harderror, softerrors)
		if found {
			log.Printf("Found in address: %x\n", address)
		}

	case "search":
		found, address, harderror, softerrors := memsearch.FindBytesSequence(proc, uintptr(*addr), []byte(*needle))
		logErrors(harderror, softerrors)
		if found {
			log.Printf("Found in address: %x\n", address)
		}

	case "regexp-search":
		r, err := regexp.Compile(*regexpString)
		if err != nil {
			log.Fatal(err)
		}

		found, address, harderror, softerrors := memsearch.FindRegexpMatch(proc, uintptr(*addr), r)
		logErrors(harderror, softerrors)
		if found {
			log.Printf("Found in address: %x\n", address)
		}

	case "print":
		buf := make([]byte, *size)
		harderror, softerrors = memaccess.CopyMemory(proc, uintptr(*addr), buf)
		logErrors(harderror, softerrors)
		log.Println(string(buf))

	default:
		log.Fatal("Unrecognized action ", *action)
	}
}
Esempio n. 4
0
func TestRegexpSearchInOtherProcess(t *testing.T) {
	cmd, err := test.LaunchTestCaseAndWaitForInitialization()
	if err != nil {
		t.Fatal(err)
	}
	defer cmd.Process.Kill()

	pid := uint(cmd.Process.Pid)
	proc, err, softerrors := process.OpenFromPid(pid)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}
	defer proc.Close()

	for i, str := range regexpToMatch {
		r, err := regexp.Compile(str)
		if err != nil {
			t.Fatal(err)
		}

		found, _, err, softerrors := FindRegexpMatch(proc, 0, r)
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		} else if !found {
			t.Fatalf("memoryGrep failed for case %d, the following regexp should be found: %s", i, str)
		}
	}

	// These must not match
	for i, str := range regexpToNotMatch {
		r, err := regexp.Compile(str)
		if err != nil {
			t.Fatal(err)
		}

		found, _, err, softerrors := FindRegexpMatch(proc, 0, r)
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		} else if found {
			t.Fatalf("memoryGrep failed for case %d, the following regexp shouldnt be found: %s", i, str)
		}
	}
}
Esempio n. 5
0
func TestManuallyWalk(t *testing.T) {
	cmd, err := test.LaunchTestCase()
	if err != nil {
		t.Fatal(err)
	}
	defer cmd.Process.Kill()

	pid := uint(cmd.Process.Pid)
	proc, err, softerrors := process.OpenFromPid(pid)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	var region MemoryRegion
	region, err, softerrors = NextReadableMemoryRegion(proc, 0)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	if region == NoRegionAvailable {
		t.Error("No starting region returned")
	}

	previousRegion := region
	for region != NoRegionAvailable {
		region, err, softerrors = NextReadableMemoryRegion(proc, region.Address+uintptr(region.Size))
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		}

		if region != NoRegionAvailable && region.Address < previousRegion.Address+uintptr(previousRegion.Size) {
			t.Error("Returned region is not after the previous one.")
		}

		previousRegion = region
	}
}
Esempio n. 6
0
func (r Runner) Run(in io.Reader) (out string) {
	var ts statistics
	stats = ts
	// in debug mode, we just panic
	if !debug {
		defer func() {
			if e := recover(); e != nil {
				// return error in json
				res := newResults()
				res.Statistics = stats
				res.Errors = append(res.Errors, fmt.Sprintf("%v", e))
				res.Success = false
				err, _ := json.Marshal(res)
				out = string(err[:])
				return
			}
		}()
	}
	t0 := time.Now()
	err := modules.ReadInputParameters(in, &r.Parameters)
	if err != nil {
		panic(err)
	}
	err = r.ValidateParameters()
	if err != nil {
		panic(err)
	}
	// create the checks based on the search parameters
	for label, search := range r.Parameters.Searches {
		if debug {
			fmt.Println("making checks for label", label)
		}
		err := search.makeChecks()
		if err != nil {
			panic(err)
		}
		r.Parameters.Searches[label] = search
	}
	// evaluate each process one by one
	pids, err, serr := process.GetAllPids()
	if err != nil {
		panic(err)
	}
	if debug {
		fmt.Println("found", len(pids), "processes to evaluate")
	}
	for _, err = range serr {
		stats.Failures = append(stats.Failures, err.Error())
	}
	for _, pid := range pids {
		// activate all searches
		for label, search := range r.Parameters.Searches {
			search.activate()
			r.Parameters.Searches[label] = search
		}
		proc, err, serr := process.OpenFromPid(pid)
		if err != nil {
			// if we encounter a hard failure, skip this process
			stats.Failures = append(stats.Failures, err.Error())
			continue
		}
		for _, err = range serr {
			// soft failures are just logged but we continue inspection
			stats.Failures = append(stats.Failures, err.Error())
		}
		err = r.evaluateProcess(proc)
		if err != nil {
			stats.Failures = append(stats.Failures, err.Error())
		}
		stats.ProcessCount++
	}

	out, err = r.buildResults(t0)
	if err != nil {
		panic(err)
	}

	if debug {
		fmt.Println("---- results ----")
		var tmpres modules.Result
		err = json.Unmarshal([]byte(out), &tmpres)
		printedResults, err := r.PrintResults(tmpres, false)
		if err != nil {
			panic(err)
		}
		for _, res := range printedResults {
			fmt.Println(res)
		}
	}
	return
}
Esempio n. 7
0
func TestCopyMemory(t *testing.T) {
	cmd, err := test.LaunchTestCaseAndWaitForInitialization()
	if err != nil {
		t.Fatal(err)
	}
	defer cmd.Process.Kill()

	pid := uint(cmd.Process.Pid)
	proc, err, softerrors := process.OpenFromPid(pid)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	var region MemoryRegion
	region, err, softerrors = NextReadableMemoryRegion(proc, 0)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	if region == NoRegionAvailable {
		t.Error("No starting region returned")
	}

	min_region_size := uint(os.Getpagesize() + 100) // one page plus something

	for region.Size < min_region_size {
		if region == NoRegionAvailable {
			t.Fatal("We couldn't find a region of %d bytes", min_region_size)
		}

		region, err, softerrors = NextReadableMemoryRegion(proc, region.Address+uintptr(region.Size))
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		}
	}

	buffers := [][]byte{
		make([]byte, 2),
		make([]byte, os.Getpagesize()),
		make([]byte, min_region_size),
	}

	for _, buffer := range buffers {
		// Valid read
		err, softerrors = CopyMemory(proc, region.Address, buffer)
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Error(fmt.Sprintf("Couldn't read %d bytes from region", len(buffer)))
		}

		// Crossing boundaries
		err, softerrors = CopyMemory(proc, region.Address+uintptr(region.Size)-uintptr(len(buffer)/2), buffer)
		test.PrintSoftErrors(softerrors)
		if err == nil {
			t.Error(fmt.Sprintf("Read %d bytes inbetween regions", len(buffer)))
		}

		// Entirely outside region
		err, softerrors = CopyMemory(proc, region.Address+uintptr(region.Size), buffer)
		test.PrintSoftErrors(softerrors)
		if err == nil {
			t.Error(fmt.Sprintf("Read %d bytes after the region", len(buffer)))
		}
	}

}
Esempio n. 8
0
func TestSlidingWalkMemory(t *testing.T) {
	cmd, err := test.LaunchTestCaseAndWaitForInitialization()
	if err != nil {
		t.Fatal(err)
	}
	defer cmd.Process.Kill()

	pid := uint(cmd.Process.Pid)
	proc, err, softerrors := process.OpenFromPid(pid)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	pageSize := uint(os.Getpagesize())
	bufferSizes := []uint{1024, pageSize, pageSize + 100, pageSize * 2, pageSize*2 + 124}
	for _, size := range bufferSizes {
		lastRegion := MemoryRegion{}
		err, softerrors = SlidingWalkMemory(proc, 0, size, func(address uintptr, buffer []byte) (keepSearching bool) {
			currentRegion := MemoryRegion{Address: address, Size: uint(len(buffer))}

			if lastRegion.Address == 0 {
				lastRegion = currentRegion
				return true
			}

			lastRegionLimit := lastRegion.Address + uintptr(lastRegion.Size)
			overlappedBytes := uintptr(0)
			regionIsContigous := false

			if lastRegionLimit > currentRegion.Address {
				overlappedBytes = lastRegionLimit - currentRegion.Address
			} else if lastRegionLimit == currentRegion.Address {
				regionIsContigous = true
			}

			if regionIsContigous {
				if regionIsContigous {
					t.Error(fmt.Sprintf("Contigous buffer while we are expecting overlapped ones."+
						"buffer size %d - lastRegion %v - currentRegion %v", size, lastRegion, currentRegion))
				}
				return false
			}

			// If the last buffer wasn't read complete the current one can't be overlapped
			if lastRegion.Size != size && overlappedBytes > 0 {
				t.Error(fmt.Sprintf("Overlapped buffer after non-complete one. "+
					"buffer size %d - lastRegion %v - currentRegion %v", size, lastRegion, currentRegion))
				return false
			}

			// Overlapped bytes should be half of the buffer, or the buffer must came from another region
			if overlappedBytes != uintptr(size/2) && overlappedBytes != 0 {
				t.Error(fmt.Sprintf("Overlapping buffer by %d bytes. "+
					"buffer size %d - lastRegion %v - currentRegion %v", overlappedBytes, size, lastRegion,
					currentRegion))
				return false
			}

			lastRegion = currentRegion
			return true
		})
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		}
	}
}
Esempio n. 9
0
func TestWalkRegionReadsEntireRegion(t *testing.T) {
	cmd, err := test.LaunchTestCaseAndWaitForInitialization()
	if err != nil {
		t.Fatal(err)
	}
	defer cmd.Process.Kill()

	pid := uint(cmd.Process.Pid)
	proc, err, softerrors := process.OpenFromPid(pid)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	pageSize := uint(os.Getpagesize())
	bufferSizes := []uint{1024, pageSize, pageSize + 100, pageSize * 2, pageSize*2 + 123}

	var region MemoryRegion
	region, err, softerrors = NextReadableMemoryRegion(proc, 0)
	test.PrintSoftErrors(softerrors)
	if err != nil {
		t.Fatal(err)
	}

	if region == NoRegionAvailable {
		t.Error("No starting region returned")
	}

	min_region_size := bufferSizes[len(bufferSizes)-1]
	for region.Size < min_region_size {
		if region == NoRegionAvailable {
			t.Fatal("We couldn't find a region of %d bytes", min_region_size)
		}

		region, err, softerrors = NextReadableMemoryRegion(proc, region.Address+uintptr(region.Size))
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		}
	}

	for _, size := range bufferSizes {
		buf := make([]byte, size)
		readRegion := MemoryRegion{}

		_, _, err, softerrors := walkRegion(proc, region, buf,
			func(address uintptr, buffer []byte) (keepSearching bool) {
				if readRegion.Address == 0 {
					readRegion.Address = address
					readRegion.Size = uint(len(buffer))
					return true
				}

				readRegionLimit := readRegion.Address + uintptr(readRegion.Size)
				if readRegionLimit != address {
					t.Error(fmt.Sprintf("walkRegion skept %d bytes starting at %x", address-readRegionLimit,
						readRegionLimit))
					return false
				}

				readRegion.Size += uint(len(buffer))
				return true
			})
		test.PrintSoftErrors(softerrors)
		if err != nil {
			t.Fatal(err)
		}

		if region != readRegion {
			t.Error(fmt.Sprintf("%v not entirely read", region))
		}
	}
}