Hi,
In the past I've worked a lot with VB6 and am now migrating many functions and projects to C#.
I'm trying to connect the bot using WAR3 and continually get IP-Banned from any server I connect to right after sending 0x51. Usually when I get this problem I've overlooked a packet format or something. I've tried to make the source as close as I can to that which works in VB6, but have been unsuccessful in getting it to connect.
One thing I found odd, yet seems to be correct is the Version and Checksum values in BNLS S->C 0x1A overlap and render the leading 0xFF unused.
Below I've included the entire packet log, but I'm unsure of which functions to post (as I can't seem to narrow down where the problem is).
Any help would be very much appreciated, Thanks
Client -> BNLS
0000: 07 00 10 07 00 00 00 ................
Client -> BNLS
0000: 07 00 0D 02 00 00 00 ................
BNLS -> Client
0000: 0B 00 10 07 00 00 00 15 00 00 00 ................
Client -> BNET
0000: FF 50 3A 00 00 00 00 00 36 38 58 49 33 52 41 57 ÿP:.....68XI3RAW
0001: 15 00 00 00 00 00 00 00 00 00 00 00 80 04 00 00 ................
0002: 33 10 00 00 33 10 00 00 55 53 41 00 55 6E 69 74 3...3...USA.Unit
0003: 65 64 20 53 74 61 74 65 73 00 ed States.......
BNLS -> Client
0000: 07 00 0D 01 00 00 00 ................
BNET -> Client
0000: FF 25 08 00 10 EC F0 26 ÿ%...ìð&........
BNET -> Client
0000: FF 50 E7 00 02 00 00 00 1F E9 15 BE 15 35 3B 00 ÿPç......é.¾.5;.
0001: 00 4D 89 7E 99 CB C6 01 76 65 72 2D 49 58 38 36 .M.~.ËÆ.ver-IX86
0002: 2D 37 2E 6D 70 71 00 41 3D 32 36 38 33 39 33 31 -7.mpq.A=2683931
0003: 39 30 33 20 43 3D 39 31 35 38 32 34 36 39 32 20 903 C=915824692
0004: 42 3D 32 31 35 39 31 39 31 38 39 39 20 34 20 41 B=2159191899 4 A
0005: 3D 41 2D 53 20 42 3D 42 5E 43 20 43 3D 43 5E 41 =A-S B=B^C C=C^A
0006: 20 41 3D 41 2D 42 00 93 DB 9F BB 28 04 86 BF 3C A=A-B..Û»(..¿<
0007: 37 7C ED 41 4E 0D 37 50 33 98 FA 55 4A 85 1D 37 7|íAN.7P3.úUJ..7
0008: FF FD 2C BB E3 F0 98 97 E4 5F C1 32 C7 11 EF C7 ÿý,»ãð..ä_Á2Ç.ïÇ
0009: 1A FB 4A 1A 6C A4 2F 0D 82 22 7E 95 F4 C2 3A E5 .ûJ.l¤/.."~.ôÂ:å
0010: 89 57 03 6B D7 4B 8A EB D5 70 83 DB AA 13 21 C5 .W.k×K.ëÕp.Ûª.!Å
0011: 4D F3 B2 49 E8 F6 4D D1 B7 CC D9 88 4D 5B 12 B5 Mó²IèöMÑ·ÌÙ.M[.µ
0012: B4 70 6F DC B9 07 0A 60 C4 32 F7 5F EC 31 33 57 ´poܹ..`Ä2÷_ì13W
0013: 2A FA F7 7F E5 3C FF 41 97 6F 85 E6 0D 05 99 81 *ú÷å<ÿA.o.æ....
0014: 6D 80 E2 6A 5D 2D 0A m.âj]-..........
Client -> BNLS
0000: 66 00 1A 07 00 00 00 00 00 00 00 01 00 00 00 00 f...............
0001: 4D 89 7E 99 CB C6 01 76 65 72 2D 49 58 38 36 2D M.~.ËÆ.ver-IX86-
0002: 37 2E 6D 70 71 00 41 3D 32 36 38 33 39 33 31 39 7.mpq.A=26839319
0003: 30 33 20 43 3D 39 31 35 38 32 34 36 39 32 20 42 03 C=915824692 B
0004: 3D 32 31 35 39 31 39 31 38 39 39 20 34 20 41 3D =2159191899 4 A=
0005: 41 2D 53 20 42 3D 42 5E 43 20 43 3D 43 5E 41 20 A-S B=B^C C=C^A
0006: 41 3D 41 2D 42 00 A=A-B...........
BNLS -> Client
0000: 39 00 1A 01 00 00 00 FF FF FF 9C FD 01 03 D9 77 9......ÿÿÿ.ý..Ùw
0001: 61 72 33 2E 65 78 65 20 30 36 2F 31 39 2F 30 37 ar3.exe 06/19/07
0002: 20 31 34 3A 34 31 3A 31 32 20 34 30 39 36 36 30 14:41:12 409660
0003: 00 01 00 00 00 15 00 00 00 ................
Client -> BNLS
0000: 22 00 01 1F E9 15 BE -- -- -- -- -- -- -- -- -- "...é.¾---------
0001: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------
0002: -- 00 -...............
BNLS -> Client
0000: 2F 00 01 01 00 00 00 D4 08 DE 5E 1A 00 00 00 0E /......Ô.Þ^.....
0001: 00 00 00 F0 2F 20 00 00 00 00 00 93 9D 0D 43 FD ...ð/ ........Cý
0002: 09 41 A8 C2 83 49 92 29 4F CD 9E 37 5C 97 30 .A¨Â.I.)OÍ.7\.0.
Client -> BNET
0000: FF 51 68 00 D4 08 DE 5E FF FF 9C FD FD 01 03 D9 ÿQh.Ô.Þ^ÿÿ.ýý..Ù
0001: 01 00 00 00 00 00 00 00 1A 00 00 00 0E 00 00 00 ................
0002: F0 2F 20 00 00 00 00 00 93 9D 0D 43 FD 09 41 A8 ð/ ........Cý.A¨
0003: C2 83 49 92 29 4F CD 9E 37 5C 97 30 77 61 72 33 Â.I.)OÍ.7\.0war3
0004: 2E 65 78 65 20 30 36 2F 31 39 2F 30 37 20 31 34 .exe 06/19/07 14
0005: 3A 34 31 3A 31 32 20 34 30 39 36 36 30 00 53 6F :41:12 409660.So
0006: 6D 65 74 68 69 6E 67 00 mething.........
BNET -> Client
0000: FF 51 09 00 00 02 00 00 00 ÿQ..............
FF 51 68 00 ÿQh. - Header
D4 08 DE 5E Ô.Þ^ - Client Token
FF FF 9C FD ÿÿ.ý - Exe Ver (This dosent look right)
FD 01 03 D9 ý..Ù - Exe Hash
01 00 00 00 .... - Key Count
00 00 00 00 .... - non-spawn
1A 00 00 00 .... - Length
0E 00 00 00 .... - Product
F0 2F 20 00 ð/ . - Public
00 00 00 00 .... - Unknown(0)
93 9D 0D 43 FD 09 41 A8 C2 83 49 92 29 4F CD 9E 37 5C 97 30 ...Cý.A¨Â.I.)OÍ.7\.0 - Key Hash
77 61 72 33 2E 65 78 65 20 30 36 2F 31 39 2F 30 37 20 31 34 3A 34 31 3A 31 32 20 34 30 39 36 36 30 00 war3.exe 06/19/07 14:41:12 409660. - Exe Info
53 6F 6D 65 74 68 69 6E 67 00 Something. - Owner
Everything looks right format wise, but Something is messed up in your BNLS server as it's returning weird values.
What BNLS server are you using, as none that I know of have 'overlap' issues [Overflow is the word i think you're looking for]
The server you're using may be simply hashing the key wrong if it has issues like this.
Yea, I've gone over the packet documentation a few times and it looks right, but something is getting messed up ;)
What I meant by the overlap is in BNLS 0x1A:
BNLS -> Client [0x1A]
0000: 39 00 | 1A | 01 00 00 00 | FF FF FF 9C | FD 01 03 D9 ...
Length PackID Success Version Checksum
Is my labeling right for that part of the packet? The packet format suggests that Version = 0x9CFFFFFF and Checksum = 0xD90301FD (the value shown in the packet). However, in the VB version of the code that is working, Version = 0xFD9CFFFF and Checksum = 0xD90301FD. (Note the overlapping of 0xFD in the two DWORDs/variables.) The first 0xFF in the Version DWORD (right after Success DWORD) of the packet then appears to be unused.
This is the packet format the VB program says is correct:
BNLS -> Client [0x1A]
| Checksum |
0000: 39 00 | 1A | 01 00 00 00 | FF | FF FF 9C FD 01 03 D9 ...
Length PackID Success Unused
| Version |
I tried two different BNLS servers -- pyro.no-ip.biz and hdx.jbls.org, both resulting in the same issue.
Thanks
It's probable that your packet parsing code itself is wrong. Show us it?
Here's the code from clsParse:
public clsPacketBuffer PBuffer;
public clsEvents Events;
public Socket sckBNET;
public Socket sckBNLS;
public frmMain frmmain;
//BNLS Connection Variables
private long VerByte;
private long SessionKey;
private long version;
private long Checksum;
private string VersionStatString;
private string CDKeyHash;
private long GTC;
public void ParseDataBNET(string Data)
{
//Create and set the debuffer
clsPacketDebuffer Debuffer = new clsPacketDebuffer();
Debuffer.SetPacketBNET(Data);
//Get the Packet ID
int PacketID = System.Convert.ToInt32(Encoding.Default.GetBytes(Data.Substring(1, 1))[0]);
//Parse the packet
switch (PacketID)
{
case 0x50:
long NLSRevision = Debuffer.GetDWORD();
SessionKey = LongFromDWORD(Data.Substring(8, 4));
string MPQFileTime = Data.Substring(16, 8);
string MPQFileName = Data.Substring(24, 14);
string Hash = Debuffer.GetStringAt(35);
switch (frmmain.Connection.vClient)
{
case "WAR3":
PBuffer.InsertDWORD(0x07);
break;
default:
frmmain.AddChat(frmMain.AddChatType.Error, "Invalid client selected.", frmMain.AddChatColor.Error);
frmmain.Connection.CloseandUnload();
return;
break;
}
PBuffer.InsertDWORD(0); //Flags
PBuffer.InsertDWORD(1); //Cookie
PBuffer.InsertNonNTString(MPQFileTime.ToString()); //MPQ File Time
PBuffer.InsertNTString(MPQFileName.ToString()); //MPQ File Name
PBuffer.InsertNTString(Hash); //Checksum Formula
PBuffer.SendPacketBNLS(0x1A);
break;
case 0x25:
PBuffer.InsertNonNTString(Data);
PBuffer.SendRaw(sckBNET);
break;
case 0x51:
switch (IntFromWORD(Data.Substring(4,2)))
{
case 0x00: //Key Accepted
switch (frmmain.Connection.vClient)
{
case "WAR3":
PBuffer.InsertNTString(frmmain.Connection.vUsername);
PBuffer.InsertNTString(frmmain.Connection.vPassword);
PBuffer.SendPacketBNLS(0x02);
break;
case "D2DV":
PBuffer.InsertDWORD(frmmain.Connection.vPassword.Length);
PBuffer.InsertDWORD(0x02);
PBuffer.InsertNonNTString(frmmain.Connection.vPassword);
PBuffer.InsertDWORD(2048);
PBuffer.InsertDWORD(SessionKey);
PBuffer.SendPacketBNLS(0x0B);
break;
default:
break;
}
break;
case 0x100: //CheckRevision Failure
break;
case 0x101: //CheckRevision Failure
break;
case 0x200: //Key Bad
break;
case 0x203: //Wrong Product
break;
case 0x202: //Key Banned
break;
case 0x201: //Key In Use
break;
default: //Version Check Failed
break;
}
break;
case 0x53:
if (Asc(Data.Substring(4, 1)) == 0x01)
{
//Attempt to create the account
PBuffer.InsertNTString(frmmain.Connection.vUsername);
PBuffer.InsertNTString(frmmain.Connection.vPassword);
PBuffer.SendPacketBNLS(0x04);
}
else
{
PBuffer.InsertNonNTString(Data.Substring(8, 64));
PBuffer.SendPacketBNLS(0x03);
}
break;
}
}
public void ParseDataBNLS(string Data)
{
//Create and set the debuffer
clsPacketDebuffer Debuffer = new clsPacketDebuffer();
Debuffer.SetPacketBNLS(Data);
//Get the Packet ID
int PacketID = System.Convert.ToInt32(Encoding.Default.GetBytes(Data.Substring(2, 1))[0]);
//Parse the packet
switch (PacketID)
{
case 0x00:
break;
case 0x0D:
break;
case 0x10:
long junk_0x10 = Debuffer.GetDWORD();
VerByte = Debuffer.GetDWORD();
frmmain.Connection.ConnectBNET();
break;
case 0x1A:
bool success = Convert.ToBoolean(LongFromDWORD(Data.Substring(3, 4)));
version = LongFromDWORD(Data.Substring(8, 4));
Checksum = LongFromDWORD(Data.Substring(11, 4));
VersionStatString = Debuffer.GetStringAt(12);
long cookie = LongFromDWORD(Data.Substring((15 + VersionStatString.Length + 1), 4));
long versioncode = LongFromDWORD(Data.Substring((19 + VersionStatString.Length + 1), 4));
long versioncode2 = LongFromDWORD(Data.Substring((15 + VersionStatString.Length + 1), 4));
//Construct and send BNLS packet 0x01
PBuffer.InsertDWORD(SessionKey);
PBuffer.InsertNTString(frmmain.Connection.vCDKey);
PBuffer.SendPacketBNLS(0x01);
break;
case 0x01:
long success0x01 = Debuffer.GetDWORD();
CDKeyHash = Data.Substring(11);
GTC = LongFromDWORD(Data.Substring(7, 4));
//Send packet 0x51
Send0x51();
break;
case 0x02:
PBuffer.InsertNonNTString(Data.Substring(3));
PBuffer.InsertNTString(frmmain.Connection.vUsername);
PBuffer.SendPacketBNET(0x53);
break;
}
}
public void Send0x50()
{
//Reverse the client string
char[] tmpReverse = frmmain.Connection.vClient.ToCharArray();
Array.Reverse(tmpReverse);
string tmpClient = new string(tmpReverse);
//Construct and send packet 0x50
PBuffer.InsertDWORD(0x00);
PBuffer.InsertNonNTString("68XI" + tmpClient);
PBuffer.InsertDWORD(VerByte);
PBuffer.InsertDWORD(0x00);
PBuffer.InsertDWORD(0x00);
PBuffer.InsertDWORD(0x480);
PBuffer.InsertDWORD(0x1033);
PBuffer.InsertDWORD(0x1033);
PBuffer.InsertNTString("USA");
PBuffer.InsertNTString("United States");
PBuffer.SendPacketBNET(0x50);
}
public void Send0x51()
{
PBuffer.InsertDWORD(GTC);
PBuffer.InsertDWORD(version);
PBuffer.InsertDWORD(Checksum);
PBuffer.InsertDWORD(0x01);
PBuffer.InsertDWORD(0x00);
PBuffer.InsertNonNTString(CDKeyHash);
PBuffer.InsertNTString(VersionStatString);
PBuffer.InsertNTString("Sovereign");
PBuffer.SendPacketBNET(0x51);
}
private int IntFromWORD(string WORD)
{
//Return 0 if not a WORD
if (WORD.Length < 2)
{
return 0;
}
//Get the 2 byte values
int value2 = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(WORD.Substring(1, 1))));
int value = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(WORD.Substring(0, 1))));
value += (value2 * 256);
return value;
}
private int Asc(string Value)
{
return (int)Value.ToCharArray()[0];
}
private long LongFromDWORD(string DWORD)
{
//Return 0 if not a DWORD
if (DWORD.Length < 4)
{
return 0;
}
//Get the 4 byte values
int value4 = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(3, 1))));
int value3 = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(2, 1))));
int value2 = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(1, 1))));
int value = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(0, 1))));
value += (value2 * 256) + (value3 * 256 * 256) + (value4 * 256 * 256 * 256);
return value;
}
Here's the clsPacketBuffer class:
public Socket sckBNET;
public Socket sckBNLS;
private string buffer = "";
private string MakeWORD(int Value)
{
string returnstr = "";
//Return format: 11 22
// 01 00
if (Value <= 255)
{
returnstr += Convert.ToString(Convert.ToChar(Value));
//Add 1 characters in back
returnstr += Convert.ToString(Convert.ToChar(0));
}
else if (Value <= 65025) //255 ^ 2
{
//Value / 256 = tmp
//256 * Int(above_rtn) = byte2
//Value - (byte2 * 256) = byte1
long tmp = Value / 255;
long byte2 = 255 * tmp;
long byte1 = Value - (byte2 * 255);
returnstr += Convert.ToString(Convert.ToChar(byte1));
returnstr += Convert.ToString(Convert.ToChar(byte2));
}
return returnstr;
}
public string MakeDWORD(long Value)
{
byte b0 = (byte)((Value & 0xFF000000) >> 24);
byte b1 = (byte)((Value & 0x00FF0000) >> 16);
byte b2 = (byte)((Value & 0x0000FF00) >> 8);
byte b3 = (byte)(Value & 0x000000FF);
return Convert.ToChar(b3).ToString() + Convert.ToChar(b2).ToString() + Convert.ToChar(b1).ToString() + Convert.ToChar(b0).ToString();
}
public void InsertDWORD(long Data)
{
buffer += MakeDWORD(Data);
}
public void InsertData(string Data)
{
buffer += Data;
}
public void InsertByte(byte Data)
{
buffer += Convert.ToString(Convert.ToChar(Data));
}
public void InsertByteArray(byte[] Data)
{
int i;
for (i = Data.GetLowerBound(0); i <= Data.GetUpperBound(0); i++)
{
buffer += Convert.ToString(Convert.ToChar(Data[i]));
}
}
public void InsertNTString(string Data)
{
buffer += Data + Convert.ToString(Convert.ToChar(0));
}
public void InsertNonNTString(string Data)
{
buffer += Data;
}
public void SendPacketBNET(int PacketID)
{
//Construct the byte array to send
string tmpbuffer = "";
tmpbuffer += Convert.ToString(Convert.ToChar(0xFF));
tmpbuffer += Convert.ToString(Convert.ToChar(PacketID));
tmpbuffer += MakeWORD(buffer.Length + 4);
tmpbuffer += buffer;
byte[] Data = Encoding.Default.GetBytes(tmpbuffer);
//Send the byte array
sckBNET.Send(Data);
//Debug Dump
System.Diagnostics.Debug.Print("\nClient -> BNET");
System.Diagnostics.Debug.Print(DebugOutput(tmpbuffer));
buffer = "";
}
public void SendPacketBNLS(int PacketID)
{
//Construct the byte array to send
string tmpbuffer = "";
tmpbuffer += MakeWORD(buffer.Length + 3);
tmpbuffer += Convert.ToString(Convert.ToChar(PacketID));
tmpbuffer += buffer;
byte[] Data = Encoding.Default.GetBytes(tmpbuffer);
//Send the byte array
sckBNLS.Send(Data);
//Debug Dump
System.Diagnostics.Debug.Print("\nClient -> BNLS");
System.Diagnostics.Debug.Print(DebugOutput(tmpbuffer));
buffer = "";
}
public void SendRaw(Socket sck)
{
//Construct the byte array to send
string tmpbuffer = buffer;
byte[] Data = Encoding.Default.GetBytes(tmpbuffer);
//Send the byte array
sck.Send(Data);
buffer = "";
}
private string Chr(int Value)
{
return ((char)Value).ToString();
}
private int Asc(string Value)
{
return (int)Value.ToCharArray()[0];
}
private long LongFromDWORD(string DWORD)
{
//Return 0 if not a DWORD
if (DWORD.Length < 4)
{
return 0;
}
//Get the 4 byte values
int value4 = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(3, 1))));
int value3 = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(2, 1))));
int value2 = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(1, 1))));
int value = System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(DWORD.Substring(0, 1))));
value += (value2 * 256) + (value3 * 256 * 256) + (value4 * 256 * 256 * 256);
return value;
}
public string DebugOutput(string Data)
{
//Output to format:
// returnstr1 returnstr2
//0001: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 1234567890123456
//0002: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 1234567890123456
//0003: 01 02 03 04 05 06 07 08 12345678........
string returnstr1 = "";
string returnstr2 = "";
int limit = 0;
int maxlimit = 16;
for (int i = 0; i < Data.Length; i++)
{
//Limit bytes per line to maxlimit
if (limit == maxlimit)
{
limit = 0;
returnstr1 += "\n";
returnstr2 += "\n";
}
//Add the data to the output
//returnstr1 += HexFromInt(IntFromWORD(Data.Substring(i, 1) + Convert.ToChar(0).ToString()));
returnstr1 += HexFormat(HexFromInt(System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(Data.Substring(i, 1)))))) + " ";
//System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(WORD.Substring(0, 1))))
returnstr2 += ChrFormat(Data.Substring(i, 1));
//Increase limit
limit++;
}
//Split the returnstr into array by "\n"
//Check length of each line for (maxlimit + (maxlimit * 3) + 4)
char[] delimeter = { "\n".ToCharArray()[0] };
string[] split1 = returnstr1.Split(delimeter);
string[] split2 = returnstr2.Split(delimeter);
string returnstr = "";
//Rebuild the returnstr
for (int i = split1.GetLowerBound(0); i <= split1.GetUpperBound(0); i++)
{
//Check length of returnstr1
while (split1[i].Length < (3 * maxlimit))
{
split1[i] += " ";
}
//Check length of returnstr2
while (split2[i].Length < maxlimit)
{
split2[i] += ".";
}
returnstr += LineFormat(i) + ": " + split1[i] + " " + split2[i] + "\n";
}
//Return returnstr
return returnstr;
}
private string LineFormat(int LineNum)
{
//Output "0001" from input of 1
switch (LineNum.ToString().Length)
{
case 1:
return "000" + LineNum.ToString();
break;
case 2:
return "00" + LineNum.ToString();
break;
case 3:
return "0" + LineNum.ToString();
break;
default:
return LineNum.ToString();
break;
}
}
private string HexFormat(string HEX)
{
switch (HEX.Length)
{
case 1:
return "0" + HEX;
break;
default:
return HEX;
break;
}
}
private string ChrFormat(string CHR)
{
if (System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(CHR))) < 32)
{
return ".";
}
else if ((System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(CHR))) > 127) && (System.Convert.ToInt32(Convert.ToByte(Convert.ToChar(CHR))) < (127 + 32)))
{
return ".";
}
else
{
return CHR;
}
}
private string HexFromInt(int INT)
{
//return Convert.ToInt32(INT, 16);
return INT.ToString("X");
}
Since I had so many problems with the MakeDWORD() function (and ended up temporarily copying one I found on the forums), I'd assume there's probably also a problem with the MakeWORD() function. It hasn't poked its head out yet, so I haven't taken the time to look over it yet.
well if you're using bnls.valhallalegends.com it's not updated for latest war3
You're using strings as buffers and getting problems? Surprise surprise. .NET isn't VB6.
I decided to packet log the bot two different ways to check my thoughts of it has to be some format or conversion issue. Here's what I found:
Client -> BNET
0000: FF 50 3A 00 00 00 00 00 36 38 58 49 33 52 41 57 ÿP:.....68XI3RAW
0001: 15 00 00 00 00 00 00 00 00 00 00 00 80 04 00 00 ................
0002: 33 10 00 00 33 10 00 00 55 53 41 00 55 6E 69 74 3...3...USA.Unit
0003: 65 64 20 53 74 61 74 65 73 00 ed States.......
Client -> BNET
0000: FF 50 3A 00 00 00 00 00 36 38 58 49 33 52 41 57 ÿP:.....68XI3RAW
0001: 15 00 00 00 00 00 00 00 00 00 00 00 3F 04 00 00 ............?...
0002: 33 10 00 00 33 10 00 00 55 53 41 00 55 6E 69 74 3...3...USA.Unit
0003: 65 64 20 53 74 61 74 65 73 00 ed States.......
C->S 0x51 looks ok, but I found this to be interesting:
Client -> BNET
0000: FF 51 68 00 ED DA 98 5C FF FF 9C E7 E7 3A A3 30 ÿQh.íÚ.\ÿÿ.çç:£0
0001: 01 00 00 00 00 00 00 00 1A 00 00 00 0E 00 00 00 ................
0002: F0 2F 20 00 00 00 00 00 E5 8C 3F F5 1C 85 E7 9A ð/ .....å.?õ..ç.
0003: 2E 83 C9 D8 AB B3 0F 98 03 D5 FF C7 77 61 72 33 ..ÉØ«³...ÕÿÇwar3
0004: 2E 65 78 65 20 30 36 2F 31 39 2F 30 37 20 31 31 .exe 06/19/07 11
0005: 3A 34 31 3A 31 34 20 34 30 39 36 36 30 00 53 6F :41:14 409660.So
0006: 6D 65 74 68 69 6E 67 00 mething.........
Client -> BNET
0000: FF 51 68 00 ED DA 3F 5C FF FF 3F E7 E7 3A A3 30 ÿQh.íÚ?\ÿÿ?çç:£0
0001: 01 00 00 00 00 00 00 00 1A 00 00 00 0E 00 00 00 ................
0002: F0 2F 20 00 00 00 00 00 E5 3F 3F F5 1C 3F E7 3F ð/ .....å??õ.?ç?
0003: 2E 3F C9 D8 AB B3 0F 3F 03 D5 FF C7 77 61 72 33 .?ÉØ«³.?.ÕÿÇwar3
0004: 2E 65 78 65 20 30 36 2F 31 39 2F 30 37 20 31 31 .exe 06/19/07 11
0005: 3A 34 31 3A 31 34 20 34 30 39 36 36 30 00 53 6F :41:14 409660.So
0006: 6D 65 74 68 69 6E 67 00 mething.........
I noticed that the bot is building the packet correctly, but the data is being changed (converted wrong) before it's being sent. I'm sure this has to do with the packet sending function -- does the below code look ok? The values that are changing are becoming 0x3F, so I'm thinking it has something to do with the Encoding.Default.GetBytes() line. Many places I've seen say to use ASCII or UTF8, however these produce other problems for me, such as converting 0xFF to 0x3F (apparently I'm having a similar problem with using Default).
public void SendPacketBNET(int PacketID)
{
//Construct the byte array to send
string tmpbuffer = "";
tmpbuffer += Convert.ToString(Convert.ToChar(0xFF));
tmpbuffer += Convert.ToString(Convert.ToChar(PacketID));
tmpbuffer += MakeWORD(buffer.Length + 4);
tmpbuffer += buffer;
byte[] Data = Encoding.Default.GetBytes(tmpbuffer);
//Send the byte array
sckBNET.Send(Data);
buffer = "";
}
Quote from: MyndFyre[vL] on February 21, 2008, 09:21 AM
You're using strings as buffers and getting problems? Surprise surprise. .NET isn't VB6.
Well, it's using a string array to collect the data from the Socket, and then I have it convert that into a string. What's the best way to do this in C#?
Use byte arrays instead?
Oh, sorry it's one of those mornings...
Originally I have it pull it into a byte array, then I convert it using:
private byte[] BNETbuffer = new byte[255];
private byte[] BNLSbuffer = new byte[255];
for (int i = 0; i < BytesReceived; i++)
{
sBNETbuffer += Convert.ToChar(BNETbuffer[i]).ToString();
}
Right now I'm only doing it that way because I was having other issues with the Text.Decoder I was using. (It was a quick-fix)
Edit: I wrote my own function to convert the string to a byte[], which resolved the problem. What's the best/most efficient way to convert the data?
private byte[] StringToByteArray(string Data)
{
//Declare the byte array
byte[] returnarray = new byte[Data.Length];
//Loop through the Data
for (int i = 0; i < Data.Length; i++)
{
//Set each element of the byte array to the value of each character
returnarray[i] = Convert.ToByte(Convert.ToChar(Data.Substring(i, 1)));
}
//Return the byte array
return returnarray;
}
MBNCSUtil (http://www.jinxbot.net/mbncsutil/) implements a packet buffer and data reader so that you can use C# native types rather than using strings to hole the byte data. Source code is also available from the same URL if you don't want to be dependent on an external library. It also doesn't use a restrictive license like GPL, so you don't even need to give the author credit. Who knew?
BNET -> Client
0000: FF 50 E7 00 02 00 00 00 1F E9 15 BE 15 35 3B 00 ÿPç......é.¾.5;.
0001: 00 4D 89 7E 99 CB C6 01 76 65 72 2D 49 58 38 36 .M.~.ËÆ.ver-IX86
0002: 2D 37 2E 6D 70 71 00 41 3D 32 36 38 33 39 33 31 -7.mpq.A=2683931
0003: 39 30 33 20 43 3D 39 31 35 38 32 34 36 39 32 20 903 C=915824692
0004: 42 3D 32 31 35 39 31 39 31 38 39 39 20 34 20 41 B=2159191899 4 A
0005: 3D 41 2D 53 20 42 3D 42 5E 43 20 43 3D 43 5E 41 =A-S B=B^C C=C^A
0006: 20 41 3D 41 2D 42 00 93 DB 9F BB 28 04 86 BF 3C A=A-B..ÛŸ»(..¿<
0007: 37 7C ED 41 4E 0D 37 50 33 98 FA 55 4A 85 1D 37 7|íAN.7P3.úUJ..7
0008: FF FD 2C BB E3 F0 98 97 E4 5F C1 32 C7 11 EF C7 ÿý,»ãð..ä_Á2Ç.ïÇ
0009: 1A FB 4A 1A 6C A4 2F 0D 82 22 7E 95 F4 C2 3A E5 .ûJ.l¤/.."~.ôÂ:å
0010: 89 57 03 6B D7 4B 8A EB D5 70 83 DB AA 13 21 C5 .W.k×K.ëÕp.Ûª.!Å
0011: 4D F3 B2 49 E8 F6 4D D1 B7 CC D9 88 4D 5B 12 B5 Mó²IèöMÑ·ÌÙ.M[.µ
0012: B4 70 6F DC B9 07 0A 60 C4 32 F7 5F EC 31 33 57 ´poܹ..`Ä2÷_ì13W
0013: 2A FA F7 7F E5 3C FF 41 97 6F 85 E6 0D 05 99 81 *ú÷å<ÿA.o.æ....
0014: 6D 80 E2 6A 5D 2D 0A m.âj]-..........
Client -> BNLS
0000: 66 00 1A 07 00 00 00 00 00 00 00 01 00 00 00 00 f...............
0001: 4D 89 7E 99 CB C6 01 76 65 72 2D 49 58 38 36 2D M.~.ËÆ.ver-IX86-
0002: 37 2E 6D 70 71 00 41 3D 32 36 38 33 39 33 31 39 7.mpq.A=26839319
0003: 30 33 20 43 3D 39 31 35 38 32 34 36 39 32 20 42 03 C=915824692 B
0004: 3D 32 31 35 39 31 39 31 38 39 39 20 34 20 41 3D =2159191899 4 A=
0005: 41 2D 53 20 42 3D 42 5E 43 20 43 3D 43 5E 41 20 A-S B=B^C C=C^A
0006: 41 3D 41 2D 42 00 A=A-B...........
BNLS -> Client
0000: 39 00 1A 01 00 00 00 FF FF FF 9C FD 01 03 D9 77 9......ÿÿÿ.ý..Ùw
0001: 61 72 33 2E 65 78 65 20 30 36 2F 31 39 2F 30 37 ar3.exe 06/19/07
0002: 20 31 34 3A 34 31 3A 31 32 20 34 30 39 36 36 30 14:41:12 409660
0003: 00 01 00 00 00 15 00 00 00 ................
Looks fine so far, but why is BNLS sending you 0x9CFFFFFF as a version code? is that right?
Check sum is 0xD90301FD
Client -> BNLS
0000: 22 00 01 1F E9 15 BE -- -- -- -- -- -- -- -- -- "...é.¾---------
0001: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------
0002: -- 00 -...............
BNLS -> Client
0000: 2F 00 01 01 00 00 00 D4 08 DE 5E 1A 00 00 00 0E /......Ô.Þ^.....
0001: 00 00 00 F0 2F 20 00 00 00 00 00 93 9D 0D 43 FD ...ð/ ........Cý
0002: 09 41 A8 C2 83 49 92 29 4F CD 9E 37 5C 97 30 .A¨Â.I.)OÍ.7\.0.
Looks fine, server token went across fine, client token and decoded cdkey came back fine.
Client -> BNET
0000: FF 51 68 00 D4 08 DE 5E FF FF 9C FD FD 01 03 D9 ÿQh.Ô.Þ^ÿÿ.ýý..Ù
0001: 01 00 00 00 00 00 00 00 1A 00 00 00 0E 00 00 00 ................
0002: F0 2F 20 00 00 00 00 00 93 9D 0D 43 FD 09 41 A8 ð/ ........Cý.A¨
0003: C2 83 49 92 29 4F CD 9E 37 5C 97 30 77 61 72 33 Â.I.)OÍ.7\.0war3
0004: 2E 65 78 65 20 30 36 2F 31 39 2F 30 37 20 31 34 .exe 06/19/07 14
0005: 3A 34 31 3A 31 32 20 34 30 39 36 36 30 00 53 6F :41:12 409660.So
0006: 6D 65 74 68 69 6E 67 00 mething.........
BNET -> Client
0000: FF 51 09 00 00 02 00 00 00 ÿQ..............
Looks like client token (from BNLS 0x1A) is fine, ur version code looks out by 1 byte:
FF FF 9C FD FD 01 03 D9 <-- 2x 0xFD's?
Other than that, at a glance, it all looks fine, but im not sure why bnet isnt failing your game version, unless im missing somthing.
The responce is invalid cdkey, so that will result in a long IP ban, but looks like the cdkey went through fine. If you sort the exe version code out (looks like ur parseing it 1 byte ahead of its position) and you still get invalid cdkey, then it might be your cdkey is generaly invalid.
the invalid cdkey responce is odd tho, idk
Quote from: Ringo on February 21, 2008, 11:49 AM
Looks like client token (from BNLS 0x1A) is fine, ur version code looks out by 1 byte:
FF FF 9C FD FD 01 03 D9 <-- 2x 0xFD's?
That's the weird thing I couldn't quite figure out. Now that the program connects, I looked over the log again and it's still duplicating at that position. I'm not sure if this is just a mis-type on the Battle.net server-side or something. (Doesn't seem to fit the documentation I've found for the packet.) Odds are it's something I managed to break ;)
Thanks for the link to MBNCSUtil, I'll take a look at that here in a little bit.
And thanks all for the assistance in fixing the problem. Turns out I have a lot to learn about data conversions in C# :)
Quote from: Rndom on February 22, 2008, 12:27 AM
That's the weird thing I couldn't quite figure out. Now that the program connects, I looked over the log again and it's still duplicating at that position. I'm not sure if this is just a mis-type on the Battle.net server-side or something. (Doesn't seem to fit the documentation I've found for the packet.) Odds are it's something I managed to break ;)
Yeah, im guessing you fixed it now, the problem was right here:
Quote from: Rndom
case 0x1A:
bool success = Convert.ToBoolean(LongFromDWORD(Data.Substring(3, 4)));
version = LongFromDWORD(Data.Substring(8, 4));
Checksum = LongFromDWORD(Data.Substring(11, 4));
VersionStatString = Debuffer.GetStringAt(12);
Should of been:
version = LongFromDWORD(Data.Substring(7, 4));
Easy mistake to make, Just need to remember that the BNLS header is 3 bytes, not 4, thats probly how you ended up starting on the wrong byte.
Actually I'm still using that same code, I found if I change it to Data.Substring(7, 4) instead of the (8, 4), Battle.net returns an error (can't remember what error though, think it was either 0x200 or 0x201). Now it's getting successfully through the entire logon sequence and now I just have to figure out why it's clumping all the events. Fun times with packets ;)
Quote from: MyndFyre[vL] on February 21, 2008, 11:09 AM
It also doesn't use a restrictive license like GPL, so you don't even need to give the author credit. Who knew?
Sounds like a true badass wrote this library. :)
Quote from: Newby on February 23, 2008, 12:39 PM
Quote from: MyndFyre[vL] on February 21, 2008, 11:09 AM
It also doesn't use a restrictive license like GPL, so you don't even need to give the author credit. Who knew?
Sounds like a true badass wrote this library. :)
LOL
Quote from: MyndFyre[vL] on February 21, 2008, 11:09 AMIt also doesn't use a restrictive license like GPL, so you don't even need to give the author credit.
Where in the GPL does it say that you must include a statement giving credit to the author of the GPL-covered work? The closest I can find is that you can't remove the copyright statement on the copy of the covered work. Perhaps you were thinking of a restrictive license like BSD-with-attribution, which requires a statement of attribution to the Berkeley regents.
Also, which GPL did you mean?
I had the same problem I had to have it call the next packet at the end of sending the next, So like
public void 0x0aSend()
{
//Stuff
0x0bSend();
}
public void 0x0bSend()...etc.
Quote from: Kp on February 23, 2008, 07:55 PM
Quote from: MyndFyre[vL] on February 21, 2008, 11:09 AMIt also doesn't use a restrictive license like GPL, so you don't even need to give the author credit.
Where in the GPL does it say that you must include a statement giving credit to the author of the GPL-covered work? The closest I can find is that you can't remove the copyright statement on the copy of the covered work. Perhaps you were thinking of a restrictive license like BSD-with-attribution, which requires a statement of attribution to the Berkeley regents.
Also, which GPL did you mean?
Quote from: GPLv21. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty;
GPL requires that the source code be made available, and source code must include verbatim copyright notices and disclaimers of warranty.
When I refer to restrictive copyleft I am almost always referring to the GPL, not variants like LGPL. That is true in this case.
Quote from: MyndFyre[vL] on March 12, 2008, 01:35 AM
Quote from: Kp on February 23, 2008, 07:55 PM
Where in the GPL does it say that you must include a statement giving credit to the author of the GPL-covered work? The closest I can find is that you can't remove the copyright statement on the copy of the covered work. Perhaps you were thinking of a restrictive license like BSD-with-attribution, which requires a statement of attribution to the Berkeley regents.
Quote from: GPLv21. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty;
GPL requires that the source code be made available, and source code must include verbatim copyright notices and disclaimers of warranty.
To me, "giving credit" implies a requirement to actively advertise that you're using their work. That part of the GPL is the one I mentioned, and it only requires that the covered works bear the relevant copyright and warranty disclaimer. In contrast, the BSD-with-attribution requires that that your documentation actively advertise that you have included software covered by that license.
Quote from: MyndFyre[vL] on March 12, 2008, 01:35 AM
Quote from: Kp on February 23, 2008, 07:55 PM
Also, which GPL did you mean?
When I refer to restrictive copyleft I am almost always referring to the GPL, not variants like LGPL. That is true in this case.
You missed the point of my question. I didn't mean LGPL vs. GPL, but which version of GPL.