Reverse Engineering for Beginners

(avery) #1

CHAPTER 43. INLINE FUNCTIONS CHAPTER 43. INLINE FUNCTIONS


43.1.5 memcpy().


Short blocks


The routine to copy short blocks is often implemented as a sequence ofMOVinstructions.


Listing 43.15: memcpy() example

void memcpy_7(char inbuf, char outbuf)
{
memcpy(outbuf+10, inbuf, 7);
};


Listing 43.16: Optimizing MSVC 2010

_inbuf$ = 8 ; size = 4
_outbuf$ = 12 ; size = 4
_memcpy_7 PROC
mov ecx, DWORD PTR _inbuf$[esp-4]
mov edx, DWORD PTR [ecx]
mov eax, DWORD PTR _outbuf$[esp-4]
mov DWORD PTR [eax+10], edx
mov dx, WORD PTR [ecx+4]
mov WORD PTR [eax+14], dx
mov cl, BYTE PTR [ecx+6]
mov BYTE PTR [eax+16], cl
ret 0
_memcpy_7 ENDP


Listing 43.17: Optimizing GCC 4.8.1

memcpy_7:
push ebx
mov eax, DWORD PTR [esp+8]
mov ecx, DWORD PTR [esp+12]
mov ebx, DWORD PTR [eax]
lea edx, [ecx+10]
mov DWORD PTR [ecx+10], ebx
movzx ecx, WORD PTR [eax+4]
mov WORD PTR [edx+4], cx
movzx eax, BYTE PTR [eax+6]
mov BYTE PTR [edx+6], al
pop ebx
ret


That’s usually done as follows: 4-byte blocks are copied first, then a 16-bit word (if needed), then the last byte (if needed).


Structures are also copied usingMOV:21.4.1 on page 345.


Long blocks


The compilers behave differently in this case.


Listing 43.18: memcpy() example

void memcpy_128(char inbuf, char outbuf)
{
memcpy(outbuf+10, inbuf, 128);
};


void memcpy_123(char inbuf, char outbuf)
{
memcpy(outbuf+10, inbuf, 123);
};


For copying 128 bytes, MSVC uses a singleMOVSDinstruction (because 128 divides evenly by 4):


Listing 43.19: Optimizing MSVC 2010

_inbuf$ = 8 ; size = 4

Free download pdf