首页
社区
课程
招聘
[原创]deurus's keygenMe#02算法分析及注册机
发表于: 2010-7-24 07:21 5818

[原创]deurus's keygenMe#02算法分析及注册机

2010-7-24 07:21
5818

【文章标题】: deurus's keygenMe#02算法分析及注册机
【文章作者】:  pickup
【软件名称】: keygenMe#02.exe
【软件大小】: 52 KB
【下载地址】: 见以下附件 
【编写语言】: VC6.0
【使用工具】: PEID,OD
【操作平台】: Windows XP3
【连接地址】: http://bbs.pediy.com/showthread.php?p=839354#post839354

今天在Crackmes.de上看到这个,查了下没有壳,刚好适合我来学习,于是就分析了下,以下是分析结果,分析的不对的地方请指正。

bp GetDlgItemTextA  下断,找到关键点

需要找出2个注册码的算法,这是第一个注册码的算法代码

00401610  |.  52            PUSH EDX
00401611  |.  68 E8030000   PUSH 3E8
00401616  |.  8B4D BC       MOV ECX,DWORD PTR SS:[EBP-44]
00401619  |.  E8 BE0B0000   CALL <JMP.&MFC42.#3098>                  ;  取输入的注册名
0040161E  |.  68 20404000   PUSH keygenMe.00404020                   ;  ASCII "Hi newbie! I hope you enjoy with this"
00401623  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
00401626  |.  E8 690B0000   CALL <JMP.&MFC42.#860>
0040162B  |.  68 48404000   PUSH keygenMe.00404048                   ;  ASCII "BadBoy!"
00401630  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
00401633  |.  E8 5C0B0000   CALL <JMP.&MFC42.#860>
00401638  |.  68 50404000   PUSH keygenMe.00404050                   ;  ASCII "BadBoy!"
0040163D  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
00401640  |.  E8 4F0B0000   CALL <JMP.&MFC42.#860>
00401645  |.  68 58404000   PUSH keygenMe.00404058                   ;  ASCII "BadBoy!"
0040164A  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
0040164D  |.  E8 420B0000   CALL <JMP.&MFC42.#860>
00401652  |.  68 60404000   PUSH keygenMe.00404060                   ;  ASCII "BadBoy!"
00401657  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
0040165A  |.  E8 350B0000   CALL <JMP.&MFC42.#860>
0040165F  |.  68 68404000   PUSH keygenMe.00404068                   ;  ASCII "BadBoy!"
00401664  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
00401667  |.  E8 280B0000   CALL <JMP.&MFC42.#860>
0040166C  |.  68 70404000   PUSH keygenMe.00404070                   ;  ASCII "BadBoy!"
00401671  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
00401674  |.  E8 1B0B0000   CALL <JMP.&MFC42.#860>
00401679  |.  68 78404000   PUSH keygenMe.00404078                   ;  ASCII "BadBoy!"
0040167E  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
00401681  |.  E8 0E0B0000   CALL <JMP.&MFC42.#860>
00401686  |.  68 80404000   PUSH keygenMe.00404080                   ;  ASCII "BadBoy!"
0040168B  |.  8D4D F0       LEA ECX,DWORD PTR SS:[EBP-10]
0040168E  |.  E8 010B0000   CALL <JMP.&MFC42.#860>
00401693  |.  C745 D4 00000>MOV DWORD PTR SS:[EBP-2C],0
0040169A  |.  EB 09         JMP SHORT keygenMe.004016A5
0040169C  |>  8B45 D4       /MOV EAX,DWORD PTR SS:[EBP-2C]
0040169F  |.  83C0 01       |ADD EAX,1
004016A2  |.  8945 D4       |MOV DWORD PTR SS:[EBP-2C],EAX
004016A5  |>  8D4D DC        LEA ECX,DWORD PTR SS:[EBP-24]           ;  注册名送|ECX
004016A8  |.  51            |PUSH ECX                                ; /s
004016A9  |.  E8 F20B0000   |CALL <JMP.&MSVCRT.strlen>               ; \strlen
004016AE  |.  83C4 04       |ADD ESP,4
004016B1  |.  3945 D4       |CMP DWORD PTR SS:[EBP-2C],EAX           ;  判断循环是否结束
004016B4  |.  77 25         |JA SHORT keygenMe.004016DB              ;  计算完用户名的所有位就跳走
004016B6  |.  8B55 D4       |MOV EDX,DWORD PTR SS:[EBP-2C]           ;  每次循环EDX都赋初值0
004016B9  |.  0FBE4415 DC   |MOVSX EAX,BYTE PTR SS:[EBP+EDX-24]      ;  取出注册名的每一位送EAX
004016BE  |.  8B4D D4       |MOV ECX,DWORD PTR SS:[EBP-2C]
004016C1  |.  0FBE540D DC   |MOVSX EDX,BYTE PTR SS:[EBP+ECX-24]      ;  取注册名的每一位送EDX
004016C6  |.  81C2 B11C0000 |ADD EDX,1CB1                            ;  和0x1CB1相加
004016CC  |.  C1E2 09       |SHL EDX,9                               ;  再乘以0x200
004016CF  |.  0355 D8       |ADD EDX,DWORD PTR SS:[EBP-28]           ;  累加edx。ebp-28中是上次累加和
004016D2  |.  8D4402 C0     |LEA EAX,DWORD PTR DS:[EDX+EAX-40]       ;  edx+eax-0x40
004016D6  |.  8945 D8       |MOV DWORD PTR SS:[EBP-28],EAX           ;  保存当前循环计算结果,
004016D9  |.^ EB C1         \JMP SHORT keygenMe.0040169C
004016DB  |>  8B4D D8       MOV ECX,DWORD PTR SS:[EBP-28]
004016DE  |.  51            PUSH ECX
004016DF  |.  68 88404000   PUSH keygenMe.00404088                   ;  ASCII "%i"
004016E4  |.  8B55 BC       MOV EDX,DWORD PTR SS:[EBP-44]
004016E7  |.  81C2 64010000 ADD EDX,164
004016ED  |.  52            PUSH EDX
004016EE  |.  E8 E30A0000   CALL <JMP.&MFC42.#2818>
004016F3  |.  83C4 0C       ADD ESP,0C
004016F6  |.  6A 14         PUSH 14
004016F8  |.  8D45 C0       LEA EAX,DWORD PTR SS:[EBP-40]
004016FB  |.  50            PUSH EAX
004016FC  |.  68 E9030000   PUSH 3E9
00401701  |.  8B4D BC       MOV ECX,DWORD PTR SS:[EBP-44]
00401704  |.  E8 D30A0000   CALL <JMP.&MFC42.#3098>
00401709  |.  68 8C404000   PUSH keygenMe.0040408C                   ;  ASCII "GoodBoy!"


00401B36  |.  50            PUSH EAX
00401B37  |.  68 E9030000   PUSH 3E9
00401B3C  |.  8B8D B0FEFFFF MOV ECX,DWORD PTR SS:[EBP-150]
00401B42  |.  E8 95060000   CALL <JMP.&MFC42.#3098>                    ;  取输入的的第二个假注册码的字符,getdlgitemtext函数
00401B47  |.  8D4D B4       LEA ECX,DWORD PTR SS:[EBP-4C]
00401B4A  |.  51            PUSH ECX                                   ; /参数2,真正的第二个注册码,真码的计算是在其他地方。
00401B4B  |.  8D55 C8       LEA EDX,DWORD PTR SS:[EBP-38]              ; |
00401B4E  |.  52            PUSH EDX                                   ; |参数1.取输入的第二个注册码
00401B4F  |.  E8 1C020000   CALL keygenMe.00401D70                     ; \比较输入的注册码是否正确。
00401B54  |.  25 FF000000   AND EAX,0FF
00401B59  |.  85C0          TEST EAX,EAX
00401B5B  |.  74 19         JE SHORT keygenMe.00401B76                 ;  修改此处可以爆破第二个注册
00401B5D  |.  6A 40         PUSH 40
00401B5F  |.  68 F0424000   PUSH keygenMe.004042F0
00401B64  |.  68 98414000   PUSH keygenMe.00404198                     ;  ASCII "GoodBoy!"
00401B69  |.  8B8D B0FEFFFF MOV ECX,DWORD PTR SS:[EBP-150]
00401B6F  |.  E8 56060000   CALL <JMP.&MFC42.#4224>



[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 897
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
算法分析:  第一个注册码是根据输入用户名计算出来,将用户名的每位加0x1CB1,再*0x200;之后累加后的十进制就是第一个注册码
输入第一个码后check1就会灰色,check2就可以点击了,第二个注册码的格式必须是:A-系统用户名-B-XXXXXX-C-YYYYYY,其中系统用
户名是断GetUserNameA来跟踪的,XXXXXX是根据系统用户名计算出来的,YYYYYY是根据输入的注册名字计算出来的,具体看上面的反汇编
代码和下面的注册机源码,本人编程初学,只能写成这样了。
有一点要注意下,之前我的登录名是:administrator,跟踪时已经看到注册码了,可就是不成功,搞了好久才明白,原来系统的用户名不能超过8位,主要原因是在后面GetDlgItemTextA时最多去取30个字符,这样就把最后几位截掉了,所以即使是正确的注册码也不对,后来我把getdlgitemtext的一个参数改大了才好了,大家可以试下,我在上面并没有刻意提到哪个地方。

注册机:
#include <stdlib.h> 
#include <stdio.h> 
#include <string>

#include <ctype.h>
#include <windows.h>

char name[]={"pediy"};    

using namespace std;
void sn2();
void sn1();
int main(void) 
{  	
	printf("注册名:  %s\n",name);
	sn1();                   //求第一个注册码并输出;
	TCHAR user[50];          //取当前的系统用户名;
	DWORD dwN=50;
	GetUserName(user,&dwN);	
	int namelen;			//求第二个注册码的第一组数字,
	int i,edx,eax,ecx;      //根据当前系统用户名计算出来,
	edx=0;eax=0;ecx=0;
	namelen=strlen(user);
	for (i=0;i<=namelen;i++)
	{
		edx=user[i];
		eax=user[i];
		edx=edx*0x7;
		ecx=ecx+edx+0x0F7C5;
	}
		printf("注册码二:A-");
		printf("%s-",user);
		printf("B-%d",ecx);	
		sn2();
		
		printf("\n\n");		
	getchar();
	return 0; 
}

void sn1(void)      //第一个注册码的计算。
{
	int namelen;
	int i,edx,eax,sum;
	sum=0;
	namelen=strlen(name);
	for (i=0;i<=namelen;i++)
	{
		edx=name[i];
		eax=name[i];
		edx=edx+0x1CB1;
		edx=edx*0x200;
		
		eax=edx+eax-0x40;
		sum=sum+eax;
			
		}
	printf("注册码一:%d   \n",sum);
}
void sn2(void)          //第二个注册码的第二组数字部分
{
	int namelen;
	int i,edx,esi,sum;
	sum=0;edx=0;esi=0;
	namelen=strlen(name);
	for (i=0;i<=namelen;i++)
	{
		esi=name[4]*0x5;
		edx=name[1]*0x144;
		edx=edx+sum;
		edx=edx+esi;
		sum=edx;
	//	printf("   %lX    ",sum);
	}
		printf("-C-%d",sum);
}

2010-7-24 07:36
0
雪    币: 246
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
怎么后面说得有点模糊,可能我不会,呵呵,支持个
2010-8-2 20:24
0
游客
登录 | 注册 方可回帖
返回