shadow1ng/fscan · error
local_invalid_pe
Error message
local_invalid_pe
What it means
After confirming the PE file exists, WinSchTaskPlugin.Scan checks its extension: only .exe and .dll are accepted because scheduled-task actions must reference executable images. Any other extension (.bin, .ps1, .sys, no extension) produces this localized 'invalid PE' error with the path interpolated.
Source
Thrown at plugins/local/winschtask.go:38
}
func NewWinSchTaskPlugin() *WinSchTaskPlugin {
return &WinSchTaskPlugin{
BasePlugin: plugins.NewBasePlugin("winschtask"),
}
}
func (p *WinSchTaskPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *plugins.Result {
pePath := session.Config.WinPEFile
if pePath == "" {
return &plugins.Result{Success: false, Error: fmt.Errorf("%s", i18n.GetText("local_pe_not_specified"))}
}
if _, err := os.Stat(pePath); err != nil {
return &plugins.Result{Success: false, Error: fmt.Errorf("%s", i18n.Tr("local_pe_not_found", pePath))}
}
ext := strings.ToLower(filepath.Ext(pePath))
if ext != ".exe" && ext != ".dll" {
return &plugins.Result{Success: false, Error: fmt.Errorf("%s", i18n.Tr("local_invalid_pe", pePath))}
}
absPath, _ := filepath.Abs(pePath)
baseName := strings.TrimSuffix(filepath.Base(absPath), filepath.Ext(absPath))
tasks := []struct {
name string
schedule string
modifier string
}{
{fmt.Sprintf("WindowsUpdateCheck_%s", baseName), "DAILY", "1"},
{fmt.Sprintf("SystemSecurityScan_%s", baseName), "ONLOGON", ""},
{fmt.Sprintf("MaintenanceTask_%s", baseName), "ONSTART", ""},
{fmt.Sprintf("BackgroundService_%s", baseName), "HOURLY", "2"},
}
var output strings.Builder
var successCount intView on GitHub (pinned to 95cc12e753)
Solutions
- Configure a path to an actual .exe or .dll file.
- Rename/copy the sample with an .exe or .dll extension only if it genuinely is a PE image; do not rename non-PE files.
- If you need to scan scripts or drivers, use the appropriate plugin rather than the schtask PE matcher.
Example fix
// before session.Config.WinPEFile = "C:\\samples\\payload.bin" // ext not allowed // after session.Config.WinPEFile = "C:\\samples\\payload.dll" // valid PE extension p.Scan(ctx, host, session)
Defensive patterns
Strategy: validation
Validate before calling
ext := strings.ToLower(filepath.Ext(cfg.WinPEFile))
if ext != ".exe" && ext != ".dll" {
return fmt.Errorf("WinPEFile must be .exe or .dll, got %q", ext)
} Prevention
- Configure only PE image files (.exe/.dll) for scheduled-task matching.
- Check the extension when accepting user-supplied sample paths.
- Rename raw payloads to .exe/.dll only if they truly are PE images.
When it happens
Trigger: session.Config.WinPEFile points to an existing file whose lowercased filepath.Ext is neither ".exe" nor ".dll", e.g. a raw payload with no extension, a .sys driver, or a script file.
Common situations: Pointing the plugin at a shellcode/payload blob without an extension; mistakenly configuring a script (.ps1/.bat) or driver (.sys) where a PE image is required; case-only extensions are fine (handled via strings.ToLower), but files like 'agent.exe.bak' are not.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- local_pe_not_specified
- local_pe_not_found
- local_pe_not_specified
- local_pe_not_found
- local_pe_not_specified
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/2a58d8de1c9acd6d.
Report an issue: GitHub.