{"record":{"id":"41cc6a8354acbab2","repo":"shadow1ng/fscan","slug":"local-pe-not-specified-41cc6a","errorCode":null,"errorMessage":"local_pe_not_specified","messagePattern":"local_pe_not_specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/local/winservice.go","lineNumber":31,"sourceCode":"\t\"github.com/shadow1ng/fscan/common\"\n\t\"github.com/shadow1ng/fscan/common/i18n\"\n\t\"github.com/shadow1ng/fscan/plugins\"\n)\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","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/local/winservice.go#L13-L49","documentation":"WinServicePlugin.Scan requires the path of a local PE file in session.Config.WinPEFile to correlate against Windows service ImagePath entries. When that field is empty, the plugin returns this localized error and does not query services. It is a required-input precondition check.","triggerScenarios":"Calling Scan with Config.WinPEFile unset/empty — e.g. the winservice plugin was selected but the PE-file option was not provided on the command line or in the constructed Config struct.","commonSituations":"Missing CLI flag for the local PE file; programmatically built ScanSession omitting WinPEFile; config file lacking the win-pe-file field; a flag-parsing regression that drops the value.","solutions":["Set session.Config.WinPEFile to the PE path before calling Scan.","Ensure the CLI/config layer maps the PE-file option into Config.WinPEFile.","Validate required config fields before dispatching to local plugins."],"exampleFix":"// before\ncfg := &common.Config{} // WinPEFile \"\"\np.Scan(ctx, host, &common.ScanSession{Config: cfg})\n// after\ncfg := &common.Config{WinPEFile: \"/opt/samples/svc.exe\"}\np.Scan(ctx, host, &common.ScanSession{Config: cfg})","handlingStrategy":"validation","validationCode":"if cfg.WinPEFile == \"\" {\n    return errors.New(\"winservice plugin requires Config.WinPEFile\")\n}","typeGuard":"func hasWinPE(c *common.Config) bool { return c != nil && strings.TrimSpace(c.WinPEFile) != \"\" }","tryCatchPattern":null,"preventionTips":["Set all required local-plugin fields in one config-construction helper.","Run a dry-run validation of Config before launching scans.","Log the effective Config (minus secrets) when a plugin aborts on missing input."],"tags":["configuration","windows","services","pe-file"],"backgroundTag":"missing-required-config-field","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"}