The solution is that the option is embedded in the PE binary header. But rather than
loadedImage.FileHeader.FileHeader.Characteristics
it's in:
loadedImage.FileHeader.OptionalHeader.DllCharacteristics
Where you set the flag:
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040; //The DLL can be relocated at load time.
For a helper function pseudo-code of:
void SetPEOptFlags(String filename, UInt32 flags)
{
// Any code is released into the public domain. No attribution required.
LOADED_IMAGE li;
MapAndLoad(filename, null, li, false, false);
li.FileHeader.OptionalHeader.DllCharacteristics |= flags;
UnMapAndLoad(li);
}
and then calling
//Optional dll characteristics
const IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040; //The DLL can be relocated at load time.
const IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100; //The image is compatible with data execution prevention (DEP).
SetPEOptFlags("C:\Foo\Contoso.exe",
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT);