Well I got the tcp for ventrilo down but the udp is giving problems.
Its a bit messy right now (trying to get it to just work), but this is the code.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
namespace Vent_Algos
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int GetTickCount();
byte[] EC_Key = { 0xAA, 0x55, 0x22, 0xCC, 0x69, 0x7C, 0x38, 0x91, 0x88, 0xF5, 0xE1 };
void EncryptConnect(ref byte[] buf) //Encrypt and decrypt
{
if (buf.Length < 1)
return;
int q = 0;
for (int i = 0; i < buf.Length; i++)
{
buf[i] += (byte)(EC_Key[q] + (i % 0x1B));
q = (q + 1) % 0xB;
}
}
void DecryptConnect(ref byte[] buf) //Encrypt and decrypt
{
if (buf.Length < 1)
return;
int q = 0;
for (int i = 0; i < buf.Length; i++)
{
buf[i] -= (byte)(EC_Key[q] + (i % 0x1B));
q = (q + 1) % 0xB;
}
}
int E_Step = 0;
void Encrypt(ref byte[] buf,byte[] Key) //Encrypt and decrypt
{
if (buf.Length < 1)
return;
for (int i = 0; i < buf.Length; i++)
{
buf[i] += (byte)(Key[E_Step] + (i % 0x2D));
E_Step = ((E_Step + 1) % Key.Length);
}
}
int D_Step = 0;
void Decrypt(ref byte[] buf, byte[] Key) //Encrypt and decrypt
{
if (buf.Length < 1)
return;
for (int i = 0; i < buf.Length; i++)
{
buf[i] -= (byte)(Key[D_Step] + (i % 0x2D));
D_Step = ((D_Step + 1) % Key.Length);
}
}
int MorphedTime(ref int time)
{
time = (time * 0x343FD) + 0x269EC3;
return (time >> 0x10) & 0x7FFF;
}
int Unknown(int t,byte[] Key)
{
t = t | (t << 0x8);
t = t | (t << 0x10);
int i = 0;
int t1;
int t2;
int t3;
int t4;
int t5;
t3 = t;
again:
t2 = BitConverter.ToInt32(Key,i);
t5 = 0x7EFEFEFF;
t1 = t2;
t4 = t5;
t2 = t2 ^ t3;
t4 += t1;
t5 += t2;
t2 = (int)(t2 ^ 0xFFFFFFFF);
t1 = (int)(t1 ^ 0xFFFFFFFF);
t2 = t2 ^ t5;
t1 = t1 ^ t4;
i+=4;
t2 = (int)(t2 & 0x81010100);
if (t2 != 0)
{
t1 = BitConverter.ToInt32(Key,i - 4);
t = t & 0xFF;
if (t == (t1 & 0xFF))
return i - 4;
if ((t1 & 0xFF) == 0)
return 0;
if (t == ((t1 & 0xFF00) >> 8))
return i - 3;
if (((t1 & 0xFF00) >> 8) == 0)
return 0;
t1 = t1 >> 0x10;
if (t == (t1 & 0xFF))
return i - 2;
if ((t1 & 0xFF) == 0)
return 0;
if (t == ((t1 & 0xFF00) >> 8))
return i - 1;
if (((t1 & 0xFF00) >> 8) == 0)
return 0;
goto again;
}
t1 = (int)(t1 & 0x81010100);
if (t1 == 0)
goto again;
t1 = t1 & 0x1010100;
if (t1 != 0)
return 0;
t4 = (int)(t4 & 0x80000000);
if (t4 != 0)
goto again;
return 0;
}
byte[] Unknown_Key = { 0x2C,0x23,0x27,0x60,0x2D,0x2B,0x2E,0x5F,0x7C,0x2F,0x3D,0x3A,0x22,0x5C,0x00,0x00};
byte[] GenerateKey(ref int time,int size)
{
byte[] ret = new byte[size];
int t = 0;
for (int i = size-1; i > -1; i--)
{
tryagain:
t = MorphedTime(ref time);
t = (int)(t & 0x8000007F);
if (t < 0)
{
t--;
t = (int)(t | 0xFFFFFF80);
t++;
}
if (t < 0x21)
goto tryagain;
if (t > 0x7F)
goto tryagain;
if (Unknown(t, Unknown_Key) != 0)
goto tryagain;
ret[i] = (byte)t;
}
return ret;
}
string _Version = "3.0.0";
string _Version2 = "3.0.1";
TcpClient TC;
byte[] E_Key;
byte[] D_Key;
short Endian(short num)
{
return (short)((num << 8) | (num >> 8));
}
ushort Endian(ushort num)
{
return (ushort)((num << 8) | (num >> 8));
}
int Endian(int num)
{
byte[] t = BitConverter.GetBytes(num);
Array.Reverse(t);
return BitConverter.ToInt32(t, 0);
}
uint Endian(uint num)
{
byte[] t = BitConverter.GetBytes(num);
Array.Reverse(t);
return BitConverter.ToUInt32(t, 0);
}
void Send(byte[] buf)
{
byte[] t = new byte[buf.Length + 2];
BitConverter.GetBytes((short)Endian((short)buf.Length)).CopyTo(t, 0);
Encrypt(ref buf, E_Key);
Array.Copy(buf, 0, t, 2, buf.Length);
TC.Client.Send(t);
}
void SendConnect(byte[] buf)
{
state = 0;
E_Step = 0;
D_Step = 0;
byte[] t = new byte[buf.Length + 2];
BitConverter.GetBytes((short)Endian((short)buf.Length)).CopyTo(t, 0);
EncryptConnect(ref buf);
Array.Copy(buf, 0, t, 2, buf.Length);
TC.Client.Send(t);
}
int state = 0;
bool ParsePacket(ref byte[] buf)
{
if (state == 0)
{
DecryptConnect(ref buf);
state++;
}
else
{
Decrypt(ref buf, D_Key);
}
switch (BitConverter.ToInt32(buf, 0))
{
case (0x6):
byte[] key = new byte[buf.Length - 12];
Array.Copy(buf, 12, key, 0, key.Length);
int len = Unknown(0x7C, key);
E_Key = new byte[len];
int i = len;
while (i < (buf.Length - 12))
{
if (key[i] == 0)
{
break;
}
i++;
}
i--;
D_Key = new byte[i - len];
Array.Copy(key, 0, E_Key, 0, len);
Array.Copy(key, len + 1, D_Key, 0, i - len);
byte[] p = new byte[0x118];
p[0] = 0x48;
p[4] = 2;
p[0xC] = 0x7F;
p[0xF] = 1;
BitConverter.GetBytes(0x1F137).CopyTo(p, 0x10);
p[0x16] = 1;
Array.Copy(new byte[] { 0xBE, 0x31, 0x82, 0x95, 0x6E, 0xEA, 0xCF, 0x91, 0x0D, 0x0F, 0x98, 0xA1, 0xAB, 0x44, 0x4B, 0x76 },0,p,0x18,0x10);
Encoding.ASCII.GetBytes(_Version2).CopyTo(p, 0x28);
Encoding.ASCII.GetBytes(_Version).CopyTo(p, 0x68);
Encoding.ASCII.GetBytes("High").CopyTo(p, 0x98);
Encoding.ASCII.GetBytes("WIN32").CopyTo(p, 0xD8);
Send(p);
break;
case (0x37): //Ping PONG!
Send(buf);
break;
default:
break;
}
return true;
}
bool ParsePacketFrom(ref byte[] buf)
{
switch (BitConverter.ToInt32(buf, 0))
{
default:
break;
}
return true;
}
byte[] RollOver = new byte[0];
void Recv(IAsyncResult ar)
{
if (ar == null || TC == null)
return;
byte[] buf = (byte[])ar.AsyncState;
int read = TC.Client.EndReceive(ar);
if (read > 0)
{
Array.Resize(ref buf, read);
if (RollOver.Length > 0)
{
byte[] t = new byte[buf.Length + RollOver.Length];
Array.Copy(RollOver, t, RollOver.Length);
Array.Copy(buf, 0, t, RollOver.Length, buf.Length);
buf = t;
}
ushort start = 0;
int i = 0;
while (i < read)
{
start = Endian(BitConverter.ToUInt16(buf, i));
if (start + i > read)
{
Array.Resize(ref RollOver, read - i);
Array.Copy(buf, i, RollOver, 0, read - i);
break;
}
byte[] packet = new byte[start];
Array.Copy(buf, i + 2, packet, 0, start);
if (!ParsePacket(ref packet))
return;
i += start + 2;
}
}
buf = new byte[0x200];
TC.Client.BeginReceive(buf, 0, 0x200, SocketFlags.None, Recv, buf);
}
byte[] RollOverFrom = new byte[0];
void RecvFrom(IAsyncResult ar)
{
if (ar == null || UC == null)
return;
passa p = (passa)ar.AsyncState;
byte[] buf = p.bytes;
EndPoint ep = p.ep;
int read = UC.Client.EndReceiveFrom(ar, ref ep);
if (read > 0)
{
Array.Resize(ref buf, read);
if (RollOverFrom.Length > 0)
{
byte[] t = new byte[buf.Length + RollOverFrom.Length];
Array.Copy(RollOverFrom, t, RollOverFrom.Length);
Array.Copy(buf, 0, t, RollOverFrom.Length, buf.Length);
buf = t;
}
ushort start = 0;
int i = 0;
while (i < read)
{
start = Endian(BitConverter.ToUInt16(buf, i+0xA));
if (start + i > read)
{
Array.Resize(ref RollOverFrom, read - i);
Array.Copy(buf, i, RollOverFrom, 0, read - i);
break;
}
byte[] packet = new byte[start];
Array.Copy(buf, i, packet, 0, start);
if (!ParsePacketFrom(ref packet))
return;
i += start;
}
}
buf = new byte[0x200];
UC.Client.BeginReceiveFrom(buf, 0, 0x200, SocketFlags.None,ref ep, RecvFrom, buf);
}
void DecryptUDP(ref byte[] buf,uint keyy)
{
byte[] key = BitConverter.GetBytes(keyy);
for (int i = 0x10; i < Math.Min(buf.Length, 200); i++)
{
buf[i] -= key[i & 3];
}
}
void EncryptUDP(ref byte[] buf, uint keyy,byte idx)
{
byte[] key = BitConverter.GetBytes(keyy);
idx = (byte)((key[0] & 0xF) * idx);
for (int i = 0x10; i < Math.Min(buf.Length, 200); i++)
{
buf[i] += key[(idx+i) & 3];
}
}
byte[] EncryptUDP(byte[] buf, uint keyy,byte idx)
{
byte[] ret = new byte[buf.Length];
buf.CopyTo(ret, 0);
byte[] key = BitConverter.GetBytes(keyy);
idx = (byte)((key[0] & 0xF) * idx);
for (int i = 0x10; i < Math.Min(buf.Length, 200); i++)
{
ret[i] += key[(idx + i) & 3];
}
return ret;
}
EndPoint EP;
UdpClient UC;
struct ventrilo3_auth
{
public uint key;
public int port;
public ventrilo3_auth(uint k, int p)
{
key = k;
port = p;
}
}
struct passa
{
public EndPoint ep;
public byte[] bytes;
public passa(EndPoint e,byte[] b)
{
ep = e;
bytes = b;
}
}
ventrilo3_auth[] va = {
new ventrilo3_auth( 0x48332e1f, 6100 ),
new ventrilo3_auth( 0x4022b2b2, 6100 ),
new ventrilo3_auth( 0x3dc24a36, 6100 ),
new ventrilo3_auth( 0x46556ef2, 6100 )
};
private void Form1_Load(object sender, EventArgs e)
{
TC = new TcpClient();
UC = new UdpClient();
TC.Connect("127.0.0.1", 3784);
UC.Connect("127.0.0.1", 3784);
EP = UC.Client.RemoteEndPoint;
byte[] p = new byte[0x54];
Encoding.ASCII.GetBytes(_Version).CopyTo(p,4);
int time = GetTickCount();
Array.Copy(GenerateKey(ref time,0x1F),0,p,0x14,0x1F);
Array.Copy(GenerateKey(ref time,0x1F),0,p,0x34,0x1F);
SendConnect(p);
byte[] p2 = { 0x00, 0x00, 0x00, 0x00, 0x55, 0x44, 0x43, 0x4C, 0x00, 0x04, 0x00, 0xC8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x65, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte[] p3 = { 0x00, 0x00, 0x00, 0x00, 0x55, 0x44, 0x43, 0x4C, 0x00, 0x05, 0x00, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xC5, 0x03, 0x4B, 0x7E, 0x03, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x7E, 0x03, 0x22, 0x47, 0xB0, 0x95, 0x77, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFC, 0x00, 0x00, 0x4B, 0x7E, 0x03, 0x22, 0x72, 0x19, 0xF6, 0x87, 0x3E, 0xAE, 0x6D, 0x61, 0xD3, 0x7A, 0x87, 0xF1, 0xE2, 0x61, 0x54, 0x2B, 0x57, 0x49, 0x4E, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x2E, 0x30, 0x2E, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
UC.Client.SendTo(p2, EP);
byte[] buf2 = new byte[0x200];
UC.Client.BeginReceiveFrom(buf2, 0, 0x200, SocketFlags.None, ref EP, RecvFrom, buf2);
for (int i = 0; i < 4; i++)
{
EndPoint ep = new IPEndPoint(va[i].key, va[i].port);
UC.Client.SendTo(EncryptUDP(p3, Endian(va[i].key), (byte)(i+1)), ep);
byte[] buf3 = new byte[0x200];
passa pp = new passa(ep, buf3);
UC.Client.ReceiveFrom(buf3,ref ep);
}
byte[] buf = new byte[0x200];
TC.Client.BeginReceive(buf, 0, 0x200, SocketFlags.None, Recv, buf);
//byte[] buf2 = new byte[0x200];
//UC.Client.BeginReceiveFrom(buf2, 0, 0x200, SocketFlags.None, ref EP, RecvFrom, buf2);
}
}
}
Yes I know its messy/etc, just trying to get it working, then plan on rewriting.
So first recvfrom packet is received but the other 4 aren't.