CrackMe的分析
crackme:http://re-xe.com/?p=111
反汇编代码:
0040110C |> /0FBE840D 48FF>/movsx eax, byte ptr [ebp+ecx-B8] ; 分别取用户名的每个字符
00401114 |. |41 |inc ecx ; 当前是第几个字符,从1开始
00401115 |. |33C1 |xor eax, ecx ; 字符值和字符位置异或,存入eax中
00401117 |. |03D8 |add ebx, eax ; 累加
00401119 |. |3B4D D8 |cmp ecx, dword ptr [ebp-28]
0040111C |.^\75 EE \jnz short 0040110C
0040111E |. 6BC0 06 imul eax, eax, 6 ; eax = eax * 6 结果乘6,eax是最后一个字母异或后的结果
00401121 |. C1E3 07 shl ebx, 7 ; 累加的和左移7位
00401124 |. 03C3 add eax, ebx ; eax和ebx相加
00401126 |. 8945 C8 mov dword ptr [ebp-38], eax
00401129 |. FF75 C8 push dword ptr [ebp-38]
0040112C |. 68 38B44000 push 0040B438 ; ASCII "%lX"
00401131 |. 8D8D 80FEFFFF lea ecx, dword ptr [ebp-180]
00401137 |. 51 push ecx
00401138 |. E8 873D0000 call 00404EC4 ; 将注册码转换为十六进制字符串
0040113D |. 83C4 0C add esp, 0C
00401140 |. 8D85 80FEFFFF lea eax, dword ptr [ebp-180]
00401146 |. 50 push eax ; /String2
00401147 |. 8D95 E4FEFFFF lea edx, dword ptr [ebp-11C] ; |
0040114D |. 52 push edx ; |String1
0040114E |. E8 339C0000 call <jmp.&KERNEL32.lstrcmpA> ; \lstrcmp 将真码和假码比较
00401153 |. 85C0 test eax, eax
00401155 |. 75 0D jnz short 00401164
00401157 |. 68 3CB44000 push 0040B43C ; /Text = "Congratulations! IF this number comes *FROM YOUR* keygen, Write a tutorial dude ;)."
0040115C |. 56 push esi ; |hWnd
0040115D |. E8 289B0000 call <jmp.&USER32.SetWindowTextA> ; \SetWindowTextA
00401162 |. EB 18 jmp short 0040117C
00401164 |> 68 90B44000 push 0040B490 ; /Text = "This serial is *NOT* Valid!! Try again... : UNREGISTERED"
00401169 |. 56 push esi ; |hWnd
0040116A |. E8 1B9B0000 call <jmp.&USER32.SetWindowTextA> ; \SetWindowTextA
0040116F |. EB 0B jmp short 0040117C
00401171 |> 68 C9B44000 push 0040B4C9 ; /Text = "Name must contain more than 4 chars and less than 50 chars !!"
00401176 |. 56 push esi ; |hWnd
00401177 |. E8 0E9B0000 call <jmp.&USER32.SetWindowTextA> ; \SetWindowTextA
0040117C |> 5F pop edi
0040117D |. 5E pop esi
0040117E |. 5B pop ebx
0040117F |. 8BE5 mov esp, ebp
00401181 |. 5D pop ebp
00401182 \. C3 retn
算法分析及注册机:(VS2010 + XP Sp3 测试通过)
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
char username[100];
char key[100];
cout << "username :" ;
cin >> username;
int length = strlen(username);
if (length <= 4 || length >= 50)
{
cout << "Name must contain more than 4 chars and less than 50 chars !!";
cin.get();
cin.get();
return 0;
}
cout << "Key is :";
int value = 0;
int sum = 0;
for (int i =0;i<length;i++)
value = (username[i]) ^ (i+1); //1. 将每个字符和该字符所在位置异或
sum += value; //2. 异或的结果累加
}
value *= 6; //3. 最后一个字符和该字符所在的位置异或,结果乘以6
sum = (sum << 7); //4. 步骤2中计算出的值向左移动7位
sum += value; //5. 步骤3和步骤4的值累加
itoa(sum,key,16); //6. 步骤5的值转换为16进制
char *upkey;
upkey = _strupr(_strdup(key)); //7. 将16进制字符串转换为大写
cout << upkey;
cin.get();
cin.get();
return 0;
}
没事,别怕,这是签名→→┃ 青山幽谷笛声扬,白鹤振羽任翱翔。往事前尘随风逝,携手云峰隐仙乡。 ┃