Skip to content

AD2015: EnableHighEntropyVirtualAddresses

Summary

Property Value
ID AD2015
Name EnableHighEntropyVirtualAddresses
Category Security
Severity Error
Applies to PE (Windows) - 64-bit binaries

Description

Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities.

Standard ASLR on 64-bit systems provides about 17 bits of entropy. High entropy ASLR increases this to approximately 24 bits, making brute-force attacks infeasible.

How It Works

The rule checks for the IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag (0x0020) in the PE optional header's DLL characteristics field.

Why This Matters

High-entropy ASLR exponentially increases the difficulty of brute-force attacks against memory layout. The difference between standard and high-entropy ASLR can mean the difference between a successful attack and an impossible one.

The Mathematics of Entropy

ASLR security is measured in bits of entropy:

Configuration Entropy Possible Locations Brute-force at 1000/sec
No ASLR 0 bits 1 Instant
32-bit ASLR ~16 bits ~65,536 ~1 minute
64-bit standard ~17 bits ~131,072 ~2 minutes
64-bit high entropy ~24 bits ~16 million ~4.5 hours
Theoretical max ~47 bits ~140 trillion ~4,400 years

Each additional bit of entropy doubles the attack difficulty.

Why 64-bit Systems Default to Low Entropy

For backward compatibility, 64-bit Windows limits ASLR entropy by default. High-entropy ASLR opts binaries into using the full 64-bit address space, but this requires:

  1. The binary to be marked compatible (/HIGHENTROPYVA)
  2. All pointers to be valid 64-bit values (not truncated)
  3. No assumptions about address ranges

Brute-Force Attack Scenarios

Scenario 1: Local brute-force

Attacker can crash and restart service repeatedly
Standard ASLR: ~65K attempts = minutes to crack
High-entropy: ~16M attempts = impractical in many scenarios

Scenario 2: Network service

Each connection attempt reveals success/failure
Network latency limits to ~100 attempts/sec
High-entropy: ~45 hours average, likely to be noticed

Scenario 3: Combined with info leak

Partial pointer leak gives some bits
High-entropy: Even with leak, more bits remain unknown
Standard: Leak may completely defeat ASLR

Compatibility Considerations

High-entropy ASLR can break code that:

  1. Truncates pointers: int ptr = (int)address; loses high bits
  2. Uses signed comparison: if (ptr1 > ptr2) can fail for high addresses
  3. Stores addresses in 32-bit fields: Database schemas, file formats

Modern 64-bit code should not have these issues. Legacy code may need updates.

Performance Impact

High-entropy ASLR has zero runtime performance impact. The only effect is on where memory is allocated—the CPU doesn't care whether addresses are above or below any threshold.

Combined with Other Mitigations

Mitigation Effect on Attacker
High-entropy ASLR Must find ~24 bits of address
+ CFG Can't call arbitrary addresses
+ CET Can't manipulate returns
Combined Exploitation becomes extremely difficult

Resolution

Enable High Entropy ASLR

Linker flag:

link.exe /HIGHENTROPYVA ...

This is enabled by default for 64-bit binaries in modern Visual Studio. Ensure it's not disabled:

# Explicitly enable
link.exe /HIGHENTROPYVA:YES ...

# Don't do this
link.exe /HIGHENTROPYVA:NO ...

Project Properties

  1. Open Project Properties
  2. Navigate to Linker → Advanced
  3. Set "High Entropy ASLR" to "Yes (/HIGHENTROPYVA)"

CMake

if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
    add_link_options(/HIGHENTROPYVA)
endif()

When to Suppress

This rule may be suppressed for:

  • 32-bit binaries: High entropy ASLR is 64-bit only
  • Large address space requirements: Some applications need predictable addresses
  • Pointer truncation issues: Legacy code that truncates pointers to 32 bits

Caveats

  • Only applies to 64-bit binaries
  • Requires /DYNAMICBASE to also be enabled
  • May break code that assumes addresses fit in 32 bits
  • Third-party libraries must also be compatible

Entropy Comparison

Configuration Entropy Possible Addresses
No ASLR 0 bits 1 (fixed)
Standard ASLR ~17 bits ~131,000
High Entropy ASLR ~24 bits ~16,000,000

Checking Compatibility

Before enabling, verify your code doesn't:

// Bad - truncates 64-bit pointer
DWORD ptr32 = (DWORD)pointer;

// Bad - assumes address fits in 32 bits
struct { DWORD address; } legacy;

// Good - use proper pointer sizes
DWORD_PTR ptr = (DWORD_PTR)pointer;

References