找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 14073|回复: 21

【VB】VB6+ASM写文件的SHA1哈希值计算工具

[复制链接]
发表于 2016-6-11 01:59:44 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
20160611023349.png

BIN下载: sha1_demo_bin.7z (11.62 KB, 下载次数: 21)
要下载源代码请先回帖。
游客,如果您要查看本帖隐藏内容请回复


VB6用自己的加减乘除与或非进行位运算的话有个先天性不足:左移或右移难以实现。VB6的IDE有整数溢出检查,挺麻烦的。
然后SHA1的算法是需要做 leftrotate 运算的。所以要是用加减乘除来模拟左移和右移就会严重影响速度。因此我写了个Shellcode,用这个Shellcode完成SHA1的区块处理。
  1. bits 32

  2. _SHA1_ProcChunk:

  3. ;[esp+4]        void*psrc // uint8_t src[64]
  4. ;[esp+8]        uint32_t pstate[5]

  5. push esi
  6. push edi

  7. %define SizeOfTempVar (80*4+6*4)
  8. %define OffsetToInitESP (SizeOfTempVar+8)
  9. ;Parameters
  10. %define pSrcData_ [esp+OffsetToInitESP+4]
  11. %define pSHA1States_ [esp+OffsetToInitESP+8]
  12. ;Local vars
  13. %define WordBuf (esp+6*4)
  14. %define A_ [esp+0*4]
  15. %define B_ [esp+1*4]
  16. %define C_ [esp+2*4]
  17. %define D_ [esp+3*4]
  18. %define E_ [esp+4*4]
  19. %define T_ [esp+5*4]
  20. %macro MovRegs 0
  21. mov T_,eax
  22. mov eax,D_
  23. mov E_,eax
  24. mov eax,C_
  25. mov D_,eax
  26. mov eax,B_
  27. rol eax,30
  28. mov C_,eax
  29. mov eax,A_
  30. mov B_,eax
  31. mov eax,T_
  32. mov A_,eax
  33. %endmacro

  34. ;Allocate memory from stack
  35. sub esp,SizeOfTempVar

  36. ;break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15
  37. mov ecx,16
  38. mov esi,pSrcData_
  39. lea edi,[WordBuf]
  40. .InitWords:
  41. lodsd
  42. bswap eax
  43. stosd
  44. loop .InitWords

  45. ;Extend the sixteen 32-bit words into eighty 32-bit words:
  46. ;for i from 16 to 79
  47. ;    w[i] = (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1
  48. lea edi,[WordBuf+16*4]
  49. mov ecx,64
  50. .InitAllWords:
  51. mov eax,[edi-3*4]
  52. xor eax,[edi-8*4]
  53. xor eax,[edi-14*4]
  54. xor eax,[edi-16*4]
  55. rol eax,1
  56. stosd
  57. loop .InitAllWords

  58. ;Initialize hash value for this chunk:
  59. ;a = h0
  60. ;b = h1
  61. ;c = h2
  62. ;d = h3
  63. ;e = h4
  64. mov esi,pSHA1States_
  65. lea edi,A_
  66. mov ecx,5
  67. rep movsd

  68. lea esi,[WordBuf]

  69. ;========
  70. mov ecx,20
  71. .ProcStep1:
  72. mov eax,B_
  73. mov edx,eax
  74. and eax,C_ ;B & C
  75. not edx
  76. and edx,D_ ;(~B) & D
  77. or eax,edx ;(B & C) | ((~B) & D)
  78. mov edx,A_
  79. rol edx,5
  80. add edx,eax ;+ rotateleft(A,5)
  81. lodsd
  82. add eax,edx ;+ W[i]
  83. add eax,E_  ;+ E
  84. add eax,0x5A827999 ;+ K
  85. MovRegs
  86. loop .ProcStep1

  87. ;========
  88. mov ecx,20
  89. .ProcStep2:
  90. mov eax,A_
  91. rol eax,5  ;rorareleft(A,5)
  92. mov edx,B_
  93. xor edx,C_
  94. xor edx,D_ ;B^C^D
  95. add eax,E_
  96. add edx,eax
  97. lodsd
  98. add eax,edx;+ W[i]
  99. add eax,0x6ED9EBA1;+ K
  100. MovRegs
  101. loop .ProcStep2

  102. ;========
  103. mov ecx,20
  104. .ProcStep3:
  105. mov edx,B_
  106. and edx,D_ ;B & D
  107. mov eax,B_
  108. and eax,C_ ;B & C
  109. or edx,eax
  110. mov eax,C_
  111. and eax,D_ ;C & D
  112. or edx,eax
  113. mov eax,A_
  114. rol eax,5  ;rorareleft(A,5)
  115. add eax,E_
  116. add edx,eax
  117. lodsd
  118. add eax,edx;+ W[i]
  119. add eax,0x8F1BBCDC;+ K
  120. MovRegs
  121. loop .ProcStep3

  122. ;========
  123. mov ecx,20
  124. .ProcStep4:
  125. mov eax,A_
  126. rol eax,5  ;rorareleft(A,5)
  127. mov edx,B_
  128. xor edx,C_
  129. xor edx,D_ ;B^C^D
  130. add eax,E_
  131. add edx,eax
  132. lodsd
  133. add eax,edx;+ W[i]
  134. add eax,0xCA62C1D6;+ K
  135. MovRegs
  136. loop .ProcStep4

  137. ;Finished
  138. mov edi,pSHA1States_
  139. mov eax,A_
  140. add [edi+0*4],eax
  141. mov eax,B_
  142. add [edi+1*4],eax
  143. mov eax,C_
  144. add [edi+2*4],eax
  145. mov eax,D_
  146. add [edi+3*4],eax
  147. mov eax,E_
  148. add [edi+4*4],eax

  149. add esp,SizeOfTempVar

  150. pop edi
  151. pop esi
  152. ret 16
复制代码
因为我打算用CallWindowProc来调用它,因此它其实是被当作LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);来调用的。但其实第一个参数是数据Chunk的指针,第二个参数是SHA1状态结构体(存储5个uint32_t)的指针。

  1. Attribute VB_Name = "modSHA1"
  2. Option Explicit

  3. Type SHA1State_t
  4.     h0 As Long
  5.     h1 As Long
  6.     h2 As Long
  7.     h3 As Long
  8.     h4 As Long
  9. End Type

  10. Private Declare Function CallProc4Param Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal Param1 As Long, ByVal Param2 As Long, ByVal Param3 As Long, ByVal Param4 As Long) As Long
  11. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
  12. Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (Dest As Any, ByVal numBytes As Long)
  13. Private Declare Function GetSystemDefaultLCID Lib "kernel32" () As Long


  14. Private m_Ops(121) As Long

  15. Sub SHA1_Init(State As SHA1State_t)

  16. m_Ops(0) = &HEC815756:   m_Ops(1) = &H158&:       m_Ops(2) = &H10B9&:      m_Ops(3) = &H24B48B00:   m_Ops(4) = &H164&
  17. m_Ops(5) = &H18247C8D:   m_Ops(6) = &HABC80FAD:   m_Ops(7) = &H7C8DFAE2:   m_Ops(8) = &H40B95824:   m_Ops(9) = &H8B000000
  18. m_Ops(10) = &H4733F447:  m_Ops(11) = &HC84733E0:  m_Ops(12) = &HD1C04733:  m_Ops(13) = &HEFE2ABC0:  m_Ops(14) = &H6824B48B
  19. m_Ops(15) = &H8D000001:  m_Ops(16) = &H5B9243C:   m_Ops(17) = &HF3000000:  m_Ops(18) = &H24748DA5:  m_Ops(19) = &H14B918
  20. m_Ops(20) = &H448B0000:  m_Ops(21) = &HC2890424:  m_Ops(22) = &H8244423:   m_Ops(23) = &H5423D2F7:  m_Ops(24) = &HD0090C24
  21. m_Ops(25) = &HC124148B:  m_Ops(26) = &HC20105C2:  m_Ops(27) = &H3D001AD:   m_Ops(28) = &H5102444:   m_Ops(29) = &H5A827999
  22. m_Ops(30) = &H14244489:  m_Ops(31) = &HC24448B:   m_Ops(32) = &H10244489:  m_Ops(33) = &H824448B:   m_Ops(34) = &HC244489
  23. m_Ops(35) = &H424448B:   m_Ops(36) = &H891EC0C1:  m_Ops(37) = &H8B082444:  m_Ops(38) = &H44892404:  m_Ops(39) = &H448B0424
  24. m_Ops(40) = &H4891424:   m_Ops(41) = &HB9ABE224:  m_Ops(42) = &H14&:       m_Ops(43) = &HC124048B:  m_Ops(44) = &H548B05C0
  25. m_Ops(45) = &H54330424:  m_Ops(46) = &H54330824:  m_Ops(47) = &H44030C24:  m_Ops(48) = &HC2011024:  m_Ops(49) = &H5D001AD
  26. m_Ops(50) = &H6ED9EBA1:  m_Ops(51) = &H14244489:  m_Ops(52) = &HC24448B:   m_Ops(53) = &H10244489:  m_Ops(54) = &H824448B
  27. m_Ops(55) = &HC244489:   m_Ops(56) = &H424448B:   m_Ops(57) = &H891EC0C1:  m_Ops(58) = &H8B082444:  m_Ops(59) = &H44892404
  28. m_Ops(60) = &H448B0424:  m_Ops(61) = &H4891424:   m_Ops(62) = &HB9B1E224:  m_Ops(63) = &H14&:       m_Ops(64) = &H424548B
  29. m_Ops(65) = &HC245423:   m_Ops(66) = &H424448B:   m_Ops(67) = &H8244423:   m_Ops(68) = &H448BC209:  m_Ops(69) = &H44230824
  30. m_Ops(70) = &HC2090C24:  m_Ops(71) = &HC124048B:  m_Ops(72) = &H440305C0:  m_Ops(73) = &HC2011024:  m_Ops(74) = &H5D001AD
  31. m_Ops(75) = &H8F1BBCDC:  m_Ops(76) = &H14244489:  m_Ops(77) = &HC24448B:   m_Ops(78) = &H10244489:  m_Ops(79) = &H824448B
  32. m_Ops(80) = &HC244489:   m_Ops(81) = &H424448B:   m_Ops(82) = &H891EC0C1:  m_Ops(83) = &H8B082444:  m_Ops(84) = &H44892404
  33. m_Ops(85) = &H448B0424:  m_Ops(86) = &H4891424:   m_Ops(87) = &HB9A1E224:  m_Ops(88) = &H14&:       m_Ops(89) = &HC124048B
  34. m_Ops(90) = &H548B05C0:  m_Ops(91) = &H54330424:  m_Ops(92) = &H54330824:  m_Ops(93) = &H44030C24:  m_Ops(94) = &HC2011024
  35. m_Ops(95) = &H5D001AD:   m_Ops(96) = &HCA62C1D6:  m_Ops(97) = &H14244489:  m_Ops(98) = &HC24448B:   m_Ops(99) = &H10244489
  36. m_Ops(100) = &H824448B:  m_Ops(101) = &HC244489:  m_Ops(102) = &H424448B:  m_Ops(103) = &H891EC0C1: m_Ops(104) = &H8B082444
  37. m_Ops(105) = &H44892404: m_Ops(106) = &H448B0424: m_Ops(107) = &H4891424:  m_Ops(108) = &H8BB1E224: m_Ops(109) = &H16824BC
  38. m_Ops(110) = &H48B0000:  m_Ops(111) = &H8B070124: m_Ops(112) = &H1042444:  m_Ops(113) = &H448B0447: m_Ops(114) = &H47010824
  39. m_Ops(115) = &H24448B08: m_Ops(116) = &HC47010C:  m_Ops(117) = &H1024448B: m_Ops(118) = &H81104701: m_Ops(119) = &H158C4
  40. m_Ops(120) = &HC25E5F00: m_Ops(121) = &H10&

  41. State.h0 = &H67452301
  42. State.h1 = &HEFCDAB89
  43. State.h2 = &H98BADCFE
  44. State.h3 = &H10325476
  45. State.h4 = &HC3D2E1F0

  46. Int64_InitGlobal
  47. End Sub

  48. '读取sha1.bin并在立即窗口打印数组
  49. 'Sub SHA1_LoadOps()
  50. 'Dim Ops() As Long
  51. 'Open App.Path & "\sha1.bin" For Binary Access Read As #1
  52. 'ReDim Ops(LOF(1) \ 4)
  53. 'Get #1, , Ops
  54. 'Close #1
  55. '
  56. 'Dim I&, X&
  57. 'For I = 0 To UBound(Ops)
  58. '    X = X + 1
  59. '    If X > 4 Then
  60. '        Debug.Print "m_Ops("; CStr(I); ") = &H"; Hex$(Ops(I)); "&"
  61. '        X = 0
  62. '    Else
  63. '        Debug.Print "m_Ops("; CStr(I); ") = &H"; Hex$(Ops(I)); "&:";
  64. '    End If
  65. 'Next
  66. 'End Sub

  67. '处理每个64字节区块
  68. Sub SHA1_ProcChunk(State As SHA1State_t, ByVal ChunkPtr As Long)
  69. CallProc4Param VarPtr(m_Ops(0)), ChunkPtr, VarPtr(State), 0, 0
  70. End Sub

  71. '处理最后一个区块
  72. Sub SHA1_ProcLastChunk(State As SHA1State_t, ByVal LastDataPtr As Long, ByVal cbLastData As Long, cbTotal As Int64_t)
  73. Dim Padded(63) As Byte
  74. Dim BETotalBits As Int64_t

  75. '规则:
  76. '在数据的最后一个字节后面添加一个0x80
  77. '总数据用0补足为64字节的N倍大小
  78. '将数据最后的8个字节替换成,数据的总bits的Big-Ending顺序方式存储
  79. '然后做一次区块计算

  80. BETotalBits = cbTotal
  81. Int64_Shl BETotalBits, 3 'Bytes * 8
  82. Int64_BSWAP BETotalBits

  83. If cbLastData + 9 <= 64 Then
  84.     CopyMemory Padded(0), ByVal LastDataPtr, cbLastData
  85.     Padded(cbLastData) = &H80 'Last bit
  86.     CopyMemory Padded(56), BETotalBits, 8
  87.     SHA1_ProcChunk State, VarPtr(Padded(0))
  88. ElseIf cbLastData = 64 Then
  89.     SHA1_ProcChunk State, LastDataPtr
  90.     Padded(0) = &H80
  91.     CopyMemory Padded(56), BETotalBits, 8
  92.     SHA1_ProcChunk State, VarPtr(Padded(0))
  93. Else
  94.     CopyMemory Padded(0), ByVal LastDataPtr, cbLastData
  95.     Padded(cbLastData) = &H80  'Last bit
  96.     SHA1_ProcChunk State, VarPtr(Padded(0))
  97.    
  98.     ZeroMemory Padded(0), 64
  99.     CopyMemory Padded(56), BETotalBits, 8
  100.     SHA1_ProcChunk State, VarPtr(Padded(0))
  101. End If
  102. End Sub

  103. '将处理后的5个寄存器输出为字符串
  104. Function SHA1_GetResultStr(State As SHA1State_t) As String
  105. SHA1_GetResultStr = Hex32(State.h0) & Hex32(State.h1) & Hex32(State.h2) & Hex32(State.h3) & Hex32(State.h4)
  106. End Function

  107. '数字转换为用0补足的8位十六进制数字字符串
  108. Private Function Hex32(ByVal Num As Long) As String
  109. Hex32 = Right$("0000000" & Hex$(Num), 8)
  110. End Function

  111. '计算字符串的SHA1值
  112. Function SHA1_CalcStringSHA1(ByVal StrToCalc As String, Optional ByVal LocaleID As Long) As String
  113. Dim MBArr() As Byte, cbMBArr As Int64_t
  114. If LocaleID = 0 Then LocaleID = GetSystemDefaultLCID
  115. MBArr = StrConv(StrToCalc, vbFromUnicode, LocaleID)
  116. cbMBArr.L = UBound(MBArr) + 1

  117. Dim State As SHA1State_t, I&
  118. SHA1_Init State
  119. Do While I + 64 < cbMBArr.L
  120.     SHA1_ProcChunk State, VarPtr(MBArr(I))
  121.     I = I + 64
  122. Loop
  123. SHA1_ProcLastChunk State, VarPtr(MBArr(I)), cbMBArr.L - I, cbMBArr
  124. SHA1_CalcStringSHA1 = SHA1_GetResultStr(State)
  125. End Function

  126. Function SHA1_CalcFileSHA1(ByVal FilePath As String) As String
  127. Dim Chunk(63) As Byte, FileLen As Long
  128. Dim ChunkLen As Int64_t
  129. Dim SHA1State As SHA1State_t

  130. SHA1_Init SHA1State

  131. ChunkLen.L = 64

  132. Dim FO As File_t
  133. If File_OpenForRead(FilePath, FO) = False Then GoTo ErrHandler
  134. Dim RestLen As Int64_t

  135. RestLen = FO.Size

  136. Do While RestLen.H <> 0 Or RestLen.L > 64
  137.     File_Read FO, VarPtr(Chunk(0)), 64
  138.     SHA1_ProcChunk SHA1State, VarPtr(Chunk(0))
  139.     Int64_Sub RestLen, ChunkLen
  140. Loop

  141. File_Read FO, VarPtr(Chunk(0)), RestLen.L
  142. SHA1_ProcLastChunk SHA1State, VarPtr(Chunk(0)), RestLen.L, FO.Size
  143. File_Close FO
  144. SHA1_CalcFileSHA1 = SHA1_GetResultStr(SHA1State)

  145. Exit Function
  146. ErrHandler:
  147. File_Close FO
  148. SHA1_CalcFileSHA1 = "Calc SHA1 failed."
  149. End Function

  150. 'Sub SHA1_Test()
  151. 'Dim Blank(63) As Byte
  152. 'Blank(0) = &H80
  153. '
  154. 'Dim State As SHA1State_t
  155. '
  156. 'SHA1_Init State
  157. 'SHA1_ProcChunk State, VarPtr(Blank(0))
  158. 'Debug.Print SHA1_GetResultStr(State)
  159. 'Debug.Print "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 - 0 byte"
  160. 'End Sub
复制代码


SHA1的详细算法,请参考以下文章:
https://en.wikipedia.org/wiki/SHA-1
http://www.mattmahoney.net/dc/sha1.c


回复

使用道具 举报

发表于 2016-10-24 09:00:37 | 显示全部楼层
这个看起来很赞
回复 赞! 0 靠! 1

使用道具 举报

发表于 2016-11-17 10:30:21 | 显示全部楼层
支持    !!
回复 赞! 靠!

使用道具 举报

发表于 2016-11-20 02:17:24 | 显示全部楼层
好好学习天天向上
回复 赞! 靠!

使用道具 举报

发表于 2017-1-9 12:33:07 | 显示全部楼层
不错的东西,谢谢楼主分享
回复 赞! 靠!

使用道具 举报

发表于 2017-1-9 12:33:31 | 显示全部楼层
不错的东西谢谢楼主分享
回复 赞! 靠!

使用道具 举报

发表于 2017-3-18 01:05:43 | 显示全部楼层
刚开始学习。
回复 赞! 靠!

使用道具 举报

发表于 2017-3-18 01:13:20 | 显示全部楼层
老哥,我发现,选择大文件就会崩溃。。
回复 赞! 靠!

使用道具 举报

发表于 2017-3-22 20:28:04 | 显示全部楼层
回复

使用道具 举报

发表于 2017-7-24 07:03:25 | 显示全部楼层
先回复一下,看看里面的内容.
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2017-9-2 12:58:10 | 显示全部楼层
这是一个手动用汇编写无栈帧函数的实例,给局部变量从栈上分配内存+使用esp对参数和局部变量进行寻址等。
用了宏把偏移的计算自动化了。
有栈帧便于调试,代码也好写,不过栈帧本身对于运行而言是可有可无的。
其实优不优化栈帧意义不大。
回复 赞! 靠!

使用道具 举报

发表于 2017-9-19 18:01:29 | 显示全部楼层
VB】VB6+ASM写文件的SHA1哈希值计算工具
回复 赞! 靠!

使用道具 举报

发表于 2017-9-27 08:08:26 | 显示全部楼层
先回复一下先.
回复 赞! 靠!

使用道具 举报

发表于 2018-9-15 00:42:38 | 显示全部楼层
看看汇编怎么做
回复 赞! 靠!

使用道具 举报

发表于 2018-11-19 22:44:01 | 显示全部楼层
不错,正需要这个!!!!
回复 赞! 靠!

使用道具 举报

发表于 2020-1-15 15:19:12 | 显示全部楼层
学习一下
回复

使用道具 举报

发表于 2020-1-15 20:15:21 | 显示全部楼层
感觉VB6直接用WinAPI来算就够了
回复 赞! 靠!

使用道具 举报

发表于 2020-4-3 21:02:55 | 显示全部楼层
看看学习下
回复 赞! 靠!

使用道具 举报

发表于 2020-7-4 22:54:31 | 显示全部楼层
可以考虑用sha扩展指令集重写一下asm,把sha1rnds4, sha1nexte, sha1msg1, sha1msg2指令代进来。
需要检测cpuid[eax=7,ecx=0].ebx[bit29]置位。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2020-7-5 08:05:13 | 显示全部楼层
tangptr@126.com 发表于 2020-7-4 22:54
可以考虑用sha扩展指令集重写一下asm,把sha1rnds4, sha1nexte, sha1msg1, sha1msg2指令代进来。
需要检测c ...

在这之前我需要把文件IO改成支持超4G大文件流式读取的那种
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-23 17:26 , Processed in 0.043855 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表