一个含有crc32算法的CrackMe分析

来源:互联网 发布:ckplayer电影网站源码 编辑:程序博客网 时间:2024/05/15 05:13

exe文件的下载地址为: http://pan.baidu.com/s/1gfw0XKf

启动界面:
这里写图片描述
大概意思是输入用户名和序列号,检查是否匹配,现在用ida打开分析一下:
这里写图片描述

msg==0x111位处理传过来的WM_COMMAND消息

这里写图片描述

这里写图片描述
这里写图片描述
下面对关键的地方进行分析,F5大法:

size = GetDlgItemTextA(hWnd, 1004, name, 255);// 取Name放到name数组里面        if ( size >= 4 )      // 名字必须大于等于4        {          nameSize = size;          codeSize[0] = GetDlgItemTextA(hWnd, 1005, code, 255);          crc32Init();          //对codeSize进行CRC32加密,且必须为0x2f6016f7          //用python写个爆破脚本可得到codeSize为26          if ( Funcrc32(codeSize) == 0x2F6016F7 )          {            RtlZeroMemory(byte_40347F, 8);//初始化0x40347f的8个字节            byte_40347F[0] = code[8];           //取第9位              byte_40347F[1] = code[17];//取第18位            crc32Init();            //将第9位和第18组成的字节数组进行CRC32加密,且必须为0x242C1465            if ( Funcrc32(byte_40347F) == 0x242C1465 )            {              //用python写个爆破脚本可得到9位和18位都为'-'              //可得到Serial的格式为12345678-12345678-12345678              RtlZeroMemory(&buffer1, 10);              RtlZeroMemory(&buffer2, 10);              cnt = 0;              while ( 1 )              {                t = code[cnt];                if ( t > '9' && t < 'A' )                  break;                if ( t < '0' || t > 'F' )       // 16进制检查                  break;                if ( ++cnt == 8 )                {                  count = 0;                  v10 = 0;                  buffer1_1 = &buffer1;                  do                  {                    v10 *= 16;                    v12 = code[count];                    *buffer1_1 = v12;                    if ( v12 < 'A' || v12 > 'F' )                      v13 = v12 - '0';          // 不正常                    else                      v13 = v12 - '7';          // 正常                    LOBYTE(v10) = v13 & 0xF | v10;                    ++buffer1_1;                    ++count;                    step1 = v10;                                  }                  while ( count != 8 );                  // 这个while循环将相应的16进制字符串转化为int类型                  crc32Init();                  crcName = Funcrc32(name);                  //对name数组进行crc32加密,且必须等于Serial的第一部分                  if ( step1 == crcName )       // 名字必须满足这个条件                  {                    v15 = 0;                    v16 = &code[9];//Serial的第二部分的首地址                    while ( 1 )                    {                      v17 = v16[v15];                      if ( v17 > '9' && v17 < 'A' )                        break;                      if ( v17 < '0' || v17 > 'F' )                        break;                      if ( ++v15 == 8 )                      {                        cnt_1 = 0;                        v19 = 0;                        v20 = &buffer2;                        do                        {                          v19 *= 16;                          v21 = v16[cnt_1];                          *v20 = v21;                          *v16 = v21;                          if ( v21 < 'A' || v21 > 'F' )                            v22 = v21 - 48;                          else                            v22 = v21 - 55;                          LOBYTE(v19) = v22 & 0xF | v19;                          ++v20;                          ++cnt_1;                          step2 = v19;                        }                        while ( cnt_1 != 8 );                        // 这个while循环将Serial第二部分的16进制字符串转化为int类型,并保存在step2变量里                        crc32Init();                        crcBuffer1 = Funcrc32(&buffer1);                        if ( step2 == crcBuffer1 )                        {                         //Serial第二部分的值必须等于Serial第一部分CRC32加密后的值                          crc32Init();                          step2 = Funcrc32(&buffer2);                          //对第二部分进行crc32加密,并且保存到step2变量里                          v24 = 0;                          v25 = &code[18];                          while ( 1 )                          {                            v26 = v25[v24];                            if ( (unsigned __int8)v26 > 0x39u && (unsigned __int8)v26 < 0x41u )                              break;                            if ( (unsigned __int8)v26 < 0x30u || (unsigned __int8)v26 > 0x46u )                              break;                            if ( ++v24 == 8 )                            {                              cnt_2 = 0;                              v28 = 0;                              do                              {                                v28 *= 16;                                v29 = v25[cnt_2];                                *v25 = v29;                                if ( (unsigned __int8)v29 < 0x41u || (unsigned __int8)v29 > 0x46u )                                  v30 = v29 - 48;                                else                                  v30 = v29 - 55;                                LOBYTE(v28) = v30 & 0xF | v28;                                ++cnt_2;                                step3 = v28;                              }                              while ( cnt_2 != 8 );这个while循环将Serial的第三部分16进制字符串转换为int类型                              //                               if ( (step2 ^ step1) == step3 )//最后一个条件step2和step1进行异或的值必须为step3                              {                                SetWindowTextA(hWnd, "GOOD JOB, MAN!");//成功                                hCheck = GetDlgItem(hWnd, 0x3EE);                                EnableWindow(hCheck, 0);// 禁用单击按钮
#求codeSize的脚本:def     crc32(v):        '''        Generates the crc32 hash of the v.        @return: str, the str value for the crc32 of the v        '''        return "%08X"%(binascii.crc32(v)&0xffffffff) for i in range(60):            crc = crc32(binascii.a2b_hex('%02X'%i))            #print crc            if crc=='2F6016F7':                print i                break#求第9位和第18位的脚本:for i,j in itertools.product(string.printable,string.printable):            crc =crc32(binascii.a2b_hex('%02X%02x'%(ord(i),ord(j))))            if crc=='242C1465':                print i,j                break#上面是确定Serial的长度和格式:12345678-12345678-12345678#最后注册机为:        import crypt,binascii,itertools        name = raw_input('输入你的注册名(大于4):')        c1 = crc32(name)        print 'c1',c1,hex(int(c1,16))        c2 = crypt.crc32(c1)        print 'c2',c2,hex(int(c2,16))        t = crypt.crc32(c2)        c3 = '%08X'%(int(t,16)^int(c1,16))        print 'Serial:',c1+'-'+c2+'-'+c3
原创粉丝点击