{"record":{"id":"48a1f817b9d124b9","repo":"shadow1ng/fscan","slug":"local-pe-not-found-48a1f8","errorCode":null,"errorMessage":"local_pe_not_found","messagePattern":"local_pe_not_found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/local/winservice.go","lineNumber":34,"sourceCode":")\n\ntype WinServicePlugin struct {\n\tplugins.BasePlugin\n}\n\nfunc NewWinServicePlugin() *WinServicePlugin {\n\treturn &WinServicePlugin{\n\t\tBasePlugin: plugins.NewBasePlugin(\"winservice\"),\n\t}\n}\n\nfunc (p *WinServicePlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result {\n\tpePath := session.Config.WinPEFile\n\tif pePath == \"\" {\n\t\treturn &plugins.Result{Success: false, Error: fmt.Errorf(\"%s\", i18n.GetText(\"local_pe_not_specified\"))}\n\t}\n\tif _, err := os.Stat(pePath); err != nil {\n\t\treturn &plugins.Result{Success: false, Error: fmt.Errorf(\"%s\", i18n.Tr(\"local_pe_not_found\", pePath))}\n\t}\n\n\tabsPath, _ := filepath.Abs(pePath)\n\tbaseName := strings.TrimSuffix(filepath.Base(absPath), filepath.Ext(absPath))\n\n\tservices := []struct {\n\t\tname    string\n\t\tdisplay string\n\t\tstart   string\n\t}{\n\t\t{fmt.Sprintf(\"WinDefendUpdate_%s\", baseName), \"Windows Defender Update Service\", \"auto\"},\n\t\t{fmt.Sprintf(\"SysHealthMon_%s\", baseName), \"System Health Monitor\", \"delayed-auto\"},\n\t}\n\n\tvar output strings.Builder\n\tvar successCount int\n\n\tfor _, svc := range services {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/local/winservice.go#L16-L52","documentation":"WinServicePlugin.Scan stats the configured PE path to ensure the local file exists before comparing it with installed service binaries. If os.Stat fails, the plugin returns this localized 'local PE not found' error including the configured path. Service enumeration is skipped entirely.","triggerScenarios":"Config.WinPEFile non-empty but the path does not resolve: nonexistent file, relative path against an unexpected CWD, removed/quarantined sample, or unreadable directory.","commonSituations":"Path typo; the sample was deleted after the config was written; running the tool under a different user/CWD; pointing to a network share that is offline.","solutions":["Verify and correct the path stored in Config.WinPEFile.","Use an absolute path and check existence (os.Stat) before invoking the plugin.","Restore the file or re-point the config to a copy that exists locally.","Check read permissions on the file's directory."],"exampleFix":"// before\nsession.Config.WinPEFile = \"./agent.exe\" // not in CWD\n// after\npe := \"/home/analyst/samples/agent.exe\"\nif _, err := os.Stat(pe); err != nil { log.Fatal(err) }\nsession.Config.WinPEFile = pe","handlingStrategy":"validation","validationCode":"pePath := cfg.WinPEFile\nif abs, err := filepath.Abs(pePath); err == nil { pePath = abs }\nif _, err := os.Stat(pePath); err != nil {\n    return fmt.Errorf(\"service PE sample missing: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"res := plugin.Scan(ctx, host, session)\nif !res.Success {\n    if _, statErr := os.Stat(session.Config.WinPEFile); statErr != nil {\n        // file vanished; re-acquire sample and retry\n    }\n}","preventionTips":["Stat the sample immediately before scanning, not only at config time.","Keep samples outside AV-monitored directories or add exclusions.","Store absolute paths in case configs."],"tags":["file-not-found","windows","services","pe-file"],"backgroundTag":"file-not-found","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}