HPKEr 发表于 2010-3-1 12:41

虎年:CrackMe算法分析

本帖最后由 HPKEr 于 2010-3-1 12:58 编辑

【文章标题】: 虎年:CrackMe算法分析
【文章作者】: HPKEr
【软件名称】: CrackMe
【软件大小】: 21.28 KB
【下载地址】: http://xz.qupan.com/down/945520_5928700.html
【编写语言】: Microsoft Visual C++ 6.0
【使用工具】:OD PEID0.95
【操作平台】: Windows XP SP3
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
1.OD载入查找字符串插件搜索发现:“sorry! serial incorrect!”跟随过去。到段首0010114F处,F2下断。
2.Ctrl+F2重新载入,F9运行,填写内容如下:“NAME:guapi TEAM:guagua SERIAL:123456”。
3.点击“TRY SERIAL”按钮,断在0010114F处。

0040114F/$55            PUSH EBP
00401150|.8BEC          MOV EBP,ESP
00401152|.83EC 30       SUB ESP,30
00401155|.6A 01         PUSH 1
00401157|.6A 40         PUSH 40
00401159|.E8 B6030000   CALL CrackMe.00401514
0040115E|.83C4 08       ADD ESP,8
00401161|.8945 F8       MOV DWORD PTR SS:,EAX
00401164|.6A 01         PUSH 1
00401166|.6A 40         PUSH 40
00401168|.E8 A7030000   CALL CrackMe.00401514
0040116D|.83C4 08       ADD ESP,8
00401170|.8945 E4       MOV DWORD PTR SS:,EAX
00401173|.6A 01         PUSH 1
00401175|.6A 40         PUSH 40
00401177|.E8 98030000   CALL CrackMe.00401514
0040117C|.83C4 08       ADD ESP,8
0040117F|.8945 D8       MOV DWORD PTR SS:,EAX
00401182|.6A 40         PUSH 40                                  ; /Count = 40 (64.)
00401184|.8B45 F8       MOV EAX,DWORD PTR SS:             ; |
00401187|.50            PUSH EAX                                 ; |Buffer
00401188|.68 EA030000   PUSH 3EA                                 ; |ControlID = 3EA (1002.)
0040118D|.8B4D 08       MOV ECX,DWORD PTR SS:             ; |
00401190|.51            PUSH ECX                                 ; |hWnd
00401191|.FF15 AC604000 CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \获取NAME字符数为:05
00401197|.8845 D0       MOV BYTE PTR SS:,AL
0040119A|.6A 40         PUSH 40                                  ; /Count = 40 (64.)
0040119C|.8B55 E4       MOV EDX,DWORD PTR SS:            ; |
0040119F|.52            PUSH EDX                                 ; |Buffer
004011A0|.68 EB030000   PUSH 3EB                                 ; |ControlID = 3EB (1003.)
004011A5|.8B45 08       MOV EAX,DWORD PTR SS:             ; |
004011A8|.50            PUSH EAX                                 ; |hWnd
004011A9|.FF15 AC604000 CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \获取TEAM字符数为:06
004011AF|.8845 E8       MOV BYTE PTR SS:,AL
004011B2|.6A 40         PUSH 40                                  ; /Count = 40 (64.)
004011B4|.8B4D D8       MOV ECX,DWORD PTR SS:            ; |
004011B7|.51            PUSH ECX                                 ; |Buffer
004011B8|.68 EC030000   PUSH 3EC                                 ; |ControlID = 3EC (1004.)
004011BD|.8B55 08       MOV EDX,DWORD PTR SS:             ; |
004011C0|.52            PUSH EDX                                 ; |hWnd
004011C1|.FF15 AC604000 CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \获取SERIAL字符数为:06
004011C7|.8845 F0       MOV BYTE PTR SS:,AL
004011CA|.C645 E0 00    MOV BYTE PTR SS:,0               ;循环变量
004011CE|>C645 D4 00    /MOV BYTE PTR SS:,0
004011D2|.8B45 E0       |MOV EAX,DWORD PTR SS:
004011D5|.25 FF000000   |AND EAX,0FF                           ;EAX AND OFF清零
004011DA|.8B4D F8       |MOV ECX,DWORD PTR SS:
004011DD|.8A1401      |MOV DL,BYTE PTR DS:            ;NAME:guagua第一个字母十六进制67入DL
004011E0|.8855 F4       |MOV BYTE PTR SS:,DL            ;储存DL临时变量
004011E3|.8B45 F4       |MOV EAX,DWORD PTR SS:
004011E6|.25 FF000000   |AND EAX,0FF                           ;运算结果为:67
004011EB|.8B4D E8       |MOV ECX,DWORD PTR SS:         ;取TEAM:guagua长度为06
004011EE|.81E1 FF000000 |AND ECX,0FF                           ;运算结果为:06
004011F4|.33C1          |XOR EAX,ECX                           ;EAX与ECX进行XOR结果为:61
004011F6|.8845 F4       |MOV BYTE PTR SS:,AL            ;将AL:61临时变量存储在堆栈
004011F9|.8B55 F4       |MOV EDX,DWORD PTR SS:            ;将变量61入EDX
004011FC|.81E2 FF000000 |AND EDX,0FF                           ;运算结果为:61
00401202|.33C0          |XOR EAX,EAX                           ;EAX清零
00401204|.A0 14764000   |MOV AL,BYTE PTR DS:             ;将十六进制1E送入AL
00401209|.33D0          |XOR EDX,EAX                           ;EDX与EAX异或结果为:7F
0040120B|.8855 F4       |MOV BYTE PTR SS:,DL
0040120E|.C645 DC 00    |MOV BYTE PTR SS:,0
00401212|.EB 09         |JMP SHORT CrackMe.0040121D
00401214|>8A4D DC       |/MOV CL,BYTE PTR SS:            ;(初始化 cpu 选择状态)
00401217|.80C1 01       ||ADD CL,1                               ;计数器CL=1
0040121A|.884D DC       ||MOV BYTE PTR SS:,CL            ;将CL临时变量存储于堆栈
0040121D|>8B55 DC       | MOV EDX,DWORD PTR SS:
00401220|.81E2 FF000000 ||AND EDX,0FF                            ;EDX清零
00401226|.8B45 E8       ||MOV EAX,DWORD PTR SS:          ;取TEAM:guagua长度
00401229|.25 FF000000   ||AND EAX,0FF                            ;EAX=06
0040122E|.3BD0          ||CMP EDX,EAX                            ;EDX与EAX比较
00401230|.7D 20         ||JGE SHORT CrackMe.00401252             ;结果高于等于0跳至00401252处
00401232|.8B4D F4       ||MOV ECX,DWORD PTR SS:
00401235|.81E1 FF000000 ||AND ECX,0FF                            ;ECX=7F
0040123B|.8B55 DC       ||MOV EDX,DWORD PTR SS:
0040123E|.81E2 FF000000 ||AND EDX,0FF                            ;EDX清零
00401244|.8B45 E4       ||MOV EAX,DWORD PTR SS:          ;TEAM:guagua入EAX
00401247|.0FBE1410      ||MOVSX EDX,BYTE PTR DS:      ;TEAM:guagua第一个字母'g'符号扩展至EDX
0040124B|.33CA          ||XOR ECX,EDX                            ;7F与67异或,ECX=18。
0040124D|.884D F4       ||MOV BYTE PTR SS:,CL             ;CL=18、6D、C、6B、1E、7F存入堆栈
00401250|.^ EB C2         |\JMP SHORT CrackMe.00401214             ;循环
00401252|>8B45 F4       |MOV EAX,DWORD PTR SS:            ;7F入EAX
00401255|.25 FF000000   |AND EAX,0FF                           ;结果为:7F
0040125A|.C1F8 02       |SAR EAX,2                               ;算术右移2位,结果为:1F
0040125D|.8845 F4       |MOV BYTE PTR SS:,AL
00401260|.C645 DC 00    |MOV BYTE PTR SS:,0
00401264|.EB 09         |JMP SHORT CrackMe.0040126F
00401266|>8A4D DC       |/MOV CL,BYTE PTR SS:
00401269|.80C1 01       ||ADD CL,1
0040126C|.884D DC       ||MOV BYTE PTR SS:,CL
0040126F|>8B55 DC       | MOV EDX,DWORD PTR SS:
00401272|.81E2 FF000000 ||AND EDX,0FF                            ;EDX清零
00401278|.83FA 02       ||CMP EDX,2
0040127B|.7D 26         ||JGE SHORT CrackMe.004012A3             ;直到EDX值为2跳出循环
0040127D|.8B45 E0       ||MOV EAX,DWORD PTR SS:
00401280|.25 FF000000   ||AND EAX,0FF                            ;EAX值为0
00401285|.8B4D DC       ||MOV ECX,DWORD PTR SS:
00401288|.81E1 FF000000 ||AND ECX,0FF                            ;ECX值为0
0040128E|.034D D8       ||ADD ECX,DWORD PTR SS:          ;SERIAL:123456
00401291|.8B55 DC       ||MOV EDX,DWORD PTR SS:
00401294|.81E2 FF000000 ||AND EDX,0FF                            ;EDX清零
0040129A|.8A0441      ||MOV AL,BYTE PTR DS:
0040129D|.884415 FC   ||MOV BYTE PTR SS:,AL
004012A1|.^ EB C3         |\JMP SHORT CrackMe.00401266
004012A3|>8B4D DC       |MOV ECX,DWORD PTR SS:
004012A6|.81E1 FF000000 |AND ECX,0FF                           ;ECX=2
004012AC|.C6440D FC 00|MOV BYTE PTR SS:,0
004012B1|.8D55 FC       |LEA EDX,DWORD PTR SS:            ;每次取SERIAL两位字符“12”“34”“56”“”“”到EDX
004012B4|.52            |PUSH EDX
004012B5|.E8 4F020000   |CALL CrackMe.00401509                   ;第一次将十进制12转化为十六进制数为c,第二次将34转化为十六进制的22,第三次将56转化为十六进制的38,由于第四次和第五次,通过修改标志位取值为空。
004012BA|.83C4 04       |ADD ESP,4
004012BD|.8945 EC       |MOV DWORD PTR SS:,EAX
004012C0|.8B45 F4       |MOV EAX,DWORD PTR SS:            ;EAX=1F
004012C3|.25 FF000000   |AND EAX,0FF                           ;EAX=1F
004012C8|.3945 EC       |CMP DWORD PTR SS:,EAX         ;c与1F比较,明显不相等,暂且先记下“1F、1B、1E、1A、1C”比较五次后就结束了。将字符串转化为十进制连接起来:3127302628这一串数字就是真SERIAL:3127302628
004012CB|.75 04         |JNZ SHORT CrackMe.004012D1            ;不为0,就跳。这个标志位不能让它,实现跳转,如果实现就没有办法跟出真注册码了。通过修改标志位让它不能实现跳转,目的就达到了。
004012CD|.C645 D4 01    |MOV BYTE PTR SS:,1
004012D1|>8A4D E0       |MOV CL,BYTE PTR SS:
004012D4|.80C1 01       |ADD CL,1                              ;CL=1
004012D7|.884D E0       |MOV BYTE PTR SS:,CL
004012DA|.8B55 E0       |MOV EDX,DWORD PTR SS:
004012DD|.81E2 FF000000 |AND EDX,0FF                           ;EDX=01
004012E3|.8B45 D0       |MOV EAX,DWORD PTR SS:         ;NAME:guapi位数
004012E6|.25 FF000000   |AND EAX,0FF                           ;EAX=05
004012EB|.3BD0          |CMP EDX,EAX
004012ED|.7D 12         |JGE SHORT CrackMe.00401301            ;直到EDX=5时跳出循环
004012EF|.8B4D D4       |MOV ECX,DWORD PTR SS:
004012F2|.81E1 FF000000 |AND ECX,0FF
004012F8|.83F9 01       |CMP ECX,1
004012FB|.^ 0F84 CDFEFFFF \JE CrackMe.004011CE
00401301|>8B55 D0       MOV EDX,DWORD PTR SS:            ;NAME:guapi位数入EDX
00401304|.81E2 FF000000 AND EDX,0FF
0040130A|.85D2          TEST EDX,EDX
0040130C|.74 19         JE SHORT CrackMe.00401327                ;如果NAME为空就提示:“please! fill all fields!”
0040130E|.8B45 E8       MOV EAX,DWORD PTR SS:
00401311|.25 FF000000   AND EAX,0FF
00401316|.85C0          TEST EAX,EAX
00401318|.74 0D         JE SHORT CrackMe.00401327                ;如果TEAM为空就提示:“please! fill all fields!”
0040131A|.8B4D F0       MOV ECX,DWORD PTR SS:            ;206入ECX
0040131D|.81E1 FF000000 AND ECX,0FF                              ;ECX=6
00401323|.85C9          TEST ECX,ECX
00401325|.75 16         JNZ SHORT CrackMe.0040133D               ;如果TEAM不为空就跳至0010133D处
00401327|>68 30704000   PUSH CrackMe.00407030                  ; /please! fill all fields!
0040132C|.68 F3030000   PUSH 3F3                                 ; |ControlID = 3F3 (1011.)
00401331|.8B55 08       MOV EDX,DWORD PTR SS:             ; |
00401334|.52            PUSH EDX                                 ; |hWnd
00401335|.FF15 B0604000 CALL DWORD PTR DS:[<&USER32.SetDlgItemTe>; \SetDlgItemTextA
0040133B|.EB 37         JMP SHORT CrackMe.00401374
0040133D|>8B45 D4       MOV EAX,DWORD PTR SS:            ;EAX=0
00401340|.25 FF000000   AND EAX,0FF
00401345|.83F8 01       CMP EAX,1
00401348|.75 16         JNZ SHORT CrackMe.00401360
0040134A|.68 4C704000   PUSH CrackMe.0040704C                  ; /congratulations! serial correct!
0040134F|.68 F3030000   PUSH 3F3                                 ; |ControlID = 3F3 (1011.)
00401354|.8B4D 08       MOV ECX,DWORD PTR SS:             ; |
00401357|.51            PUSH ECX                                 ; |hWnd
00401358|.FF15 B0604000 CALL DWORD PTR DS:[<&USER32.SetDlgItemTe>; \SetDlgItemTextA
0040135E|.EB 14         JMP SHORT CrackMe.00401374
00401360|>68 70704000   PUSH CrackMe.00407070                  ; /sorry! serial incorrect!
00401365|.68 F3030000   PUSH 3F3                                 ; |ControlID = 3F3 (1011.)
0040136A|.8B55 08       MOV EDX,DWORD PTR SS:             ; |
0040136D|.52            PUSH EDX                                 ; |hWnd
0040136E|.FF15 B0604000 CALL DWORD PTR DS:[<&USER32.SetDlgItemTe>; \SetDlgItemTextA
00401374|>33C0          XOR EAX,EAX
00401376|.8BE5          MOV ESP,EBP
00401378|.5D            POP EBP
00401379\.C3            RETN
0040137A/$8B4424 04   MOV EAX,DWORD PTR SS:
0040137E|.A3 8C704000   MOV DWORD PTR DS:,EAX
00401383\.C3            RETN

三组可用SERIAL:

1.当Positions位置为A时
NAEM:guapi
TEAM:guagua
SERIAL:2630273125

2.当Positions位置为B时
NAEM:guapi
TEAM:guagua
SERIAL:2925282430

3.当Positions位置为C时
NAEM:guapi
TEAM:guagua
SERIAL:3127302628

A.当Positions位置为A时,注册成功图:



B.当Positions位置为B时,注册成功图:



C.当Positions位置为C时,注册成功图:




--------------------------------------------------------------------------------
【经验总结】
1.此CrackMe爆破相当简单,只要将00401348|. /75 16         JNZ SHORT CrackMe.00401360处反汇编代码NOP掉或者改
为JZ,就OK了。

2.总体感觉此CrackMe不是很难,特别适合新手练习,由于我也是今天早上仓促分析它,时间有限,有些地方写的不是很明
白,兄弟们只要仔细想,细心看,也不难明白。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于HPKEr, 转载请注明作者并保持文章的完整, 谢谢!
                                                       2010年03月01日 12:45:02

qst50781820 发表于 2010-3-1 12:54

沙发做主,慢慢学习

czjh2008 发表于 2010-3-1 14:26

谢谢分享……

zxiaoxin 发表于 2010-3-3 15:22

谢谢楼主分享,算法我一点不会,真是谢谢楼主,我回去慢慢研究一下

lxm745630 发表于 2010-3-5 14:15




HPKEr 发表于 2010-3-5 19:06

回复 5# lxm745630


    爆破很简单!
页: [1]
查看完整版本: 虎年:CrackMe算法分析