D
DioProcess

String Scanning

Ring 3

Extract 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

EncodingRangeDescription
ASCII0x20 - 0x7EPrintable ASCII + space
ASCII0x09, 0x0A, 0x0DTab, newline, carriage return
UTF-160x0020 - 0xFFFFBMP 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

TypeSourceTypical Contents
PrivateVirtualAlloc, heapDynamic data, buffers, objects
ImagePE file mappingModule strings, resources, exports
MappedMemory-mapped fileFile 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