it seems that around since w10 build 15007 format of rfg relocs was changed and field IMAGE_DYNAMIC_RELOCATION_TABLE.Version now has value 2. So lets install platform SDK for 15003 and see what was changed
First remarkable thing is that IMAGE_LOAD_CONFIG_DIRECTORY now has two additional fields:
and we can also find declaration for yet several rfg related structs:
So how it look all together (sample was taken from ImagingDevices.exe):
load_config
rfg relocs in .reloc section at offset 0x30:
yep, it seems that body of prolog now stored in IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER after PrologueByteCount field. I have no idea why it was done bcs you anyway restricted with free space in prolog of each function
First remarkable thing is that IMAGE_LOAD_CONFIG_DIRECTORY now has two additional fields:
WORD DynamicValueRelocTableSection;
WORD Reserved2;
// since w10 build 15003 ?
ULONGLONG GuardRFVerifyStackPointerFunctionPointer; // VA
DWORD HotPatchTableOffset;
} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
so sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) is now 0xf4
and we can also find declaration for yet several rfg related structs:
typedef struct _IMAGE_DYNAMIC_RELOCATION64_V2 {
DWORD HeaderSize;
DWORD FixupInfoSize;
ULONGLONG Symbol;
DWORD SymbolGroup;
DWORD Flags;
// ... variable length header fields
// BYTE FixupInfo[FixupInfoSize]
} IMAGE_DYNAMIC_RELOCATION64_V2, *PIMAGE_DYNAMIC_RELOCATION64_V2;
typedef struct _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER {
BYTE PrologueByteCount;
// BYTE PrologueBytes[PrologueByteCount];
} IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER;
typedef IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER UNALIGNED *PIMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER;
typedef struct _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER {
DWORD EpilogueCount;
BYTE EpilogueByteCount;
BYTE BranchDescriptorElementSize;
WORD BranchDescriptorCount;
// BYTE BranchDescriptors[...];
// BYTE BranchDescriptorBitMap[...];
} IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER;
typedef IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER UNALIGNED *PIMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER;
So how it look all together (sample was taken from ImagingDevices.exe):
load_config
.rdata:0000000140003100 dq 0 ; lc + c0 - DynamicValueRelocTable
.rdata:0000000140003108 dq 0 ; CHPEMetadataPointer
.rdata:0000000140003110 dq offset __guard_ss_verify_failure
.rdata:0000000140003118 dq offset __guard_ss_verify_failure_fptr
.rdata:0000000140003120 dd 30h ; lc + e0 - DynamicValueRelocTableOffset
.rdata:0000000140003124 dd 6 ; lc + e4 - DynamicValueRelocTableSection
.rdata:0000000140003128 dq offset __guard_ss_verify_sp_fptr
rfg relocs in .reloc section at offset 0x30:
.reloc:0000000140019030 dd 2 ; version
.reloc:0000000140019034 dd 0BFh ; size
.reloc:0000000140019038 dd 22h ; HeaderSize
.reloc:000000014001903C dd 3Ch ; FixupInfoSize
.reloc:0000000140019040 dq 1 ; Symbol - 1 - prolog
.reloc:0000000140019048 dd 1 ; SymbolGroup
.reloc:000000014001904C dd 0 ; Flags
.reloc:0000000140019050 db 9 ; PrologueByteCount
.reloc:0000000140019051 ; ---------------------------------------------------------------------------
.reloc:0000000140019051 db 66h ; body of prolog
.reloc:0000000140019051 nop
.reloc:0000000140019053 nop dword ptr [rax+00000000h]
.reloc:0000000140019053 ; ---------------------------------------------------------------------------
.reloc:000000014001905A dd 1000h ; va of rfg fixup block
.reloc:000000014001905E dd 24h ; sizeofblock
.reloc:0000000140019062 dw 0
.reloc:0000000140019064 dw 13Ch
.reloc:0000000140019066 dw 2ACh
.reloc:0000000140019068 dw 6F0h
.reloc:000000014001906A dw 0A00h
.reloc:000000014001906C dw 0AF0h
.reloc:000000014001906E dw 0B54h
.reloc:0000000140019070 dw 0DD0h
.reloc:0000000140019072 dw 0E40h
.reloc:0000000140019074 dw 0EA0h
.reloc:0000000140019076 dw 0ED8h
.reloc:0000000140019078 dw 0F44h
.reloc:000000014001907A dw 0FB0h
.reloc:000000014001907C dw 0FD0h
.reloc:000000014001907E dd 2000h ; va of next rfg fixup block
.reloc:0000000140019082 dd 18h ; sizeofblock
yep, it seems that body of prolog now stored in IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER after PrologueByteCount field. I have no idea why it was done bcs you anyway restricted with free space in prolog of each function