首页
社区
课程
招聘
[讨论]第三题分析
发表于: 2010-10-24 12:08 7661

[讨论]第三题分析

2010-10-24 12:08
7661

很郁闷。。。
这是我处女KEYGEN,原本想的挺简单,谁知道弄了我一个晚上,伤心吖。。。 评委组有同情分没?
代码如下:
哈希算法,注册算法,都没什么问题,就是逆回去的时候发现 根本对应不到用户名与注册码。这个程序是把ABCDEFGHJKMNPQRSTVWXYZ1234567890 32个字符的位置对应到一章表(256个字节)上 然后取注册码的字符然后用这个字符做索引在这个表里查询,由于有效就有34个,(算上了0xFF + '='号), 后面有个计算的路径,不过最多的组合就是34 * 34 种算子的组合。 里面各有两个运算, 单个字节是256 ,这样有很大的几率对应不上。
也不多说了。。我把代码贴这里,希望KEYGEN高手可以帮我解答一下。。。 向你们学习。


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

收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 179
活跃值: (26)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
哈哈,玩命阴沟里翻船了 这个是BASE32编码
2010-10-24 12:42
0
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
3
小伙子体力不错啊
2010-10-24 12:42
0
雪    币: 179
活跃值: (26)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
就是将所有数据看做一串二进制码,然后5位5位的取,每取五位在前面补3个0形成一个字节。

再用形成的这个字节查表,因为这个字节最大值为32,所以表的大小也就是32。
就是ABCDEFGHJKMNPQRSTVWXYZ1234567890

这样生成的数据会比原数据增加五分之三,20字节就刚好生成了32字节的数据。
2010-10-24 12:47
0
雪    币: 1115
活跃值: (122)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
其实不需要汇编代码的
SHA1 直接用openssl库就行了

#include <openssl/sha.h>

#pragma comment (lib,"libeay32.lib")

#define SWAPDWORD(x) (((x)<<24) | (((x)<<8)&0x00FF0000) | (((x)>>8) & 0x0000FF00) | ((x)>>24))

void GetHash(const char* pszUserName, BYTE* pHash)
{
        DWORD dwVolumeSerialNumber = 0;
        GetVolumeInformation("c:\\", NULL, 0, &dwVolumeSerialNumber, NULL, NULL, NULL, 0);
       
        int nLen = strlen(pszUserName);
        BYTE* pData = new BYTE[nLen + 16];
        memcpy(pData, pszUserName, nLen);
        memcpy(pData+nLen, &dwVolumeSerialNumber, 4);
        memcpy(pData+nLen+4, "Tencent", 7);
       
       
        SHA_CTX c;
        unsigned long h[] = {
                        0xB1CAB1CA,
                        0xCCBFCCBF,
                        0xBFB2D6BE,
                        0xF8C7D8B5,
                        0xEEC7BCCD};
               
        unsigned char byte_40CD50[0x80] = {0};
        byte_40CD50[0] = byte_40CD50[0x48] = 0x80;
        byte_40CD50[0x40] = 0x3d;
       
       
        SHA1_Init(&c);
        c.h0 = h[0];
        c.h1 = h[1];
        c.h2 = h[2];
        c.h3 = h[3];
        c.h4 = h[4];
       
        SHA1_Update(&c, pData, nLen+4+7);
       
        delete[] pData;
        pData = NULL;
       
        DWORD xlen[2];
        xlen[0] = SWAPDWORD(c.Nh);
        xlen[1] = SWAPDWORD(c.Nl);
       
        int n1 = (c.Nl >> 3) & 0x3F;
        int n2 = 56;
        if ( (unsigned int)n1 >= 0x38 )
                n2 = 120;
       
        SHA1_Update(&c, byte_40CD50, n2-n1);
        SHA1_Update(&c, xlen, 8);
       
        DWORD* hash = (DWORD*)pHash;
        hash[0] = SWAPDWORD(c.h0);
        hash[1] = SWAPDWORD(c.h1);
        hash[2] = SWAPDWORD(c.h2);
        hash[3] = SWAPDWORD(c.h3);
        hash[4] = SWAPDWORD(c.h4);
}

void HashToData(BYTE* pHash, BYTE* pData)
{
        int i;
        int j;
        BYTE bits[20*8];
        for(i=0; i<20; i++)
        {
                for(j=0; j<8; j++)
                {
                        bits[i*8+7-j] = (pHash[i]>>j)&1;
                }
        }

        for(i=0; i<32; i++)
        {
                for(j=0; j<5; j++)
                {
                        pData[i] |= bits[i*5+j] << (4-j);
                }
        }
}

void DataToCode(BYTE* pData, char* pszCode)
{
        char* pstr = "ABCDEFGHJKMNPQRSTVWXYZ1234567890";
        int i;
        for(i=0; i<32; i++)
        {
                pszCode[i] = pstr[pData[i]];
        }
}

void Keygen(const char* pszUserName, char* pszLicenseCode)
{
        BYTE cbHash[20];
        BYTE cbData[32];
        GetHash(pszUserName, cbHash);

        memset(cbData, 0, sizeof(cbData));
        HashToData(cbHash, cbData);

        char szCode[64] = {0};
        DataToCode(cbData, szCode);

        pszLicenseCode[8] = pszLicenseCode[0x11] = pszLicenseCode[0x1a] = '-';
        memcpy(pszLicenseCode, szCode, 8);
        memcpy(pszLicenseCode+9, szCode+8, 8);
        memcpy(pszLicenseCode+0x12, szCode+16, 8);
        memcpy(pszLicenseCode+0x1b, szCode+24, 8);
}

void CKeygenDlg::OnGen()
{
        CString sUserName;
        GetDlgItemText(IDC_EDIT_USERNAME, sUserName);
        if(sUserName.IsEmpty())
        {
                SetDlgItemText(IDC_EDIT_LIC_CODE, NULL);
                GetDlgItem(IDC_EDIT_USERNAME)->SetFocus();
                return;
        }

        char szLicenseCode[128];
        memset(szLicenseCode, 0, sizeof(szLicenseCode));
        Keygen(sUserName, szLicenseCode);

        SetDlgItemText(IDC_EDIT_LIC_CODE, szLicenseCode);
}
2010-10-25 16:48
0
雪    币: 7115
活跃值: (639)
能力值: (RANK:1290 )
在线值:
发帖
回帖
粉丝
6
没看那么多东西, 直接放到OD里调的。 经验不足,准备以后每周一个KEYGENME 练习。。。
2010-10-25 17:49
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
顶礼膜拜玩命大神
2010-10-25 18:50
0
游客
登录 | 注册 方可回帖
返回
//