首页
社区
课程
招聘
[原创]HappyTown的第17个CrackMe
发表于: 2006-9-14 13:17 9371

[原创]HappyTown的第17个CrackMe

2006-9-14 13:17
9371

这是专为新手入门而制作的系列CrackMe之一。

因为算法太简单,所以,你必须做出注册机才算成功。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (19)
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
2
因为算法太简单,所以,你必须做出注册机才算成功。

狠:好像不太简单吧,一大对的检测,明天有时间再看
2006-9-14 15:14
0
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
3
最初由 KAN 发布
因为算法太简单,所以,你必须做出注册机才算成功。

狠:好像不太简单吧,一大对的检测,明天有时间再看

你仔细分析一下就知道了,那些检测很容易通过,因为不涉及算法。

核心代码就那几行。
2006-9-14 16:06
0
雪    币: 2943
活跃值: (1788)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
4
抽个空也看看?
2006-9-15 02:39
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我来写个注册机,只有代码:),并且对输入错误未作限制
输入有以下限制
1.未处理的用户名长度应该在0x6和0xf之间
2.经过处理后(不清楚是什么处理,貌似除掉重复字符,但又不是),长度至少为0x6
3.序列号必须长度为0xe
4.用户名和序列号好像必须是字母(proc 401420没看明白,根据经验得出)
所以输入的限制请自己把握

下面是注册代码

bool crack(const char * in ,char *out)
{
        char username[100];
        char u[100];
        char pass[100];
        memset(pass,0,sizeof(pass));
        const char *p="CRACKINGFORFUN";
       
        int a,b,a1,b1;
        int i,j,k;
        memset(username,0,sizeof(username));
        strcpy(username,in);
        //用户初始处理
        int len=strlen(username);
        for(i=1;i<len;i++)
        {
                for(j=0;j<i;j++)
                {
                        if(username[i]==username[j])
                        {
                                memmove(&username[i],&username[i+1],len);
                        }
                }
        }
        strupr(username);
        //自成包含用户名的表
        memset(u,0,sizeof(u));
        strcpy(u,username);
        len=strlen(u);
        for(i='A';i<='Z';i++)
        {
                if(i==0x4a)
                {
                        j=0x49;
                }
                else
                {
                        j=i;
                }
                char *p=strchr(u,j);
                if(p==NULL)
                {
                        u[len++]=j;
                }
        }
       
        for(k=0;k<0xe/2;k++)
        {
                for(i=0;i<25;i++)
                {
                        for(j=0;j<25;j++)
                        {
                                a=i/5;
                                b=i%5;
                                a1=j/5;
                                b1=j%5;
                                if(a==a1)
                                {
                                        if(b!=0)
                                        {
                                                b--;
                                        }
                                        else
                                        {
                                                b=4;
                                        }
                                        if(b1!=0)
                                        {
                                                b1--;
                                        }
                                        else
                                        {
                                                b1=4;
                                        }
                                        if( *(u+a*5+b)==*(p+k*2) && *(u+a1*5+b1)==*(p+1+k*2))
                                        {
                                                pass[k*2]=*(u+i);
                                                pass[k*2+1]=*(u+j);
                                        }
                                }
                                else if(b==b1)
                                {
                                        if(a!=0)
                                        {
                                                a--;
                                        }
                                        else
                                        {
                                                a=4;
                                        }
                                        if(a1!=0)
                                        {
                                                a1--;
                                        }
                                        else
                                        {
                                                a1=4;
                                        }
                                        if( *(u+a*5+b)==*(p+k*2) && *(u+a1*5+b1)==*(p+1+k*2))
                                        {
                                                pass[k*2]=*(u+i);
                                                pass[k*2+1]=*(u+j);
                                        }
                                }
                                else if( *(u+a*5+b1)==*(p+k*2) && *(u+a1*5+b)==*(p+1+k*2))
                                {
                                        pass[k*2]=*(u+i);
                                        pass[k*2+1]=*(u+j);
                                }
                        }
                }
        }
        strcpy(out,pass);
        return true;
}
2006-9-15 19:59
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
顺便提一句,序列号大小写无关,i,j是相等的
2006-9-15 20:22
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
第一次CALL401420是把注册名转成大写,第二次CALL401420不明白
2006-9-15 20:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
两次都是,如果有他认为非法的字符会返回0,否则会返回1
2006-9-15 20:45
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
[QUOTE].1.未处理的用户名长度应该在0x6和0xf之间
2.经过处理后(不清楚是什么处理,貌似除掉重复字符,但又不是),长度至少为0x6
zheng 你能否说说去了重复字符后对其扩展的的详细算法.
如注册名为FEDCJBA(设它为A1)和ABCDEFGHIKLMNOPQRSTUVWXYZ(注.这里为25个字符,没有"J"设它为A2),A2中去了A1中有的字符得到字符串A3,A3+A1=FEDCJBAGHIKLMNOPQRSTUVWXYZd,不知为何多出个"d".
  输入不同的字串时A3+A1的最后位还会出乱码,晕
  HAPPY TOWN真能忽悠人呀
2006-9-15 21:22
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
//自成包含用户名的表
  memset(u,0,sizeof(u));
  strcpy(u,username);
  len=strlen(u);
  for(i='A';i<='Z';i++)
  {
    if(i==0x4a)
    {
      j=0x49;
    }
    else
    {
      j=i;
    }
    char *p=strchr(u,j);
    if(p==NULL)
    {
      u[len++]=j;
    }
  }
这一段就是处理的算法啊
FEDCJBA处理后结果为
FEDCJBAGHIKLMNOPQRSTUVWXYZ
后面有什么不管,只取25位,另发现新问题,如果说序列号是唯一的话,如果刚好算的序列号含有'J',那么就无法提供一个序列号.刚巧海东青山提供的FEDCJBA我就无法得到序列号,郁闷,请happytown解说一下.
2006-9-16 00:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我提供的注册名是我研究这个CRACKME时,跟据有关算法,有意选择"FEDCJBA"
2006-9-16 08:24
0
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
12
碰到序列号中有J时,会当做I处理。
谁给出一组可用的name和serial?
2006-9-20 20:25
0
雪    币: 3688
活跃值: (4242)
能力值: (RANK:215 )
在线值:
发帖
回帖
粉丝
13
最初由 happytown 发布
碰到序列号中有J时,会当做I处理。
谁给出一组可用的name和serial?


俺凑出来的

2006-9-20 22:24
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
请问happytown
FEDCJBA
的注册码是什么
2006-9-21 11:31
0
雪    币: 296
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
同楼上所问...
2006-9-24 20:51
0
雪    币: 3688
活跃值: (4242)
能力值: (RANK:215 )
在线值:
发帖
回帖
粉丝
16
最初由 zheng 发布
请问happytown
FEDCJBA
的注册码是什么


无解吧。

DSHE0BMH**PDXK

星号位置的没合适的
2006-9-25 09:04
0
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
17
最初由 zheng 发布
请问happytown
FEDCJBA
的注册码是什么


含有字母J的用户名均被列入黑名单。
2006-9-27 20:30
0
雪    币: 297
活跃值: (21)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
18
其实并不是所有序列号中的J都是当I处理的.
序列号是2位一组生成的(共14位7组),只有序列号中的J处于作任何一组(2位)的第1位时,才当I处理,此时就无法得出正确的序列号;如果J处于任何一组(2位)的第2位时,就还是当J,这时可得到正确的序列号.
在这里贴一组用户名含J的注册码
2007-1-5 17:14
0
雪    币: 148
活跃值: (25)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
19
004011F2   |.  33ED              xor ebp,ebp
004011F4   |.  33C9              xor ecx,ecx
004011F6   |.  3BF5              cmp esi,ebp
004011F8   |.  7E 2F             jle short CrackMe_.00401229
004011FA   |>  33FF              /xor edi,edi
004011FC   |.  3BCD              |cmp ecx,ebp
004011FE   |.  7E 24             |jle short CrackMe_.00401224
00401200   |>  8A543C 4C         |/mov dl,byte ptr ss:[esp+edi+4C]
00401204   |.  8A440C 4C         ||mov al,byte ptr ss:[esp+ecx+4C]
00401208   |.  3AD0              ||cmp dl,al
0040120A   |.  75 13             ||jnz short CrackMe_.0040121F
0040120C   |.  3BCE              ||cmp ecx,esi
0040120E   |.  8BC1              ||mov eax,ecx
00401210   |.  7D 0D             ||jge short CrackMe_.0040121F
00401212   |>  8A5404 4D         ||/mov dl,byte ptr ss:[esp+eax+4D]
00401216   |.  885404 4C         |||mov byte ptr ss:[esp+eax+4C],dl
0040121A   |.  40                |||inc eax
0040121B   |.  3BC6              |||cmp eax,esi
0040121D   |.^ 7C F3             ||\jl short CrackMe_.00401212
0040121F   |>  47                ||inc edi
00401220   |.  3BF9              ||cmp edi,ecx
00401222   |.^ 7C DC             |\jl short CrackMe_.00401200
00401224   |>  41                |inc ecx
00401225   |.  3BCE              |cmp ecx,esi
00401227   |.^ 7C D1             \jl short CrackMe_.004011FA
00401229   |>  8D4424 4C         lea eax,dword ptr ss:[esp+4C]

对应
void aTst(char *buf, int len)
{
        int offEcx        = 0;
        int iebp        = 0;
        int iedi        = 0;
        int ieax        = 0;
        while(offEcx < len)
        {
                iedi = 0;
                if(offEcx > iebp)
                {
                        while(iedi < offEcx)
                        {
                                if(buf[offEcx]==buf[iedi])
                                {
                                        ieax = iedi;
                                        while(ieax < len)
                                        {
                                                buf[ieax] = buf[ieax+1];
                                                ieax ++;
                                        }
                                }
                                iedi ++;
                        }
                }
                offEcx ++;
        }

        return ;
}

是去重, 但不是完全的去重.如果有相临的三个相同的字母, 则会留下两个.
如COOOLSTAR会留下COOLSTAR.
COOLSTLALR会留下COLSTAR, 不好意思, 写错了. 应该是COSTALR.
2007-1-7 11:20
0
雪    币: 148
活跃值: (25)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
20
LPCTSTR baseString = "CRACKINGFORFUN";
void main()
{
bTst("coolstar");
}
void bTst(char *buf)
{
        printf("%s\n", buf);

        //
        int len = strlen(buf);
        int offEcx        = 0;
        int iebp        = 0;
        int iedi        = 0;
        int ieax        = 0;
        while(offEcx < len)
        {
                iedi = 0;
                if(offEcx > iebp)
                {
                        while(iedi < offEcx)
                        {
                                if(buf[offEcx]==buf[iedi])
                                {
                                        ieax = iedi;
                                        while(ieax < len)
                                        {
                                                buf[ieax] = buf[ieax+1];
                                                ieax ++;
                                        }
                                }
                                iedi ++;
                        }
                }
                offEcx ++;
        }

        //
        int bufLen = strlen(buf);
        char chrI;
        for (char iChar='A'; iChar<='Z' ; iChar++)
        {
                chrI = iChar;
                if(chrI == 'J')
                        chrI = 'I';
                if(NULL == strchr(buf, chrI))
                {
                        buf[bufLen++] = chrI;
                }
        }

        int aBase[16] = {0};
        char *pFind = NULL;
        for(int i = 0; i< strlen(baseString); i++)
        {
                pFind = strchr(buf, baseString[i]);
                ASSERT(pFind != NULL);
                aBase[i] = pFind-buf;
        }

        BOOL bRev, bInvalid;
        int a5f, a1f;
        int b5f, b1f;
        UCHAR aReg1, aReg2;
        bInvalid = TRUE;
        for(i = 0; i< 14; i+=2)
        {
                bRev = FALSE;
                a5f = aBase[i] / 5;
                a1f = aBase[i] % 5;
                b5f = aBase[i+1] / 5;
                b1f = aBase[i+1] % 5;
                if(a5f == b5f)
                {
                        bRev = TRUE;
                        a1f = (a1f==4)?0:a1f+1;
                        b1f = (b1f==4)?0:b1f+1;
                }
                else
                {
                        if(a1f == b1f)
                        {
                                a5f = (a5f==4)?0:a5f+1;
                                b5f = (b5f==4)?0:b5f+1;
                        }
                }

                aReg1 = a5f*5+b1f;
                aReg2 = b5f*5+a1f;

                aReg1 = buf[aReg1];
                aReg2 = buf[aReg2];

                if(bRev)
                {
                        if(aReg2 == 'J')
                                bInvalid = FALSE;
                        printf("%c%c", aReg2, aReg1);
                }
                else
                {
                        if(aReg1 == 'J')
                                bInvalid = FALSE;
                        printf("%c%c", aReg1, aReg2);
                }
        }
        printf("\n");
        if(FALSE == bInvalid)
                printf("因为J处于注册码中的非法位置(位于奇数位), 无注册码\n");
        return ;
}
2007-1-8 08:56
0
游客
登录 | 注册 方可回帖
返回
//