DonationCoder.com forum
 
Read-only archive. This is a static copy of the DonationCoder.com forum. Reading and searching work as before; logging in, posting and private messages do not.
Archive of 2026-10-21 · About this archive · Main site

Author Topic: Why do Windows functions all begin with a pointless MOV EDI, EDI instruction?  (Read 5,298 times)

KynloStephen66515

  • Animated Giffer in Chief
  • Honorary Member
  • Joined in 2010
  • **
  • Posts: 3,772
    • Participated in NANY Challenge Three Times
    • Cody Award
    • Coding Snacks
    • Official Forum Clown
    • Volunteers/Staff
    • Writer
    • Hardware Hacker
    • DJ Badge - DJ
    • Linux User
Quote
If you look at the disassembly of functions inside Windows DLLs, you'll find that they begin with the seemingly pointless instruction MOV EDI, EDI. This instruction copies a register to itself and updates no flags; it is completely meaningless. So why is it there?

It's a hot-patch point.

The MOV EDI, EDI instruction is a two-byte NOP, which is just enough space to patch in a jump instruction so that the function can be updated on the fly. The intention is that the MOV EDI, EDI instruction will be replaced with a two-byte JMP $-5 instruction to redirect control to five bytes of patch space that comes immediately before the start of the function. Five bytes is enough for a full jump instruction, which can send control to the replacement function installed somewhere else in the address space.

Although the five bytes of patch space before the start of the function consists of five one-byte NOP instructions, the function entry point uses a single two-byte NOP.

Why not use Detours to hot-patch the function, then you don't need any patch space at all.

The problem with Detouring a function during live execution is that you can never be sure that at the moment you are patching in the Detour, another thread isn't in the middle of executing an instruction that overlaps the first five bytes of the function. (And you have to alter the code generation so that no instruction starting at offsets 1 through 4 of the function is ever the target of a jump.) You could work around this by suspending all the threads while you're patching, but that still won't stop somebody from doing a CreateRemoteThread after you thought you had successfully suspended all the threads.

Why not just use two NOP instructions at the entry point?

Sauce: https://blogs.msdn.microsoft.com/oldnewthing/20110921-00

Jibz

  • Cold Warrior
  • Developer
  • Joined in 2005
  • ***
  • Posts: 1,187
    • Programming School - Stage 1 Medal
    • Coding Snacks
    • Participated in NANY Challenge Four Times
The specific instruction used here (MOV EDI, EDI) reminded me of a bug I had almost ten years ago with it being used in 64-bit code - for anyone interested I wrote a blog post about it.
"A problem, properly stated, is a problem on it's way to being solved" -Buckminster Fuller
"Multithreading is just one damn thing after, before, or simultaneous with another" -Andrei Alexandrescu

Original address: https://www.donationcoder.com/forum/index.php?topic=45438.0