A3 returns help

Page 1 of 2 12 LastLast
Results 1 to 15 of 25
  1. #1

    ! A3 returns help


    RaGEZONE Recommends

    RaGEZONE Recommends

    It would be glad if some one can provide ACL file structure information about a3 returns.
    The form in which bytes are stored etc etc.


  2. #2
    Member prologos is offline
    MemberRank
    Jan 2012 Join Date
    South KoreaLocation
    75Posts

    Re: A3 returns help

    Click image for larger version. 

Name:	acl.gif 
Views:	67 
Size:	35.4 KB 
ID:	157112

    attached image is one of a slot.
    packet is composed of a HEADER + 5 slots DATA.

    but, in Returns(572), all packets has changed.
    but, in Returns(578), all packets has changed.
    Last edited by prologos; 14-06-16 at 04:21 PM.
    Sorry, I can not English well.
    I have posted using Google Translate.

  3. #3
    Programmer cyberinferno is offline
    True MemberRank
    Jun 2009 Join Date
    BangaloreLocation
    414Posts

    Re: A3 returns help

    Quote Originally Posted by prologos View Post
    Click image for larger version. 

Name:	acl.gif 
Views:	67 
Size:	35.4 KB 
ID:	157112

    attached image is one of a slot.
    packet is composed of a HEADER + 5 slots DATA.
    but, in Returns(572), all packets has changed.
    What about encryption key used for encrypt/decrypt functions in the cracked client you gave?
    Please help me in my dream MMORPG emulator https://github.com/cyberinferno/inferno-emu-v2

  4. #4

    Re: A3 returns help

    Quote Originally Posted by prologos View Post
    Click image for larger version. 

Name:	acl.gif 
Views:	67 
Size:	35.4 KB 
ID:	157112

    attached image is one of a slot.
    packet is composed of a HEADER + 5 slots DATA.

    but, in Returns(572), all packets has changed.
    Thank you prologs for the reply.
    I would like to know more about headers in which you have marked with Ctrl, Cmd and Protocol. What are this in header?
    And does this 578 packet structure (shown in image) works with returns client ?

  5. #5

    Re: A3 returns help

    I tried login using cracked client of a3 returns provided by prologos,
    But don't know where the problem is, client crashes on login and on LS it shows user disconnected.

  6. #6
    Programmer cyberinferno is offline
    True MemberRank
    Jun 2009 Join Date
    BangaloreLocation
    414Posts

    Re: A3 returns help

    Quote Originally Posted by mihir View Post
    I tried login using cracked client of a3 returns provided by prologos,
    But don't know where the problem is, client crashes on login and on LS it shows user disconnected.
    Does the client DC after getting character list packet or before?
    Please help me in my dream MMORPG emulator https://github.com/cyberinferno/inferno-emu-v2

  7. #7

    Re: A3 returns help

    Quote Originally Posted by cyberinferno View Post
    Does the client DC after getting character list packet or before?
    Before character packet,
    As I entered username and password pressed enter and client crashes,
    login packet is received by login agent and login server, but disconnects as client crashes

  8. #8
    Programmer cyberinferno is offline
    True MemberRank
    Jun 2009 Join Date
    BangaloreLocation
    414Posts

    Re: A3 returns help

    Quote Originally Posted by mihir View Post
    Before character packet,
    As I entered username and password pressed enter and client crashes,
    login packet is received by login agent and login server, but disconnects as client crashes
    Then there might be slight difference in the packet structure format hence while trying to parse it the client is crashing (Maybe array out of bounds?)
    Please help me in my dream MMORPG emulator https://github.com/cyberinferno/inferno-emu-v2

  9. #9

    Re: A3 returns help

    Quote Originally Posted by cyberinferno View Post
    Then there might be slight difference in the packet structure format hence while trying to parse it the client is crashing (Maybe array out of bounds?)
    May be possible. Will try it out differently modifying login packets and will post results.

  10. #10
    Member prologos is offline
    MemberRank
    Jan 2012 Join Date
    South KoreaLocation
    75Posts

    Re: A3 returns help

    1. Login packet has been changed. It must be treated with LA.

    2. encrypt/decrypt function is substantially the same as 562.
    578, to encrypt/decrypt the protocol part of the header in a new way.

    *Examples of encrypt/decrypt function in C#
    Code:
    class Config
        {
            public static int m_ConstKey1 = 0x241AE7;
            public static int m_ConstKey2 = 0x15DCB2;
            public static int m_DynamicKey = 0x4C478BD;
            public const int p_Type562 = 0x0C;
            public const int p_Type578 = 0x0A;
            public static int p_DynamicKey1 = 0x02;
            public static int p_DynamicKey2 = 0x01;
            public static uint p_ConstKey_En = 0xA7F0753B;
            public static uint p_ConstKey_De = 0xAAF29BF3;
        }
    Code:
    class Crypt
        {
            public static byte[] Decrypt(byte[] packet, int Type = Config.p_Type578)
            {
                //[0]-[11]: Packet Header
                for (int i = Type; i + 4 <= packet.Length; i += 4)
                {
                    if (i == Config.p_Type578)
                    {
                        uint wProtocol = (BitConverter.ToUInt32(packet, i) * Config.p_ConstKey_De) >> 16;
                        var wProtocolByte = BitConverter.GetBytes(wProtocol);
                        Buffer.BlockCopy(wProtocolByte, 0, packet, 10, 4);
                        continue;
                    }
                    int DynamicKey = Config.m_DynamicKey;
                    for (int j = i; j < i + 4; j++)
                    {
                        byte pSrc = packet[j];
                        packet[j] = (byte)(packet[j] ^ (DynamicKey >> 8));
                        DynamicKey = (pSrc + DynamicKey) * Config.m_ConstKey1 + Config.m_ConstKey2;
                    }
                }
                return packet;
            }
    
            public static byte[] Encrypt(byte[] packet, int Type = Config.p_Type578)
            {
                //[0]-[11]: Packet Header
                for (int i = Type; i + 4 <= packet.Length; i += 4)
                {
                    if (i == Config.p_Type578)
                    {
                        uint wProtocol = (uint)((BitConverter.ToUInt16(packet, i) << 16) + (Config.p_DynamicKey1 << 8) + Config.p_DynamicKey2) * Config.p_ConstKey_En;
                        var wProtocolByte = BitConverter.GetBytes(wProtocol);
                        Buffer.BlockCopy(wProtocolByte, 0, packet, 10, 4);
                        Config.p_DynamicKey2 = (byte)Config.p_DynamicKey1 + Config.p_DynamicKey2;
                        Config.p_DynamicKey1 = (byte)Config.p_DynamicKey1 + 0xB3;
                        continue;
                    }
                    int DynamicKey = Config.m_DynamicKey;
                    for (int j = i; j < i + 4; j++)
                    {
                        packet[j] = (byte)(packet[j] ^ (DynamicKey >> 8));
                        DynamicKey = (packet[j] + DynamicKey) * Config.m_ConstKey1 + Config.m_ConstKey2;
                    }
                }
                return packet;
            }
        }
    Precisely, using the random number to encrypt the part of the protocol. However, to work well, just above code.
    Sorry, I can not English well.
    I have posted using Google Translate.

  11. #11
    Programmer cyberinferno is offline
    True MemberRank
    Jun 2009 Join Date
    BangaloreLocation
    414Posts

    Re: A3 returns help

    Quote Originally Posted by prologos View Post
    1. Login packet has been changed. It must be treated with LA.

    2. encrypt/decrypt function is substantially the same as 562.
    578, to encrypt/decrypt the protocol part of the header in a new way.

    *Examples of encrypt/decrypt function in C#
    Code:
    class Config
        {
            public static int m_ConstKey1 = 0x241AE7;
            public static int m_ConstKey2 = 0x15DCB2;
            public static int m_DynamicKey = 0x4C478BD;
            public const int p_Type562 = 0x0C;
            public const int p_Type578 = 0x0A;
            public static int p_DynamicKey1 = 0x02;
            public static int p_DynamicKey2 = 0x01;
            public static uint p_ConstKey_En = 0xA7F0753B;
            public static uint p_ConstKey_De = 0xAAF29BF3;
        }
    Code:
    class Crypt
        {
            public static byte[] Decrypt(byte[] packet, int Type = Config.p_Type578)
            {
                //[0]-[11]: Packet Header
                for (int i = Type; i + 4 <= packet.Length; i += 4)
                {
                    if (i == Config.p_Type578)
                    {
                        uint wProtocol = (BitConverter.ToUInt32(packet, i) * Config.p_ConstKey_De) >> 16;
                        var wProtocolByte = BitConverter.GetBytes(wProtocol);
                        Buffer.BlockCopy(wProtocolByte, 0, packet, 10, 4);
                        continue;
                    }
                    int DynamicKey = Config.m_DynamicKey;
                    for (int j = i; j < i + 4; j++)
                    {
                        byte pSrc = packet[j];
                        packet[j] = (byte)(packet[j] ^ (DynamicKey >> 8));
                        DynamicKey = (pSrc + DynamicKey) * Config.m_ConstKey1 + Config.m_ConstKey2;
                    }
                }
                return packet;
            }
    
            public static byte[] Encrypt(byte[] packet, int Type = Config.p_Type578)
            {
                //[0]-[11]: Packet Header
                for (int i = Type; i + 4 <= packet.Length; i += 4)
                {
                    if (i == Config.p_Type578)
                    {
                        uint wProtocol = (uint)((BitConverter.ToUInt16(packet, i) << 16) + (Config.p_DynamicKey1 << 8) + Config.p_DynamicKey2) * Config.p_ConstKey_En;
                        var wProtocolByte = BitConverter.GetBytes(wProtocol);
                        Buffer.BlockCopy(wProtocolByte, 0, packet, 10, 4);
                        Config.p_DynamicKey2 = (byte)Config.p_DynamicKey1 + Config.p_DynamicKey2;
                        Config.p_DynamicKey1 = (byte)Config.p_DynamicKey1 + 0xB3;
                        continue;
                    }
                    int DynamicKey = Config.m_DynamicKey;
                    for (int j = i; j < i + 4; j++)
                    {
                        packet[j] = (byte)(packet[j] ^ (DynamicKey >> 8));
                        DynamicKey = (packet[j] + DynamicKey) * Config.m_ConstKey1 + Config.m_ConstKey2;
                    }
                }
                return packet;
            }
        }
    Precisely, using the random number to encrypt the part of the protocol. However, to work well, just above code.
    As usual @prologos saving the day
    Please help me in my dream MMORPG emulator https://github.com/cyberinferno/inferno-emu-v2

  12. #12

    Re: A3 returns help

    Quote Originally Posted by prologos View Post
    1. Login packet has been changed. It must be treated with LA.

    2. encrypt/decrypt function is substantially the same as 562.
    578, to encrypt/decrypt the protocol part of the header in a new way.

    *Examples of encrypt/decrypt function in C#
    Code:
    class Config
        {
            public static int m_ConstKey1 = 0x241AE7;
            public static int m_ConstKey2 = 0x15DCB2;
            public static int m_DynamicKey = 0x4C478BD;
            public const int p_Type562 = 0x0C;
            public const int p_Type578 = 0x0A;
            public static int p_DynamicKey1 = 0x02;
            public static int p_DynamicKey2 = 0x01;
            public static uint p_ConstKey_En = 0xA7F0753B;
            public static uint p_ConstKey_De = 0xAAF29BF3;
        }
    Code:
    class Crypt
        {
            public static byte[] Decrypt(byte[] packet, int Type = Config.p_Type578)
            {
                //[0]-[11]: Packet Header
                for (int i = Type; i + 4 <= packet.Length; i += 4)
                {
                    if (i == Config.p_Type578)
                    {
                        uint wProtocol = (BitConverter.ToUInt32(packet, i) * Config.p_ConstKey_De) >> 16;
                        var wProtocolByte = BitConverter.GetBytes(wProtocol);
                        Buffer.BlockCopy(wProtocolByte, 0, packet, 10, 4);
                        continue;
                    }
                    int DynamicKey = Config.m_DynamicKey;
                    for (int j = i; j < i + 4; j++)
                    {
                        byte pSrc = packet[j];
                        packet[j] = (byte)(packet[j] ^ (DynamicKey >> 8));
                        DynamicKey = (pSrc + DynamicKey) * Config.m_ConstKey1 + Config.m_ConstKey2;
                    }
                }
                return packet;
            }
    
            public static byte[] Encrypt(byte[] packet, int Type = Config.p_Type578)
            {
                //[0]-[11]: Packet Header
                for (int i = Type; i + 4 <= packet.Length; i += 4)
                {
                    if (i == Config.p_Type578)
                    {
                        uint wProtocol = (uint)((BitConverter.ToUInt16(packet, i) << 16) + (Config.p_DynamicKey1 << 8) + Config.p_DynamicKey2) * Config.p_ConstKey_En;
                        var wProtocolByte = BitConverter.GetBytes(wProtocol);
                        Buffer.BlockCopy(wProtocolByte, 0, packet, 10, 4);
                        Config.p_DynamicKey2 = (byte)Config.p_DynamicKey1 + Config.p_DynamicKey2;
                        Config.p_DynamicKey1 = (byte)Config.p_DynamicKey1 + 0xB3;
                        continue;
                    }
                    int DynamicKey = Config.m_DynamicKey;
                    for (int j = i; j < i + 4; j++)
                    {
                        packet[j] = (byte)(packet[j] ^ (DynamicKey >> 8));
                        DynamicKey = (packet[j] + DynamicKey) * Config.m_ConstKey1 + Config.m_ConstKey2;
                    }
                }
                return packet;
            }
        }
    Precisely, using the random number to encrypt the part of the protocol. However, to work well, just above code.
    Great @prologos , thanks for the code snippet.
    As you mentioned 1st point about login packets are changed.
    I observed login packet is of 64 bytes which was 56 bytes in case of v562.
    So it would be glad if you can provide with login packet structure and its response to be send from server.

  13. #13
    Member prologos is offline
    MemberRank
    Jan 2012 Join Date
    South KoreaLocation
    75Posts

    Re: A3 returns help

    Quote Originally Posted by mihir View Post
    Great @prologos , thanks for the code snippet.
    As you mentioned 1st point about login packets are changed.
    I observed login packet is of 64 bytes which was 56 bytes in case of v562.
    So it would be glad if you can provide with login packet structure and its response to be send from server.
    perhaps... Try the following code to the Inferno-Login-Agent-562

    *change on line 130 of Packet.cs
    case 52:
    desiredPacket = new byte[] { 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0 };
    if (desiredPacket.SequenceEqual(packetGot))
    {
    var temp = CreateReverseHexPacket(cindex);
    buffer[4] = temp[0];
    buffer[5] = temp[1];
    returnPacket = buffer;
    }
    break;


    case 64:
    desiredPacket = new byte[] { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0 };
    if (desiredPacket.SequenceEqual(packetGot))
    {
    var temp = CreateReverseHexPacket(cindex);
    buffer[4] = temp[0];
    buffer[5] = temp[1];
    returnPacket = buffer;
    }
    break;


    *add function to Packet.cs
    public static byte[] CreateServerList(byte[] buffer)
    {
    var packetLen = BitConverter.ToInt32(new byte[] { buffer[0], buffer[1], buffer[2], buffer[3] }, 0);
    var newPacket = new byte[packetLen + 21];
    byte[] byteArray = BitConverter.GetBytes(packetLen + 21);
    Buffer.BlockCopy(byteArray, 0, newPacket, 0, 4);
    Buffer.BlockCopy(buffer, 4, newPacket, 4, 6);
    Buffer.BlockCopy(buffer, 10, newPacket, 31, packetLen - 10);
    return newPacket;
    }


    *change on line 271 of LoginAgent.cs
    else if (Encoding.ASCII.GetString(bytes).Substring(30, 6) == "ONLINE")
    {
    // Prepend welcome message to the server name data
    bytes = Packet.CombineByteArray(Packet.CreateWelcomeMessage(cindex), Packet.TrimPacket(bytes));
    }


    else if (Encoding.ASCII.GetString(bytes).Substring(30, 6) == "ONLINE" || Encoding.ASCII.GetString(bytes).Substring(30, 7) == "OFFLINE")
    {
    // Prepend welcome message to the server name data
    bytes = Packet.CreateServerList(bytes);
    }



    Perhaps the code is not perfect. However, the Test is possible.
    Sorry, I can not English well.
    I have posted using Google Translate.

  14. #14

    Re: A3 returns help

    Quote Originally Posted by prologos View Post
    perhaps... Try the following code to the Inferno-Login-Agent-562

    *change on line 130 of Packet.cs
    case 52:
    desiredPacket = new byte[] { 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0 };
    if (desiredPacket.SequenceEqual(packetGot))
    {
    var temp = CreateReverseHexPacket(cindex);
    buffer[4] = temp[0];
    buffer[5] = temp[1];
    returnPacket = buffer;
    }
    break;


    case 64:
    desiredPacket = new byte[] { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0 };
    if (desiredPacket.SequenceEqual(packetGot))
    {
    var temp = CreateReverseHexPacket(cindex);
    buffer[4] = temp[0];
    buffer[5] = temp[1];
    returnPacket = buffer;
    }
    break;


    *add function to Packet.cs
    public static byte[] CreateServerList(byte[] buffer)
    {
    var packetLen = BitConverter.ToInt32(new byte[] { buffer[0], buffer[1], buffer[2], buffer[3] }, 0);
    var newPacket = new byte[packetLen + 21];
    byte[] byteArray = BitConverter.GetBytes(packetLen + 21);
    Buffer.BlockCopy(byteArray, 0, newPacket, 0, 4);
    Buffer.BlockCopy(buffer, 4, newPacket, 4, 6);
    Buffer.BlockCopy(buffer, 10, newPacket, 31, packetLen - 10);
    return newPacket;
    }


    *change on line 271 of LoginAgent.cs
    else if (Encoding.ASCII.GetString(bytes).Substring(30, 6) == "ONLINE")
    {
    // Prepend welcome message to the server name data
    bytes = Packet.CombineByteArray(Packet.CreateWelcomeMessage(cindex), Packet.TrimPacket(bytes));
    }


    else if (Encoding.ASCII.GetString(bytes).Substring(30, 6) == "ONLINE" || Encoding.ASCII.GetString(bytes).Substring(30, 7) == "OFFLINE")
    {
    // Prepend welcome message to the server name data
    bytes = Packet.CreateServerList(bytes);
    }



    Perhaps the code is not perfect. However, the Test is possible.
    @prologos Great work, Thanks, I was able to login, now trying to sort out character packets

  15. #15
    Member roshan_jadhav32 is offline
    MemberRank
    Apr 2008 Join Date
    44Posts

    Re: A3 returns help

    Hi can you share us how you are able to login in ?
    Thanks
    Quote Originally Posted by mihir View Post
    @prologos Great work, Thanks, I was able to login, now trying to sort out character packets




Page 1 of 2 12 LastLast

Advertisement