Valhalla Legends Forums Archive | BnetDocs Research and Discussion | Starcraft Verhash Creation

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

[pre](BYTE) Major
(BYTE) Int(Minor / 10)
(BYTE) (Minor % 10)
(BYTE) Revision[/pre]

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

[code]  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;
  }
[/code]
December 12, 2005, 5:28 PM
Myndfyr
What is a "verhash"?

Please use terminology consistent with BnetDocs.
December 12, 2005, 6:11 PM
JoeTheOdd
I can't remember what BnetDocs calls it, and I'm too laggy right now to see (stupid timeouts).

x86:
[quote]Its 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).[/quote]

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).
December 12, 2005, 8:07 PM
Myndfyr
This is C->S 0x50:
[pre]
(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
[/pre]

This is C->S 0x51:
[pre]
(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
[/pre]
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?
December 12, 2005, 10:35 PM
kamakazie
[quote author=MyndFyre link=topic=13484.msg137300#msg137300 date=1134426957]
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?
[/quote]

He is talking about EXE Version.
December 12, 2005, 10:43 PM
JoeTheOdd
Yup. EXE hash is from CheckRevision() itself.

EXE Version is the DWORD value returned when you call getEXEInfo or whatever in BNCSutil.
December 13, 2005, 2:02 AM
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.
December 13, 2005, 2:44 PM
JoeTheOdd
I'll look into it, eventually.
December 14, 2005, 1:02 AM
shout
[quote author=Joe link=topic=13484.msg137537#msg137537 date=1134522159]
I'll look into it, eventually.
[/quote]

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

[hr]

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:

[code]
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;
}
[/code]

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

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

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

[code]
(actualsize / 1024) * 1024
[/code]

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

[code]
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;
}

{...}
}
[/code]

After all three files have been processed, the EXE Hash is B.
December 15, 2005, 3:52 AM
kamakazie
[quote author=Shout link=topic=13484.msg137761#msg137761 date=1134618733]
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):

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

The mpq number will always be between 0 and 7.
[/quote]

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.
December 15, 2005, 5:15 AM
shout
[quote author=dxoigmn link=topic=13484.msg137768#msg137768 date=1134623758]
[quote author=Shout link=topic=13484.msg137761#msg137761 date=1134618733]
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):

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

The mpq number will always be between 0 and 7.
[/quote]

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

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.
December 16, 2005, 1:10 AM
kamakazie
[quote author=Shout link=topic=13484.msg137927#msg137927 date=1134695415]
[quote author=dxoigmn link=topic=13484.msg137768#msg137768 date=1134623758]
[quote author=Shout link=topic=13484.msg137761#msg137761 date=1134618733]
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):

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

The mpq number will always be between 0 and 7.
[/quote]

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

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

Well if bnetdocs strives to provide accurate information, then I wouldn't accept this as an explanation of the CheckRevision algorithm.
December 16, 2005, 2:06 AM

Search