首页
社区
课程
招聘
[原创]一个CrackMe的算法分析+注册机
发表于: 2007-6-18 09:09 10256

[原创]一个CrackMe的算法分析+注册机

2007-6-18 09:09
10256

【文章标题】: 一个CrackMe的分析
【文章作者】: qianyicy
【作者主页】: 8600606.ys168.com
【下载地址】: 己上传
【加壳方式】: 无壳
【保护方式】: crc检校
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
      首先感谢风间仁兄弟,破解这个CM,他帮了我的大忙,呵呵,
      刚拿到这个CM,说实在话,由于接触破解的时间不怎么长,对这个CM一点头绪都没,一设断点就自动退出,没办法,来论坛
  求助,刚刚好碰上风间仁,他说这个有crc检校,于是,又猛攻了几天的CRC检校,才明白了一点,下面言归正传.
      用ollydbg载入,由于他有crc检校,我们在ReadFile这个函数上下断f9运行,断在了下面:
  00401819  |.  6A 00            push 0                               ; /pOverlapped = NULL
  0040181B  |.  52               push edx                             ; |pBytesRead
  0040181C  |.  56               push esi                             ; |BytesToRead
  0040181D  |.  57               push edi                             ; |Buffer
  0040181E  |.  53               push ebx                             ; |hFile
  0040181F  |.  FF15 0C304000    call dword ptr ds:[<&KERNEL32.ReadFi>; \ReadFile
  00401825  |.  53               push ebx                             ; /hObject
  00401826  |.  FF15 08304000    call dword ptr ds:[<&KERNEL32.CloseH>; \CloseHandle
  0040182C  |.  8A47 3C          mov al,byte ptr ds:[edi+3C]
  0040182F  |.  884424 10        mov byte ptr ss:[esp+10],al
  00401833  |.  8B4424 10        mov eax,dword ptr ss:[esp+10]
  00401837  |.  25 FF000000      and eax,0FF
  0040183C  |.  2BF0             sub esi,eax
  0040183E  |.  8D0C38           lea ecx,dword ptr ds:[eax+edi]
  00401841  |.  56               push esi                             ; /Arg2
  00401842  |.  51               push ecx                             ; |Arg1
  00401843  |.  8B79 FC          mov edi,dword ptr ds:[ecx-4]         ; |
  00401846  |.  8BCD             mov ecx,ebp                          ; |
  00401848  |.  E8 23000000      call CrackMe(.00401870               ; \CrackMe(.00401870
  0040184D  |.  33C9             xor ecx,ecx
  0040184F  |.  3BC7             cmp eax,edi                          
  00401851  |.  5F               pop edi
  00401852  |.  5E               pop esi
  00401853  |.  0F94C1           sete cl
  00401856  |.  5D               pop ebp
  F8跟踪几步后,可以确定cmp eax,edi为关键,只要eax=edi,crc检校便通过,我们只要改为cmp eax,eax,就OK了,
  改完后,F9继续运行,断在了下面:
  00401AA1  |.  6A 00            push 0                               ; /pOverlapped = NULL
  00401AA3  |.  52               push edx                             ; |pBytesRead
  00401AA4  |.  53               push ebx                             ; |BytesToRead
  00401AA5  |.  56               push esi                             ; |Buffer
  00401AA6  |.  57               push edi                             ; |hFile
  00401AA7  |.  FF15 0C304000    call dword ptr ds:[<&KERNEL32.ReadFi>; \ReadFile
  00401AAD  |.  57               push edi                             ; /hObject
  00401AAE  |.  FF15 08304000    call dword ptr ds:[<&KERNEL32.CloseH>; \CloseHandle
  00401AB4  |.  8BBE 00600000    mov edi,dword ptr ds:[esi+6000]
  00401ABA  |.  56               push esi                             ; /block
  00401ABB  |.  E8 38010000      call <jmp.&MFC42.#825>               ; \free
  00401AC0  |.  83C4 04          add esp,4
  00401AC3  |.  8BCD             mov ecx,ebp
  00401AC5  |.  68 42100000      push 1042                            ; /Arg2 = 00001042
  00401ACA  |.  68 00104000      push CrackMe(.00401000               ; |Arg1 = 00401000
  00401ACF  |.  E8 9CFDFFFF      call CrackMe(.00401870               ; \CrackMe(.00401870
  00401AD4  |.  33C9             xor ecx,ecx
  00401AD6  |.  3BF8             cmp edi,eax
  00401AD8  |.  5E               pop esi
  00401AD9  |.  5F               pop edi
  00401ADA  |.  0F94C1           sete cl
  00401ADD  |.  5D               pop ebp
  同样F8跟踪几步后,可以确定cmp edi,eax为关键,只要eax=edi,crc检校便通过,我们只要改为cmp edi,edi,就OK了,
  把改后的程序保存为新文件,再次载入,这下,我们可以下断点了,

  F9运行程序,我们先用mfcspy检测下,看有什么可用信息,
  message map=004032F8(CrackMe(去crc检校).exe+0032F8)
  msg map entries at 00403300(CrackMe(去crc检校).exe+003300)
  OnMsg:WM_PAINT(000f),func=00401370(CrackMe(去crc检校).exe+001370)
  OnMsg:WM_QUERYDRAGICON(0037),func=00401430(CrackMe(去crc检校).exe+001430)
  OnCommand: notifycode=0000 id=03e8,func=00401440(CrackMe(去crc检校).exe+001440)
  OnMsg:WM_TIMER(0113),func=00401A10(CrackMe(去crc检校).exe+001A10)
  OnMsg:WM_CLOSE(0010),func=00401350(CrackMe(去crc检校).exe+001350)
  
  OnCommand: notifycode=0000 id=03e8,func=00401440(CrackMe(去crc检校).exe+001440)
  
  OK,我们在00401440处下断,填入注册码,注册名,按OK,断下来了:
  
  F8一直走:
  0040154B   .  8B46 64          mov eax,dword ptr ds:[esi+64]
  0040154E   .  8B2D D4314000    mov ebp,dword ptr ds:[<&MSVCRT._mbsc>;  msvcrt._mbscmp
  00401554   .  68 EC404000      push CrackMe(.004040EC               ; /s2 = ""
  00401559   .  50               push eax                             ; |s1
  0040155A   .  FFD5             call ebp                             ; \_mbscmp
  0040155C   .  83C4 08          add esp,8
  0040155F   .  85C0             test eax,eax
  00401561   .  74 7A            je short CrackMe(.004015DD
  00401563   .  8B46 60          mov eax,dword ptr ds:[esi+60]
  00401566   .  8D5E 60          lea ebx,dword ptr ds:[esi+60]
  00401569   .  68 EC404000      push CrackMe(.004040EC
  0040156E   .  50               push eax
  0040156F   .  FFD5             call ebp
  00401571   .  83C4 08          add esp,8
  00401574   .  85C0             test eax,eax
  00401576   .  74 65            je short CrackMe(.004015DD           ;  以上为判断注册码和注册名是否为0为0就跳
  00401578   .  8B4E 64          mov ecx,dword ptr ds:[esi+64]
  0040157B   .  33C0             xor eax,eax
  0040157D   >  0FBE1401         movsx edx,byte ptr ds:[ecx+eax]      ;  内存中预存0D F0 AD BA 0D F0 AD BA 0D
  00401581   .  81F2 AA000000    xor edx,0AA                          ;  注册码不足9位时,在注册码后+00,再用相应的数据补足9位
  00401587   .  03FA             add edi,edx                          ;  每一位与0xAA异或后,把结果相加,记为X
  00401589   .  40               inc eax
  0040158A   .  83F8 09          cmp eax,9
  0040158D   .^ 7C EE            jl short CrackMe(.0040157D
  0040158F   .  57               push edi
  00401590   .  51               push ecx
  00401591   .  8BCC             mov ecx,esp
  00401593   .  896424 1C        mov dword ptr ss:[esp+1C],esp
  00401597   .  53               push ebx
  00401598   .  E8 81070000      call <jmp.&MFC42.#535>
  0040159D   .  8BCE             mov ecx,esi                          ; |
  0040159F   .  E8 8C030000      call CrackMe(.00401930               ; \关键跳转,F7跟进
  F8继续,来到:
  00401989  |> /0FBE1C10         /movsx ebx,byte ptr ds:[eax+edx]
  0040198D  |. |03F3             |add esi,ebx
  0040198F  |. |40               |inc eax
  00401990  |. |3BC1             |cmp eax,ecx
  00401992  |.^\7C F5            \jl short CrackMe(.00401989          ;  以上循环求注册名ascii码的和记为Y
  00401994  |>  33C9             xor ecx,ecx
  00401996  |>  0FBE440C 0C      /movsx eax,byte ptr ss:[esp+ecx+C]   ;  关键字符:KEY-KANON
  0040199B  |.  0FAFC6           |imul eax,esi                        ;  Y与关键字符的第一个字符相乘,记为a
  0040199E  |.  99               |cdq                                 ;  符号扩展
  0040199F  |.  BB 1A000000      |mov ebx,1A                          ;  EBX=1A
  004019A4  |.  F7FB             |idiv ebx                            ;  a/ebx
  004019A6  |.  83C2 61          |add edx,61                          ;  余数+61,结果记为b
  004019A9  |.  81F2 AA000000    |xor edx,0AA                         ;  b与AA异或,结果记为c
  004019AF  |.  03FA             |add edi,edx                         ;  EDI=EDI+c,把EDI最终结果记为Z
  004019B1  |.  41               |inc ecx                             ;  计数器+1
  004019B2  |.  83F9 09          |cmp ecx,9                           ;  字符是否读取完,
  004019B5  |.^ 7C DF            \jl short CrackMe(.00401996
  004019B7  |.  8B4424 2C        mov eax,dword ptr ss:[esp+2C]
  004019BB  |.  C74424 20 FFFFFF>mov dword ptr ss:[esp+20],-1
  004019C3  |.  3BF8             cmp edi,eax                          ;  比较X是否和Z相等,如果相等,则注册成功把他改为
                                                                         cmp edi,edi,则爆破成功.
  
  
  到此,此CM己经破解,下面附上C语言注册机原码,
  
  main()
  {
      long x=0,y;
      int a,b,c=0,i;
      char aa[]="KEY-KANON",name[20];
      printf("name:");
      gets(name);
      for(i = 0; i < 20; i++){
           if(name[i] == '\0')
               break;
           x = x+name[i];
           }
      for(i = 0; i < 9; i++){
           y=((x*aa[i])%26+97)^170;
           c=c+y;
           }
      a=c/9;
      b=c/9+c%9;
      for (i = 32; i < 126; i++){
          if ((i^170) == a)
               a=i;
          if ((i^170) == b)
               b=i;
      }
      clrscr();
      printf("Your name is:\t\t\t");
      puts(name);
      printf("\n");
      printf("The Registration code is:\t");
      printf("%c%c%c%c%c%c%c%c%c\n",a,a,a,a,a,a,a,a,b);
      getch();
  }
  
  
--------------------------------------------------------------------------------
【经验总结】
  再次感谢风间仁兄弟,这个CM同一个用户名,应该有很多种注册码,我写的应该是最傻瓜的一种注册方式吧,


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (15)
雪    币: 30303
活跃值: (8804)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
2
灌水....
2007-6-18 10:48
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
顶.......
2007-6-19 21:52
0
雪    币: 244
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
某版主说不得灌水
2007-6-19 22:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
都强啊  看不大懂啊
要努力学习了  呵呵
2007-7-14 00:03
0
雪    币: 215
活跃值: (85)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
哈哈,飞过,看看了~
2007-7-16 23:42
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
7
原来CRC的校验是这样去的,学习了

算法……
2007-7-17 00:29
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
8
再来问下,mfcspy是不是和DEDE性质差不多的那种,是不是检测MFC编译的程序的?
2007-7-17 00:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习编程了.............
2007-7-18 17:18
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
我修改第1处crc后,F9运行,程序自动退出了,这是?
2007-7-18 18:10
0
雪    币: 228
活跃值: (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
11
两处全改掉,程序才可正常运行
2007-7-21 09:41
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
两处全改了后,F9运行还是退出了,为什么?
2007-7-26 15:48
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
为什么我的第二个断点(ReadFile)断不下来,谢谢
2007-7-26 16:24
0
雪    币: 228
活跃值: (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
14
改了任何一个断点后,不能马上存为新文件再次载入,
必须两处断点全改后再存为新文件,用od载入才可设置断点
2007-7-27 09:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
我也是这么做的,F9程序界面一闪就过去了,后就退出了,期待解决!
2007-7-27 10:54
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
期待中......
2007-7-31 08:00
0
游客
登录 | 注册 方可回帖
返回