一个含有crc32算法的CrackMe分析
2017-07-17 22:26
316 查看
exe文件的下载地址为: http://pan.baidu.com/s/1gfw0XKf
启动界面:
大概意思是输入用户名和序列号,检查是否匹配,现在用ida打开分析一下:
下面对关键的地方进行分析,F5大法:
启动界面:
大概意思是输入用户名和序列号,检查是否匹配,现在用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 __i b4cd nt8)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
相关文章推荐
- 一个简单的CrackMe分析
- 新手论坛中的的一个CrackMe_0008的分析
- 一个简单的CrackMe分析
- 终于找到一个最适合新手的Crackme(算法分析+注册机)(转载)
- Ericky的一个crackme的分析
- CrackMe技术等级自测3级一个CrackMe分析
- 一个CrackMe的分析
- 一个简单CrackMe分析+keyGen编写
- 数据结构习题分析:已知由一个线性链表表示的线性表中含有三类字符的数据元素,是编写算法将该线性表分割为三个循环链表,其中每个。。。。。
- 一个通过异常处理进行验证的crackme分析
- 一个用汇编写的crackme分析,隐藏函数调用方面做的很好,很喜欢这个CM
- 一个CrackMe核心代码的不完整分析
- 分析windowManager中添加一个悬浮框的方式
- 又一个有趣的mysql死锁测试与源码分析
- 很早之前想做的一个技术点掌握的分析图表
- 分析Linux内核创建一个新进程的过程
- Linux内核创建一个新进程的过程分析
- 一个notify()的实例分析
- 丁磊:做一个有分析能力的人
- 公共云&私有云对比:一个简单的分析