Compiled .NET 8 PowerShell deobfuscator. Hosts the PowerShell engine directly to intercept execution layers from obfuscated/malicious scripts without needing pwsh installed.
Replaces the deobfuscate_ps.ps1 + psdecode shell wrapper with a single self-contained binary.
WARNING: This tool executes real malware. The sandbox intercepts most execution paths, but PowerShell is a full language runtime — novel techniques can bypass proxy functions. Even with Docker, always run this on a dedicated malware analysis VM or disposable host, never on a workstation with access to production networks, credentials, or sensitive data. Docker adds isolation but is not a security boundary against a determined adversary.
# Build
docker build -t psdecode .
# Scan a file (no network, read-only, temp filesystem)
docker run --rm --network none --read-only --tmpfs /tmp \
-v /path/to/samples:/samples:ro \
-v /path/to/output:/output \
psdecode -o /output /samples/malware.ps1
# JSON output
docker run --rm --network none --read-only --tmpfs /tmp \
-v ./samples:/samples:ro \
psdecode -j /samples/malware.ps1
# Pipe from stdin
cat malware.ps1 | docker run --rm -i --network none --read-only --tmpfs /tmp \
psdecode -Key Docker flags:
--network none— no network access, blocks reverse shells and C2 callbacks--read-only— immutable root filesystem--tmpfs /tmp— writable temp on tmpfs, destroyed when container exits-v ...:ro— samples mounted read-only
Requires .NET 8 SDK.
# Debug build
dotnet build
# Self-contained single-file release (~50MB ELF)
dotnet publish -c Release
# Output: bin/Release/net8.0/linux-x64/publish/psdecodeNote: The runtimes/ directory from the publish output must sit alongside the binary for PowerShell module discovery.
psdecode [options] <script.ps1>
psdecode [options] - # read from stdin
| Flag | Description |
|---|---|
-o <dir> |
Save layer files to directory (per-sample subfolders) |
-R |
Write plain-text report to output dir (or <input>.report.txt) |
-j |
JSON output |
-q |
Quiet mode (final layer only) |
-r |
Raw layer content (no truncation) |
-b |
Show binary layer hex dumps |
--tags |
MITRE ATT&CK tags only |
-t <sec> |
Execution timeout (default: 30, max: 300) |
-v |
Verbose diagnostics to stderr |
--version |
Print version |
-h |
Help |
./psdecode sample.ps1
./psdecode -j sample.ps1 2>/dev/null | jq .
./psdecode -o ./output -R sample.ps1 # layers + report in ./output/sample/
./psdecode --tags sample.ps1
cat sample.ps1 | ./psdecode -
# Batch: process all samples, each gets its own subfolder in ./output/
for f in samples/*.ps1; do ./psdecode -o ./output -R "$f"; doneWhen using -o, each sample gets its own subfolder:
output/
├── malware1/
│ ├── layer_1.txt
│ ├── layer_1.meta.json
│ ├── layer_2.bin
│ ├── layer_2.bin.desc
│ ├── layer_2.meta.json
│ └── report.txt
├── malware2/
│ ├── ...
The tool has multiple layers of containment:
Application-level (built-in):
- Constrained
InitialSessionStatewith dangerous commands removed - 45+ proxy functions intercepting execution, I/O, network, and registry at the PowerShell engine level
- Custom
PSHostthat interceptsRead-Host,Get-Credential, andPromptForChoice— prevents hangs and captures credential harvesting - Assembly load hooks that detect .NET payloads loaded via
[Reflection.Assembly]::Load() - Fake Windows filesystem (C: drive via PSDrive, env vars, PSVersionTable)
- Execution timeout with async cancellation
OS-level (Docker):
- Network namespace isolation (
--network none) - Read-only root filesystem
- Non-root container user
- Ephemeral tmpfs for temp files
- Resource limits via
--memoryand--cpusif needed
psdecode.net/
├── Program.cs CLI entry, arg parsing, output formatting
├── Sandbox.cs Runspace setup, ISS config, script execution
├── SandboxPSHost.cs Custom PSHost for Read-Host/Get-Credential interception
├── AssemblyLoadHook.cs Captures reflective .NET assembly loading
├── Dockerfile Docker build for isolated execution
├── psdecode.csproj .NET 8 project, Microsoft.PowerShell.SDK 7.4.5
├── Hooks/
│ ├── CommandHooks.cs IEX, Start-Process, Invoke-Command, LOLBins
│ ├── FileIOHooks.cs Set-Content, Add-Content, Out-File, BITS, registry
│ ├── NetworkHooks.cs WebClient (Download/Upload/Open), Invoke-WebRequest, COM stubs
│ ├── SecurityHooks.cs ConvertTo-SecureString, Add-Type, Defender prefs
│ └── StubHooks.cs WMI, Get-Process, services, Write-Host
├── Analysis/
│ ├── AstAnalyzer.cs Pre-execution AST analysis (base64, hex, char[])
│ ├── LayerWriter.cs Layer file output, dedup, 32-layer cap
│ ├── MitreTagging.cs ~90 MITRE ATT&CK behavior rules
│ └── PostProcessor.cs Binary artifact extraction from text layers
└── Environment/
├── FakeFileSystem.cs Fake C: drive directory tree
└── FakeEnvironment.cs Env vars, PSVersionTable, PSDrive
-
AST pre-analysis -- Parses the script AST to extract base64 strings,
-EncodedCommandargs, hex blobs, and[char]sequences before execution. -
Constrained runspace -- Creates an
InitialSessionStatewith dangerous commands removed and 40+ proxy functions registered. Proxies interceptIEX,Start-Process,New-Object, file I/O, network calls, registry ops, and more. -
Execution -- Runs the script inside the sandboxed runspace with a custom PSHost and fake Windows environment. Interactive prompts are intercepted, assembly loads are monitored, and intercepted content is written as numbered layers.
-
Post-processing -- Extracts binary artifacts from text layers, applies MITRE ATT&CK tags, collects file drops from the fake filesystem.
Academic papers on PowerShell deobfuscation and malware detection. Most report strong numbers but never released code.
| Paper | Venue | Claimed Result |
|---|---|---|
| Detecting Malicious PowerShell using Deep Neural Networks (Hendler, Kels, Rubin — Microsoft) | ACM AsiaCCS 2018 | AUC ~0.99 |
| AMSI-Based Detection using Contextual Embeddings (Hendler, Kels, Rubin — Microsoft) | ACM AsiaCCS 2020 | 90% TPR, <0.1% FPR |
| PSDEM: A Feasible De-Obfuscation Method (Liu et al.) | IEEE ISCC 2018 | High FP, couldn't handle unknowns |
| MPSAutodetect (Alahmadi et al.) | Computers & Security 2022 | 98% TPR, 0.6% FPR |
| AST2Vec: Robust Neural Code Representation (Miao et al.) | SciSec 2023 | 97.76% accuracy |
| Power-ASTNN (Zhang et al.) | Computers & Security 2025 | 98.87% accuracy, AUC >0.995 |
| Transformer-Based Original Content Recovery (Dedek & Scherer) | ICONIP 2022 | 92% full recovery, 100% ≥90% recovery |
| Sentence Transformer + Similarity Learning (Fu, Song, Ding, Alaca) | ACM TOPS 2025 | 99.01–99.73% accuracy |
| Command-line Obfuscation Detection using Small LMs (Outrata, Polak, Kopp — Cisco) | arXiv 2024 | Precision 0.9996, Recall 0.9991 |
| Static Detection via Word Embeddings (Mimura & Tajiri) | Internet of Things 2021 | F1 0.995 |
| GCN-based Detection (Choi) | MDPI Applied Sciences 2021 | +8.2% improvement |
| Malicious PS Detection using Attention | MDPI Electronics 2020 | 96.5% detection rate |
| AI-based Detection with Feature Optimizations (Song et al.) | ETRI Journal 2021 | 98% detection |
| Paper | Venue | Result | Code |
|---|---|---|---|
| Li et al. — Semantic-Aware Deobfuscation | ACM CCS 2019 | 93.2% similarity recovery | GitHub |
| PowerPeeler | ACM CCS 2024 | 95% deobfuscation correctness | Gitee |
| PowerDrive | DIMVA 2019 | 4,642 scripts analyzed | GitHub |
| Invoke-Deobfuscation | IEEE DSN 2022 | 46% obfuscation score reduction | Gitee |