Created
December 19, 2017 18:07
-
-
Save tomzorz/4ee9a03af84d2e83056b6a7acedcd16e to your computer and use it in GitHub Desktop.
Reverse engineering the Unity Network Discovery protocol to broadcast from a 3rd party source
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
// see blog post here: https://shoreparty.org/reverse-engineering-the-unity-network-discovery-protocol-9cd01280ed08 | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Net.NetworkInformation; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.Threading; | |
namespace UnityNetworkDicoveryReimplementation | |
{ | |
class Program | |
{ | |
private static byte[] GetBytesForInt(int i) => BitConverter.GetBytes(i).Reverse().ToArray(); | |
private static byte[] CreateMessage() | |
{ | |
var l = new List<byte>(); | |
l.AddRange(new byte[] {0x00, 0x00, 0x09}); // prefix | |
var rand = new byte[2]; | |
new Random().NextBytes(rand); | |
l.AddRange(rand); // random value per started session | |
l.AddRange(GetBytesForInt(36001)); // KEY | |
l.AddRange(Enumerable.Repeat(0, 4*8).Select(x => (byte)x)); // padding | |
l.AddRange(GetBytesForInt(1)); // VER | |
l.AddRange(GetBytesForInt(1)); // SUBVER | |
l.AddRange(Encoding.ASCII.GetBytes("test data please ignore").Select(x => new byte[]{x, 0x00}).SelectMany(y => y)); // DATA | |
return l.ToArray(); | |
} | |
static void Main(string[] args) | |
{ | |
var interfaces = NetworkInterface.GetAllNetworkInterfaces().Where(x => x.GetIPProperties().GatewayAddresses.Any()).ToList(); | |
var dict = interfaces.ToDictionary(x => x, y => y.GetIPProperties().GatewayAddresses[0].Address); | |
var msg = CreateMessage(); | |
var uc = new UdpClient(); | |
while (true) | |
{ | |
Thread.Sleep(2000); | |
foreach (var id in dict) | |
{ | |
Console.WriteLine($"Sending broadcast for interface {id.Key.Name} {id.Value}"); | |
var broadcastIp = new IPAddress(id.Value.GetAddressBytes().Take(3).Concat(new[] {(byte) 0xff}).ToArray()); | |
uc.Send(msg, msg.Length, broadcastIp.ToString(), 64764); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment