FNV-1a Algorithm
FNV-1a is a fast, non-cryptographic hash function that produces 32-bit hashes. The implementation uses:- Offset Basis:
0x811c9dc5 - FNV Prime:
0x01000193 - Case Normalization: Converts lowercase ASCII to uppercase (
a-z→A-Z) - 32-bit Output: Suitable for hash table lookups
Algorithm Steps
- Initialize hash to
0x811c9dc5 - For each character:
- Convert lowercase to uppercase (subtract
0x20if>= 'a') - XOR hash with byte value
- Multiply hash by
0x01000193
- Convert lowercase to uppercase (subtract
- Return final 32-bit hash
expr::hash_string()
Compile-time consteval hash function that computes string hashes during compilation.Pointer to null-terminated string. Supports both
char and wchar_t types.Character type - either
char for ANSI strings or wchar_t for Unicode strings.32-bit FNV-1a hash computed at compile-time.
Characteristics
- Compile-Time Evaluation:
constevalkeyword forces computation during compilation - Zero Runtime Cost: Hash values are embedded as constants in the binary
- Template Support: Works with both narrow (
char) and wide (wchar_t) strings - Case-Insensitive: Automatically normalizes ASCII characters to uppercase
Example Usage
Implementation
stardust::hash_string()
Runtime hash function for dynamic string hashing during shellcode execution.Pointer to null-terminated string to hash. Supports
char and wchar_t.Character type -
char for ANSI or wchar_t for Unicode strings.32-bit FNV-1a hash computed at runtime.
Characteristics
- Runtime Evaluation: Computed during shellcode execution
- Section Attribute:
declfnplaces function in.text$Bsection - Dynamic Input: Can hash strings from memory, PEB structures, or user input
- Identical Algorithm: Produces same hashes as
expr::hash_string()
Example Usage
Implementation
The
declfn attribute (__attribute__((section(".text$B")))) ensures the function is placed in the correct position-independent code section during linking.Compile-Time vs Runtime
| Feature | expr::hash_string() | stardust::hash_string() |
|---|---|---|
| Evaluation | Compile-time (consteval) | Runtime (inline) |
| Use Case | Static string literals | Dynamic strings from memory |
| Performance | Zero runtime cost | Fast runtime computation |
| Placement | Embedded as constants | .text$B section |
| Typical Usage | Macro expansions, API lookups | PEB iteration, export parsing |
When to Use Each
Useexpr::hash_string() when:
- Hashing known string literals at compile time
- Working with
RESOLVE_API()orRESOLVE_TYPE()macros - Initializing constant hash values
stardust::hash_string() when:
- Hashing strings from PEB structures
- Parsing PE export tables
- Processing dynamic or runtime-provided strings
Hash Collision Considerations
Collision Probability
With a 32-bit hash space and ~2,000 exported functions per typical Windows DLL:- Collision probability: ~0.0005% per DLL
- Mitigation: Hashing algorithm includes case normalization
- Best Practice: Test hash uniqueness in your target environment
