Beispiel #1
0
 public void Decrypt()
 {
     packet             = crypt.decrypt(packet, 2, packet.Length - 2);
     packetBufferStream = new MemoryStream(packet);
     packetBuffer       = new BinaryReader(packetBufferStream);
 }
Beispiel #2
0
        public override void DataReceived(ref byte[] inputPacket)
        {
            if (gameData.Blowfish_Key.Length > 0)
            {
                LoginReader packet = new LoginReader(inputPacket, gameData);
                packet.Decrypt();
                byte opcode = packet.readB();
                switch (opcode)
                {
                case 0x01:
                    #region Failed Login.
                    byte   reason  = packet.readB();
                    string message = "";
                    switch (reason)
                    {
                    case 0x01:
                        message = "System Error.";
                        break;

                    case 0x02:
                        message = "Password is incorrect.";
                        break;

                    case 0x03:
                        message = "Username or password incorrect.";
                        break;

                    case 0x04:
                        message = "Access Failed.";
                        break;

                    case 0x07:
                        message = "Account in use.";
                        break;

                    case 0x0f:
                        message = "Server overloaded.";
                        break;

                    case 0x10:
                        message = "Server undergoing maintenance.";
                        break;

                    case 0x11:
                        message = "Temporary password has expired.";
                        break;

                    case 0x23:
                        message = "Dual box detected.";
                        break;
                    }
                    Debug.Error("Unable to login, message from server: " + message);
                    Close();
                    break;

                    #endregion
                case 0x0B:
                    #region GameGuard Response.
                    string name       = UserConfig.Username;
                    string pw         = UserConfig.Password;
                    byte[] login_info = new byte[128];
                    login_info[0x5B] = 0x24;
                    for (int i = 0; i < name.Length; i++)
                    {
                        login_info[0x5E + i] = (byte)name[i];
                    }
                    for (int i = 0; i < pw.Length; i++)
                    {
                        login_info[0x6C + i] = (byte)pw[i];
                    }
                    byte[] Exponent = { 1, 0, 1 };
                    System.Security.Cryptography.RSAParameters RSAKeyInfo = new System.Security.Cryptography.RSAParameters();

                    //Set RSAKeyInfo to the public key values.
                    RSAKeyInfo.Modulus  = gameData.RSA_Key;
                    RSAKeyInfo.Exponent = Exponent;

                    RSA poo = new RSA();
                    poo.ImportParameters(RSAKeyInfo);

                    byte[] outb = new byte[128];

                    outb = poo.EncryptValue(login_info);
                    byte[] login_send  = new byte[176];
                    byte[] login_sende = new byte[176];
                    outb.CopyTo(login_send, 1);
                    login_send[129] = gameData.Session[0];
                    login_send[130] = gameData.Session[1];
                    login_send[131] = gameData.Session[2];
                    login_send[132] = gameData.Session[3];
                    login_send[133] = 0x23;    //gameguard reply start
                    login_send[134] = 0x01;
                    login_send[135] = 0x00;
                    login_send[136] = 0x00;
                    login_send[137] = 0x67;    //
                    login_send[138] = 0x45;
                    login_send[139] = 0x00;
                    login_send[140] = 0x00;
                    login_send[141] = 0xAB;    //
                    login_send[142] = 0x89;
                    login_send[143] = 0x00;
                    login_send[144] = 0x00;
                    login_send[145] = 0xEF;    //
                    login_send[146] = 0xCD;
                    login_send[147] = 0x00;
                    login_send[148] = 0x00;    //game guard reply stop
                    login_send[149] = 0x08;    //
                    login_send[150] = 0x00;
                    login_send[151] = 0x00;
                    login_send[152] = 0x00;
                    login_send[153] = 0x00;    //
                    login_send[154] = 0x00;
                    login_send[155] = 0x00;
                    login_send[156] = 0x00;
                    login_send[157] = 0x00;    //
                    login_send[158] = 0x00;
                    login_send[159] = 0x00;

                    ulong chk = General.CheckSum(login_send, 160);

                    login_send[160] = (byte)(chk & 0xff);
                    login_send[161] = (byte)(chk >> 0x08 & 0xff);
                    login_send[163] = (byte)(chk >> 0x10 & 0xff);
                    login_send[163] = (byte)(chk >> 0x18 & 0xff);

                    LoginWriter pck = new LoginWriter(login_send, gameData);
                    pck.Encrypt();
                    Send(pck.Finalize());
                    Debug.Information("Sending login information.");
                    break;

                    #endregion
                case 0x03:
                    #region LoginOK
                    byte[] send = new byte[32];

                    send[0]  = 0x05;
                    send[1]  = packet.readB();
                    send[2]  = packet.readB();
                    send[3]  = packet.readB();
                    send[4]  = packet.readB();
                    send[5]  = packet.readB();
                    send[6]  = packet.readB();
                    send[7]  = packet.readB();
                    send[8]  = packet.readB();
                    send[9]  = 0x04;
                    send[10] = 0x00;
                    send[11] = 0x00;
                    send[12] = 0x00;
                    send[13] = 0x00;
                    send[14] = 0x00;
                    send[15] = 0x00;

                    gameData.LoginOK    = new byte[8];
                    gameData.LoginOK[0] = send[1];
                    gameData.LoginOK[1] = send[2];
                    gameData.LoginOK[2] = send[3];
                    gameData.LoginOK[3] = send[4];
                    gameData.LoginOK[4] = send[5];
                    gameData.LoginOK[5] = send[6];
                    gameData.LoginOK[6] = send[7];
                    gameData.LoginOK[7] = send[8];

                    chk = General.CheckSum(send, 16);

                    send[16] = (byte)(chk & 0xff);
                    send[17] = (byte)(chk >> 0x08 & 0xff);
                    send[18] = (byte)(chk >> 0x10 & 0xff);
                    send[19] = (byte)(chk >> 0x18 & 0xff);

                    pck = new LoginWriter(send, gameData);
                    pck.Encrypt();
                    Send(pck.Finalize());
                    break;

                    #endregion
                case 0x04:
                    #region Server List
                    int serv_num = packet.readB();
                    Servers = new GameServer[serv_num];
                    packet.readB();     // Unknown byte
                    for (int i = 0; i < serv_num; i++)
                    {
                        GameServer server = new GameServer(ref UserConfig, ref gameData, ref Plugins, ref Extensions);
                        server.ID              = packet.packetBuffer.ReadByte();
                        server.IP              = new IPAddress(BitConverter.GetBytes(packet.packetBuffer.ReadInt32()));
                        server.Port            = packet.packetBuffer.ReadInt32();
                        server.AgeLimit        = packet.packetBuffer.ReadByte();
                        server.PvP             = packet.packetBuffer.ReadByte();
                        server.CurrentPlayers  = packet.packetBuffer.ReadInt16();
                        server.MaxPlayers      = packet.packetBuffer.ReadInt16();
                        server.Online          = packet.packetBuffer.ReadByte();
                        server.ExtraData       = packet.packetBuffer.ReadInt32();
                        server.DisplayBrackets = packet.packetBuffer.ReadByte();
                        Servers[i]             = server;
                    }
                    try {
                        selectedServer = Int32.Parse(UserConfig.GameServer) - 1;
                    } catch (Exception ex) {
                        Debug.Exception("Unable to parse which gameserver to use.", ex);
                        return;
                    }
                    Debug.Information("Logging into: " + General.ServerNames[selectedServer]);
                    byte[] buff = new byte[32];

                    buff[0]  = 0x02;
                    buff[1]  = gameData.LoginOK[0];
                    buff[2]  = gameData.LoginOK[1];
                    buff[3]  = gameData.LoginOK[2];
                    buff[4]  = gameData.LoginOK[3];
                    buff[5]  = gameData.LoginOK[4];
                    buff[6]  = gameData.LoginOK[5];
                    buff[7]  = gameData.LoginOK[6];
                    buff[8]  = gameData.LoginOK[7];
                    buff[9]  = Servers[selectedServer].ID;
                    buff[10] = 0x00;
                    buff[11] = 0x00;
                    buff[12] = 0x00;
                    buff[13] = 0x00;
                    buff[14] = 0x00;
                    buff[15] = 0x00;

                    chk = General.CheckSum(buff, 16);

                    buff[16] = (byte)(chk & 0xff);
                    buff[17] = (byte)(chk >> 0x08 & 0xff);
                    buff[18] = (byte)(chk >> 0x10 & 0xff);
                    buff[19] = (byte)(chk >> 0x18 & 0xff);

                    pck = new LoginWriter(buff, gameData);
                    pck.Encrypt();
                    Send(pck.Finalize());
                    break;

                    #endregion
                case 0x06:
                    #region PlayFailed
                    message = "";
                    switch (packet.packetBuffer.ReadByte())
                    {
                    case 0x01:
                        message = "System Error.";
                        break;

                    case 0x02:
                        message = "Username or password is wrong.";
                        break;

                    case 0x03:
                        message = "Reason 3.";
                        break;

                    case 0x04:
                        message = "Reason 4.";
                        break;

                    case 0x0F:
                        message = "Too many players connected.";
                        break;
                    }
                    Debug.Error("Unable to connect to the game server, message: " + message);
                    break;

                    #endregion
                case 0x07:
                    #region PlayOK
                    gameData.PlayOK = new byte[] { packet.readB(), packet.readB(), packet.readB(), packet.readB(), packet.readB(), packet.readB(), packet.readB(), packet.readB() };
                    Debug.Information("Transfering to the GameServer Module.");
                    Close();
                    Servers[selectedServer].StartConnect();
                    break;

                    #endregion
                default:
                    Debug.Warning("Unknown packet: " + General.Hex(opcode));
                    break;
                }
            }
            else
            {
                Blowfish   blowfish = new Blowfish();
                LoginCrypt crypt    = new LoginCrypt(General.Hex(UserConfig.BlowfishKey));

                #region Blowfish key stuff
                Debug.Information("Attempting to get Blowfish key.");
                try
                {
                    int    size = 180;
                    byte[] raw  = inputPacket;
                    raw = crypt.decrypt(raw, 2, size + 4);
                    int key = ByteHelper.ByteIntR(raw, size - 4);

                    int Bloques = (size / 4) - 1;

                    int[] r = new int[Bloques];
                    int   t;
                    for (t = Bloques - 1; t > 0; t--)
                    {
                        int p = ByteHelper.ByteIntR(raw, (4 * t)) ^ key;
                        r[Bloques - t - 1] = p;
                        key = ByteHelper.Vuelta(ByteHelper.Vuelta(key) - ByteHelper.Vuelta(p));
                    }
                    r[Bloques - 1] = ByteHelper.ByteIntR(raw, 0);
                    inputPacket    = ByteHelper.IntByte(r);

                    int    ia;
                    byte[] t2 = new byte[16];
                    for (ia = 0; ia < 16; ia++)
                    {
                        t2[ia] = inputPacket[153 + ia];
                    }

                    gameData.Blowfish_Key = t2;

                    byte[] session = new byte[4];
                    session[0] = inputPacket[1];
                    session[1] = inputPacket[2];
                    session[2] = inputPacket[3];
                    session[3] = inputPacket[4];

                    gameData.Session = session;

                    crypt = new LoginCrypt(gameData.Blowfish_Key);
                }
                catch (Exception ex)
                {
                    Debug.Exception("Error getting Blowfish key", ex);
                    return;
                }
                Debug.Information("Successfully got Blowfish key:");
                Debug.Information(" - " + General.Hex(gameData.Blowfish_Key));
                #endregion

                #region RSA key stuff
                Debug.Information("Attempting to get RSA key.");
                try
                {
                    byte[] enckey = new byte[128];
                    for (int i = 0; i < 128; i++)
                    {
                        enckey[i] = inputPacket[9 + i];
                    }

                    for (int i = 0; i < 0x40; i++)
                    {
                        enckey[0x40 + i] = (byte)(enckey[0x40 + i] ^ enckey[i]);
                    }

                    for (int i = 0; i < 4; i++)
                    {
                        enckey[0x0d + i] = (byte)(enckey[0x0d + i] ^ enckey[0x34 + i]);
                    }

                    for (int i = 0; i < 0x40; i++)
                    {
                        enckey[i] = (byte)(enckey[i] ^ enckey[0x40 + i]);
                    }

                    for (int i = 0; i < 4; i++)
                    {
                        byte temp = enckey[0x00 + i];
                        enckey[0x00 + i] = enckey[0x4d + i];
                        enckey[0x4d + i] = temp;
                    }

                    gameData.RSA_Key = enckey;
                }
                catch (Exception ex)
                {
                    Debug.Exception("Error getting RSA key", ex);
                    return;
                }
                Debug.Information("Successfully got RSA key:");
                Debug.Information(" - " + General.Hex(gameData.RSA_Key));
                #endregion

                #region GameGuard Login stuff
                try
                {
                    byte[] send  = new byte[40];
                    byte[] sende = new byte[40];

                    send[00] = 0x07;
                    send[01] = inputPacket[1];
                    send[02] = inputPacket[2];
                    send[03] = inputPacket[3];
                    send[04] = inputPacket[4];

                    ulong chk = General.CheckSum(send, 24);

                    send[24] = (byte)(chk & 0xff);
                    send[25] = (byte)(chk >> 0x08 & 0xff);
                    send[26] = (byte)(chk >> 0x10 & 0xff);
                    send[27] = (byte)(chk >> 0x18 & 0xff);

                    LoginWriter lw = new LoginWriter(send, gameData);
                    lw.Encrypt();
                    Send(lw.Finalize());
                }
                catch (Exception ex)
                {
                    Debug.Exception("Error sending GameGuard packet.", ex);
                    return;
                }
                Debug.Information("Successfully sent GameGuard packet.");
                #endregion
            }
        }