title: Proper way move register values in assembly from one location to another
body: <p>I'm currently having some unexplained register issues which I can't figure my guess is I'm moving registers improperly from one register to another one.</p>
  
  <p>I'm trying to get the value of <code>EDX</code> into a <code>test.myEDX</code> which mostly always puts the wrong value of <code>EDX</code> into <code>test.myEDX</code>, but part of that <code>EDX</code> value seems right which is very strange some kind of Hi/Lo Bits issues I assume.<br></p>
  
  <p>Let me explain what I'm trying to do.<br>
  First I hook a location in memory which contains some arbitrary assembly code.<br></p>
  
  <p>I hook it by placing a hardware breakpoint at that location then I can see all the register values at that location in time.<br>
  Now I made a simple program that everytime the cpu goes into that breakpointed location I put the <code>EDX</code> value into a struct in C++.<br>
  As far as i am aware nothing should modify the <code>EDX</code> register while I am putting it into the struct unless putting values into the struct modifies the <code>EDX</code> which I tested isn't the case, I tested by moving the <code>EDX</code> first into <code>EAX</code> then passing <code>EAX</code> into struct which should have the same value as <code>EDX</code> and it's still wrong maybe <code>EAX</code> is used as well when putting data into the struct? I didn't go further then that in testing all registers to find which one isn't used, doubt that's even the problem anyways.<br></p>
  
  <p>Another thing to take into consideration to actually do any operations like putting <code>EDX</code> into the struct I have to make in C++ the current <code>EIP</code> go into my naked function, I know from previously doing this stuff that naked functions don't modify any registers at all, they are simply used as a way to extend the current asm code at that EIP into much larger asm code without any trash that C++ would add when going into subroutines.</p>
  
  <p>I also use <code>PUSHAD</code> and <code>PUSHFD</code> to restore previously set register values when I finish dumping <code>EDX</code> into struct it's all in a safe environment (as long as I don't use <code>PUSH/POP</code>'s incorrectly of course) before I call <code>POPFD</code> then <code>POPAD</code><br></p>
  
  <p>I barely know any ASM but from looking at many examples I never see registers moved like this. (which obviously wouldn't make any sense to duplicate a register, but even the same register moved into 2 different addresses one after the one I haven't seen that).</p>
  
  <pre><code>MOV EBX, EDX
  MOV ECX, EDX
  </code></pre>
  
  <p>But in fact I see something like this (which I thought was my problem why it wasn't working), (it wasn't, I am still clueless what I am doing wrong)</p>
  
  <pre><code>MOV EBX, EDX 
  MOV EAX, EDX //Theory: in order to move EDX a second time into ECX, I must not move EDX directly into ECX.
  MOV ECX, EAX
  </code></pre>
  
  <p>I don't see any difference except now <code>EAX</code> is lost, but I still figured I have to re-route every multiple moving of the same register to multiple locations by moving it over and over before actually moving to the original location, silly but that's what I thought you had to do I still think this is the proper way to this job.<br>
  Either way this still hasn't helped me I still get wrong values.<br><br></p>
  
  <p>I think either those option's <code>AL</code> <code>BL</code> registers screw up <code>EDX</code> or maybe <code>TEST</code> or <code>JE</code> messes it up I can't really tell, I pasted this code into OllyDBG and seems like nothing modified <code>EDX</code> mystery why <code>EDX</code> is wrong, Maybe the address updates it's value too slow? since it's based on RAM speed which doesn't sync up with CPU speed (all stupid theories of course).</p>
  
  <p>Anyways that's about everything I can explain here is the code.</p>
  
  <pre><code>struct TestStruct {
    int myEDX;
    int mySetEDX;
  } test;
  
  extern bool optionOne = false;
  extern bool optionTwo = false;
  DWORD gotoDumpBackAddress = 0x40012345;
  
  void __declspec( naked ) dump(void) {
      __asm {
          PUSHAD
          PUSHFD
          XOR EAX, EAX //zero EAX, used below as AL (optionOne)
          XOR EBX, EBX //zero EBX, used below as BL (optionTwo)
          MOV AL, optionOne //optionOne set
          MOV BL, optionTwo //optionTwo set
  
          TEST EAX, EAX //Tests if optionOne equals == 0, then je will be equal.
          je gotoOptionOne //Jumps if optionOne equals 0.
          TEST EBX, EBX //Tests if optionTwo equals == 0, then je will be equal.
          je gotoOptionTwo  //Jumps if optionTwo equals 0.
  
  gotoOptionOne:
  //This the default case (improper value in EDX..., I could just use address at [ESI+0x2] which is old EDX, which is risky since it's delayed (outdated)
              MOV DWORD PTR DS:[ESI+0x2], EDX //(normal operation)
              MOV test.myEDX, EDX //Stores freshest EDX to test.myEDX (wrong EDX value)
              JMP finish  //Clear temporary used registers and go back to next asm code
  
  //Special case. (works mostly properly)
  //Thing is EDX gets updated very frequently, Causes no side-effect only because
  //[ESI+0x2] gets updated in a different location as well a bit later to renew the value.
  //So it's not even noticeable, but when I run this at it's peak speeds, you start to see the flickering effect, which isn't normal, if I run peak speeds without hook.
  //I eliminated the problem that the hook could cause the flicker effect since after
  //I call a empty naked Hook with just return address to same location and disable hook
  //Then re-enable hook and repeat step above (no flicker occurs).
  gotoOptionTwo:
              //MOV DWORD PTR DS:[ESI+0x2], EDX //(normal operation), omitted
              MOV EAX, DWORD PTR DS:[ESI+0x2] //Old EDX, but atleast it's correct.
              MOV test.myEDX, EAX //Stores old EDX into struct test.myEDX
              MOV EAX, test.mySetEDX //Replace old EDX with what I wish it should be.
              MOV DWORD PTR DS:[ESI+0x2], EAX //nySetEDX into what EDX should of did.
              JMP finish //Clear temporary used registers and go back to next asm code
  finish:
          POPFD
          POPAD
  
          JMP gotoDumpBackAddress //return to starting location before dump + 1.
  
      }
  }
  </code></pre>
  
  <p><strong>EDIT:</strong> Okay I haven't explained how I test this code out.</p>
  
  <p>I'm not going to explain how I do the Hardware breakpoint, I don't want this method to be public on the internet, for my own security reasons in the future.<br>
  But it works by calling another DLL which communicates with a system driver.</p>
  
  <p>But this should explain how I test it.</p>
  
  <p>I run in a different thread in this DLL Injection.</p>
  
  <pre><code>void diffThread() {
    while(1) {
      if(GetAsyncKeyState(VK_NUMPAD0)) {
        optionOne != optionOne;
        Sleep(1000);
      }
  
      if(GetAsyncKeyState(VK_NUMPAD1)) {
        optionTwo != optionTwo;
        Sleep(1000);
      }
  
      Sleep(10);
    }
  }
  
  bool __stdcall DllMain(HINSTANCE hInst,DWORD uReason,void* lpReserved)
  {
      if(uReason == DLL_PROCESS_ATTACH)
      {
          CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&amp;diffThread,0 ,NULL,NULL); 
      }
      else if(uReason == DLL_PROCESS_DETACH) 
      { 
          ExitThread(0);
      } 
      return true;
  }
  </code></pre>