0040116B |. 68 6C804000 push CrackMe2.0040806C ; ASCII "%s"
00401170 |. E8 DB000000 call CrackMe2.00401250
00401175 |. 68 54804000 push CrackMe2.00408054
0040117A |. E8 E8000000 call CrackMe2.00401267 ; 111111111111111111
0040117F |. 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
00401183 |. 51 push ecx
00401184 |. 68 6C804000 push CrackMe2.0040806C ; ASCII "%s"
00401189 |. E8 C2000000 call CrackMe2.00401250
0040118E |. 8D9424 940000>lea edx,dword ptr ss:[esp+0x94]
00401195 |. 8D4424 6C lea eax,dword ptr ss:[esp+0x6C]
00401199 |. 52 push edx
0040119A |. 50 push eax
0040119B |. E8 60FEFFFF call CrackMe2.00401000 ; 加密1
004011A0 |. 8D8C24 C40000>lea ecx,dword ptr ss:[esp+0xC4]
004011A7 |. 8D9424 9C0000>lea edx,dword ptr ss:[esp+0x9C]
004011AE |. 51 push ecx
004011AF |. 8D4424 78 lea eax,dword ptr ss:[esp+0x78]
004011B3 |. 52 push edx
004011B4 |. 50 push eax
004011B5 |. E8 96FEFFFF call CrackMe2.00401050 ;加密2
004011BA |. 8D4C24 58 lea ecx,dword ptr ss:[esp+0x58]
004011BE |. 8D9424 D00000>lea edx,dword ptr ss:[esp+0xD0]
004011C5 |. 51 push ecx
004011C6 |. 8D8424 AC0000>lea eax,dword ptr ss:[esp+0xAC]
004011CD |. 52 push edx
004011CE |. 8D8C24 880000>lea ecx,dword ptr ss:[esp+0x88]
004011D5 |. 50 push eax
004011D6 |. 51 push ecx
004011D7 |. E8 A4FEFFFF call CrackMe2.00401080 ;加密3
004011DC |. 8D7C24 40 lea edi,dword ptr ss:[esp+0x40]
004011E0 |. 83C9 FF or ecx,0xFFFFFFFF
004011E3 |. 33C0 xor eax,eax
004011E5 |. 83C4 3C add esp,0x3C
004011E8 |. F2:AE repne scas byte ptr es:[edi]
004011EA |. F7D1 not ecx
004011EC |. 49 dec ecx ;长度
004011ED |. 5F pop edi
004011EE |. 85C9 test ecx,ecx
004011F0 |. 7E 0F jle XCrackMe2.00401201
004011F2 |> 8A5404 00 /mov dl,byte ptr ss:[esp+eax] ; 依次读取注册码
004011F6 |. FEC2 |inc dl
004011F8 |. 885404 00 |mov byte ptr ss:[esp+eax],dl
004011FC |. 40 |inc eax
004011FD |. 3BC1 |cmp eax,ecx
004011FF |.^ 7C F1 \jl XCrackMe2.004011F2 ; 注册码ascii加 1
00401201 |> 8D5424 00 lea edx,dword ptr ss:[esp]
00401205 |. 8D4424 28 lea eax,dword ptr ss:[esp+0x28]
00401209 |. 52 push edx
0040120A |. 50 push eax
0040120B |. E8 F0FEFFFF call CrackMe2.00401100
00401210 |. 83C4 08 add esp,0x8
00401213 |. 83F8 01 cmp eax,0x1
00401216 |. 75 19 jnz XCrackMe2.00401231 //跳向失败
00401218 |. 68 40804000 push CrackMe2.00408040
0040121D |. E8 45000000 call CrackMe2.00401267
00401222 |. 83C4 04 add esp,0x4
00401225 |. E8 7C580000 call CrackMe2.00406AA6
0040122A |. 81C4 C8000000 add esp,0xC8
00401230 |. C3 retn
00401231 |> 68 30804000 push CrackMe2.00408030
00401236 |. E8 2C000000 call CrackMe2.00401267
0040123B |. 83C4 04 add esp,0x4
0040123E |. E8 63580000 call CrackMe2.00406AA6
00401243 |. 81C4 C8000000 add esp,0xC8
00401249 \. C3 retn
加密1:
00401013 |> /0FBEC0 /movsx eax,al
00401016 |. |8BC8 |mov ecx,eax
00401018 |. |81E1 0F000080 |and ecx,0x8000000F
0040101E |. |79 05 |jns XCrackMe2.00401025
00401020 |. |49 |dec ecx
00401021 |. |83C9 F0 |or ecx,0xFFFFFFF0
00401024 |. |41 |inc ecx
00401025 |> |99 |cdq ;eax 高位为0 相当于 edx = 0
00401026 |. |83E2 0F |and edx,0xF
00401029 |. |03C2 |add eax,edx
0040102B |. |C0E1 04 |shl cl,0x4 ;左移4位
0040102E |. |C1F8 04 |sar eax,0x4 ;右移4位
00401031 |. |02C8 |add cl,al ;相加
00401033 |. |880E |mov byte ptr ds:[esi],cl
00401035 |. |79 04 |jns XCrackMe2.0040103B ;判断是否为正数
00401037 |. |F6D9 |neg cl ;不为正数则取反加1
00401039 |. |880E |mov byte ptr ds:[esi],cl ; 存放起来
0040103B |> |8A47 01 |mov al,byte ptr ds:[edi+0x1]
0040103E |. |47 |inc edi
0040103F |. |46 |inc esi
00401040 |. |43 |inc ebx
00401041 |. |84C0 |test al,al
00401043 |.^\75 CE \jnz XCrackMe2.00401013
加密2:
00401050 /$ 57 push edi
00401051 |. 8B7C24 08 mov edi,dword ptr ss:[esp+0x8]
00401055 |. 8A0F mov cl,byte ptr ds:[edi]
00401057 |. 84C9 test cl,cl
00401059 |. 74 20 je XCrackMe2.0040107B ;若第一位为空则退出这个计算
0040105B |. 8B5424 10 mov edx,dword ptr ss:[esp+0x10]
0040105F |. 56 push esi
00401060 |. 8B7424 10 mov esi,dword ptr ss:[esp+0x10] ;取加密后的用户名
00401064 |> 8A06 /mov al,byte ptr ds:[esi]
00401066 |. 32C1 |xor al,cl ;与加密前的用户名进行异或运算
00401068 |. 8802 |mov byte ptr ds:[edx],al
0040106A |. 7F 04 |jg XCrackMe2.00401070 ;判断是否小于等于0
0040106C |. 04 60 |add al,0x60 ;如果是,则加上0x60
0040106E |. 8802 |mov byte ptr ds:[edx],al
00401070 |> 8A4F 01 |mov cl,byte ptr ds:[edi+0x1]
00401073 |. 47 |inc edi
00401074 |. 46 |inc esi
00401075 |. 42 |inc edx
00401076 |. 84C9 |test cl,cl
00401078 |.^ 75 EA \jnz XCrackMe2.00401064
0040107A |. 5E pop esi
0040107B |> 5F pop edi
0040107C \. C3 retn
加密3:
00401080 /$ 55 push ebp
00401081 |. 8B6C24 08 mov ebp,dword ptr ss:[esp+0x8] ; ebp=用户名
00401085 |. 8A4D 00 mov cl,byte ptr ss:[ebp]
00401088 |. 84C9 test cl,cl ;取第一个用户名,判断是否为空
0040108A |. 74 6C je XCrackMe2.004010F8
0040108C |. 8B5424 14 mov edx,dword ptr ss:[esp+0x14]
00401090 |. 53 push ebx
00401091 |. 56 push esi
00401092 |. 8B7424 18 mov esi,dword ptr ss:[esp+0x18] ; 第二次加密后的数据
00401096 |. 57 push edi
00401097 |. 8B7C24 18 mov edi,dword ptr ss:[esp+0x18] ; 第一次加密后的数据
0040109B |. 74 0E je XCrackMe2.004010AB
0040109D |> 8A07 mov al,byte ptr ds:[edi] ;依次取第一次加密后的数据
0040109F |. C74424 14 010>mov dword ptr ss:[esp+0x14],0x1
004010A7 |. 84C0 test al,al ;用第一次加密后的数据作为条件结束依据
004010A9 |. 75 08 jnz XCrackMe2.004010B3
004010AB |> C74424 14 000>mov dword ptr ss:[esp+0x14],0x0
004010B3 |> 803F 00 cmp byte ptr ds:[edi],0x0 ;用第一次加密后的数据作为条件结束依据
004010B6 |. 75 09 jnz XCrackMe2.004010C1
004010B8 |. 803E 00 cmp byte ptr ds:[esi],0x0
004010BB |. 75 04 jnz XCrackMe2.004010C1
004010BD |. 33DB xor ebx,ebx
004010BF |. EB 05 jmp XCrackMe2.004010C6
004010C1 |> BB 01000000 mov ebx,0x1
004010C6 |> 8A06 mov al,byte ptr ds:[esi] ;依次取第二次加密后的数据
004010C8 |. 32C1 xor al,cl ; 将第二次加密后的数据与原用户名进行异或运算
004010CA |. 32C3 xor al,bl ;再与数字1进行异或运算
004010CC |. 8A5C24 14 mov bl,byte ptr ss:[esp+0x14]
004010D0 |. 32C3 xor al,bl ;再与bl进行异或运算
004010D2 |. 3C 30 cmp al,0x30 ; 比较是否小于0x30
004010D4 |. 8802 mov byte ptr ds:[edx],al
004010D6 |. 7D 04 jge XCrackMe2.004010DC
004010D8 |. 34 45 xor al,0x45 ;若小于,则与0x45进行异或运算
004010DA |. 8802 mov byte ptr ds:[edx],al
004010DC |> 8A02 mov al,byte ptr ds:[edx]
004010DE |. 3C 5B cmp al,0x5B ;比较是否5B<x<5F
004010E0 |. 7C 08 jl XCrackMe2.004010EA
004010E2 |. 3C 5F cmp al,0x5F
004010E4 |. 7F 04 jg XCrackMe2.004010EA
004010E6 |. 04 08 add al,0x8 ;若满足条件 ,则+0x8
004010E8 |. 8802 mov byte ptr ds:[edx],al ;继续取下一位数据,准备进行计算
004010EA |> 8A4D 01 mov cl,byte ptr ss:[ebp+0x1]
004010ED |. 45 inc ebp
004010EE |. 47 inc edi
004010EF |. 46 inc esi
004010F0 |. 42 inc edx
004010F1 |. 84C9 test cl,cl
004010F3 |.^ 75 A8 jnz XCrackMe2.0040109D
004010F5 |. 5F pop edi
004010F6 |. 5E pop esi
004010F7 |. 5B pop ebx
004010F8 |> 5D pop ebp
004010F9 \. C3 retn
注册机:
#include <stdio.h>
int main(){
char name[20];
char name1[20];
char name2[20];
char name3[20];
int i,a,b,c;
printf("请输入你的用户名啊::\n");
scanf("%s",name);
printf("这就是你的注册码啊:\n");
for(i=0;name[i];i++)
{
a=name[i]<<4&0x000000F0;
b=name[i]>>4&0x0000000F;
c=a+b;
name1[i]=c;
if(name1[i]&0x80)
name1[i]=~name1[i]+0x1;
}//完成第一次加密
for(i=0;name[i];i++)
{
name2[i]=name[i]^name1[i];
if(name2[i]<=0)
name2[i]+=0x60;
}//完成第二次加密
for(i=0;name[i];i++)
{
name3[i]=name2[i]^name[i];
if(name3[i]<=0x30)
{
name3[i]=name3[i]^0x45;
}
if(name3[i]>0x5B&&name3[i]<0x5F)
name3[i]=name3[i]+8;
name3[i]=name3[i]-0x1;
printf("%c",name3[i]);
}
printf("\n");
getchar();
getchar();
}
思路:
1、 依次取各位用户名的ascii值,将十六进制格式的ascii值十位于个位进行对换,如 3F变为F3,2D变成D2,如果变换的结果出现负数,则取它的补码。补码=原码取反+1
2、 将第一步得到的数据与原用户名各字符对应进行异或运算,若得到的结果中有值小于等于0,则将该值加上0x60
3、 将第二步得到的数据,与原用户名进行异或运算,得到的值按以下步骤处理。(1)若小于等于0x30,则与0x45进行异或运算。(2)若0x5B<X<0X5F,则将该值加上0x8
4、 将第三步得到的数据减0x1,就得到正确的注册码。