// Dump data just as we receive it. private void DumpPacket(string typeName, object[] args) { // Maybe do some kind of double write protection here? var tee = TeeStream.Get(); object packet = args[0]; switch (typeName) { case "bgs.SslClientConnection": // The packet is always battle.net packet var packetData = (byte[])TypeBattleNetPacket.GetMethod("Encode").Invoke(packet, EMPTY_ARGS); tee.WriteBattlePacket(packetData, false); break; case "bgs.ClientConnection`1": // Test type of the packet. Type argType = packet.GetType(); if (argType.Equals(TypeBattleNetPacket)) { byte[] data = (byte[])TypeBattleNetPacket.GetMethod("Encode").Invoke(packet, EMPTY_ARGS); tee.WriteBattlePacket(data, false); } else if (argType.Equals(TypePegasusPacket)) { byte[] data = (byte[])TypePegasusPacket.GetMethod("Encode").Invoke(packet, EMPTY_ARGS); tee.WritePegasusPacket(data, false); } else { HookRegistry.Panic("Unknown packet type!"); } break; default: // Returning null here would just introduce undefined behaviour var msg = string.Format("Unknown typename: {0}!", typeName); HookRegistry.Panic(msg); break; } }
// Dumps the current packet onto the tee stream. // The packet has to be reconstructed according to the rules found in the respective // encoding(..) method. private void DumpPacket(string typeName, object thisObj) { TeeStream tee = TeeStream.Get(); // Container for our dumped packet. MemoryStream dataStream = new MemoryStream(); switch (typeName) { case "bgs.BattleNetPacket": { // Get data. object header = TypeBattleNetPacket.GetMethod("GetHeader").Invoke(thisObj, EMPTY_ARGS); // bnet.protocol.Header object data = TypeBattleNetPacket.GetMethod("GetBody").Invoke(thisObj, EMPTY_ARGS); // byte[] // Get sizes of packet parts. uint headerSize = (uint)TypeBattleNetHeader.GetMethod("GetSerializedSize").Invoke(header, EMPTY_ARGS); // uint int bodySize = ((byte[])data).Length; // Write sizes to buffer. int shiftedHeaderSize = ((int)headerSize >> 8); dataStream.WriteByte((byte)(shiftedHeaderSize & 0xff)); dataStream.WriteByte((byte)(headerSize & 0xff)); // Write header to buffer. TypeBattleNetHeader.GetMethod("Serialize", BindingFlags.Instance | BindingFlags.Public) .Invoke(header, new object[] { dataStream }); // Copy body to buffer. dataStream.Write((byte[])data, 0, bodySize); var packetData = dataStream.ToArray(); // Write data to tee stream. tee.WriteBattlePacket(packetData, true); } break; case "PegasusPacket": { // Get data. object data = TypePegasusPacket.GetMethod("GetBody").Invoke(thisObj, EMPTY_ARGS); // byte[] var typeField = TypePegasusPacket.GetField("Type"); object type = typeField.GetValue(thisObj); // int // Get size of body. int bodySize = ((byte[])data).Length; // Write sizes to buffer. byte[] typeBytes = BitConverter.GetBytes((int)type); // 4 bytes byte[] sizeBytes = BitConverter.GetBytes(bodySize); // 4 bytes dataStream.Write(typeBytes, 0, 4); dataStream.Write(sizeBytes, 0, 4); // Write body to the stream. dataStream.Write((byte[])data, 0, bodySize); var packetData = dataStream.ToArray(); // Write to tee stream. tee.WritePegasusPacket(packetData, true); } break; default: // Returning false here would just introduce undefined behaviour HookRegistry.Panic("Unknown typename!"); break; } }