Skip to content

AD6005: EnableOptimizeReferences

Summary

Property Value
ID AD6005
Name EnableOptimizeReferences
Category Performance
Severity Warning
Applies to PE (Windows)

Description

This rule checks that PE binaries were linked with reference optimization (/OPT:REF) enabled. This linker option removes unreferenced functions and data (dead code elimination), reducing binary size and attack surface.

Why This Matters

Reference optimization removes unreferenced code and data, directly reducing attack surface. Dead code that's never called can still contain vulnerabilities and ROP gadgets that attackers can exploit.

Dead Code Security Risk

// Old debugging function, no longer called
void debug_dump_all() {
    // Contains buffer overflow vulnerability
    // Never called in production
    // BUT: Still in binary without /OPT:REF
    // Still provides ROP gadgets
}

// With /OPT:REF: Function removed entirely
// Without /OPT:REF: Vulnerability ships in production

Attack Surface Reduction

Component Without /OPT:REF With /OPT:REF
Functions All compiled Only referenced
Data All included Only referenced
Gadgets Maximum Reduced
Binary size Larger Smaller

What Gets Removed

Unreferenced functions:
  - Old API compatibility shims
  - Debug-only functions in release
  - Unreachable error handlers
  - Dead library code

Unreferenced data:
  - Unused string tables
  - Old configuration data
  - Debug symbols

Size Impact

Binary Type Typical Reduction
Small apps 5-15%
Libraries 10-30%
Large apps 5-20%
Static linked 20-50%

Security-Relevant Dead Code

Common sources of dead code with security implications:

1. Test/debug functions accidentally included
2. Old API versions kept for "compatibility"
3. Unreachable error paths with vulnerabilities
4. Library functions never actually called
5. Disabled features still compiled

Combined with ICF

Best results come from both optimizations:

link /OPT:REF /OPT:ICF myapp.obj

/OPT:REF → Removes unreferenced code
/OPT:ICF → Merges identical remaining code

Result: Minimal, optimized binary
  • Smaller binaries: Unused code and data are removed
  • Reduced attack surface: Less code means fewer potential vulnerabilities
  • Security: Eliminates unreachable code that may contain security issues
  • Release build indicator: /OPT:REF should be enabled for release builds

How to Fix

Enable reference optimization

# Link with REF enabled
link /OPT:REF myapp.obj

# Full release optimization (both REF and ICF)
link /OPT:REF /OPT:ICF myapp.obj

Disable incremental linking (required)

Reference optimization is incompatible with incremental linking:

link /INCREMENTAL:NO /OPT:REF myapp.obj

Visual Studio

  1. Project Properties → Linker → Optimization
  2. Set "References" to "Yes (/OPT:REF)"
  3. Ensure "Link Incrementally" is set to "No (/INCREMENTAL:NO)"

CMake

if(MSVC)
    set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /OPT:REF")
endif()

Detection Method

aldur detects reference optimization availability by checking for the .textbss section. This section is created by incremental linking and indicates that /OPT:REF is disabled.

Example

Warning: Reference optimization not enabled

Binary appears to use incremental linking (.textbss section present).
Dead code elimination is disabled. Link with /INCREMENTAL:NO /OPT:REF for release builds.

Pass: Reference optimization available

Binary does not use incremental linking. Dead code elimination (/OPT:REF) is available.

What Gets Removed

With /OPT:REF enabled, the linker removes: - Functions that are never called - Global variables that are never referenced - Static data that is unused - COMDAT sections with no references

Preserving Specific Symbols

If you need to keep specific symbols that appear unused:

// Use pragma to prevent removal
#pragma comment(linker, "/INCLUDE:_my_required_symbol")

// Or use __declspec
__declspec(dllexport) void my_required_function() { }

See Also