初学 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:[EAX]
004417CF |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
004417D2 |. 8D55 FC LEA EDX,DWORD PTR SS:[EBP-4]
004417D5 |. 8B83 C8020000 MOV EAX,DWORD PTR DS:[EBX+2C8]
004417DB >|. E8 C419FEFF CALL CrackMe.004231A4 ; 获取注册码->controls.TControl.GetText(TControl):TCaption;
004417E0 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; [0012F650] 送 EAX
004417E3 |. 50 PUSH EAX ; EAX 压栈
004417E4 |. 8D55 F4 LEA EDX,DWORD PTR SS:[EBP-C]
004417E7 |. 8B83 C4020000 MOV EAX,DWORD PTR DS:[EBX+2C4]
004417ED >|. E8 B219FEFF CALL CrackMe.004231A4 ; 获取用户名->controls.TControl.GetText(TControl):TCaption;
004417F2 |. 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] ; [0012F648] 送 EAX
004417F5 |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8]
004417F8 >|. E8 FBFEFFFF CALL CrackMe.004416F8 ; 关键 CALL 计算注册码 F7 跟进->Unit1.Proc_004416F8
004417FD |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8] ; 真码送 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:[442C30]
00441819 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
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:[442C30]
00441833 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
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:[EAX],EDX
00441842 |. 68 67184400 PUSH CrackMe.00441867
00441847 |> 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
0044184A >|. E8 691FFCFF CALL CrackMe.004037B8 ; ->System.Proc_004037B8
0044184F |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
00441852 >|. E8 611FFCFF CALL CrackMe.004037B8 ; ->System.Proc_004037B8
00441857 |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
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:[ESP],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:[EDI+EDX-1] ; 取用户名 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:[ESP]
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:[ESP+8],EAX ; |结果送 [0012F604]
00441755 |. C64424 0C 00 MOV BYTE PTR SS:[ESP+C],0 ; |
0044175A |. C1EB 10 SHR EBX,10 ; |取结果 1 前 4 位
0044175D |. 895C24 10 MOV DWORD PTR SS:[ESP+10],EBX ; |送 [0012F60C]
00441761 |. C64424 14 00 MOV BYTE PTR SS:[ESP+14],0 ; |
00441766 |. 8BC6 MOV EAX,ESI ; |结果 2 送 EAX
00441768 |. 25 FFFF0000 AND EAX,0FFFF ; |取结果 2 后 4 位
0044176D |. 894424 18 MOV DWORD PTR SS:[ESP+18],EAX ; |结果送 [0012F614]
00441771 |. C64424 1C 00 MOV BYTE PTR SS:[ESP+1C],0 ; |
00441776 |. C1EE 10 SHR ESI,10 ; |取结果 2 前 4 位
00441779 |. 897424 20 MOV DWORD PTR SS:[ESP+20],ESI ; |送 [0012F61C]
0044177D |. C64424 24 00 MOV BYTE PTR SS:[ESP+24],0 ; |
00441782 |. 8D5424 08 LEA EDX,DWORD PTR SS:[ESP+8] ; |
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[SIZE] ={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[i]^0x49390305;
Result2=Result1^0x48631220;
}
else //第二个字母开始用这个公式算
{
Result1=Result1^Name[i];
Result2=Result2^Result1;
}
//结果1后两位奇偶效验
if ((Result1 & 0xFF)%2) //奇数
{
Result1=Result1/2^0x1200311;
}
else Result1=Result1/2; //偶数
if (!Name[i+1]) 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 ;
}
CrackMe 下载:crackme.rar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)