吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

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

[CrackMe] 【吾爱2013CM大赛解答】 -- MK的小玩意+qq54007 算法分析+注册机

  [复制链接]
playboysen 发表于 2013-12-19 21:22
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

本帖最后由 playboysen 于 2013-12-19 21:53 编辑

本文针对以下CM:
http://www.52pojie.cn/thread-229379-1-1.html

OD查找字符串发现存在类似“software\crack me1”之类,猜测程序应该是往注册表某处写值以便重启验证,反正要重启验证干脆单刀直入,双击那个字符串OD自动定位到关键代码,直接从伪造注册表值入手看看,代码如下
[AppleScript] 纯文本查看 复制代码
00401614  |.  C74424 20 000>mov dword ptr ss:[esp+20],0           ; |
0040161C  |.  8D4424 34     lea eax,dword ptr ss:[esp+34]         ; |
00401620  |.  894424 1C     mov dword ptr ss:[esp+1C],eax         ; |
00401624  |.  C74424 18 000>mov dword ptr ss:[esp+18],0           ; |
0040162C  |.  C74424 14 3F0>mov dword ptr ss:[esp+14],0F003F      ; |
00401634  |.  C74424 10 000>mov dword ptr ss:[esp+10],0           ; |
0040163C  |.  C74424 0C 000>mov dword ptr ss:[esp+C],0            ; |
00401644  |.  C74424 08 000>mov dword ptr ss:[esp+8],0            ; |
0040164C  |.  C74424 04 6A5>mov dword ptr ss:[esp+4],crackme.0040>; |software\crack me1
00401654  |.  C70424 020000>mov dword ptr ss:[esp],80000002       ; |
0040165B  |.  E8 5C0F0000   call <jmp.&ADVAPI32.RegCreateKeyExA>  ; \RegCreateKeyExA
00401660  |.  83EC 24       sub esp,24
00401663  |.  8D5C24 3C     lea ebx,dword ptr ss:[esp+3C]         ; |
00401667  |.  895C24 14     mov dword ptr ss:[esp+14],ebx         ; |
0040166B  |.  C74424 10 000>mov dword ptr ss:[esp+10],0           ; |
00401673  |.  C74424 0C 000>mov dword ptr ss:[esp+C],0            ; |
0040167B  |.  C74424 08 000>mov dword ptr ss:[esp+8],0            ; |
00401683  |.  C74424 04 7D5>mov dword ptr ss:[esp+4],crackme.0040>; |name
0040168B  |.  8B4424 34     mov eax,dword ptr ss:[esp+34]         ; |
0040168F  |.  890424        mov dword ptr ss:[esp],eax            ; |
00401692  |.  E8 2D0F0000   call <jmp.&ADVAPI32.RegQueryValueExA> ; \RegQueryValueExA
......
004016D8  |> \895C24 14     mov dword ptr ss:[esp+14],ebx         ; |
004016DC  |.  C74424 10 000>mov dword ptr ss:[esp+10],0           ; |
004016E4  |.  C74424 0C 000>mov dword ptr ss:[esp+C],0            ; |
004016EC  |.  C74424 08 000>mov dword ptr ss:[esp+8],0            ; |
004016F4  |.  C74424 04 825>mov dword ptr ss:[esp+4],crackme.0040>; |key
004016FC  |.  8B4424 34     mov eax,dword ptr ss:[esp+34]         ; |
00401700  |.  890424        mov dword ptr ss:[esp],eax            ; |
00401703  |.  E8 BC0E0000   call <jmp.&ADVAPI32.RegQueryValueExA> ; \RegQueryValueExA
......
0040173B  |.  83EC 18       sub esp,18
0040173E  |.  8B4424 34     mov eax,dword ptr ss:[esp+34]         ; |
00401742  |.  890424        mov dword ptr ss:[esp],eax            ; |
00401745  |.  E8 820E0000   call <jmp.&ADVAPI32.RegCloseKey>      ; \RegCloseKey
0040174A  |.  50            push eax
0040174B  |.  803D 20744000>cmp byte ptr ds:[407420],0
00401752  |.^ 0F84 79FFFFFF je crackme.004016D1
00401758  |.  C74424 08 010>mov dword ptr ss:[esp+8],1
00401760  |.  C74424 04 207>mov dword ptr ss:[esp+4],crackme.0040>
00401768  |.  C70424 207440>mov dword ptr ss:[esp],crackme.004074>;  name
0040176F  |.  E8 18FCFFFF   call crackme.0040138C                 ;  关键Call
00401774  |.  31C0          xor eax,eax

一看就知道在software\crack me1这个注册表项下面有两个名为name和key的值

打开regedit注册表编辑器搜索“crack”,找到这里“HKLM\software\crack me1”,新建文本值name=playboysen,key=369852147
在0040176F关键Call下断点,重新加载运行断下后F7跟入
[AppleScript] 纯文本查看 复制代码
004013B4  |.  C74424 04 645>mov dword ptr ss:[esp+4],crackme.0040>; |%s
004013BC  |.  8D7424 11     lea esi,dword ptr ss:[esp+11]         ; |
004013C0  |.  893424        mov dword ptr ss:[esp],esi            ; |
004013C3  |.  E8 1C120000   call <jmp.&USER32.wsprintfA>          ; \wsprintfA
004013C8  |.  85DB          test ebx,ebx
004013CA  |.  7E 50         jle short crackme.0040141C
004013CC  |>  0FBE5424 11   movsx edx,byte ptr ss:[esp+11]        ;  [esp + 11] = userName
004013D1  |.  84D2          test dl,dl                            ;  dl = userName[1]
004013D3  |.  74 71         je short crackme.00401446
004013D5  |.  B8 09000000   mov eax,9                             ;  eax = 9
004013DA  |.  31C9          xor ecx,ecx                           ;  ecx = 0
004013DC  |>  0FAFD0        /imul edx,eax                         ;  userName[i] * (9+i)
004013DF  |.  01D1          |add ecx,edx                          ;  ecx = ecx + userName[i]*(9+i)
004013E1  |.  40            |inc eax
004013E2  |.  0FBE5404 08   |movsx edx,byte ptr ss:[esp+eax+8]    ;  dl = userName下一字节
004013E7  |.  84D2          |test dl,dl
004013E9  |.^ 75 F1         \jnz short crackme.004013DC           ;  for i in range(len(userName))
004013EB  |.  81F9 C9F48100 cmp ecx,81F4C9                        ;  比较运算后的结果
004013F1  |.  7F 0C         jg short crackme.004013FF
004013F3  |.  90            nop
004013F4  |>  8D0C49        /lea ecx,dword ptr ds:[ecx+ecx*2]     ;  while ecx<=0x81F4C9: ecx=ecx*3
004013F7  |.  81F9 C9F48100 |cmp ecx,81F4C9
004013FD  |.^ 7E F5         \jle short crackme.004013F4
004013FF  |>  81C9 CAF48100 or ecx,81F4CA                         ; |两次运算后ECX OR 0x81F4CA
00401405  |.  894C24 08     mov dword ptr ss:[esp+8],ecx          ; |
00401409  |.  C74424 04 675>mov dword ptr ss:[esp+4],crackme.0040>; |%d
00401411  |.  893424        mov dword ptr ss:[esp],esi            ; |
00401414  |.  E8 CB110000   call <jmp.&USER32.wsprintfA>          ; \wsprintfA

简单运算还原为Python源码如下:
[Python] 纯文本查看 复制代码
for j in range(len(userName)):
    regCode = regCode + ord(userName[j]) * (9+j)

while True:
    if regCode > 0x81F4C9:
        regCode = regCode | 0x81F4CA
        break
    else:
        regCode = regCode*3

用以上代码计算出来name=playboysen,key=10878155,打开regedit注册表编辑器“HKLM\software\crack me1”,填入这组信息再打开程序提示已注册O(∩_∩)O~


一番激动后,删除上面的注册表值,直接把name=playboysen,key=10878155输入主程序,点击注册竟然完全没有反应,我顶⊙﹏⊙b 上当鸟儿~~~~
不是我方太无能,实在是对手太狡猾!!!

重新梳理一遍思路,刚刚OD查看字符串的时候好像看到有个“注册成功”提示,打开代码上下翻一翻,发现附近有处代码连续两次调用GetDlgItemTextA,很可疑啊猜测是读取用户名和注册码用的,下断点测试成功断下
[AppleScript] 纯文本查看 复制代码
00401A6B   .  83EC 08       sub esp,8
00401A6E   .  8B4424 30     mov eax,dword ptr ss:[esp+30]         ; |
00401A72   .  890424        mov dword ptr ss:[esp],eax            ; |
00401A75   .  E8 520B0000   call <jmp.&ADVAPI32.RegCloseKey>      ; \RegCloseKey
00401A7A   .  52            push edx
00401A7B   .  E8 90FBFFFF   call crackme.00401610
00401A80   .  85C0          test eax,eax                          ; |
00401A82   .  74 27         je short crackme.00401AAB             ; |
00401A84   .  C74424 0C 000>mov dword ptr ss:[esp+C],0            ; |
00401A8C   .  C74424 08 995>mov dword ptr ss:[esp+8],crackme.0040>; |fd
00401A94   .  C74424 04 9C5>mov dword ptr ss:[esp+4],crackme.0040>; |注册成功
00401A9C   .  8B4424 60     mov eax,dword ptr ss:[esp+60]         ; |
00401AA0   .  890424        mov dword ptr ss:[esp],eax            ; |
00401AA3   .  E8 5C0B0000   call <jmp.&USER32.MessageBoxA>        ; \MessageBoxA
......
00401ACC   >  C74424 0C FF0>mov dword ptr ss:[esp+C],0FF          ; |
00401AD4   .  C74424 08 207>mov dword ptr ss:[esp+8],crackme.0040>; |
00401ADC   .  C74424 04 EA0>mov dword ptr ss:[esp+4],3EA          ; |
00401AE4   .  8B4424 60     mov eax,dword ptr ss:[esp+60]         ; |
00401AE8   .  890424        mov dword ptr ss:[esp],eax            ; |
00401AEB   .  E8 1C0B0000   call <jmp.&USER32.GetDlgItemTextA>    ; \GetDlgItemTextA
00401AF0   .  83EC 10       sub esp,10
00401AF3   .  C70424 207340>mov dword ptr ss:[esp],crackme.004073>; |
00401AFA   .  E8 3D0B0000   call <jmp.&KERNEL32.lstrlenA>         ; \lstrlenA
00401AFF   .  51            push ecx
......
00401B85   .  C74424 0C FF0>mov dword ptr ss:[esp+C],0FF          ; |
00401B8D   .  C74424 08 207>mov dword ptr ss:[esp+8],crackme.0040>; |
00401B95   .  C74424 04 E90>mov dword ptr ss:[esp+4],3E9          ; |
00401B9D   .  A1 88754000   mov eax,dword ptr ds:[407588]         ; |
00401BA2   .  890424        mov dword ptr ss:[esp],eax            ; |
00401BA5   .  E8 620A0000   call <jmp.&USER32.GetDlgItemTextA>    ; \GetDlgItemTextA
00401BAA   .  83EC 10       sub esp,10
00401BAD   .  C74424 0C FF0>mov dword ptr ss:[esp+C],0FF          ; |
00401BB5   .  C74424 08 207>mov dword ptr ss:[esp+8],crackme.0040>; |
00401BBD   .  C74424 04 EA0>mov dword ptr ss:[esp+4],3EA          ; |
00401BC5   .  A1 88754000   mov eax,dword ptr ds:[407588]         ; |
00401BCA   .  890424        mov dword ptr ss:[esp],eax            ; |
00401BCD   .  E8 3A0A0000   call <jmp.&USER32.GetDlgItemTextA>    ; \GetDlgItemTextA
00401BD2   .  83EC 10       sub esp,10
00401BD5   .  803D 20744000>cmp byte ptr ds:[407420],0
00401BDC   .  74 09         je short crackme.00401BE7
00401BDE   .  803D 20734000>cmp byte ptr ds:[407320],0
00401BE5   .  75 10         jnz short crackme.00401BF7
00401BE7   >  C705 24754000>mov dword ptr ds:[407524],0
00401BF1   .  83C4 4C       add esp,4C
00401BF4   .  C2 1400       retn 14
00401BF7   >  C70424 0A0000>mov dword ptr ss:[esp],0A             ;  赋值常数10,关键!
00401BFE   .  E8 49F8FFFF   call crackme.0040144C                 ;  关键Call,注册码来啦!!

一路F8单步下来到00401BFE又是个关键Call(何以见得?程序已经读入用户名和注册码接着就来了个函数,你猜他要干嘛?)F7跟进发现了熟悉的身影!!!
[AppleScript] 纯文本查看 复制代码
0040144C  /$  56            push esi
0040144D  |.  53            push ebx
0040144E  |.  83EC 14       sub esp,14
00401451  |.  8B5C24 20     mov ebx,dword ptr ss:[esp+20]         ;  记得这个参数吗?ebx = 10
00401455  |.  31F6          xor esi,esi                           ;  esi = 0
00401457  |.  85DB          test ebx,ebx
00401459  |.  7E 59         jle short crackme.004014B4
0040145B  |.  90            nop
0040145C  |>  0FBE15 207440>/movsx edx,byte ptr ds:[407420]       ;  [407420] = userName
00401463  |.  84D2          |test dl,dl                           ;  dl = userName[1]
00401465  |.  74 24         |je short crackme.0040148B
00401467  |.  B8 09000000   |mov eax,9                            ;  eax = 9
0040146C  |>  0FAFD0        |/imul edx,eax                        ;  userName[i] * (9+i)
0040146F  |.  01D6          ||add esi,edx                         ;  esi = esi + userName[i]*(9+i)
00401471  |.  40            ||inc eax
00401472  |.  0FBE90 177440>||movsx edx,byte ptr ds:[eax+407417]  ;  dl = userName下一字节
00401479  |.  84D2          ||test dl,dl
0040147B  |.^ 75 EF         |\jnz short crackme.0040146C          ;  for i in range(len(userName))
0040147D  |.  81FE C9F48100 |cmp esi,81F4C9                       ;  比较运算后的结果
00401483  |.  7F 0E         |jg short crackme.00401493
00401485  |.  8D76 00       |lea esi,dword ptr ds:[esi]
00401488  |>  8D3476        |lea esi,dword ptr ds:[esi+esi*2]     ;  while esi<=0x81F4C9: esi=esi*3
0040148B  |>  81FE C9F48100 |cmp esi,81F4C9
00401491  |.^ 7E F5         |jle short crackme.00401488
00401493  |>  81CE CAF48100 |or esi,81F4CA                        ; |多次运算后ESI OR 0x81F4CA
00401499  |.  897424 08     |mov dword ptr ss:[esp+8],esi         ; |esi是最终结果
0040149D  |.  C74424 04 675>|mov dword ptr ss:[esp+4],crackme.004>; |%d
004014A5  |.  C70424 207240>|mov dword ptr ss:[esp],crackme.00407>; |12056270
004014AC  |.  E8 33110000   |call <jmp.&USER32.wsprintfA>         ; \wsprintfA
004014B1  |.  4B            |dec ebx                              ;  以上运算要重复10次
004014B2  |.^ 75 A8         \jnz short crackme.0040145C
004014B4  |>  B8 01000000   mov eax,1                             ;  一段不太复杂的运算重复10次
004014B9  |.  83C4 14       add esp,14                            ;  就得出了亲爱的注册码!!
004014BC  |.  5B            pop ebx
004014BD  |.  5E            pop esi
004014BE  \.  C3            retn

我晕哪,太狡猾鸟儿~~最终的注册码竟然是用户名重复运算十次生成的,刚刚不成功主要是因为才运算了一次!

搞定!注册机源码如下:
[Python] 纯文本查看 复制代码
#-------------------------------------------------------------------------------
# Name:     MK的小玩意+qq54007
# Author:   Playboysen
# Created: 19/12/2013
# Version:  Python2.7 && Windows7 x64
#-------------------------------------------------------------------------------
#!/usr/bin/env python

userName = raw_input("UserName:")
regCode = 0

if len(userName)>20:
    print "UserName: %s\nCome on,your name is too long!" % userName
else:
    for temp in range(10):
        for j in range(len(userName)):
            regCode = regCode + ord(userName[j]) * (9+j)

        while True:
            if regCode > 0x81F4C9:
                regCode = regCode | 0x81F4CA
                break
            else:
                regCode = regCode*3

    print  "UserName: %s\nRegCode: %s" % (userName,regCode)


爆破也很容易,见图

测试以上注册机,生成可用的用户名和注册码如下图:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

免费评分

参与人数 1热心值 +1 收起 理由
Chief + 1 吾爱破解2013CM大赛,有你更精彩!

查看全部评分

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

我是用户 发表于 2013-12-19 21:26
膜拜大神
 楼主| playboysen 发表于 2013-12-19 22:02
我是用户 发表于 2013-12-19 21:26
膜拜大神

长期挂机啊 经常第一时间看到你
sugie0708 发表于 2013-12-19 23:23
zrmpop 发表于 2013-12-20 00:41
膜拜大神, 很厉害
qq54007 发表于 2013-12-20 10:27
仁兄果然犀利,身为cm作者被破得心服口服……但也算长见识了。
1、注册表这里的确忽略了,成了突破口
2、“注册成功”字样本是迷惑破解者,但是不曾想反被其误,成了破解者的武器
3、算法过于简单,以至于被轻松还原代码
4、程序的验证部分在定时器里,也就是按钮事件只是设置一个标志位,告诉定时器可以检查了,但是对于API断点的干扰,只有按钮事件里一带而过,力度不够
5、注册码的生成过程依然没有避免明码字符串在内存中的出现

几日之后我会再写一个绑定机器的crack me,这次难度一定会大大提高,请楼主留意,诚邀破解、交流
 楼主| playboysen 发表于 2013-12-20 11:18
qq54007 发表于 2013-12-20 10:27
仁兄果然犀利,身为cm作者被破得心服口服……但也算长见识了。
1、注册表这里的确忽略了,成了突破口
2、 ...

角度不一样 对于Cracker就是找漏洞挖墙脚 四处寻觅抓住木桶的明显短板
千里之堤溃于蚁穴 其实对于防守方来说难度更大要求更高
等待下一大作=_=
华仔 发表于 2013-12-21 01:08
进来膜拜大神,学习了
bonwe95 发表于 2013-12-21 01:17
好厉害的样子
qq54007 发表于 2013-12-23 20:20
playboysen 发表于 2013-12-20 11:18
角度不一样 对于Cracker就是找漏洞挖墙脚 四处寻觅抓住木桶的明显短板
千里之堤溃于蚁穴 其实对于防守方 ...

MK的杀手锏:http://www.52pojie.cn/thread-230167-1-1.html,请指教
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-24 23:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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