We have a post build step which modifies (patches) some locations in the executable. The patching process loads the process in the memory using CreateProcess
and reads its code segment memory using ReadProcessMemory
. Then a sequence 0x8D, 0x05, XX, XX, XX, XX, MAGIC
is searched in the memory, and the file is modified on the corresponding offset to contain a different code. The offset into the file is computed as the address of the instruction in the process memory space minus preferred load address of the exe. The exe is marked as /BASE:"0x400000" /DYNAMICBASE:NO /FIXED (no address randomization, no relocation).
The works fine with executables produced with VS 2005, however it fails when the exe is built using VS 2010. The sequence in the memory is found, but the content of the file at corresponding offset does not match. When searching the binary file, the corresponding code can be found 0xc00 earlier in the file.
When comparing the command lines, I can see there is /OPT:WIN98 used for VS 2005 which is missing for VS 2010 and seems not to be supported by the linker any more.
Now my question is:
It seems exe produced with /OPT:WIN98 has a slightly larger header (aligned to 4 KB). When this flag is not specified, the code is still loaded from 0x401000, but the header is only 0x400 instead of 0x1000, resulting in the image offset of 0xc00.