Valhalla Legends Forums Archive | Battle.net Bot Development | Invalid Version Error while trying to connect to USWest.Battle.net

AuthorMessageTime
lxcid
Hi,

Although this is my first post, this is not the first time I'm here. For the pass days, I been lurking around here and getting all the information I need to make a java bot. I have been pretty fine on my own until I was going to send PacketID 51. I got Invalid Version error. I uses CheckRevision of Battle.net Connection Core. Trying to connect to Warcraft 3: The Frozen Throne

here's the result:

[pre]
0000  fa 23 20 00 01 00 01 00 01 00 00 00 08 00 45 00  .# ...........E.
0010  00 ae 49 23 40 00 80 06 86 bd db 5f bc 11 3f f1  ..I#@......_..?.
0020  53 07 05 f3 17 e0 72 88 c1 e6 76 fa dd f6 50 18  S.....r...v...P.
0030  ff 14 e2 b8 00 00 ff 51 86 00 9c e6 8d 00 8e 12  .......Q........
0040  00 01 e6 a4 54 ba 02 00 00 00 00 00 00 00 XX XX  ....T...........
0050  XXX
0060  XXX
0070  XXX
0080  XXX
0090  XX XX XX XX XX XX 77 61 72 33 2e 65 78 65 20 30  ......war3.exe 0
00a0  33 2f 30 32 2f 30 35 20 32 31 3a 31 38 3a 35 32  3/02/05 21:18:52
00b0  20 31 35 37 32 33 30 37 00 4b 53 00              1572307.KS.
[/pre]

[Kp edit: switch post from code tags to pre tags.  I appreciate that you tagged the content at all, but pre makes hex dumps much easier to read than code.]
August 28, 2005, 7:28 AM
lxcid
I'm quite comfirm is the CheckRevision problem.

With these values:
serverToken = 0xFE5D004B
mpqFile = "IX86ver1.mpq"
versionString = "A=131067354 B=157892914 C=517531622 4 A=A-S B=B+C C=C^A A=A-B"

These files in this order:
1st: war3.exe
2nd: game.dll
3rd: storm.dll

client: Warcraft III: Frozen Throne

this is the value i get for exe Hash:
(directly from ethereal)
[code]
Actual W3XP: 6c 9a 44 98
MY BOT: 25 ed 69 a9
[/code]
August 28, 2005, 2:34 PM
Networks
Through my work with SID_AUTH_CHECK (0x51) my answer to you is to make sure you have lots of debugging. My handler function for it is pratically all debugging of it. Make sure you have the correct information, make sure your version byte for SID_AUTH_INFO is correct, and make sure that none of your information is null. If you have all that, it should be fine. Also make sure your hash files are correct.
August 28, 2005, 3:11 PM
l2k-Shadow
Since I don't know your CheckRevision() function, I don't know if this will make any difference for you, but the file order is usually:

1st: War3.exe
2nd: Storm.dll
3rd: Game.dll
August 28, 2005, 5:11 PM
lxcid
Thats a information I need :) Thanks! but I still got the same error. This time the value is 23 50 8C 51. still doesn't match.

I will post my CheckRevision. I wan everyone to know that this is not my code. Its from Battle.net Connection Core. I'm sorry if anyone get offended.

[code]
/*
* Created on Apr 16, 2005
*
* CheckRevision.java
* Copyright (C) 2005  CoW]8(0)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* A copy of the GNU Lesser General Public License is included in the
* BNCC distribution in the file LICENSE.  If you did not receive this
* copy, write to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA  02110-1301  USA
*/
package DFvRBot.cls.auth;

import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.ByteOrder;

/**
* This class performs the checksum algorithm sent by a BNCS server to assure the
* correct version of the game files as well as to prevent any tampering of them.
*/
public class CheckRevision {

//Seeds of each MPQ file ordered respectively  (IX86Ver?.mpq = mpqSeeds[?-1])
public static final int mpqSeeds[] = {0xE7F4CB62, 0xF6A14FFC, 0xAA5504AF, 0x871FCDC2,
  0x11BF6A18, 0xC57292E6, 0x7927D27E, 0x2FEC8733};   


/* A cache to store past ExeHashes in-case a BNCS server requests the same checksum.
* This has occurred most often between reconnect intervals of no more than a few
* minutes.
*/
private static Hashtable exeHashCache = new Hashtable();

/* This method performs the checksum algorithm which is found in the IX86Ver?.mpq file of
* an actual client.
* @param mpqFilename - the file which contains the dll which exports the CheckRevision
* function (getExeHash)
* Ex: IX86ver2.mpq
* @param versionString - the formula to be used for the version check of the files
* Ex: A=89369133 B=106585185 C=966163689 4 A=A^S B=B+C C=C^A A=A+B
* @param files - the game files to be checked
* Ex: Starcraft.exe, Storm.dll, and Battle.snp
* @return - the calculated hash
*/
public static int getExeHash(String mpqFilename, String versionString, String[] files) throws IOException {
Integer cache = (Integer)exeHashCache.get(mpqFilename + versionString + files[0]);
if(cache != null)
return cache.intValue();

int mpqSeedKey = Character.digit(mpqFilename.charAt(7), 10);

StringTokenizer versionTok = new StringTokenizer(versionString, " ");

int[] abc = new int[3];
abc[0] = Integer.parseInt(versionTok.nextToken().substring(2));
abc[1] = Integer.parseInt(versionTok.nextToken().substring(2));
abc[2] = Integer.parseInt(versionTok.nextToken().substring(2));

//Number of operations in the versionString, in the above example that value is 4
int numOps = Integer.parseInt(versionTok.nextToken());

char[] ops = new char[numOps];
for(int i = 0; i < numOps; i++) {
ops[i] = versionTok.nextToken().charAt(3);
}


abc[0] ^= mpqSeeds[mpqSeedKey];
if(numOps == 4) {
//A faster static implemenation
for(int i = 0; i < files.length; i++) {
File curFile = new File("C:\\Program Files\\Warcraft III\\" + files[i]);
int roundedSize = (int)((curFile.length() / 1024) * 1024);
System.out.println("curFile[" + i + "]: " + curFile.length() + " : " + roundedSize);
MappedByteBuffer fileData = (new FileInputStream(curFile)).getChannel().map(FileChannel.MapMode.READ_ONLY, 0, roundedSize);
fileData.order(ByteOrder.LITTLE_ENDIAN);

int s, k;
for(int j = 0; j < roundedSize; j += 4) {
s = fileData.getInt(j);

switch(ops[0]) {
case '^':
abc[0] ^= s;
break;
case '-':
abc[0] -= s;
break;
case '+':
abc[0] += s;
break;
}

                switch(ops[1]) {
                    case '^':
                        abc[1] ^= abc[2];
                        break;
                    case '-':
                    abc[1] -= abc[2];
                        break;
                    case '+':
                    abc[1] += abc[2];
                    break;
                }
           
                switch(ops[2]) {
                case '^':
                abc[2] ^= abc[0];
                break;
                case '-':
                abc[2] -= abc[0];
                    break;
                case '+':
                abc[2] += abc[0];
                break;
                }
           
                switch(ops[3]) {
                case '^':
                abc[0] ^= abc[1];
            break;
                case '-':
                abc[0] -= abc[1];
                break;
                case '+':
                abc[0] += abc[1];
                break;
                }
               
}


}
} else {
//A dynamic implementation (should the BNCS server send an anomaly)
for(int i = 0; i < files.length; i++) {
File curFile = new File(files[i]);
int roundedSize = (int)((curFile.length() / 1024) * 1024);
MappedByteBuffer fileData = (new FileInputStream(curFile)).getChannel().map(FileChannel.MapMode.READ_ONLY, 0, roundedSize);
fileData.order(ByteOrder.LITTLE_ENDIAN);

int s, k;
for(int j = 0; j < roundedSize; j += 4) {
s = fileData.getInt(j);

switch(ops[0]) {
case '^':
abc[0] ^= s;
break;
case '-':
abc[0] -= s;
break;
case '+':
abc[0] += s;
break;
}

for(k = 1; k < numOps; k++) {
switch(ops[k]) {
case '^':
abc[k % 3] ^= abc[(k + 1) % 3];
break;
case '-':
abc[k % 3] -= abc[(k + 1) % 3];
break;
case '+':
abc[k % 3] += abc[(k + 1) % 3];
break;
}
}
               
}


}
}

exeHashCache.put(mpqFilename + versionString + files[0], new Integer(abc[2]));
return abc[2];
}

public static String getExeInfo(String file) {
File exeFile = new File("C:\\Program Files\\Warcraft III\\" + file);

SimpleDateFormat formatD = new SimpleDateFormat("MM/dd/yy HH:mm:ss");

Date exeDate = new Date(exeFile.lastModified());

return exeFile.getName() + " " + formatD.format(exeDate) + " " + exeFile.length();  
}

public static void clearCache() {
exeHashCache = new Hashtable();
}

/* This method will be substituted with config values for the time being.
* Documentation to implement this method in the future:
* http://www.installshield.com/news/newsletter/0203-articles/ISMPtip.pdf
* JNI implementation will check if Win32, throws exception if not Win32
*/
/*public static int getExeVersion(String file) {

}*/
}
[/code]
August 28, 2005, 5:34 PM
lxcid
[quote author=Networks link=topic=12640.msg125781#msg125781 date=1125241917]
Through my work with SID_AUTH_CHECK (0x51) my answer to you is to make sure you have lots of debugging. My handler function for it is pratically all debugging of it. Make sure you have the correct information, make sure your version byte for SID_AUTH_INFO is correct, and make sure that none of your information is null. If you have all that, it should be fine. Also make sure your hash files are correct.
[/quote]

I don't think mine 0x50 packet had any problem. Locale ID and Language ID are optional so there's should be any problem.

My bot 0x50
[pre]
0000  fa 23 20 00 01 00 01 00 01 00 00 00 08 00 45 00  .# ...........E.
0010  00 62 f8 41 40 00 80 06 d7 e6 db 5f bc 11 3f f1  .b.A@......_..?.
0020  53 0b 0a 42 17 e0 d7 13 59 cf 69 3c c6 ac 50 18  S..B....Y.i<..P.
0030  ff ff f3 d4 00 00 ff 50 3a 00 00 00 00 00 36 38  .......P:.....68
0040  58 49 50 58 33 57 12 00 00 00 53 55 6e 65 db 5f  XIPX3W....SUne._
0050  bc 11 20 fe ff ff 00 00 00 00 00 00 00 00 55 53  .. ...........US
0060  41 00 55 6e 69 74 65 64 20 53 74 61 74 65 73 00  A.United States.
0070 
[/pre]

Actual Client 0x50
[pre]
0000  fa 23 20 00 01 00 01 00 01 00 00 00 08 00 45 00  .# ...........E.
0010  00 62 fc f0 40 00 80 06 d2 d6 db 5f bc 11 3f f1  .b..@......_..?.
0020  53 6c 0a 6a 17 e0 93 8a b5 d4 4f 15 93 65 50 18  Sl.j......O..eP.
0030  ff ff 16 36 00 00 ff 50 3a 00 00 00 00 00 36 38  ...6...P:.....68
0040  58 49 50 58 33 57 12 00 00 00 53 55 6e 65 db 5f  XIPX3W....SUne._
0050  bc 11 20 fe ff ff 09 04 00 00 09 04 00 00 55 53  .. ...........US
0060  41 00 55 6e 69 74 65 64 20 53 74 61 74 65 73 00  A.United States.
0070 
[/pre]

[Kp edit: switch post from code tags to pre tags.  I appreciate that you tagged the content at all, but pre makes hex dumps much easier to read than code.]
August 28, 2005, 5:43 PM
Lenny
Well looking at the source, you've added the directory path in various places where it doesn't need to be.  The string file and files[] can contain the path as well as the file name...

Also check that your hash files are the newest.  Post the checksum alg Bnet gives in 0x50 you and the hash outputted.  Also make sure your hashes work for w3xp...
August 28, 2005, 6:13 PM
R.a.B.B.i.T
Just a note, lxcid, it's usually helpful to keep the packet headers in the dumps ;\
August 28, 2005, 9:47 PM
UserLoser.
[quote author=rabbit link=topic=12640.msg125822#msg125822 date=1125265659]
Just a note, lxcid, it's usually helpful to keep the packet headers in the dumps ;\
[/quote]
They are in all the dumps...
August 28, 2005, 11:29 PM
lxcid
[quote author=Lenny link=topic=12640.msg125803#msg125803 date=1125252837]
Well looking at the source, you've added the directory path in various places where it doesn't need to be.  The string file and files[] can contain the path as well as the file name...

Also check that your hash files are the newest.  Post the checksum alg Bnet gives in 0x50 you and the hash outputted.  Also make sure your hashes work for w3xp...
[/quote]

I append "C:\\Program Files\\Warcraft III\\" to the string file. So I don't think there's a problem with it... I'm using the latest, because my warcraft: frozen throne is 1.18 and able to connect to battle.net. I posted the checksum alg at top of the post, versionString. I don't whether my hash work... sighx... could it be my warcraft 3 cd key decode? but if its that problem, won't it give me invalid cd key error? hmmmp...
August 29, 2005, 2:09 AM
lxcid
exe Hash field: 6c 9a 44 98

directly extract from ethereal. it can be found on top. The formula and stuff are all location on top. :)
August 29, 2005, 2:56 AM
Lenny
The changes in code you mentioned should have no effect if it is even possible to have code compile in such a format:
[quote]
abc[1] ^ abc[2];
[/quote]

And, IMO, having more portable code is much better than a slight performance gain.  As you see, the code only reverts to the slower implementation should Bnet ever send an anomaly.

What exactly is slow about the implementation?
August 29, 2005, 3:42 AM
R.a.B.B.i.T
[quote author=UserLoser link=topic=12640.msg125836#msg125836 date=1125271778]
[quote author=rabbit link=topic=12640.msg125822#msg125822 date=1125265659]
Just a note, lxcid, it's usually helpful to keep the packet headers in the dumps ;\
[/quote]
They are in all the dumps...
[/quote]Yeah...I just noticed he was including the TCP headers......so.......it usually a good idea to strip the TCP headers :P
August 29, 2005, 5:07 AM
lxcid
Hmmmp, I think I'll use iago checkRevision and see whether the result has changed.
August 29, 2005, 5:51 AM
Lenny
Well I just performed a quick check with your values...

[code]
import bncc.authentication.CheckRevision;

public class TestRevision {
public static void main(String[] args) throws Exception {
String[] files = {"C:\\war3.exe",
"C:\\storm.dll",
        "C:\\game.dll"};

System.out.println(Integer.toHexString(CheckRevision.getExeHash("IX86ver1.mpq", "A=131067354 B=157892914 C=517531622 4 A=A-S B=B+C C=C^A A=A-B", files)));
}
}
[/code]

Output: 98449a6c
which would be sent as: 6c 9a 44 98 (little endian)...

So it must be your usage that's causing a different hash...
August 29, 2005, 6:15 AM
lxcid
I still get the same wrong error. this could mean the problem lies on the files... but mine was from my actual folder, I try ask my friend to send me and use his and see the result. Thanks! :)
August 29, 2005, 8:49 AM
lxcid
Damn I used my friend war3.exe storm.dll game.dll and i still get the same wrong hash value with bncc CheckRevision and the TestRevision of Lenny unmodified. Those are directly extracted from my Warcraft III folder. My friend and I Warcraft 3 Forzen Throne is 1.18. Lenny could u send me ur war3.exe storm.dll and game.dll? sighx...
August 29, 2005, 11:34 AM
lxcid
I'm sorry for all the trouble. The problem is solved. :) my file has problem. I don't know why. maybe its because I use cd emulator. I asked my friend to send me his and it works fine. :)
August 29, 2005, 12:07 PM

Search