飘云 发表于 2005-10-20 03:28:45

[PYG]算法分析入门第十五课

【破文标题】PYG算法分析入门第十五课
【破文作者】飘云
【作者邮箱】[email protected]
【作者主页】www.chinapyg.com
【破解工具】OD
【破解平台】Win9x/NT/2000/XP
【软件名称】tsrh-crackme
【软件大小】31KB
【原版下载】论坛下载
【保护方式】Nag+序列号
【软件简介】tsrh-crackme
------------------------------------------------------------------------
【破解过程】
NAG 解除就不分析了,简单
0040105D   E8 99020000       call tsrh-cra.004012FB
00401062   B8 01000000       mov eax,1                  ; 这里改为mov eax,0
00401067   84C0            test al,al
00401069   74 13             je short tsrh-cra.0040107E ; 或者这里改为jmp
0040106B   6A 40             push 40
0040106D   68 52354000       push tsrh-cra.00403552            ; ASCII "TSRh CrackMe *Easy*"
00401072   68 00304000       push tsrh-cra.00403000            ; ASCII "Kill this Nag!!!"
00401077   6A 00             push 0
00401079   E8 B2020000       call <jmp.&USER32.MessageBoxA>

跟踪了一遍,发现注册码是这个形式:

'注册码由三部分组成
'tsrh-sn1-sn2

OD载入程序运行,输入注册信息:
piaoyun
tsrh123456789

字符插件找到:

***********************************★中间码(sn1)计算★***********************************

004011F3   A3 14354000       mov dword ptr ds:,eax
004011F8   BF D3070000       mov edi,7D3                         ; 7D3(10进制2003)   常量
004011FD   033D 14354000   add edi,dword ptr ds:       ; 与用户名长度相加
00401203   57                push edi
00401204   68 1B354000       push 1.0040351B                     ; ASCII "tsrh-%d-"   ▲找到这个东西~~★
00401209   68 20334000       push 1.00403320
0040120E   E8 05010000       call <jmp.&USER32.wsprintfA>      ; 转换成10进制作为中间码(sn1)
00401213   83C4 0C         add esp,0C
00401216   68 20334000       push 1.00403320
0040121B   E8 34010000       call <jmp.&KERNEL32.lstrlenA>
00401220   8B3D 14354000   mov edi,dword ptr ds:
00401226   BE 01000000       mov esi,1
0040122B   8BC8            mov ecx,eax
0040122D   C3                retn

*****************************************************************************************
sn2计算:
BP MessageBoxA 来到下面关键点:
00401126   E8 FF010000       call <jmp.&USER32.GetDlgItemTextA>; 取得假码
0040112B   A1 90314000       mov eax,dword ptr ds:       ; 前4位的ascii
00401130   3D 74737268       cmp eax,68727374                  ; 比较前4位“68727374”即“tsrh”
00401135   75 23             jnz short 1.0040115A                ; 不是则跳!
这里判断前4位是否为“tsrh”
00401137   05 20320000       add eax,3220
0040113C   50                push eax
0040113D   33C0            xor eax,eax
0040113F   E8 EA000000       call 1.0040122E                     ; 算法call,进入
00401144   58                pop eax
00401145   85C0            test eax,eax
00401147   74 11             je short 1.0040115A
00401149   33C2            xor eax,edx
0040114B   8BD0            mov edx,eax
0040114D   8BF0            mov esi,eax
0040114F   33C0            xor eax,eax
00401151   E8 31010000       call 1.00401287                     ; 关键call
00401156   84C0            test al,al
00401158   75 1F             jnz short 1.00401179                ; 关键跳转
0040115A   B8 85354000       mov eax,1.00403585
0040115F   E8 97010000       call 1.004012FB


******************************call 0040122E:************************************
0040122E   56                push esi
0040122F   68 20334000       push 1.00403320                     ; ASCII "tsrh-2010-"
00401234   E8 1B010000       call <jmp.&KERNEL32.lstrlenA>       ; 上面东西的长度
00401239   8B3D 14354000   mov edi,dword ptr ds:       ; 用户名长度
0040123F   BE 01000000       mov esi,1                           ; esi 初始值为1
00401244   8BC8            mov ecx,eax                         ; 特征码长度送ecx,也是给ecx赋初值
00401246   B8 B0344000       mov eax,1.004034B0                  ; ASCII "piaoyun"
0040124B   0FB64406 FF       movzx eax,byte ptr ds:   ; 逐位取用户名ascii
00401250   04 0C             add al,0C                           ; 加上c(10进制12) ★★
00401252   0FB6D0            movzx edx,al                        ; 保存到edx
00401255   83EA 11         sub edx,11                        ; edx = edx - 11
00401258   03D0            add edx,eax                         ; edx = edx + eax = edx - 11 + eax
0040125A   2BD1            sub edx,ecx                         ; edx = edx - ecx = edx - 11 + eax - ecx
0040125C   33C2            xor eax,edx                         ; eax = edx xor eax = (edx - 11 + eax - ecx) xor eax
0040125E   50                push eax
0040125F   68 18354000       push 1.00403518                     ; ASCII "%X"
00401264   8D81 20334000   lea eax,dword ptr ds:   
0040126A   50                push eax
0040126B   E8 A8000000       call <jmp.&USER32.wsprintfA>           ; 转换为字符输出
00401270   83C4 0C         add esp,0C
00401273   68 20334000       push 1.00403320                     ; ASCII "tsrh-2010-"
00401278   E8 D7000000       call <jmp.&KERNEL32.lstrlenA>       ; 取上面的长度
0040127D   8BC8            mov ecx,eax                         ; 长度送到ecx
0040127F   46                inc esi                                   ; esi+1(用户名位置指针)
00401280   4F                dec edi                                   ; edi-1(用户名长度)
00401281   ^ 75 C3             jnz short 1.00401246                   ; 循环
00401283   33C0            xor eax,eax
00401285   5E                pop esi
00401286   C3                retn

最后得到:“tsrh-2010-A1B8D6AE625CB7” (就令它为“特征码”吧◎)   ★你的不同哦!★

返回之后进入关键call
*******************************call 00401287*****************************************
00401287   53                push ebx
00401288   BE 01000000       mov esi,1                           ; esi初始值为1
0040128D   B8 B0344000       mov eax,1.004034B0                  ; 用户名送到eax
00401292   0FB64406 FF       movzx eax,byte ptr ds:   ; 逐位取用户名ascii送eax
00401297   85C0            test eax,eax
00401299   74 34             je short 1.004012CF               ; 是否为0
0040129B   40                inc eax                           ; ascii+1
0040129C   BA 20334000       mov edx,1.00403320                  ; 特征码送edx
004012A1   0FB65416 0B       movzx edx,byte ptr ds:   ; 从特征码中esi+b位置取ascii值(注:0表示第一位,所以这里

理解为esi+13位开始取)★第二次取值时由于13位之后都被替换,所以ascii为0★
004012A6   33C2            xor eax,edx                         ; 和eax(用户名ascii+1) 进行异或运算
004012A8   83F8 41         cmp eax,41
004012AB   7D 05             jge short 1.004012B2                ; 是否大于41(A)
004012AD   83C0 08         add eax,8                           ; 不大于则+8
004012B0   ^ EB F6             jmp short 1.004012A8                ; 循环(直到大于为止)
004012B2   83F8 5A         cmp eax,5A                        ; 是否小于5A(Z)
004012B5   7E 05             jle short 1.004012BC
004012B7   83E8 03         sub eax,3                           ; 不小于则+3
004012BA   ^ EB F6             jmp short 1.004012B2                ; 循环(直到小于为止)
004012BC   83C6 09         add esi,9                           ; esi+9
004012BF   BB 20334000       mov ebx,1.00403320                  ; 特征码送ebx
004012C4   89041E            mov dword ptr ds:,eax      ; 将eax转换为字符后替换到特征码的esi位之后
004012C7   83EE 08         sub esi,8                           ; esi-8★和前面"esi+9"一起就是esi+1★
004012CA   83FE 10         cmp esi,10                        ; 和10比较(十进制16)也就是最多循环16次,用户名超过16位就

没有意义了
004012CD   ^ 75 BE             jnz short 1.0040128D                ; 循环取用户名
004012CF   33C0            xor eax,eax
004012D1   5B                pop ebx
004012D2   E8 01000000       call 1.004012D8
004012D7   C3                retn
------------------------------------------------------------------------
【算法注册机】         随便写的,没有做优化,大家将就着看吧!

'注册码由三部分组成
'tsrh-sn1-sn2

Private Sub Command1_Click()
Dim name, reg, a, b, c, d, tzm, str, zjm As String
name = Text1.Text
c = 10
If Len(name) < 5 Or Len(name) > 29 Then
    MsgBox "用户名不能小于5位或大于29位", 64, "提示"          '文本框限制输入29位
Else
    zjm = 2003 + Len(name)      '中间码(sn1)的计算
For i = 1 To Len(name)
    a = Asc(Mid(name, i, 1)) + &HC
    b = a '给b赋值
    b = Hex((a - &H11 + a - c) Xor a) ' 对每一位用户名的计算
    tzm = tzm & b               '得到中间结果(即特征码),待后面计算
    str = "tsrh-" & zjm & "-" & tzm    '构成新字符串
    c = Len(str)                '下一轮的c值由此计算
Next
'第二步算法开始(sn2)
For i = 1 To Len(name)
    If i + 12 < Len(str) Then    '由于13位之后ascii都取0,所以偷懒用这种方式写了~~ ^_^
    d = Asc(Mid(str, i + 12, i)) Xor (Asc(Mid(name, i, 1)) + 1)
    Else
    d = 0 Xor (Asc(Mid(name, i, 1)) + 1)
    End If
    While d < &H41   '判断是否大于41
    d = d + 8
    Wend
    While d > &H5A   '判断是否小于5a
    d = d - 3
    Wend
    str = "tsrh-" & zjm & "-" & Chr(d)
    reg = Mid(reg & Chr(d), 1, 16)
    Next
    Text2 = "tsrh-" & zjm & "-" & reg
    End If
End Sub

------------------------------------------------------------------------
【破解总结】算法比较无聊~ 各位慢慢看吧!
------------------------------------------------------------------------
【版权声明】本文纯属技术交流, 转载请注明作者信息并保持文章的完整, 谢谢!

cha23 发表于 2005-10-30 12:51:21

好文!!!
.

Iceman 发表于 2005-11-4 11:31:23

学习,学习

wzwgp 发表于 2006-1-14 10:45:46

辛苦!谢谢!

wx73721 发表于 2006-3-14 19:05:39

好文,注册部分分析的不错,支持下!

rhinomax 发表于 2006-3-26 13:48:09

good,3ks to share

fanxun001 发表于 2006-3-30 02:53:18

为什么有两个十四课??????
https://www.chinapyg.com/viewthread.php?tid=2109&extra=page%3D3

野猫III 发表于 2006-4-21 16:54:32

原帖由 fanxun001 于 2006-3-30 02:53 发表
为什么有两个十四课??????
https://www.chinapyg.com/viewthread.php?tid=2109&extra=page%3D3

有这事!老大check一下。

godhack 发表于 2006-5-4 14:33:41

写的很详细,学习喽

hnmeec 发表于 2006-5-10 16:33:16

好文章,收藏学习!!!
页: [1] 2 3 4
查看完整版本: [PYG]算法分析入门第十五课