title: Dumping memory of a function
body: <p>I would like to dump a functions memory (void) to a byte array (<code>unsinged char[]</code>). Aftwerwards, a dummy function shall be pointed to the byte array and the dummy function shall be executed.</p>
  
  <p>The function I want to dump:</p>
  
  <pre><code>void CallMessageBoxExA()
  {
      message = "ManualMessageBoxExA";
      caption = "Caption";
      pAddr = GetProcAddress(GetModuleHandle(L"User32.dll"), "MessageBoxExA");
  
      __asm // Call MessageBoxA
      {
          push dword ptr 0 //--- push languageID: 0
          push dword ptr 0 //--- push style: 0
          push dword ptr caption //--- push DWORD parameter (caption)
          push dword ptr message //--- push DWORD parameter (message)
          push dword ptr 0 //--- push hOwner: 0
          mov eax, pAddr
          call eax //-- call address of the function, which is currently in EAX
      }
  }
  </code></pre>
  
  <p>Dumping the memory:</p>
  
  <pre><code>string DumpMemory(void *pAddress, int maxLength)
  {
      string result = "";
      const unsigned char * p = reinterpret_cast&lt; const unsigned char *&gt;(pAddress);
      cout &lt;&lt; "Memory location: 0x" &lt;&lt; hex &lt;&lt; (unsigned int)p &lt;&lt; endl;
      for (unsigned int i = 0; i &lt; maxLength; i++) {
          string code = "";
          stringstream ss;
          ss &lt;&lt; hex &lt;&lt; int(p[i]);
          ss &gt;&gt; code;
          result += code;
      }
      return result;
  }
  </code></pre>
  
  <p>When looking at the memory location <code>DumpMemory</code> prints to the console, ollydbg shows a JMP instruction at this location:</p>
  
  <pre><code>CPU Disasm
  Address   Hex dump          Command                                  Comments
  00281627   $-/E9 044C0000   JMP CallMessageBoxExA
  </code></pre>
  
  <p>Is this the correct memory-location, or do I have to follow the JMP?</p>
  
  <p>Memory location jump leads to:</p>
  
  <pre><code>CPU Disasm
  Address   Hex dump          Command                                  Comments
  00286230  /$  55            PUSH EBP                                 ; ASM.CallMessageBoxExA(void)
  00286231  |.  8BEC          MOV EBP,ESP
  00286233  |.  81EC C0000000 SUB ESP,0C0
  00286239  |.  53            PUSH EBX
  0028623A  |.  56            PUSH ESI
  0028623B  |.  57            PUSH EDI
  0028623C  |.  8DBD 40FFFFFF LEA EDI,[EBP-0C0]
  00286242  |.  B9 30000000   MOV ECX,30
  00286247  |.  B8 CCCCCCCC   MOV EAX,CCCCCCCC
  0028624C  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
  0028624E  |.  C705 A8562900 MOV DWORD PTR DS:[message],OFFSET 00291D ; ASCII "ManualMessageBoxExA"
  00286258  |.  C705 AC562900 MOV DWORD PTR DS:[caption],OFFSET 00291D ; ASCII "Caption"
  00286262  |.  8BF4          MOV ESI,ESP
  00286264  |.  68 041E2900   PUSH OFFSET 00291E04                     ; ASCII "MessageBoxExA"
  00286269  |.  8BFC          MOV EDI,ESP
  0028626B  |.  68 D01D2900   PUSH OFFSET 00291DD0                     ; /ModuleName = "User32.dll"
  00286270  |.  FF15 00602900 CALL DWORD PTR DS:[&lt;&amp;KERNEL32.GetModuleH ; \KERNEL32.GetModuleHandleW
  00286276  |.  3BFC          CMP EDI,ESP
  00286278  |.  E8 5BB2FFFF   CALL 002814D8                            ; [_RTC_CheckEsp
  0028627D  |.  50            PUSH EAX                                 ; |hModule
  0028627E  |.  FF15 04602900 CALL DWORD PTR DS:[&lt;&amp;KERNEL32.GetProcAdd ; \KERNEL32.GetProcAddress
  00286284  |.  3BF4          CMP ESI,ESP
  00286286  |.  E8 4DB2FFFF   CALL 002814D8                            ; [_RTC_CheckEsp
  0028628B  |.  A3 B0562900   MOV DWORD PTR DS:[pAddr],EAX
  00286290  |.  6A 00         PUSH 0
  00286292  |.  6A 00         PUSH 0
  00286294  |.  FF35 AC562900 PUSH DWORD PTR DS:[caption]
  0028629A  |.  FF35 A8562900 PUSH DWORD PTR DS:[message]
  002862A0  |.  6A 00         PUSH 0
  002862A2  |.  A1 B0562900   MOV EAX,DWORD PTR DS:[pAddr]
  002862A7  |.  FFD0          CALL EAX
  002862A9  |.  5F            POP EDI
  002862AA  |.  5E            POP ESI
  002862AB  |.  5B            POP EBX
  002862AC  |.  81C4 C0000000 ADD ESP,0C0
  002862B2  |.  3BEC          CMP EBP,ESP
  002862B4  |.  E8 1FB2FFFF   CALL 002814D8                            ; [_RTC_CheckEsp
  002862B9  |.  8BE5          MOV ESP,EBP
  002862BB  |.  5D            POP EBP
  002862BC  \.  C3            RETN
  </code></pre>
  
  <p>Pointing the dummy function at the byte array:</p>
  
  <pre><code>void(*func_ptr)();
  func_ptr = (void(*)()) &amp;foo[0]; // make function point to foo[]
  (*func_ptr)(); // Call the function
  </code></pre>
  
  <p>Is this the correct way to make the dummy function point to the byte array?</p>
  
  <p>At which point is the function's end reached? Should I simply check for the different return opcodes (C3 -> return near to caller, CB -> return far to caller, ...)?</p>
  
  <p>PS:
  A simple (e.g. not very elaborate) solution is preferred as I am new to C++. </p>
  
  <p>Edit: I want to achieve this in a Windows environment.</p>