Most visitors online was 8830 , on 6 Feb 2024
Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!
Join Today!Is anyone willing to share the xor decryption algorithm? From what I see, it changes every session, but for a single session it is deterministic and reused for all packets (both server and client). Maybe a table or something? Some clues would also be helpful as to what data is used to initialize this table/sequence.
if you mean packet i know someone who get 1.4 and 2.0 packet decryption algorithm
Yes, I mean packet. Are they willing to share?
AA AA AA AA BB BB BB BB CC DD EE EE FF FF FF FF GG GG GG GG HH HH HH HH II II II II DATA
A = conv (session id 1)
B = conv (session id 2)
C = cmd (command PUSH=0x81, ACK=0x82, WASK=0x83, WINS=0x84)
D = frg (fragment number)
E = wnd (window size)
F = ts (timestamp)
G = sn (serial number, count)
H = una (ack number, count)
I = len (data length)
AA AA AA AA BB BB BB BB CC CC CC CC DD DD DD DD EE EE EE EE
A = Special Value 1
B = SessionId 1
C = SessionId 2
D = Enet*
E = Special Value 2
EnetTimeout = 0
EnetClientClose = 1
EnetClientRebindFail = 2
EnetClientShutdown = 3
EnetServerRelogin = 4
EnetServerKick = 5
EnetServerShutdown = 6
EnetNotFoundSession = 7
EnetLoginUnfinished = 8
EnetPacketFreqTooHigh = 9
EnetPingTimeout = 10
EnetTranferFailed = 11
EnetServerKillClient = 12
EnetCheckMoveSpeed = 13
EnetAccountPasswordChange = 14
EnetClientEditorConnectKey = 987654321
EnetClientConnectKey = 1234567890
SEND 00 00 00 FF 00 00 00 00 00 00 00 00 49 96 02 D2 FF FF FF FF
RECV 00 00 01 45 XX XX XX XX YY YY YY YY 49 96 02 D2 14 51 45 45
RECV 00 00 01 94 XX XX XX XX YY YY YY YY 00 00 00 01 19 41 94 94
SEND 00 00 01 94 XX XX XX XX YY YY YY YY 00 00 00 01 19 41 94 94
Small update; There is a select group working on a private server. It hasn't been dropped but people have lives so things take time.
void __stdcall MPOPONDMPGP_LJIKGPHDBNA(void *this, Byte__Array **LKANOGJKKDA, int32_t MHNBJBBPFGM, MethodInfo *method)
if ( v6->static_fields->BLNKMJCJNMP )
{
if ( (*(&v6->_1 + 90) & 1) != 0 && !v6->_1.cctor_finished )
{
il2cpp_runtime_class_init_0(v6);
v6 = MPOPONDMPGP__TypeInfo;
}
v10 = &v6->static_fields->GFFCHKDELNC;
}
else
{
if ( (*(&v6->_1 + 90) & 1) != 0 && !v6->_1.cctor_finished )
{
il2cpp_runtime_class_init_0(v6);
v6 = MPOPONDMPGP__TypeInfo;
}
v10 = &v6->static_fields->ALHLOPIEDNI;
}
v11 = *v10;
if ( v11 )
{
if ( *(v11 + 6) )
{
v12 = *(v11 + 6);
for ( i = 0i64; i < MHNBJBBPFGM; v15[32] ^= v11[v17 + 32] )
{
v14 = *LKANOGJKKDA;
if ( !*LKANOGJKKDA )
sub_187F51300(i);
if ( i >= LODWORD(v14->max_length) )
{
v21 = sub_187F50B10(i, i);
sub_187F51220(v21, 0i64); // Exception
}
v15 = v14 + i;
v16 = (i >> 31);
v17 = i % v12;
if ( v17 >= *(v11 + 6) )
{
LODWORD(v16) = i % v12;
v20 = sub_187F50B10(i, v16);
sub_187F51220(v20, 0i64); // Exception
}
i = (i + 1);
}
}
}
Spent some more time and was able to figure out decryption. For those who are still looking, the decrypt function is MPOPONDMPGP_LJIKGPHDBNA (0x1815AF400) for v2.0 and is just a simple XOR based on a key.
There are two keys: GFFCHKDELNC +0x00, ALHLOPIEDNI +0x08 being used for decryption which are static fields of MPOPONDMPGP. The key to be used is determined by a bool BLNKMJCJNMP +0x10. Note that these are all obfuscated names and will change in future versions.
Code:void __stdcall MPOPONDMPGP_LJIKGPHDBNA(void *this, Byte__Array **LKANOGJKKDA, int32_t MHNBJBBPFGM, MethodInfo *method)
Code:if ( v6->static_fields->BLNKMJCJNMP ) { if ( (*(&v6->_1 + 90) & 1) != 0 && !v6->_1.cctor_finished ) { il2cpp_runtime_class_init_0(v6); v6 = MPOPONDMPGP__TypeInfo; } v10 = &v6->static_fields->GFFCHKDELNC; } else { if ( (*(&v6->_1 + 90) & 1) != 0 && !v6->_1.cctor_finished ) { il2cpp_runtime_class_init_0(v6); v6 = MPOPONDMPGP__TypeInfo; } v10 = &v6->static_fields->ALHLOPIEDNI; } v11 = *v10; if ( v11 ) { if ( *(v11 + 6) ) { v12 = *(v11 + 6); for ( i = 0i64; i < MHNBJBBPFGM; v15[32] ^= v11[v17 + 32] ) { v14 = *LKANOGJKKDA; if ( !*LKANOGJKKDA ) sub_187F51300(i); if ( i >= LODWORD(v14->max_length) ) { v21 = sub_187F50B10(i, i); sub_187F51220(v21, 0i64); // Exception } v15 = v14 + i; v16 = (i >> 31); v17 = i % v12; if ( v17 >= *(v11 + 6) ) { LODWORD(v16) = i % v12; v20 = sub_187F50B10(i, v16); sub_187F51220(v20, 0i64); // Exception } i = (i + 1); } } }
Credits toYou must be registered to see linkswhich helped a lot in finding this.
i dont know much but packet encryption are XOR & mt19937_64
Thanks, HGHNILEBHMN seems to be mt19937_64 and is used for generating the key.
I don't have any plans to make a server, I just wanted to decrypt packets so I can see data from the game. Why not 2.0 though, seems like going with the latest version is the best.
for (int i = 0; i < data_length; i++) {
data[i] ^= key[i % key_length];
}
45 67 AA AA BB BB CC CC CC CC XX YY 89 AB
45 67 = Constant
AA AA = OpCode?
BB BB = X Length
CC CC CC CC = Y Length
XX = Data
YY = Data
89 AB = Constant