I got tired of manually checking if processes were tampered with, so I built Ghost. It scans running processes and flags anything that looks like code injection. Took a few months of evenings and weekends.
What it detects:
The usual injection techniques malware uses:
RWX memory regions (shouldn't exist in normal programs)
Shellcode patterns (x86/x64 instruction sequences)
Hooked APIs (IAT and inline hooks)
Process hollowing (gutting a legit process and replacing it)
Thread hijacking
APC injection
Plus YARA integration so you can throw custom rules at it.
Why Rust:
Needed something that could do low-level memory operations without constantly worrying about segfaults and buffer overflows. Rust's type system caught a bunch of bugs during development that would've been annoying to track down in C. Performance was important too since I wanted this to run continuously without killing the system. Can scan 200 processes in about 5 seconds now.
Cross-platform nightmare:
Windows was straightforward - ReadProcessMemory, NtQueryInformationProcess, VirtualQueryEx. The APIs are well documented and do what you expect. Linux was weirder. You're stuck with procfs (/proc/[pid]/maps, /proc/[pid]/mem) and ptrace. Reading memory through procfs is slow and ptrace has its own quirks. Had to add caching and be smart about what gets scanned. macOS was the worst. task_for_pid requires special entitlements, and even with those you can't always read process memory depending on hardened runtime settings. Ended up with limited support there.
Detection techniques:
Shellcode scanning: Look for common x86/x64 instruction patterns. Things like push/pop sequences, call instructions with suspicious offsets, NOP sleds. Not foolproof but catches a lot of basic stuff. Hook detection: Read function prologues and check if they've been modified. Compare IAT entries with actual module exports. If they don't match, something hooked it. Memory analysis: Enumerate all memory regions and flag anything with RWX permissions. Legit programs rarely need that. Also check if memory is backed by a file on disk - unbacked executable memory is suspicious. Process hollowing: Compare the PE header in memory with what's on disk. If they don't match, the process was probably hollowed.
False positives:
This is still a work in progress. Browsers with JIT compilation (V8, SpiderMonkey) look super sketchy because they generate executable code at runtime. Game anti-cheat does weird memory tricks. Debuggers obviously trigger everything. So the tool assigns confidence scores instead of just flagging things as malicious/clean. High confidence + multiple indicators = probably bad. One weird thing in Chrome = probably fine.
Performance tricks:
Reading process memory is slow. Had to optimize:
Parallel scanning - Multiple processes at once
Smart filtering - Skip kernel processes and known-good stuff
Caching - Don't re-scan the same regions over and over
Lazy loading - Only read memory when needed
Gets through a full system scan fast enough for real-time monitoring now.
YARA integration:
Included rules for common malware families - Metasploit, Cobalt Strike, generic shellcode. You can add your own rules too. Just drop .yar files in the rules directory. YARA scanning adds overhead but it's worth it for catching known payloads.
What's next:
eBPF support for Linux would be nice - kernel-level visibility without needing a custom module. Better heuristics for reducing false positives. Maybe a Windows kernel driver for deeper inspection. Also thinking about adding network behavior correlation - if a process has injection indicators AND is making weird network connections, that's way more suspicious than either alone.
Try it:
Code's on GitHub: https://github.com/pandaadir05/ghost MIT licensed. Works on Windows, Linux, macOS. Has both CLI and terminal UI. If you find bugs or have ideas for better detection methods, open an issue or PR. drop a star.
Top comments (0)