• Welcome to Valhalla Legends Archive.
 

Deriving version byte?

Started by iago, January 29, 2006, 01:45 PM

Previous topic - Next topic

iago

I know it's been discussed before, but has anybody done any work on deriving the version byte from the game's files?  I've always meant to go back and figure out where it comes from, but I've never gotten around to it. 
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Skywing

There is no good way to do this.  It's hardcoded as part of an immediate instruction operand in most cases.

For some games, it has often been the rule that the version code is always the minor version, but this is not the case for all games and not something I'd rely on.

The perhaps most reliable way to do it is to just bruteforce the version code starting at the current one and incrementing once per connection attempt until you find the new one.

Yegg

Quote from: Skywing on January 29, 2006, 01:54 PM
The perhaps most reliable way to do it is to just bruteforce the version code starting at the current one and incrementing once per connection attempt until you find the new one.

I once considered that very same method. However, the game client must somehow obtain the version byte. It makes sense that the server would send it to the client? Why is it that we cannot immitate the client in this area?

UserLoser

Quote from: Yegg on January 29, 2006, 02:48 PM
I once considered that very same method. However, the game client must somehow obtain the version byte. It makes sense that the server would send it to the client? Why is it that we cannot immitate the client in this area?

Because:
Quote from: Skywing on January 29, 2006, 01:54 PM
It's hardcoded as part of an immediate instruction operand in most cases.

For some games, it has often been the rule that the version code is always the minor version, but this is not the case for all games and not something I'd rely on.

Yegg

Quote from: UserLoser on January 29, 2006, 02:49 PM
Quote from: Yegg on January 29, 2006, 02:48 PM
I once considered that very same method. However, the game client must somehow obtain the version byte. It makes sense that the server would send it to the client? Why is it that we cannot immitate the client in this area?

Because:
Quote from: Skywing on January 29, 2006, 01:54 PM
It's hardcoded as part of an immediate instruction operand in most cases.

For some games, it has often been the rule that the version code is always the minor version, but this is not the case for all games and not something I'd rely on.

I figured I'd get an answer like this. However I don't understand the hardcoded part. Does the client send the server something to check for an updated version of the game? Or does the server send something to the client? I don't understand how if the server were to send something to the client, we cant receive this message and figure out what the value is.

topaz

The client sends the current version byte, and the server checks it against the current.
RLY...?

iago

When the game is updated, parts of the game are re-written to work differently.  The version byte is part of one of those sections.  So there might be code like:

version_byte = 0xC7;
game.send(version_byte);

Which, when you update it, changes to:

version_byte = 0xC9;
game.send(version_byte);

There is no good way to find that code, unfortunately. 
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


UserLoser

Quote from: Yegg on January 29, 2006, 02:52 PM
I figured I'd get an answer like this. However I don't understand the hardcoded part. Does the client send the server something to check for an updated version of the game? Or does the server send something to the client? I don't understand how if the server were to send something to the client, we cant receive this message and figure out what the value is.

The version byte is hardcoded in your bot, unless you're using BNLS/something else like it so I don't get the confusion.

When there's a new patch, you'll get a version update required message, say, in SID_AUTH_CHECK.  Then the client downloads the patch file given, and performs the patching routine.  Then the game files the client has (Starcraft.exe, Battle.snp, etc) are updated and the game restarts.  Since Starcraft.exe was patched, there is a new hardcoded value for the version code and then that's just sent again next time you connect.

iago

Quote from: UserLoser on January 29, 2006, 03:42 PM
Quote from: Yegg on January 29, 2006, 02:52 PM
I figured I'd get an answer like this. However I don't understand the hardcoded part. Does the client send the server something to check for an updated version of the game? Or does the server send something to the client? I don't understand how if the server were to send something to the client, we cant receive this message and figure out what the value is.

The version byte is hardcoded in your bot, unless you're using BNLS/something else like it so I don't get the confusion.

When there's a new patch, you'll get a version update required message, say, in SID_AUTH_CHECK.  Then the client downloads the patch file given, and performs the patching routine.  Then the game files the client has (Starcraft.exe, Battle.snp, etc) are updated and the game restarts.  Since Starcraft.exe was patched, there is a new hardcoded value for the version code and then that's just sent again next time you connect.

Somebody failed to understand what "hardcoded" means. 
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


FrOzeN

Maybe you could download patch.txt of Battle.net's FTP. Then there might be a simple formula for each game plus to update the Version Byte (excluding revisions; letters).

Eg, StarCraft:
Hex(179 + 2 x Patch)

That formula seems to work like so:
1.13: Hex(179 + 2 * 13) = CD
1.12: Hex(179 + 2 * 12) = CB
1.11: Hex(179 + 2 * 11) = C9
And so fourth...

Just a theory that came to mind. :)
~ FrOzeN

Skywing

There is no guarantee that patches will follow the same pattern in the future.

Warrior

I've found the best solution is to have configuration overrides for the version byte incase it changes in another way than that known along with the "smart" bruteforce method Frozen posted.
Quote from: effect on March 09, 2006, 11:52 PM
Islam is a steaming pile of fucking dog shit. Everything about it is flawed, anybody who believes in it is a terrorist, if you disagree with me, then im sorry your wrong.

Quote from: Rule on May 07, 2006, 01:30 PM
Why don't you stop being American and start acting like a decent human?

iago

Quote from: Warrior on January 29, 2006, 04:26 PM
I've found the best solution is to have configuration overrides for the version byte incase it changes in another way than that known along with the "smart" bruteforce method Frozen posted.

Yeah, same.  I'm also going to provide an automatic-updater which will pull the current version byte from BNLS/RCRS.  I just need to find a way to download the hash files.. :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Skywing

#13
Quote from: iago on January 29, 2006, 05:51 PM
Quote from: Warrior on January 29, 2006, 04:26 PM
I've found the best solution is to have configuration overrides for the version byte incase it changes in another way than that known along with the "smart" bruteforce method Frozen posted.

Yeah, same.  I'm also going to provide an automatic-updater which will pull the current version byte from BNLS/RCRS.  I just need to find a way to download the hash files.. :)
As I alluded to in previous threads, you might look into calling bnupdate with a slightly modified patch script with the patch mpq you get from Battle.net when you try to log in with an old version of a product.

You could also try to implement the entire patch language yourself, though I can tell you from experience that it's a lot of work to do so.

The way BC does it is if it gets a too-old-version reply, it will download the given patch MPQ and apply a subset of it (only the parts affecting the files relevant for CheckRevision) and then do a brute force search for the new version code to update in its configuration.

BNLS has something similar, although you have to manually tell it which patch MPQ to download and what the new version code is as it does not have a built in Battle.net client.

iago

#14
Quote from: Skywing on January 29, 2006, 06:23 PM
As I alluded to in previous threads, you might look into calling bnupdate with a slightly modified patch script with the patch mpq you get from Battle.net when you try to log in with an old version of a product.

You could also try to implement the entire patch language yourself, though I can tell you from experience that it's a lot of work to do so.

The way BC does it is if it gets a too-old-version reply, it will download the given patch MPQ and apply a subset of it (only the parts affecting the files relevant for CheckRevision) and then do a brute force search for the new version code to update in its configuration.

BNLS has something similar, although you have to manually tell it which patch MPQ to download and what the new version code is as it does not have a built in Battle.net client.
It would definitely be useful for use the automatic-updater, but I don't have the time or motivation to figure out enough about it to be useful.  Plus, I'm trying to implement everything in Java in a cross-platform manner, so I'd probably have to figure out the patch scripting myself; of course, to do that, I would also have to figure out how to read the .mpq.  That is a lot more work than I want to do. 

Maybe some day, though....

By the way, do they ever ban you for too many old/invalid version bytes?
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*