首页
社区
课程
招聘
[旧帖] [原创]汇编写Hash工具(MD5和SHA1),附源码 0.00雪花
发表于: 2014-7-9 19:02 2489

[旧帖] [原创]汇编写Hash工具(MD5和SHA1),附源码 0.00雪花

2014-7-9 19:02
2489
断断续续写了几个月的Hash工具,当时学习Win32汇编和熟悉算法的实践,想来自己一直一个人单干,也不知写得怎么样,如有错漏,请海涵指出,不胜感激。

源文件夹结构
Common里面就是放包含的文件以及各个段
Verify里面是Md5和SHA1,每组计算用的算法
Hash.asm是基本的消息流程
_MessageDeal.asm是一堆子程序,其实是Hash.asm使用的
_Thread.asm这个是负责计算的工作者线程,这个最苦逼了,修修改改改了不下10遍还是不满意,没有想到好的编写结构,不过怎么复杂,有一部分是为了兼容大文件的,继而使用内存映射文件,所以又要分段映射,除此此外,为了显示进度条,还要由这个子程序通知主窗口更新进度条……所以越写越长。
manifest.txt这个应该算是一个特殊的资源文件,加入以后就可以使用Visual Styles,而非很丑的经典风格,附上使用说明http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb773175(v=vs.85).aspx 要在汇编中使用,特别注意要先用invoke InitCommonControls,否则程序会自动退出
_CmdLine.asm这个是老罗写好的命令行解析,我直接拿来用了,所以本工具也是支持命令行的,另外为了实现添加右键菜单,也用到了带参数运行。

数据结构
INHASH                STRUCT
lpFiledir  dd ?                  ;文件名指针
bList       dd ?                 ;计算哪些值,这里偷懒,每8位标志一个哈希值是否计算
lpObject   dd ?                 ;事件句柄,用来停止
hWnd      dd ?                 ;接收消息的窗口句柄
INHASH                ENDS

OUTHASH STRUCT
lpFiledir  dd ?                   ;文件名指针
stSize    FILELEN<>         ;文件大小
MD5                dd  4 dup(?)         ;MD5值
SHA1   dd  5 dup(?)         ;SHA1值
OUTHASH ENDS

INHASH是传递给计算线程的信息,OUTHASH 是计算线程返回的信息

部分源码
先是计算64Byte/分组的MD5
_FF proc ta,tb,tc,td,M,ts,k
      mov eax,tb    ;F(tb,tc,td)
      mov ecx,eax
      and eax,tc
      not ecx
      and ecx,td
      or eax,ecx

      add eax,ta
      add eax,M
      add eax,k
      mov ecx,ts
      rol eax,cl
      add eax,tb
      ret
_FF endp
_GG proc ta,tb,tc,td,M,ts,k
      mov eax,td     ;G(tb,tc,td)
      mov ecx,eax
      and eax,tb
      not ecx
      and ecx,tc
      or eax,ecx

      add eax,ta
      add eax,M
      add eax,k
      mov ecx,ts
      rol eax,cl
      add eax,tb
      ret
_GG endp
_HH proc ta,tb,tc,td,M,ts,k
      mov eax,tb        ;H(tb,tc,td)
      xor eax,tc
      xor eax,td

      add eax,ta
      add eax,M
      add eax,k
      mov ecx,ts
      rol eax,cl
      add eax,tb
      ret
_HH endp
_II proc ta,tb,tc,td,M,ts,k
      mov eax,td       ;I(tb,tc,td)
      not eax
      or eax,tb
      xor eax,tc

      add eax,ta
      add eax,M
      add eax,k
      mov ecx,ts
      rol eax,cl
      add eax,tb
      ret
_II endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;_MD5to64  ebx,edx固定分配作state_md5和带变换的字符lpMemory
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>	
_MD5to64 proc uses eax ebx ecx edx lpMemory,lpstate_md5
     local @aa,@bb,@cc,@dd          
                                            
     mov ebx,lpstate_md5
     mov edx,lpMemory        
     push dword ptr [ebx]
     pop @aa
     push dword ptr [ebx+4]
     pop @bb
     push dword ptr [ebx+8]
     pop @cc
     push dword ptr [ebx+12]
     pop @dd

     invoke _FF,@aa,@bb,@cc,@dd,[edx+0],7,0d76aa478h;第1轮
     mov @aa,eax
     invoke _FF,@dd,@aa,@bb,@cc,[edx+4],12,0e8c7b756h;第2轮
     mov @dd,eax
     invoke _FF,@cc,@dd,@aa,@bb,[edx+8],17,0242070dbh;第3轮
     mov @cc,eax
     invoke _FF,@bb,@cc,@dd,@aa,[edx+12],22,0c1bdceeeh;第4轮
     mov @bb,eax
     invoke _FF,@aa,@bb,@cc,@dd,[edx+16],7,0f57c0fafh;第5轮
     mov @aa,eax
     invoke _FF,@dd,@aa,@bb,@cc,[edx+20],12,04787c62ah;第6轮
     mov @dd,eax
     invoke _FF,@cc,@dd,@aa,@bb,[edx+24],17,0a8304613h;第7轮
     mov @cc,eax
     invoke _FF,@bb,@cc,@dd,@aa,[edx+28],22,0fd469501h;第8轮
     mov @bb,eax
     invoke _FF,@aa,@bb,@cc,@dd,[edx+32],7,0698098d8h;第9轮
     mov @aa,eax
     invoke _FF,@dd,@aa,@bb,@cc,[edx+36],12,08b44f7afh;第10轮
     mov @dd,eax
     invoke _FF,@cc,@dd,@aa,@bb,[edx+40],17,0ffff5bb1h;第11轮
     mov @cc,eax
     invoke _FF,@bb,@cc,@dd,@aa,[edx+44],22,0895cd7beh;第12轮
     mov @bb,eax
     invoke _FF,@aa,@bb,@cc,@dd,[edx+48],7,06b901122h;第13轮
     mov @aa,eax
     invoke _FF,@dd,@aa,@bb,@cc,[edx+52],12,0fd987193h;第14轮
     mov @dd,eax
     invoke _FF,@cc,@dd,@aa,@bb,[edx+56],17,0a679438eh;第15轮
     mov @cc,eax
     invoke _FF,@bb,@cc,@dd,@aa,[edx+60],22,049b40821h;第16轮
     mov @bb,eax
     invoke _GG,@aa,@bb,@cc,@dd,[edx+4],5,0f61e2562h;第17轮
     mov @aa,eax
     invoke _GG,@dd,@aa,@bb,@cc,[edx+24],9,0c040b340h;第18轮
     mov @dd,eax
     invoke _GG,@cc,@dd,@aa,@bb,[edx+44],14,0265e5a51h;第19轮
     mov @cc,eax
     invoke _GG,@bb,@cc,@dd,@aa,[edx+0],20,0e9b6c7aah;第20轮
     mov @bb,eax
     invoke _GG,@aa,@bb,@cc,@dd,[edx+20],5,0d62f105dh;第21轮
     mov @aa,eax
     invoke _GG,@dd,@aa,@bb,@cc,[edx+40],9,002441453h;第22轮
     mov @dd,eax
     invoke _GG,@cc,@dd,@aa,@bb,[edx+60],14,0d8a1e681h;第23轮
     mov @cc,eax
     invoke _GG,@bb,@cc,@dd,@aa,[edx+16],20,0e7d3fbc8h;第24轮
     mov @bb,eax
     invoke _GG,@aa,@bb,@cc,@dd,[edx+36],5,021e1cde6h;第25轮
     mov @aa,eax
     invoke _GG,@dd,@aa,@bb,@cc,[edx+56],9,0c33707d6h;第26轮
     mov @dd,eax
     invoke _GG,@cc,@dd,@aa,@bb,[edx+12],14,0f4d50d87h;第27轮
     mov @cc,eax
     invoke _GG,@bb,@cc,@dd,@aa,[edx+32],20,0455a14edh;第28轮
     mov @bb,eax
     invoke _GG,@aa,@bb,@cc,@dd,[edx+52],5,0a9e3e905h;第29轮
     mov @aa,eax
     invoke _GG,@dd,@aa,@bb,@cc,[edx+8],9,0fcefa3f8h;第30轮
     mov @dd,eax
     invoke _GG,@cc,@dd,@aa,@bb,[edx+28],14,0676f02d9h;第31轮
     mov @cc,eax
     invoke _GG,@bb,@cc,@dd,@aa,[edx+48],20,08d2a4c8ah;第32轮
     mov @bb,eax
     invoke _HH,@aa,@bb,@cc,@dd,[edx+20],4,0fffa3942h;第33轮
     mov @aa,eax
     invoke _HH,@dd,@aa,@bb,@cc,[edx+32],11,08771f681h;第34轮
     mov @dd,eax
     invoke _HH,@cc,@dd,@aa,@bb,[edx+44],16,06d9d6122h;第35轮
     mov @cc,eax
     invoke _HH,@bb,@cc,@dd,@aa,[edx+56],23,0fde5380ch;第36轮
     mov @bb,eax
     invoke _HH,@aa,@bb,@cc,@dd,[edx+4],4,0a4beea44h;第37轮
     mov @aa,eax
     invoke _HH,@dd,@aa,@bb,@cc,[edx+16],11,04bdecfa9h;第38轮
     mov @dd,eax
     invoke _HH,@cc,@dd,@aa,@bb,[edx+28],16,0f6bb4b60h;第39轮
     mov @cc,eax
     invoke _HH,@bb,@cc,@dd,@aa,[edx+40],23,0bebfbc70h;第40轮
     mov @bb,eax
     invoke _HH,@aa,@bb,@cc,@dd,[edx+52],4,0289b7ec6h;第41轮
     mov @aa,eax
     invoke _HH,@dd,@aa,@bb,@cc,[edx+0],11,0eaa127fah;第42轮
     mov @dd,eax
     invoke _HH,@cc,@dd,@aa,@bb,[edx+12],16,0d4ef3085h;第43轮
     mov @cc,eax
     invoke _HH,@bb,@cc,@dd,@aa,[edx+24],23,004881d05h;第44轮
     mov @bb,eax
     invoke _HH,@aa,@bb,@cc,@dd,[edx+36],4,0d9d4d039h;第45轮
     mov @aa,eax
     invoke _HH,@dd,@aa,@bb,@cc,[edx+48],11,0e6db99e5h;第46轮
     mov @dd,eax
     invoke _HH,@cc,@dd,@aa,@bb,[edx+60],16,01fa27cf8h;第47轮
     mov @cc,eax
     invoke _HH,@bb,@cc,@dd,@aa,[edx+8],23,0c4ac5665h;第48轮
     mov @bb,eax
     invoke _II,@aa,@bb,@cc,@dd,[edx+0],6,0f4292244h;第49轮
     mov @aa,eax
     invoke _II,@dd,@aa,@bb,@cc,[edx+28],10,0432aff97h;第50轮
     mov @dd,eax
     invoke _II,@cc,@dd,@aa,@bb,[edx+56],15,0ab9423a7h;第51轮
     mov @cc,eax
     invoke _II,@bb,@cc,@dd,@aa,[edx+20],21,0fc93a039h;第52轮
     mov @bb,eax
     invoke _II,@aa,@bb,@cc,@dd,[edx+48],6,0655b59c3h;第53轮
     mov @aa,eax
     invoke _II,@dd,@aa,@bb,@cc,[edx+12],10,08f0ccc92h;第54轮
     mov @dd,eax
     invoke _II,@cc,@dd,@aa,@bb,[edx+40],15,0ffeff47dh;第55轮
     mov @cc,eax
     invoke _II,@bb,@cc,@dd,@aa,[edx+4],21,085845dd1h;第56轮
     mov @bb,eax
     invoke _II,@aa,@bb,@cc,@dd,[edx+32],6,06fa87e4fh;第57轮
     mov @aa,eax
     invoke _II,@dd,@aa,@bb,@cc,[edx+60],10,0fe2ce6e0h;第58轮
     mov @dd,eax
     invoke _II,@cc,@dd,@aa,@bb,[edx+24],15,0a3014314h;第59轮
     mov @cc,eax
     invoke _II,@bb,@cc,@dd,@aa,[edx+52],21,04e0811a1h;第60轮
     mov @bb,eax
     invoke _II,@aa,@bb,@cc,@dd,[edx+16],6,0f7537e82h;第61轮
     mov @aa,eax
     invoke _II,@dd,@aa,@bb,@cc,[edx+44],10,0bd3af235h;第62轮
     mov @dd,eax
     invoke _II,@cc,@dd,@aa,@bb,[edx+8],15,02ad7d2bbh;第63轮
     mov @cc,eax
     invoke _II,@bb,@cc,@dd,@aa,[edx+36],21,0eb86d391h;第64轮
     mov @bb,eax

     mov eax,@aa
     add dword ptr [ebx],eax
     mov eax,@bb
     add dword ptr [ebx+4],eax
     mov eax,@cc
     add dword ptr [ebx+8],eax
     mov eax,@dd
     add dword ptr [ebx+12],eax

     ret 
_MD5to64 endp


再是计算64Byte/分组的SHA1
_SHA1to80 proc uses eax ebx ecx edx lpMemory,lpstate_sha1
     local @aa,@bb,@cc,@dd,@ee
     local _Sha1Buffer[80]
     
   ;  Extend the sixteen 32-bit words into eighty 32-bit words:
     lea eax,_Sha1Buffer
     xor ecx,ecx
     mov edx,lpMemory
     .while ecx<=15
       mov bl,[edx+ecx*4+3]
       mov [eax+ecx*4],bl
       mov bl,[edx+ecx*4+2]
       mov [eax+ecx*4+1],bl
       mov bl,[edx+ecx*4+1]
       mov [eax+ecx*4+2],bl
       mov bl,[edx+ecx*4]
       mov [eax+ecx*4+3],bl
       inc ecx
     .endw
     .while ecx<=79
        mov ebx,[eax+ecx*4-16*4]
        xor ebx,[eax+ecx*4-14*4]
        xor ebx,[eax+ecx*4-8*4]
        xor ebx,[eax+ecx*4-3*4]
        rol ebx,1
        mov [eax+ecx*4],ebx
        inc ecx
     .endw
     
      ; Initialize hash value for this chunk:
     mov ebx,lpstate_sha1
     push dword ptr [ebx]
     pop @aa
     push dword ptr [ebx+4]
     pop @bb
     push dword ptr [ebx+8]
     pop @cc
     push dword ptr [ebx+12]
     pop @dd
     push dword ptr [ebx+16]
     pop @ee
     
    ; Main loop:
     xor ecx,ecx
     .while ecx<=79
         .if ecx<=19
            mov ebx,@bb
            and ebx,@cc
            mov edx,@bb
            not edx
            and edx,@dd
            or ebx,edx
            add ebx,5A827999h
         .elseif ecx>= 40 && ecx <= 59
            mov ebx,@bb
            and ebx,@cc
            mov edx,@bb
            and edx,@dd
            or ebx,edx
            mov edx,@cc
            and edx,@dd
            or ebx,edx
            add ebx,8F1BBCDCh
          .else
              mov ebx,@bb
              xor ebx,@cc
              xor ebx,@dd
              .if ecx<=39
                 add ebx,6ED9EBA1h
              .else
                 add ebx,0CA62C1D6h
               .endif
           .endif
           mov edx,@aa             ;edx表示temp,ebx表示f+k
           rol edx,5
           add edx,ebx
           add edx,@ee
           lea eax,_Sha1Buffer
           add edx,[eax+ecx*4]
           push @dd
           pop @ee
           push @cc
           pop @dd
           mov ebx,@bb
           rol ebx,30
           mov @cc,ebx
           push @aa
           pop @bb
           mov @aa,edx
      inc ecx
      .endw
      
      mov ebx,lpstate_sha1
      mov edx,@aa
      add dword ptr [ebx],edx
      mov edx,@bb
      add dword ptr [ebx+4],edx
      mov edx,@cc
      add dword ptr [ebx+8],edx
      mov edx,@dd
      add dword ptr [ebx+12],edx
      mov edx,@ee
      add dword ptr [ebx+16],edx
           
     ret
_SHA1to80  endp

_ThreadCalc proc uses eax ebx ecx edx esi lpHashCtrl 
       
     assume esi:ptr INHASH
     mov esi,lpHashCtrl
     
       ;打开文件
       invoke  CreateFile,addr szFiledir,GENERIC_READ, 0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
       .if eax== INVALID_HANDLE_VALUE 
          invoke SendMessage,[esi].hWnd,WM_HASH,1,0  
		      ret
	     .endif
	     mov @hFile,eax
	   	 invoke  GetFileSize,@hFile,addr @stHashResult.stSize.h
       mov @stHashResult.stSize.l,eax
       invoke	CreateFileMapping,@hFile,NULL,PAGE_READONLY,0,0,NULL
       mov @hFileMap,eax
       
       push [esi].bList
       pop @List
       
       ;初始化
       invoke  RtlMoveMemory,addr @stHashResult.MD5,offset Init_data,16
       invoke  RtlMoveMemory,addr @stHashResult.SHA1,offset Init_data,20 
        ;计算分段映射的次数
       	mov edx,@stHashResult.stSize.h
	      mov eax,@stHashResult.stSize.l
      	mov ebx,FILEMAPSIZE
	      div ebx
	      mov @nPart,eax
      	mov @nPart_Remainder,edx
	      inc eax       ;进一,进度条刚好完全
	      shl eax,16  ;低位为最小值,高位为最大值
        invoke SendMessage,[esi].hWnd,WM_HASH,2,eax
        
	      mov @counth,0
        mov @countl,0
        mov esi,lpHashCtrl
        mov edi,[esi].lpObject                           ;检测标志,以便停止
        mov ebx,FILEMAPSIZE                          ;
	      .while @nPart 
	        invoke	MapViewOfFile,@hFileMap,FILE_MAP_READ,@counth,@countl,FILEMAPSIZE
	        mov @lpMemory,eax
	        invoke _@BlockDispatch,FILEMAPSIZE,@lpMemory,addr @stHashResult,@List
	        invoke	UnmapViewOfFile,@lpMemory
	        invoke SendMessage,[esi].hWnd,WM_HASH,3,0
	        mov eax,[edi]                                     ;在耗时最多的地方检验标志
	         .if !eax
             invoke SendMessage,[esi].hWnd,WM_HASH,0,0
             jmp break
          .endif
	      
	        add @countl,ebx
          adc @counth,0
          dec @nPart
	      .endw
       
        .if @nPart_Remainder
        invoke	MapViewOfFile,@hFileMap,FILE_MAP_READ,@counth,@countl,@nPart_Remainder
        mov @lpMemory,eax
        .if @nPart_Remainder>=64  ;将本次映射的前n*64字节计算
           invoke _@BlockDispatch,@nPart_Remainder,@lpMemory,addr @stHashResult,@List
        .endif
        mov eax,@lpMemory                                                                        ;eax为映射的初始地址
        add eax,@nPart_Remainder                                                              ; eax为映射最后地址
        and @nPart_Remainder,3Fh                                                              ;@nPart_Remainder 现在代表%64的余数
        sub eax,@nPart_Remainder                                                               ; eax为映射最后地址-上面的余数
        invoke RtlMoveMemory,addr @buffer_last,eax,@nPart_Remainder    ;将剩余不足64字节的数据存入buffer_last
        invoke	UnmapViewOfFile,@lpMemory
        invoke SendMessage,[esi].hWnd,WM_HASH,3,0
    .endif
       
     .if @nPart_Remainder>=56                                                         
         lea ebx,@buffer_last
         add ebx,@nPart_Remainder
         mov ecx,64
         sub ecx,@nPart_Remainder                                             ;ecx=64-@nPart_Remainder 
         invoke RtlMoveMemory,ebx,offset added,ecx
         invoke _@BlockDispatch,64,addr @buffer_last,addr @stHashResult,@List   ;先
         mov ebx,offset added
         add ebx,64                                                       
         sub ebx,@nPart_Remainder
         invoke RtlMoveMemory,addr @buffer_last,ebx,56
    .else                                                                             ;<56则只会变换一轮
         lea ebx,@buffer_last
         add ebx,@nPart_Remainder
         mov ecx,56
         sub ecx,@nPart_Remainder
         invoke RtlMoveMemory,ebx,offset added,ecx
     .endif  
     ;将@countl @counth 组成的64位长度乘以8,变成以bit计算的文件长度
     push @stHashResult.stSize.l
     pop @countl            
     push @stHashResult.stSize.h
     pop @counth              
     mov eax,0E0000000h                             ;将64位数乘以8
     and eax,@countl 
     shr eax,29
     shl @countl ,3
     shl @counth,3
     add @counth,eax
     
      lea ebx,@buffer_last    ;填充输入信息长度,并进行最后一次变换
      ;md5的按照小端排序
      push @countl  
      pop dword ptr [ebx+56]
      push @counth
      pop dword ptr [ebx+60]
      invoke _MD5to64,ebx,addr @stHashResult.MD5
      ;sha1的按照大端端排序
      invoke _ChangeEndian,@counth
      mov [ebx+56],eax
      invoke _ChangeEndian,@countl
      mov [ebx+60],eax
      invoke _SHA1to80,ebx,addr @stHashResult.SHA1
     
       ;通知窗口完成计算
       invoke GlobalAlloc,GMEM_FIXED,sizeof OUTHASH
       mov @lpResult,eax
       invoke RtlMoveMemory,@lpResult,addr @stHashResult,sizeof OUTHASH    ;将 
       invoke SendMessage,[esi].hWnd,WM_HASH,0,@lpResult
  break:
	     invoke	CloseHandle,@hFileMap
	     invoke	CloseHandle,@hFile
	     
	     assume esi:nothing
	     
       ret
_ThreadCalc endp

每次映射的大小由FILEMAPSIZE equ 100000h 决定,我定为1MB
流程是每次映射1MB(当然要是64KB的倍数),最后的一次不足1MB,但又可能大于64KB,那么先将本次映射的前n个64字节计算掉,将剩下的不足64字节放入缓冲区,剩下的看过MD5和SHA1应该都知道怎么做了。
考虑到停止和进度条功能,又在每次映射1MB这部分加了一些语句,因为这部分是最耗时间的
后来在实现加入右键的功能时,发现要管理员权限,搜了一圈发现进程无法运行到一半提升权限,想了个方法,以管理员身份带参数运行自身,这个新的实例只是添删右键就退出了,参数?Y和?N代表添加和删除右键。

[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 259
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好东西啊,大牛
2014-8-18 08:35
0
雪    币: 86
活跃值: (18)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
膜拜,完全看不懂。
2014-8-20 15:48
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
2014-8-20 16:19
0
游客
登录 | 注册 方可回帖
返回
//