首页
社区
课程
招聘
[原创]第一阶段 第三题 keygen分析
发表于: 2010-10-24 12:05 6650

[原创]第一阶段 第三题 keygen分析

2010-10-24 12:05
6650

这个KeygenMe的验证过程主要就是:利用username计算出一个20字节的数据,然后利用lic的32字节的数据同样计算出一个20字节的数据,如果相同,那么就成功。
利用username计算出20字节的过程是一个正向的过程,直接剥代码就搞定,这道题目的关键就是怎样利用username计算出的20字节的数据推出lic,因为lic有32字节的数据。表明上看来这是一个不可能的事情,因为20字节到32字节是一个扩充的过程,可是只要仔细分析lic把32字节压缩成20字节的过程,这个逆向过程其实是很简单的。
由于username的组成限定了只能在“ABCDEFGHJKMNPQRSTVWXYZ1234567890”这32个中选择,然后根据查表得出值,这个值才是验证计算过程需要使用的数据。
这里需要特别注意一点,这个值最大不超过32,也就是最大值是5位。这就是这个压缩过程的关键所在。一个字节有8位,用8位来存储5位的值,有3位是空闲的,这个压缩过程就是将这空闲的3位全部利用起来。20/32正好等于5/8,这就是最好的证明。实际上这个压缩过程是没有任何数据损失的!!!
仔细分析lic压缩的过程,实际上就是一个精心构造的过程,把所有的空闲3字节都填上数据。下表就是利用5个字节存储8个字节的构造(注意,这8字节的数据每个值都不超过32),整个20字节就是将这个过程重复4次。表中每个单元格表示压缩后数组的一位。
1      2       3      4      5       6      7       8
(1-1        1-2        1-3        1-4        1-5)        (2-1        2-2        2-3     第1字节
2-4        2-5)        (3-1        3-2        3-3        3-4        3-5)        (4-1    第2字节
4-2        4-3        4-4        4-5)        (5-1        5-2        5-3        5-4    第3字节
5-5)        (6-1        6-2        6-3        6-4        6-5)        (7-1        7-2    第4字节
7-3        7-4        7-5)        (8-1        8-2        8-3        8-4        8-5)   第5字节

注:1-1表示原始数据的第一个值的第一位。
只要了解了这个压缩过程,逆向过程就很好写出来了。只要逐字节额的拼凑,就可以利用20字节拼出所需要的32字节了,也就是需要计算出来的lic。!!!


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 334
活跃值: (151)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
一种BASE32加密法
2010-10-24 12:07
0
雪    币: 7115
活跃值: (639)
能力值: (RANK:1290 )
在线值:
发帖
回帖
粉丝
3
哥们发个答案吧。。。  我真想知道怎么弄的。。
2010-10-24 12:13
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
5 - 8 反向的扩充时候那三位  填0 ?
2010-10-24 12:24
0
雪    币: 12
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
恩   是得   头三位填0
2010-10-24 12:32
0
雪    币: 179
活跃值: (26)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
好像好多人都死在这个BASE32编码算法上了

char *Base32(char *sha1,char *code,int len)
{
        char base[]={"ABCDEFGHJKMNPQRSTVWXYZ1234567890"};

        int length =(len*8+4)/5;
    char* sb = code;
    int cur_i = 0;
    byte cur_b = 0;
    int index;
    int k;
    for (int i = 0; i < length; i++)
    {
        index = 0;
        for (int j = 0; j < 5; j++)
        {
            k = i * 5 + j;
            if (k == len * 8)
                break;
            if (k % 8 == 0)
                        {
                cur_b = *(BYTE*)(sha1+cur_i);
                                cur_i++;
                        }
            index <<= 1;
            index |= (cur_b & 128) == 0 ? 0 : 1;
            cur_b <<= 1;
        }
                *(BYTE*)(code+i)=base[index];
    }

        return code;
}
2010-10-24 12:35
0
雪    币: 86
活跃值: (56)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
7
实际上看出这段比较代码
00401556  |> /8B32          /mov     esi, dword ptr [edx]
00401558  |. |3B31          |cmp     esi, dword ptr [ecx]
0040155A  |. |75 12         |jnz     short 0040156E
0040155C  |. |83E8 04       |sub     eax, 4
0040155F  |. |83C1 04       |add     ecx, 4
00401562  |. |83C2 04       |add     edx, 4
00401565  |. |83F8 04       |cmp     eax, 4
00401568  |.^\73 EC         \jnb     short 00401556
0040156A  |.  3BC3          cmp     eax, ebx
0040156C  |.  74 5D         je      short 004015CB
0040156E  |>  0FB632        movzx   esi, byte ptr [edx]
00401571  |.  0FB639        movzx   edi, byte ptr [ecx]
00401574  |.  2BF7          sub     esi, edi
00401576  |.  75 45         jnz     short 004015BD
00401578  |.  83E8 01       sub     eax, 1
0040157B  |.  83C1 01       add     ecx, 1
0040157E  |.  83C2 01       add     edx, 1
00401581  |.  3BC3          cmp     eax, ebx

然后硬件断点0012F9D4,找出些这段数据的代码
00407F50   > /83FB 03       cmp     ebx, 3
00407F53   . |8B4424 18     mov     eax, dword ptr [esp+18]
00407F57   . |0FB60C28      movzx   ecx, byte ptr [eax+ebp]
00407F5B   . |8B4424 10     mov     eax, dword ptr [esp+10]
00407F5F   . |8A0401        mov     al, byte ptr [ecx+eax]
00407F62   . |77 10         ja      short 00407F74
00407F64   . |83C3 FD       add     ebx, -3
00407F67   . |83E3 07       and     ebx, 7
00407F6A   . |75 1E         jnz     short 00407F8A
00407F6C   . |08043E        or      byte ptr [esi+edi], al
00407F6F   . |83C6 01       add     esi, 1
00407F72   . |EB 22         jmp     short 00407F96
00407F74   > |83C3 FD       add     ebx, -3
00407F77   . |83E3 07       and     ebx, 7
00407F7A   . |8AD0          mov     dl, al
00407F7C   . |8ACB          mov     cl, bl
00407F7E   . |D2EA          shr     dl, cl
00407F80   . |08143E        or      byte ptr [esi+edi], dl
00407F83   . |8B5424 1C     mov     edx, dword ptr [esp+1C]
00407F87   . |83C6 01       add     esi, 1
00407F8A   > |B9 08000000   mov     ecx, 8
00407F8F   . |2BCB          sub     ecx, ebx
00407F91   . |D2E0          shl     al, cl
00407F93   . |08043E        or      byte ptr [esi+edi], al
00407F96   > |83C5 01       add     ebp, 1
00407F99   . |3BEA          cmp     ebp, edx
00407F9B   .^\7C B3         jl      short 00407F50

到这就看出怎么回事了。。。不过懒得写注册机了,要抠代码。。。
2010-10-24 13:51
0
游客
登录 | 注册 方可回帖
返回
//