Memory Pattern Search built with Go - High-performance pattern matching for memory forensics.
NullSec MemGrep is a high-performance memory pattern search tool written in Go, designed for forensic analysis and malware hunting. Features concurrent scanning, hex/string/regex patterns, and built-in security signatures.
- Multi-Pattern Types - Hex, string, and regex patterns
- Concurrent Scanning - Goroutine-based parallel search
- Security Patterns - Built-in shellcode and API signatures
- Context Display - Show bytes surrounding matches
- Large File Support - Chunked scanning for memory dumps
- Cross-Platform - Windows, Linux, macOS support
| Pattern | Type | Severity | Description |
|---|---|---|---|
| NOP Sled | Hex | High | 0x90909090 |
| GetPC x86 | Hex | High | e800000000 |
| PEB Access | Hex | Critical | fs:[0x30] access |
| cmd.exe | String | Medium | Command shell |
| powershell | String | Medium | PowerShell |
| WinExec | String | High | WinExec API |
| VirtualAlloc | String | Medium | Memory allocation |
| Base64 PS | String | High | Encoded PowerShell |
# Install Go
# https://golang.org/dl/
# Clone and build
git clone https://github.com/bad-antics/nullsec-memgrep
cd nullsec-memgrep
go build -o memgrep memgrep.go# Run demo mode
./memgrep
# Scan with security patterns
./memgrep -s dump.bin
# Hex pattern search
./memgrep -p 90909090 -t hex binary.exe
# String search
./memgrep -p 'password' -t string memory.dmp
# Regex search
./memgrep -p 'cmd\.exe|powershell' -t regex file.bin-h, --help Show help message
-p, --pattern Search pattern (hex, string, or regex)
-t, --type Pattern type: hex, string, regex
-s, --security Include built-in security patterns
-b, --base Base address for display (hex)
-j, --json Output results as JSON
-c, --context Context bytes to show (default: 32)
# Full security scan
./memgrep -s memdump.raw
# Search for shellcode indicators
./memgrep -p "e800000000" -t hex -s shellcode.bin
# Find credentials
./memgrep -p "password|secret|key" -t regex config.bin
# Process memory dump with base address
./memgrep -s -b 0x7ff800000000 process.dmp┌───────────────────────────────────────────────────────────┐
│ Scanning Pipeline │
├───────────────────────────────────────────────────────────┤
│ │
│ Input Data │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Chunk Splitter │ │
│ │ 1MB chunks with 256-byte overlap │ │
│ └──────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Goroutine │ │ Goroutine │ │ Goroutine │ │
│ │ Chunk 1 │ │ Chunk 2 │ │ Chunk N │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │ │
│ └───────────────┼───────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Pattern Matchers │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Hex │ │ String │ │ Regex │ │ │
│ │ │ Match │ │ Match │ │ Match │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └──────────────────────┬──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Results Aggregator (mutex) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────┘
# Shellcode signature
./memgrep -p "90909090" -t hex file.bin
# PEB access (mov eax, fs:[0x30])
./memgrep -p "64a130000000" -t hex malware.bin
# syscall instruction
./memgrep -p "0f05" -t hex binary# API names
./memgrep -p "VirtualAlloc" -t string dump.bin
# Shell references
./memgrep -p "/bin/sh" -t string memory.raw# IP addresses
./memgrep -p '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' -t regex dump.bin
# URLs
./memgrep -p 'https?://[^\s]+' -t regex memory.rawPattern Matches:
[HIGH] NOP Sled
Offset: 0x00000000
Address: 0x0000000010000000
Length: 4 bytes
Type: hex
Classic NOP sled
Context: 909090909090909090909090909090909090...
[CRITICAL] PEB Access
Offset: 0x00000120
Address: 0x0000000010000120
Length: 6 bytes
Type: hex
fs:[0x30] PEB access
Context: 64a1300000008b400c8b701c...
[MEDIUM] cmd.exe
Offset: 0x00000080
Address: 0x0000000010000080
Length: 7 bytes
Type: string
Command shell reference
Context: 706174685c636d642e6578652f6377686f616d69...
═══════════════════════════════════════════
Statistics:
Patterns: 15
Matches: 8
Scanned: 512 bytes
Time: 1.234ms
Critical: 1
High: 3
Medium: 4
- Goroutines - Lightweight concurrent scanning
- Channels - Safe inter-goroutine communication
- bytes Package - Efficient byte slice operations
- Cross-Platform - Single binary, no dependencies
- Fast Compilation - Quick iteration during development
// Parallel chunk scanning with mutex protection
func (s *Scanner) Scan(data []byte) {
chunkSize := 1024 * 1024
var wg sync.WaitGroup
for offset := 0; offset < len(data); offset += chunkSize {
wg.Add(1)
go s.scanChunk(chunk, int64(offset), &wg)
}
wg.Wait()
}Part of the NullSec security toolkit collection:
MIT License - See LICENSE for details.
NullSec - Memory pattern search for forensic analysis