BNETDocs
CheckRevision

CheckRevision is a module sent by the server during the logon process. The purpose of CheckRevision is to ensure that only official, unmodified Battle.net clients are connecting to Battle.net servers.

Procedure

In all versions of CheckRevision, the following procedure is used to obtain CheckRevision and run it to return some values to the server:

  1. The client sends the server its platform ID, product ID, and version byte via C>S 0x06 SID_STARTVERSIONING or C>S 0x50 SID_AUTH_INFO.

  2. The server will then determine which CheckRevision to serve the client and then send the appropriate filename and filetime of the CheckRevision MPQ and a formula for the CheckRevision function via S>C 0x06 SID_STARTVERSIONING or S>C 0x50 SID_AUTH_INFO.

  3. The client checks bncache for CheckRevision. If CheckRevision is not found in bncache, the client initiates a BNFTPv1 connection to download CheckRevision.

  4. The client verifies that the CheckRevision MPQ contains a valid Blizzard Weak Digital Signature. If one is not found, the client immediately closes the connection to the server. It appears that this does not apply for XMAC/PMAC clients.

  5. The client extracts the CheckRevision DLL, whose base filename is the same as the CheckRevision MPQ's base filename (e.g. CheckRevision.mpq contains CheckRevision.dll). Modern versions of game clients verifies the CheckRevision DLL's signature. If one is not found, the client immediately closes the connection to the server.

  6. The client calls CheckRevision(). If the function returns 0, the client immediately closes the connection to the server.

  7. Information returned from CheckRevision() is sent to the server via C>S 0x07 SID_REPORTVERSION or C>S 0x51 SID_AUTH_CHECK.

CheckRevision() function declaration in C++

extern "C" __declspec(dllexport) std::int32_t __stdcall CheckRevision(const char* filename1, const char* filename2, const char* filename3, const char* formula, std::uint32_t* version, std::uint32_t* checksum, char* exeinfo);

Filenames

Product filename1 filename2 filename3
W2BN WarCraft II BNE.exe Storm.dll Battle.snp
STAR, SEXP StarCraft.exe Storm.dll Battle.snp
D2DV, D2XP Game.exe Bnclient.dll D2Client.snp
WAR3, W3XP War3.exe Storm.dll Game.dll

* - In the more recent versions of some products, NULL pointers are passed in for the filename2 and filename3 when the corresponding files are missing.

Version 1a

Also known as "classic CheckRevision", this version uses the following naming format: {PLATFORM}ver{NUM}.mpq (ex: IX86ver0.mpq).

{PLATFORM}: IX86, XMAC, PMAC

{NUM}: 0 - 7

The formula given by the server is generally in the following format: A={int} B={int} C={int} 4 A=A{op}S B=B{op}C C=C{op}A A=A{op}B.

{int}: A positive integer, whose max value is presumably the max value of a 32-bit signed integer.

{op}: +, -, *, /, ^ (XOR)

Example formulas:

  • A=5 B=10 C=15 4 A=A+S B=B-C C=C+A A=A-B
  • A=1239576727 C=1604096186 B=4198521212 4 A=A+S B=B-C C=C^A A=A+B
  • A=0 B=0 C=0 4 A=A+S C=C+A

It is possible that some operators may never be used, and also possible that the operands will not be consistent, so custom implementations should be wary of this.

In some cases, Battle.net may return a "default" formula, A=0 B=0 C=0 4 A=A+S C=C+A.

Known Cases:

- Connecting with StarCraft pre-1.18

Checksum Algorithm

Each file is compiled with a different "hash code" that is first XOR'd with the A value from the formula.

For {NUM} 0-7, the hash codes are 0xE7F4CB62, 0xF6A14FFC, 0xAA5504AF, 0x871FCDC2, 0x11BF6A18, 0xC57292E6, 0x7927D27E, and 0x2FEC8733 respectively.

Each of up to 3 hash files are read in 4-byte chunks (as integers) as 'S' and then each operation in the formula is performed on every chunk. The resulting value of 'C' is returned as the checksum.

Version and EXE Info

The version value is a combination of dwProductVersionMS and dwProductVersionLS from VS_FIXEDFILEINFO for the EXE.

The exeinfo value is a space-delimited C string containing the following values:

  1. EXE Name (ex. war3.exe)
  2. Last Modified Date (ex. 08/16/09)
  3. Last Modified Time (ex. 19:21:59)
  4. Filesize in bytes (ex. 471040)

An example of a valid string would be: war3.exe 08/16/09 19:21:59 471040

Version 1b

In late 2006, Blizzard began to serve CheckRevision 1b. This version uses the following naming format: ver-{PLATFORM}-{NUM}.mpq (ex: ver-IX86-3.mpq).

{PLATFORM}: IX86, XMAC, PMAC, OSXI

{NUM}: 0 - 7

These files were mostly the same as the old ones, except that the hashed files were padded to the next 1024-byte interval using bytes of descending values starting at 0xFF and going to 0x00 before looping back around.

Digital Signing

In May 2016, Blizzard signed CheckRevision 1b DLLs. Starting with StarCraft 1.17.0 and Diablo II 1.14d, the client will verify the signature of the CheckRevision DLL.

Version 2

In late 2006, possibly at the same time CheckRevision 1b was released, Blizzard began to serve CheckRevision 2.

There are two variants of CheckRevision 2, lockdown and psistorm for PC and Mac clients respectively. This version uses the following naming format: {VARIANT}-{PLATFORM}-{NUM}.mpq (ex: lockdown-IX86-03.mpq or psistorm-XMAC-11.mpq).

{VARIANT}: lockdown, psistorm

{PLATFORM}: IX86 (valid only for lockdown variant), XMAC(valid only for psistorm variant), PMAC(valid only for psistorm variant)

{NUM}: 00 - 19

Checksum Algorithm

The algorithm for this version is somewhat more complicated. In short (for Lockdown at least), the seed string is shuffled and then hashed along with various parts of the game files, the library (DLL) itself, and a dump from the game's video memory. The hashing function used for this hash is another variation of SHA-1 (different from both standard SHA-1 and XSHA-1 used in password hashing).

For more information, see the following resources:

Version and EXE Info

The version value is the same as from CheckRevision v1.

The info value is a null-terminated, shuffled continuation of the hash digest returned when calculating the checksum. The shuffling process will sometimes affect the size of this value, so it may not always be 16 bytes in length (not including the terminator).

Version 3a

In early 2019 Battle.net began serving CheckRevision.mpq to Diablo 2 clients. The seed value is base64-encoded and appears like kjen1QAA.

Checksum Algorithm

The algorithm used by CheckRevision.mpq is much simpler than all of the previous version checks, but does not actually verify the full checksum of the game, only the EXE's version number. Because of this it can be emulated without actually having a copy of the game EXE.

Once decoded, the first 4 bytes of the seed are combined with a colon :, the EXE's version number (as a dot-separated string, ex: 1.14.3.71), another colon, and a single byte 0x01. This value is then hashed using standard SHA1.

result = b64encode(sha1(b64decode(seed)[:4], ':' + version + ':', 0x01))

The first 4 bytes of this result are used as the checksum value.

Version and EXE Info

The version value for CheckRevision version 3a is always 0.

The info value is a null-terminated continuation of the result.

Version 3b

Version 3b appeared along with the re-release of Diablo 1 and WarCraft 2. It is (so far) only used for these 2 games, and only on their entirely separate, special server connect-forever.classic.blizzard.com. The archive for this version is CheckRevisionD1.mpq.

The checksum algorithm for this version is the same as for version 3a.

Version and EXE Info

Version 3b includes the base64-encoded SHA1 hash of the EXE's signature's public key (as a hex string) and the 4-byte seed value, appended to the result, after a colon ':'. This only affects the value returned for info.

result += ':' + b64encode(sha1(public_key, value))

See the implementation in Warden.dll for more details.

For version 3b the version value is now always 6.

If calling the CheckRevision() function from the v3 DLL, the calling app's version needs to match the version of the game EXE and have any valid signature.

History

  • February 25, 2020 CheckRevision v3a (CheckRevision.mpq) recompiled.
  • March 28, 2019 GOG releases W2BN client, connect-forever.classic.blizzard.com:6112 serve CheckRevision v3b (CheckRevisionD1.mpq) to W2BN clients.
  • March 7, 2019 GOG releases DRTL client, connect-forever.classic.blizzard.com:6112 serve CheckRevision v3b (CheckRevisionD1.mpq) to DRTL clients.
  • February 2, 2019 CheckRevision v3b (CheckRevisionD1.mpq) compiled.
  • January 4, 2019 Battle.net server reset, traditional Battle.net servers serve CheckRevision v3a (CheckRevision.mpq) to D2DV and D2XP clients.
  • January 3, 2019 CheckRevision v3a (CheckRevision.mpq) compiled.
  • May 27, 2016 CheckRevision v1b DLL files signed
  • April 21, 2016 CheckRevision v2 updated for XMAC
  • March 5, 2007 CheckRevision is updated
  • Late 2006 CheckRevision v2 released
  • Late 2006 Checkrevision v1b released
  • August 10, 2006 CheckRevision v1b compiled.
  • March 3, 1997 CheckRevision v1a compiled.
| Edited: xboi209
Comments
Davnit

Added information on the new algorithm for v3.

xboi209

I found that if D2 1.13c is served IX86ver1.mpq, it crashes with a 0xc00000005 error. Serving it ver-IX86-1.mpq, which is what Battle.net served, no longer causes it to crash. This leads me to think that Blizzard didn't just rename CheckRevision v1 files in 2006, they probably recompiled CheckRevision v1 with the same code or different code while keeping the output the same.