From 49188fc3c2d894c5e1cd909b612873f6ef60fb1d Mon Sep 17 00:00:00 2001 From: Kouame Behouba Manasse Date: Wed, 6 Mar 2024 07:46:13 -0500 Subject: [PATCH] feat(crit): add SearchPattern method on MemoryReader This commit add a new method SearchPattern to MemoryReader to search for patterns inside the process memory pages. This method accept regular expressions for flexible pattern matching. Signed-off-by: Kouame Behouba Manasse --- crit/mempages.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/crit/mempages.go b/crit/mempages.go index c823edbaa..4134fc6c7 100644 --- a/crit/mempages.go +++ b/crit/mempages.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "path/filepath" + "regexp" "github.com/checkpoint-restore/go-criu/v7/crit/images/mm" "github.com/checkpoint-restore/go-criu/v7/crit/images/pagemap" @@ -193,3 +194,54 @@ func (mr *MemoryReader) GetShmemSize() (int64, error) { return size, nil } + +// SearchPattern searches for a pattern in the process memory pages. +// If the pattern is found, it returns slices of strings containing the matched patterns +// along with the specified context before and after each match. +func (mr *MemoryReader) SearchPattern(pattern string, context int) ([]string, error) { + if context < 0 { + return nil, errors.New("context size cannot be negative") + } + + var results []string + regexPattern, err := regexp.Compile(pattern) + if err != nil { + return nil, err + } + + for _, entry := range mr.pagemapEntries { + start := entry.GetVaddr() + end := start + uint64(entry.GetNrPages())*uint64(mr.pageSize) + + // Read the entire page content + buffer, err := mr.GetMemPages(start, end) + if err != nil { + return nil, err + } + + // Replace null bytes with space + filteredBytes := bytes.ReplaceAll(buffer.Bytes(), []byte{0x0}, []byte{0x20}) + + // Search for all matching pattern using the regular expression + matches := regexPattern.FindAllIndex(filteredBytes, -1) + + for _, match := range matches { + startPattern, endPattern := match[0], match[1] + + // Calculate the start and end indices for the context surrounding the match + startContext := startPattern - context + if startContext < 0 { + startContext = startPattern + } + + endContext := endPattern + context + if endContext > buffer.Len() { + endContext = endPattern + } + + results = append(results, string(filteredBytes[startContext:endContext])) + } + } + + return results, nil +}