Welcome!

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!

Genshin Impact Private Server

Initiate Mage
Joined
May 6, 2021
Messages
2
Reaction score
0
Has anyone tried to check decompiled Android app file? I think that's a great idea! Correct me if I am not correct, because I am a green hand.
 
Initiate Mage
Joined
Dec 16, 2020
Messages
1
Reaction score
0
So,the discord for now its only reserved to who knows how to work on things,right?But if that is the case,how will we know when it's done?Will you guys give a link here after it's done?Considering it will take long anyway but yeah...i have those questions floating in my head from quite a while back when i started following this thread.
 
Initiate Mage
Joined
Jul 2, 2007
Messages
1
Reaction score
0
We are also looking forward to being able to help and make this project go forward
 
Newbie Spellweaver
Joined
Jul 20, 2021
Messages
5
Reaction score
0
It's been a few months since there was any update on this thread. Is this project still being worked on? I really hope it is.
 
Newbie Spellweaver
Joined
Dec 26, 2015
Messages
51
Reaction score
3
Yeah, I'm looking forward to this development too. Can't wait for the private files to be release. Any update?
 
Newbie Spellweaver
Joined
Mar 13, 2016
Messages
28
Reaction score
9
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.
 
Newbie Spellweaver
Joined
Jul 30, 2021
Messages
6
Reaction score
0
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
 
Newbie Spellweaver
Joined
Mar 13, 2016
Messages
28
Reaction score
9
Does anyone have a link to "UnityPlayer.dll" from version 1.2? This is needed to decrypt the game files and will help with reversing.

EDIT:
You can download the official 1.2 client
 
Last edited:
Newbie Spellweaver
Joined
Mar 13, 2016
Messages
28
Reaction score
9
I have found out that they are using a variation of (seemed to be some modified version of , see mihoyonet.dll) with an additional "session id/conv" (32bits) at the front. This article has a good overview of the kcp header: . The kcp header itself is not encrypted, but the data part is with some xor based encryption. The data segment has yet another protocol header in it, but I'm still working on figuring out a reliable way to decrypt it.

Example:
Code:
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)

Before connecting, there is some handshake process that goes on. These packets are 20 bytes long and follow the format:
Code:
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

Here are all the values for Enet*
Code:
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

Special Value 1/2 are used to determine what type of packet it is.

  • When connecting, SV1=0x145 (325) and SV2=0x14514545 (340870469).
  • When disconnecting, SV1=0x194 (404) and SV2=0x19419494 (423728276).

Example Connect (As Client):
Code:
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

Example Disconnect (As Client):
Code:
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
 
Initiate Mage
Joined
Aug 2, 2021
Messages
1
Reaction score
0
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.

Hi, im actually searching to understand packet structure of the game, did you think it would be possible to contact them? thx ^^
 
Newbie Spellweaver
Joined
Mar 13, 2016
Messages
28
Reaction score
9
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.

GFFCHKDELNC is used until ALHLOPIEDNI gets seeded, at which point BLNKMJCJNMP becomes false. This happens early in the communications. (only a couple packets are encrypted with GFFCHKDELNC)

GFFCHKDELNC is set by a call to UnityEngine.Application::ResetDispatchData(System.Byte[])
ALHLOPIEDNI is set using mt19937_64 based on a seed.

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 to which helped a lot in finding this.
 
Last edited:
Newbie Spellweaver
Joined
Jul 30, 2021
Messages
6
Reaction score
0
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 to which helped a lot in finding this.

i dont know much but packet encryption are XOR & mt19937_64





 
Newbie Spellweaver
Joined
Mar 13, 2016
Messages
28
Reaction score
9
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.
 
Initiate Mage
Joined
Aug 6, 2021
Messages
2
Reaction score
0
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.

Not sure what the scope of your goals is, but if you wind up writing an API of some kind for working with the packets I would be willing to work on a server emulator that sits on top of it. Unfortunately I'm entry level at best for native reversing and packet reversing so I really wouldn't be useful for much beyond that.
 
Initiate Mage
Joined
Aug 7, 2021
Messages
1
Reaction score
0
Hey everyone, I have been lurking this thread for a while, I dont understand anything to do with the code stuff since im not much of a tech savvy guy but I just want to know.. Is there alot of progress done?
 
Newbie Spellweaver
Joined
Mar 13, 2016
Messages
28
Reaction score
9
Last update from me, I was able to figure out how both keys are derived. First time I've ever reversed something on my own, so it was quite the challenge. For purposes of keeping things simple, GFFCHKDELNC = Key1, ALHLOPIEDNI = Key2. Both keys are 4096 bytes, and if the packet is over this length, it will just cycle back. Encryption and decryption are the same as XOR is symmetric. I'm not going to spoon feed here, but hopefully this helps people out.

Code:
for (int i = 0; i < data_length; i++) {
  data[i] ^= key[i % key_length];
}

Key1 is constant, if you get it from memory you can keep using it. However, if you are interested in figuring out how it is derived, the function is found in UnityPlayer.dll (sub_180C9B9C0). It was a real pain to trace this one, for no real gain, so I suggest you just dump the key from memory. (It's a static variable so you can find it pretty easily) Not sure how this changes between updates, but we'll see once 2.1 is out.

You can also dump Key2 from memory, but it changes every session, so it's better to figure out how it is derived. You will need Key1 to decrypt the first few packets, one of which contains the seed for Key2.

Both keys are generated by mt19937_64 (mostly)



The decrypted packet should follow this structure. Note that I haven't really dissected any packets yet, but this is what I see:

Code:
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
 
Last edited:
Back
Top