逆向序列号生成算法(二)

接上次的,将序列号的验证算法流程及代码都整理出来了,最后弄成了三个小函数,为了更加方面阅读,理解验证算法的原理,进而为序列号生成算法的设计做铺垫,这里,我们将上次代码中的汇编部分,都逆向成C/C++来表述。

    首先是计算部分的Step1: 

void CalculateKeyStep1( const char *pStrName, const char *pStrSerialNum, 
                        DWORD &outTempNum1, DWORD &outTempNum2 )
{
    assert( NULL != pStrName );
    assert( NULL != pStrSerialNum );
    if ( NULL == pStrName || NULL == pStrSerialNum )
        return;


    outTempNum1 =  *(DWORD*)pStrName;
    outTempNum2 = *(DWORD*)(pStrName+4);
    DWORD nSerialTemp1 = *(DWORD*)pStrSerialNum;
    DWORD nSerialTemp2 = *(DWORD*)(pStrSerialNum+4);


    outTempNum1 ^= nSerialTemp1;
    outTempNum2 ^= nSerialTemp2;


    outTempNum1 &= 0x7F3F1F0F; //0111 1111-0011 1111-0001 1111-0000 1111
                               //x31=0,x23=0,x15=0,x7=0
    outTempNum2 &= 0x07030100; //0111 0000-0011 0000-0001 0000-0000 0000
                               //x31=0,x23=0,x15=0,x7=0


    for (int idx=0; idx<8; ++idx)
    {
        std::bitset<32>  vBtsEAX( outTempNum1<<idx );
        std::bitset<32>  vBtsEBX( outTempNum2<<idx );
        std::bitset<32>  vBtsR(0);
        vBtsR[7] = vBtsEAX[31];
        vBtsR[6] = vBtsEAX[23];
        vBtsR[5] = vBtsEAX[15];
        vBtsR[4] = vBtsEAX[7];
        vBtsR[3] = vBtsEBX[31];
        vBtsR[2] = vBtsEBX[23];
        vBtsR[1] = vBtsEBX[15];
        vBtsR[0] = vBtsEBX[7];
        int nValue = vBtsR.to_ulong();
        if (idx <= 3)
        {
            nValue <<= 8*(3-idx);
            outTempNum1 ^= nValue;
        }
        else
        {
            nValue <<= 8*(7-idx);
            outTempNum2 ^=nValue;
        }
    }
}
接着就是最后一个验证步骤Step2,由于验证步骤里面有一个递归调用,故此,Step2拆分成两个函数,如下:
void Func( DWORD nTempNum1, DWORD nTempNum2, 
           UINT &uCount, DWORD &nMagicNum )
{
    if ( uCount <= 0x80 ) return;
    UINT uTMCount = uCount;
    DWORD nValue = nTempNum1;
    uCount &= 0xff;       //取最低一个字节,根据下面程序的执行
    if ( uCount > 8 )     //其实为取CL的低四位.
    {
        nValue = nTempNum2;
        uCount >>= 4;     //取CL高4位.
    }
    
    //nValue为DWORD,占4个字节,如下图示:
    //|---|---|---|---|
    //| 1 | 2 | 3 | 4 |
    //|___|___|___|___|
    //
    UINT uRotateCount = (UINT)(log((float)uCount)/log(2.0f));
    switch( uRotateCount%4 )
    {
    case 1:
        nValue >>= 16; //|---|
        break;         //| 2 |
                       //|___|
    case 2:
        nValue >>= 8;  //|---|
        break;         //| 3 |
                       //|___|
    case 3:
        break;         //|---|
                       //| 4 |
                       //|___|
    default:
        nValue >>= 24; //|---|
        break;         //| 1 |
                       //|___|
    }
    uCount = (uTMCount&0xff00)>>8;
    nValue &=uCount;
    uCount = 0x80;
    while ( uCount&nValue ? 1:uCount>>=1 )
    {
        if ( !(uCount&nValue) ) continue;
        nValue ^= uCount;
        uCount ^= ((uCount&0xff)<<8);
        uTMCount &= 0xff00;
        uTMCount ^= uCount;
        ++nMagicNum;
        Func( nTempNum1, nTempNum2, uTMCount, nMagicNum );
        uCount = 0x80;
    }
    uCount = uTMCount; //In order to retrieve the return value
}
bool CalculateKeyStep2( const DWORD nTempNum1, const DWORD nTempNum2, 
                        const char *pStrName, const char *pStrSerialNum )
{
    DWORD nMagicNum = 0xfedcba98;
    UINT  uCount = 0xff01;
    Func( nTempNum1, nTempNum2, uCount,nMagicNum );
    if ( 1 == uCount )
    {
        nTempNum1 = *(DWORD*)(pStrName+8);
        nTempNum2 = *(DWORD*)(pStrName+ 0xc);
        nTempNum1 ^= nTempNum2; 
        nTempNum1 ^= nMagicNum;
        nTempNum1 |= 0x40404040;
        nTempNum1 &= 0x77777777;
        nTempNum1 ^= *(DWORD*)(pStrSerialNum+8);
        nTempNum1 ^= *(DWORD*)(pStrSerialNum+0xc);
        if ( 0 == nTempNum1 )
            return true;
    }

    return false;
}
至此,将汇编代表都转成了C/C++语言的形式,但是依然不是很好阅读,需要进一步做调整。To be continued......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值