Skip to content

spawn451/Delphi-LitCrypt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Delphi LitCrypt - String Encryption with Disk & Memory Protection

A Delphi library that provides compile-time string encryption with enhanced runtime memory protection. Protects sensitive strings from both static analysis tools (like Ghidra) and provides significant memory protection during execution.

πŸ”’ Security Features

Disk Protection (Static Analysis)

  • βœ… Encrypted in Binary: Strings are stored as encrypted byte arrays in the compiled executable
  • βœ… Hidden Encryption Key: The actual encryption key never appears in the binary - only encrypted bytes
  • βœ… Salt-Based Key Encryption: Key is XOR encrypted with salt
  • βœ… Ghidra-Proof: Static analysis tools cannot find plain-text strings or the actual key
  • βœ… Hex Editor Safe: No readable strings or keys visible in binary files

Memory Protection (Runtime Analysis)

  • βœ… ISecureString Interface: Enhanced memory protection using reference-counted secure strings
  • βœ… Automatic Cleanup: Secure strings automatically clear memory when going out of scope
  • βœ… Secure Buffer Clearing: Temporary decryption buffers are immediately zeroed after use
  • βœ… Key Recovery: Actual key is reconstructed at runtime from encrypted bytes
  • ⚠️ Limited by Delphi: Perfect memory protection is impossible due to automatic string copying
  • ⚠️ Concatenation Risk: String concatenation (+ operator) creates uncontrolled copies

πŸš€ Quick Start

1. Install the Plugin

  1. Install the Plugin Package: Open src/LitCryptPlugin.dpk in Delphi and Install it
  2. Add Library Path: Go to Tools β†’ Options β†’ Language β†’ Delphi β†’ Library
    • Library path - Click the "..." button next to Library path
    • Add the full path to your src folder (e.g., C:\YourPath\Delphi LitCrypt Plugin_v.1.1\src)
    • Click OK to save
  3. Restart Delphi
  4. Verify: Tools β†’ Encrypt Selected String Ctrl+Shift+E and Decrypt Selected String Ctrl+Shift+D menu appears

2. Use in Your Projects

The LitCrypt unit is now available in all your projects through the library path! Simply add it to your uses clause:

uses
  System.SysUtils,
  LitCrypt;  // Available via library path - automatically initializes!

No file copying needed - Delphi will automatically find LitCrypt.pas in the library path. No manual initialization needed - The encryption system initializes automatically when the unit loads.

3. Use Encrypted Strings

program MySecureApp;
uses LitCrypt; // That's it! No manual initialization needed.

begin
  // Write your code with plain strings
  WriteLn('Database password: ' + 'my-secret-password');
  WriteLn('API Key: ' + 'sk-1234567890abcdef');
end.

4. Encrypt Strings

  1. Select the string including quotes: 'my-secret-password'
  2. Press Ctrl+Shift+E (or Tools β†’ Encrypt Selected String)
  3. Result: String becomes DecryptString([$66, $2A, $2D, ...])
// Before encryption
WriteLn('Database password: ' + 'my-secret-password');

// After encryption (done by plugin)
WriteLn('Database password: ' + DecryptString([$66, $2A, $2D, $32, $2A, $74, $66, $32, $2C, $33, $32, $67, $74, $2D, $26, $66, $66, $2E, $7B, $33, $75, $1A, $1B, $1C]));

πŸ”§ How It Works

Encryption Process (Compile Time)

  1. Key Encryption: The actual encryption key is XOR encrypted with a salt
  2. String Encryption: Selected strings are encrypted using XOR cipher with the actual key
  3. Code Generation: Replaces plain strings with DecryptString([byte array])
  4. Binary Storage: Only encrypted key bytes and salt bytes are stored in the binary

Decryption Process (Runtime)

  1. Key Recovery: EncryptedKey XOR Salt = ActualKey
  2. String Decryption: EncryptedString XOR ActualKey = PlainText
  3. Secure Memory Handling: All intermediate buffers are cleared after use
  4. Result: Original string is returned for immediate use
function DecryptString(const EncryptedData: array of Byte): string;
var
  SecureStr: ISecureString;
begin
  // Use secure decryption and return the data
  // The secure string will auto-clear when this function exits
  SecureStr := DecryptSecure(EncryptedData);
  Result := SecureStr.Data;  // Creates a copy - this is the limitation
end;

πŸ›‘οΈ Memory Protection

Two-Tier Protection System

1. DecryptString() - Standard Usage:

var
  Password: string;
begin
  Password := DecryptString([$66, $2A, $2D, ...]);  // Creates persistent copy
  WriteLn('Password: ' + Password);                  // String concatenation creates more copies
end;
  • βœ… Secure decryption process
  • ❌ Returned string persists in memory
  • ❌ String operations create additional copies

2. DecryptSecure() - Enhanced Protection:

var
  Password: ISecureString;
begin
  Password := DecryptSecure([$66, $2A, $2D, ...]);    // Secure container
  WriteLn(Password.Data);                              // Direct output, minimal copies
  // Password automatically cleared when going out of scope
end;
  • βœ… Secure decryption process
  • βœ… Automatic memory clearing on scope exit
  • ⚠️ Accessing .Data still creates temporary copies

Memory Protection Features

Security Measure DecryptString() DecryptSecure() Description
Secure Decryption βœ… βœ… Temporary buffers cleared during decryption
Automatic Cleanup ❌ βœ… Memory cleared when variable goes out of scope
Reference Counting ❌ βœ… Uses Delphi's interface system for automatic cleanup
Buffer Zeroing βœ… βœ… SecureZeroMemory clears intermediate data
Global Key Protection βœ… βœ… Key cleared at program finalization

Critical Memory Protection Rules

βœ… SAFE PRACTICES:

// Direct output without concatenation
SecStr := DecryptSecure([...]);
WriteLn(SecStr.Data);

// Separate operations
Write('Password: ');
WriteLn(SecStr.Data);

❌ UNSAFE PRACTICES:

// String concatenation creates persistent copies
WriteLn('Password: ' + SecStr.Data);  // BREAKS MEMORY PROTECTION!

// Assignment to regular string variables
MyPassword := DecryptString([...]);   // Creates persistent copy

Delphi Limitations:

  • ❌ Automatic String Copying: Delphi's string system creates copies automatically
  • ❌ Non-deterministic Cleanup: Garbage collection timing is unpredictable
  • ❌ Concatenation Risk: The + operator always creates new string objects
  • ❌ No Ownership System: Unlike Rust, Delphi can't prevent uncontrolled copying

Testing Memory Protection

To verify the memory protection differences:

// Test 1: Standard approach (will persist in memory)
var Password: string;
begin
  Password := DecryptString([$66, $2A, $2D, ...]);
  WriteLn('Password: ' + Password);  // Multiple copies created
end;

// Test 2: Secure approach (minimal memory exposure)
var SecStr: ISecureString;
begin
  SecStr := DecryptSecure([$66, $2A, $2D, ...]);
  WriteLn(SecStr.Data);  // Direct output, auto-cleanup
end;

Testing Steps:

  1. Compile your program with both approaches
  2. Run a memory analyzer (Process Hacker, System Informer, etc.)
  3. Search for your decrypted strings in process memory
  4. Compare results between the two approaches

Expected Results:

  • βœ… Static analysis: No plaintext strings in binary
  • ⚠️ Memory analysis: Secure approach shows significantly fewer instances
  • ❌ Perfect protection: Not achievable due to Delphi's string system

πŸ›‘οΈ Security Analysis

Protection Against Static Analysis

Tool What They See Status
Strings Command No plain text strings βœ… Protected
Hex Editors Only encrypted bytes 08 5C 5C 06 βœ… Protected
Ghidra/IDA Pro Encrypted byte arrays, no readable keys βœ… Protected

Protection Against Memory Analysis

Attack Vector DecryptString() DecryptSecure() Notes
Memory Dumps ⚠️ Limited βœ… Enhanced Secure version clears automatically
Debugger Inspection ❌ Visible ⚠️ Reduced Strings still temporarily visible
Process Memory Scan ❌ Persistent βœ… Minimal Depends on usage patterns
String Concatenation ❌ Creates copies ❌ Still creates copies Fundamental limitation

Real-World Memory Protection

Best Case Scenario (DecryptSecure + Careful Usage):

  • Decrypted strings exist in memory only during scope lifetime
  • Automatic cleanup when variables go out of scope
  • Significantly reduced memory exposure compared to standard approach

Worst Case Scenario (DecryptString + Concatenation):

  • Multiple persistent copies in memory
  • No automatic cleanup
  • Similar to storing plain text strings

Practical Reality:

  • βœ… Significant improvement over plain text storage
  • βœ… Automatic cleanup in many scenarios
  • ⚠️ Not perfect due to Delphi language limitations
  • ❌ String concatenation always breaks protection

πŸ” Use DecryptSecure() with direct output for best memory protection!

πŸ›‘οΈ Configuration

Library Path Setup

After installing the plugin, you must add the src folder to your Delphi library path:

  1. Tools β†’ Options β†’ Language β†’ Delphi β†’ Library
  2. Library path - Click "..." next to "Library path"
  3. Add the full path to your src folder
    • Example: C:\YourPath\Delphi LitCrypt Plugin_v.1.1\src
  4. Click OK to save

This makes LitCrypt.pas available to all your projects without copying files.

Key Security

  • Encryption key is encrypted with salt during compilation
  • Same key derivation approach ensures consistent encryption/decryption
  • No external dependencies - works on any computer

πŸ“ Project Structure

β”œβ”€β”€ src/                          # Plugin & Runtime Library
β”‚   β”œβ”€β”€ LitCryptPlugin.dpk        # Plugin package (Build & Install)
β”‚   β”œβ”€β”€ LitCrypt.pas              # Runtime library (add src to library path)
β”‚   β”œβ”€β”€ LitCryptIDEPlugin.pas     # IDE integration
β”‚   └── LitCryptCore.pas          # Plugin encryption logic
β”‚
β”œβ”€β”€ tools/                        # Utility Tools
β”‚   └── KeyGenerator/             # Key generation utility
β”‚       └── KeyGenerator.dpr      # Generates secure encryption keys and salts
β”‚
β”œβ”€β”€ demo/                         # Examples
β”‚   └── Demo.dpr                  # Example usage
β”‚
└── README.md                     # This file

πŸ” Testing Security

Test Static Analysis Protection

# Compile your program, then test with strings command
strings MyProgram.exe | grep "my-secret-password"
# Should return nothing if properly encrypted

Test Memory Analysis Protection

You can use System Informer for this.

⚠️ Security Notes

What This Protects Against

  • βœ… Static analysis - Strings are encrypted, actual key is hidden
  • βœ… Automated string extraction tools - No plain-text strings in executable
  • βœ… Casual reverse engineering - Requires understanding of XOR decryption
  • βœ… Memory analysis - Keys and strings are cleared after use
  • βœ… Binary inspection - Actual encryption key never appears in binary

What This Does NOT Protect Against

  • ❌ Determined reverse engineers with time and XOR knowledge
  • ❌ Runtime code injection attacks
  • ❌ Cryptographic attacks (uses simple XOR cipher)
  • ❌ Social engineering or other attack vectors
  • ⚠️ Salt discovery (salt bytes might be identifiable in binary)

Recommendations

  • Use for obfuscation and moderate security against casual analysis
  • Significant improvement over plain text storage
  • Salt-based approach hides the actual key from static analysis
  • Combine with other security measures for high-security applications
  • Works consistently across all computers without external dependencies

🀝 Usage Example

Database Connection

program MyApp;
uses LitCrypt;

begin
  // Before
  ConnectionString := 'Server=prod;Password=secret123;';

  // After encryption
  ConnectionString := DecryptString([$53, $32, $33, $76, $32, $33, ...]);
end.

About

Delphi plugin that provides compile-time string encryption

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages