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 }
// evaluateProcess takes a single process and applies searches to it. All searches are evaluated. The `name` and `library` // checks are run first, and if needed, the memory of the process is read to run the checks on `contents` and `bytes`. // The logic is optimized to only read the process memory once and apply all the checks to it. func (r Runner) evaluateProcess(proc process.Process) (err error) { if !debug { defer func() { if e := recover(); e != nil { err = fmt.Errorf("evaluateProcess() -> %v", e) } }() } procname, err, serr := proc.Name() if err != nil { return } for _, err = range serr { stats.Failures = append(stats.Failures, err.Error()) if debug { fmt.Printf("evaluateProcess: soft error -> %v\n", err) } } if debug { fmt.Printf("evaluateProcess: evaluating proc %s\n", procname) } // first pass: apply all name & library checks against the current process for label, search := range r.Parameters.Searches { if !search.isactive { goto skip } if !search.checkName(proc, procname) && search.Options.MatchAll { if debug { fmt.Printf("evaluateProcess: proc %s does not match the names of search %s and matchall is set\n", procname, label) } search.deactivate() goto skip } if !search.checkLibraries(proc, procname) && search.Options.MatchAll { if debug { fmt.Printf("evaluateProcess: proc %s does not match the libraries of search %s and matchall is set\n", procname, label) } search.deactivate() goto skip } skip: r.Parameters.Searches[label] = search } // second pass: walk the memory of the process and apply contents regexes and bytes searches return r.walkProcMemory(proc, procname) }
func listLoadedLibraries(p process.Process) (libraries []string, harderror error, softerrors []error) { var ptr uintptr var sizeT C.size_t clibs := (***C.char)(C.malloc(C.size_t(unsafe.Sizeof(ptr)))) count := (*C.size_t)(C.malloc(C.size_t(unsafe.Sizeof(sizeT)))) defer C.free_loaded_libraries_list(*clibs, *count) defer C.free(unsafe.Pointer(clibs)) defer C.free(unsafe.Pointer(count)) response := C.list_loaded_libraries((C.process_handle_t)(p.Handle()), clibs, count) harderror, softerrors = cresponse.GetResponsesErrors(unsafe.Pointer(response)) C.response_free(response) if harderror != nil { return } libraries = make([]string, 0, *count) clibsSlice := *(*[]*C.char)(unsafe.Pointer( &reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(*clibs)), Len: int(*count), Cap: int(*count)})) processName, harderror, softs := p.Name() if harderror != nil { return } softerrors = append(softerrors, softs...) for i, _ := range clibsSlice { if clibsSlice[i] == nil { continue } str := C.GoString(clibsSlice[i]) if str == processName { continue } libraries = append(libraries, str) } return }