• Welcome to Valhalla Legends Archive.
 

Starcraft Verhash Creation

Started by Joe[x86], December 12, 2005, 11:28 AM

Previous topic - Next topic

Joe[x86]

This isn't documented anywhere on BnetDocs, so maybe it should be?

(BYTE) Major
(BYTE) Int(Minor / 10)
(BYTE) (Minor % 10)
(BYTE) Revision


That's kinda confusing, so I might as well post my function to create them.

  static String scVerhash(int major, int minor, String revision) {
    String ret = "";
    /*  (BYTE) Major
     *  (BYTE) Int(Minor / 10)
     *  (BYTE) (Minor % 10)
     *  (BYTE) Revision */
    ret += String.valueOf(major);
    ret += String.valueOf((int)minor / 10);
    ret += String.valueOf((int)minor % 10);
    switch(revision.getBytes()[0]) {
      case 65: ret += 1; break;   // A
      case 66: ret += 2; break;   // B
      case 67: ret += 3; break;   // C
      case 68: ret += 4; break;   // D
      case 69: ret += 5; break;   // E
      case 70: ret += 6; break;   // F
      default: ret += 1; break;   // Probably null.
    }
    return ret;
  }
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

MyndFyre

What is a "verhash"?

Please use terminology consistent with BnetDocs.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Joe[x86]

I can't remember what BnetDocs calls it, and I'm too laggy right now to see (stupid timeouts).

x86:
QuoteIts one of the fields in 0x51, can't remember which. Its extracted from the EXE in JBBE, using BNCSutil, but its usually requested from BNLS in remote-hashing bots.

Its one of those stupid things that can be done locally yet it outsourced to BNCS, such as key hashing, password hashing, version bytes, etc. The only thing BNLS should ever be used for is CheckRevision, which is why I'm a fan of RCRS and debated implementing it in my bot before BNLS (neither of which ever got added, if you're wondering).

I didn't say this on x86, but its sort of building off the outsourcing to BNLS idea. I think that if it was documented on BneDocs + linked to in 0x51 page, it'd discourage the idea of insecure BNLS (remote password + key hashing).
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

MyndFyre

This is C->S 0x50:

(DWORD)       Protocol ID (0)
(DWORD)       Platform ID
(DWORD)       Product ID
(DWORD)       Version Byte
(DWORD)       Product language
(DWORD)       Local IP for NAT compatibility*
(DWORD)       Time zone bias*
(DWORD)       Locale ID*
(DWORD)       Language ID*
(STRING)     Country abreviation
(STRING)     Country


This is C->S 0x51:

(DWORD)       Client Token
(DWORD)       EXE Version
(DWORD)       EXE Hash
(DWORD)       Number of keys in this packet
(BOOLEAN)    Using Spawn (32-bit)

For Each Key:
(DWORD)       Key Length
(DWORD)       CD key's product value
(DWORD)       CD key's public value
(DWORD)       Unknown (0)
(DWORD[5])    Hashed Key Data

(STRING)     Exe Information
(STRING)     CD Key owner name

It obviously is not something related to a CD key, we know it's not the protocol/platform/product ID, or the localization stuff.  I figure it can be one of the following values:
* Version byte
* EXE Version
* EXE Hash

Which one?
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

dxoigmn

Quote from: MyndFyre on December 12, 2005, 04:35 PM
It obviously is not something related to a CD key, we know it's not the protocol/platform/product ID, or the localization stuff.  I figure it can be one of the following values:
* Version byte
* EXE Version
* EXE Hash

Which one?

He is talking about EXE Version.

Joe[x86]

Yup. EXE hash is from CheckRevision() itself.

EXE Version is the DWORD value returned when you call getEXEInfo or whatever in BNCSutil.
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

Arta

Yes, the EXE version is obtained from the .exe's resource info. I'd be happy to add a document to explain that and related checkrevision things, but it should explain all of checkrevision, not just the easy bits. That's a fairly big task, and no one has volunteered to do it yet.

Joe[x86]

Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

shout

Quote from: Joe on December 13, 2005, 07:02 PM
I'll look into it, eventually.

I made a document quite a while ago but never did anything with it. Here it is + tags.




CheckRevision

--Shout

The Battle.Net checkrevision is an algorithm for making sure the core game files have not been tampered with. In SID_AUTH_INFO (S -> C) the ValueString contains the values used in the checkrevision. It is as follows:

"A=? B=? C=? 4 A=A?S B=B?C C=C?A A=A?B"

There are four integers that calculations are performed on. The first three question marks are the first 3 of the forementioned integers. The 4 is the fourth value, which also happens to be the number of bytes read from the file at any one time. The other four question marks are the operations, either +, -, or [xor]^ (ops[]).

My C implentation of this is:


void BreakString(PSTR string, PDWORD values, PCHAR ops)
{
DWORD n = 0;
for (int i = 0; i < 3; i++)
{
for (; string[n] != '='; n++);
values[i] = parse(&string[++n], NOLIMIT | BASE10);
}
for (int i = 0; i < 4; i++)
{
for(; string[n] != '='; n++);
ops[i] = (CHAR)string[++n];
}
values[3] = 4;
}


Also, there is a string called IX86ver filename, which is in the format "IX86Ver?.mpq". The ? is a number that corrosponds with this array of numbers (in hex):


H[8] = E7F4CB62 F6A14FFC AA5504AF 871FCDC2 11BF6A18 C57292E6 7927D27E 2FEC8733


The mpq number will always be between 0 and 7.

The acutal hashing is started by A xor H[IX86Ver].
Then you find the size of the first file (rounded). This is done by


(actualsize / 1024) * 1024


Next you open the first file then read four bytes into S. Then you perform the 4 calculations on it. My C implementation (borrowed from iago):


for(DWORD j = 0; j < rounded; j += 4)
{
ReadFile(hFile, &s, 4, NULL, NULL);

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

{...}
}


After all three files have been processed, the EXE Hash is B.

dxoigmn

Quote from: Shout on December 14, 2005, 09:52 PM
Also, there is a string called IX86ver filename, which is in the format "IX86Ver?.mpq". The ? is a number that corrosponds with this array of numbers (in hex):


H[8] = E7F4CB62 F6A14FFC AA5504AF 871FCDC2 11BF6A18 C57292E6 7927D27E 2FEC8733


The mpq number will always be between 0 and 7.

This may not always be true. It is probably better to mention that each of these IX86Ver?.mpq files contain a unique secret which has in the past corresponded to these values. For true compatability, one should download the file battle.net specifies and run the dll contained within. An update form of CheckRevision is certainly possible and would be an easy way to disable most emulated battle.net clients.

shout

Quote from: dxoigmn on December 14, 2005, 11:15 PM
Quote from: Shout on December 14, 2005, 09:52 PM
Also, there is a string called IX86ver filename, which is in the format "IX86Ver?.mpq". The ? is a number that corrosponds with this array of numbers (in hex):


H[8] = E7F4CB62 F6A14FFC AA5504AF 871FCDC2 11BF6A18 C57292E6 7927D27E 2FEC8733


The mpq number will always be between 0 and 7.

This may not always be true. It is probably better to mention that each of these IX86Ver?.mpq files contain a unique secret which has in the past corresponded to these values. For true compatability, one should download the file battle.net specifies and run the dll contained within. An update form of CheckRevision is certainly possible and would be an easy way to disable most emulated battle.net clients.

Yes, it would. But I am going over the ultra-basic algorithm, not the Blizzard-made code. The point of this is to provide an understanding of the algorithm.

dxoigmn

Quote from: Shout on December 15, 2005, 07:10 PM
Quote from: dxoigmn on December 14, 2005, 11:15 PM
Quote from: Shout on December 14, 2005, 09:52 PM
Also, there is a string called IX86ver filename, which is in the format "IX86Ver?.mpq". The ? is a number that corrosponds with this array of numbers (in hex):


H[8] = E7F4CB62 F6A14FFC AA5504AF 871FCDC2 11BF6A18 C57292E6 7927D27E 2FEC8733


The mpq number will always be between 0 and 7.

This may not always be true. It is probably better to mention that each of these IX86Ver?.mpq files contain a unique secret which has in the past corresponded to these values. For true compatability, one should download the file battle.net specifies and run the dll contained within. An update form of CheckRevision is certainly possible and would be an easy way to disable most emulated battle.net clients.

Yes, it would. But I am going over the ultra-basic algorithm, not the Blizzard-made code. The point of this is to provide an understanding of the algorithm.

Well if bnetdocs strives to provide accurate information, then I wouldn't accept this as an explanation of the CheckRevision algorithm.