Skip to content

AD6002: EliminateDuplicateStrings

Summary

Property Value
ID AD6002
Name EliminateDuplicateStrings
Category Performance
Severity Warning
Applies to PE (Windows)

Description

This rule checks that PE binaries were compiled with the /GF (Eliminate Duplicate Strings) option enabled. String pooling reduces binary size and can improve performance by ensuring identical string literals share the same memory.

Why This Matters

String pooling is a simple optimization with measurable binary size reduction. Without it, identical string literals are duplicated throughout the binary, wasting memory and reducing cache efficiency.

The Duplication Problem

// File1.c
printf("Error: %s\n", msg);  // "Error: %s\n" stored

// File2.c
printf("Error: %s\n", other); // "Error: %s\n" stored AGAIN

// File3.c
printf("Error: %s\n", val);   // "Error: %s\n" stored AGAIN

// Without /GF: 3 copies of same string
// With /GF: 1 copy, 3 references

Size Impact

Binary Type Typical Savings
Small apps 1-5%
Large apps 3-10%
Localized apps 5-15% (many strings)
Debug builds Often more

Cache Efficiency

Without string pooling:
  0x1000: "Error: %s\n"  (file1.c)
  0x2000: "Error: %s\n"  (file2.c)
  0x3000: "Error: %s\n"  (file3.c)
  Each access may miss cache

With string pooling:
  0x1000: "Error: %s\n"  (all files)
  Single location, stays in cache

Implied by Optimization

String pooling is enabled by optimization flags:

Flag /GF Status
/O1 Implied
/O2 Implied
/Ox Implied
/GF explicit Direct
None Not enabled

Security Consideration

Larger binary:
  - More code/data pages
  - Larger attack surface (more gadgets)
  - Slower load time

Smaller binary (with /GF):
  - Fewer pages
  - Smaller attack surface
  - Faster load

Build Configuration Indicator

Missing /GF often indicates misconfigured release builds:

Expected: Release build with /O2 (implies /GF)
Found: No string pooling

Probable cause:
  - Debug build shipped as release
  - Optimization accidentally disabled
  - Build system misconfiguration
  • Smaller binaries: Duplicate strings are stored only once
  • Cache efficiency: Less memory used for string constants
  • Optimization indicator: /GF is implied by /O1, /O2, and /Ox
  • Release build verification: Helps ensure proper release build configuration

How to Fix

Enable string pooling

cl /GF myapp.c

# Or use optimization flags (implies /GF)
cl /O2 myapp.c

Visual Studio

  1. Project Properties → C/C++ → Code Generation
  2. Set "Enable String Pooling" to "Yes (/GF)"

Or enable optimization which implies string pooling: 1. Project Properties → C/C++ → Optimization 2. Set "Optimization" to "Maximize Speed (/O2)" or "Full Optimization (/Ox)"

CMake

if(MSVC)
    add_compile_options(/GF)
    # Or use Release build type which typically enables /O2
endif()

Detection Method

aldur detects string pooling by examining compiler command lines stored in PDB debug information. The rule looks for: - Explicit /GF flag - Optimization flags that imply /GF: /O1, /O2, /Ox

Example

Warning: String pooling not enabled

Binary was compiled without /GF string pooling.
Consider enabling /GF or using /O2 optimization.

Pass: String pooling enabled

Binary was compiled with string pooling (/GF) enabled.

Relationship with Optimization

Flag String Pooling Notes
/GF ✅ Explicit Directly enables
/O1 ✅ Implied Minimize size
/O2 ✅ Implied Maximize speed
/Ox ✅ Implied Full optimization
/Od Debug, no optimization

See Also