CrackMe 6 算法分析+注册机
初学 C++ 和算法分析,这东西坛子里的人都折腾过N次了。不过好像都觉得太简单没人写过注册机,贴上我的练习,分析的不好,代码写的更差,贴出来看看谁有时间帮我精简下算法。用DEDE找到关键点后分析如下:
004417B8 >/.55 PUSH EBP ;注册码判断开始<-TForm1@Button1Click
004417B9|.8BEC MOV EBP,ESP
004417BB|.6A 00 PUSH 0
004417BD|.6A 00 PUSH 0
004417BF|.6A 00 PUSH 0
004417C1|.53 PUSH EBX
004417C2|.8BD8 MOV EBX,EAX
004417C4|.33C0 XOR EAX,EAX
004417C6|.55 PUSH EBP
004417C7|.68 60184400 PUSH <CrackMe.->System.Proc_00403278>
004417CC|.64:FF30 PUSH DWORD PTR FS:
004417CF|.64:8920 MOV DWORD PTR FS:,ESP
004417D2|.8D55 FC LEA EDX,DWORD PTR SS:
004417D5|.8B83 C8020000 MOV EAX,DWORD PTR DS:
004417DB >|.E8 C419FEFF CALL CrackMe.004231A4 ;获取注册码->controls.TControl.GetText(TControl):TCaption;
004417E0|.8B45 FC MOV EAX,DWORD PTR SS: ; 送 EAX
004417E3|.50 PUSH EAX ;EAX 压栈
004417E4|.8D55 F4 LEA EDX,DWORD PTR SS:
004417E7|.8B83 C4020000 MOV EAX,DWORD PTR DS:
004417ED >|.E8 B219FEFF CALL CrackMe.004231A4 ;获取用户名->controls.TControl.GetText(TControl):TCaption;
004417F2|.8B45 F4 MOV EAX,DWORD PTR SS: ; 送 EAX
004417F5|.8D55 F8 LEA EDX,DWORD PTR SS:
004417F8 >|.E8 FBFEFFFF CALL CrackMe.004416F8 ;关键 CALL 计算注册码 F7 跟进->Unit1.Proc_004416F8
004417FD|.8B55 F8 MOV EDX,DWORD PTR SS: ;真码送 EDX
00441800|.58 POP EAX ;假码出栈送 EAX
00441801 >|.E8 3E23FCFF CALL CrackMe.00403B44 ;真假码比较->System.Proc_00403B44
00441806|.75 1A JNZ SHORT CrackMe.00441822 ;不等就 OVER
00441808|.6A 40 PUSH 40
0044180A|.B9 6C184400 MOV ECX,CrackMe.0044186C ;ASCII "U made it"
0044180F|.BA 78184400 MOV EDX,CrackMe.00441878 ;ASCII "Right Code"
00441814|.A1 302C4400 MOV EAX,DWORD PTR DS:
00441819|.8B00 MOV EAX,DWORD PTR DS:
0044181B >|.E8 D4D6FFFF CALL CrackMe.0043EEF4 ;->:TApplication._PROC_0043EEF4()
00441820|.EB 18 JMP SHORT CrackMe.0044183A
00441822|>6A 10 PUSH 10
00441824|.B9 84184400 MOV ECX,CrackMe.00441884 ;ASCII "Error"
00441829|.BA 8C184400 MOV EDX,CrackMe.0044188C ;ASCII "Wrong Code"
0044182E|.A1 302C4400 MOV EAX,DWORD PTR DS:
00441833|.8B00 MOV EAX,DWORD PTR DS:
00441835 >|.E8 BAD6FFFF CALL CrackMe.0043EEF4 ;->:TApplication._PROC_0043EEF4()
0044183A|>33C0 XOR EAX,EAX
0044183C|.5A POP EDX
0044183D|.59 POP ECX
0044183E|.59 POP ECX
0044183F|.64:8910 MOV DWORD PTR FS:,EDX
00441842|.68 67184400 PUSH CrackMe.00441867
00441847|>8D45 F4 LEA EAX,DWORD PTR SS:
0044184A >|.E8 691FFCFF CALL CrackMe.004037B8 ;->System.Proc_004037B8
0044184F|.8D45 F8 LEA EAX,DWORD PTR SS:
00441852 >|.E8 611FFCFF CALL CrackMe.004037B8 ;->System.Proc_004037B8
00441857|.8D45 FC LEA EAX,DWORD PTR SS:
0044185A >|.E8 591FFCFF CALL CrackMe.004037B8 ;->System.Proc_004037B8
0044185F\.C3 RETN
00441860 > .^ E9 131AFCFF JMP CrackMe.00403278 ;->System.Proc_00403278
00441865 .^ EB E0 JMP SHORT CrackMe.00441847
00441867 .5B POP EBX
00441868 .8BE5 MOV ESP,EBP
0044186A .5D POP EBP
0044186B .C3 RETN
004417F8 >|.E8 FBFEFFFF CALL CrackMe.004416F8 跟进后
004416F8/$53 PUSH EBX ;
004416F9|.56 PUSH ESI
004416FA|.57 PUSH EDI
004416FB|.83C4 DC ADD ESP,-24
004416FE|.891424 MOV DWORD PTR SS:,EDX
00441701|.8BF8 MOV EDI,EAX ;用户名送 EDI
00441703|.BB 05033949 MOV EBX,49390305
00441708|.BE 20126348 MOV ESI,48631220
0044170D|.8BC7 MOV EAX,EDI
0044170F|.E8 2023FCFF CALL CrackMe.00403A34 ;获取注册码位数
00441714|.85C0 TEST EAX,EAX
00441716|.7E 2E JLE SHORT CrackMe.00441746 ;没输入注册码就 OVER
00441718|.BA 01000000 MOV EDX,1
0044171D|>33C9 /XOR ECX,ECX ;清空 ECX
0044171F|.8A4C17 FF |MOV CL,BYTE PTR DS: ;取用户名 ASCII 送 CL
00441723|.33D9 |XOR EBX,ECX ;与 49390305 做 XOR 运算 结果送 EBX
00441725|.33F3 |XOR ESI,EBX ;再与 48631220 做 XOR 运算 结果送 ESI
00441727|.F6C3 01 |TEST BL,1 ;BL 做奇偶效验
0044172A|.74 0F |JE SHORT CrackMe.0044173B ;偶数跳
0044172C|.D1FB |SAR EBX,1 ;EBX = EBX/2
0044172E|.79 03 |JNS SHORT CrackMe.00441733
00441730|.83D3 00 |ADC EBX,0
00441733|>81F3 11032001 |XOR EBX,1200311 ;与 1200311 做 XOR 运算 结果送 EBX
00441739|.EB 07 |JMP SHORT CrackMe.00441742 ;准备取下一个字母
0044173B|>D1FB |SAR EBX,1 ;EBX = EBX/2
0044173D|.79 03 |JNS SHORT CrackMe.00441742
0044173F|.83D3 00 |ADC EBX,0
00441742|>42 |INC EDX ;计数器 + 1
00441743|.48 |DEC EAX ;用户名位数 - 1
00441744|.^ 75 D7 \JNZ SHORT CrackMe.0044171D
00441746|>8B0424 MOV EAX,DWORD PTR SS:
00441749|.50 PUSH EAX ; /Arg1
0044174A|.8BC3 MOV EAX,EBX ; |结果 1 送 EAX
0044174C|.25 FFFF0000 AND EAX,0FFFF ; |取结果 1 后 4 位
00441751|.894424 08 MOV DWORD PTR SS:,EAX ; |结果送
00441755|.C64424 0C 00MOV BYTE PTR SS:,0 ; |
0044175A|.C1EB 10 SHR EBX,10 ; |取结果 1 前 4 位
0044175D|.895C24 10 MOV DWORD PTR SS:,EBX ; |送
00441761|.C64424 14 00MOV BYTE PTR SS:,0 ; |
00441766|.8BC6 MOV EAX,ESI ; |结果 2 送 EAX
00441768|.25 FFFF0000 AND EAX,0FFFF ; |取结果 2 后 4 位
0044176D|.894424 18 MOV DWORD PTR SS:,EAX ; |结果送
00441771|.C64424 1C 00MOV BYTE PTR SS:,0 ; |
00441776|.C1EE 10 SHR ESI,10 ; |取结果 2 前 4 位
00441779|.897424 20 MOV DWORD PTR SS:,ESI ; |送
0044177D|.C64424 24 00MOV BYTE PTR SS:,0 ; |
00441782|.8D5424 08 LEA EDX,DWORD PTR SS: ; |
00441786|.B9 03000000 MOV ECX,3 ; |
0044178B|.B8 A4174400 MOV EAX,CrackMe.004417A4 ; |ASCII "%.4x-%.4x-%.4x-%.4x"
00441790|.E8 6F68FCFF CALL CrackMe.00408004 ; \格式转换
00441795|.83C4 24 ADD ESP,24
00441798|.5F POP EDI
00441799|.5E POP ESI
0044179A|.5B POP EBX
0044179B\.C3 RETN
注册机:
#include <iostream>
#include <iomanip>
using namespace std;
#define SIZE 100 //定义100位大小准备定义数组存放用户名
#define OPF hex<<setfill('0')<<setw(4)<<setiosflags(ios::uppercase) //定义输出格式 OPF=Output Format
void output(void); //定义输出头信息
int main()
{
char Name ={0}; //初始化数组为0
int Result1=0,Result2=0;
output();
cout<<"Please Input Your Name: " ;
cin>>Name;
for (int i=0;i<SIZE;i++)
{
if (0==i) //取出的是用户名中第一个字母的话用这个算
{
Result1=Name^0x49390305;
Result2=Result1^0x48631220;
}
else //第二个字母开始用这个公式算
{
Result1=Result1^Name;
Result2=Result2^Result1;
}
//结果1后两位奇偶效验
if ((Result1 & 0xFF)%2) //奇数
{
Result1=Result1/2^0x1200311;
}
else Result1=Result1/2; //偶数
if (!Name) break; //用户名全部取完就结束
}
//格式化输出结果
cout<<"Your Serial Number Is : "<<OPF<<(Result1&0xFFFF)<<"-"<<OPF<<(Result1>>0x10)<<"-"<<OPF<<(Result2&0xFFFF)<<"-"<<OPF<<(Result2>>0x10)<<endl;
system("pause");
return 0;
}
void output(void)
{
cout<<" " ;
cout<<".::KEYGEN for CrackMe 6::."<<endl<<endl ;
cout<<" " ;
cout<<"Code BY RegKiller"<<endl<<endl ;
cout<<" " ;
cout<<"QQ Group Number: 21051610"<<endl<<endl ;
}
支持学习了! 很强的样子,支持兄弟!!!! :00441806 751A jne 00441822 //暴破点
:00441808 6A40 push 00000040
:0044180A B96C184400 mov ecx, 0044186C
* Possible StringData Ref from Code Obj ->"Right Code"
|
:0044180F BA78184400 mov edx, 00441878
:00441814 A1302C4400 mov eax, dword ptr
:00441819 8B00 mov eax, dword ptr
:0044181B E8D4D6FFFF call 0043EEF4
:00441820 EB18 jmp 0044183A
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00441806(C)
|
:00441822 6A10 push 00000010
* Possible StringData Ref from Code Obj ->"Error"
|
:00441824 B984184400 mov ecx, 00441884
* Possible StringData Ref from Code Obj ->"Wrong Code"
|
:00441829 BA8C184400 mov edx, 0044188C
:0044182E A1302C4400 mov eax, dword ptr
:00441833 8B00 mov eax, dword ptr
:00441835 E8BAD6FFFF call 0043EEF4
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00441820(U) 谢谢提供,学习一下。 DEDE不会用!不知谁有他的使用方法!
页:
[1]