首页
社区
课程
招聘
一个crackme的算法分析
发表于: 2006-3-6 08:59 7116

一个crackme的算法分析

2006-3-6 08:59
7116

【破文标题】一个crackme的算法分析
【破文作者】windycandy
【破解工具】OD,Peid0.94
【破解平台】Windows xp
【软件名称】crackme
【软件大小】12K
【原版下载】http://bbs.chinapyg.cn/viewthread.php?tid=3951&extra=page%3D1
【保护方式】name & SN
【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享
------------------------------------------------------------------------
1.前言

最近学习CCDebuger前辈的<OllyDBG 入门系列>,使我等菜鸟受益匪浅,今有所成,又巧遇一crackme,可用前辈的
<消息断点及 RUN 跟踪>方法破之,遂将过程写出来,与跟我一样的菜鸟共勉,同时激励前辈在有时间情况下写出
更多的教程,以供我们观摩学习.

2.破解过程

先运行程序看看情况,点HELP随便输入name:windycandy,serial:87654321.按OK,出现错误提示框.好了,现在拿
工具开始行动.

Peid 查壳无壳,为MASM32 / TASM32 [Overlay]编写的程序.

OD载入,停在入口:

00401000 C>/$  6A 00         push 0                              ; /(初始化 cpu 选择状态)
00401002   |.  E8 FF040000   call <jmp.&KERNEL32.GetModuleHandle>; \GetModuleHandleA
00401007   |.  A3 CA204000   mov dword ptr ds:[4020CA],eax
0040100C   |.  6A 00         push 0                              ; /Title = NULL
0040100E   |.  68 F4204000   push CRACKME.004020F4               ; |no need to disasm the code!
00401013   |.  E8 A6040000   call <jmp.&USER32.FindWindowA>      ; \FindWindowA
00401018   |.  0BC0          or eax,eax
0040101A   |.  74 01         je short CRACKME.0040101D

用字符串插件能找到有效字符"great work, mate!\nnow try the next crackme!"及"no luck there, mate!"分别
双击都能来到反汇编窗口,但是向上找都没有找到能跳过错误提示框的关键跳,这下好象有点意思了.这样找关键算法
的call好象也比较困难,改用<消息断点及 RUN 跟踪>方法则轻松破之.

OD重新载入,F9运行,到注册界面输入"windycandy"及"8765432100",不按"OK"
在OD菜单找"查看"下的"窗口"或直接按"M"(有时按"窗口"或"M"看不到内容,这时可以轮换按"M"或"窗口")
出现以下窗口

句柄           标题                 父级       WinProc    ID      ? 样式       ExtStyle   线程       ClsProc    Class
00020684                            Topmost                          0CC00000   00000100   主          10005F60   ATL:10055250
00040682       Register             Topmost                          14C800C4   00010101   主          77D1C6C4   #32770
K0002064E      Serial               00040682              0000FFFF   50020000   00000004   主          77D1CC6C   Static
K00020652      Name                 00040682              0000FFFF   50020000   00000004   主          77D1CC6C   Static
K00020654      Cancel               00040682              000003EB   50010000   00000004   主          77D30515   Button
K00020664      OK                   00040682              000003EA   50010000   00000004   主          77D30515   Button
K00020666                           00040682              000003E9   50010080   00000204   主          77D28530   Edit
K00030668                           00040682              000003E8   50010080   00000204   主          77D28530   Edit
E00090650      Default IME          00040682                         8C000000              主          77D63CE2   IME
NE0008066C     M                    00090650                         8C000000              主          FFFF037D   MSCTFIME UI
00060644       Hammer of Thor       Topmost                          8C000000              主          77D15C55   Mjolnir
E00040642      THOR MAIN WINDOW     00060644                         8C400000   00000188   主          10037BCB   CiceroUIWndFrame
NK0002063E     CiceroUIWndFrame     00040642                         8C000000   00080008   主          10037BCB   CiceroUIWndFrame
NIK0002062E    PadListView          0002063E                         56000000   00000200   主          10028210   PadListView
NIIE000206A2                        0002062E              00000020   50000002              主          FFFF02C1   SysHeader32
NIE0002063C    CiceroUIWndFrame     0002063E                         8C800000   00000008   主          10037BCB   CiceroUIWndFrame
NK00020640     CiceroUIWndFrame     00040642                         8C800000   00000008   主          10037BCB   CiceroUIWndFrame
NE00020698     PadListView          00040642                         56000000   00000200   主          10028210   PadListView
NNE00020658                         00020698              00000020   40000002              主          FFFF02C1   SysHeader32
00090648       CrackMe v1.0         Topmost               00070781   1CCF0000   00000100   主          00401128   No need to disasm the code!

找到按钮"OK"
单击右键------->  "在Classproc上设消息断点"---------> 选"202 WM_LBUTTONUP"--------> 点"确定"

再在"调试"菜单下"打开或清除RUN跟踪",开始RUN跟踪
确保在反汇编窗口下
单击右键---------> RUN跟踪------------->  添加全部函数例程的入口
返回到crackme窗口,按"OK"
条件中断在
77D30515 [>  55              push ebp--------中断在这里
77D30516     8BEC            mov ebp,esp
77D30518     8B4D 08         mov ecx,dword ptr ss:[ebp+8]
77D3051B     56              push esi
77D3051C     E8 0335FEFF     call USER32.77D13A24
77D30521     8BF0            mov esi,eax
77D30523     85F6            test esi,esi
77D30525     74 38           je short USER32.77D3055F
77D30527     8B55 0C         mov edx,dword ptr ss:[ebp+C]
77D3052A     3B15 C8C0D677   cmp edx,dword ptr ds:[77D6C0C8]
77D30530     77 1E           ja short USER32.77D30550
77D30532     33C0            xor eax,eax

按Alt+M

内存映射,项目 23
地址=00401000
大小=00001000 (4096.)
宿主=CRACKME  00400000
区段=CODE
包含=code
类型=Imag 01001002
访问=R
初始访问=RWE

在crackme, code 段下F2断点,F9运行,中断在00401253

00401253   /.  C8 000000     enter 0,0-------断在这里
00401257   |.  53            push ebx
00401258   |.  56            push esi
00401259   |.  57            push edi
0040125A   |.  817D 0C 10010>cmp dword ptr ss:[ebp+C],110
00401261   |.  74 34         je short CRACKME.00401297
00401263   |.  817D 0C 11010>cmp dword ptr ss:[ebp+C],111
0040126A   |.  74 35         je short CRACKME.004012A1
0040126C   |.  837D 0C 10    cmp dword ptr ss:[ebp+C],10
00401270   |.  0F84 81000000 je CRACKME.004012F7
00401276   |.  817D 0C 01020>cmp dword ptr ss:[ebp+C],201
0040127D   |.  74 0C         je short CRACKME.0040128B
0040127F   |.  B8 00000000   mov eax,0
00401284   |>  5F            pop edi
00401285   |.  5E            pop esi

向下翻,看到

004012B5   |.  6A 0B         |push 0B                            ; /Count = B (11.)
004012B7   |.  68 8E214000   |push CRACKME.0040218E              ; |Buffer = CRACKME.0040218E
004012BC   |.  68 E8030000   |push 3E8                           ; |ControlID = 3E8 (1000.)
004012C1   |.  FF75 08       |push dword ptr ss:[ebp+8]          ; |hWnd
004012C4   |.  E8 07020000   |call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA--------------这个,我们喜欢
004012C9   |.  83F8 01       |cmp eax,1
004012CC   |.  C745 10 EB030>|mov dword ptr ss:[ebp+10],3EB
004012D3   |.^ 72 CC         \jb short CRACKME.004012A1
004012D5   |.  6A 0B         push 0B                             ; /Count = B (11.)
004012D7   |.  68 7E214000   push CRACKME.0040217E               ; |Buffer = CRACKME.0040217E
004012DC   |.  68 E9030000   push 3E9                            ; |ControlID = 3E9 (1001.)
004012E1   |.  FF75 08       push dword ptr ss:[ebp+8]           ; |hWnd
004012E4   |.  E8 E7010000   call <jmp.&USER32.GetDlgItemTextA>  ; \GetDlgItemTextA--------------这个,我们喜欢
004012E9   |.  B8 01000000   mov eax,1
004012EE   |.  EB 07         jmp short CRACKME.004012F7

于是在4012B5,F2下断,删除其他断点, Ctrl+F2重新载入,F9运行,输入name和serail,点确定中断在4012B5
F8一路来到
00401223    .  83F8 00       cmp eax,0
00401226    .^ 74 BE         je short CRACKME.004011E6
00401228    .  68 8E214000   push CRACKME.0040218E               ;  ASCII "windycandy"姓名入栈
0040122D    .  E8 4C010000   call CRACKME.0040137E -----------------对name进行算法运算,F7跟进
00401232    .  50            push eax
00401233    .  68 7E214000   push CRACKME.0040217E               ;  ASCII "8765432100"
00401238    .  E8 9B010000   call CRACKME.004013D8
0040123D    .  83C4 04       add esp,4
00401240    .  58            pop eax
00401241    .  3BC3          cmp eax,ebx
00401243    .  74 07         je short CRACKME.0040124C
00401245    .  E8 18010000   call CRACKME.00401362
0040124A    .^ EB 9A         jmp short CRACKME.004011E6
0040124C    >  E8 FC000000   call CRACKME.0040134D
00401251    .^ EB 93         jmp short CRACKME.004011E6

进入40122D来到
0040137E   /$  8B7424 04     mov esi,dword ptr ss:[esp+4]------------输入的name放入esi
00401382   |.  56            push esi
00401383   |>  8A06          /mov al,byte ptr ds:[esi]---------------取name的字符进行逐个判断
00401385   |.  84C0          |test al,al
00401387   |.  74 13         |je short CRACKME.0040139C---------------所有字符判断结束则跳走
00401389   |.  3C 41         |cmp al,41               ----------------是否是字母"A"以上的字符
0040138B   |.  72 1F         |jb short CRACKME.004013AC---------------不是,over
0040138D   |.  3C 5A         |cmp al,5A
0040138F   |.  73 03         |jnb short CRACKME.00401394---------------与字母"Z"比较,不小于则进行处理
00401391   |.  46            |inc esi                  ------------------下一个字符
00401392   |.^ EB EF         |jmp short CRACKME.00401383
00401394   |>  E8 39000000   |call CRACKME.004013D2------------------------字符转换,关键call,F7跟进
00401399   |.  46            |inc esi                            ;  CRACKME.0040218E
0040139A   |.^ EB E7         \jmp short CRACKME.00401383

F7进入401394
004013D2   /$  2C 20         sub al,20---------------------------------------将name中的小写字母换成大写字母
004013D4   |.  8806          mov byte ptr ds:[esi],al
004013D6   \.  C3            retn-----------------------------------------------返回

字符转换完后,返回到这里继续以下处理

0040139C   |> \5E            pop esi             ---------------------------换算结果入esi
0040139D   |.  E8 20000000   call CRACKME.004013C2--------------------------算法call,F7跟进
004013A2   |.  81F7 78560000 xor edi,5678
004013A8   |.  8BC7          mov eax,edi

F7进入40139D

004013C2   /$  33FF          xor edi,edi-----------------清零,准备运算
004013C4   |.  33DB          xor ebx,ebx-----------------清零,准备运算
004013C6   |>  8A1E          /mov bl,byte ptr ds:[esi]---逐一取esi的字符
004013C8   |.  84DB          |test bl,bl            
004013CA   |.  74 05         |je short CRACKME.004013D1--esi内的字符处理完则跳走
004013CC   |.  03FB          |add edi,ebx------------------累加,结果放入edi
004013CE   |.  46            |inc esi  -------------------下一位字符
004013CF   |.^ EB F5         \jmp short CRACKME.004013C6
004013D1   \>  C3            retn----------------------------返回

返回到这里
004013A2   |.  81F7 78560000 xor edi,5678---------------运算结果与"5678"异域运算
004013A8   |.  8BC7          mov eax,edi-----------------运算结果送入eax
004013AA   |.  EB 15         jmp short CRACKME.004013C1---跳到4013C1,返回

返回这里
00401232    .  50            push eax--------------------返回这里
00401233    .  68 7E214000   push CRACKME.0040217E               ;  ASCII "8765432100"假码入栈
00401238    .  E8 9B010000   call CRACKME.004013D8------------------算法call,F7跟进
0040123D    .  83C4 04       add esp,4
00401240    .  58            pop eax
00401241    .  3BC3          cmp eax,ebx
00401243    .  74 07         je short CRACKME.0040124C
00401245    .  E8 18010000   call CRACKME.00401362
0040124A    .^ EB 9A         jmp short CRACKME.004011E6
0040124C    >  E8 FC000000   call CRACKME.0040134D
00401251    .^ EB 93         jmp short CRACKME.004011E6

F7进入
004013D8   /$  33C0          xor eax,eax-----------------清零,准备运算
004013DA   |.  33FF          xor edi,edi-----------------清零,准备运算
004013DC   |.  33DB          xor ebx,ebx-----------------清零,准备运算
004013DE   |.  8B7424 04     mov esi,dword ptr ss:[esp+4]----假码送入esi
004013E2   |>  B0 0A         /mov al,0A
004013E4   |.  8A1E          |mov bl,byte ptr ds:[esi]----逐一取假码进行运算
004013E6   |.  84DB          |test bl,bl
004013E8   |.  74 0B         |je short CRACKME.004013F5---处理完则跳走
004013EA   |.  80EB 30       |sub bl,30-------------------减30
004013ED   |.  0FAFF8        |imul edi,eax-----------------edi=edi*eax
004013F0   |.  03FB          |add edi,ebx------------------edi=eid+ebx
004013F2   |.  46            |inc esi----------------------下一位
004013F3   |.^ EB ED         \jmp short CRACKME.004013E2
004013F5   |>  81F7 34120000 xor edi,1234--------------------运算结果与1234异域
004013FB   |.  8BDF          mov ebx,edi----------------------运算结果送入edx
004013FD   \.  C3            retn-----------------------------返回

返回这里
0040123D    .  83C4 04       add esp,4------返回这里
00401240    .  58            pop eax
00401241    .  3BC3          cmp eax,ebx-----------------------name的算法运算结果与serial的算法运算结果比较
00401243    .  74 07         je short CRACKME.0040124C---------------关键跳,爆破点
00401245    .  E8 18010000   call CRACKME.00401362--------------------不等则OVER
0040124A    .^ EB 9A         jmp short CRACKME.004011E6
0040124C    >  E8 FC000000   call CRACKME.0040134D--------------------相等"congraduatin!"
00401251    .^ EB 93         jmp short CRACKME.004011E6

破解总结:
这个crackme的注册属于F'(name)=F'(serial)的类型,其算法为:
①输入的name必须全部是字母,在name的字母中如果有小写字母则需要将该小写字母换成大写
字母,本身是大写字母的不用转换,然后将name(都是大写字母)的各字符串的ARSII值累加,累
加结果与"5678"进行异域运算,得出F'(name);
②取输入假码的每位ARSCII值(B),作如下运算(A为常数):
y<=B-30
Z<=Z*A
Z<=Z+Y
算完一位再取下一位.
最后将累加结果(Z)与"1234"作异域运算,得出F'(serial)

如果F'(name)=F'(serial)则注册成功.

注册机,我不会写,只能算出自己的注册码,有时间再学写写注册机.

name=windycandy
serial=B102或serial=18102

推算过程:
windycany

│转换为大写

WINDYCANDY

│name的算法、累加处理

2FA

│xor 5678

5482----F'(name)

│xor 1234

46B6

│除以常数“A”------------余数“2”,2+30=32-----ARSII表中为字符“2”------注册码倒数第一位

712

│除以常数“A”------------余数“0”,0+30=30-----ARSII表中为字符“0”------注册码倒数第二位

B5

│除以常数“A”------------余数“1”,1+30=31-----ARSII表中为字符“1”------注册码倒数第三位

12---------(如果只算到这里余数“12”,12+30=42---ARSII表中为字符“B”------注册码倒数第四位)----得出serial=B102

│除以常数“A”------------余数“8”,8+30=38-----ARSII表中为字符“8”------注册码倒数第四位

1--------------------------余数“1”,1+30=31-----ARSII表中为字符“1”------注册码倒数第五位----得出serial=18102

最后,如果使用字符串插件找到"no luck there, mate!",双击来到反汇编窗口
00401362   /$  6A 00         push 0                              ; /BeepType = MB_OK
00401364   |.  E8 AD000000   call <jmp.&USER32.MessageBeep>      ; \MessageBeep
00401369   |.  6A 30         push 30                             ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
0040136B   |.  68 60214000   push CRACKME.00402160               ; |no luck!
00401370   |.  68 69214000   push CRACKME.00402169               ; |no luck there, mate!--------------到这里
00401375   |.  FF75 08       push dword ptr ss:[ebp+8]           ; |hOwner
00401378   |.  E8 BD000000   call <jmp.&USER32.MessageBoxA>      ; \MessageBoxA
0040137D   \.  C3            retn

到这里后,注意401362及40137D,可以猜测这是某个CALL调用的子程序,于是使用Ctrl+F查找"call 401362"也能找到关键点
00401241    .  3BC3          cmp eax,ebx
00401243    .  74 07         je short CRACKME.0040124C
00401245    .  E8 18010000   call CRACKME.00401362------------找到这里
0040124A    .^ EB 9A         jmp short CRACKME.004011E6
0040124C    >  E8 FC000000   call CRACKME.0040134D
00401251    .^ EB 93         jmp short CRACKME.004011E6
以下分析相同.
------------------------------------------------------------------------
【版权声明】本文仅属于技术交流,如有转载请注明出处.


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 236
活跃值: (100)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
2
附件,上传crackme
2006-3-6 09:25
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错,学习!
2006-3-6 09:25
0
雪    币: 2506
活跃值: (1030)
能力值: (RANK:990 )
在线值:
发帖
回帖
粉丝
4
分析的不错,支持!
2006-3-6 10:02
0
雪    币: 236
活跃值: (100)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
5
第一次入精华,激动ing~~~~~~~~~~
2006-3-6 11:30
0
雪    币: 214
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
支持并学习!
2006-3-6 13:10
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
上传crackme
2006-3-6 17:55
0
雪    币: 200
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
顶,学习一下!
2006-3-6 18:04
0
雪    币: 236
活跃值: (100)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
9
没权限,不能上传
2006-3-9 10:35
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
啊 没附件 支持处女做 谢谢,学习,慢慢看
2006-4-6 09:19
0
雪    币: 560
活跃值: (359)
能力值: ( LV13,RANK:1370 )
在线值:
发帖
回帖
粉丝
11
送上个注册机
上传的附件:
2006-4-14 13:43
0
雪    币: 236
活跃值: (100)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
12
这个注册机不错,学习了
2006-4-27 16:31
0
游客
登录 | 注册 方可回帖
返回
//