Функция расчета
хеша MD5 на Ассемблере. Готовых решений на FASM как всегда не было, пришлось портировать из MASM. Для работы процедуры в сегменте .data надо подготовить следующие данные:
; Сегмент данных
section '.data' data readable writeable
...
; Шаблоны функции wsprintf для перевода хеша в строковый вид,
; при необходимости можно оставить только какой-нибудь один
szMD5Format1 db '%.8X%.8X%.8X%.8X',0 ; Для получения заглавных букв
szMD5Format2 db '%.8x%.8x%.8x%.8x',0 ; Для маленьких букв в строке хеша
stMD5Result:
stdtA dd ? ; Переменные для получения и хранения
stdtB dd ? ; результата хеширования
stdtC dd ?
stdtD dd ?
stMD5Hash rb 33 ; Буфер для строки хеша в формате ASCIIZ
А вот собственно сама процедура хеширования и пример использования:
;-------------------------------------------------------
; Процедура расчета хеша MD5
; На входе:
; dta, dtb, dtc, dtd - начальные значения MD5, по умолчанию = 0
; ptBuffer - указатель на буфер от которого считается хеш
; dtBufferLength - длина буфера в байтах
; На выходе:
; Заполненные переменные stdtA, stdtB, stdtC, stdtD
;-------------------------------------------------------
proc procMD5hash dta, dtb, dtc, dtd, ptBuffer, dtBufferLength
push eax ebx ecx edx edi esi
; phase I - padding
mov edi,[ptBuffer]
mov eax,[dtBufferLength]
inc eax
add edi,eax
mov byte [edi-1],080h
xor edx,edx
mov ebx,64
div ebx
neg edx
add edx,64
cmp edx,8
jae @f
add edx,64
@@:
mov ecx,edx
xor al,al
rep stosb
mov eax,[dtBufferLength]
inc edx
add [dtBufferLength],edx
xor edx,edx
mov ebx,8
mul ebx
mov dword [edi-8],eax
mov dword [edi-4],edx
mov edx,[dtBufferLength]
mov edi,[ptBuffer]
; phase II - chaining variables initialization
mov [stdtA],067452301h
mov [stdtB],0efcdab89h
mov [stdtC],098badcfeh
mov [stdtD],010325476h
; phase III - hashing
hashloop:
mov eax,[stdtA]
mov [dta],eax
mov eax,[stdtB]
mov [dtb],eax
mov eax,[stdtC]
mov [dtc],eax
mov eax,[stdtD]
mov [dtd],eax
stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+00*4],07,0d76aa478h
mov [dta],eax
stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+01*4],12,0e8c7b756h
mov [dtd],eax
stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+02*4],17,0242070dbh
mov [dtc],eax
stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+03*4],22,0c1bdceeeh
mov [dtb],eax
stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+04*4],07,0f57c0fafh
mov [dta],eax
stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+05*4],12,04787c62ah
mov [dtd],eax
stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+06*4],17,0a8304613h
mov [dtc],eax
stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+07*4],22,0fd469501h
mov [dtb],eax
stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+08*4],07,0698098d8h
mov [dta],eax
stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+09*4],12,08b44f7afh
mov [dtd],eax
stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+10*4],17,0ffff5bb1h
mov [dtc],eax
stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+11*4],22,0895cd7beh
mov [dtb],eax
stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+12*4],07,06b901122h
mov [dta],eax
stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+13*4],12,0fd987193h
mov [dtd],eax
stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+14*4],17,0a679438eh
mov [dtc],eax
stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+15*4],22,049b40821h
mov [dtb],eax
; round 2
stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+01*4],05,0f61e2562h
mov [dta],eax
stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+06*4],09,0c040b340h
mov [dtd],eax
stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+11*4],14,0265e5a51h
mov [dtc],eax
stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+00*4],20,0e9b6c7aah
mov [dtb],eax
stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+05*4],05,0d62f105dh
mov [dta],eax
stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+10*4],09,002441453h
mov [dtd],eax
stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+15*4],14,0d8a1e681h
mov [dtc],eax
stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+04*4],20,0e7d3fbc8h
mov [dtb],eax
stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+09*4],05,021e1cde6h
mov [dta],eax
stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+14*4],09,0c33707d6h
mov [dtd],eax
stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+03*4],14,0f4d50d87h
mov [dtc],eax
stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+08*4],20,0455a14edh
mov [dtb],eax
stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+13*4],05,0a9e3e905h
mov [dta],eax
stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+02*4],09,0fcefa3f8h
mov [dtd],eax
stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+07*4],14,0676f02d9h
mov [dtc],eax
stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+12*4],20,08d2a4c8ah
mov [dtb],eax
; round 3
stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+05*4],04,0fffa3942h
mov [dta],eax
stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+08*4],11,08771f681h
mov [dtd],eax
stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+11*4],16,06d9d6122h
mov [dtc],eax
stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+14*4],23,0fde5380ch
mov [dtb],eax
stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+01*4],04,0a4beea44h
mov [dta],eax
stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+04*4],11,04bdecfa9h
mov [dtd],eax
stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+07*4],16,0f6bb4b60h
mov [dtc],eax
stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+10*4],23,0bebfbc70h
mov [dtb],eax
stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+13*4],04,0289b7ec6h
mov [dta],eax
stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+00*4],11,0eaa127fah
mov [dtd],eax
stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+03*4],16,0d4ef3085h
mov [dtc],eax
stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+06*4],23,004881d05h
mov [dtb],eax
stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+09*4],04,0d9d4d039h
mov [dta],eax
stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+12*4],11,0e6db99e5h
mov [dtd],eax
stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+15*4],16,01fa27cf8h
mov [dtc],eax
stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+02*4],23,0c4ac5665h
mov [dtb],eax
; round 4
stdcall II,[dta],[dtb],[dtc],[dtd],dword [edi+00*4],06,0f4292244h
mov [dta],eax
stdcall II,[dtd],[dta],[dtb],[dtc],dword [edi+07*4],10,0432aff97h
mov [dtd],eax
stdcall II,[dtc],[dtd],[dta],[dtb],dword [edi+14*4],15,0ab9423a7h
mov [dtc],eax
stdcall II,[dtb],[dtc],[dtd],[dta],dword [edi+05*4],21,0fc93a039h
mov [dtb],eax
stdcall II,[dta],[dtb],[dtc],[dtd],dword [edi+12*4],06,0655b59c3h
mov [dta],eax
stdcall II,[dtd],[dta],[dtb],[dtc],dword [edi+03*4],10,08f0ccc92h
mov [dtd],eax
stdcall II,[dtc],[dtd],[dta],[dtb],dword [edi+10*4],15,0ffeff47dh
mov [dtc],eax
stdcall II,[dtb],[dtc],[dtd],[dta],dword [edi+01*4],21,085845dd1h
mov [dtb],eax
stdcall II,[dta],[dtb],[dtc],[dtd],dword [edi+08*4],06,06fa87e4fh
mov [dta],eax
stdcall II,[dtd],[dta],[dtb],[dtc],dword [edi+15*4],10,0fe2ce6e0h
mov [dtd],eax
stdcall II,[dtc],[dtd],[dta],[dtb],dword [edi+06*4],15,0a3014314h
mov [dtc],eax
stdcall II,[dtb],[dtc],[dtd],[dta],dword [edi+13*4],21,04e0811a1h
mov [dtb],eax
stdcall II,[dta],[dtb],[dtc],[dtd],dword [edi+04*4],06,0f7537e82h
mov [dta],eax
stdcall II,[dtd],[dta],[dtb],[dtc],dword [edi+11*4],10,0bd3af235h
mov [dtd],eax
stdcall II,[dtc],[dtd],[dta],[dtb],dword [edi+02*4],15,02ad7d2bbh
mov [dtc],eax
stdcall II,[dtb],[dtc],[dtd],[dta],dword [edi+09*4],21,0eb86d391h
mov [dtb],eax
mov eax,[dta]
add [stdtA],eax
mov eax,[dtb]
add [stdtB],eax
mov eax,[dtc]
add [stdtC],eax
mov eax,[dtd]
add [stdtD],eax
add edi,64
sub edx,64
jnz hashloop
; phase IV - results
mov ecx,4
mov esi,stMD5Result
@@:
mov eax,dword [esi]
xchg al,ah
rol eax,16
xchg al,ah
mov dword [esi],eax
add esi,4
loop @b
pop esi edi edx ecx ebx eax
ret
endp
; Вспомогательная функция
proc FF var1,var2,var3,var4,x,s,t
; a = b + ((a + F(b,c,d) + x + t) << s )
push ebx ecx
mov eax,[var2]
mov ebx,[var3]
mov ecx,[var4]
; F(x,y,z) = (x and y) or ((not x) and z)
and ebx,eax
not eax
and eax,ecx
or eax,ebx
add eax,[var1]
add eax,[x]
add eax,[t]
mov ecx,[s]
rol eax,cl
add eax,[var2]
pop ecx ebx
ret
endp
; Вспомогательная функция
proc GG var1,var2,var3,var4,x,s,t
push ebx ecx
; a = b + ((a + G(b,c,d) + x + t) << s)
mov eax,[var2]
mov ebx,[var3]
mov ecx,[var4]
; G(x,y,z) = (x and z) or (y and (not z))
and eax,ecx
not ecx
and ecx,ebx
or eax,ecx
add eax,[var1]
add eax,[x]
add eax,[t]
mov ecx,[s]
rol eax,cl
add eax,[var2]
pop ecx ebx
ret
endp
; Вспомогательная функция
proc HH var1,var2,var3,var4,x,s,t
push ebx ecx
; a = b + ((a + H(b,c,d) + x + t) << s)
mov eax,[var2]
mov ebx,[var3]
mov ecx,[var4]
; H(x,y,z) = x xor y xor z
xor eax,ebx
xor eax,ecx
add eax,[var1]
add eax,[x]
add eax,[t]
mov ecx,[s]
rol eax,cl
add eax,[var2]
pop ecx ebx
ret
endp
; Вспомогательная функция
proc II var1,var2,var3,var4,x,s,t
push ebx ecx
; a = b + ((a + I(b,c,d) + x + t) << s)
mov eax,[var2]
mov ebx,[var3]
mov ecx,[var4]
; I(x,y,z) = y xor (x or (not z))
not ecx
or eax,ecx
xor eax,ebx
add eax,[var1]
add eax,[x]
add eax,[t]
mov ecx,[s]
rol eax,cl
add eax,[var2]
pop ecx ebx
ret
endp
Пример использования:
; Сегмент данных
section '.data' data readable writeable
...
somedata db 'Yeah! I like Flat Assembler!',0 ; Исходные данные для хеширования
; Сегмент кода
section '.code' code readable executable
...
; Расчет длины строки. Для бинарных данных lstrlen лучше не использовать
invoke lstrlen,somedata
; Расчет MD5
stdcall procMD5hash,0,0,0,0,somedata,eax
; Перевод в строку, буквы заглавные
invoke wsprintf,stMD5Hash,szMD5Format1,[stdtA],[stdtB],[stdtC],[stdtD]
...
В результате выполнения приведенного пример в буфере stMD5Hash будет строка хеша MD5 "
475023083BE370BCC9CBE9C300EA3D4A" в формате ASCIIZ. В приложении пример программы, считающей хеш MD5 от введенной строки.