Skip to content

Instantly share code, notes, and snippets.

@LordJZ
Created May 27, 2011 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save LordJZ/995263 to your computer and use it in GitHub Desktop.
Save LordJZ/995263 to your computer and use it in GitHub Desktop.
MemoryStream stream = new MemoryStream();
try
{
m_packets.Clear();
int count = m_packetCount;
if (count > 0)
m_packets.Capacity = count;
RawChunkHeader header;
LinkedList<ChunkHeaderWrapper> headers = new LinkedList<ChunkHeaderWrapper>();
int i = 0;
while (count == 0 && !m_fileReader.IsRead() || ++i <= count)
{
header = m_fileReader.ReadStruct<RawChunkHeader>();
m_fileStream.Position += header.OptionalDataLength;
headers.AddLast(new ChunkHeaderWrapper { m_header = header, m_position = stream.Position });
var tmp = m_fileReader.ReadBytes(Math.Min(header.DataLength, (int)m_fileReader.GetRemainingLength()));
stream.Write(tmp, 0, tmp.Length);
if (progress != null)
progress(m_fileStream.Position, m_fileStream.Length);
}
var descr = GetDescriptor();
var opcEnum = descr.OpcodeEnumType;
var authChallengeValue = (uint)opcEnum.GetField("SMSG_AUTH_CHALLENGE").GetRawConstantValue();
var authSessionValue = (uint)opcEnum.GetField("CMSG_AUTH_SESSION").GetRawConstantValue();
var contSessValue = (uint)opcEnum.GetField("CMSG_AUTH_CONTINUED_SESSION").GetRawConstantValue();
var challengeType = Type.GetType(opcEnum.Namespace + ".OpcodeDatas.AuthChallenge");
//var challengeSeed = challengeType.GetField("Seed");
var challengeClientSeed = challengeType.GetField("ClientSeed");
var challengeServerSeed = challengeType.GetField("ServerSeed");
//uint seed = 0;
byte[] ClientSeed = null;
byte[] ServerSeed = null;
var cryptToClient = new WowCrypt(Direction.ToClient);
var cryptToServer = new WowCrypt(Direction.ToServer);
byte[] chunkHdr = new byte[3 + 4];
var node = headers.First;
stream.Position = 0;
while (!stream.IsRead())
{
while (node.Next != null && node.Next.Value.m_position <= stream.Position)
node = node.Next;
var direction = node.Value.m_header.Direction;
var ticks = node.Value.m_header.TickCount;
int SizeLength = 2;
int Size = 0;
int OpcodeLength = (direction == Direction.ToServer) ? 4 : 2;
uint Opcode = 0;
bool large = (stream.ReadByte() & 0x80) != 0;
--stream.Position;
if (large)
SizeLength += 1;
stream.Read(chunkHdr, 0, SizeLength + OpcodeLength);
(direction == Direction.ToClient ? cryptToClient : cryptToServer).Process(chunkHdr, 0, SizeLength + OpcodeLength);
// Size includes OpcodeLength, but doesn't include SizeLength.
for (int j = 0; j < SizeLength; ++j)
Size = (Size << 8) | (int)(chunkHdr[i++] & (j == 0 ? 0x7F : 0xFF));
for (int j = 0; j < OpcodeLength; ++j)
Opcode |= (uint)chunkHdr[i++] << (j * 8);
byte[] data = new byte[Size - OpcodeLength];
stream.Read(data, 0, Size - OpcodeLength);
if (Opcode == authChallengeValue)
{
using (var _stream = new MemoryStream(data))
using (var _reader = new BinaryReader(_stream))
{
var challenge = Activator.CreateInstance(challengeType, _reader);
//seed = (uint)challengeSeed.GetValue(challenge);
ClientSeed = (byte[])challengeClientSeed.GetValue(challenge);
ServerSeed = (byte[])challengeServerSeed.GetValue(challenge);
}
}
else if (Opcode == authSessionValue)
{
cryptToClient.Init(SessionKey, null);
cryptToServer.Init(SessionKey, null);
}
else if (Opcode == contSessValue)
{
cryptToClient.Init(SessionKey, ClientSeed);
cryptToServer.Init(SessionKey, ServerSeed);
}
var wowPacket = new WowPacket(data, direction,
PacketFlags.None, Opcode,
(StartedOnUnix + (ticks - StartedOnTicks) / 1000).AsUnixTime(),
ticks,
Size - OpcodeLength, node.Value.m_header.ConnectionId);
m_packets.Add(wowPacket);
if (callback != null)
callback(wowPacket);
}
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
throw;
}
finally
{
stream.Close();
CloseFile();
}
@CarlosX
Copy link

CarlosX commented Sep 9, 2011

can post the cryptToClient class ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment