Last active
May 26, 2016 22:44
-
-
Save jmoyers/b76cc8e9dbf122b60cab515025d7bb76 to your computer and use it in GitHub Desktop.
memcpy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 00F61000 push ebp ; save base pointer | |
// 00F61001 mov ebp, esp ; create new stack frame | |
// 00F61003 sub esp, 10h ; give me 16 bytes (2 x 8 byte struct) | |
// 00F61006 mov dword ptr[ebp - 8], 0FFh ; store 0xff into first 8 bytes on stack (a.v1) | |
// 00F6100D push 8 ; param 3: push 8 onto the stack (sizeof struct) | |
// 00F6100F lea eax, [ebp - 8] ; eax = address of start of a | |
// 00F61012 push eax ; param 2: push the address of "a" onto stack | |
// 00F61013 lea ecx, [ebp - 10h] ; ecx = address of start of b | |
// 00F61016 push ecx ; param 1: push address of "b" onto the stack | |
// 00F61017 call 00F62716 ; call memcpy -- we'll grab asm and put below | |
// 00F6101C add esp, 0Ch ; destroy the 3 parameter on stack (12 bytes) | |
// 00F6101F xor eax, eax ; clear eax for return | |
// 00F61021 mov esp, ebp ; destroy the rest of our local stack frame | |
// 00F61023 pop ebp ; restore previous stack frame | |
// 00F61024 ret | |
// memcpy jumps to a list of jumps, then here: | |
// (destination = 4, source = 4, size = 4) | |
// Stack: | |
// higher addresses | |
// arg3: size 0x14 | |
// arg2: source 0x10 | |
// arg1: destination 0x0C | |
// saved eip 0x08 | |
// saved edi 0x04 | |
// saved esi 0x00 <-- esp | |
// lower addresses | |
// | |
// 6E5C4C40 push edi ; callee save edi, matched by pops | |
// 6E5C4C41 push esi ; callee save esi | |
// 6E5C4C42 mov esi, dword ptr[esp + 10h] ; esi = address of source | |
// 6E5C4C46 mov ecx, dword ptr[esp + 14h] ; ecx = 8 (size) | |
// 6E5C4C4A mov edi, dword ptr[esp + 0Ch] ; edi = address of destination | |
// 6E5C4C4E mov eax, ecx ; eax = 8 (size) | |
// 6E5C4C50 mov edx, ecx ; edx = 8 (size) | |
// 6E5C4C52 add eax, esi ; eax = address of destination + 8 | |
// 6E5C4C54 cmp edi, esi ; destination (edi) - souce (esi) = edi is lower | |
// 6E5C4C56 jbe 6E5C4C60 ; jump if below or equal = will jump | |
// 6E5C4C58 cmp edi, eax | |
// 6E5C4C5A jb 6E5C4EF4 | |
// 6E5C4C60 cmp ecx, 20h ; 8 (ecx) - 32 (0x20), size is < 32 bytes | |
// 6E5C4C63 jb 6E5C513B ; jump if below = will jump -- "next chunk" below | |
// 6E5C4C69 cmp ecx, 80h ; speculation, behavior is diff >= 128 bytes | |
// 6E5C4C6F jae 6E5C4C84 | |
// 6E5C4C71 bt dword ptr ds : [6E5D7060h], 1 | |
// 6E5C4C79 jb 6E5C510D | |
// 6E5C4C7F jmp 6E5C4E67 | |
// 6E5C4C84 bt dword ptr ds : [6E5D736Ch], 1 | |
// 6E5C4C8C jae 6E5C4C97 | |
// 6E5C4C8E rep movs byte ptr es : [edi], byte ptr[esi] | |
// 6E5C4C90 mov eax, dword ptr[esp + 0Ch] | |
// 6E5C4C94 pop esi | |
// 6E5C4C95 pop edi | |
// 6E5C4C96 ret | |
// Next chunk - note from a different run, addresses are different | |
// 50B9513B and ecx, 1Fh ; 0000 1000 & 0001 1111 = 0000 1000 | |
// 50B9513E je 50B95170 ; it does nothing if size = 0 or > 31 bytes | |
// ; looks like sanity check for 0 byte copy | |
// 50B95140 mov eax, ecx ; eax = 8 | |
// 50B95142 shr ecx, 2 ; 8 / 4 = 2, setup for 4 byte copy per count | |
// 50B95145 je 50B95156 ; if there are no 4 byte chunks, go copy 1 byte per | |
// 50B95147 mov edx, dword ptr[esi] ; edx = actual source (4 bytes) -- start copy loop | |
// 50B95149 mov dword ptr[edi], edx ; [edi] (destination), so 4 byte copy complete | |
// 50B9514B add edi, 4 ; edi = destination + 4 | |
// 50B9514E add esi, 4 ; esi = source + 4 | |
// 50B95151 sub ecx, 1 ; ecx = size - 1 = 1, next iter = 0, 8 bytes total | |
// 50B95154 jne 50B95147 ; if we're not done, loop copy next 4 bytes | |
// 50B95156 mov ecx, eax ; move original size into ecx (8) | |
// 50B95158 and ecx, 3 ; 0000 1000 & 0000 0011 = 0 | |
// 50B9515B je 50B95170 ; yes, we're equal, skip to return | |
// 50B9515D mov al, byte ptr[esi] ; al = 1 byte out of source | |
// 50B9515F mov byte ptr[edi], al ; copy al into destination | |
// 50B95161 inc esi ; source + 1 | |
// 50B95162 inc edi ; destination + 1 | |
// 50B95163 dec ecx ; count - 1 | |
// 50B95164 jne 50B9515D ; if count is zero, end | |
// 50B95166 lea esp, [esp] | |
// 50B9516D lea ecx, [ecx] | |
// 50B95170 mov eax, dword ptr[esp + 0Ch] ; prepare return, eax = destionation address | |
// 50B95174 pop esi ; callee save register restore | |
// 50B95175 pop edi ; callee save register restore | |
// 50B95176 ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment