|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->BenGaly.CrackMe#1 分析 004012B1 |. 6A 40 PUSH 40 ; /Count = 40 (64.) 004012B3 |. 68 38304000 PUSH Crackme2.00403038 ; |Buffer = Crackme2.00403038 004012B8 |. 6A 6A PUSH 6A ; |ControlID = 6A (106.) 004012BA |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004012BD |. E8 08010000 CALL <JMP.&USER32.GetDlgItemTextA> ; \取用户名 004012C2 |. 83F8 00 CMP EAX,0 ; 用户名是否是空 004012C5 |. 74 18 JE SHORT Crackme2.004012DF 004012C7 |. 6A 40 PUSH 40 ; /Count = 40 (64.) 004012C9 |. 68 38314000 PUSH Crackme2.00403138 ; |Buffer = Crackme2.00403138 004012CE |. 6A 6B PUSH 6B ; |ControlID = 6B (107.) 004012D0 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004012D3 |. E8 F2000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \取输入的注册码 004012D8 |. 83F8 00 CMP EAX,0 ; 注册码是否为空 004012DB |. 74 02 JE SHORT Crackme2.004012DF 004012DD |. EB 17 JMP SHORT Crackme2.004012F6 004012DF |> 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 004012E1 |. 68 62344000 PUSH Crackme2.00403462 ; |Key/CrackMe #2 004012E6 |. 68 00304000 PUSH Crackme2.00403000 ; | Please Fill in 1 more Char!! 004012EB |. 6A 00 PUSH 0 ; |hOwner = NULL 004012ED |. E8 FC000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 004012F2 |. C9 LEAVE 004012F3 |. C2 1000 RETN 10 004012F6 |> 68 38304000 PUSH Crackme2.00403038 ; /String = "pediy" 004012FB |. E8 30010000 CALL <JMP.&KERNEL32.lstrlenA> ; \取用户名的长度 00401300 |. 33F6 XOR ESI,ESI 00401302 |. 8BC8 MOV ECX,EAX 00401304 |. B8 01000000 MOV EAX,1 00401309 |> 8B15 38304000 /MOV EDX,DWORD PTR DS:[403038] 0040130F |. 8A90 37304000 |MOV DL,BYTE PTR DS:[EAX+403037] 00401315 |. 81E2 FF000000 |AND EDX,0FF ; 取出每位字符送到EDX。 0040131B |. 8BDA |MOV EBX,EDX 0040131D |. 0FAFDA |IMUL EBX,EDX 00401320 |. 03F3 |ADD ESI,EBX 00401322 |. 8BDA |MOV EBX,EDX 00401324 |. D1FB |SAR EBX,1 00401326 |. 03F3 |ADD ESI,EBX 00401328 |. 2BF2 |SUB ESI,EDX 0040132A |. 40 |INC EAX 0040132B |. 49 |DEC ECX 0040132C |.^ 75 DB \JNZ SHORT Crackme2.00401309 0040132E |. 56 PUSH ESI 0040132F |. 68 38314000 PUSH Crackme2.00403138 ; ASCII "123456" 00401334 |. E8 4A000000 CALL Crackme2.00401383 ; 这个call是将输入的注册码转换成10进制。 00401339 |. 5E POP ESI ; 如果输入的全是数字的话跟进call则很容易看明白 0040133A |. 3BC6 CMP EAX,ESI ; 真假注册码比较 0040133C 75 15 JNZ SHORT Crackme2.00401353 ; 修改此处可以爆破 下面是将注册码转换成10进制数字的call 00401383 /$ 55 PUSH EBP 00401384 |. 8BEC MOV EBP,ESP 00401386 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; /String 00401389 |. E8 A2000000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA 0040138E |. 53 PUSH EBX 0040138F |. 33DB XOR EBX,EBX 00401391 |. 8BC8 MOV ECX,EAX 00401393 |. 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] 00401396 |> 51 /PUSH ECX 00401397 |. 33C0 |XOR EAX,EAX 00401399 |. AC |LODS BYTE PTR DS:[ESI] 0040139A |. 83E8 30 |SUB EAX,30 0040139D |. 49 |DEC ECX 0040139E |. 74 05 |JE SHORT Crackme2.004013A5 004013A0 |> 6BC0 0A |/IMUL EAX,EAX,0A 004013A3 |.^ E2 FB |\LOOPD SHORT Crackme2.004013A0 004013A5 |> 03D8 |ADD EBX,EAX 004013A7 |. 59 |POP ECX 004013A8 |.^ E2 EC \LOOPD SHORT Crackme2.00401396 004013AA |. 8BC3 MOV EAX,EBX 004013AC |. 5B POP EBX 004013AD |. C9 LEAVE 004013AE \. C2 0400 RETN 4 算法:注册码是根据用户名计算出来的,一组正确注册码:pediy 58140 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char name[]={"123456"}; //注册名,注册码不能为空。 int i,namelen; unsigned int eax,ecx,edx,esi,ebx; esi=0; namelen=strlen(name); ecx=namelen; eax=1; for (i=0;i<namelen;i++) { edx=name[i]; edx=edx & 0x0FF; ebx=edx; ebx=ebx*edx; esi=esi+ebx; ebx=edx; ebx=ebx/0x2; esi=esi+ebx; esi=esi-edx; } printf("注册码:%d\n",esi); getchar(); return 0; } |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->AD_CM#4 分析 查找字符串,来到以下地方, 00458159 |. 55 PUSH EBP 0045815A |. 68 90824500 PUSH AD_CM#4_.00458290 0045815F |. 64:FF30 PUSH DWORD PTR FS:[EAX] 00458162 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 00458165 |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8] 00458168 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0045816B |. 8B80 D8020000 MOV EAX,DWORD PTR DS:[EAX+2D8] 00458171 |. E8 16BFFCFF CALL AD_CM#4_.0042408C ; 取输入用户名放于【EBP-8】 00458176 |. 8D55 EC LEA EDX,DWORD PTR SS:[EBP-14] 00458179 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0045817C |. 8B80 D8020000 MOV EAX,DWORD PTR DS:[EAX+2D8] 00458182 |. E8 05BFFCFF CALL AD_CM#4_.0042408C ; 又取用户名,放于【EBP-14】 00458187 |. 837D EC 00 CMP DWORD PTR SS:[EBP-14],0 ; 判断用户名是否为空 0045818B |. 75 0A JNZ SHORT AD_CM#4_.00458197 0045818D |. B8 A8824500 MOV EAX,AD_CM#4_.004582A8 ; Enter you name, pls. 00458192 |. E8 4DC1FEFF CALL AD_CM#4_.004442E4 ; 用户名空则提示错误 00458197 |> 8D55 E8 LEA EDX,DWORD PTR SS:[EBP-18] 0045819A |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0045819D |. 8B80 DC020000 MOV EAX,DWORD PTR DS:[EAX+2DC] 004581A3 |. E8 E4BEFCFF CALL AD_CM#4_.0042408C ; 取输入的注册码放于【EBP-18】 004581A8 |. 837D E8 00 CMP DWORD PTR SS:[EBP-18],0 ; 注册码是否为空,空则提示错误 004581AC |. 75 0A JNZ SHORT AD_CM#4_.004581B8 004581AE |. B8 C8824500 MOV EAX,AD_CM#4_.004582C8 ; Enter the serial, pls. 004581B3 |. E8 2CC1FEFF CALL AD_CM#4_.004442E4 004581B8 |> 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 004581BB |. E8 BCB9FAFF CALL AD_CM#4_.00403B7C ; 返回用户名的长度 004581C0 |. 8BF8 MOV EDI,EAX ; 长度存放EDI 004581C2 |. 85FF TEST EDI,EDI 004581C4 |. 7E 50 JLE SHORT AD_CM#4_.00458216 004581C6 |. BB 01000000 MOV EBX,1 ; EBX置初值1 004581CB |> 8B45 F8 /MOV EAX,DWORD PTR SS:[EBP-8] ; 输入的用户名送入EAX 004581CE |. 0FB67418 FF |MOVZX ESI,BYTE PTR DS:[EAX+EBX-1] ; 取出用户名的每一位 004581D3 |. 8BC6 |MOV EAX,ESI 004581D5 |. B9 06000000 |MOV ECX,6 004581DA |. 33D2 |XOR EDX,EDX 004581DC |. F7F1 |DIV ECX 004581DE |. 8B55 F8 |MOV EDX,DWORD PTR SS:[EBP-8] 004581E1 |. 8BD6 |MOV EDX,ESI 004581E3 |. C1EA 02 |SHR EDX,2 004581E6 |. F7EA |IMUL EDX 004581E8 |. 50 |PUSH EAX 004581E9 |. 8B45 F8 |MOV EAX,DWORD PTR SS:[EBP-8] 004581EC |. 8BC6 |MOV EAX,ESI 004581EE |. B9 0A000000 |MOV ECX,0A 004581F3 |. 33D2 |XOR EDX,EDX 004581F5 |. F7F1 |DIV ECX 004581F7 |. 5A |POP EDX 004581F8 |. 92 |XCHG EAX,EDX 004581F9 |. 8BCA |MOV ECX,EDX 004581FB |. 33D2 |XOR EDX,EDX 004581FD |. F7F1 |DIV ECX 004581FF |. 8D55 E4 |LEA EDX,DWORD PTR SS:[EBP-1C] 00458202 |. E8 FDF8FAFF |CALL AD_CM#4_.00407B04 ; 这个call将计算出来的值(EAX中)转换成10进制 00458207 |. 8B55 E4 |MOV EDX,DWORD PTR SS:[EBP-1C] 0045820A |. 8D45 F4 |LEA EAX,DWORD PTR SS:[EBP-C] 0045820D |. E8 72B9FAFF |CALL AD_CM#4_.00403B84 ; 将转换后的十进制逐个合并。 00458212 |. 43 |INC EBX 00458213 |. 4F |DEC EDI 00458214 |.^ 75 B5 \JNZ SHORT AD_CM#4_.004581CB ; 这个循环根据注册名每一位计算出一个值并转换成10进制, 00458216 |> 68 E8824500 PUSH AD_CM#4_.004582E8 ; ADCM4- 0045821B |. FF75 F4 PUSH DWORD PTR SS:[EBP-C] 0045821E |. 68 F8824500 PUSH AD_CM#4_.004582F8 ; -YEAH! 00458223 |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10] 00458226 |. BA 03000000 MOV EDX,3 0045822B |. E8 0CBAFAFF CALL AD_CM#4_.00403C3C ; 将2个字符串和计算出来的字符串合并 00458230 |. 8D55 E0 LEA EDX,DWORD PTR SS:[EBP-20] 00458233 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00458236 |. 8B80 DC020000 MOV EAX,DWORD PTR DS:[EAX+2DC] 0045823C |. E8 4BBEFCFF CALL AD_CM#4_.0042408C ; 取输入的注册码 00458241 |. 8B55 E0 MOV EDX,DWORD PTR SS:[EBP-20] 00458244 |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] 00458247 |. E8 40BAFAFF CALL AD_CM#4_.00403C8C ; 两个注册码比较 0045824C |. 75 0A JNZ SHORT AD_CM#4_.00458258 ; 修改此处可以爆破 0045824E |. B8 08834500 MOV EAX,AD_CM#4_.00458308 ; Well done Cracker, You did it! 00458253 |. E8 8CC0FEFF CALL AD_CM#4_.004442E4 算法分析:注册名不能低于5位,根据注册名算出一个值并转换成10进制,之后合并成一个字符串,最后在该字串的前后添加固定的字符串组成真正的注册码。 一组正确的注册码:“123456” “ADCM4-241919202023-YEAH!”。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char name[]={"123456"}; //注册名不能低于5位。 int i,namelen; unsigned int eax,ecx,edx,esi; unsigned int num1,num2; namelen=strlen(name); printf("注册名:%s\n",name); printf("注册码:ADCM4-"); for (i=0;i<namelen;i++) { esi=name[i]; eax=esi; ecx=0x6; edx=0; eax=eax/ecx; edx=esi; edx=edx/0x04; eax=eax*edx; num1=eax; eax=esi; ecx=0x0A; edx=0; eax=eax/ecx; edx=num1; num2=eax; eax=edx; edx=num2; ecx=edx; edx=0; eax=eax/ecx; printf("%d",eax); } printf("-YEAH!\n"); getchar(); return 0; } |
|
[讨论]找个朋友一起学习探讨,有意思的回帖
彼此彼此呀,我也不是学计算机的。 |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->CodeFantasy CrackMe 分析 OD载入程序,用“超级字符串查找”发现有注册成功的提示,下断点,跟踪如下: 00408DDC |> \68 FF000000 PUSH 0FF ; /Count = FF (255.); Case 3EA of switch 00408DBB 00408DE1 |. 68 9CA24000 PUSH CodeFant.0040A29C ; |Buffer = CodeFant.0040A29C 00408DE6 |. 68 F2030000 PUSH 3F2 ; |ControlID = 3F2 (1010.) 00408DEB |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; | 00408DEE |. 50 PUSH EAX ; |hWnd 00408DEF |. E8 68B9FFFF CALL <JMP.&user32.GetDlgItemTextA> ; \取用户名 00408DF4 |. 8D45 B4 LEA EAX,DWORD PTR SS:[EBP-4C] 00408DF7 |. BA 9CA24000 MOV EDX,CodeFant.0040A29C 00408DFC |. B9 FF000000 MOV ECX,0FF 00408E01 |. E8 6AAAFFFF CALL CodeFant.00403870 00408E06 |. 837D B4 00 CMP DWORD PTR SS:[EBP-4C],0 ; 用户名不为空 00408E0A |. 0F84 9E000000 JE CodeFant.00408EAE 00408E10 |. 68 FF000000 PUSH 0FF ; /Count = FF (255.) 00408E15 |. 68 9CA34000 PUSH CodeFant.0040A39C ; |Buffer = CodeFant.0040A39C 00408E1A |. 68 F3030000 PUSH 3F3 ; |ControlID = 3F3 (1011.) 00408E1F |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; | 00408E22 |. 50 PUSH EAX ; |hWnd 00408E23 |. E8 34B9FFFF CALL <JMP.&user32.GetDlgItemTextA> ; \取输入的注册码 00408E28 |. 8D45 AC LEA EAX,DWORD PTR SS:[EBP-54] 00408E2B |. BA 9CA24000 MOV EDX,CodeFant.0040A29C 00408E30 |. B9 FF000000 MOV ECX,0FF 00408E35 |. E8 36AAFFFF CALL CodeFant.00403870 00408E3A |. 8B45 AC MOV EAX,DWORD PTR SS:[EBP-54] 00408E3D |. 8D55 B0 LEA EDX,DWORD PTR SS:[EBP-50] 00408E40 |. E8 23FCFFFF CALL CodeFant.00408A68 ; 关键call,根据用户名计算一个值 00408E45 |. 8B45 B0 MOV EAX,DWORD PTR SS:[EBP-50] 00408E48 |. 50 PUSH EAX 00408E49 |. 8D45 A8 LEA EAX,DWORD PTR SS:[EBP-58] 00408E4C |. BA 9CA34000 MOV EDX,CodeFant.0040A39C 00408E51 |. B9 FF000000 MOV ECX,0FF 00408E56 |. E8 15AAFFFF CALL CodeFant.00403870 00408E5B |. 8B55 A8 MOV EDX,DWORD PTR SS:[EBP-58] 00408E5E |. 58 POP EAX 00408E5F |. E8 84ABFFFF CALL CodeFant.004039E8 00408E64 |. 75 48 JNZ SHORT CodeFant.00408EAE 00408E66 |. 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 00408E68 |. 68 AC8F4000 PUSH CodeFant.00408FAC ; |注册提示 00408E6D |. 68 B88F4000 PUSH CodeFant.00408FB8 ; |恭喜您,注册码正确! 00408E72 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; | 00408E75 |. 50 PUSH EAX ; |hOwner 00408E76 |. E8 19B9FFFF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA 注册码计算的关键call就不贴了,计算过程如下:分别取出用户名的每一位,其ascii码值+0xA,并转换成16进制表示,且16进制的字母用大写表示,把用户名的所有字符都转换完后就得到了注册码。如:pediy 对应的注册码:7A6F6E7383 p的ascii值0x70 加上0xA 得0x7A,以此类推,y的ascii码:0x79,加0xA后是0x83; 注册机: #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char name[]={"pediy"}; int i; int namelen=strlen(name); printf("注册名:%s\n",name); printf("注册码:"); for (i=0;i<namelen;i++) { printf("%X",name[i]+0xA); } getchar(); return 0; } |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->Rith—CrackMe1 分析 一组正确的注册码:ABCDEF f6d2bh 不知这个cm有问题还是程序有问题,还是我分析的不彻底,有人知道的话请指出。计算出来的值如果超过0x7F的话就是错误的注册码,全部都小于0x7F时才正确,也就是超过了ascii表的范围显示出来的就不正确。注册名不能小于5位,注册码和注册名位数要相同,取出注册名的每一位和固定字串中的每一位后计算出一个值。 0040159A . 56 PUSH ESI 0040159B . 8BF1 MOV ESI,ECX 0040159D . 57 PUSH EDI 0040159E . 68 48304000 PUSH Rith_Cra.00403048 ; 31415926535897932384 004015A3 . 8D4C24 14 LEA ECX,DWORD PTR SS:[ESP+14] 004015A7 . 897424 1C MOV DWORD PTR SS:[ESP+1C],ESI 004015AB . E8 FA020000 CALL <JMP.&MFC42.#537> 004015B0 . 6A 01 PUSH 1 004015B2 . 8BCE MOV ECX,ESI 004015B4 . C74424 28 000>MOV DWORD PTR SS:[ESP+28],0 004015BC . E8 E3020000 CALL <JMP.&MFC42.#6334> 004015C1 . 8B7E 60 MOV EDI,DWORD PTR DS:[ESI+60] ; 取得用户名,送EDI 004015C4 . 8B5F F8 MOV EBX,DWORD PTR DS:[EDI-8] ; 用户名长度送EBX 004015C7 . 83FB 05 CMP EBX,5 ; EBX中用户名长度不能小于5 004015CA . 7C 7E JL SHORT Rith_Cra.0040164A 004015CC . 8B46 64 MOV EAX,DWORD PTR DS:[ESI+64] ; 注册码送EAX 004015CF . 894424 14 MOV DWORD PTR SS:[ESP+14],EAX 004015D3 . 3958 F8 CMP DWORD PTR DS:[EAX-8],EBX ; 比较用户名长度和注册码长度 004015D6 . 75 72 JNZ SHORT Rith_Cra.0040164A ; 不等就跳走 004015D8 . 83FB 14 CMP EBX,14 ; 用户名长度是否大于0x14,是否大于20位 004015DB . 7F 6D JG SHORT Rith_Cra.0040164A 004015DD . 33C9 XOR ECX,ECX 004015DF . 85DB TEST EBX,EBX 004015E1 . 7E 54 JLE SHORT Rith_Cra.00401637 004015E3 . 8B7424 10 MOV ESI,DWORD PTR SS:[ESP+10] ; 取字串“31415926535897932384” 004015E7 > 8A040F MOV AL,BYTE PTR DS:[EDI+ECX] ; 逐位取出用户名 004015EA . 0FBE2C31 MOVSX EBP,BYTE PTR DS:[ECX+ESI] ; 逐位取出刚才字串中的字符 004015EE . 0FBEC0 MOVSX EAX,AL 004015F1 . 99 CDQ 004015F2 . F7FD IDIV EBP 004015F4 . 8BC2 MOV EAX,EDX ; 2个字符ascii码相除 004015F6 . D1E0 SHL EAX,1 ; 商值乘以0x2,左移一位相当于*2 004015F8 . 83F8 7B CMP EAX,7B 004015FB . 7E 03 JLE SHORT Rith_Cra.00401600 004015FD . 83E8 1A SUB EAX,1A ; 若大于0x7B,就减去0x1A 00401600 > 83F8 41 CMP EAX,41 00401603 . 7D 09 JGE SHORT Rith_Cra.0040160E 00401605 . BA 82000000 MOV EDX,82 ; 是否小于0x41,小的话就0x82-该值 0040160A . 2BD0 SUB EDX,EAX 0040160C . 8BC2 MOV EAX,EDX 0040160E > 83F8 5B CMP EAX,5B 00401611 . 7E 12 JLE SHORT Rith_Cra.00401625 00401613 . 83F8 61 CMP EAX,61 ; 若<=0x5B 且 >=0x61 就跳到下面 00401616 . 7D 0D JGE SHORT Rith_Cra.00401625 00401618 . 99 CDQ 00401619 . BD 0A000000 MOV EBP,0A 0040161E . F7FD IDIV EBP 00401620 . 83C2 30 ADD EDX,30 00401623 . 8BC2 MOV EAX,EDX 00401625 > 8B5424 14 MOV EDX,DWORD PTR SS:[ESP+14] 00401629 . 38040A CMP BYTE PTR DS:[EDX+ECX],AL 0040162C . 75 1C JNZ SHORT Rith_Cra.0040164A 0040162E . 41 INC ECX 0040162F . 3BCB CMP ECX,EBX 00401631 .^ 7C B4 JL SHORT Rith_Cra.004015E7 00401633 . 8B7424 18 MOV ESI,DWORD PTR SS:[ESP+18] 00401637 > 6A 00 PUSH 0 00401639 . 68 34304000 PUSH Rith_Cra.00403034 ; Congratulations! 0040163E . 68 20304000 PUSH Rith_Cra.00403020 ; Well done cracker! #include <stdlib.h> #include <stdio.h> #include <string.h> #include <windows.h> int main(void) { char name[]={"ABCDEF"}; //不知这个cm有问题还是程序有问题,计算出来的值如果超过0x7F的话就是错误 //的注册码,全部都小于0x7F时才正确,也就是超过了ascii表的范围。 //注册名不能小于5位,注册码和注册名位数要相同,取出注册名的每一位和 //固定字串中的每一位后计算出一个值。 printf("注册名:%s\n",name); printf("注册名:"); char table[]={"31415926535897932384"}; int i,j,namelen,tablelen; int eax,ebx,ecx,edx,ebp; namelen=strlen(name); tablelen=strlen(table); for (i=0;i<namelen;i++) { eax=name[i]; ebp=table[i]; edx=0; edx=eax % ebp; eax=edx; eax=eax*0x2; if (eax>0x7B) { eax=eax-0x1A; } if (eax<0x41) { eax=0x82-eax; } if (eax>0x5B ) { if (eax<0x61) { edx=0; ebp=0x0A; edx=eax % ebp; edx=edx+0x30; eax=edx; } } printf("%c",eax); } printf("\n\n"); getchar(); return 0; } |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->DTC。CrackMe10 分析 查找字符串,来到以下地方,分析如下:脱壳用论坛上的软件脱的 0040119B . 6A 33 PUSH 33 ; /Count = 33 (51.) 0040119D . 68 2C624000 PUSH keygenme.0040622C ; |Buffer = keygenme.0040622C 004011A2 . 68 D1070000 PUSH 7D1 ; |ControlID = 7D1 (2001.) 004011A7 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004011AA . E8 AF010000 CALL <JMP.&user32.GetDlgItemTextA> ; \取输入的用户名 004011AF . 6BC0 05 IMUL EAX,EAX,5 ; 用户名长度*0x5; 004011B2 . 3D FA000000 CMP EAX,0FA ; 是否大于等于0x0FA 004011B7 . 0F87 89000000 JA keygenme.00401246 ; 是否小于等于0x1E,即用户名长度大于5小于50; 004011BD . 83F8 1E CMP EAX,1E 004011C0 . 0F82 80000000 JB keygenme.00401246 004011C6 . 6A 00 PUSH 0 ; /IsSigned = FALSE 004011C8 . 6A 00 PUSH 0 ; |pSuccess = NULL 004011CA . 68 D2070000 PUSH 7D2 ; |ControlID = 7D2 (2002.) 004011CF . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004011D2 . E8 81010000 CALL <JMP.&user32.GetDlgItemInt> ; \GetDlgItemInt 004011D7 . A3 5F624000 MOV DWORD PTR DS:[40625F],EAX ; 取注册码输入框中的值,看来一定要输入数字 004011DC . 68 2C624000 PUSH keygenme.0040622C 004011E1 . E8 C2000000 CALL keygenme.004012A8 ; 关键call跟进。 004011E6 . 803D 63624000>CMP BYTE PTR DS:[406263],1 ; 关键call中会对【406263】设置个标志,在这判断 004011ED . 74 43 JE SHORT keygenme.00401232 ; 若为“1”就跳到失败处,否则成功。 关键算法call跟进后如下: 004012A8 /$ 55 PUSH EBP 004012A9 |. 8BEC MOV EBP,ESP 004012AB |. 803D B4124000>CMP BYTE PTR DS:[4012B4],0CC 004012B2 |. 74 53 JE SHORT keygenme.00401307 004012B4 |. 33C0 XOR EAX,EAX 004012B6 |. 33C9 XOR ECX,ECX 004012B8 |. 803D D4124000>CMP BYTE PTR DS:[4012D4],0CC 004012BF |. 74 46 JE SHORT keygenme.00401307 004012C1 |. 33D2 XOR EDX,EDX 004012C3 |. 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8] ; EDX是输入的用户名 004012C6 |> 8A02 /MOV AL,BYTE PTR DS:[EDX] ; 依次取出注册名的每一个字符送入AL 004012C8 |. 84C0 |TEST AL,AL ; 字符是否取完? 004012CA |. 74 08 |JE SHORT keygenme.004012D4 ; 取完则跳出循环 004012CC |. 03C8 |ADD ECX,EAX 004012CE |. C1C1 08 |ROL ECX,8 004012D1 |. 42 |INC EDX 004012D2 |.^ EB F2 \JMP SHORT keygenme.004012C6 004012D4 |> 83F1 02 XOR ECX,2 004012D7 |. 83E9 50 SUB ECX,50 004012DA |. 81F1 37130000 XOR ECX,1337 004012E0 |. 56 PUSH ESI 004012E1 |. 66:8B35 79614>MOV SI,WORD PTR DS:[406179] 004012E8 |. 66:03CE ADD CX,SI 004012EB |. 803D FA124000>CMP BYTE PTR DS:[4012FA],0CC 004012F2 |. 74 13 JE SHORT keygenme.00401307 004012F4 |. 5E POP ESI 004012F5 |. A1 5F624000 MOV EAX,DWORD PTR DS:[40625F] 【40625f】存放的是先前取得的注册码,是一个16进制数字。 004012FA |. 3BC1 CMP EAX,ECX 004012FC |. 75 04 JNZ SHORT keygenme.00401302 004012FE |. 33C0 XOR EAX,EAX 00401300 |. EB 0E JMP SHORT keygenme.00401310 00401302 |> 33C0 XOR EAX,EAX 00401304 |. 40 INC EAX 00401305 |. EB 10 JMP SHORT keygenme.00401317 00401307 |> C605 63624000>MOV BYTE PTR DS:[406263],1 0040130E |. EB 07 JMP SHORT keygenme.00401317 00401310 |> C605 63624000>MOV BYTE PTR DS:[406263],0 00401317 |> C9 LEAVE 00401318 \. C2 0400 RETN 4 算法:用户名长度大于5小于50位,注册码必须是数字,根据用户名计算出一个值,然后和输入的注册码比较,相等就在一个位置置0,不相等就置1,然后判断该位置的值。 做这个的时候要用到循环移位,但是c语言中的移位运算符并不是循环移位的,后来在网上搜到一个代码 假设移位的数字在ecx中: if (ecx & 0x80000000) { ecx=ecx<<1; ecx=ecx | 0x01; } else ecx=ecx<<1; } 一组正确的注册码:abcdef 1690755840 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <windows.h> int main(void) { char name[]={"abcdef"}; int i,j,namelen; unsigned long int ecx,eax; eax=0; ecx=0; namelen=strlen(name); for (i=0;i<namelen;i++) { eax=name[i]; ecx=ecx+eax; for (j=0;j<8;j++) { if (ecx & 0x80000000) //循环左移一位运算, { ecx=ecx<<1; ecx=ecx | 0x01; } else ecx=ecx<<1; } } ecx=ecx^0x2; ecx=ecx-0x50; ecx=ecx^0x1337; ecx=ecx+0x07DA; printf("注册名:%s\n",name); printf("注册码:%d\n",ecx); printf("\n\n"); getchar(); return 0; } |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->ThrawN的CrackMe 分析 输入注册名和注册码后无反应,后来发现不输入注册名时会提示字符要在2个字符以上,就查找这个字符串提示,来到关键断点处,注册名不能低于3个字符。 00444BFB |. 8BF8 MOV EDI,EAX 00444BFD |. 33C0 XOR EAX,EAX 00444BFF |. 55 PUSH EBP 00444C00 |. 68 EB4C4400 PUSH UP8.00444CEB 00444C05 |. 64:FF30 PUSH DWORD PTR FS:[EAX] 00444C08 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 00444C0B |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 00444C0E |. 8B87 D0020000 MOV EAX,DWORD PTR DS:[EDI+2D0] 00444C14 |. E8 87F1FDFF CALL UP8.00423DA0 ; 取输入的用户名,【EBP-4】 00444C19 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00444C1C |. E8 3FEFFBFF CALL UP8.00403B60 ; 取用户名长度 00444C21 |. 83F8 03 CMP EAX,3 ; 判断用户名长度是否大于等于3 00444C24 |. 7D 15 JGE SHORT UP8.00444C3B 00444C26 |. 6A 00 PUSH 0 ; /Arg1 = 00000000 00444C28 |. 66:8B0D FC4C4>MOV CX,WORD PTR DS:[444CFC] ; | 00444C2F |. B2 01 MOV DL,1 ; | 00444C31 |. B8 084D4400 MOV EAX,UP8.00444D08 ; |Name must be more than 2 characters! 00444C36 |. E8 E5F9FFFF CALL UP8.00444620 ; \UP8.00444620 00444C3B |> 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; 用户名送EAX 00444C3E |. E8 1DEFFBFF CALL UP8.00403B60 ; 该call返回用户名长度 00444C43 |. 8BD8 MOV EBX,EAX 00444C45 |. 85DB TEST EBX,EBX 00444C47 |. 7E 29 JLE SHORT UP8.00444C72 00444C49 |. BE 01000000 MOV ESI,1 ; ESI赋初值1 00444C4E |> 8D4D E8 /LEA ECX,DWORD PTR SS:[EBP-18] 00444C51 |. 8B45 FC |MOV EAX,DWORD PTR SS:[EBP-4] ; 用户名送EAX 00444C54 |. 0FB64430 FF |MOVZX EAX,BYTE PTR DS:[EAX+ESI-1] ; 取出用户名的每一位字符 00444C59 |. BA 02000000 |MOV EDX,2 ; EDX赋值0x2 00444C5E |. E8 BD2EFCFF |CALL UP8.00407B20 ; 从堆栈中可知是该call会是EBP-18等于上面取得的字符ascii码 00444C63 |. 8B55 E8 |MOV EDX,DWORD PTR SS:[EBP-18] 00444C66 |. 8D45 F8 |LEA EAX,DWORD PTR SS:[EBP-8] 00444C69 |. E8 FAEEFBFF |CALL UP8.00403B68 ; 将取出的每个字符的ASCII码合并 00444C6E |. 46 |INC ESI 00444C6F |. 4B |DEC EBX 00444C70 |.^ 75 DC \JNZ SHORT UP8.00444C4E 00444C72 |> 8D55 F0 LEA EDX,DWORD PTR SS:[EBP-10] 00444C75 |. A1 48784400 MOV EAX,DWORD PTR DS:[447848] ; 将【447848】的值送给EAX。 00444C7A |. E8 712EFCFF CALL UP8.00407AF0 ; 该call将EAX的值转换成有符号十进制表示%d 00444C7F |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C] 00444C82 |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8] 00444C85 |. E8 EEECFBFF CALL UP8.00403978 ; 将根据用户名字符计算的结果存于ebp-C 00444C8A |. 8D45 EC LEA EAX,DWORD PTR SS:[EBP-14] 00444C8D |. 8B4D F4 MOV ECX,DWORD PTR SS:[EBP-C] 00444C90 |. 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10] 00444C93 |. E8 14EFFBFF CALL UP8.00403BAC ; 将上面转换的十进制数和上面的结果按字符方式合并成一个 00444C98 |. 8D55 E4 LEA EDX,DWORD PTR SS:[EBP-1C] 00444C9B |. 8B87 D4020000 MOV EAX,DWORD PTR DS:[EDI+2D4] 00444CA1 |. E8 FAF0FDFF CALL UP8.00423DA0 ; 取出输入的假的注册码 00444CA6 |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C] 00444CA9 |. 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14] 00444CAC |. E8 BFEFFBFF CALL UP8.00403C70 ; 比较真假注册码是否相同 00444CB1 |. 75 15 JNZ SHORT UP8.00444CC8 ; 修改此处可以爆破 00444CB3 |. 6A 00 PUSH 0 ; /Arg1 = 00000000 00444CB5 |. 66:8B0D FC4C4>MOV CX,WORD PTR DS:[444CFC] ; | 00444CBC |. B2 02 MOV DL,2 ; | 00444CBE |. B8 384D4400 MOV EAX,UP8.00444D38 ; |Correct! 00444CC3 |. E8 58F9FFFF CALL UP8.00444620 ; \UP8.00444620 上面【447848】的值计算方法是:先取C:盘的序列号,再乘以2, 得值A,将A转换成10进制,取其第四位的数字和A相乘,得值B,B再乘以3的值就是送入【447848】的值。 反汇编分析如下: 00444B18 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 00444B1B |. 6A 00 PUSH 0 ; /pFileSystemNameSize = NULL 00444B1D |. 6A 00 PUSH 0 ; |pFileSystemNameBuffer = NULL 00444B1F |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10] ; | 00444B22 |. 50 PUSH EAX ; |pFileSystemFlags 00444B23 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C] ; | 00444B26 |. 50 PUSH EAX ; |pMaxFilenameLength 00444B27 |. 56 PUSH ESI ; |pVolumeSerialNumber 00444B28 |. 68 00010000 PUSH 100 ; |MaxVolumeNameSize = 100 (256.) 00444B2D |. 8D85 F0FEFFFF LEA EAX,DWORD PTR SS:[EBP-110] ; | 00444B33 |. 50 PUSH EAX ; |VolumeNameBuffer 00444B34 |. 68 E84B4400 PUSH UP8.00444BE8 ; |c:\ 00444B39 |. E8 2A15FCFF CALL <JMP.&KERNEL32.GetVolumeInformation>; \GetVolumeInformationA 00444B3E |. 8B06 MOV EAX,DWORD PTR DS:[ESI] ; 取的的c:\序列号送EAX 00444B40 |. 03C0 ADD EAX,EAX ; 序列号乘以2 00444B42 |. 8BF0 MOV ESI,EAX 00444B44 |. 8D95 ECFEFFFF LEA EDX,DWORD PTR SS:[EBP-114] 00444B4A |. 8BC6 MOV EAX,ESI 00444B4C |. E8 9F2FFCFF CALL UP8.00407AF0 ; 将序列号转换成10进制表示。 00444B51 |. 8B95 ECFEFFFF MOV EDX,DWORD PTR SS:[EBP-114] ; EBP-114中就是转换成的10进制 00444B57 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 00444B5D |. E8 6EF2FDFF CALL UP8.00423DD0 ; 再将10进制数转换成字符串保存 00444B62 |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8] 00444B65 |. 8B83 E8020000 MOV EAX,DWORD PTR DS:[EBX+2E8] 00444B6B |. E8 30F2FDFF CALL UP8.00423DA0 00444B70 |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] 00444B73 |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8] 00444B76 |. 8A52 03 MOV DL,BYTE PTR DS:[EDX+3] ; 十进制数的第4位送DL,从0开始的话就是第三位 00444B79 |. E8 0AEFFBFF CALL UP8.00403A88 00444B7E |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00444B81 |. E8 D62FFCFF CALL UP8.00407B5C ; 取出并转换成数字, 00444B86 |. F7EE IMUL ESI ; 将上面序列号乘以2后的值再乘以转换成10进制数的第四位。 00444B88 |. 8D0440 LEA EAX,DWORD PTR DS:[EAX+EAX*2] ; 再乘以0x3 00444B8B |. A3 48784400 MOV DWORD PTR DS:[447848],EAX ; 将结果送入【447848】,用于后面注册码的计算 贴出一组正确的注册码:用户名“pediy”,注册码是:“-1670752387065646979” 算法见注册机中注释 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <windows.h> int sn(); int main(void) { //这个的算法也很简单,注册码是由2个字符串合并得到的,第一个字符串 //是先求出c盘的序列号并*2,得值A,将A转换成10进制取第四位数字和A相乘后再乘以0x3所得的值按10进制输出。 //第二部分是将输入的用户名的每个字符的ASCII码(16进制表示)转换成字符串 //如用户名“pediy”,注册码是:“-1670752387065646979” char name[]={"pediy"}; printf("注册名:%s\n",name); printf("注册码:%d",sn()); //输出根据序列号计算出的值。 int namelen=strlen(name); int i; for (i=0;i<namelen;i++) //此处就不转换成字符串了,直接打印输出。 { printf("%LX",name[i]); //此处必须是“X”,因为小写的得到的注册码是错误的 } printf("\n\n"); getchar(); return 0; } int sn() //取硬盘序列号并计算出一个值 { char pathName[]={"c:\\"}; char vName[255]; char fName[255]; unsigned long int Serial; GetVolumeInformation(pathName,vName,255,&Serial,0,0,fName,255); Serial=Serial*2; //序列号*2 char buffer[255]; itoa(Serial,buffer,10);//转换成10进制 char n=buffer[3]-0x30; //取其第三位,得的值是该数字的ascii码-0x30 Serial=Serial*n; //和上面的数字相乘 Serial=Serial*0x3; //再乘以3 return Serial; } |
|
[讨论][讨论]你看到最多精华帖子的账户叫什么和精华帖子数?
为什么我看中文都看不明白 |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->Olivers CrackMe 分析 这个crackme分析起来不是很难,但就是很麻烦,中间对字符处理了不下5次。在注册码比较过程中采用的是明码,所以可以直接看到真正的注册码。由于编程水平不行,目前没有写出注册机,等以后再说。具体如下: 输入用户名:abcdef,注册码:123456 注册名必须大于等于6位。 第一步操作是将用户名倒序后得以字符串记作A; 此时为:fedcba 第二步操作是将用户名的N-1位字符分别取出,A的每一位分别转换成10进制,之后组成第二个字符串,用户名的第一位是a,A的第一个字符f的10进制是103,这样就组成a103,依次类推,最终得到字符B:a103b101c100d99e98, 第三步操作是字符串B的首位和末尾除外的字符进行一次重复操作,如B中“a”和“最后的8”不进行操作,得的结果是记作C: 103b101c100d99e9 110033bb110011cc110000dd9999ee99=C 第四步操作是将C 的每一位字符的ASCII码转换成10进制但是最后一位不进行操作。得到的结果记作:D即: 110033bb110011cc110000dd9999ee9 494948485151989849494848494999994949484848481001005757575710110157 第五步操作是从D的第三位开始取字符,并且每次间隔3位,知道D中的字符取到最后或者取得字符数达到0x30位。取出的字符记作:E 485199484949481 第六步操作是从D的第3位开始取字符,从E中取字符,将取出的2个字符分别转换成10进制的数字,然后求2个数相减的绝对值,之后用这个绝对值修改对应的E值,,D值每次循环都累加3,E的每次循环累加1。 直到将E中的每个值就修改完,此时得到的值就是真正的注册码。 001748175151013 00430CA2 |. 33DB XOR EBX,EBX ; EBX置零,用于下面的循环赋初值 00430CA4 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 00430CA7 |. 8B86 DC010000 MOV EAX,DWORD PTR DS:[ESI+1DC] 00430CAD |. E8 669FFEFF CALL <ocrackme.取字符文本> ; 取输入的用户名,存于ebp-4 00430CB2 |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8] 00430CB5 |. 8B86 E0010000 MOV EAX,DWORD PTR DS:[ESI+1E0] 00430CBB |. E8 589FFEFF CALL <ocrackme.取字符文本> ; 取输入的注册码,存于ebp-8 00430CC0 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; 用户名送EAX 00430CC3 |. E8 702CFDFF CALL <ocrackme.取字符串长度> ; 用户名长度 00430CC8 |. 83F8 06 CMP EAX,6 ; 是否大于等于6位 00430CCB |. 7D 0F JGE SHORT ocrackme.00430CDC 00430CCD |. B8 F40E4300 MOV EAX,ocrackme.00430EF4 ; Name must be at least 6 Characters long 00430CD2 |. E8 65DEFFFF CALL ocrackme.0042EB3C 00430CD7 |. E9 E8010000 JMP ocrackme.00430EC4 00430CDC |> 837D F8 00 CMP DWORD PTR SS:[EBP-8],0 ; 注册码是否是空。 00430CE0 |. 75 34 JNZ SHORT ocrackme.00430D16 00430CE2 |. B8 240F4300 MOV EAX,ocrackme.00430F24 ; Enter a Serial # 00430CE7 |. E8 50DEFFFF CALL ocrackme.0042EB3C 00430CEC |. E9 D3010000 JMP ocrackme.00430EC4 00430CF1 |> 8B45 FC /MOV EAX,DWORD PTR SS:[EBP-4] ; 取得输入的注册码 00430CF4 |. E8 3F2CFDFF |CALL <ocrackme.取字符串长度> ; 计算注册码长度,在返回值EAX中 00430CF9 |. 2BC3 |SUB EAX,EBX 00430CFB |. 8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] ; 注册码送EDX 00430CFE |. 8A5402 FF |MOV DL,BYTE PTR DS:[EDX+EAX-1] ; 从最后一位开始取注册码的每个字符 00430D02 |. 8D45 E4 |LEA EAX,DWORD PTR SS:[EBP-1C] 00430D05 |. E8 562BFDFF |CALL ocrackme.00403860 00430D0A |. 8B55 E4 |MOV EDX,DWORD PTR SS:[EBP-1C] ; 这个循环倒叙取出注册码并保存到一个位置。可由堆栈ebp-c中看出 00430D0D |. 8D45 F4 |LEA EAX,DWORD PTR SS:[EBP-C] 00430D10 |. E8 2B2CFDFF |CALL ocrackme.00403940 00430D15 |. 43 |INC EBX 00430D16 |> 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; 输入的注册码送EAX 00430D19 |. E8 1A2CFDFF |CALL <ocrackme.取字符串长度> ; 取输入的注册码长度 00430D1E |. 3BD8 |CMP EBX,EAX ; 是否已到注册码最后 00430D20 |.^ 7C CF \JL SHORT ocrackme.00430CF1 ; 未到最后则继续循环 00430D22 |. BB 01000000 MOV EBX,1 00430D27 |. EB 36 JMP SHORT ocrackme.00430D5F 00430D29 |> FF75 EC /PUSH DWORD PTR SS:[EBP-14] ; 这个循环是顺序取每个字符,并得到每个字符的十进制数 00430D2C |. 8D45 E4 |LEA EAX,DWORD PTR SS:[EBP-1C] ; 在ebp-14中存放,取得位数是字符长度减一 00430D2F |. 8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] 00430D32 |. 8A541A FF |MOV DL,BYTE PTR DS:[EDX+EBX-1] 00430D36 |. E8 252BFDFF |CALL ocrackme.00403860 00430D3B |. FF75 E4 |PUSH DWORD PTR SS:[EBP-1C] 00430D3E |. 8D55 E0 |LEA EDX,DWORD PTR SS:[EBP-20] 00430D41 |. 8B45 F4 |MOV EAX,DWORD PTR SS:[EBP-C] 00430D44 |. 0FB64418 FF |MOVZX EAX,BYTE PTR DS:[EAX+EBX-1] 00430D49 |. E8 2A5AFDFF |CALL ocrackme.00406778 00430D4E |. FF75 E0 |PUSH DWORD PTR SS:[EBP-20] 00430D51 |. 8D45 EC |LEA EAX,DWORD PTR SS:[EBP-14] 00430D54 |. BA 03000000 |MOV EDX,3 00430D59 |. E8 9A2CFDFF |CALL ocrackme.004039F8 00430D5E |. 43 |INC EBX 00430D5F |> 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00430D62 |. E8 D12BFDFF |CALL <ocrackme.取字符串长度> 00430D67 |. 3BD8 |CMP EBX,EAX 00430D69 |.^ 7C BE \JL SHORT ocrackme.00430D29 00430D6B |. BB 01000000 MOV EBX,1 00430D70 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C] 00430D73 |. E8 4429FDFF CALL ocrackme.004036BC 00430D78 |. EB 4D JMP SHORT ocrackme.00430DC7 00430D7A |> 8D45 DC /LEA EAX,DWORD PTR SS:[EBP-24] 00430D7D |. 8B55 EC |MOV EDX,DWORD PTR SS:[EBP-14] ; 这个循环是将上面ebp-14中的字符去掉首尾和最后一位后, 00430D80 |. 8A141A |MOV DL,BYTE PTR DS:[EDX+EBX] ; 每个字符在重复一遍,比如字符:a102b101,结果就是:110022bb1100 00430D83 |. 8850 01 |MOV BYTE PTR DS:[EAX+1],DL 00430D86 |. C600 01 |MOV BYTE PTR DS:[EAX],1 00430D89 |. 8D55 DC |LEA EDX,DWORD PTR SS:[EBP-24] 00430D8C |. 8D45 D8 |LEA EAX,DWORD PTR SS:[EBP-28] 00430D8F |. E8 581AFDFF |CALL ocrackme.004027EC 00430D94 |. 8D45 D4 |LEA EAX,DWORD PTR SS:[EBP-2C] 00430D97 |. 8B55 EC |MOV EDX,DWORD PTR SS:[EBP-14] 00430D9A |. 8A141A |MOV DL,BYTE PTR DS:[EDX+EBX] 00430D9D |. 8850 01 |MOV BYTE PTR DS:[EAX+1],DL 00430DA0 |. C600 01 |MOV BYTE PTR DS:[EAX],1 00430DA3 |. 8D55 D4 |LEA EDX,DWORD PTR SS:[EBP-2C] 00430DA6 |. 8D45 D8 |LEA EAX,DWORD PTR SS:[EBP-28] 00430DA9 |. B1 02 |MOV CL,2 00430DAB |. E8 0C1AFDFF |CALL ocrackme.004027BC 00430DB0 |. 8D55 D8 |LEA EDX,DWORD PTR SS:[EBP-28] 00430DB3 |. 8D45 F0 |LEA EAX,DWORD PTR SS:[EBP-10] 00430DB6 |. E8 212BFDFF |CALL ocrackme.004038DC 00430DBB |. 8D45 F4 |LEA EAX,DWORD PTR SS:[EBP-C] 00430DBE |. 8B55 F0 |MOV EDX,DWORD PTR SS:[EBP-10] 00430DC1 |. E8 7A2BFDFF |CALL ocrackme.00403940 00430DC6 |. 43 |INC EBX 00430DC7 |> 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14] 00430DCA |. E8 692BFDFF |CALL <ocrackme.取字符串长度> 00430DCF |. 48 |DEC EAX 00430DD0 |. 3BD8 |CMP EBX,EAX 00430DD2 |.^ 7C A6 \JL SHORT ocrackme.00430D7A 00430DD4 |. BB 01000000 MOV EBX,1 00430DD9 |. 8D45 EC LEA EAX,DWORD PTR SS:[EBP-14] 00430DDC |. E8 DB28FDFF CALL ocrackme.004036BC 00430DE1 |. EB 1C JMP SHORT ocrackme.00430DFF 00430DE3 |> 8D55 E4 /LEA EDX,DWORD PTR SS:[EBP-1C] ; 这个循环是将上见的重复后的字符每位的ASCII码值转换为10进制保存,但最后一位不转换 00430DE6 |. 8B45 F4 |MOV EAX,DWORD PTR SS:[EBP-C] 00430DE9 |. 0FB64418 FF |MOVZX EAX,BYTE PTR DS:[EAX+EBX-1] 00430DEE |. E8 8559FDFF |CALL ocrackme.00406778 00430DF3 |. 8B55 E4 |MOV EDX,DWORD PTR SS:[EBP-1C] 00430DF6 |. 8D45 EC |LEA EAX,DWORD PTR SS:[EBP-14] 00430DF9 |. E8 422BFDFF |CALL ocrackme.00403940 00430DFE |. 43 |INC EBX 00430DFF |> 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] 00430E02 |. E8 312BFDFF |CALL <ocrackme.取字符串长度> 00430E07 |. 3BD8 |CMP EBX,EAX 00430E09 |.^ 7C D8 \JL SHORT ocrackme.00430DE3 00430E0B |. BB 03000000 MOV EBX,3 00430E10 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C] 00430E13 |. E8 A428FDFF CALL ocrackme.004036BC 00430E18 |. 83FB 30 CMP EBX,30 00430E1B |. 7D 22 JGE SHORT ocrackme.00430E3F 00430E1D |> 8D45 E4 /LEA EAX,DWORD PTR SS:[EBP-1C] 00430E20 |. 8B55 EC |MOV EDX,DWORD PTR SS:[EBP-14] 00430E23 |. 8A541A FF |MOV DL,BYTE PTR DS:[EDX+EBX-1] 00430E27 |. E8 342AFDFF |CALL ocrackme.00403860 00430E2C |. 8B55 E4 |MOV EDX,DWORD PTR SS:[EBP-1C] 00430E2F |. 8D45 F4 |LEA EAX,DWORD PTR SS:[EBP-C] 00430E32 |. E8 092BFDFF |CALL ocrackme.00403940 00430E37 |. 83C3 03 |ADD EBX,3 00430E3A |. 83FB 30 |CMP EBX,30 00430E3D |.^ 7C DE \JL SHORT ocrackme.00430E1D 00430E3F |> BB 01000000 MOV EBX,1 00430E44 |. EB 5B JMP SHORT ocrackme.00430EA1 00430E46 |> 8B45 FC /MOV EAX,DWORD PTR SS:[EBP-4] 00430E49 |. E8 EA2AFDFF |CALL <ocrackme.取字符串长度> 00430E4E |. 03C3 |ADD EAX,EBX 00430E50 |. 8B55 EC |MOV EDX,DWORD PTR SS:[EBP-14] 00430E53 |. 8A5402 FD |MOV DL,BYTE PTR DS:[EDX+EAX-3] 00430E57 |. 8D45 E4 |LEA EAX,DWORD PTR SS:[EBP-1C] 00430E5A |. E8 012AFDFF |CALL ocrackme.00403860 ; 将DL从复制到一个地方 00430E5F |. 8B45 E4 |MOV EAX,DWORD PTR SS:[EBP-1C] 00430E62 |. E8 4159FDFF |CALL ocrackme.004067A8 ; 取得DL的十进制值,在eax 00430E67 |. 50 |PUSH EAX 00430E68 |. 8D45 E4 |LEA EAX,DWORD PTR SS:[EBP-1C] 00430E6B |. 8B55 F4 |MOV EDX,DWORD PTR SS:[EBP-C] ; 第五个字符串送EDX 00430E6E |. 8A541A FF |MOV DL,BYTE PTR DS:[EDX+EBX-1] ; 依次取出每一位 00430E72 |. E8 E929FDFF |CALL ocrackme.00403860 00430E77 |. 8B45 E4 |MOV EAX,DWORD PTR SS:[EBP-1C] ; DL的值复制到其他地方 00430E7A |. E8 2959FDFF |CALL ocrackme.004067A8 ; 也转换成10进制 00430E7F |. 5A |POP EDX 00430E80 |. 2BC2 |SUB EAX,EDX 00430E82 |. 99 |CDQ 00430E83 |. 33C2 |XOR EAX,EDX 00430E85 |. 2BC2 |SUB EAX,EDX 00430E87 |. 8D55 E8 |LEA EDX,DWORD PTR SS:[EBP-18] 00430E8A |. E8 E958FDFF |CALL ocrackme.00406778 00430E8F |. 8D45 F4 |LEA EAX,DWORD PTR SS:[EBP-C] 00430E92 |. E8 712CFDFF |CALL ocrackme.00403B08 00430E97 |. 8B55 E8 |MOV EDX,DWORD PTR SS:[EBP-18] 00430E9A |. 8A12 |MOV DL,BYTE PTR DS:[EDX] 00430E9C |. 885418 FF |MOV BYTE PTR DS:[EAX+EBX-1],DL 00430EA0 |. 43 |INC EBX 00430EA1 |> 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] 00430EA4 |. E8 8F2AFDFF |CALL <ocrackme.取字符串长度> 00430EA9 |. 3BD8 |CMP EBX,EAX 00430EAB |.^ 7E 99 \JLE SHORT ocrackme.00430E46 00430EAD |. 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] 00430EB0 |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8] 00430EB3 |. E8 902BFDFF CALL ocrackme.00403A48 ; 真假注册码比较 00430EB8 |. 75 0A JNZ SHORT ocrackme.00430EC4 ; 修改此处可以爆破 00430EBA |. B8 400F4300 MOV EAX,ocrackme.00430F40 ; You Got It!!! :) 00430EBF |. E8 78DCFFFF CALL ocrackme.0042EB3C |
|
[原创]借书-有点小悲剧~
像是在写日记 |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->Prolixe-KeygenMe#1 分析和注册机 这个CM分析了下算法,虽然计算注册码的call很好确定,但是要跟进去里面的call还有不少,后来就反复的试了好多次,主要用猜测的方法,同时要注意查看内存和堆栈的变化,比如在进入一个call前肯定要传参数,有时也要传入返回值保存的地方,所以主要查看call前面的几个语句的地址,F8不过call后在查看堆栈后的变化来猜测该call的功能,后来分析出计算注册码的过程(这步并没有在call里面,可以直接看到),计算出后有小写字母的话就转换大些等这些操作就是通过执行call后的变化猜出来的。 注册码分3部分,首尾部分是固定的字符,中间的字符数和输入的用户名位数相同,具体看代码。 00407FAD |. 50 PUSH EAX ; |Buffer 00407FAE |. 68 E8030000 PUSH 3E8 ; |ControlID = 3E8 (1000.) 00407FB3 |. 53 PUSH EBX ; |hWnd 00407FB4 |. E8 97C6FFFF CALL <JMP.&user32.GetDlgItemTextA> ; \取输入的用户名,存放在【EBP-104】 00407FB9 |. 6A 1E PUSH 1E ; /Count = 1E (30.) 00407FBB |. 8D85 FCFDFFFF LEA EAX,DWORD PTR SS:[EBP-204] ; | 00407FC1 |. 50 PUSH EAX ; |Buffer 00407FC2 |. 68 E9030000 PUSH 3E9 ; |ControlID = 3E9 (1001.) 00407FC7 |. 53 PUSH EBX ; |hWnd 00407FC8 |. E8 83C6FFFF CALL <JMP.&user32.GetDlgItemTextA> ; \取输入的注册码,存放于【EBP-204】 00407FCD |. 80BD FCFDFFFF>CMP BYTE PTR SS:[EBP-204],0 ; 注册码是否是空?空则提示错误 00407FD4 |. 75 17 JNZ SHORT Keygen去.00407FED 00407FD6 |. 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 00407FD8 |. 68 0C814000 PUSH Keygen去.0040810C ; |Error 00407FDD |. 68 14814000 PUSH Keygen去.00408114 ; |Enter a Serial 00407FE2 |. 53 PUSH EBX ; |hOwner 00407FE3 |. E8 88C6FFFF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA 00407FE8 |. E9 B9000000 JMP Keygen去.004080A6 00407FED |> 80BD FCFEFFFF>CMP BYTE PTR SS:[EBP-104],0 ; 用户名是否为空?空则提示错误 00407FF4 |. 75 17 JNZ SHORT Keygen去.0040800D 00407FF6 |. 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 00407FF8 |. 68 0C814000 PUSH Keygen去.0040810C ; |Error 00407FFD |. 68 24814000 PUSH Keygen去.00408124 ; |Enter a Name 00408002 |. 53 PUSH EBX ; |hOwner 00408003 |. E8 68C6FFFF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA 00408008 |. E9 99000000 JMP Keygen去.004080A6 0040800D |> 8D85 F8FDFFFF LEA EAX,DWORD PTR SS:[EBP-208] 00408013 |. 8D95 FCFEFFFF LEA EDX,DWORD PTR SS:[EBP-104] ; 用户名送EAX 00408019 |. B9 00010000 MOV ECX,100 0040801E |. E8 19B8FFFF CALL Keygen去.0040383C 00408023 |. 8B85 F8FDFFFF MOV EAX,DWORD PTR SS:[EBP-208] 00408029 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 0040802C |. E8 E3FDFFFF CALL Keygen去.00407E14 ; 关键call,计算出注册码 00408031 |. 8D85 F4FDFFFF LEA EAX,DWORD PTR SS:[EBP-20C] 00408037 |. 8D95 FCFDFFFF LEA EDX,DWORD PTR SS:[EBP-204] 0040803D |. B9 00010000 MOV ECX,100 00408042 |. E8 F5B7FFFF CALL Keygen去.0040383C 00408047 |. 8B95 F4FDFFFF MOV EDX,DWORD PTR SS:[EBP-20C] 0040804D |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00408050 |. E8 EBB8FFFF CALL Keygen去.00403940 ; 比较注册码 00408055 75 2F JNZ SHORT Keygen去.00408086 ; 修改此处可以爆破。 贴出一组正确的注册码:用户名:123 注册码:HZF-RQX-GFD #include <stdlib.h> #include <stdio.h> #include <string> int main(void) { char name[]={"123"}; //感觉这个CM的算法有些问题,当输入一些字符,比如有些小写字母 //计算出来的就不一定对,主要原因应该是计算的超出了ASCII的范围。 //比如我用pediy做用户名,计算出来的就不能用。 //注册码必须以“HZF-”开始,以"-GDF"结束,中间的字符是下面计算的结果。 int namelen=strlen(name); int ebx,ecx,edx,edi,i; printf("注册名:%s\n",name); ebx=1; for (i=0;i<namelen;i++) { edi=name[i]; edx=edi; ecx=ebx+5; edx=edx^ecx; edx=edx+edi; edx=edx+0x0A; ebx=ebx+1; if (edx>=0x61 && edx<=0x7A) { edx=edx-0x20; //小写转换成大写,其他字符不变。 } name[i]=edx; //用name数组保存计算的结果。 } printf("注册码:HZF-%s-GFD\n",name); getchar(); return 0; } |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->moon’s KGme #1 分析和注册机 这个脱壳很顺利,之后查找字符串,到以下位置。这个cm很简单,分析如下。 00447EB0 |. 55 PUSH EBP 00447EB1 |. 68 A17F4400 PUSH 123.00447FA1 00447EB6 |. 64:FF30 PUSH DWORD PTR FS:[EAX] 00447EB9 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 00447EBC |> 8D55 F0 /LEA EDX,DWORD PTR SS:[EBP-10] 00447EBF |. 8B86 D0020000 |MOV EAX,DWORD PTR DS:[ESI+2D0] 00447EC5 |. E8 36C2FDFF |CALL 123.00424100 ; 取输入的用户名放于【EBP-10】 00447ECA |. 8B55 F0 |MOV EDX,DWORD PTR SS:[EBP-10] 00447ECD |. 8D45 FC |LEA EAX,DWORD PTR SS:[EBP-4] 00447ED0 |. E8 EFBCFBFF |CALL 123.00403BC4 00447ED5 |. 8B45 FC |MOV EAX,DWORD PTR SS:[EBP-4] 00447ED8 |. E8 DFBCFBFF |CALL 123.00403BBC ; 取输入的用户名长度 00447EDD |. 83F8 06 |CMP EAX,6 ; 判断是否大于等于6位,小于6的话重复上面循环 00447EE0 |.^ 7C DA \JL SHORT 123.00447EBC ; 将输入注册名复制后追加到原注册名后 00447EE2 |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8] 00447EE5 |. BA B87F4400 MOV EDX,123.00447FB8 ; xxxxxx 00447EEA |. E8 E5BAFBFF CALL 123.004039D4 00447EEF |. BB 01000000 MOV EBX,1 00447EF4 |> 8D45 F8 /LEA EAX,DWORD PTR SS:[EBP-8] 00447EF7 |. E8 90BEFBFF |CALL 123.00403D8C 00447EFC |. 8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] 00447EFF |. 8A541A FF |MOV DL,BYTE PTR DS:[EDX+EBX-1] ; 依次取出注册名每一位,循环6次,所以只取前6位 00447F03 |. 80C2 05 |ADD DL,5 ; 注册名每位字符加5 00447F06 |. 885418 FF |MOV BYTE PTR DS:[EAX+EBX-1],DL ; 保存到这个地址。用于后面比较 00447F0A |. 43 |INC EBX 00447F0B |. 83FB 07 |CMP EBX,7 00447F0E |.^ 75 E4 \JNZ SHORT 123.00447EF4 00447F10 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C] 00447F13 |. BA C87F4400 MOV EDX,123.00447FC8 ; Hey, u r realy good!\n\rSend ur solution to moon.86@gmx.de! 00447F18 |. E8 B7BAFBFF CALL 123.004039D4 00447F1D |. 8D55 EC LEA EDX,DWORD PTR SS:[EBP-14] 00447F20 |. 8B86 EC020000 MOV EAX,DWORD PTR DS:[ESI+2EC] 00447F26 |. E8 F9C4FFFF CALL 123.00444424 00447F2B |. 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14] ; 取输入的注册码 00447F2E |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] ; 取计算出的真码 00447F31 |. E8 96BDFBFF CALL 123.00403CCC ; 比较注册码函数 00447F36 |. 75 26 JNZ SHORT 123.00447F5E ; 此处是爆破位置。 00447F38 |. 6A 00 PUSH 0 00447F3A |. 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] 00447F3D |. E8 3EBEFBFF CALL 123.00403D80 00447F42 |. 8BD0 MOV EDX,EAX 00447F44 |. B9 04804400 MOV ECX,123.00448004 ; Yeah, u got it! 算法看代码中的注释。 [B]一组正确的注册码:pediy ujin~u[/B] #include <stdlib.h> #include <stdio.h> #include <string> int main(void) { //注册名注意最好是数字和字母,且字母不能是小写z,否则 //计算出的注册码可能不容易输入,因为注册码是根据注册名每位 //的ascii码加5得到的,而小写z和其后面的ascii码+5后会大于128. //注册名会单独保存一个位置且是6位,如果注册名大于6位则计算时只取 //前6位计算,如果不够6位,则赋值输入的注册名并和输入的注册名合并,直到》=6位后就进入计算过程。 char Name[]={"pediy"}; const int n=6; int i; char RegName[n]; int NameLen=strlen(Name); if (NameLen>=n) { for (i=0;i<6;i++) RegName[i]=Name[i]; } else { int j=0; for (i=0;i<6;i++) { if (j>NameLen-1) { j=0; } RegName[i]=Name[j]; j++; } } printf("注册名:%s\n",Name); printf("注册码:"); for (i=0;i<6;i++) { RegName[i]=RegName[i]+0x5; printf("%c",RegName[i]); } getchar(); return 0; } |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->lnn1123 CrackMe0.11 算法分析 这个分析不是很难,可是后来在写注册机时怎么也没有写出来,后来又看了几遍论坛上的原帖,里面也没有这方面的分析,也没有给出一个注册码来,没办法,这次只能修改程序爆破了,,爆破的语句在下面分析中写出了。 00401112 . 6A 28 PUSH 28 ; /Count = 28 (40.) 00401114 . 8D45 BC LEA EAX,DWORD PTR SS:[EBP-44] ; | 00401117 . 50 PUSH EAX ; |Buffer 00401118 . FF35 04304000 PUSH DWORD PTR DS:[403004] ; |hWnd = NULL 0040111E . E8 5B010000 CALL <JMP.&user32.GetWindowTextA> ; \GetWindowTextA 00401123 . 8D75 BC LEA ESI,DWORD PTR SS:[EBP-44] ; 【EBP-44】保存输入用户名 00401126 . AC LODS BYTE PTR DS:[ESI] 00401127 . 3C 00 CMP AL,0 ; 判断用户名是否是空, 00401129 . 75 11 JNZ SHORT Crack.0040113C 0040112B . FF35 04304000 PUSH DWORD PTR DS:[403004] ; /hWnd = NULL 00401131 . E8 60010000 CALL <JMP.&user32.SetFocus> ; \SetFocus 00401136 . 33C0 XOR EAX,EAX 00401138 . C9 LEAVE 00401139 . C2 1000 RETN 10 0040113C > 8D45 BC LEA EAX,DWORD PTR SS:[EBP-44] ; 用户名不是空到这里,将用户名送EAX 0040113F . 50 PUSH EAX 00401140 . E8 6F010000 CALL Crack.004012B4 ; 关键call,根据用户名计算出一个值。返回在ECX中 00401145 . 8D45 BC LEA EAX,DWORD PTR SS:[EBP-44] 00401148 . 50 PUSH EAX ; /String 00401149 . E8 60010000 CALL <JMP.&kernel32.lstrlenA> ; \取输入用户名的长度 0040114E . 8BF8 MOV EDI,EAX ; 用户名长度送EDI,用作循环次数 00401150 . 8BC8 MOV ECX,EAX ; ECX也是用户名长度 00401152 . BB 01000000 MOV EBX,1 ; EBX赋初值1 00401157 . 33D2 XOR EDX,EDX ; EDX置零 00401159 . EB 1C JMP SHORT Crack.00401177 0040115B > 4F DEC EDI ; 循环计数值减一。初值是用户名的长度 0040115C . 36:0FB6542F B>MOVZX EDX,BYTE PTR SS:[EDI+EBP-44] ; 从用户名的末位开始读字符 00401162 . 33D3 XOR EDX,EBX ; 于EBX异或 00401164 . 0FAFD3 IMUL EDX,EBX ; 再与EBX相乘 00401167 . 83C3 05 ADD EBX,5 0040116A . 3115 24304000 XOR DWORD PTR DS:[403024],EDX 00401170 . C105 24304000>ROL DWORD PTR DS:[403024],5 ; 和【403024】异或后再乘以0x20 00401177 > 0BFF OR EDI,EDI ; 判断是否循环结束 00401179 .^ 75 E0 JNZ SHORT Crack.0040115B 0040117B . A1 24304000 MOV EAX,DWORD PTR DS:[403024] 00401180 . 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ; 将【403024】的值放入【EBP-4】中保存 00401183 . 33C0 XOR EAX,EAX 00401185 . 6A 28 PUSH 28 ; /Count = 28 (40.) 00401187 . 8D85 3CFFFFFF LEA EAX,DWORD PTR SS:[EBP-C4] ; | 0040118D . 50 PUSH EAX ; |Buffer 0040118E . FF35 08304000 PUSH DWORD PTR DS:[403008] ; |hWnd = NULL 00401194 . E8 E5000000 CALL <JMP.&user32.GetWindowTextA> ; \取输入的注册码 00401199 . 33C9 XOR ECX,ECX 0040119B . 33DB XOR EBX,EBX ; ECX EBX置零 0040119D > 36:0FB69429 3>MOVZX EDX,BYTE PTR SS:[ECX+EBP-C4] ; 循环取出注册码的每一位 004011A6 . 03DA ADD EBX,EDX 004011A8 . 6BDB 10 IMUL EBX,EBX,10 ; 先累加后再乘以0x10 004011AB . 41 INC ECX 004011AC . 3BC8 CMP ECX,EAX ; 判断是否循环结束 004011AE .^ 75 ED JNZ SHORT Crack.0040119D 004011B0 . 3B5D FC CMP EBX,DWORD PTR SS:[EBP-4] ; 上面上次计算的结果比较是否相等,相等则成功。 004011B3 . 74 15 JE SHORT Crack.004011CA ;此处修改成JMP 后既可以爆破。 004011B5 . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 004011B7 . 68 30304000 PUSH Crack.00403030 ; |Crackme V 0.11 004011BC . 68 54304000 PUSH Crack.00403054 ; |NO,try again 004011C1 . 6A 00 PUSH 0 ; |hOwner = NULL 004011C3 . E8 C2000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA 004011C8 . EB 32 JMP SHORT Crack.004011FC 004011CA > 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 004011CC . 68 30304000 PUSH Crack.00403030 ; |Crackme V 0.11 004011D1 . 68 3F304000 PUSH Crack.0040303F ; |Register successful! 004011D6 . 6A 00 PUSH 0 ; |hOwner = NULL 004011D8 . E8 AD000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA |
|
[求助]这个怎样追注册码?
光看个图根本就看不出来,建议传附件 |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->CZG CrackMe 分析 这个比较简单,但是当逆推计算公式时感觉很麻烦,后来就想直接照搬计算注册码的语句,之前看到论坛上有说明如何把汇编直接考到程序中,但当时也没仔细看,于是有了下面的代码,定义变量时用汇编中的各个寄存器和堆栈的名字,贴一个正确的注册码:pediy 3272156575 004015C5 |. /EB 09 JMP SHORT ECrackMe.004015D0 004015C7 |> |8B55 E0 /MOV EDX,DWORD PTR SS:[EBP-20] ; 这个循环是计算注册码的关键代码 004015CA |. |83C2 01 |ADD EDX,1 004015CD |. |8955 E0 |MOV DWORD PTR SS:[EBP-20],EDX 004015D0 |> \8B45 E0 MOV EAX,DWORD PTR SS:[EBP-20] 004015D3 |. 3B45 E4 |CMP EAX,DWORD PTR SS:[EBP-1C] 004015D6 |. 7D 42 |JGE SHORT ECrackMe.0040161A 004015D8 |. 8B4D E0 |MOV ECX,DWORD PTR SS:[EBP-20] 004015DB |. 51 |PUSH ECX ; /Arg1 004015DC |. 8D4D EC |LEA ECX,DWORD PTR SS:[EBP-14] ; | 004015DF |. E8 1C030000 |CALL ECrackMe.00401900 ; \这个call是依次循环取出输入注册名的每一位送到AL 004015E4 |. 0FBED0 |MOVSX EDX,AL 004015E7 |. 8B45 F0 |MOV EAX,DWORD PTR SS:[EBP-10] 004015EA |. 03C2 |ADD EAX,EDX 004015EC |. 8945 F0 |MOV DWORD PTR SS:[EBP-10],EAX 004015EF |. 8B4D E0 |MOV ECX,DWORD PTR SS:[EBP-20] 004015F2 |. C1E1 08 |SHL ECX,8 004015F5 |. 8B55 F0 |MOV EDX,DWORD PTR SS:[EBP-10] 004015F8 |. 33D1 |XOR EDX,ECX 004015FA |. 8955 F0 |MOV DWORD PTR SS:[EBP-10],EDX 004015FD |. 8B45 E0 |MOV EAX,DWORD PTR SS:[EBP-20] 00401600 |. 83C0 01 |ADD EAX,1 00401603 |. 8B4D E4 |MOV ECX,DWORD PTR SS:[EBP-1C] 00401606 |. 0FAF4D E0 |IMUL ECX,DWORD PTR SS:[EBP-20] 0040160A |. F7D1 |NOT ECX 0040160C |. 0FAFC1 |IMUL EAX,ECX 0040160F |. 8B55 F0 |MOV EDX,DWORD PTR SS:[EBP-10] 00401612 |. 0FAFD0 |IMUL EDX,EAX 00401615 |. 8955 F0 |MOV DWORD PTR SS:[EBP-10],EDX ; 此时EDX中的值的10进制数就是正确的注册码。 00401618 |.^ EB AD \JMP SHORT ECrackMe.004015C7 ; 后面的注册码比较函数就不在仔细跟了。 0040161A |> 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] 0040161D |. 50 PUSH EAX ; 下面这句是格式输出 %lu格式 0040161E |. 68 54404000 PUSH ECrackMe.00404054 ; %lu 00401623 |. 8D4D DC LEA ECX,DWORD PTR SS:[EBP-24] 00401626 |. 51 PUSH ECX 00401627 |. E8 52070000 CALL <JMP.&MFC42.#2818> 这个比较简单,但是当逆推计算公式时感觉很麻烦,后来就想直接照搬计算注册码的语句,之前看到论坛上有说明如何把汇编直接考到程序中,但当时也没仔细看,于是有了下面的代码,定义变量时用汇编中的各个寄存器和堆栈的名字,这样可以把那个循环中的每一句都替换,最后输出edx的值,刚开始输出时用的是“%d”,结果发现是负数,后来跟踪了好久发现计算的都是对的,后来查看edx寄存器发现如果是有符号数的话就是输出的值,如果是无符号时就是正确的注册码了。后来改成printf("注册码:%lu\n",ebp10);后就正确了, 之前是printf("注册码:%lu\n",ebp10),真是疏忽呀。 贴一个正确的注册码:pediy 3272156575 #include <stdlib.h> #include <stdio.h> #include <string> int main(void) { char name[]={"pediy"}; unsigned int ebp1c,ebp20,ebp10; unsigned int eax,ecx,edx,i; ebp20=0; ebp10=0x081276345; ebp1c=strlen(name); for (i=0;i<ebp1c;i++) { eax=name[i];//以下并不是汇编语句,只是定义的变量是汇编中的一些名字, edx=eax; //具体的每一句是和上面的那个计算注册码循环中的代码一一对应。 eax=ebp10; eax=eax+edx; ebp10=eax; ecx=ebp20; ecx=ecx*0x100; edx=ebp10; edx=edx^ecx; ebp10=edx; eax=ebp20; eax++; ecx=ebp1c; ecx=ecx*ebp20; ecx=~ecx; eax=eax*ecx; edx=ebp10; edx=edx*eax; ebp10=edx; ebp20++; } printf("注册名:%s\n",name); printf("注册码:%lu\n",ebp10); getchar(); return 0; } |
|
[原创]牧民战天VIP会员免杀捆绑器(求邀请码)
已经找到了为什么不自己分析下注册码是如何算出来的。 |
|
[求助]下个破解软件为什么都上不了网了?
估计没什么好的回复,你又不说在哪下载的,怎么使用的,等等。。。 |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->Salazan’s KeyGenMe#001 分析 查找字符串,很容易找到断点,输入注册名:pediy,注册码:12345678901234567890123456789 0045618C |. 64:FF30 PUSH DWORD PTR FS:[EAX] 0045618F |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 00456192 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4] 00456195 |. 8B83 F8020000 MOV EAX,DWORD PTR DS:[EBX+2F8] 0045619B |. E8 90CDFDFF CALL SalazanK.00432F30 ; 取输入的注册名,结果在【EBP-4】 004561A0 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 004561A3 |. E8 58E3FAFF CALL SalazanK.00404500 004561A8 |. 83F8 03 CMP EAX,3 ; 判断注册名长度是否小于3,小则跳走 004561AB |. 7C 1B JL SHORT SalazanK.004561C8 004561AD |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8] 004561B0 |. 8B83 FC020000 MOV EAX,DWORD PTR DS:[EBX+2FC] 004561B6 |. E8 75CDFDFF CALL SalazanK.00432F30 ; 取输入的注册码,放于【EBP-8】中 004561BB |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 004561BE |. E8 3DE3FAFF CALL SalazanK.00404500 004561C3 |. 83F8 03 CMP EAX,3 ; 判断是否大于等于3,如果小于3则提示错误 004561C6 |. 7D 0C JGE SHORT SalazanK.004561D4 004561C8 |> B8 58624500 MOV EAX,SalazanK.00456258 ; Min. 3 char in name/serial! 004561CD |. E8 3E6BFDFF CALL SalazanK.0042CD10 004561D2 |. EB 53 JMP SHORT SalazanK.00456227 004561D4 |> 8D55 F4 LEA EDX,DWORD PTR SS:[EBP-C] 004561D7 |. 8B83 FC020000 MOV EAX,DWORD PTR DS:[EBX+2FC] 004561DD |. E8 4ECDFDFF CALL SalazanK.00432F30 ; 取输入的注册码 004561E2 |. 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] 004561E5 |. E8 2EFBFFFF CALL SalazanK.00455D18 ; 关键call要跟进 004561EA |. 84C0 TEST AL,AL 004561EC 74 1F JE SHORT SalazanK.0045620D ; 此处改成JNE既可以爆破 004561EE |. 8B83 00030000 MOV EAX,DWORD PTR DS:[EBX+300] 004561F4 |. 8B80 08020000 MOV EAX,DWORD PTR DS:[EAX+208] 004561FA |. 33D2 XOR EDX,EDX 004561FC |. E8 73EDFFFF CALL SalazanK.00454F74 00456201 |. BA 7C624500 MOV EDX,SalazanK.0045627C ; Congr! You are real cracker! 关键call根进后分析: 00455DD1 |. 33D2 XOR EDX,EDX 00455DD3 |> 8B4D F4 /MOV ECX,DWORD PTR SS:[EBP-C] 00455DD6 |. 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] 00455DDB |. 03D9 |ADD EBX,ECX 00455DDD |. 42 |INC EDX 00455DDE |. 48 |DEC EAX 00455DDF |.^ 75 F2 \JNZ SHORT SalazanK.00455DD3 ; 注册码的1-5位的ascii码累加 00455DE1 |> 81FB 8D010000 CMP EBX,18D ; 累加和是否是0x18D 00455DE7 |. 75 04 JNZ SHORT SalazanK.00455DED 00455DE9 |. C645 E3 01 MOV BYTE PTR SS:[EBP-1D],1 ; 【EBP-1D】置1 00455DED |> 33DB XOR EBX,EBX 00455DEF |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] 00455DF2 |. E8 09E7FAFF CALL SalazanK.00404500 00455DF7 |. 85C0 TEST EAX,EAX 00455DF9 |. 7C 11 JL SHORT SalazanK.00455E0C 00455DFB |. 40 INC EAX 00455DFC |. 33D2 XOR EDX,EDX 00455DFE |> 8B4D F0 /MOV ECX,DWORD PTR SS:[EBP-10] 00455E01 |. 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] 00455E06 |. 03D9 |ADD EBX,ECX 00455E08 |. 42 |INC EDX 00455E09 |. 48 |DEC EAX 00455E0A |.^ 75 F2 \JNZ SHORT SalazanK.00455DFE 00455E0C |> 81FB 8C010000 CMP EBX,18C ; 7--11位的ascii码相加后是否等于0x18C 00455E12 |. 75 04 JNZ SHORT SalazanK.00455E18 00455E14 |. C645 E2 01 MOV BYTE PTR SS:[EBP-1E],1 ; 【EBP-1E】置1 00455E18 |> 33DB XOR EBX,EBX 00455E1A |. 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14] 00455E1D |. E8 DEE6FAFF CALL SalazanK.00404500 00455E22 |. 85C0 TEST EAX,EAX 00455E24 |. 7C 11 JL SHORT SalazanK.00455E37 00455E26 |. 40 INC EAX 00455E27 |. 33D2 XOR EDX,EDX 00455E29 |> 8B4D EC /MOV ECX,DWORD PTR SS:[EBP-14] 00455E2C |. 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] 00455E31 |. 03D9 |ADD EBX,ECX 00455E33 |. 42 |INC EDX 00455E34 |. 48 |DEC EAX 00455E35 |.^ 75 F2 \JNZ SHORT SalazanK.00455E29 00455E37 |> 81FB 90010000 CMP EBX,190 ; 13--17位ascii码累加 00455E3D |. 75 04 JNZ SHORT SalazanK.00455E43 00455E3F |. C645 E1 01 MOV BYTE PTR SS:[EBP-1F],1 ; 【EBP-1F】置1 00455E43 |> 33DB XOR EBX,EBX 00455E45 |. 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18] 00455E48 |. E8 B3E6FAFF CALL SalazanK.00404500 00455E4D |. 85C0 TEST EAX,EAX 00455E4F |. 7C 11 JL SHORT SalazanK.00455E62 00455E51 |. 40 INC EAX 00455E52 |. 33D2 XOR EDX,EDX 00455E54 |> 8B4D E8 /MOV ECX,DWORD PTR SS:[EBP-18] 00455E57 |. 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] 00455E5C |. 03D9 |ADD EBX,ECX 00455E5E |. 42 |INC EDX 00455E5F |. 48 |DEC EAX 00455E60 |.^ 75 F2 \JNZ SHORT SalazanK.00455E54 00455E62 |> 81FB 88010000 CMP EBX,188 ; 19--23位ascii码累加 00455E68 |. 75 04 JNZ SHORT SalazanK.00455E6E 00455E6A |. C645 E0 01 MOV BYTE PTR SS:[EBP-20],1 ; 【EBP-20】置1 00455E6E |> 33DB XOR EBX,EBX 00455E70 |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C] 00455E73 |. E8 88E6FAFF CALL SalazanK.00404500 00455E78 |. 85C0 TEST EAX,EAX 00455E7A |. 7C 11 JL SHORT SalazanK.00455E8D 00455E7C |. 40 INC EAX 00455E7D |. 33D2 XOR EDX,EDX 00455E7F |> 8B4D E4 /MOV ECX,DWORD PTR SS:[EBP-1C] 00455E82 |. 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] 00455E87 |. 03D9 |ADD EBX,ECX 00455E89 |. 42 |INC EDX 00455E8A |. 48 |DEC EAX 00455E8B |.^ 75 F2 \JNZ SHORT SalazanK.00455E7F 00455E8D |> 81FB 86010000 CMP EBX,186 ; 25--29位ascii码累加 00455E93 |. 75 04 JNZ SHORT SalazanK.00455E99 00455E95 |. C645 DF 01 MOV BYTE PTR SS:[EBP-21],1 ; 【EBP-21】置1 00455E99 |> 8A45 E3 MOV AL,BYTE PTR SS:[EBP-1D] 00455E9C |. 2245 E2 AND AL,BYTE PTR SS:[EBP-1E] 00455E9F |. 74 18 JE SHORT SalazanK.00455EB9 00455EA1 |. 807D E1 00 CMP BYTE PTR SS:[EBP-1F],0 00455EA5 |. 74 12 JE SHORT SalazanK.00455EB9 00455EA7 |. 807D E0 00 CMP BYTE PTR SS:[EBP-20],0 00455EAB |. 74 0C JE SHORT SalazanK.00455EB9 00455EAD |. 807D DF 00 CMP BYTE PTR SS:[EBP-21],0 00455EB1 |. 74 06 JE SHORT SalazanK.00455EB9 00455EB3 |. C645 FB 01 MOV BYTE PTR SS:[EBP-5],1 00455EB7 |. EB 04 JMP SHORT SalazanK.00455EBD 00455EB9 |> C645 FB 00 MOV BYTE PTR SS:[EBP-5],0 00455EBD |> 33C0 XOR EAX,EAX 00455EBF |. 5A POP EDX 00455EC0 |. 59 POP ECX 00455EC1 |. 59 POP ECX 00455EC2 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX 00455EC5 |. 68 E75E4500 PUSH SalazanK.00455EE7 00455ECA |> 8D45 E4 LEA EAX,DWORD PTR SS:[EBP-1C] 00455ECD |. BA 05000000 MOV EDX,5 00455ED2 |. E8 95E3FAFF CALL SalazanK.0040426C 00455ED7 |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] 00455EDA |. E8 69E3FAFF CALL SalazanK.00404248 00455EDF \. C3 RETN 算法:注册码和用户名没有关系,注册码位数必须是29位,注册码的6 、12、18、24位可以是任意字符,其他的要分成5组,每组的ascii码累加和分别是:0x18D 0x18C 0x190 0x188 0x186 。下面注册机代码中先根据每组的和算出平均值,最后一位取累加和减去前四位的和,也就是每组都是前4位相同,最后一位不同而已。 [ATTACH]45996[/ATTACH] 这是关键call跟进后发现里面有好多call调用,执行到下面的循环累加过程时,查看堆栈的结果,应该是将29位注册码分成5部分,第一部分1—5位。第二部分:7-11位,第三部分:13-17位,第四部分:19—23位,第五部分:25-29位。29位中去掉了4位,每部分有5位。 注册机代码:这个只是个参考而已。。 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> int main(void) { //注册名和计算没有关系,所以直接打印出注册码, //本来这个注册码组合就非常多,只是练习随便算出一个结果就行了。 char sn[29]; int i; //以下只是结果中的一种情况 //前4位我取一样的值,第五位取判断累加和的值减去前4位的和。 for (i=0;i<5;i++) //第一组结果 { sn[i]=0x18D/5; if (i==4) { sn[i]=0x18D-0x18D/5*4;//每组的第五位的值 } } for (i=6;i<11;i++) //第二组结果 { sn[i]=0x18C/5; if (i==10) { sn[i]=0x18C-0x18C/5*4;//每组的第五位的值 } } for (i=12;i<17;i++) //第三组结果 { sn[i]=0x190/5; if (i==16) { sn[i]=0x190-0x190/5*4;//每组的第五位的值 } } for (i=18;i<23;i++) //第四组结果 { sn[i]=0x188/5; if (i==22) { sn[i]=0x188-0x188/5*4;//每组的第五位的值 } } for (i=24;i<29;i++) //第五组结果 { sn[i]=0x186/5; if (i==28) { sn[i]=0x186-0x186/5*4;//每组的第五位的值 } } sn[5]='-'; sn[11]='-'; sn[17]='-'; sn[23]='-'; for (i=0;i<29;i++) { printf("%c",sn[i]); } printf("\n\n"); getchar(); return 0; } |
|
[分享]CrackMe 2007专辑学习笔记
CrackMe 2007->序列号->逍遥风->Trsh—CrackMe 分析和注册机 重要的是先自己做几遍,实在不行再看教程。 004010D3 . 6A 50 PUSH 50 ; /Count = 50 (80.) 004010D5 . 68 B0344000 PUSH tsrh-cra.004034B0 ; |Buffer = tsrh-cra.004034B0 004010DA . 68 DE000000 PUSH 0DE ; |ControlID = DE (222.) 004010DF . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 004010E2 . E8 43020000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 004010E7 . 83F8 05 CMP EAX,5 ; 取注册名并判断长度是否大于等于5位,否则跳走 004010EA . 7D 26 JGE SHORT tsrh-cra.00401112 004010EC . B8 66354000 MOV EAX,tsrh-cra.00403566 004010F1 . E8 05020000 CALL tsrh-cra.004012FB 004010F6 . 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 004010F8 . 68 52354000 PUSH tsrh-cra.00403552 ; |Title = "TSRh CrackMe *Easy*" 004010FD . 68 00304000 PUSH tsrh-cra.00403000 ; |Text = "Kill this Nag!!!" 00401102 . 6A 00 PUSH 0 ; |hOwner = NULL 00401104 . E8 27020000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 00401109 . 33C0 XOR EAX,EAX 0040110B . 5E POP ESI 0040110C . 5F POP EDI 0040110D . 5B POP EBX 0040110E . C9 LEAVE 0040110F . C2 1000 RETN 10 00401112 > E8 DC000000 CALL tsrh-cra.004011F3 ; 关键call,跟进,格式化字符串:trsh-“7D3+注册名长度的十进制” 00401117 . 6A 50 PUSH 50 ; /Count = 50 (80.) 00401119 . 68 90314000 PUSH tsrh-cra.00403190 ; |Buffer = tsrh-cra.00403190 0040111E . 68 4D010000 PUSH 14D ; |ControlID = 14D (333.) 00401123 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd 00401126 . E8 FF010000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 0040112B . A1 90314000 MOV EAX,DWORD PTR DS:[403190] ; 取注册码字符,存放于【403190】处并赋值给eax 00401130 . 3D 74737268 CMP EAX,68727374 ; 比较注册码的前4个字符是否是:0x68727374 00401135 . 75 23 JNZ SHORT tsrh-cra.0040115A 00401137 . 05 20320000 ADD EAX,3220 ; EAX赋值+0x3220,注册码前4为字符值加3220 0040113C . 50 PUSH EAX 0040113D . 33C0 XOR EAX,EAX 0040113F . E8 EA000000 CALL tsrh-cra.0040122E ; 关键call,跟进 00401144 . 58 POP EAX 00401145 . 85C0 TEST EAX,EAX 00401147 . 74 11 JE SHORT tsrh-cra.0040115A 00401149 . 33C2 XOR EAX,EDX 0040114B . 8BD0 MOV EDX,EAX 0040114D . 8BF0 MOV ESI,EAX 0040114F . 33C0 XOR EAX,EAX 00401151 . E8 31010000 CALL tsrh-cra.00401287 ; 比较结果 00401156 . 84C0 TEST AL,AL 00401158 . 75 1F JNZ SHORT tsrh-cra.00401179 ; 此处跳走就完蛋 0040115A > B8 85354000 MOV EAX,tsrh-cra.00403585 0040115F . E8 97010000 CALL tsrh-cra.004012FB 关键call根进 0040122E /$ 56 PUSH ESI 0040122F |. 68 20334000 PUSH tsrh-cra.00403320 ; /String = "tsrh-2008-CZYXY" 00401234 |. E8 1B010000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA 00401239 |. 8B3D 14354000 MOV EDI,DWORD PTR DS:[403514] ; 【403514】存放的是注册名的长度,取出送EDI 0040123F |. BE 01000000 MOV ESI,1 00401244 |. 8BC8 MOV ECX,EAX ; EAX是取得的格式字符“tsrh-2008-”的长度,送ECX 00401246 |> B8 B0344000 MOV EAX,tsrh-cra.004034B0 ; ASCII "pediy" 0040124B |. 0FB64406 FF MOVZX EAX,BYTE PTR DS:[ESI+EAX-1] ; 依次取出注册名的每位字符 00401250 |. 04 0C ADD AL,0C ; 和0x0C相加 00401252 |. 0FB6D0 MOVZX EDX,AL ; 相加后的值送EDX 00401255 |. 83EA 11 SUB EDX,11 ; 相加后的值减0X11 00401258 |. 03D0 ADD EDX,EAX 0040125A |. 2BD1 SUB EDX,ECX 0040125C |. 33C2 XOR EAX,EDX 0040125E |. 50 PUSH EAX ; /<%X> 0040125F |. 68 18354000 PUSH tsrh-cra.00403518 ; |Format = "%X" 00401264 |. 8D81 20334000 LEA EAX,DWORD PTR DS:[ECX+403320] ; | 0040126A |. 50 PUSH EAX ; |s 0040126B |. E8 A8000000 CALL <JMP.&USER32.wsprintfA> ; \wsprintfA 00401270 |. 83C4 0C ADD ESP,0C 00401273 |. 68 20334000 PUSH tsrh-cra.00403320 ; /String = "tsrh-2008-CZYXY" 00401278 |. E8 D7000000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA 0040127D |. 8BC8 MOV ECX,EAX 0040127F |. 46 INC ESI 00401280 |. 4F DEC EDI 00401281 |.^ 75 C3 JNZ SHORT tsrh-cra.00401246 00401283 |. 33C0 XOR EAX,EAX 00401285 |. 5E POP ESI 00401286 \. C3 RETN 00401287 /$ 53 PUSH EBX 00401288 |. BE 01000000 MOV ESI,1 ; ESI赋给值1 0040128D |> B8 B0344000 /MOV EAX,tsrh-cra.004034B0 ; ASCII "pediy" 00401292 |. 0FB64406 FF |MOVZX EAX,BYTE PTR DS:[ESI+EAX-1] 00401297 |. 85C0 |TEST EAX,EAX ; 判断是否取完注册码,取完则跳出循环 00401299 |. 74 34 |JE SHORT tsrh-cra.004012CF 0040129B |. 40 |INC EAX ; 注册名每位先加1 0040129C |. BA 20334000 |MOV EDX,tsrh-cra.00403320 ; ASCII "tsrh-2008-CZYXY" 004012A1 |. 0FB65416 0B |MOVZX EDX,BYTE PTR DS:[ESI+EDX+B] 004012A6 |. 33C2 |XOR EAX,EDX 004012A8 |> 83F8 41 |/CMP EAX,41 ; 小于“A”则加0x8 004012AB |. 7D 05 ||JGE SHORT tsrh-cra.004012B2 004012AD |. 83C0 08 ||ADD EAX,8 004012B0 |.^ EB F6 |\JMP SHORT tsrh-cra.004012A8 004012B2 |> 83F8 5A |/CMP EAX,5A ; 大于0x5A则减0x3 004012B5 |. 7E 05 ||JLE SHORT tsrh-cra.004012BC 004012B7 |. 83E8 03 ||SUB EAX,3 004012BA |.^ EB F6 |\JMP SHORT tsrh-cra.004012B2 004012BC |> 83C6 09 |ADD ESI,9 004012BF |. BB 20334000 |MOV EBX,tsrh-cra.00403320 ; ASCII "tsrh-2008-CZYXY" 004012C4 |. 89041E |MOV DWORD PTR DS:[ESI+EBX],EAX 004012C7 |. 83EE 08 |SUB ESI,8 004012CA |. 83FE 10 |CMP ESI,10 004012CD |.^ 75 BE \JNZ SHORT tsrh-cra.0040128D 004012CF |> 33C0 XOR EAX,EAX 004012D1 |. 5B POP EBX 004012D2 |. E8 01000000 CALL tsrh-cra.004012D8 004012D7 \. C3 RETN 算法:用户名必须大于=5,其他具体看注册机源码 注册机: #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> //初步试了下好像用户名输入的是数字计算出来的不对, //所以下面的最好输入字母且不能低于5位。。 //注册码的第二部分是0x7D3+用户名的长度,第一部分必须是“tsrh-” int main(void) { char name[]={"pediy"}; int i; int namelen; char temp[20]; //存放一个中间计算过程 char temp2[20];//存放注册码的第三部分 printf("注册名:%s\n",name); for (i=0;i<20;i++) { temp[i]='\0'; temp2[i]='\0'; } namelen=strlen(name); for (i=0;i<namelen;i++) { // printf("%lX",(((name[i]+0x0C)*2-0x11)-0x0A-i)^(name[i]+0x0C)); //计算注册码中间的一个call,在根据这个结果计算真正的注册码 int a; a=(((name[i]+0x0C)*2-0x11)-0x0A-i)^(name[i]+0x0C); if (i==1) { itoa(a,temp,16); } } if (islower(temp[0])) { temp[0]-=32; } for (i=0;i<namelen;i++) { name[i]++; if (i==0) { name[i]=name[i]^temp[0]; } else { name[i]=name[i]^0x00; } while (name[i]<0x41) { name[i]+=0x8; } while (name[i]>0x5A) { name[i]-=3; } temp2[i]=name[i]; } printf("\n\n"); printf("注册码:tsrh-"); printf("%d-",0x7D3+namelen); printf("%s",temp2); printf("\n\n"); getchar(); return 0; } |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值