How dcg Handles Windows-Specific Commands and PowerShell Scripts
Destructive Command Guard detects Windows systems via cfg!(windows) and loads dedicated pattern packs from src/packs/windows/ to intercept dangerous PowerShell cmdlets like Remove-Item -Recurse and Invoke-Expression, while normalizing Windows paths and handling .ps1 script execution through platform-specific configuration abstractions.
The Dicklesworthstone/destructive_command_guard repository implements comprehensive Windows support to ensure that destructive operations are caught consistently across operating systems. While the core engine remains platform-agnostic, dcg leverages conditional compilation and dedicated modules to handle Windows executable naming conventions, PowerShell-specific dangerous patterns, and filesystem path differences. This approach allows the guard to analyze commands targeting Windows subsystems without sacrificing the sub-millisecond performance guarantees of its evaluation engine.
Platform Detection and Executable Handling
On Windows builds, dcg accounts for the .exe suffix when resolving its own binary path or validating command targets. The source code in src/cli.rs utilizes the compile-time constant env!("CARGO_BIN_EXE_dcg") to determine the correct executable path during the build process. For runtime path operations that must remain portable across platforms, the codebase falls back to std::env::consts::EXE_SUFFIX to handle the extension appropriately.
This dual approach ensures that dcg can locate its own binary for update operations (src/update.rs) and validate subprocess calls without hardcoding Windows-specific assumptions. The platform detection occurs at compile time through Rust's #[cfg(windows)] attribute, eliminating runtime overhead for path resolution logic.
Windows-Specific Pattern Packs
The repository ships with dedicated destructive pattern definitions located under src/packs/windows/. These packs extend the core evaluation logic with Windows-specific dangerous commands that would not appear in Unix-based systems. The Windows pack includes patterns for:
- Filesystem destruction: Commands like
rm -rf C:\,del /s /q *, andrmdir /s /q - PowerShell dangerous cmdlets:
Remove-Item -Recurse,Stop-Process -Force,Invoke-Expression(iex), andSet-ExecutionPolicymodifications
When dcg initializes on a Windows host, the load_platform_packs() function automatically includes these patterns in the evaluation pipeline defined in src/evaluator.rs. The engine treats PowerShell commands identically to shell commands, applying regex-based pattern matching to identify destructive operations before execution.
PowerShell Script Detection
PowerShell script handling operates through the src/heredoc.rs module, which extracts and processes inline scripts regardless of shell type. dcg identifies PowerShell scripts through two primary mechanisms:
- File extension detection: Scripts ending with
.ps1 - Shebang analysis: Lines containing
#!/usr/bin/env pwshor similar PowerShell interpreters
Once identified, the script body is extracted and evaluated against the PowerShell-specific rules defined in the Windows pack. This allows dcg to catch dangerous cmdlets within multi-line heredocs or piped script blocks, treating them as separate command contexts for safety analysis.
// Pattern matching logic for PowerShell detection
if line.ends_with(".ps1") || line.contains("#!/usr/bin/env pwsh") {
let script_body = extract_script(&input);
evaluate_against_pack(&script_body, &windows::powershell_pack());
}
Cross-Platform Command Normalization
Before pattern matching occurs, dcg normalizes Windows-specific path conventions to ensure consistent evaluation. The src/normalize.rs module strips absolute Windows paths (e.g., C:\Program Files\git\git.exe) to their base command equivalents (e.g., git), allowing the same safety patterns to apply regardless of installation location.
This normalization proves critical when analyzing commands that include full Windows paths to executables. By removing the path prefix, dcg can apply generic safety rules about git reset --hard or del operations without maintaining separate pattern sets for every possible installation directory.
// Normalizing a Windows command before evaluation
let raw = r#"C:\Program Files\Git\usr\bin\git.exe reset --hard HEAD"#;
let normalized = normalize::strip_path(raw);
// normalized → "git reset --hard HEAD"
Configuration Path Abstraction
Windows-specific configuration storage is handled through abstractions in src/config.rs. Rather than hardcoding Windows paths, dcg uses config::system_config_dir() to resolve the appropriate location for allow-lists and user settings. On Windows systems, this resolves to %ProgramData%\dcg, ensuring that configuration files respect Windows filesystem conventions and permissions models.
This abstraction allows the same configuration code to operate on Linux, macOS, and Windows without conditional compilation cluttering the business logic, while still respecting each platform's standard for system-wide data storage.
Summary
- Platform detection uses
cfg!(windows)to conditionally load Windows-specific code at compile time, avoiding runtime overhead. - Windows pattern packs in
src/packs/windows/define dangerous commands specific to CMD and PowerShell environments, includingRemove-Itemanddel /s /qvariants. - PowerShell support detects
.ps1files andpwshshebangs viasrc/heredoc.rs, extracting script bodies for independent safety evaluation. - Path normalization in
src/normalize.rsstrips Windows absolute paths to ensure cross-platform pattern compatibility. - Configuration abstraction leverages
config::system_config_dir()to store data in%ProgramData%\dcgon Windows while maintaining portable code structure.
Frequently Asked Questions
How does dcg detect dangerous PowerShell cmdlets specifically?
dcg identifies PowerShell scripts by checking for the .ps1 file extension or shebang lines containing pwsh in src/heredoc.rs. Once detected, the extracted script content is evaluated against the PowerShell-specific pattern pack defined in src/packs/windows/, which includes regex patterns for dangerous cmdlets like Invoke-Expression, Set-ExecutionPolicy, and Remove-Item -Recurse.
Why does dcg need platform-specific configuration paths on Windows?
Windows stores system-wide application data in %ProgramData% rather than /etc or /usr/local/etc. The config::system_config_dir() abstraction in src/config.rs resolves to this location on Windows builds, ensuring that allow-lists and settings files are stored in the appropriate directory with correct permissions, while keeping the configuration logic portable across operating systems.
Does dcg handle PowerShell heredocs differently than Bash scripts?
No, dcg handles PowerShell heredocs through the same extraction pipeline in src/heredoc.rs. The module treats inline scripts uniformly regardless of shell type, extracting the script body and passing it to the appropriate platform-specific pack for evaluation. PowerShell-specific dangerous patterns are applied only during the evaluation phase in src/evaluator.rs.
How does dcg manage the .exe extension when validating Windows commands?
The codebase uses std::env::consts::EXE_SUFFIX to handle executable extensions portably in src/cli.rs. For build-time path resolution, it uses env!("CARGO_BIN_EXE_dcg"), which automatically includes the correct extension for the target platform. This ensures that command validation and self-updates work correctly on Windows without hardcoding .exe assumptions throughout the source.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →