吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4773|回复: 7
收起左侧

[原创] 160个CrackMe之156 算法分析

[复制链接]
zbnysjwsnd8 发表于 2017-8-24 13:54
本帖最后由 zbnysjwsnd8 于 2017-8-30 20:48 编辑

翻了一圈 好像论坛里还没有人成功破解这个CM 刚好今天看了一下 于是就有了这篇文章。
我并不是大神 就是一个菜鸟 如果有错误还希望各位大佬们指出来。

0x0 KeyFile的检测
CM首先会读取 crack.dat 如果这个文件不存在则失败
[Asm] 纯文本查看 复制代码
00401170  |.  A1 6CCA4000   mov eax,dword ptr ds:[filebuf::openprot]
00401175  |.  50            push eax                                           ; /Arg4 = 0019FE60
00401176  |.  68 81000000   push 0x81                                          ; |Arg3 = 00000081
0040117B  |.  68 3EB44000   push thecodin.0040B43E                             ; |Arg2 = 0040B43E ASCII "crack.dat"
00401180  |.  8D95 D0FEFFFF lea edx,[local.datfile]                            ; |
00401186  |.  52            push edx                                           ; |Arg1 = 0019FE74
00401187  |.  E8 705A0000   call thecodin.fstreambase::open                    ; \fstreambase::open
0040118C  |.  83C4 10       add esp,0x10
0040118F  |.  8B8D D0FEFFFF mov ecx,[local.datfile]
00401195  |.  F641 0C 86    test byte ptr ds:[ecx+0xC],0x86
00401199  |.  74 6B         je short thecodin.00401206                         ;  如果不存在则失败
0040119B  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
0040119D  |.  68 48B44000   push thecodin.0040B448                             ; |Arg2 = 0040B448 ASCII "Kein Dat file vorhanden......"
004011A2  |.  56            push esi                                           ; |Arg1 = 0040D830
004011A3  |.  E8 34670000   call thecodin.ostream::outstr                      ; \ostream::outstr
004011A8  |.  83C4 0C       add esp,0xC
004011AB  |.  56            push esi                                           ; /Arg1 = 0040D830
004011AC  |.  E8 DB510000   call thecodin.endl                                 ; \endl
004011B1  |.  59            pop ecx                                            ;  0019FE60
004011B2  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
004011B4  |.  68 66B44000   push thecodin.0040B466                             ; |Arg2 = 0040B466 ASCII "Press a Key....."
004011B9  |.  56            push esi                                           ; |Arg1 = 0040D830
004011BA  |.  E8 1D670000   call thecodin.ostream::outstr                      ; \ostream::outstr
004011BF  |.  83C4 0C       add esp,0xC
004011C2  |.  56            push esi                                           ; /Arg1 = 0040D830
004011C3  |.  E8 C4510000   call thecodin.endl                                 ; \endl
004011C8  |.  59            pop ecx                                            ;  0019FE60
004011C9  |.  E8 2A0A0000   call thecodin.getch
004011CE  |.  33C0          xor eax,eax
004011D0  |.  50            push eax
004011D1  |.  6A 02         push 0x2                                           ; /Arg2 = 00000002
004011D3  |.  8D95 D0FEFFFF lea edx,[local.datfile]                            ; |
004011D9  |.  52            push edx                                           ; |Arg1 = 0019FE74
004011DA  |.  E8 0D5B0000   call thecodin.fstream::~fstream                    ; \fstream::~fstream
004011DF  |.  83C4 08       add esp,0x8
004011E2  |.  6A 02         push 0x2                                           ; /Arg2 = 00000002
004011E4  |.  8D8D 68FFFFFF lea ecx,[local.checkfile]                          ; |
004011EA  |.  51            push ecx                                           ; |Arg1 = E6898150
004011EB  |.  E8 FC5A0000   call thecodin.fstream::~fstream                    ; \fstream::~fstream
004011F0  |.  83C4 08       add esp,0x8
004011F3  |.  58            pop eax                                            ;  0019FE60
004011F4  |.  8B95 B0FEFFFF mov edx,[local.84]
004011FA  |.  64:8915 00000>mov dword ptr fs:[0],edx
00401201  |.  E9 E7010000   jmp thecodin.004013ED                              ;  返回
00401206  |>  6A 00         push 0x0                                           ; /Arg3 = 00000000
00401208  |.  68 77B44000   push thecodin.0040B477                             ; |Arg2 = 0040B477 ASCII "SuCCeSS."
0040120D  |.  56            push esi                                           ; |Arg1 = 0040D830
0040120E  |.  E8 C9660000   call thecodin.ostream::outstr                      ; \ostream::outstr
00401213  |.  83C4 0C       add esp,0xC
00401216  |.  56            push esi                                           ; /Arg1 = 0040D830
00401217  |.  E8 70510000   call thecodin.endl                                 ; \endl
0040121C  |.  59            pop ecx                                            ;  0019FE60
0040121D  |.  8D8D 98FEFFFF lea ecx,[local.CRCfile]                            ;  读文件(crack.dat)
00401223  |.  51            push ecx                                           ; /Arg2 = E6898150
00401224  |.  8D85 14FFFFFF lea eax,[local.datfile+44]                         ; |
0040122A  |.  50            push eax                                           ; |Arg1 = 0019FE60
0040122B  |.  E8 6C620000   call thecodin.istream::operator >>                 ; \istream::operator
00401230  |.  83C4 08       add esp,0x8
00401233  |.  3BBD 98FEFFFF cmp edi,[local.CRCfile]                            ;  如果文件的内容(整数型)和edi(0xE6898150)不相等则失败
00401239  |.  74 6D         je short thecodin.004012A8                         ;  如果相等则转移
0040123B  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
0040123D  |.  68 80B44000   push thecodin.0040B480                             ; |Arg2 = 0040B480 ASCII "
DON'T TOUCH MY FILE THATS ILLEGAL."
00401242  |.  56            push esi                                           ; |Arg1 = 0040D830
00401243  |.  E8 94660000   call thecodin.ostream::outstr                      ; \ostream::outstr
00401248  |.  83C4 0C       add esp,0xC
0040124B  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
0040124D  |.  68 A4B44000   push thecodin.0040B4A4                             ; |Arg2 = 0040B4A4 ASCII "
FILE KORRUPTED DON'T PATCH........"
00401252  |.  56            push esi                                           ; |Arg1 = 0040D830
00401253  |.  E8 84660000   call thecodin.ostream::outstr                      ; \ostream::outstr
00401258  |.  83C4 0C       add esp,0xC
0040125B  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
0040125D  |.  68 C8B44000   push thecodin.0040B4C8                             ; |Arg2 = 0040B4C8 ASCII "
Press a Key...."
00401262  |.  56            push esi                                           ; |Arg1 = 0040D830
00401263  |.  E8 74660000   call thecodin.ostream::outstr                      ; \ostream::outstr
00401268  |.  83C4 0C       add esp,0xC
0040126B  |.  E8 88090000   call thecodin.getch
00401270  |.  33C0          xor eax,eax
00401272  |.  50            push eax
00401273  |.  6A 02         push 0x2                                           ; /Arg2 = 00000002
00401275  |.  8D95 D0FEFFFF lea edx,[local.datfile]                            ; |
0040127B  |.  52            push edx                                           ; |Arg1 = 0019FE74
0040127C  |.  E8 6B5A0000   call thecodin.fstream::~fstream                    ; \fstream::~fstream
00401281  |.  83C4 08       add esp,0x8
00401284  |.  6A 02         push 0x2                                           ; /Arg2 = 00000002
00401286  |.  8D8D 68FFFFFF lea ecx,[local.checkfile]                          ; |
0040128C  |.  51            push ecx                                           ; |Arg1 = E6898150
0040128D  |.  E8 5A5A0000   call thecodin.fstream::~fstream                    ; \fstream::~fstream
00401292  |.  83C4 08       add esp,0x8
00401295  |.  58            pop eax                                            ;  0019FE60
00401296  |.  8B95 B0FEFFFF mov edx,[local.84]
0040129C  |.  64:8915 00000>mov dword ptr fs:[0],edx
004012A3  |.  E9 45010000   jmp thecodin.004013ED

新建一个crack.dat 内容是0xE6898150的十进制,即可过掉这步验证
QQ截图20170824131502.jpg
第一步验证过掉后CM的截图:
QQ截图20170824131608.jpg


0x1 Name Organization Serial的输入及Serial的检测
上一步验证成功以后 CM要求用户输入Name Organization Serial这三个信息 其中Serial必须为整数,否则失败。
[Asm] 纯文本查看 复制代码
004012CA  |> \6A 00         push 0x0                                           ; /Arg3 = 00000000
004012CC  |.  68 D9B44000   push thecodin.0040B4D9                             ; |Arg2 = 0040B4D9 ASCII "Name:  ->"
004012D1  |.  56            push esi                                           ; |Arg1 = 0040D830
004012D2  |.  E8 05660000   call thecodin.ostream::outstr                      ; \ostream::outstr
004012D7  |.  83C4 0C       add esp,0xC
004012DA  |.  FFB5 A4FEFFFF push [local.pname]                                 ; /Arg2 = 02023628
004012E0  |.  68 E4D74000   push offset thecodin.cin                           ; |Arg1 = 0040D7E4
004012E5  |.  E8 FE5D0000   call thecodin.istream::operator >>                 ; \istream::operator
004012EA  |.  83C4 08       add esp,0x8
004012ED  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
004012EF  |.  68 E3B44000   push thecodin.0040B4E3                             ; |Arg2 = 0040B4E3 ASCII "Orga:  ->"
004012F4  |.  56            push esi                                           ; |Arg1 = 0040D830
004012F5  |.  E8 E2650000   call thecodin.ostream::outstr                      ; \ostream::outstr
004012FA  |.  83C4 0C       add esp,0xC
004012FD  |.  FFB5 A0FEFFFF push [local.porg]                                  ; /Arg2 = 02023638
00401303  |.  68 E4D74000   push offset thecodin.cin                           ; |Arg1 = 0040D7E4
00401308  |.  E8 DB5D0000   call thecodin.istream::operator >>                 ; \istream::operator
0040130D  |.  83C4 08       add esp,0x8
00401310  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
00401312  |.  68 EDB44000   push thecodin.0040B4ED                             ; |Arg2 = 0040B4ED ASCII "Serial:->"
00401317  |.  56            push esi                                           ; |Arg1 = 0040D830
00401318  |.  E8 BF650000   call thecodin.ostream::outstr                      ; \ostream::outstr
0040131D  |.  83C4 0C       add esp,0xC
00401320  |.  8D8D 9CFEFFFF lea ecx,[local.serial]
00401326  |.  51            push ecx                                           ; /Arg2 = 0040D830
00401327  |.  68 E4D74000   push offset thecodin.cin                           ; |Arg1 = 0040D7E4
0040132C  |.  E8 6B610000   call thecodin.istream::operator >>                 ; \istream::operator
00401331  |.  83C4 08       add esp,0x8
00401334  |.  A1 E4D74000   mov eax,dword ptr ds:[cin]
00401339  |.  F640 0C 86    test byte ptr ds:[eax+0xC],0x86
0040133D  |.  74 5B         je short thecodin.0040139A                         ;  如果输入的是整数则转移
0040133F  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
00401341  |.  68 F7B44000   push thecodin.0040B4F7                             ; |Arg2 = 0040B4F7 ASCII "Eingabe Fehler !!"
00401346  |.  56            push esi                                           ; |Arg1 = 0040D830
00401347  |.  E8 90650000   call thecodin.ostream::outstr                      ; \ostream::outstr
0040134C  |.  83C4 0C       add esp,0xC
0040134F  |.  6A 00         push 0x0                                           ; /Arg3 = 00000000
00401351  |.  68 09B54000   push thecodin.0040B509                             ; |Arg2 = 0040B509 ASCII "
Press a key."
00401356  |.  56            push esi                                           ; |Arg1 = 0040D830
00401357  |.  E8 80650000   call thecodin.ostream::outstr                      ; \ostream::outstr
0040135C  |.  83C4 0C       add esp,0xC
0040135F  |.  E8 94080000   call thecodin.getch
00401364  |.  83C8 FF       or eax,0xFFFFFFFF
00401367  |.  50            push eax                                           ;  thecodin.cout
00401368  |.  6A 02         push 0x2                                           ; /Arg2 = 00000002
0040136A  |.  8D95 D0FEFFFF lea edx,[local.datfile]                            ; |
00401370  |.  52            push edx                                           ; |Arg1 = 0040D838
00401371  |.  E8 76590000   call thecodin.fstream::~fstream                    ; \fstream::~fstream
00401376  |.  83C4 08       add esp,0x8
00401379  |.  6A 02         push 0x2                                           ; /Arg2 = 00000002
0040137B  |.  8D8D 68FFFFFF lea ecx,[local.checkfile]                          ; |
00401381  |.  51            push ecx                                           ; |Arg1 = 0040D830
00401382  |.  E8 65590000   call thecodin.fstream::~fstream                    ; \fstream::~fstream
00401387  |.  83C4 08       add esp,0x8
0040138A  |.  58            pop eax                                            ;  thecodin.cout
0040138B  |.  8B95 B0FEFFFF mov edx,[local.84]
00401391  |.  64:8915 00000>mov dword ptr fs:[0],edx                           ;  thecodin.0040D838
00401398  |.  EB 53         jmp short thecodin.004013ED                        ;  返回

然后,CM将Name作为第一个参数 Organization作为第二个参数 Serial作为第三个参数来调用0x004013F4这个函数

0x2 分析函数:0x004013F4
CM首先计算Name的长度
[Asm] 纯文本查看 复制代码
00401403  |.  8B7D 08       mov edi,[arg.name]
00401406  |.  33C0          xor eax,eax
00401408  |.  8945 FC       mov [local.serial],eax
0040140B  |.  57            push edi                                           ; /s = Name
0040140C  |.  E8 0F0B0000   call thecodin.strlen                               ; \strlen
00401411  |.  59            pop ecx                                            ;  02023628
00401412  |.  8945 F4       mov [local.len_name],eax                           ;  Name长度

然后获取以time(0)的返回值为随机数种子 获取一个随机数r(无符号整数)
[Asm] 纯文本查看 复制代码
00401443  |.  6A 00         push 0x0                                           ; /timer = NULL
00401445  |.  E8 1A980000   call thecodin.time                                 ; \time
0040144A  |.  59            pop ecx                                            ;  02023628
0040144B  |.  50            push eax                                           ; /seed = 0x6
0040144C  |.  E8 3B6E0000   call thecodin.srand                                ; \srand
00401451  |.  59            pop ecx                                            ;  02023628
00401452  |.  E8 4D6E0000   call thecodin.rand                                 ; [获取一个随机数 记为r

然后将r mod 10的结果保存
[Asm] 纯文本查看 复制代码
00401457  |.  B9 0A000000   mov ecx,0xA
0040145C  |.  99            cdq
0040145D  |.  F7F9          idiv ecx
0040145F  |.  8955 F8       mov [local.dummy],edx                              ;  r mod 10

然后就开始用Name和Organization来计算Serial(_Serial的初始值是0)
[Asm] 纯文本查看 复制代码
00401462  |. /EB 14         jmp short thecodin.00401478
00401464  |> |0FBE06        /movsx eax,byte ptr ds:[esi]             ;  Organization
00401467  |. |0FBE17        |movsx edx,byte ptr ds:[edi]             ;  Name
0040146A  |. |F7EA          |imul edx
0040146C  |. |0145 FC       |add [local.serial],eax
0040146F  |. |3B5D F4       |cmp ebx,[local.len_name]
00401472  |. |75 02         |jnz short thecodin.00401476
00401474  |. |33DB          |xor ebx,ebx
00401476  |> |46            |inc esi
00401477  |. |47            |inc edi
00401478  |> \56            |push esi                                ; /s = Organization
00401479  |.  E8 A20A0000   |call thecodin.strlen                    ; \strlen
0040147E  |.  59            |pop ecx
0040147F  |.  85C0          |test eax,eax                            ;  eax是Orgaization的长度
00401481  |.^ 75 E1         \jnz short thecodin.00401464

这里需要注意一下:Orgaization的长度要和Name的长度相等;观察一下Name和Serial在内存中存放的顺序 可以得知Name的长度不能超过16个字节。
最后开始校验用户输入的Serial
[Asm] 纯文本查看 复制代码
00401483  |.  33DB          xor ebx,ebx
00401485  |.  8B45 10       mov eax,[arg.usernum]
00401488  |.  F76D F8       imul [local.dummy]
0040148B  |.  8B55 FC       mov edx,[local.serial]
0040148E  |.  0FAF55 F8     imul edx,[local.dummy]
00401492  |.  3BC2          cmp eax,edx                                        ;  相等则成功 不相等则失败
00401494  |.  75 43         jnz short thecodin.004014D9


0x3 计算注册码

由这段代码可以得知:
当usernum(用户输入的serial) * dummy == serial(CM计算的serial) * dummy(均为无符号乘法)时 就会成功。
其中dummy = r mod 10.
因为dummy可能为0 所以应分为两种情况讨论:
当dummy为0时:
usernum * dummy == serial * dummy总是成立的 因此这时一定会成功
当dummy不为0时:
即usernum == serial时才能成功.

如果想让用户在任何情况下都能注册成功 我们直接考虑第二种情况即可,即dummy不为0的时候。
这样就可以写出一个注册机:

QQ截图20170824155017.jpg
运行效果如图所示:
QQ截图20170824134950.jpg

最后附上一组可用的Name Organization和Serial以及CM的注册成功图片和CM源文件(包括KeyFile)
Name:_KaQqi
Organization:_52pj_
Serial:48875
CM成功图片:
QQ截图20170824135216.jpg
CM源文件以及KeyFile:
thecodingone.1.zip (44.79 KB, 下载次数: 8)

免费评分

参与人数 6威望 +1 吾爱币 +18 热心值 +6 收起 理由
winooxx + 1 + 1 谢谢@Thanks!
苏川剑 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hejialong + 2 + 1 谢谢@Thanks!
siuhoapdou + 1 + 1 谢谢@Thanks!
Hmily + 1 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
KaQqi + 3 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

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

KaQqi 发表于 2017-8-24 14:11
膜拜星斗

标题改一下,160cm之156 算法分析
魔弑神 发表于 2017-8-24 15:39
大神 厉害,
160个cm在哪里下载呢

点评

百度就有下载地址  发表于 2017-8-24 15:44
winooxx 发表于 2017-8-25 11:48
云飞扬1 发表于 2017-8-25 17:16
求一份1-156的算法解析,
我是渣渣,想学习学习
whb122 发表于 2017-8-26 15:06
这是干嘛用的?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-22 16:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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