首页
社区
课程
招聘
[原创][原创]crc32crackme程序分析
发表于: 2014-9-20 00:44 10079

[原创][原创]crc32crackme程序分析

2014-9-20 00:44
10079

crc32crackme.exe这个程序下到电脑有一段时间了,一直没有时间分析。晚上有时间就简单分析了一下。大牛略过。图片传送失败,直接上代码吧。
程序无壳,直接拖入OD分析。
在模块之间调用对GetWindowTextA、MessageBoxA下断,F9让程序跑起来。在弹出的对话框中输入。
Name:obabydbg
Code:123456789
点击CheckMe。
断在这里。
004042F4  |.  50            PUSH EAX                                 ; |Buffer
004042F5  |.  A1 28654000   MOV EAX,DWORD PTR DS:[406528]            ; |
004042FA  |.  50            PUSH EAX                                 ; |hWnd => 00030272 (class='Edit',parent=0033004C)
004042FB  |.  E8 DCF9FFFF   CALL <JMP.&user32.GetWindowTextA>        ; \GetWindowTextA
00404300  |.  83FE 05       CMP ESI,5                                ;  输入用户名大于5
00404303  |.  0F8C B1000000 JL crc32cra.004043BA
00404309  |.  8D45 FC       LEA EAX,DWORD PTR SS:[EBP-4]
0040430C  |.  8B4D FC       MOV ECX,DWORD PTR SS:[EBP-4]
0040430F  |.  BA F8434000   MOV EDX,crc32cra.004043F8                ;  ASCII "DiKeN"
00404314  |.  E8 03ECFFFF   CALL crc32cra.00402F1C                   ;  DiKeN和obabydbg连接
00404319  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
0040431C  |.  E8 AFEBFFFF   CALL crc32cra.00402ED0
00404321  |.  8BD0          MOV EDX,EAX
00404323  |.  8D45 FC       LEA EAX,DWORD PTR SS:[EBP-4]
00404326  |.  E8 C5FAFFFF   CALL crc32cra.00403DF0                   ;  用户名算法

输入的Name要大于5,然后会跟字符串DiKeN连接成DiKeNobabydbg。进入00404326这个CALL中。
00403DF0   $  51            PUSH ECX
00403DF1   .  53            PUSH EBX
00403DF2   .  56            PUSH ESI
00403DF3   .  57            PUSH EDI
00403DF4   .  BF 1A3E4000   MOV EDI,crc32cra.00403E1A
00403DF9   .  8B30          MOV ESI,DWORD PTR DS:[EAX]
00403DFB   .  83C8 FF       OR EAX,FFFFFFFF
00403DFE   .  31C9          XOR ECX,ECX
00403E00   >  3206          XOR AL,BYTE PTR DS:[ESI]                 ;  把用户名做运算,生成一个32位的数值
00403E02   .  50            PUSH EAX
00403E03   .  25 FF000000   AND EAX,0FF
00403E08   .  8B1C87        MOV EBX,DWORD PTR DS:[EDI+EAX*4]
00403E0B   .  58            POP EAX
00403E0C   .  C1E8 08       SHR EAX,8
00403E0F   .  31D8          XOR EAX,EBX
00403E11   .  46            INC ESI
00403E12   .  4A            DEC EDX
00403E13   .^ 75 EB         JNZ SHORT crc32cra.00403E00


这里实际上是把用户名做运算,得到一个32位的数值。DiKeNobabydbg我这里得出来的数值为:0xfb000411。其实也模仿上面的代码写程序得出这个值。
F8继续运行程序,断在这里。
00404356  |> \6A 20         PUSH 20
00404358  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
0040435B  |.  E8 40ECFFFF   CALL crc32cra.00402FA0
00404360  |.  50            PUSH EAX                                 ; |Buffer
00404361  |.  A1 2C654000   MOV EAX,DWORD PTR DS:[40652C]            ; |
00404366  |.  50            PUSH EAX                                 ; |hWnd => 00030270 (class='Edit',parent=0033004C)
00404367  |.  E8 70F9FFFF   CALL <JMP.&user32.GetWindowTextA>        ; \GetWindowTextA
0040436C  |.  8D45 F8       LEA EAX,DWORD PTR SS:[EBP-8]
0040436F  |.  8B4D F8       MOV ECX,DWORD PTR SS:[EBP-8]
00404372  |.  BA 08444000   MOV EDX,crc32cra.00404408
00404377  |.  E8 A0EBFFFF   CALL crc32cra.00402F1C
0040437C  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
0040437F  |.  E8 A0FEFFFF   CALL crc32cra.00404224                   ;  注册码的算法
00404384  |.  33F0          XOR ESI,EAX                              ;  用户名生成的数值跟注册码生成的数值异域
进行0040437F这个CALL中。
00404261  |.  B8 01000000   MOV EAX,1
00404266  |>  03D2          /ADD EDX,EDX                             ;  主要是在这里生成的
00404268  |.  8D1492        |LEA EDX,DWORD PTR DS:[EDX+EDX*4]
0040426B  |.  8B5D F8       |MOV EBX,DWORD PTR SS:[EBP-8]
0040426E  |.  0FB65C03 FF   |MOVZX EBX,BYTE PTR DS:[EBX+EAX-1]
00404273  |.  03D3          |ADD EDX,EBX
00404275  |.  83EA 30       |SUB EDX,30
00404278  |.  40            |INC EAX
00404279  |.  3BC8          |CMP ECX,EAX
0040427B  |.^ 75 E9         \JNZ SHORT crc32cra.00404266
这里是主要算法。
然后把Name运算得出的数值跟Code字符串通过算法得出来的值做异或,如果为0就正确。
0xfb000411这个值是通过Name得出来的,如果异或要为0的话,那么通过Code得出的值也必须是0xfb000411。这样的话异或运算才得为0。
通过对代码的分析,把0123456789这个字符串运算成要异或的值。既然有正确的值了,那么就通过0xfb000411这个值把字符串逆算出来。
以下为逆算的代码,代码还可以优化,有兴趣的朋友可以修改。
#include <stdio.h>
#include <stdlib.h>

int main()
{
  unsigned int crc32=0xfb000411;
  unsigned int buffer[20];
  char value[20];
  int i=0;
  int j=0;
  int temp=0;
  while(1)
  {
    if(crc32>=0 && crc32<=0x4a)
      break;
    crc32/=5;
    crc32/=2;
    buffer[i] = crc32;
    i++;
  }
  i-=2;
  temp = crc32;
  temp+=0x30;
  value[j]=(char )temp;
  j+=1;
  while(i>=0)
  {
    crc32*=2;
    crc32*=5;
    temp = buffer[i];
    temp-=crc32;
    temp+=0x30;
    value[j]=temp;
    crc32 = buffer[i];
    i--;
    j++;
  }
  crc32*=2;
  crc32*=5;
  temp = 0xfb000411 - crc32;
  temp+=0x30;
  value[j] = temp;
  value[j+1]='\0';
  printf("%s\n",value);
  return 0;
}
我这里得出来的字符串为:Z11082257
注册正确
文字编辑看起来有点乱,大家就将就着看看吧。


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

收藏
免费 3
支持
分享
最新回复 (9)
雪    币: 1555
活跃值: (3103)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
2
顶一个。/。。。
2014-9-20 09:05
0
雪    币: 207
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
不错。。
2014-9-20 13:00
0
雪    币: 492
活跃值: (51)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
-_-!!!!
2014-9-20 22:39
0
雪    币: 4761
活跃值: (4184)
能力值: ( LV8,RANK:138 )
在线值:
发帖
回帖
粉丝
5
程序也上传上来吧………………
2014-9-20 22:56
0
雪    币: 9178
活跃值: (3104)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
附件为crack文件
上传的附件:
2014-9-21 09:57
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
7
楼主厉害,不过如果crackeme 如果有反调试 就更好了,想看看这方便的
2014-9-22 08:34
0
雪    币: 9178
活跃值: (3104)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
8
可以去看安于此生翻译的使用OllyDbg从零开始Cracking,里面有几章是专门叫反调试的
2014-9-22 09:27
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
楼主,我按你的做法断下来地址和内容你的不一样,是什么原因?
2014-10-4 11:27
0
雪    币: 9178
活跃值: (3104)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
10
不同的系统,不同的机器地址不同很正常的。这只是个方法,不是所有的东西都是一模一样的
2014-10-8 17:05
0
游客
登录 | 注册 方可回帖
返回
//