| 关键词: nbsp 004010 004012 PTR EAX ECX PUSH DWORD ESP 注册码 |
为了好好的学习一下加密中的各种类型的算法,正好windrand贴出了各类应用密码学的CrackMe(下载地址:http://bbs.pediy.com/showthread.php?t=47488)。本来很早就想系统学习一下了,但由于各种原因,一直没有时间,现在总算有时间了,可以慢慢研究了,希望可以都能通过自己全部了解和掌握。再次感谢windrand无私的提供了练习的好机会! Hash类CrackMe: CRC32算法 ==>CRC32CrackMe CRC(CyclicRedundancyCheck,直译:循环冗余校验)技术是一项很成熟的技术,在众多领域有广泛的应用,在数据存储和通信传输应用中处处都可以看到它的身影。最常用的CRC校验形式有CRC-16,CRC-32两种形式,采用CRC-16校验,可以保证在1014 位码元中只含有一位未被检测出的错误,采用CRC-32校验的出错概率比CRC-16还低105 倍。CRC的主要特点就是:检错能力极强,开销很小,易于实现。从性能和开销上综合考虑,其远远优于奇偶校验及算术和校验等方式。因此,很多软件在加密保护时都将CRC技术应用其中。 -------------------------------------------------------------------------------- 【注册验证部分代码】 00401282 . 68 00010000 PUSH 100 ; /Count = 100 (256.) 00401287 . 51 PUSH ECX ; |Buffer 00401288 . 68 E8030000 PUSH 3E8 ; |ControlID = 3E8 (1000.) 0040128D . 56 PUSH ESI ; |hWnd 0040128E . FFD3 CALL EBX ; \GetDlgItemTextA 00401290 . 8DBC24 0C0100>LEA EDI,DWORD PTR SS:[ESP+10C] ; 用户名地址送EDI(根据字符串参考在这里下断)00401297 . 83C9 FF OR ECX,FFFFFFFF 0040129A . 33C0 XOR EAX,EAX 0040129C . F2:AE REPNE SCAS BYTE PTR ES:[EDI] 0040129E . F7D1 NOT ECX 004012A0 . 49 DEC ECX 004012A1 . 83F9 01 CMP ECX,1 ; 用户名位数与1比较 004012A4 . 73 1F JNB SHORT CRC32Cra.004012C5 ; 大于等于1则跳 004012A6 . 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 004012A8 . 68 8C604000 PUSH CRC32Cra.0040608C ; |注册提示 004012AD . 68 74604000 PUSH CRC32Cra.00406074 ; |用户名不能为空请输入! 004012B2 . 56 PUSH ESI ; |hOwner 004012B3 . FF15 A8504000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>] ; \MessageBoxA 004012B9 . 5F POP EDI 004012BA . 5E POP ESI 004012BB . 33C0 XOR EAX,EAX 004012BD . 5B POP EBX 004012BE . 81C4 00030000 ADD ESP,300 004012C4 . C3 RET 004012C5 > 8D5424 0C LEA EDX,DWORD PTR SS:[ESP+C] 004012C9 . 68 00010000 PUSH 100 004012CE . 52 PUSH EDX 004012CF . 68 07040000 PUSH 407 004012D4 . 56 PUSH ESI 004012D5 . FFD3 CALL EBX 004012D7 . 8D7C24 0C LEA EDI,DWORD PTR SS:[ESP+C] ; 试验码地址送EDI 004012DB . 83C9 FF OR ECX,FFFFFFFF 004012DE . 33C0 XOR EAX,EAX 004012E0 . F2:AE REPNE SCAS BYTE PTR ES:[EDI] 004012E2 . F7D1 NOT ECX 004012E4 . 49 DEC ECX 004012E5 . 83F9 01 CMP ECX,1 ; 试验码位数与1比较 004012E8 . 73 1F JNB SHORT CRC32Cra.00401309 ; 大于等于1则跳 004012EA . 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 004012EC . 68 8C604000 PUSH CRC32Cra.0040608C ; |注册提示 004012F1 . 68 5C604000 PUSH CRC32Cra.0040605C ; |注册码不能为空请输入! 004012F6 . 56 PUSH ESI ; |hOwner 004012F7 . FF15 A8504000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>] ; \MessageBoxA 004012FD . 5F POP EDI 004012FE . 5E POP ESI 004012FF . 33C0 XOR EAX,EAX 00401301 . 5B POP EBX 00401302 . 81C4 00030000 ADD ESP,300 00401308 . C3 RET 00401309 > 8D8424 0C0200>LEA EAX,DWORD PTR SS:[ESP+20C] 00401310 . 8D8C24 0C0100>LEA ECX,DWORD PTR SS:[ESP+10C] ; 用户名地址 00401317 . 50 PUSH EAX 00401318 . 51 PUSH ECX 00401319 . E8 F2FDFFFF CALL CRC32Cra.00401110 ; 算法Call,F7跟进去 0040131E . 8D9424 140200>LEA EDX,DWORD PTR SS:[ESP+214] ; 算法Call计算得到的值 00401325 . 8D4424 14 LEA EAX,DWORD PTR SS:[ESP+14] ; 试验码 00401329 . 52 PUSH EDX ; 注册码地址入栈 0040132A . 50 PUSH EAX ; 试验码地址入栈 0040132B . E8 D0FCFFFF CALL CRC32Cra.00401000 ; 比较真假注册码Call,F7跟进00401330 . 83C4 10 ADD ESP,10 00401333 . 83F8 01 CMP EAX,1 ; EAX=0与0比较 00401336 . 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 00401338 . 68 8C604000 PUSH CRC32Cra.0040608C ; |注册提示 0040133D . 75 18 JNZ SHORT CRC32Cra.00401357 ; |不相等则跳向死亡(关健跳) 0040133F . 68 48604000 PUSH CRC32Cra.00406048 ; |恭喜你,注册码正确! 00401344 . 56 PUSH ESI ; |hOwner 00401345 . FF15 A8504000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>] ; \MessageBoxA 0040134B . 5F POP EDI 0040134C . 5E POP ESI 0040134D . 33C0 XOR EAX,EAX 0040134F . 5B POP EBX 00401350 . 81C4 00030000 ADD ESP,300 00401356 . C3 RET 00401357 > 68 30604000 PUSH CRC32Cra.00406030 ; |注册码错误,继续加油! 0040135C . 56 PUSH ESI ; |hOwner 0040135D . FF15 A8504000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>] ; \MessageBoxA 00401363 . 5F POP EDI 00401364 . 5E POP ESI 00401365 . 33C0 XOR EAX,EAX 00401367 . 5B POP EBX 00401368 . 81C4 00030000 ADD ESP,300 0040136E . C3 RET 【算法Call代码】 00401110 /$ 83EC 0C SUB ESP,0C ; 来到这里 00401113 |. 56 PUSH ESI 00401114 |. 57 PUSH EDI 00401115 |. E8 B6FFFFFF CALL CRC32Cra.004010D0 ; 动态生成码表Call,F7跟进0040111A |. 8B7424 18 MOV ESI,DWORD PTR SS:[ESP+18] ; 取用户名地址送ESI 0040111E |. 83C9 FF OR ECX,FFFFFFFF 00401121 |. 8BFE MOV EDI,ESI 00401123 |. 33C0 XOR EAX,EAX 00401125 |. 83CA FF OR EDX,FFFFFFFF 00401128 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 0040112A |. F7D1 NOT ECX 0040112C |. 49 DEC ECX 0040112D |. 85C9 TEST ECX,ECX ; 测试用户名位数 0040112F |. 7E 1F JLE SHORT CRC32Cra.00401150 ; 为0则跳 00401131 |. 53 PUSH EBX 00401132 |> 8BC2 /MOV EAX,EDX ; 以下循环将进行一系列运算后根据EAX值取上面计算出码表中数据 00401134 |. 33DB |XOR EBX,EBX 00401136 |. 8A1E |MOV BL,BYTE PTR DS:[ESI] ; 依次取用户名 00401138 |. 25 FF000000 |AND EAX,0FF 0040113D |. 33C3 |XOR EAX,EBX 0040113F |. C1EA 08 |SHR EDX,8 00401142 |. 8B0485 208540>|MOV EAX,DWORD PTR DS:[EAX*4+408520] ; 根据EAX的值取动态码表数组中的数据 00401149 |. 33D0 |XOR EDX,EAX ; EDX最后得到一个数值 0040114B |. 46 |INC ESI 0040114C |. 49 |DEC ECX 0040114D |.^ 75 E3 \JNZ SHORT CRC32Cra.00401132 0040114F |. 5B POP EBX 00401150 |> 33C9 XOR ECX,ECX 00401152 |. 8D4424 08 LEA EAX,DWORD PTR SS:[ESP+8] 00401156 |. 894C24 09 MOV DWORD PTR SS:[ESP+9],ECX 0040115A |. 6A 10 PUSH 10 0040115C |. F7D2 NOT EDX ; 这里对EDX取反 0040115E |. 894C24 11 MOV DWORD PTR SS:[ESP+11],ECX 00401162 |. 50 PUSH EAX 00401163 |. 52 PUSH EDX 00401164 |. C64424 14 00 MOV BYTE PTR SS:[ESP+14],0 00401169 |. 884C24 1D MOV BYTE PTR SS:[ESP+1D],CL 0040116D |. E8 24380000 CALL CRC32Cra.00404996 00401172 |. 8D7C24 14 LEA EDI,DWORD PTR SS:[ESP+14] 00401176 |. 83C9 FF OR ECX,FFFFFFFF 00401179 |. 33C0 XOR EAX,EAX 0040117B |. 83C4 0C ADD ESP,0C 0040117E |. 33F6 XOR ESI,ESI 00401180 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 00401182 |. F7D1 NOT ECX 00401184 |. 49 DEC ECX ; 得到注册码个数 00401185 |. 74 25 JE SHORT CRC32Cra.004011AC ; 等于0则跳 00401187 |> 0FBE4C34 08 /MOVSX ECX,BYTE PTR SS:[ESP+ESI+8] 0040118C |. 51 |PUSH ECX 0040118D |. E8 4E020000 |CALL CRC32Cra.004013E0 00401192 |. 884434 0C |MOV BYTE PTR SS:[ESP+ESI+C],AL 00401196 |. 83C4 04 |ADD ESP,4 00401199 |. 8D7C24 08 |LEA EDI,DWORD PTR SS:[ESP+8] 0040119D |. 83C9 FF |OR ECX,FFFFFFFF 004011A0 |. 33C0 |XOR EAX,EAX 004011A2 |. 46 |INC ESI 004011A3 |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI] 004011A5 |. F7D1 |NOT ECX 004011A7 |. 49 |DEC ECX 004011A8 |. 3BF1 |CMP ESI,ECX 004011AA |.^ 72 DB \JB SHORT CRC32Cra.00401187 ; 以上循环用于将注册码中小写字母转换为大写字母 004011AC |> 8B4424 1C MOV EAX,DWORD PTR SS:[ESP+1C] 004011B0 |. 8D5424 08 LEA EDX,DWORD PTR SS:[ESP+8] 004011B4 |. 52 PUSH EDX ; /String2 004011B5 |. 50 PUSH EAX ; |String1 004011B6 |. FF15 00504000 CALL DWORD PTR DS:[<&KERNEL32.lstrcpyA>] ; \lstrcpyA 004011BC |. 5F POP EDI 004011BD |. 5E POP ESI 004011BE |. 83C4 0C ADD ESP,0C 004011C1 \. C3 RET ; 这里结束 【动态生成码表Call】 004010D0 /$ 56 PUSH ESI ; 这里开始 004010D1 |. 33D2 XOR EDX,EDX 004010D3 |. B9 20854000 MOV ECX,CRC32Cra.00408520 ; 指向00408520内存地址(相当于指向一定义数组) 004010D8 |> 8BC2 /MOV EAX,EDX 004010DA |. BE 08000000 |MOV ESI,8 ; 定义小循环次数 004010DF |> A8 01 |/TEST AL,1 ; 测试AL是否为奇数 004010E1 |. 74 09 ||JE SHORT CRC32Cra.004010EC ; 不是则跳 004010E3 |. D1E8 ||SHR EAX,1 ; 右移1位 004010E5 |. 35 2083B8ED ||XOR EAX,EDB88320 ; 与固定值EDB88320异或 004010EA |. EB 02 ||JMP SHORT CRC32Cra.004010EE 004010EC |> D1E8 ||SHR EAX,1 ; 右移1位 004010EE |> 4E ||DEC ESI 004010EF |.^ 75 EE |\JNZ SHORT CRC32Cra.004010DF 004010F1 |. 8901 |MOV DWORD PTR DS:[ECX],EAX ; 将EAX值送入指定内存(数组)中 004010F3 |. 83C1 04 |ADD ECX,4 ; 指向下一个数组单元地址 004010F6 |. 42 |INC EDX ; EDX加1 004010F7 |. 81F9 20894000 |CMP ECX,CRC32Cra.00408920 ; 与数组末地址比较(根据数组起始地址推算,该大循环次数为256次) 004010FD |.^ 7C D9 \JL SHORT CRC32Cra.004010D8 ; 小于则跳 004010FF |. 5E POP ESI 00401100 \. C3 RET ; 这里结束 【比较真假注册码Call】 00401000 /$ 81EC 00020000 SUB ESP,200 ; 这里开始 00401006 |. 56 PUSH ESI 00401007 |. 57 PUSH EDI 00401008 |. B9 3F000000 MOV ECX,3F 0040100D |. 33C0 XOR EAX,EAX 0040100F |. 8D7C24 09 LEA EDI,DWORD PTR SS:[ESP+9] 00401013 |. C64424 08 00 MOV BYTE PTR SS:[ESP+8],0 00401018 |. F3:AB REP STOS DWORD PTR ES:[EDI] 0040101A |. 66:AB STOS WORD PTR ES:[EDI] 0040101C |. AA STOS BYTE PTR ES:[EDI] 0040101D |. B9 3F000000 MOV ECX,3F 00401022 |. 33C0 XOR EAX,EAX 00401024 |. 8DBC24 090100>LEA EDI,DWORD PTR SS:[ESP+109] 0040102B |. C68424 080100>MOV BYTE PTR SS:[ESP+108],0 00401033 |. F3:AB REP STOS DWORD PTR ES:[EDI] 00401035 |. 66:AB STOS WORD PTR ES:[EDI] 00401037 |. 8B35 00504000 MOV ESI,DWORD PTR DS:[<&KERNEL32.lstrcpyA>>; kernel32.lstrcpyA 0040103D |. 8D4C24 08 LEA ECX,DWORD PTR SS:[ESP+8] 00401041 |. AA STOS BYTE PTR ES:[EDI] 00401042 |. 8B8424 0C0200>MOV EAX,DWORD PTR SS:[ESP+20C] 00401049 |. 50 PUSH EAX ; /String2 0040104A |. 51 PUSH ECX ; |String1 0040104B |. FFD6 CALL ESI ; \lstrcpyA 0040104D |. 8B9424 100200>MOV EDX,DWORD PTR SS:[ESP+210] 00401054 |. 8D8424 080100>LEA EAX,DWORD PTR SS:[ESP+108] 0040105B |. 52 PUSH EDX ; /String2 0040105C |. 50 PUSH EAX ; |String1 0040105D |. FFD6 CALL ESI ; \lstrcpyA 0040105F |. 8DBC24 080100>LEA EDI,DWORD PTR SS:[ESP+108] 00401066 |. 83C9 FF OR ECX,FFFFFFFF 00401069 |. 33C0 XOR EAX,EAX 0040106B |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 0040106D |. F7D1 NOT ECX 0040106F |. 49 DEC ECX ; 注册码位数(8位) 00401070 |. 8D7C24 08 LEA EDI,DWORD PTR SS:[ESP+8] 00401074 |. 8BD1 MOV EDX,ECX ; 注册码位数送EDX(EDX=8) 00401076 |. 83C9 FF OR ECX,FFFFFFFF 00401079 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 0040107B |. F7D1 NOT ECX 0040107D |. 49 DEC ECX 0040107E |. 3BCA CMP ECX,EDX ; 试验码位数与注册码位数进行比较 00401080 |. 75 40 JNZ SHORT CRC32Cra.004010C2 ; 不相等则跳 00401082 |. 8D7C24 08 LEA EDI,DWORD PTR SS:[ESP+8] 00401086 |. 83C9 FF OR ECX,FFFFFFFF 00401089 |. 33D2 XOR EDX,EDX 0040108B |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 0040108D |. F7D1 NOT ECX 0040108F |. 49 DEC ECX 00401090 |. 74 22 JE SHORT CRC32Cra.004010B4 00401092 |> 8A4414 08 /MOV AL,BYTE PTR SS:[ESP+EDX+8] 00401096 |. 8A8C14 080100>|MOV CL,BYTE PTR SS:[ESP+EDX+108] 0040109D |. 3AC1 |CMP AL,CL 0040109F |. 75 21 |JNZ SHORT CRC32Cra.004010C2 004010A1 |. 8D7C24 08 |LEA EDI,DWORD PTR SS:[ESP+8] 004010A5 |. 83C9 FF |OR ECX,FFFFFFFF 004010A8 |. 33C0 |XOR EAX,EAX 004010AA |. 42 |INC EDX 004010AB |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI] 004010AD |. F7D1 |NOT ECX 004010AF |. 49 |DEC ECX 004010B0 |. 3BD1 |CMP EDX,ECX 004010B2 |.^ 72 DE \JB SHORT CRC32Cra.00401092 ; 以上循环用于试验码与注册码比较 004010B4 |> 5F POP EDI 004010B5 |. B8 01000000 MOV EAX,1 004010BA |. 5E POP ESI 004010BB |. 81C4 00020000 ADD ESP,200 004010C1 |. C3 RET 004010C2 |> 5F POP EDI 004010C3 |. 33C0 XOR EAX,EAX 004010C5 |. 5E POP ESI 004010C6 |. 81C4 00020000 ADD ESP,200 004010CC \. C3 RET ; 这里结束 -------------------------------------------------------------------------------- C语言注册机如下:(注:该注册机得出的注册码值中字母都是小写的,在实际中应全部为大写,数字则保持不变) 以下C语言代码在VC6.0编译器下调试通过 #include "stdio.h" #include "string.h" //自定义函数// //向table写入码表值 void fun2(unsigned long int *bp1); //根据用户名计算具体数值后查码表得到注册码 unsigned long int fun1(char nam[30],unsigned long int *bp1); //主函数 void main() { unsigned long int a; char name[30];//用户名 unsigned long int table[256]={0};//动态生成的数组码表 unsigned long int *p; p=table;//指针指向动态码表table printf("请输入用户名: "); gets(name); fun2(p);//调用fun2函数向table数组码表写入数据 a=fun1(name,p);//调用fun1函数得到注册码 printf("\n"); printf("你的注册码是: "); printf("%x",a); printf("\n"); } //调用自定义函数 //向table写入码表值:该函数对应动态生成码表Call void fun2(unsigned long int *bp1) { unsigned long int a,c,d,si; unsigned long int *p; p=bp1; d=0; for(c=0;c<256;c++) { a=d; si=0x8; for(si=0x8;si!=0;si--) { if(a%2==1) { a=a>>0x1; a=a^0xedb88320; } else { a=a>>0x1; } } *(p+c)=a; d=d+1; } } //根据用户名计算具体数值后查上述码表得到注册码:该函数对应算法Call代码中蓝色小循环代码 unsigned long int fun1(char nam[30],unsigned long int *bp1) { unsigned long int a,b,d; int m,i; unsigned long int *p; p=bp1; m=strlen(nam); d=0xffffffff; for(i=0;i<m;i++) { a=d; b=0; b=nam[i]; a=a&0xff; a=a^b; d=d>>0x8; a=*(p+a); d=d^a; } d=~d; return d; } 给出一个注册码: 用户名:tgfy 注册码:92FF30CB 来源:看雪论坛 作者:天高飞扬 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|