我正在尝试确定某些许可机制使用的解密方案。我花了一些时间才意识到这是加密,这是我的另一个问题的某种跟进:从验证算法创建密钥生成器算法
我做了一些功课,在我看来,这个解密的关键特征如下:
1-首先对输入进行 base64 解码(使用一些非标准密钥表,但算法完全相同)
2-使用与输入长度相同的密钥对其进行解密。这可能是一次性的,或者只是用于非常短数据的非常长的密钥(都是 512 位)
3-最重要的是,让我感到困惑的是解密算法使用 NO xor。我见过的每个密码都在解密的某个时刻使用 XOR,但这里根本没有。
第3点是我在这里真的不明白。我看不到如何生成无需 XOR 即可解密的数据。在此过程中,使用位移位和 AND/OR 掩码似乎会丢失很多信息。
是否有任何已知的密码匹配这些特征?
编辑 :
好的,这里是对算法的更深入的描述:
有一个函数被多次调用。它首先使用数据和解密密钥创建 2 个表。第二个是在第一个的基础上。
此函数首先使用数据创建一个表,然后使用另一个表中的解密密钥处理该数据。
从数据创建的表是通过从数据中处理每个 32 位块(主块)与整个数据加上加法来制作的,以便它unsigned int
为 16 个 32 位块中的每一个生成一个。对此的呼吁看起来像这样
hash_block(&result1, &result2, current_master_block, data_array[i]);
hash_block 看起来像这样:
void hash_block(int *result1, int *result2, unsigned int pMaster_block, unsigned int pCurrent_block)
{
int current_block;
unsigned int current_high_short;
int master_high_times_master;
unsigned int master_high_master_short;
int master_high_times_current;
unsigned int sum_of_mixes;
current_block = (unsigned __int16)pCurrent_block;
current_high_short = pCurrent_block >> 16;
master_high_times_master = HIWORD(pCurrent_block) * (unsigned __int16)pMaster_block;
master_high_master_short = pMaster_block >> 16;
*(_DWORD *)result1 = current_block * (unsigned __int16)pMaster_block;
master_high_times_current = current_block * HIWORD(pMaster_block);
sum_of_mixes = master_high_times_current + master_high_times_master;
*(_DWORD *)(result2) = (unsigned __int16)current_high_short * (unsigned __int16)master_high_master_short;
if ( master_high_times_current > sum_of_mixes )
*(_DWORD *)(result2) += 65536;
*(_DWORD *)result1 += sum_of_mixes << 16;
if ( sum_of_mixes << 16 > *(_DWORD *)result1 )
++*(_DWORD *)(result2);
*(_DWORD *)(result2) += sum_of_mixes >> 16;
}
我目前正在清理代码,我将跟进有关算法第二部分如何工作的更多信息
编辑 2:
还有一个非常复杂的函数,我无法理解在这个函数中运行了 248 次:
void __fastcall sub_4D5AC0(int* result, int* serial_copy, unsigned int last_keyitem)
{
unsigned int v3; // edi@1
unsigned int v4; // edi@2
int v5; // eax@4
int v6; // eax@7
unsigned int v7; // eax@11
//int return_value; // ecx@25
int* v10; // [sp+0h] [bp-24h]@1
unsigned int v11; // [sp+4h] [bp-20h]@4
int v12; // [sp+4h] [bp-20h]@16
unsigned __int64 v13; // [sp+4h] [bp-20h]@18
int v14; // [sp+8h] [bp-1Ch]@1
unsigned int v15; // [sp+8h] [bp-1Ch]@6
unsigned int v16; // [sp+10h] [bp-14h]@16
v3 = *(serial_copy + 1);
v14 = *(serial_copy + 1);
if ( HIWORD(last_keyitem) == -1 )
v4 = v3 >> 16;
else
v4 = v3 / ((unsigned int)HIWORD(last_keyitem) + 1);
v5 = (unsigned __int16)last_keyitem * (unsigned __int16)v4 << 16;
v11 = *serial_copy - v5;
//if ( -1 - v5 < v11 )
if ( ~v5 < v11 )
--v14;
v15 = v14 - ((unsigned __int16)last_keyitem * (unsigned int)(unsigned __int16)v4 >> 16) - HIWORD(last_keyitem) * (unsigned __int16)v4;
while ( 1 )
{
if ( HIWORD(last_keyitem) >= v15 )
{
v7 = HIWORD(last_keyitem);
if ( HIWORD(last_keyitem) != v15 )
break;
v7 = (unsigned __int16)last_keyitem << 16;
if ( v7 > v11 )
break;
}
v6 = (unsigned __int16)last_keyitem << 16;
v11 -= v6;
if ( -1 - v6 < v11 )
--v15;
v15 -= HIWORD(last_keyitem);
++v4;
}
if ( HIWORD(last_keyitem) == -1 ){
//LOWORD(v7) = v15;
v7 &= 0xFFFF0000;
v7 |= v15 & 0xFFFF;
}else{
v7 = ((v11 >> 16) + (v15 << 16)) / ((unsigned int)HIWORD(last_keyitem) + 1);
}
v16 = HIWORD(last_keyitem) * (unsigned __int16)v7;
v12 = v11 - (unsigned __int16)last_keyitem * (unsigned __int16)v7;
if ( v12 > -1 - (unsigned __int16)last_keyitem * (unsigned int)(unsigned __int16)v7 )
--v15;
//LODWORD(v13) = v12 - (v16 << 16);
v13 &= 0xFFFFFFFF00000000;
v13 |= (v12 - (v16 << 16)) & 0xFFFFFFFF;
if ( -1 - (v16 << 16) < (unsigned int)v13 )
--v15;
// HIDWORD
v13 &= 0x00000000FFFFFFFF;
v13 |= (v15 - (v16 >> 16)) & 0xFFFFFFFF00000000;
while ( last_keyitem <= v13 )
{
v13 &= 0xFFFF0000;
v13 |= (v13 - last_keyitem) & 0xFFFF;
//LODWORD(v13) = v13 - a3;
v13 = (v13 - last_keyitem) & 0xFFFF;
if ( (unsigned int)v13 > -1 - last_keyitem ){
//--HIDWORD(v13);
unsigned __int64 high_word = v13 & 0xFFFFFFFF00000000;
high_word++;
v13 &= 0x00000000FFFFFFFF;
v13 |= high_word;
}
++v7;
}
*result = (unsigned __int16)v7 + ((unsigned __int16)v4 << 16);
}