String Scanning
Ring 3Extract printable strings from process memory, supporting ASCII and UTF-16 encoding with configurable length filters.
Overview
The String Scan feature scans all committed memory regions of a target process to find printable strings. This is useful for malware analysis, debugging, and reverse engineering. Implemented in the process crate.
Data Structures
crates/process/src/lib.rs
pub struct StringResult {
pub address: u64, // Memory address where string was found
pub value: String, // The extracted string content
pub encoding: StringEncoding, // ASCII or UTF-16
pub length: usize, // Character count
pub region_type: String, // Private, Mapped, or Image
}
pub enum StringEncoding {
Ascii,
Utf16,
}
pub struct StringScanConfig {
pub min_length: usize, // Minimum string length (default: 4)
pub scan_ascii: bool, // Scan for ASCII strings
pub scan_utf16: bool, // Scan for UTF-16 strings
pub max_string_length: usize, // Maximum capture length (default: 512)
}Algorithm
Algorithm
pub fn scan_process_strings(
pid: u32,
config: StringScanConfig
) -> Result<Vec<StringResult>, ProcessError> {
// 1. Open process with PROCESS_VM_READ | PROCESS_QUERY_INFORMATION
let handle = OpenProcess(..., pid)?;
// 2. Enumerate all memory regions via VirtualQueryEx
let mut address = 0usize;
loop {
let info = VirtualQueryEx(handle, address)?;
// 3. Skip uncommitted, reserved, or guarded regions
if info.State != MEM_COMMIT || info.Protect & PAGE_GUARD != 0 {
address += info.RegionSize;
continue;
}
// 4. Read region contents
let mut buffer = vec![0u8; info.RegionSize];
ReadProcessMemory(handle, info.BaseAddress, &mut buffer)?;
// 5. Scan for ASCII strings
if config.scan_ascii {
scan_ascii_strings(&buffer, info.BaseAddress, &config, &mut results);
}
// 6. Scan for UTF-16 strings
if config.scan_utf16 {
scan_utf16_strings(&buffer, info.BaseAddress, &config, &mut results);
}
address += info.RegionSize;
}
Ok(results)
}
fn scan_ascii_strings(buffer: &[u8], base: u64, config: &StringScanConfig, results: &mut Vec<StringResult>) {
// Find runs of printable ASCII characters (0x20-0x7E)
// Minimum length from config, null terminator optional
// Record address as base + offset
}
fn scan_utf16_strings(buffer: &[u8], base: u64, config: &StringScanConfig, results: &mut Vec<StringResult>) {
// Find runs of valid UTF-16 code units (pairs of bytes)
// Filter by printable characters
// Handle both little-endian (Windows standard) and BOM
}Printable Character Detection
| Encoding | Range | Description |
|---|---|---|
| ASCII | 0x20 - 0x7E | Printable ASCII + space |
| ASCII | 0x09, 0x0A, 0x0D | Tab, newline, carriage return |
| UTF-16 | 0x0020 - 0xFFFF | BMP printable characters |
UI Features
Access via right-click process → Inspect → String Scan. The modal provides:
- • Minimum length slider — 1-100 characters (default: 4)
- • Encoding filter — All, ASCII Only, UTF-16 Only
- • Search filter — Real-time text search across results
- • Pagination — 1000 results per page with navigation controls
- • Export — Export all filtered results to .txt file
- • Context menu — Copy String, Copy Address, Copy Row
- • Region type column — Shows Private, Mapped, or Image
Region Types
| Type | Source | Typical Contents |
|---|---|---|
| Private | VirtualAlloc, heap | Dynamic data, buffers, objects |
| Image | PE file mapping | Module strings, resources, exports |
| Mapped | Memory-mapped file | File contents, shared memory |
Performance
String scanning is performed on a background thread (tokio::task::spawn_blocking) to keep the UI responsive. Large processes may take several seconds to scan completely.
- • Results are paginated (1000 per page) to prevent UI lag
- • Maximum string length (512 chars) prevents memory bloat
- • Progress indicator shows scan status
Use Cases
- • Malware analysis — Extract C2 URLs, encryption keys, API names
- • Debugging — Find error messages, log strings, config values
- • Reverse engineering — Identify function names, library versions
- • Credential hunting — Search for plaintext passwords in memory
- • CTF challenges — Find flags or clues in process memory
Example Output
results.txt
Address | Encoding | Length | Region | String
-----------------+----------+--------+---------+----------------------------------
0x7FF6A1234560 | ASCII | 12 | Image | kernel32.dll
0x7FF6A1234580 | UTF-16 | 24 | Image | LoadLibraryW
0x000001A23456 | ASCII | 47 | Private | https://api.example.com/callback
0x000001A23490 | UTF-16 | 15 | Private | ACCESS_DENIED
0x7FFE12340000 | ASCII | 8 | Mapped | password