Skip to content

Instantly share code, notes, and snippets.

@jmoyers
Last active May 26, 2016 22:44
Show Gist options
  • Save jmoyers/b76cc8e9dbf122b60cab515025d7bb76 to your computer and use it in GitHub Desktop.
Save jmoyers/b76cc8e9dbf122b60cab515025d7bb76 to your computer and use it in GitHub Desktop.
memcpy
// 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