http://www.fiveking.com/bbs
#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include <stdlib.h>
#include "Algorithm.h"
using namespace std;
BYTE GamesEncryptionTable[264]; //游戏加密表
DWORD EncryptionData[16]; //全局加密函数
BYTE PacketKey[64]; //两个封包合并结果
BYTE PseudoKey[15]; //最终得到的伪Key
void UniversalEncryption(DWORD EncryptionVaule[16]); //通用加密CALL
void EncryptionTable(int sSize,BYTE *sData); //加密表
void CalcEncryptionTable(BYTE PseudoKey[15]); //计算加密表
bool CalcKeyPart1(char *UserName,char *PassWord,BYTE RecvPacketKey[64]); //通过接收到的封包,组成Key1
bool CalcPseudoKey(char *UserName,BYTE KeyPart1[64],BYTE RecvPacketKey2[15]); //接收Key2,然后算出最后的伪Key
int main(int argc, char* argv[])
{
//模拟接收到的两个封包:
BYTE PacketData1[]={0x32,0x00,0x00,0x00,0x86,0x5A,0x54,0x47,0x44,0xBA,0xF9,0x16,0xFC,0xE9,0x73,0x49};
BYTE PacketData2[]={0xFA,0x47,0xC7,0x15,0x4A,0x43,0x87,0x7B,0xBD,0xE3,0x52,0x31,0xAE,0x44,0xF3,0xC0};
BYTE PacketKey[64];
memset(PacketKey,0,sizeof(PacketKey));
memcpy(PacketKey,(void *)PacketData1,sizeof(PacketData1));
PacketKey[16]=0x80; //结束符号
PacketKey[56]=16*0x8;
PacketKey[57]=2;
if (!CalcKeyPart1(用户名,密码,PacketKey)) //开始算伪Key的第一部分
cout<<"CalcKeyPart1 Failed"<<endl;
cout<<PacketKey;
if (!CalcPseudoKey(用户名,PacketKey,PacketData2)) //合并数据+计算出伪Key
cout<<"CalcPseudoKey Failed"<<endl;
CalcEncryptionTable(PseudoKey); //利用伪Key加密Key表
cout<<GamesEncryptionTable;
return 0;
}
bool CalcKeyPart1(char *UserName,char *PassWord,BYTE RecvPacketKey[64])
{
if (RecvPacketKey[0]==0) return false;
//初始化变量
BYTE SNOne[64];
BYTE SNThree[64];
BYTE SNTwo[64];
BYTE SNFour[64];
BYTE SNFive[64];
DWORD FilterResult[4]; //过滤掉结果数据
DWORD InitVaule[6]; //初始化Key
DWORD dwTemp[6]; //复制Key,当临时变量使用
BYTE OperationalVaule[64]; //加密数据的数组 长度64位
int i=0;
memset(InitVaule,0,sizeof(InitVaule));
InitVaule[2]=0x67452301; //初始化Key
InitVaule[3]=0xEFCDAB89;
InitVaule[4]=0x98BADCFE;
InitVaule[5]=0x10325476;
//数组清0:
memset(dwTemp,0,sizeof(dwTemp));
memset(EncryptionData,0,sizeof(EncryptionData));
memset(OperationalVaule,0,sizeof(OperationalVaule));
//开工:
memcpy(dwTemp,(void *)InitVaule,sizeof(InitVaule)); //复制初始化Key
CAlgorithm::CalcAccountInfo(UserName,PassWord,OperationalVaule); //通过用户名、密码,合成加密Key
memcpy(EncryptionData,(void *)OperationalVaule,sizeof(OperationalVaule)); // 复制帐户信息
UniversalEncryption(dwTemp); //通用加密CALL(参数为初始化值,加密Key已经复制到EncryptionData)
//数组清0:
memset(FilterResult,0,sizeof(FilterResult));
memset(SNOne,0,sizeof(SNOne));
memset(SNThree,0,sizeof(SNThree));
//分别复制到SNOne和SNThree;
memcpy(FilterResult,(void *)(dwTemp+2),sizeof(dwTemp)-2);
memcpy(SNOne,(void *)FilterResult,sizeof(FilterResult));
memcpy(SNThree,(void *)FilterResult,sizeof(FilterResult));
while (SNOne!=0) //计算出SNOne长度,遂位与0x36或异
{
SNOne^=0x36;
i++;
}
i=0; //计算出SNThree长度,遂位与0x5c或异
while(SNThree!=0)
{
SNThree^=0x5C;
i++;
}
//数组清0:
memset(EncryptionData,0,sizeof(EncryptionData));
memset(dwTemp,0,sizeof(dwTemp));
memset(FilterResult,0,sizeof(FilterResult));
memset(SNTwo,0,sizeof(SNTwo));
memset(SNFour,0,sizeof(SNFour));
//计算出SNTwo:
CAlgorithm::FillEncryptionData(SNOne,0x36); //以0x36填充空白的位置
memcpy(EncryptionData,(void *)SNOne,sizeof(SNOne)); //复制到加密数据,开始加密
memcpy(dwTemp,(void *)InitVaule,sizeof(InitVaule)); //复制初始化Key
UniversalEncryption(dwTemp); //通用加密CALL(参数为初始化值,加密Key已经复制到EncryptionData)
//过滤结果后把结果复制到SNTwo:
memcpy(FilterResult,(void *)(dwTemp+2),sizeof(dwTemp)-2);
memcpy(SNTwo,(void *)FilterResult,sizeof(FilterResult));
//计算出SNFour;
CAlgorithm::FillEncryptionData(SNThree,0x5C); //以0x5C填充空白的位置
memset(EncryptionData,0,sizeof(EncryptionData));
memset(dwTemp,0,sizeof(dwTemp));
memset(FilterResult,0,sizeof(FilterResult));
memset(SNFive,0,sizeof(SNFive));
memcpy(EncryptionData,(void *)SNThree,sizeof(SNThree)); //复制到加密数据,开始加密
memcpy(dwTemp,(void *)InitVaule,sizeof(InitVaule)); //复制初始化Key
UniversalEncryption(dwTemp);
//过滤结果后把结果复制到SNFour
memcpy(FilterResult,(void *)(dwTemp+2),sizeof(dwTemp)-2);
memcpy(SNFour,(void *)FilterResult,sizeof(FilterResult));
//把SNTwo作为加密数据,复制到dwTemp
memset(EncryptionData,0,sizeof(EncryptionData));
memcpy(EncryptionData,(void *)RecvPacketKey,64); //复制接收到封包1为加密Key
memcpy(dwTemp+2,(void *)SNTwo,16); //取SNTwo作加密数据
UniversalEncryption(dwTemp); //加密
//过滤结果后把结果复制到SNFive
memcpy(FilterResult,(void *)(dwTemp+2),sizeof(dwTemp)-2);
memcpy(SNFive,(void *)FilterResult,sizeof(FilterResult));
i=0;
while (SNFive!=0)
i++;
SNFive[i++]=0x80;
SNFive[56]=(i-1)*0x8;
SNFive[57]=2;
memset(EncryptionData,0,sizeof(EncryptionData));
memcpy(EncryptionData,(void *)SNFive,sizeof(SNFive)); //把SNFive作为加密Key
memcpy(dwTemp+2,(void *)SNFour,16); //SNFour作为加密数据
UniversalEncryption(dwTemp); //加密
memcpy(FilterResult,(void *)(dwTemp+2),sizeof(dwTemp)-2);
memset(RecvPacketKey,0,sizeof(RecvPacketKey));
memcpy(RecvPacketKey,(void *)(FilterResult),16);
return true;
}
bool CalcPseudoKey(char *UserName,BYTE KeyPart1[64],BYTE RecvPacketKey2[15])
{
if (KeyPart1[0]==0) return false;
DWORD InitVaule[6];
BYTE dwTemp[64]; //临时作加密Key
memset(PseudoKey,0,sizeof(PseudoKey));
memset(InitVaule,0,sizeof(InitVaule));
memset(dwTemp,0,sizeof(dwTemp));
InitVaule[2]=0x67452301; //初始化Key
InitVaule[3]=0xEFCDAB89;
InitVaule[4]=0x98BADCFE;
InitVaule[5]=0x10325476;
int len=0;
while (UserName[len]!='\0')
len++;
memcpy(dwTemp,(void *)UserName,len);
for (int i=0;i<len;i++)
dwTemp^=0x36;
CAlgorithm::FillEncryptionData(dwTemp,0x36); //填充0x36
memset(EncryptionData,0,sizeof(EncryptionData));
memcpy(EncryptionData,(void *)dwTemp,sizeof(dwTemp));
UniversalEncryption(InitVaule);
memcpy(KeyPart1+16,(void *)RecvPacketKey2,16);
KeyPart1[32]=0x80;
KeyPart1[56]=0;
KeyPart1[57]=0x3;
memset(EncryptionData,0,sizeof(EncryptionData));
memcpy(EncryptionData,(void *)KeyPart1,64);
UniversalEncryption(InitVaule);
memcpy(PseudoKey,(void *)(InitVaule+2),sizeof(InitVaule)-2);
return true;
}
void CalcEncryptionTable(BYTE PseudoKey[15])
{
//BYTE PseudoKey[15]; //接受的伪Key,16位
//与伪Key计算得出的Key
//初始化GamesEncryptionTable;
GamesEncryptionTable[0]=0xC4;
GamesEncryptionTable[1]=0x4D;
GamesEncryptionTable[2]=0x89;
GamesEncryptionTable[3]=0x00;
GamesEncryptionTable[4]=0x02;
GamesEncryptionTable[5]=0x00;
GamesEncryptionTable[6]=0x00;
GamesEncryptionTable[7]=0x00;
//从第九位开始,直到计算完毕,256位:
for (int i=0;i<256;i++)
GamesEncryptionTable[i+0x8]=i;
BYTE *EncryptionAddress=GamesEncryptionTable+0x8; //指向指针第八位地址
int PKeyLength=0; //指向伪Key的偏移量
BYTE bResult=0; //计算结果
BYTE bTemp=0;
for (int ioffset=0;ioffset<256;ioffset++)
{
PKeyLength=ioffset%16; //用伪Key长度除以GamesEncryptionTable长度,取余数
bResult=PseudoKey[PKeyLength] + //伪Key+偏移量的值 加上
*(BYTE *)EncryptionAddress + //GamesEncryptionTable的值 加上
bResult; //上次计算的结果
bTemp=*EncryptionAddress; //取原来GamesEncryptionTable的值
*EncryptionAddress++; //指针自加
*(EncryptionAddress-1)=GamesEncryptionTable[bResult+0x8]; //指针-1的值等于GamesEncryptionTable+计算结果+8
GamesEncryptionTable[bResult+0x8]=bTemp; //写入原来取值的地方
}
}
void CAlgorithm::CalcAccountInfo(char *UserName,char *PassWord,BYTE AccountInfo[64])
{
int i=0;
int x=0;
int len=0;
int len2=0;
memset(AccountInfo,0,sizeof(AccountInfo));
//计算用户名长度:
while (UserName[len]!='\0')
len++;
//写入数组:
for (i=0;i<len;i++)
AccountInfo=UserName;
//计算密码长度:
while (PassWord[len2]!='\0')
len2++;
//继续写入数组:
for (x=0;x<len2;x++)
{
AccountInfo=PassWord[x];
i++;
}
//用户名、密码以0x80结果:
AccountInfo[i++]=0x80;
AccountInfo[56]=len*0x8+len2*0x8;
//数组的第57位=用户名长度*8+密码长度*8:
}
void CAlgorithm::FillEncryptionData(BYTE bData[64],BYTE Key)
{
int nLen=0;
while (bData[nLen]!=0)
nLen++;
for (int i=nLen;i<64;i++)
bData=Key;
}
待续