【破文标题】:土地拍卖竞标助手 专业版 6.31--MD5算法分析

【破文作者】:KuNgBiM[DFCG]

【作者邮箱】:gb_1227@163.com

【软件名称】:土地拍卖竞标助手 专业版 6.31

【整理日期】:2005-04-15 

【最新版本】:专业版 6.31

【编译语言】:Borland Delphi 6.0 - 7.0

【作者声明】:初学Crack,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

—————————————————————————————————
【破解过程】: 

1、试探:运行主程序注册,输入注册名、注册码,确认!程序提示"注册失败,请再次注册!"

2、侦测:用PEiD0.92查壳,无壳,Borland Delphi 6.0 - 7.0编译。

3、初步下药:使出法宝,用W32Dasm进行静态反汇编,查找“注册失败,请再次注册!”字符串,
   但后来我直捣黄龙,用W32Dasm找到“注册成功,欢迎使用!”字符串,来到下面的地方:


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005EA9E8(C)
|
:005EA9F4 8D55DC                  lea edxdword ptr [ebp-24]
:005EA9F7 A194D86600              mov eaxdword ptr [0066D894]
:005EA9FC 8B00                    mov eaxdword ptr [eax]
:005EA9FE E8159EFAFF              call 00594818           //检测机器码是否合法!原因:下看!

========================  原因如下 ===========================
.............(略)

* Possible StringData Ref from Code Obj ->"75EA2-2D12A-AA55A-FBCC7"  //这可能是被软件作者BAN掉了的ID号,呵呵
                                  |
:005EA9DC B86CAB5E00              mov eax, 005EAB6C
:005EA9E1 E886A0E1FF              call 00404A6C
:005EA9E6 85C0                    test eaxeax
:005EA9E8 740A                    je 005EA9F4
:005EA9EA E83595E1FF              call 00403F24
:005EA9EF E9B3000000              jmp 005EAAA7

===============================================================

:005EAA03 8D45DC                  lea eaxdword ptr [ebp-24]
:005EAA06 8D55EC                  lea edxdword ptr [ebp-14]
:005EAA09 E86E080000              call 005EB27C                  //算法CALL,跟进!
:005EAA0E 8B45EC                  mov eaxdword ptr [ebp-14]
:005EAA11 8B159CD56600            mov edxdword ptr [0066D59C]
:005EAA17 8B12                    mov edxdword ptr [edx]
:005EAA19 E84EA0E1FF              call 00404A6C                  //比对CALL
:005EAA1E 85C0                    test eaxeax
:005EAA20 7E2E                    jle 005EAA50                   //关键跳转,跳则挂!
:005EAA22 6A40                    push 00000040
:005EAA24 8D55D8                  lea edxdword ptr [ebp-28]
:005EAA27 A19CD96600              mov eaxdword ptr [0066D99C]
:005EAA2C 8B00                    mov eaxdword ptr [eax]
:005EAA2E E84574EBFF              call 004A1E78
:005EAA33 8B45D8                  mov eaxdword ptr [ebp-28]
:005EAA36 E8ED9EE1FF              call 00404928
:005EAA3B 8BC8                    mov ecxeax

* Possible StringData Ref from Code Obj ->"注册成功,欢迎使用!"      //字符串查找来到这里!
                                  |
:005EAA3D BA84AB5E00              mov edx, 005EAB84
:005EAA42 A19CD96600              mov eaxdword ptr [0066D99C]
:005EAA47 8B00                    mov eaxdword ptr [eax]
:005EAA49 E8A67AEBFF              call 004A24F4
:005EAA4E EB2C                    jmp 005EAA7C

..............(略)


4、对症下药:

下面换作Ollydbg来动态跟踪!载入程序后,在005EAA09处 F2下断!F8跟进!

================== 跟进 005EAA09  call 005EB27C  ===========================

005EB27C    55              push ebp
005EB27D    8BEC            mov ebp,esp
005EB27F    83C4 D8         add esp,-28
005EB282    53              push ebx
005EB283    56              push esi
005EB284    57              push edi
005EB285    33C9            xor ecx,ecx
005EB287    894D D8         mov dword ptr ss:[ebp-28],ecx
005EB28A    894D E8         mov dword ptr ss:[ebp-18],ecx
005EB28D    894D DC         mov dword ptr ss:[ebp-24],ecx
005EB290    894D FC         mov dword ptr ss:[ebp-4],ecx
005EB293    8BF0            mov esi,eax
005EB295    8D7D EC         lea edi,dword ptr ss:[ebp-14]
005EB298    A5              movs dword ptr es:[edi],dword ptr ds>
005EB299    A5              movs dword ptr es:[edi],dword ptr ds>
005EB29A    A5              movs dword ptr es:[edi],dword ptr ds>
005EB29B    A5              movs dword ptr es:[edi],dword ptr ds>
005EB29C    8BF2            mov esi,edx
005EB29E    33C0            xor eax,eax
005EB2A0    55              push ebp
005EB2A1    68 5EB35E00     push GSA.005EB35E
005EB2A6    64:FF30         push dword ptr fs:[eax]
005EB2A9    64:8920         mov dword ptr fs:[eax],esp
005EB2AC    8D45 E8         lea eax,dword ptr ss:[ebp-18]
005EB2AF    50              push eax
005EB2B0    8D55 DC         lea edx,dword ptr ss:[ebp-24]
005EB2B3    8D45 EC         lea eax,dword ptr ss:[ebp-14]
005EB2B6    E8 D195FAFF     call GSA.0059488C              //算法CALL,F8再跟进!
...............(略)

================== 跟进 005EB2B6   call GSA.0059488C   ===========================

0059488C    55              push ebp
0059488D    8BEC            mov ebp,esp
0059488F    83C4 E8         add esp,-18
00594892    53              push ebx
00594893    56              push esi
00594894    57              push edi
00594895    33C9            xor ecx,ecx
00594897    894D EC         mov dword ptr ss:[ebp-14],ecx
0059489A    894D E8         mov dword ptr ss:[ebp-18],ecx
0059489D    8BF0            mov esi,eax
0059489F    8D7D F0         lea edi,dword ptr ss:[ebp-10]
005948A2    A5              movs dword ptr es:[edi],dword ptr ds>
005948A3    A5              movs dword ptr es:[edi],dword ptr ds>
005948A4    A5              movs dword ptr es:[edi],dword ptr ds>
005948A5    A5              movs dword ptr es:[edi],dword ptr ds>
005948A6    8BFA            mov edi,edx
005948A8    33C0            xor eax,eax
005948AA    55              push ebp
005948AB    68 27495900     push GSA.00594927
005948B0    64:FF30         push dword ptr fs:[eax]
005948B3    64:8920         mov dword ptr fs:[eax],esp
005948B6    8BC7            mov eax,edi
005948B8    E8 9BFBE6FF     call GSA.00404458              //算法CALL,F8继续跟进!!
005948BD    B3 10           mov bl,10
005948BF    8D75 F0         lea esi,dword ptr ss:[ebp-10]

================== 跟进 005948B8    call GSA.00404458   ===========================

00404458    8B10            mov edx,dword ptr ds:[eax]
0040445A    85D2            test edx,edx
0040445C    74 1C           je short GSA.0040447A
0040445E    C700 00000000   mov dword ptr ds:[eax],0
00404464    8B4A F8         mov ecx,dword ptr ds:[edx-8]
00404467    49              dec ecx
00404468    7C 10           jl short GSA.0040447A
0040446A    F0:FF4A F8      lock dec dword ptr ds:[edx-8]
0040446E    75 0A           jnz short GSA.0040447A
00404470    50              push eax
00404471    8D42 F8         lea eax,dword ptr ds:[edx-8]
00404474    E8 B3E3FFFF     call GSA.0040282C
00404479    58              pop eax
0040447A    C3              retn                     //返回


返回来到下面代码段:

005948BD    B3 10           mov bl,10
005948BF    8D75 F0         lea esi,dword ptr ss:[ebp-10]
005948C2    FF37            push dword ptr ds:[edi]
005948C4    8D45 EC         lea eax,dword ptr ss:[ebp-14]
005948C7    33D2            xor edx,edx
005948C9    8A16            mov dl,byte ptr ds:[esi]
005948CB    C1EA 04         shr edx,4
005948CE    83E2 0F         and edx,0F
005948D1    8A92 04CB6600   mov dl,byte ptr ds:[edx+66CB04]       //MD5算法表(标准的MD5)
005948D7    E8 64FDE6FF     call GSA.00404640       //跟进则循环运算机器码的转换值,所以,在这里我们就不深入研究MD5算法了

......................(略)

以上运算完毕后经过2个返回来到:

005EB2BB    8B45 DC         mov eax,dword ptr ss:[ebp-24]   //返回来到这里,这时的堆栈显示如下

=============================== 友好堆栈 ====================================

堆栈 ss:[0012F0D0]=01044560, (ASCII "8d3186c30776cd1c19e2af4f59e169c1")     //大家用MD5计算器就可以计算出这个数值!
eax=00000000

============================================================================

005EB2BE    8945 E0         mov dword ptr ss:[ebp-20],eax    //压栈 EAX
005EB2C1    C645 E4 0B      mov byte ptr ss:[ebp-1C],0B
005EB2C5    8D55 E0         lea edx,dword ptr ss:[ebp-20]
005EB2C8    33C9            xor ecx,ecx                      //ecx=0
005EB2CA    B8 74B35E00     mov eax,GSA.005EB374                 ; ASCII "%s"    //开始赋值(把转换值赋给变量“%s”)

=============================== 友好堆栈  ===================================

005EB374=GSA.005EB374 (ASCII "%s")
eax=01044560, (ASCII "8d3186c30776cd1c19e2af4f59e169c1")

============================================================================

005EB2CF    E8 1CF1E1FF     call GSA.0040A3F0
005EB2D4    8B45 E8         mov eax,dword ptr ss:[ebp-18]
005EB2D7    8D55 FC         lea edx,dword ptr ss:[ebp-4]
005EB2DA    E8 05DAE1FF     call GSA.00408CE4                //F8 跟进,依次把MD5的转换值由小写改为大写
005EB2DF    8BC6            mov eax,esi
005EB2E1    E8 7291E1FF     call GSA.00404458
005EB2E6    33DB            xor ebx,ebx
005EB2E8    85DB            test ebx,ebx
005EB2EA    75 15           jnz short GSA.005EB301
005EB2EC    56              push esi
005EB2ED    8BD3            mov edx,ebx
005EB2EF    C1E2 02         shl edx,2
005EB2F2    B9 04000000     mov ecx,4
005EB2F7    8B45 FC         mov eax,dword ptr ss:[ebp-4]
005EB2FA    E8 8996E1FF     call GSA.00404988
005EB2FF    EB 2C           jmp short GSA.005EB32D

================== 跟进 005EB2DA     call GSA.00408CE4     ===========================

00408CE4    53              push ebx
00408CE5    56              push esi
00408CE6    57              push edi
00408CE7    8BFA            mov edi,edx
00408CE9    8BF0            mov esi,eax
00408CEB    8BC6            mov eax,esi
00408CED    E8 36BAFFFF     call GSA.00404728
00408CF2    8BD8            mov ebx,eax
00408CF4    8BC7            mov eax,edi
00408CF6    8BD3            mov edx,ebx
00408CF8    E8 B7BDFFFF     call GSA.00404AB4
00408CFD    8BD6            mov edx,esi
00408CFF    8B37            mov esi,dword ptr ds:[edi]
00408D01    85DB            test ebx,ebx
00408D03    74 15           je short GSA.00408D1A
00408D05    8A02            mov al,byte ptr ds:[edx]    //逐个数据开始转换
00408D07    3C 61           cmp al,61
00408D09    72 06           jb short GSA.00408D11
00408D0B    3C 7A           cmp al,7A
00408D0D    77 02           ja short GSA.00408D11
00408D0F    2C 20           sub al,20
00408D11    8806            mov byte ptr ds:[esi],al
00408D13    42              inc edx
00408D14    46              inc esi
00408D15    4B              dec ebx
00408D16    85DB            test ebx,ebx
00408D18  ^ 75 EB           jnz short GSA.00408D05     //转换结束,转换完毕后,停止转换,从这里跳出
00408D1A    5F              pop edi
00408D1B    5E              pop esi
00408D1C    5B              pop ebx                              ; 01048B6C
00408D1D    C3              retn                       //返回程序

返回到这里:

005EB2DF    8BC6            mov eax,esi
005EB2E1    E8 7291E1FF     call GSA.00404458
005EB2E6    33DB            xor ebx,ebx
005EB2E8    85DB            test ebx,ebx
005EB2EA    75 15           jnz short GSA.005EB301
005EB2EC    56              push esi
005EB2ED    8BD3            mov edx,ebx
005EB2EF    C1E2 02         shl edx,2
005EB2F2    B9 04000000     mov ecx,4                       //从转换码首位开始,依次取4位,作为SN1
005EB2F7    8B45 FC         mov eax,dword ptr ss:[ebp-4]
005EB2FA    E8 8996E1FF     call GSA.00404988
005EB2FF    EB 2C           jmp short GSA.005EB32D
005EB301    FF36            push dword ptr ds:[esi]
005EB303    68 80B35E00     push GSA.005EB380               //取出SN1=“8D31”
005EB308    8D45 D8         lea eax,dword ptr ss:[ebp-28]   //从第4位开始,依次再取4位,作为SN2
005EB30B    50              push eax
005EB30C    8BD3            mov edx,ebx
005EB30E    C1E2 02         shl edx,2
005EB311    B9 04000000     mov ecx,4
005EB316    8B45 FC         mov eax,dword ptr ss:[ebp-4]
005EB319    E8 6A96E1FF     call GSA.00404988
005EB31E    FF75 D8         push dword ptr ss:[ebp-28]      //取出SN2=“186C”
005EB321    8BC6            mov eax,esi
005EB323    BA 03000000     mov edx,3
005EB328    E8 BB94E1FF     call GSA.004047E8
005EB32D    43              inc ebx                         //把SN1与SN2用字符“-”连接,得到SN
005EB32E    83FB 02         cmp ebx,2
005EB331  ^ 75 B5           jnz short GSA.005EB2E8
005EB333    33C0            xor eax,eax                     //eax=005EB32D
005EB335    5A              pop edx
005EB336    59              pop ecx
005EB337    59              pop ecx
005EB338    64:8910         mov dword ptr fs:[eax],edx
005EB33B    68 65B35E00     push GSA.005EB365
005EB340    8D45 D8         lea eax,dword ptr ss:[ebp-28]
005EB343    BA 02000000     mov edx,2
005EB348    E8 2F91E1FF     call GSA.0040447C
005EB34D    8D45 E8         lea eax,dword ptr ss:[ebp-18]        //eax=00000000
005EB350    E8 0391E1FF     call GSA.00404458
005EB355    8D45 FC         lea eax,dword ptr ss:[ebp-4]         //eax=0012F0DC
005EB358    E8 FB90E1FF     call GSA.00404458
005EB35D    C3              retn
005EB35E  ^\E9 198AE1FF     jmp GSA.00403D7C
005EB363  ^ EB DB           jmp short GSA.005EB340
005EB365    5F              pop edi
005EB366    5E              pop esi
005EB367    5B              pop ebx
005EB368    8BE5            mov esp,ebp
005EB36A    5D              pop ebp                              ; 0012F140
005EB36B    C3              retn                         //返回验证

...............(略)


返回来到下面代码段:

005EAA0E    8B45 EC         mov eax,dword ptr ss:[ebp-14]        //返回到这里,注意看堆栈!

=============================== 友好堆栈  ===================================

堆栈 ss:[0012F12C]=01017188, (ASCII "8D31-186C")       //这就是所谓的注册码?
eax=0012F0F0

============================================================================

005EAA11    8B15 9CD56600   mov edx,dword ptr ds:[66D59C]        ; GSA.0066F320      //压栈赋值 EAX=“8D31-186C”
005EAA17    8B12            mov edx,dword ptr ds:[edx]             //提取我们输入的假值,赋值给 EDX=“1111-2222”

=============================== 友好堆栈  ===================================

ds:[0066F320]=01042054, (ASCII "1111-2222")
edx=0066F320 (GSA.0066F320)

============================================================================
005EAA19    E8 4EA0E1FF     call GSA.00404A6C                     //验证CALL
005EAA1E    85C0            test eax,eax
005EAA20    7E 2E           jle short GSA.005EAA50                //关键跳转


================== 跟进 005EAA19    call GSA.00404A6C ======================
   
00404A6C    85C0            test eax,eax                     //检验EAX中是否有值
00404A6E    74 40           je short GSA.00404AB0
00404A70    85D2            test edx,edx                     //检验EDX中是否有值
00404A72    74 31           je short GSA.00404AA5
00404A74    53              push ebx
00404A75    56              push esi
00404A76    57              push edi
00404A77    89C6            mov esi,eax                      //把EAX中的值转移给ESI
00404A79    89D7            mov edi,edx                      //把EDX中的值转移给EDI
00404A7B    8B4F FC         mov ecx,dword ptr ds:[edi-4]     //注册码位数应该是9位数
00404A7E    57              push edi
00404A7F    8B56 FC         mov edx,dword ptr ds:[esi-4]     //取出输入的假码,计算注册码位数
00404A82    4A              dec edx                          //若商数等于1,则接着下面的一位一位的比对,否则跳出!
00404A83    78 1B           js short GSA.00404AA0

[比对部分]..............(略)


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

算法总结:

1。机器码经过MD5运算转换为机器特征码

2。把转换后的机器特征码再由小写转换成大写

3。分别取机器特征码前4位数作为SN1以及机器特征码从第4位开始后的4位数作为SN2,并用“-”连接SN1、SN2,然后组合成SN(注册码)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

注册码保存在:(2处地方)

第1处:

[HKEY_CURRENT_USER\Software\ChaseSun\EstaExplValue 6.0]
"PrgDir"="C:\\Program Files\\追日软件\\土地拍卖竞标助手 专业版 6.31"
"User"="XXXXX-XXXXX-XXXXX-XXXXX"
"Organization"="XXXXX-XXXXX-XXXXX-XXXXX"
"Code"="8D31-186C"

第2处:

[HKEY_USERS\S-1-5-21-436374069-1383384898-839522115-1003\Software\ChaseSun\EstaExplValue 6.0]
"PrgDir"="C:\\Program Files\\追日软件\\土地拍卖竞标助手 专业版 6.31"
"User"="XXXXX-XXXXX-XXXXX-XXXXX"
"Organization"="XXXXX-XXXXX-XXXXX-XXXXX"
"Code"="8D31-186C"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

注:上述所指 "XXXXX-XXXXX-XXXXX-XXXXX" 中的“X”是我所编辑过的,实际上应该是机器码,避免被作者BAN ID!呵呵~~~

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

6、算法注册机源码

【作者声明】该注册机源码只能作为学习,请勿用于商业用途或是将本文方法制作的注册机任意传播,造成后果,本人一概不负。 


------------Visual Basic 6.0在WINX2000下编译通过--------------

'窗体部分

Private Sub Text1_Change()
Dim tzm, zcm
Set c1 = New clsMD5                            '调用算法模块:先将机器码转换成 MD5密钥,等待下步运算
tzm = c1.Md5_String_Calc(Text1.Text)
zcm = Mid(tzm, 1, 4) & "-" & Mid(tzm, 4, 4)    '取特征码前4位数作为SN1以及特征码从第4位开始后的4位数作为SN2,并用“-”连接
Text2.Text = zcm
End Sub


'类模块部分,模块名称:clsMD5

Option Explicit

' Visual Basic MD5 Implementation
' Robert Hubley and David Midkiff
' modify by simonyan, Support chinese
' Standard MD5 implementation optimised for the Visual Basic environment.
' Conforms to all standards and can be used in digital signature or password
' protection related schemes.

Private Const OFFSET_4 = 4294967296#
Private Const MAXINT_4 = 2147483647
Private State(4) As Long
Private ByteCounter As Long
Private ByteBuffer(63) As Byte
Private Const S11 = 7
Private Const S12 = 12
Private Const S13 = 17
Private Const S14 = 22
Private Const S21 = 5
Private Const S22 = 9
Private Const S23 = 14
Private Const S24 = 20
Private Const S31 = 4
Private Const S32 = 11
Private Const S33 = 16
Private Const S34 = 23
Private Const S41 = 6
Private Const S42 = 10
Private Const S43 = 15
Private Const S44 = 21
Property Get RegisterA() As String
    RegisterA = State(1)
End Property
Property Get RegisterB() As String
    RegisterB = State(2)
End Property

Property Get RegisterC() As String
    RegisterC = State(3)
End Property

Property Get RegisterD() As String
    RegisterD = State(4)
End Property
Public Function Md5_String_Calc(SourceString As String) As String
    MD5Init
    MD5Update LenB(StrConv(SourceString, vbFromUnicode)), StringToArray(SourceString)
    MD5Final
    Md5_String_Calc = GetValues
End Function
Public Function Md5_File_Calc(InFile As String) As String

GoSub begin

begin:
    Dim FileO As Integer
    FileO = FreeFile
    Call FileLen(InFile)
    Open InFile For Binary Access Read As #FileO
    MD5Init
    Do While Not EOF(FileO)
        Get #FileO, , ByteBuffer
        If Loc(FileO) < LOF(FileO) Then
            ByteCounter = ByteCounter + 64
            MD5Transform ByteBuffer
        End If
    Loop
    ByteCounter = ByteCounter + (LOF(FileO) Mod 64)
    Close #FileO
    MD5Final
    Md5_File_Calc = GetValues
End Function
Private Function StringToArray(InString As String) As Byte()
    Dim I As Integer, bytBuffer() As Byte
    ReDim bytBuffer(LenB(StrConv(InString, vbFromUnicode)))
    bytBuffer = StrConv(InString, vbFromUnicode)
    StringToArray = bytBuffer
End Function
Public Function GetValues() As String
    GetValues = LongToString(State(1)) & LongToString(State(2)) & LongToString(State(3)) & LongToString(State(4))
End Function
Private Function LongToString(Num As Long) As String
        Dim a As Byte, B As Byte, C As Byte, D As Byte
        a = Num And &HFF&
        If a < 16 Then LongToString = "0" & Hex(a) Else LongToString = Hex(a)
        B = (Num And &HFF00&) \ 256
        If B < 16 Then LongToString = LongToString & "0" & Hex(B) Else LongToString = LongToString & Hex(B)
        C = (Num And &HFF0000) \ 65536
        If C < 16 Then LongToString = LongToString & "0" & Hex(C) Else LongToString = LongToString & Hex(C)
        If Num < 0 Then D = ((Num And &H7F000000) \ 16777216) Or &H80& Else D = (Num And &HFF000000) \ 16777216
        If D < 16 Then LongToString = LongToString & "0" & Hex(D) Else LongToString = LongToString & Hex(D)
End Function

Public Sub MD5Init()
    ByteCounter = 0
    State(1) = UnsignedToLong(1732584193#)
    State(2) = UnsignedToLong(4023233417#)
    State(3) = UnsignedToLong(2562383102#)
    State(4) = UnsignedToLong(271733878#)
End Sub

Public Sub MD5Final()
    Dim dblBits As Double, padding(72) As Byte, lngBytesBuffered As Long
    padding(0) = &H80
    dblBits = ByteCounter * 8
    lngBytesBuffered = ByteCounter Mod 64
    If lngBytesBuffered <= 56 Then MD5Update 56 - lngBytesBuffered, padding Else MD5Update 120 - ByteCounter, padding
    padding(0) = UnsignedToLong(dblBits) And &HFF&
    padding(1) = UnsignedToLong(dblBits) \ 256 And &HFF&
    padding(2) = UnsignedToLong(dblBits) \ 65536 And &HFF&
    padding(3) = UnsignedToLong(dblBits) \ 16777216 And &HFF&
    padding(4) = 0
    padding(5) = 0
    padding(6) = 0
    padding(7) = 0
    MD5Update 8, padding
End Sub
Public Sub MD5Update(InputLen As Long, InputBuffer() As Byte)
    Dim II As Integer, I As Integer, J As Integer, K As Integer, lngBufferedBytes As Long, lngBufferRemaining As Long, lngRem As Long

    lngBufferedBytes = ByteCounter Mod 64
    lngBufferRemaining = 64 - lngBufferedBytes
    ByteCounter = ByteCounter + InputLen

    If InputLen >= lngBufferRemaining Then
        For II = 0 To lngBufferRemaining - 1
            ByteBuffer(lngBufferedBytes + II) = InputBuffer(II)
        Next II
        MD5Transform ByteBuffer
        lngRem = (InputLen) Mod 64
        For I = lngBufferRemaining To InputLen - II - lngRem Step 64
            For J = 0 To 63
                ByteBuffer(J) = InputBuffer(I + J)
            Next J
            MD5Transform ByteBuffer
        Next I
        lngBufferedBytes = 0
    Else
      I = 0
    End If
    For K = 0 To InputLen - I - 1
        ByteBuffer(lngBufferedBytes + K) = InputBuffer(I + K)
    Next K
End Sub
Private Sub MD5Transform(Buffer() As Byte)
    Dim X(16) As Long, a As Long, B As Long, C As Long, D As Long
    
    a = State(1)
    B = State(2)
    C = State(3)
    D = State(4)
    Decode 64, X, Buffer
    FF a, B, C, D, X(0), S11, -680876936
    FF D, a, B, C, X(1), S12, -389564586
    FF C, D, a, B, X(2), S13, 606105819
    FF B, C, D, a, X(3), S14, -1044525330
    FF a, B, C, D, X(4), S11, -176418897
    FF D, a, B, C, X(5), S12, 1200080426
    FF C, D, a, B, X(6), S13, -1473231341
    FF B, C, D, a, X(7), S14, -45705983
    FF a, B, C, D, X(8), S11, 1770035416
    FF D, a, B, C, X(9), S12, -1958414417
    FF C, D, a, B, X(10), S13, -42063
    FF B, C, D, a, X(11), S14, -1990404162
    FF a, B, C, D, X(12), S11, 1804603682
    FF D, a, B, C, X(13), S12, -40341101
    FF C, D, a, B, X(14), S13, -1502002290
    FF B, C, D, a, X(15), S14, 1236535329

    GG a, B, C, D, X(1), S21, -165796510
    GG D, a, B, C, X(6), S22, -1069501632
    GG C, D, a, B, X(11), S23, 643717713
    GG B, C, D, a, X(0), S24, -373897302
    GG a, B, C, D, X(5), S21, -701558691
    GG D, a, B, C, X(10), S22, 38016083
    GG C, D, a, B, X(15), S23, -660478335
    GG B, C, D, a, X(4), S24, -405537848
    GG a, B, C, D, X(9), S21, 568446438
    GG D, a, B, C, X(14), S22, -1019803690
    GG C, D, a, B, X(3), S23, -187363961
    GG B, C, D, a, X(8), S24, 1163531501
    GG a, B, C, D, X(13), S21, -1444681467
    GG D, a, B, C, X(2), S22, -51403784
    GG C, D, a, B, X(7), S23, 1735328473
    GG B, C, D, a, X(12), S24, -1926607734

    HH a, B, C, D, X(5), S31, -378558
    HH D, a, B, C, X(8), S32, -2022574463
    HH C, D, a, B, X(11), S33, 1839030562
    HH B, C, D, a, X(14), S34, -35309556
    HH a, B, C, D, X(1), S31, -1530992060
    HH D, a, B, C, X(4), S32, 1272893353
    HH C, D, a, B, X(7), S33, -155497632
    HH B, C, D, a, X(10), S34, -1094730640
    HH a, B, C, D, X(13), S31, 681279174
    HH D, a, B, C, X(0), S32, -358537222
    HH C, D, a, B, X(3), S33, -722521979
    HH B, C, D, a, X(6), S34, 76029189
    HH a, B, C, D, X(9), S31, -640364487
    HH D, a, B, C, X(12), S32, -421815835
    HH C, D, a, B, X(15), S33, 530742520
    HH B, C, D, a, X(2), S34, -995338651

    II a, B, C, D, X(0), S41, -198630844
    II D, a, B, C, X(7), S42, 1126891415
    II C, D, a, B, X(14), S43, -1416354905
    II B, C, D, a, X(5), S44, -57434055
    II a, B, C, D, X(12), S41, 1700485571
    II D, a, B, C, X(3), S42, -1894986606
    II C, D, a, B, X(10), S43, -1051523
    II B, C, D, a, X(1), S44, -2054922799
    II a, B, C, D, X(8), S41, 1873313359
    II D, a, B, C, X(15), S42, -30611744
    II C, D, a, B, X(6), S43, -1560198380
    II B, C, D, a, X(13), S44, 1309151649
    II a, B, C, D, X(4), S41, -145523070
    II D, a, B, C, X(11), S42, -1120210379
    II C, D, a, B, X(2), S43, 718787259
    II B, C, D, a, X(9), S44, -343485551

    State(1) = LongOverflowAdd(State(1), a)
    State(2) = LongOverflowAdd(State(2), B)
    State(3) = LongOverflowAdd(State(3), C)
    State(4) = LongOverflowAdd(State(4), D)
End Sub

Private Sub Decode(Length As Integer, OutputBuffer() As Long, InputBuffer() As Byte)
    Dim intDblIndex As Integer, intByteIndex As Integer, dblSum As Double
    For intByteIndex = 0 To Length - 1 Step 4
        dblSum = InputBuffer(intByteIndex) + InputBuffer(intByteIndex + 1) * 256# + InputBuffer(intByteIndex + 2) * 65536# + InputBuffer(intByteIndex + 3) * 16777216#
        OutputBuffer(intDblIndex) = UnsignedToLong(dblSum)
        intDblIndex = intDblIndex + 1
    Next intByteIndex
End Sub
Private Function FF(a As Long, B As Long, C As Long, D As Long, X As Long, S As Long, ac As Long) As Long
    a = LongOverflowAdd4(a, (B And C) Or (Not (B) And D), X, ac)
    a = LongLeftRotate(a, S)
    a = LongOverflowAdd(a, B)
End Function
Private Function GG(a As Long, B As Long, C As Long, D As Long, X As Long, S As Long, ac As Long) As Long
    a = LongOverflowAdd4(a, (B And D) Or (C And Not (D)), X, ac)
    a = LongLeftRotate(a, S)
    a = LongOverflowAdd(a, B)
End Function
Private Function HH(a As Long, B As Long, C As Long, D As Long, X As Long, S As Long, ac As Long) As Long
    a = LongOverflowAdd4(a, B Xor C Xor D, X, ac)
    a = LongLeftRotate(a, S)
    a = LongOverflowAdd(a, B)
End Function
Private Function II(a As Long, B As Long, C As Long, D As Long, X As Long, S As Long, ac As Long) As Long
    a = LongOverflowAdd4(a, C Xor (B Or Not (D)), X, ac)
    a = LongLeftRotate(a, S)
    a = LongOverflowAdd(a, B)
End Function

Function LongLeftRotate(value As Long, Bits As Long) As Long
    Dim lngSign As Long, lngI As Long
    Bits = Bits Mod 32
    If Bits = 0 Then LongLeftRotate = value: Exit Function
    For lngI = 1 To Bits
        lngSign = value And &HC0000000
        value = (value And &H3FFFFFFF) * 2
        value = value Or ((lngSign < 0) And 1) Or (CBool(lngSign And &H40000000) And &H80000000)
    Next
    LongLeftRotate = value
End Function
Private Function LongOverflowAdd(Val1 As Long, Val2 As Long) As Long
    Dim lngHighWord As Long, lngLowWord As Long, lngOverflow As Long
    lngLowWord = (Val1 And &HFFFF&) + (Val2 And &HFFFF&)
    lngOverflow = lngLowWord \ 65536
    lngHighWord = (((Val1 And &HFFFF0000) \ 65536) + ((Val2 And &HFFFF0000) \ 65536) + lngOverflow) And &HFFFF&
    LongOverflowAdd = UnsignedToLong((lngHighWord * 65536#) + (lngLowWord And &HFFFF&))
End Function
Private Function LongOverflowAdd4(Val1 As Long, Val2 As Long, val3 As Long, val4 As Long) As Long
    Dim lngHighWord As Long, lngLowWord As Long, lngOverflow As Long
    lngLowWord = (Val1 And &HFFFF&) + (Val2 And &HFFFF&) + (val3 And &HFFFF&) + (val4 And &HFFFF&)
    lngOverflow = lngLowWord \ 65536
    lngHighWord = (((Val1 And &HFFFF0000) \ 65536) + ((Val2 And &HFFFF0000) \ 65536) + ((val3 And &HFFFF0000) \ 65536) + ((val4 And &HFFFF0000) \ 65536) + lngOverflow) And &HFFFF&
    LongOverflowAdd4 = UnsignedToLong((lngHighWord * 65536#) + (lngLowWord And &HFFFF&))
End Function

Private Function UnsignedToLong(value As Double) As Long
    If value < 0 Or value >= OFFSET_4 Then Error 6
    If value <= MAXINT_4 Then UnsignedToLong = value Else UnsignedToLong = value - OFFSET_4
End Function
Private Function LongToUnsigned(value As Long) As Double
    If value < 0 Then LongToUnsigned = value + OFFSET_4 Else LongToUnsigned = value
End Function


--------------------------------------------------------------------------
(本文完)


版权所有(C)2005 KuNgBiM[DFCG]         Copyright (C) 2005 KuNgBiM[DFCG]

--------------------------------------------------------------------------
          Cracked BY KuNgBiM[DFCG]

                2005-04-17

               04:28:36 AM