Reverse Engineering for Beginners

(avery) #1

CHAPTER 37. CRC32 CALCULATION EXAMPLE CHAPTER 37. CRC32 CALCULATION EXAMPLE


and ebx, 255 ; EBX = hash & 0xff

; XOR EDI, EBX (EDI=EDI^EBX) - this operation uses all 32 bits of each register
; but other bits (8-31) are cleared all time, so its OK'
; these are cleared because, as for EDI, it was done by MOVZX instruction above
; high bits of EBX was cleared by AND EBX, 255 instruction above (255 = 0xff)


xor edi, ebx

; EAX=EAX>>8; bits 24-31 taken "from nowhere" will be cleared
shr eax, 8


; EAX=EAX^crctab[EDI4] - choose EDI-th element from crctab[] table
xor eax, DWORD PTR _crctab[edi
4]
inc ecx ; i++
cmp ecx, edx ; i<len?
jb SHORT $LL3@crc ; yes
pop edi
pop esi
pop ebx
$LN1@crc:
ret 0
_crc ENDP


Let’s try the same in GCC 4.4.1 with-O3option:


public crc
crc proc near


key = dword ptr 8
hash = dword ptr 0Ch


push ebp
xor edx, edx
mov ebp, esp
push esi
mov esi, [ebp+key]
push ebx
mov ebx, [ebp+hash]
test ebx, ebx
mov eax, ebx
jz short loc_80484D3
nop ; padding
lea esi, [esi+0] ; padding; works as NOP (ESI does not changing here)

loc_80484B8:
mov ecx, eax ; save previous state of hash to ECX
xor al, [esi+edx] ; AL=(key+i)
add edx, 1 ; i++
shr ecx, 8 ; ECX=hash>>8
movzx eax, al ; EAX=
(key+i)
mov eax, dword ptr ds:crctab[eax*4] ; EAX=crctab[EAX]
xor eax, ecx ; hash=EAX^ECX
cmp ebx, edx
ja short loc_80484B8


loc_80484D3:
pop ebx
pop esi
pop ebp
retn
crc endp
\


GCC has aligned the loop start on a 8-byte boundary by addingNOPandlea esi, [esi+0](that is anidle operationtoo).
Read more about it in npad section (88 on page 854).

Free download pdf