• Welcome to Valhalla Legends Archive.
 

Invalid Version Error while trying to connect to USWest.Battle.net

Started by lxcid, August 28, 2005, 02:28 AM

Previous topic - Next topic

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:


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.


[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.]

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)

Actual W3XP: 6c 9a 44 98
MY BOT: 25 ed 69 a9

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.

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
Quote from: replaced on November 04, 2006, 11:54 AM
I dunno wat it means, someone tell me whats ix86 and pmac?
Can someone send me a working bot source (with bnls support) to my email?  Then help me copy and paste it to my bot? ;D
Já jsem byl určenej abych tady žil,
Dával si ovar, křen a k tomu pivo pil.
Tam by ses povídaj jak prase v žitě měl,
Já nechci před nikym sednout si na prdel.

Já nejsem z USA, já nejsem z USA, já vážně nejsem z USA... a snad se proto na mě nezloběj.

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.


/*
* 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) {

}*/
}

lxcid

Quote from: Networks on August 28, 2005, 10:11 AM
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.

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

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 


Actual Client 0x50

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 


[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.]

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...
The Bovine Revolution
Something unimportant

Live Battle.net:

WARNING: The preceding message may have contained content unsuitable for young children.

R.a.B.B.i.T

Just a note, lxcid, it's usually helpful to keep the packet headers in the dumps ;\

UserLoser.

Quote from: rabbit on August 28, 2005, 04:47 PM
Just a note, lxcid, it's usually helpful to keep the packet headers in the dumps ;\
They are in all the dumps...

lxcid

Quote from: Lenny on August 28, 2005, 01:13 PM
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...

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...

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. :)

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];

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?
The Bovine Revolution
Something unimportant

Live Battle.net:

WARNING: The preceding message may have contained content unsuitable for young children.

R.a.B.B.i.T

Quote from: UserLoser on August 28, 2005, 06:29 PM
Quote from: rabbit on August 28, 2005, 04:47 PM
Just a note, lxcid, it's usually helpful to keep the packet headers in the dumps ;\
They are in all the dumps...
Yeah...I just noticed he was including the TCP headers......so.......it usually a good idea to strip the TCP headers :P

lxcid

Hmmmp, I think I'll use iago checkRevision and see whether the result has changed.

Lenny

Well I just performed a quick check with your values...


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)));
}
}


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...
The Bovine Revolution
Something unimportant

Live Battle.net:

WARNING: The preceding message may have contained content unsuitable for young children.