Created
August 12, 2015 07:05
-
-
Save synap5e/801072fbd7e3ee362df5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.IO; | |
using System.Net; | |
using System.Reflection; | |
using System.Runtime.Serialization.Formatters.Binary; | |
using System.Text; | |
using System.Threading; | |
namespace Hooks | |
{ | |
/* | |
* Watch the packets in real time like this: | |
* $ tail -f /cygdrive/s/Program\ Files\ \(x86\)/Hearthstone/Hearthstone_Data/output_log.txt | grep --line-buffered "####" | cut -c 6- | |
* | |
* Export to a file | |
* $ cat /cygdrive/s/Program\ Files\ \(x86\)/Hearthstone/Hearthstone_Data/output_log.txt | grep "####" | cut -c 6- > packets.txt | |
* | |
*/ | |
[RuntimeHookAttribute] | |
public class PacketLogger | |
{ | |
public PacketLogger() | |
{ | |
HookRegistry.Register(OnCall); | |
} | |
public static void Send(bool request, string payload) | |
{ | |
return; // TODO | |
} | |
private static string ValueToStr(object o, int depth=1) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
if (o is IProtoBuf){ | |
sb.Append("{\n#### "); | |
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties((IProtoBuf)o)) | |
{ | |
for (int i=0;i<depth;i++) | |
sb.Append(" "); | |
string name = descriptor.Name; | |
object v = descriptor.GetValue(o); | |
sb.Append("\"" + name + "\" : "); | |
sb.Append(ValueToStr(v, depth+1)); | |
sb.Append(",\n#### "); | |
} | |
for (int i = 0; i < depth-1; i++) | |
sb.Append(" "); | |
sb.Append("}"); | |
} | |
else if (o is IList) | |
{ | |
sb.Append("[\n#### "); | |
foreach (object e in ((IList)o)) | |
{ | |
for (int i = 0; i < depth; i++) | |
sb.Append(" "); | |
sb.Append(ValueToStr(e, depth + 1)); | |
sb.Append(",\n#### "); | |
} | |
for (int i = 0; i < depth - 1; i++) | |
sb.Append(" "); | |
sb.Append("]"); | |
} | |
else if (o == null) | |
{ | |
return "None"; | |
} | |
else | |
{ | |
return o.ToString(); | |
} | |
return sb.ToString(); | |
} | |
object OnCall(string typeName, string methodName, object thisObj, params object[] args) | |
{ | |
if (methodName == "UtilOutbound") | |
{ | |
IProtoBuf body = (IProtoBuf)args[2]; | |
Send(true, "(" + body.ToString() + ", " + ValueToStr(body)); | |
Log.Bob.Print("\n#### Request: " + body.ToString() + "\n#### " + ValueToStr(body) + "\n#### "); | |
return null; | |
} | |
else if (methodName == "NextUtilPacket") | |
{ | |
Type type = typeof(BattleNet); | |
FieldInfo info = type.GetField("s_impl", BindingFlags.NonPublic | BindingFlags.Static); | |
object value = info.GetValue(null); | |
IBattleNet s_impl = (IBattleNet)value; | |
PegasusPacket packet = s_impl.NextUtilPacket(); | |
if (packet != null && packet.Body is byte[]) | |
{ | |
type = typeof(ConnectAPI); | |
info = type.GetField("s_packetDecoders", BindingFlags.NonPublic | BindingFlags.Static); | |
value = info.GetValue(null); | |
SortedDictionary<int, ConnectAPI.PacketDecoder> s_packetDecoders = (SortedDictionary<int, ConnectAPI.PacketDecoder>)value; | |
PegasusPacket packetCopy = new PegasusPacket(packet.Type, packet.Context, packet.Size, packet.Body); | |
ConnectAPI.PacketDecoder packetDecoder; | |
if (s_packetDecoders.TryGetValue(packetCopy.Type, out packetDecoder)) | |
{ | |
PegasusPacket decodedPacket = packetDecoder.HandlePacket(packetCopy); | |
if (decodedPacket != null) | |
{ | |
IProtoBuf body = (IProtoBuf)(decodedPacket.Body); | |
Send(false, "(" + body.ToString() + ", " + ValueToStr(body)); | |
Log.Bob.Print("\n#### Response: " + body.ToString() + "\n#### " + ValueToStr(body) + "\n#### "); | |
} | |
} | |
return packet; | |
} | |
} | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment