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.
Printable View
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.
Attachment 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.
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.
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;
}
Precisely, using the random number to encrypt the part of the protocol. However, to work well, just above code.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;
}
}
As usual @prologos saving the day :thumbup:
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.
@prologos Great work, Thanks, I was able to login, now trying to sort out character packets