首页
社区
课程
招聘
[原创]riijj_cm_20041121 算法注册机
发表于: 2014-9-2 01:48 5579

[原创]riijj_cm_20041121 算法注册机

2014-9-2 01:48
5579

【破解作者】 Night
【作者主页】 www.freecracker.com
【使用工具】 OD
【破解平台】 Win7
【软件名称】 riijj_cm_20041121.zip
------------------------------------------------------------------------------------------------------------
00401030  /$  A1 846B4000   mov eax,dword ptr ds:[0x406B84]                    ;  这里是验证部分
00401035  |.  85C0          test eax,eax
00401037  |.  0F84 90000000 je riijj_cr.004010CD
0040103D  |.  56            push esi
0040103E  |.  57            push edi
0040103F  |.  E8 BCFFFFFF   call riijj_cr.00401000
00401044  |.  BF F06B4000   mov edi,riijj_cr.00406BF0                          ;  ASCII "Night"
00401049  |.  83C9 FF       or ecx,0xFFFFFFFF                                  ;  ecx = 4
0040104C  |.  33C0          xor eax,eax                                        ;  eax = 0
0040104E  |.  C705 846B4000>mov dword ptr ds:[0x406B84],0x0                    ;  ds:[0x406B84] = 0
00401058  |.  F2:AE         repne scas byte ptr es:[edi]                       ;  获取用户名字符串长度
0040105A  |.  F7D1          not ecx                                            ;  ecx中存放的是用户名长度
0040105C  |.  2BF9          sub edi,ecx                                        ;  edi 指向了用户名
0040105E  |.  C705 506C4000>mov dword ptr ds:[0x406C50],0x1                    ;  0x406C50 = 1
00401068  |.  8BC1          mov eax,ecx                                        ;  eax 中存放用户名长度
0040106A  |.  8BF7          mov esi,edi                                        ;  esi指向了 用户名
0040106C  |.  BF 406C4000   mov edi,riijj_cr.00406C40                          ;  ASCII "Night"
00401071  |.  C1E9 02       shr ecx,0x2                                        ;  ecx = ecx >> 2
00401074  |.  F3:A5         rep movs dword ptr es:[edi],dword ptr ds:[esi]     ;  把用户名赋值到 es:[edi] 中 长度为 ecx
00401076  |.  8BC8          mov ecx,eax                                        ;  ecx 中存放用户名长度
00401078  |.  33C0          xor eax,eax                                        ;  eax = 0
0040107A  |.  83E1 03       and ecx,0x3                                        ;  ecx = ecx & 3
0040107D  |.  F3:A4         rep movs byte ptr es:[edi],byte ptr ds:[esi]       ;  把用户名赋值到 es:[edi] 中 长度为 ecx
0040107F  |.  BF 006C4000   mov edi,riijj_cr.00406C00                          ;  edi 指向了 Key值
00401084  |.  83C9 FF       or ecx,0xFFFFFFFF                                  ;  ecx = -1
00401087  |.  F2:AE         repne scas byte ptr es:[edi]
00401089  |.  F7D1          not ecx                                            ;  取Key值长度  保存到 ecx 中
0040108B  |.  2BF9          sub edi,ecx                                        ;  edi 指向了Key值
0040108D  |.  A1 7C6B4000   mov eax,dword ptr ds:[0x406B7C]                    ;  eax = 10001010
00401092  |.  8BD1          mov edx,ecx                                        ;  edx 中保存Key值的长度
00401094  |.  8BF7          mov esi,edi                                        ;  esi 指向了Key值
00401096  |.  BF 206C4000   mov edi,riijj_cr.00406C20                          ;  ASCII "1234567890"
0040109B  |.  C1E9 02       shr ecx,0x2                                        ;  ecx = ecx >> 2
0040109E  |.  F3:A5         rep movs dword ptr es:[edi],dword ptr ds:[esi]     ;  把Key值保存到es:[edi] 中  长度为 ecx
004010A0  |.  8BCA          mov ecx,edx                                        ;  Key值长度保存到 ecx 中
004010A2  |.  83E1 03       and ecx,0x3                                        ;  ecx = ecx & 3
004010A5  |.  F3:A4         rep movs byte ptr es:[edi],byte ptr ds:[esi]       ;  把Key值保存到es:[edi] 中  长度为 ecx
004010A7  |.  5F            pop edi
004010A8  |.  5E            pop esi
004010A9  |.  85C0          test eax,eax                                       ;  判断eax 是否为 0  如果 为 0 就挂掉了
004010AB  |.  74 16         je Xriijj_cr.004010C3
004010AD  |.  8B0D 806B4000 mov ecx,dword ptr ds:[0x406B80]                    ;  ds:[0x406B80]   =  3044E
004010B3  |.  51            push ecx
004010B4  |.  68 206C4000   push riijj_cr.00406C20                             ;  ASCII "1234567890"
004010B9  |.  68 406C4000   push riijj_cr.00406C40                             ;  ASCII "Night"
004010BE  |.  FFD0          call eax
{
10001010 >  81EC 84000000   sub esp,0x84
10001016    B9 19000000     mov ecx,0x19
1000101B    33C0            xor eax,eax                                        ; eax = 0
1000101D    53              push ebx
1000101E    55              push ebp
1000101F    56              push esi
10001020    57              push edi
10001021    BE 54500010     mov esi,pf1.10005054                               ; fytugjhkuijonlbpvqmcnxbvzdaeqrwtryetdgfkgphonuivmdbxfanqydexzwztqnkcfkvcpvlbmhotyiufdkdnjxuzyqhfstae
10001026    8D7C24 30       lea edi,dword ptr ss:[esp+0x30]
1000102A    F3:A5           rep movs dword ptr es:[edi],dword ptr ds:[esi]
1000102C    8B9C24 98000000 mov ebx,dword ptr ss:[esp+0x98]                    ; 用户名保存到 ebx中
10001033    83C9 FF         or ecx,0xFFFFFFFF                                  ; ecx = -1
10001036    8BFB            mov edi,ebx                                        ; edi 指向了用户名
10001038    F2:AE           repne scas byte ptr es:[edi]                       ; 求用户名长度 保存到 ecx 中
1000103A    8BBC24 9C000000 mov edi,dword ptr ss:[esp+0x9C]                    ; edi 指向了Key值
10001041    F7D1            not ecx                                            ; ecx 中保存了用户名的长度
10001043    49              dec ecx                                            ; ecx = ecx - 1
10001044    8BE9            mov ebp,ecx                                        ; ebp  = ecx
10001046    83C9 FF         or ecx,0xFFFFFFFF                                  ; ecx = ecx | 0xFFFFFFFF
10001049    F2:AE           repne scas byte ptr es:[edi]
1000104B    F7D1            not ecx                                            ; ecx 中保存Key值的长度
1000104D    49              dec ecx                                            ; ecx = ecx - 1
1000104E    8D7C24 10       lea edi,dword ptr ss:[esp+0x10]
10001052    8BD1            mov edx,ecx                                        ; edx = ecx
10001054    B9 07000000     mov ecx,0x7                                        ; ecx = 0x7
10001059    F3:AB           rep stos dword ptr es:[edi]                        ; 清空 一块内存 存放数据 大小为 ecx * 4
1000105B    66:AB           stos word ptr es:[edi]                             ; 清空一块内存  大小为4字节
1000105D    83FD 0F         cmp ebp,0xF                                        ; 用户名的长度必须在4到15位之间
10001060    AA              stos byte ptr es:[edi]                             ; 清空一字节内存
10001061    0F8F A1000000   jg pf1.10001108
10001067    83FD 04         cmp ebp,0x4
1000106A    0F8C 98000000   jl pf1.10001108
10001070    83FA 1E         cmp edx,0x1E                                       ; Key值的长度必须在4到30位之间
10001073    0F8F 8F000000   jg pf1.10001108
10001079    83FA 04         cmp edx,0x4
1000107C    0F8C 86000000   jl pf1.10001108
10001082    33C9            xor ecx,ecx                                        ; ecx = 0
10001084    85ED            test ebp,ebp                                       ; 用户名长度不能为 0
10001086    76 26           jbe Xpf1.100010AE
10001088    8D7424 11       lea esi,dword ptr ss:[esp+0x11]                    ; esi 指向刚才新初始化的一块内存
1000108C    0FBE0419        movsx eax,byte ptr ds:[ecx+ebx]                    ; eax 中存放用户名的第一位
10001090    99              cdq
10001091    BF 62000000     mov edi,0x62                                       ; edi = 0x62
10001096    83C6 02         add esi,0x2                                        ; esi = esi + 2
10001099    F7FF            idiv edi                                           ; eax / edi    商保存到 eax中  余数保存到 edx 中
1000109B    41              inc ecx
1000109C    3BCD            cmp ecx,ebp                                        ; 循环 的判断条件
1000109E    8A4414 30       mov al,byte ptr ss:[esp+edx+0x30]                  ; 在初始化字符串中按照余数搜索出指定的字符 保存到 al中
100010A2    8A5414 31       mov dl,byte ptr ss:[esp+edx+0x31]                  ; 搜索出上面字符所在位置的下一个位置字符 保存到 dl中
100010A6    8846 FD         mov byte ptr ds:[esi-0x3],al                       ; 保存数据到数组
100010A9    8856 FE         mov byte ptr ds:[esi-0x2],dl                       ; 保存数据到数组
100010AC  ^ 72 DE           jb Xpf1.1000108C
100010AE    8BB424 9C000000 mov esi,dword ptr ss:[esp+0x9C]                    ; esi指向了Key值
100010B5    C64424 2E 00    mov byte ptr ss:[esp+0x2E],0x0
100010BA    8D4424 10       lea eax,dword ptr ss:[esp+0x10]                    ; eax 指向了 新生成的数组中的数据
100010BE    8A10            mov dl,byte ptr ds:[eax]                           ; 新生成的数据和Key值按位比较
100010C0    8A1E            mov bl,byte ptr ds:[esi]
100010C2    8ACA            mov cl,dl                                          ; cl = dl  新数组数据的第一位
100010C4    3AD3            cmp dl,bl
100010C6    75 1E           jnz Xpf1.100010E6
100010C8    84C9            test cl,cl                                         ; 判断是否为结束符
100010CA    74 16           je Xpf1.100010E2
100010CC    8A50 01         mov dl,byte ptr ds:[eax+0x1]                       ; 新数组数据的第二位
100010CF    8A5E 01         mov bl,byte ptr ds:[esi+0x1]                       ; Key值的第二位
100010D2    8ACA            mov cl,dl
100010D4    3AD3            cmp dl,bl
100010D6    75 0E           jnz Xpf1.100010E6
100010D8    83C0 02         add eax,0x2                                        ; eax = eax + 2
100010DB    83C6 02         add esi,0x2                                        ; esi = esi + 2
100010DE    84C9            test cl,cl
100010E0  ^ 75 DC           jnz Xpf1.100010BE
100010E2    33C0            xor eax,eax
100010E4    EB 05           jmp Xpf1.100010EB
100010E6    1BC0            sbb eax,eax
100010E8    83D8 FF         sbb eax,-0x1
100010EB    85C0            test eax,eax
100010ED    75 19           jnz Xpf1.10001108
100010EF    50              push eax
100010F0    8B8424 A4000000 mov eax,dword ptr ss:[esp+0xA4]
100010F7    68 4C500010     push pf1.1000504C                                  ; Crackme
100010FC    68 30500010     push pf1.10005030                                  ; Registration successful !
10001101    50              push eax
10001102    FF15 B0400010   call dword ptr ds:[<&USER32.MessageBoxA>]          ; user32.MessageBoxA
10001108    5F              pop edi
10001109    5E              pop esi
1000110A    5D              pop ebp
1000110B    5B              pop ebx
1000110C    81C4 84000000   add esp,0x84
10001112    C3              retn

}
004010C0  |.  83C4 0C       add esp,0xC
004010C3  |>  C705 506C4000>mov dword ptr ds:[0x406C50],0x0
004010CD  \>  C3            retn

2 算法注册机的实现

// CrackMe4.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
/***
*   riijj_crackme.exe 程序注册机  
*   完成时间: 2014年9月2日  1:40   
*   完成人  : Night
*/

int _tmain(int argc, _TCHAR* argv[])
{
        //存放用户名
        char userName[100]={0};
       
        //初始化字符串
        char ch[100]="ytugjhkuijonlbpvqmcnxbvzdaeqrwtryetdgfkgphonuivmdbxfanqydexzwztqnkcfkvcpvlbmhotyiufdkdnjxuzyqhfstae";
       
        //存放商
        unsigned int quotient = 0;

        //存放余数
        unsigned int mod      = 0;

        //存放结果
        char result [100]     = {0};

        //循环变量
        int  k                                  = 0;

        printf("请输入用户名:");
        gets_s(userName);

        if (strlen(userName)>15 || strlen(userName) < 4)
        {
                printf("用户名必须是4到15位");
                return 1;
        }
        for (int i = 0; i < strlen(userName); i++)
        {
                mod       = userName[i] % 0x62;

                quotient  = userName[i] / 0x62;

                result[k++] = ch[mod-0x1];
                result[k++] = ch[mod];
        }

        printf("\n注册码为:");
        for (int i = 0; i < strlen(result); i++)
        {
                printf("%c",result[i]);
        }
        printf("\n");
        return 0;
}

PS: VS2012 编译 ,  这个CrackMe 存在反调试功能,主要就是检测OD。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (7)
雪    币: 340
活跃值: (71)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
2
如果算法存在问题,请大神们多多指教。
2014-9-2 01:49
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
支持楼主
算法牛
2014-9-2 08:30
0
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
转换为VC的:
#include "stdio.h"
#include "STRING.H"

void main()
{
	char userName[100]={0};//存放用户名
	
	//初始化字符串
	char ch[100]="ytugjhkuijonlbpvqmcnxbvzdaeqrwtryetdgfkgphonuivmdbxfanqydexzwztqnkcfkvcpvlbmhotyiufdkdnjxuzyqhfstae";
	unsigned int mod = 0;   //存放余数
	char result [100] = {0};//存放结果
	int  i,n;               //循环变量及长度

	do
	{
		printf("请输入用户名。注意用户名必须是4到15位!:\n");
		gets(userName);
		n = strlen(userName);
	}while (n>15 || n < 4);

	for ( i = 0; i < n; i++)
	{
		mod = userName[i] % 0x62;
		result[2*i] = ch[mod-0x1];
		result[2*i+1] = ch[mod];
	}

	printf("\n注册码为:\n");
	printf("%s\n",result);
	printf("按回车键退出。\n");
	gets(userName);

}


感觉你编程和分析技术没怎长进。
2014-9-2 18:58
0
雪    币: 340
活跃值: (71)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
5
感觉你编程和分析技术没怎长进。

嗯 , 请大神们多多指教。 我的算法不正确吗? 我哪里有不正确的地方请您多指教。这个算法我也是循环了用户名长度次呢。我只是想学习下,别无他意。 谢谢。我希望知道自己哪里不足。
2014-9-2 19:43
0
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
mod = userName % 0x62;

quotient = userName / 0x62;

代码中本来就是求余,你的代码非的要多出第二行,间接说明分析技术不到位。
for (int i = 0; i < strlen(result); i++)
{
printf("%c",result);
}

使用这种方法输出结果,感觉编程技术没长进,形而上学。
2014-9-2 20:42
0
雪    币: 54
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
帮忙看个帖子:
http://bbs.pediy.com/showthread.php?p=1313698#post1313698

谢谢
2014-9-2 22:04
0
雪    币: 340
活跃值: (71)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
8
代码中本来就是求余,你的代码非的要多出第二行,间接说明分析技术不到位。


谢谢指正,下次写代码一定注意。
2014-9-2 23:24
0
游客
登录 | 注册 方可回帖
返回
//