I'll be sharing a theory about packet encryption. Note that i used an ep4 game.exe and ps_login.exe.
First lets dissect the first two packets that handle the key exchange:
1. packet:
server->client
Code:
0xc70001a10040803d2ef1183067cbc9cfeed32d53cc295285abd7900eccd0b1dc14cff863df8fc38f013dd87ecee133b70803df93557a8e3696f28a0e40d064604d60f673d631de4961f78b17d85bd6f0728e9c4da20c29bad93653f1f395b6374c1f79c915ac372f04f115581315bd0ca4d8c59fcf537db25b3eefbf78604b9c01cd363d265a1f1a28db2d64bdd095649d43d80f690983d96ab375096786b8d2e458f50a0895c06387ad05e9e2b90e667f16cf59427b0c978feb4cd240a1979d790f73ae1188a1
2byte opcode (0x01a1)
1byte param1 (0x00 size of rsa encrypted message (c) used only in response to the server)
1byte param2 (0x40 size of the rsa public exponent (e) )
1byte param3 (0x80 size of the rsa modulo (n) )
64byte param4 (rsa public exponent (e) )
128byte param5 (rsa modulo (n) )
2. packet
client->server
Code:
850001a180ac417eedabd0a668bd713088898376ec0fc12366b5d67e6d251afb28c8f91588ffefb5bd0d676da5354bf5251e84e8334f9804d4a0122ca76cc60c97799d988b95b2bb45daa8885b71f3862f17ef9574297cd0786b86f9a04060471592259327a17c2fc610a127744b8d0a5a3f4c6542b6c5539bed41ffded205e1f91fba3990
2byte opcode (0x01a1)
1byte param1 (0x80 size of rsa encrypted message (c) )
128byte (rsa encrypted message (c) - encrypted random number )
So as you can guess now the key exchange uses rsa encryption (rsa 1024bit, plain rsa no padding or anything).
For the regular packets the server uses aes(128 bit) ctr mode, the whole iv is a counter(not confirmed).
The rsa encrypted message (c from now on) which the server decrypts contains a random number. The server takes rsa modulo, the random number and does a hmac<sha256> on them. Next it takes first 16 byte of the result as the base aeskey, the remaining 16 byte is the iv. As the next step the server expands the base aeskey (176byte long, lets call it exaeskey). Then the server takes the first aeskey (16byte) from the exaeskey and the server is ready for en/decryption.
So its something like this:
Code:
unkown_data= rsa_dec(c) res=hmac<sha256>(n,random_base) base_aeskey[0..15]=res[0..15] iv[0..15]=res[16..31] exaeskey=aeskex_expand(base_aeskey) aeskey[0..15]=exaeskex[0..15]
Code:
/* Log table using 0xe5 (229) as the generator */
unsigned char ltable[256] = {
0x00, 0xff, 0xc8, 0x08, 0x91, 0x10, 0xd0, 0x36,
0x5a, 0x3e, 0xd8, 0x43, 0x99, 0x77, 0xfe, 0x18,
0x23, 0x20, 0x07, 0x70, 0xa1, 0x6c, 0x0c, 0x7f,
0x62, 0x8b, 0x40, 0x46, 0xc7, 0x4b, 0xe0, 0x0e,
0xeb, 0x16, 0xe8, 0xad, 0xcf, 0xcd, 0x39, 0x53,
0x6a, 0x27, 0x35, 0x93, 0xd4, 0x4e, 0x48, 0xc3,
0x2b, 0x79, 0x54, 0x28, 0x09, 0x78, 0x0f, 0x21,
0x90, 0x87, 0x14, 0x2a, 0xa9, 0x9c, 0xd6, 0x74,
0xb4, 0x7c, 0xde, 0xed, 0xb1, 0x86, 0x76, 0xa4,
0x98, 0xe2, 0x96, 0x8f, 0x02, 0x32, 0x1c, 0xc1,
0x33, 0xee, 0xef, 0x81, 0xfd, 0x30, 0x5c, 0x13,
0x9d, 0x29, 0x17, 0xc4, 0x11, 0x44, 0x8c, 0x80,
0xf3, 0x73, 0x42, 0x1e, 0x1d, 0xb5, 0xf0, 0x12,
0xd1, 0x5b, 0x41, 0xa2, 0xd7, 0x2c, 0xe9, 0xd5,
0x59, 0xcb, 0x50, 0xa8, 0xdc, 0xfc, 0xf2, 0x56,
0x72, 0xa6, 0x65, 0x2f, 0x9f, 0x9b, 0x3d, 0xba,
0x7d, 0xc2, 0x45, 0x82, 0xa7, 0x57, 0xb6, 0xa3,
0x7a, 0x75, 0x4f, 0xae, 0x3f, 0x37, 0x6d, 0x47,
0x61, 0xbe, 0xab, 0xd3, 0x5f, 0xb0, 0x58, 0xaf,
0xca, 0x5e, 0xfa, 0x85, 0xe4, 0x4d, 0x8a, 0x05,
0xfb, 0x60, 0xb7, 0x7b, 0xb8, 0x26, 0x4a, 0x67,
0xc6, 0x1a, 0xf8, 0x69, 0x25, 0xb3, 0xdb, 0xbd,
0x66, 0xdd, 0xf1, 0xd2, 0xdf, 0x03, 0x8d, 0x34,
0xd9, 0x92, 0x0d, 0x63, 0x55, 0xaa, 0x49, 0xec,
0xbc, 0x95, 0x3c, 0x84, 0x0b, 0xf5, 0xe6, 0xe7,
0xe5, 0xac, 0x7e, 0x6e, 0xb9, 0xf9, 0xda, 0x8e,
0x9a, 0xc9, 0x24, 0xe1, 0x0a, 0x15, 0x6b, 0x3a,
0xa0, 0x51, 0xf4, 0xea, 0xb2, 0x97, 0x9e, 0x5d,
0x22, 0x88, 0x94, 0xce, 0x19, 0x01, 0x71, 0x4c,
0xa5, 0xe3, 0xc5, 0x31, 0xbb, 0xcc, 0x1f, 0x2d,
0x3b, 0x52, 0x6f, 0xf6, 0x2e, 0x89, 0xf7, 0xc0,
0x68, 0x1b, 0x64, 0x04, 0x06, 0xbf, 0x83, 0x38 };
/* Anti-log table: */
unsigned char atable[256] = {
0x01, 0xe5, 0x4c, 0xb5, 0xfb, 0x9f, 0xfc, 0x12,
0x03, 0x34, 0xd4, 0xc4, 0x16, 0xba, 0x1f, 0x36,
0x05, 0x5c, 0x67, 0x57, 0x3a, 0xd5, 0x21, 0x5a,
0x0f, 0xe4, 0xa9, 0xf9, 0x4e, 0x64, 0x63, 0xee,
0x11, 0x37, 0xe0, 0x10, 0xd2, 0xac, 0xa5, 0x29,
0x33, 0x59, 0x3b, 0x30, 0x6d, 0xef, 0xf4, 0x7b,
0x55, 0xeb, 0x4d, 0x50, 0xb7, 0x2a, 0x07, 0x8d,
0xff, 0x26, 0xd7, 0xf0, 0xc2, 0x7e, 0x09, 0x8c,
0x1a, 0x6a, 0x62, 0x0b, 0x5d, 0x82, 0x1b, 0x8f,
0x2e, 0xbe, 0xa6, 0x1d, 0xe7, 0x9d, 0x2d, 0x8a,
0x72, 0xd9, 0xf1, 0x27, 0x32, 0xbc, 0x77, 0x85,
0x96, 0x70, 0x08, 0x69, 0x56, 0xdf, 0x99, 0x94,
0xa1, 0x90, 0x18, 0xbb, 0xfa, 0x7a, 0xb0, 0xa7,
0xf8, 0xab, 0x28, 0xd6, 0x15, 0x8e, 0xcb, 0xf2,
0x13, 0xe6, 0x78, 0x61, 0x3f, 0x89, 0x46, 0x0d,
0x35, 0x31, 0x88, 0xa3, 0x41, 0x80, 0xca, 0x17,
0x5f, 0x53, 0x83, 0xfe, 0xc3, 0x9b, 0x45, 0x39,
0xe1, 0xf5, 0x9e, 0x19, 0x5e, 0xb6, 0xcf, 0x4b,
0x38, 0x04, 0xb9, 0x2b, 0xe2, 0xc1, 0x4a, 0xdd,
0x48, 0x0c, 0xd0, 0x7d, 0x3d, 0x58, 0xde, 0x7c,
0xd8, 0x14, 0x6b, 0x87, 0x47, 0xe8, 0x79, 0x84,
0x73, 0x3c, 0xbd, 0x92, 0xc9, 0x23, 0x8b, 0x97,
0x95, 0x44, 0xdc, 0xad, 0x40, 0x65, 0x86, 0xa2,
0xa4, 0xcc, 0x7f, 0xec, 0xc0, 0xaf, 0x91, 0xfd,
0xf7, 0x4f, 0x81, 0x2f, 0x5b, 0xea, 0xa8, 0x1c,
0x02, 0xd1, 0x98, 0x71, 0xed, 0x25, 0xe3, 0x24,
0x06, 0x68, 0xb3, 0x93, 0x2c, 0x6f, 0x3e, 0x6c,
0x0a, 0xb8, 0xce, 0xae, 0x74, 0xb1, 0x42, 0xb4,
0x1e, 0xd3, 0x49, 0xe9, 0x9c, 0xc8, 0xc6, 0xc7,
0x22, 0x6e, 0xdb, 0x20, 0xbf, 0x43, 0x51, 0x52,
0x66, 0xb2, 0x76, 0x60, 0xda, 0xc5, 0xf3, 0xf6,
0xaa, 0xcd, 0x9a, 0xa0, 0x75, 0x54, 0x0e, 0x01 };
Code:
len= aes_msg_len
len_mod=aes_msg_len mod 16
len_rem=aes_msg_len rem 16
for(i=0;i<len_mod;i++)
{
out[(i*16)..((i+1)*16)]=aes_encrypt(aeskey,iv,aes_msg[(i*16)..((i+1)*16])
iv=iv+1
}
if (len_rem>0)
{
out[(len-16)..len]=aes_encrypt(aeskey,iv,aes_msg[(len-16)..(len)]
iv=iv+1
}
the key exchange uses plain rsa 1024bit encryption
the normal packages uses aes 128 bit ctr mode
Thanks for everyone in the Dev Team made by Juuf.
Reference:






