吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3969|回复: 10
收起左侧

[原创] 160 个 CrackMe 之 086 -- zerocool.2 的注册算法分析和注册机实现

[复制链接]
solly 发表于 2019-6-28 22:30
本帖最后由 solly 于 2019-6-28 23:23 编辑

160 个 CrackMe 之 086 zerocool.2 是一个 VB 6.0 编译的 p-code 代码程序,所以算法追踪相对麻烦一点,我前面分析过的VB p-cdoe程序一样,使用三大工具配合,可以方便的跟踪  p-code 代码。
具体的过程和方法就不説了, 可以参考以前的贴子: https://www.52pojie.cn/thread-943702-1-1.html , 有详细的说明。
CrackMe 启动后如下图,需要输入用户名和注册码进行验证:
00.png

我们先通过 VB Explorer 确定事件的p-code地址,如下图所示:
10.png
这里可以确定按钮事件的开始地址(p-code 中的 esi 值)。

然后我们再通地 WKTVBDebugger 来确定上面按钮事件第一条指令的解析 Handler Proc,事件处理的第一条指令如下:
[Asm] 纯文本查看 复制代码
:0042D5D4  0474FF                          FLdRfVar                   ;Push LOCAL_008C;

这条指令的指令码为“04”,操作数的偏移量是“74FF",表示变量的相对基址的偏移是 0xFF74,也就是通过[ebp+0xFF74]就可取到变量的值,0xFF74是负数,转换一下就是[ebp-0x008C],这条指令翻译过来就是 Push LOCAL_008C。
有了指令,我们就可以到 WKTVBDebugger 中查到这条指令在 MSVBVM60.DLL 中的解释子程序了,如下图所示:
11.png
可以从 Opcodes Control Dialog 面板中,查到 "04" 指令的 Handler Proc 的入口地址为 0x660FD1DE

最后我们切到 OD,载入 CrackMe 后,直接 Ctrl + G ,跳转到我们前面查到的 Handler Proc。
13.png


跳转到相应解释子程序后,我们就可以以esi 指令地址值,下一个条件指令:
14.png


下完断点,直接 F9 运行 CrackMe,如下图所示:
16.png
输入用户名和注册码假码,再点“Check"按钮,就会在前面下的断点停下,可以进一步跟踪其算法了。

VB p-code 代码中,其局部变量都是以 EBP 的值为基址,加上指令中的偏移量,就可以访问其值,我们在 OD 也可通过[EBP+偏移量]查看变量值,如下所示:
18.png


具体的注册码算法代码如下,包括算法分析在内:
[Visual Basic] 纯文本查看 复制代码
:0042D5D4  0474FF                          FLdRfVar                   ;Push LOCAL_008C;字符串变量
:0042D5D7  21                              FLdPrThis                  ;[SR]=[stack2]
:0042D5D8  0F0C03                          VCallAd                    ;Return the control index 05
:0042D5DB  1978FF                          FStAdFunc                  ;
:0042D5DE  0878FF                          FLdPr                      ;[SR]=[LOCAL_0088]
***********Reference To:[propget]TextBox.Text
                              |
:0042D5E1  0DA0000000                      VCallHresult               ;Call ptr_0042BDB8; 从界面读取用户名
:0042D5E6  6C74FF                          ILdRf                      ;Push DWORD [LOCAL_008C]; 字符串变量,保存的用户名
******Possible String Ref To->""
                               |
:0042D5E9  1B0100                          LitStr                     ;Push ptr_0042BDB4
:0042D5EC  FB30                            EqStr                      ;将用户名字符串与空串比较
:0042D5EE  2F74FF                          FFree1Str                  ;SysFreeString [LOCAL_008C]; [LOCAL_008C]=0
:0042D5F1  1A78FF                          FFree1Ad                   ;Push [LOCAL_0088]; Call [[[LOCAL_0088]]+8]; [[LOCAL_0088]]=0 
:0042D5F4  1C5700                          BranchF                    ;If Pop=0 then ESI=0042D62B; 如果不为空则跳转
'
' if TextBox.Text = "" then
'
:0042D5F7  27F4FE                          LitVar                     ;PushVar LOCAL_010C
:0042D5FA  2714FF                          LitVar                     ;PushVar LOCAL_00EC
******Possible String Ref To->"Name required!"
                               |
:0042D5FD  3A44FF0200                      LitVarStr                  ;PushVarString ptr_0042BE08
:0042D602  4E34FF                          FStVarCopyObj              ;[LOCAL_00CC]=vbaVarDup(Pop)
:0042D605  0434FF                          FLdRfVar                   ;Push LOCAL_00CC
:0042D608  F530000000                      LitI4                      ;Push 00000030
******Possible String Ref To->"Entering a name would help!"
                               |
:0042D60D  3A64FF0300                      LitVarStr                  ;PushVarString ptr_0042BDCC
:0042D612  4E54FF                          FStVarCopyObj              ;[LOCAL_00AC]=vbaVarDup(Pop)
:0042D615  0454FF                          FLdRfVar                   ;Push LOCAL_00AC
**********Reference To->msvbvm60.rtcMsgBox
                               |
:0042D618  0A04001400                      ImpAdCallFPR4              ;Call ptr_00401040; 提示输入用户名!!!
:0042D61D  36080054FF34FF14                FFreeVar                   ;Free 0008/2 variants
:0042D628  1E4102                          Branch                     ;ESI=0042D815; 跳转到函数结束代码
'   MsgBox "Entering a name would help!", vbOKOnly, "Name required!"
'   Exit Sub
'
' end if
'
' 如果用户名不为空就跳转到这里,进行注册码校验
'
:0042D62B  2824FF0100                      LitVarI2                   ;PushVarInteger 0001; 在堆栈压入立即数 0x0001, 循环开始值
:0042D630  04E4FE                          FLdRfVar                   ;Push LOCAL_011C; 循环变量
:0042D633  0474FF                          FLdRfVar                   ;Push LOCAL_008C; 字符串变量
:0042D636  21                              FLdPrThis                  ;[SR]=[stack2]
:0042D637  0F0C03                          VCallAd                    ;Return the control index 05
:0042D63A  1978FF                          FStAdFunc                  ;
:0042D63D  0878FF                          FLdPr                      ;[SR]=[LOCAL_0088]
***********Reference To:[propget]TextBox.Text
                              |
:0042D640  0DA0000000                      VCallHresult               ;Call ptr_0042BDB8; 从界面读取用户名
:0042D645  6C74FF                          ILdRf                      ;Push DWORD [LOCAL_008C]; 字符串变量,保存的用户名
:0042D648  4A                              FnLenStr                   ;vbaLenBstr; 取得用户名的长度
:0042D649  FD6944FF                        CVarI4                     ;将长度值转换成 Long 类型的 Variable,并入栈,循环结束值
:0042D64D  2F74FF                          FFree1Str                  ;SysFreeString [LOCAL_008C]; [LOCAL_008C]=0
:0042D650  1A78FF                          FFree1Ad                   ;Push [LOCAL_0088]; Call [[[LOCAL_0088]]+8]; [[LOCAL_0088]]=0 
:0042D653  FE68C4FEE100                    ForVar                     ;循环体开始
'
' 生成一个 For 循环
' for i=1 to len(username) step 1
'
:0042D659  0474FF                          FLdRfVar                   ;Push LOCAL_008C; 字符串变量,用来保存用户名
:0042D65C  21                              FLdPrThis                  ;[SR]=[stack2]
:0042D65D  0F0C03                          VCallAd                    ;Return the control index 05
:0042D660  1978FF                          FStAdFunc                  ;
:0042D663  0878FF                          FLdPr                      ;[SR]=[LOCAL_0088]
***********Reference To:[propget]TextBox.Text
                              |
:0042D666  0DA0000000                      VCallHresult               ;Call ptr_0042BDB8; 从界面读取用户名
:0042D66B  04B4FE                          FLdRfVar                   ;Push LOCAL_014C; 保存结果的变量 sum
:0042D66E  2834FF0100                      LitVarI2                   ;PushVarInteger 0001; Mid()函数的长度参数
:0042D673  04E4FE                          FLdRfVar                   ;Push LOCAL_011C; 循环变量,Mid()函数的开始位置参数
:0042D676  FC22                            CI4Var                     ;vbaI4Var; 位置参数
:0042D678  3E74FF                          FLdZeroAd                  ;Push DWORD [LOCAL_008C]; [LOCAL_008C]=0; 载入 sum = 0
:0042D67B  4654FF                          CVarStr                    ; 字符串,用户名
:0042D67E  0414FF                          FLdRfVar                   ;Push LOCAL_00EC; 保存字符的变量
**********Reference To->msvbvm60.rtcMidCharVar
                               |
:0042D681  0A05001000                      ImpAdCallFPR4              ;Call ptr_00401046; 读取字符,Mid(username, i, 1)
:0042D686  0414FF                          FLdRfVar                   ;Push LOCAL_00EC; 用户名串中的字符
:0042D689  FDFEB0FE                        CStrVarVal                 ;
**********Reference To->msvbvm60.rtcAnsiValueBstr
                               |
:0042D68D  0B06000400                      ImpAdCallI2                ;Call ptr_0040104C; 取得字符的 ASCII 码值
:0042D692  4444FF                          CVarI2                     ;
:0042D695  FB94F4FE                        AddVar                     ; 求和 sum = sum + ASCII码值
:0042D699  FCF6B4FE                        FStVar                     ; 保存 sum 
'
' sum = sum + Asc(Mid(TextBox.Text, i, 1))
'
:0042D69D  2FB0FE                          FFree1Str                  ;SysFreeString [LOCAL_0150]; [LOCAL_0150]=0
:0042D6A0  1A78FF                          FFree1Ad                   ;Push [LOCAL_0088]; Call [[[LOCAL_0088]]+8]; [[LOCAL_0088]]=0 
:0042D6A3  36060054FF34FF14                FFreeVar                   ;Free 0006/2 variants
:0042D6AC  04E4FE                          FLdRfVar                   ;Push LOCAL_011C; 循环变量
:0042D6AF  FE7EC4FE8500                    NextStepVar                ;循环体结束
'
' 循环结束
' Next i
'
:0042D6B5  04B4FE                          FLdRfVar                   ;Push LOCAL_014C; 保存运算结果的变量 s
:0042D6B8  0474FF                          FLdRfVar                   ;Push LOCAL_008C; 压入 sum
:0042D6BB  21                              FLdPrThis                  ;[SR]=[stack2]
:0042D6BC  0F0C03                          VCallAd                    ;Return the control index 05
:0042D6BF  1978FF                          FStAdFunc                  ;
:0042D6C2  0878FF                          FLdPr                      ;[SR]=[LOCAL_0088]
***********Reference To:[propget]TextBox.Text
                              |
:0042D6C5  0DA0000000                      VCallHresult               ;Call ptr_0042BDB8; 从界面读取用户名
:0042D6CA  6C74FF                          ILdRf                      ;Push DWORD [LOCAL_008C]; 用户名
:0042D6CD  4A                              FnLenStr                   ;vbaLenBstr; 取得用户长度 n = len(username)
:0042D6CE  FD6964FF                        CVarI4                     ;
:0042D6D2  FBEF54FF                        ConcatVar                  ; 字符串连接 s = sum & n, 是将两个数字转换成字符串后连接起来
:0042D6D6  FCF6B4FE                        FStVar                     ;
:0042D6DA  2F74FF                          FFree1Str                  ;SysFreeString [LOCAL_008C]; [LOCAL_008C]=0
:0042D6DD  1A78FF                          FFree1Ad                   ;Push [LOCAL_0088]; Call [[[LOCAL_0088]]+8]; [[LOCAL_0088]]=0 
:0042D6E0  04B4FE                          FLdRfVar                   ;Push LOCAL_014C; 压入 s
:0042D6E3  FEC464FF33333333                LitVarR8                   ; cd1 = 1.7
:0042D6EF  FBB454FF                        MulVar                     ; id0 = s * 1.7
:0042D6F3  FACDCCCCCCCCCC00                LitDate                    ; cd2 = 2.1
:0042D6FC  FAB81E85EB51B80A                LitDate                    ; cd3 = 3.34 
:0042D705  FA9A999999999905                LitDate                    ; cd4 = 2.7
:0042D70E  FBCF                            PwrR8R8                    ; cd3^cd4
:0042D710  B3                              MulR8                      ; id1 = (cd3 ^ cd4) * cd2
:0042D711  FD6B44FF                        CVarR8                     ;
:0042D715  FBAC34FF                        IDvVar                     ; div1 = id0/id1
:0042D719  FCF6A0FE                        FStVar                     ; 保存 div1
:0042D71D  04B4FE                          FLdRfVar                   ;Push LOCAL_014C; s
:0042D720  04A0FE                          FLdRfVar                   ;Push LOCAL_0160; div1
:0042D723  FEC464FFF2D24D62                LitVarR8                   ; cd5 = 2.918
:0042D72F  FBB454FF                        MulVar                     ; cd5 * div1
:0042D733  FB9434FF                        AddVar                     ; d0 = (cd5 * div1) + s
:0042D737  FCF690FE                        FStVar                     ; 保存d0
:0042D73B  04B4FE                          FLdRfVar                   ;Push LOCAL_014C; s
:0042D73E  04A0FE                          FLdRfVar                   ;Push LOCAL_0160; div1
:0042D741  FB9454FF                        AddVar                     ; div1 + s
:0042D745  0490FE                          FLdRfVar                   ;Push LOCAL_0170; d0
:0042D748  FB9434FF                        AddVar                     ; d1 = d0 + (div1 + s)
:0042D74C  FCF680FE                        FStVar                     ; 保存 d1
:0042D750  3554FF                          FFree1Var                  ;Free LOCAL_00AC
:0042D753  04B4FE                          FLdRfVar                   ;Push LOCAL_014C; s
:0042D756  04A0FE                          FLdRfVar                   ;Push LOCAL_0160; div1
:0042D759  FB9454FF                        AddVar                     ; d2 = div1 + s
:0042D75D  0490FE                          FLdRfVar                   ;Push LOCAL_0170; d0
:0042D760  FEC464FF9CC420B0                LitVarR8                   ; cd6 = 1.213
:0042D76C  FBAC34FF                        IDvVar                     ; i0 = d0 / cd6
:0042D770  FB9414FF                        AddVar                     ; i1 = i0 + d2
:0042D774  FCF670FE                        FStVar                     ; 保存 i1
:0042D778  3554FF                          FFree1Var                  ;Free LOCAL_00AC
:0042D77B  04B4FE                          FLdRfVar                   ;Push LOCAL_014C; s
:0042D77E  04A0FE                          FLdRfVar                   ;Push LOCAL_0160; div1
:0042D781  FB9454FF                        AddVar                     ; i2 = s + div1
:0042D785  0490FE                          FLdRfVar                   ;Push LOCAL_0170; d0
:0042D788  FB9434FF                        AddVar                     ; d3 = i2 + d0
:0042D78C  0480FE                          FLdRfVar                   ;Push LOCAL_0180; d1
:0042D78F  0470FE                          FLdRfVar                   ;Push LOCAL_0190; i1
:0042D792  FBB414FF                        MulVar                     ; d4 = i1 * d1
:0042D796  FB94F4FE                        AddVar                     ; d5 = d4 + d3
******Possible String Ref To->"]qcc["
                               |
:0042D79A  3A64FF0700                      LitVarStr                  ;PushVarString ptr_0042BE2C; 字符串常量"]qcc["
:0042D79F  FBEF60FE                        ConcatVar                  ; 连接字符串 sn = d5 & "]qcc["
:0042D7A3  FCF6B4FE                        FStVar                     ; 将 sn 存入 LOCAL_014C
:0042D7A7  36060054FF34FFF4                FFreeVar                   ;Free 0006/2 variants
'
' sn 计算完毕,下面是比较注册码是否正确
'
:0042D7B0  0474FF                          FLdRfVar                   ;Push LOCAL_008C; 保存输入的注册码的变量
:0042D7B3  21                              FLdPrThis                  ;[SR]=[stack2]
:0042D7B4  0F0803                          VCallAd                    ;Return the control index 04
:0042D7B7  1978FF                          FStAdFunc                  ;
:0042D7BA  0878FF                          FLdPr                      ;[SR]=[LOCAL_0088]
***********Reference To:[propget]TextBox.Text
                              |
:0042D7BD  0DA0000000                      VCallHresult               ;Call ptr_0042BDB8; 读取界面输入的注册码
:0042D7C2  3E74FF                          FLdZeroAd                  ;Push DWORD [LOCAL_008C]; [LOCAL_008C]=0; 读入的注册码
:0042D7C5  4654FF                          CVarStr                    ;
:0042D7C8  5D                              HardType                   ;
:0042D7C9  04B4FE                          FLdRfVar                   ;Push LOCAL_014C 计算出来的注册码
:0042D7CC  FB40                            NeVarBool                  ;比较两个注册码,是否不相等(Ne, Not Equal),相等为 False,不相等为 True
:0042D7CE  1A78FF                          FFree1Ad                   ;Push [LOCAL_0088]; Call [[[LOCAL_0088]]+8]; [[LOCAL_0088]]=0 
:0042D7D1  3554FF                          FFree1Var                  ;Free LOCAL_00AC
:0042D7D4  1C2E02                          BranchF                    ;If Pop=0 then ESI=0042D802; 注册码相等则跳转
'
' if sn != snTextBox.Text then
'
:0042D7D7  2744FF                          LitVar                     ;PushVar LOCAL_00BC
:0042D7DA  25                              PopAdLdVar                 ;
:0042D7DB  2764FF                          LitVar                     ;PushVar LOCAL_009C
:0042D7DE  25                              PopAdLdVar                 ;
:0042D7DF  050800                          ImpAdLdRf                  ;Push ptr
:0042D7E2  240900                          NewIfNullPr                ;[Pop] [SR]
:0042D7E5  0DB0020A00                      VCallHresult               ;Call ptr_0042BE38; 显示注册码错误的信息
******Possible String Ref To->""
                               |
:0042D7EA  1B0100                          LitStr                     ;Push ptr_0042BDB4; 空字符串
:0042D7ED  21                              FLdPrThis                  ;[SR]=[stack2]
:0042D7EE  0F0803                          VCallAd                    ;Return the control index 04
:0042D7F1  1978FF                          FStAdFunc                  ;
:0042D7F4  0878FF                          FLdPr                      ;[SR]=[LOCAL_0088]
***********Reference To:[propput]TextBox.Text
                              |
:0042D7F7  0DA4000000                      VCallHresult               ;Call ptr_0042BDB8; 将注册码输入框中的错误注册码清空
:0042D7FC  1A78FF                          FFree1Ad                   ;Push [LOCAL_0088]; Call [[[LOCAL_0088]]+8]; [[LOCAL_0088]]=0 
:0042D7FF  1E4102                          Branch                     ;ESI=0042D815
'
' else
'
' 注册码正确来到这里
'
:0042D802  2744FF                          LitVar                     ;PushVar LOCAL_00BC
:0042D805  25                              PopAdLdVar                 ;
:0042D806  2764FF                          LitVar                     ;PushVar LOCAL_009C
:0042D809  25                              PopAdLdVar                 ;
:0042D80A  050B00                          ImpAdLdRf                  ;Push ptr
:0042D80D  240C00                          NewIfNullPr                ;[Pop] [SR]
:0042D810  0DB0020D00                      VCallHresult               ;Call ptr_0042BEB0; 显示注册码正确的信息
'
' end if
'
' 退出
'
:0042D815  13                              ExitProcHresult            ;
:0042D816  0000                            LargeBos                   ;IDE beginning of line with 00 byte codes



如果输入的注册码不正确,则会提示:
01.png
如果输入的注册码是正确的,则提示:
02.png


既然是 VB 程序,我们可以使用Excel+VBA来做注册机,界面如下:
30.png
上面包含了计算好的注册码,VBA代码如下:
31.png
具体代码如下:
[Visual Basic] 纯文本查看 复制代码
'
' 注册机源码
'
Sub getSN()

Dim i As Long, n As Long, sum As Long
Dim username As String, s As String, sn As String

username = Sheet1.Cells(4, 4)

If username = "" Then
  MsgBox "Entering a name would help!", vbOKOnly, "Name required!"
  Exit Sub
End If

n = Len(username) 'solly88
sum = 0

For i = 1 To n Step 1
  sum = sum + Asc(Mid(username, i, 1))
Next i

s = sum & n ' "6757"

Dim cd1 As Double, cd2 As Double, cd3 As Double
Dim cd4 As Double, cd5 As Double, cd6 As Double

Dim id0 As Double, id1 As Double, id2 As Double
Dim i0 As Long, i1 As Long, i2 As Long, div1 As Long

Dim d0 As Double, d1 As Double, d2 As Double
Dim d3 As Double, d4 As Double, d5 As Double

cd1 = 1.7
cd2 = 2.1
cd3 = 3.34
cd4 = 2.7
cd5 = 2.918
cd6 = 1.213

id0 = s * cd1
id1 = (cd3 ^ cd4) * cd2
div1 = Int(CLng(id0) / CLng(id1)) '212
d0 = (div1 * cd5) + s  '618.616 + 6757 = 7375.616
d1 = div1 + s + d0 ' 212 + 6757 + 7375.616 = 14344.616
d2 = div1 + s '212 + 6757 = 6969

i0 = CLng(d0) / CLng(cd6) '7376
i1 = CLng(i0 + d2) ' 14345

i2 = s + div1 '6969
d3 = i2 + d0 '14344.616
d4 = i1 * d1 '205773515.52
d5 = d4 + d3 '205787861.136

sn = d5 & "]qcc["

Sheet1.Cells(5, 4) = sn

Range("D5").Select
Selection.Copy

End Sub



分析完毕!!!

免费评分

参与人数 4威望 +1 吾爱币 +10 热心值 +4 收起 理由
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ntgeralt + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qinqinbaby + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
天空藍 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

骑龟赛跑 发表于 2019-6-28 22:47
大牛.大佬.膜拜一下.  
qinqinbaby 发表于 2019-6-29 00:32
学士天下 发表于 2019-6-29 10:34
kmd 发表于 2019-6-29 19:58
感谢,学习一下
92013 发表于 2019-7-6 13:23
感谢大佬分享
qazqaz4753 发表于 2019-7-8 17:28
谢谢分享,学习学习!!!!!
qazqaz4753 发表于 2019-7-8 17:33
学学,,谢谢分享!!!!
qazqaz4753 发表于 2019-7-8 21:10
6666666666
qazqaz4753 发表于 2019-7-8 22:00
感谢,学习一下,膜拜大神
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 18:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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