#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;
}
待續