[C] 纯文本查看 复制代码 char __stdcall DoEncrypt(void *dataSrc, int lenth, int cookie, int key, int result)
{
int v6; // [esp+8h] [ebp-18h]
unsigned __int16 *v7; // [esp+Ch] [ebp-14h]
int i; // [esp+14h] [ebp-Ch]
int j; // [esp+14h] [ebp-Ch]
int k; // [esp+14h] [ebp-Ch]
char v11; // [esp+18h] [ebp-8h]
unsigned __int8 v12; // [esp+18h] [ebp-8h]
unsigned int v13; // [esp+1Ch] [ebp-4h]
int newLenth; // [esp+38h] [ebp+18h]
unsigned __int16 *v15; // [esp+38h] [ebp+18h]
// 明文数组不能为空且长度不能过大
if ( *(int *)lenth < 0 || *(int *)lenth >= 4098 )
return 0;
// 密文数组第一个字节保留用途,从下标1位置开始存储明文数组,密文长度就是 len(明文)+1
memcpy((void *)(result + 1), dataSrc, *(_DWORD *)lenth);
newLenth = result + 1;
v11 = 0;
// 计算明文数组元素的和
for ( i = 0; i < *(_DWORD *)lenth; ++i )
v11 += *(_BYTE *)(i + newLenth); // total += src[i];
// v15 = &dst[0]; 密文起始地址
v15 = (unsigned __int16 *)(newLenth - 1);
// 更新参数中的密文长度
++*(_DWORD *)lenth;
// dst[0] = -total; 密文第一个字节,现阶段存放后续明文的校验和
*(_BYTE *)v15 = -v11;
// 数组每一个元素与查表byte_100060D0数组中的元素进行异或操作, dst[i] ^= byte_100060D0[key]; key += 3;
v12 = *(_BYTE *)key;
for ( j = 0; j < *(_DWORD *)lenth; ++j )
{
*((_BYTE *)v15 + j) ^= byte_100060D0[v12];
v12 += 3;
}
// 更新查表的下标,应该是用于下一次加密或解密
*(_BYTE *)key = v12;
v6 = (*(_DWORD *)lenth + 3) / 4; // 计算 模4的值,用于最后四字节加密的循环次数
v7 = v15;
v13 = *(_DWORD *)cookie;
// 4字节为单位,进行最后一步加密
for ( k = 0; k < v6; ++k )
{
// 因为v15是short指针, 所以*2 每次对齐4字节, 相当于 dst[i] ^= cookie;
*(_DWORD *)&v15[2 * k] ^= v13;
// 更新密钥,这个过程不知道咋设计的,数学匮乏~ 伪代码: cookie = ((x * (dst[i+1]+0x2D08EF))&0xFFFF0000 | (0x4242D * dst[i] + 0x2D08EF))0x0000FFFF) ^ 0xD77DD77D; dst++; 这里dst默认int格式数组,过程是数组的两个元素,一通运算之后异或一个值
v13 = (((271405 * (unsigned int)v7[1] + 2951407) >> 16 << 16) | ((271405 * (unsigned int)*v7 + 2951407) >> 16)) ^ 0xD77DD77D;
v7 += 2;
}
// 把运算过程的密钥值回传给调用者
*(_DWORD *)cookie = v13;
return 1;
}
以下是个人理解
|