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;
}
posted @ 2011-02-14 21:21  Delcpp  阅读(375)  评论(1编辑  收藏  举报