Skip to content

Comment on Why do Windows functions all begin with a pointless MOV EDI, EDI instruction?

Comments

Okay I have two questions that might be very clueless but I don't know the answer to them so I will ask them anyway.

1) In the comments Raymond says, "Hot-patching is not an application feature. It's an OS internal feature for servicing." Then why does the compiler put hot-patch points in my code? Why not use a special compiler flag when building Windows DLLs?

2) Why do we need a special hot-patch point at all? What's wrong with just overwriting the first few bytes of the function you want to hot-patch?

Having a hot-patch point avoids race conditions when overwriting the code. The patch target needs to be 1 instruction, so that any OS threads executing that code either see the old instruction (and run the unpatched code), or the new instruction (and run patched code), and never some mishmash of pre-patch and post-patch instructions.

(It also needs to be possible to overwrite the patch target with 1 instruction, which isn't possible for a far JMP as they are 5 bytes in length.)

1) I didn't see anything that suggested that all DLL functions have this hot-patch point. I think from his perspective "Windows DLL" means "a DLL that is part of the Windows operating system", not "a DLL used by an application executing on Windows".

2) I think he addressed this - someone might be executing the function while you are trying to patch it. Having a 2-byte, one clock cycle NOP at the front means that you can replace it "atomically" from the perspective that nobody can walk into the middle of you updating the memory.

Thanks! Re 1), it does seem to be a compiler switch /hotpatch, not the default behavior.

For one thing, you can't just scoop out 2-5 bytes, replace them with a jump, and assume that things will work. Detours, the alternative to wired-in hot patch points, includes a small disassembler that ensures it's working on instruction boundaries. Detours is significantly more complex than the patching strategy Chen outlined.

About 2: You would have to copy the overwritten bytes to another place in memory to execute them later. As the length of x86 instructions is not fixed you would need a whole disassembler to find out what bytes belong to what instruction. Easier to have just two bytes you can overwrite at will. Saves the hassle of calculating how many bytes you need to copy.

I actually don't know how Windows hot-patching works, but I'd assume they'd just replace the whole function. You wouldn't need to execute the replaced bytes (like you do in Detours, which is usually hooking functions, not replacing them).

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.