Home » Stars! Clones, Extensions, Modding » Stars! Extensions » Detecting corrupt race files
Re: Detecting corrupt race files |
Sat, 15 May 2021 12:10 |
|
ricks03 | | | Messages: 222
Registered: January 2012 Location: NC | |
|
Here's the raw checksum (decrypted) data for having a race name of "0" and each time adding another "0"
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:248 108 11111000 1101100
BLOCK:0,Offset:138,Bytes:2 DATA DECRYPTED:248 92 11111000 01011100
BLOCK:0,Offset:139,Bytes:2 DATA DECRYPTED:200 92 11001000 01011100
BLOCK:0,Offset:140,Bytes:2 DATA DECRYPTED:200 108 11001000 01101100
BLOCK:0,Offset:141,Bytes:2 DATA DECRYPTED:248 108 11111000 01101100
BLOCK:0,Offset:142,Bytes:2 DATA DECRYPTED:248 92 11111000 01011100
BLOCK:0,Offset:143,Bytes:2 DATA DECRYPTED:200 92 11001000 01011100
BLOCK:0,Offset:144,Bytes:2 DATA DECRYPTED:200 108 11001000 01101100
BLOCK:0,Offset:145,Bytes:2 DATA DECRYPTED:248 108 11111000 01101100
BLOCK:0,Offset:146,Bytes:2 DATA DECRYPTED:248 92 11111000 01011100
BLOCK:0,Offset:147,Bytes:2 DATA DECRYPTED:200 92 11001000 01011100
BLOCK:0,Offset:148,Bytes:2 DATA DECRYPTED:200 108 11001000 01101100
BLOCK:0,Offset:149,Bytes:2 DATA DECRYPTED:248 108 11111000 01101100
BLOCK:0,Offset:150,Bytes:2 DATA DECRYPTED:248 92 11111000 01011100
BLOCK:0,Offset:151,Bytes:2 DATA DECRYPTED:200 92 11001000 01011100
The same two bits are flipping in the first and second binary set. Even "0"s change the first checksum bye; odd ones change the second checksum byte
https://www.irelandbybicycle.com
http://totalhost.sinister.net:999
https://github.com/ricks03/TotalHostReport message to a moderator
|
|
|
Re: Detecting corrupt race files |
Sat, 15 May 2021 12:29 |
|
ricks03 | | | Messages: 222
Registered: January 2012 Location: NC | |
|
Here's the results for Leftover Resources, and Race Icon:
Leftover resources
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:248 109
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:248 108
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:248 110
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:248 111
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:248 104
Race icon
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:248 108
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:240 108
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:232 108
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:224 108
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:216 108
...
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:32 108
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:24 108
BLOCK:0,Offset:137,Bytes:2 DATA DECRYPTED:0 108
I'm using Name, Leftover Resources, and Race Icon because you can change them without the race point total changing.
Leftover Resources and Race Icon clearly flip a single bit, which in turn flips a single bit in one byte of the checksum. Race name adds a bit each time. Effectively adding a single bit each time, going even odd.
I suspect difficulty in translating the checksum comes from the race score being stored in the race, so every time you change most values, you actually change two values - the value you changed, and the total race point value.
So I suspect the checksum is something done on the even bytes of block 6, and something done on the odd bytes of block 6. CRC? XOR?
Hope that's useful.
https://www.irelandbybicycle.com
http://totalhost.sinister.net:999
https://github.com/ricks03/TotalHostReport message to a moderator
|
|
| | | | | | | | | | | |
Re: Detecting corrupt race files |
Mon, 17 May 2021 14:20 |
|
ricks03 | | | Messages: 222
Registered: January 2012 Location: NC | |
|
So the formula appears to be If the Race Name is ABCDE / EFGHI
<other data that doesn't include the race name > 0 0 A E B F C G D H E I
where the values of the individual letters are converted to ASCII, with XOR'd even bytes for the first checksum value, and XOR'd odd bytes for the second checksum value.
That makes perfect sense for why ABCDE / ABCDE doesn't change the Checksum value, because you're XOR'ing A^A, C^C, E^E and 0^0, B^B,D^D, which don't change the value.
It's still not perfect, as it only works at the moment for an odd # of characters that is the same in both singular and plural, but it works for any combination of any characters for an odd number of characters. Just have to figure out how to fill in the blanks.
Edit: Literally, fill in the array of ascii values for singular and plural with 0s, so each is 15 characters long.
[Updated on: Mon, 17 May 2021 14:32]
https://www.irelandbybicycle.com
http://totalhost.sinister.net:999
https://github.com/ricks03/TotalHostReport message to a moderator
|
|
|
Re: Detecting corrupt race files |
Mon, 17 May 2021 15:32 |
|
ricks03 | | | Messages: 222
Registered: January 2012 Location: NC | |
|
This code appears to work for all cases:
singular name being random characters of random length
plural name being random characters of random length
sub raceCheckSum { # calculate a race checksum
# The race checksum is calculated from the array of decrypted data of Block 6
# without the singular/plural race name data
# The singular and plural race names are recalculated as ord arrays,
# and each padded to 15 characters
# Then the data arrray has added to it:
# + 0 0 (to replace the race name size fields I suspect)
# + the 1st two ord from the singular name, and the 1st two ord from the plural
# + the 2nd two ord from singular, and 2nd two ord from plural
# ...
#
# the 1st checksum byte is the XOR of the even data bytes
# the 2nd checksum byte is the XOR of the odd data bytes
my ($decryptedData, $singularRaceName, $pluralRaceName) = @_;
my @decryptedData = @{ $decryptedData };
my ($checkSum1, $checkSum2);
my $datalength = scalar @decryptedData - (1 + length($singularRaceName) + 1 + length($pluralRaceName) + 1);
my @dData = @decryptedData[0..$datalength];
# get the ascii values of the Race names - singular
my @singularRaceNameOrd = unpack("C*", $singularRaceName); #array of ascii values
unshift (@singularRaceNameOrd, 0); # add a starting 0
for (my $i = scalar @singularRaceNameOrd; $i <= 15; $i++) {
push (@singularRaceNameOrd, 0); # Pad out the array
}
my @pluralRaceNameOrd = unpack("C*", $pluralRaceName); #array of ascii values
unshift (@pluralRaceNameOrd, 0); # add a starting 0
for (my $i = scalar @pluralRaceNameOrd; $i <= 15; $i++) {
push (@pluralRaceNameOrd, 0); # Pad out the array
}
for (my $i=0; $i <= 15 ; $i=$i+2) { # add ords to the array in pairs (as we do odd/even)
push (@dData, $singularRaceNameOrd[$i]);
push (@dData, $singularRaceNameOrd[$i+1]);
push (@dData, $pluralRaceNameOrd[$i]);
push (@dData, $pluralRaceNameOrd[$i+1]);
}
for (my $i = 0; $i < scalar @dData; $i=$i+2) {
$checkSum1 = $checkSum1^int($dData[$i]); # Force numification
}
# Checksum 2: Odd bytes
for (my $i = 1; $i < scalar @dData; $i=$i+2) {
$checkSum2 = $checkSum2^int($dData[$i]); # Force numification
}
print "Calculated Race Checksum: $checkSum1 \t$checkSum2\n";
return $checkSum1, $checkSum2;
}
[edited to clean it up a bit]
That makes it work by the original algorothm. It correctly calculated the checksum for the file you sent me.
An alternate way would be XORing the decryptedData before the name, and then just XORing the value after that with the ord values from the names, but this is (in theory) more programmatically consistent with the formula you decoded -- apply the formula to the (modified) data.
[Updated on: Mon, 17 May 2021 16:49]
https://www.irelandbybicycle.com
http://totalhost.sinister.net:999
https://github.com/ricks03/TotalHostReport message to a moderator
|
|
|
Re: Detecting corrupt race files |
Mon, 17 May 2021 18:32 |
|
ricks03 | | | Messages: 222
Registered: January 2012 Location: NC | |
|
Darned close, but still not quite right.
Edit: found it; I had taken a shortcut, and sometimes calculated the name length by the string, which is clearly not a good idea due to the encodeOneByte characters.
sub raceCheckSum { # calculate a race checksum
# The race checksum is calculated from the array of decrypted data of Block 6
# without the singular/plural race name data
# The singular and plural race names are recalculated as ord arrays,
# and each padded to 15 characters
# Then the data arrray has added to it:
# + 0 0 (to replace the race name size fields I suspect)
# + the 1st two ord from the singular name, and the 1st two ord from the plural
# + the 2nd two ord from singular, and 2nd two ord from plural
# ...
#
# the 1st checksum byte is the XOR of the even data bytes
# the 2nd checksum byte is the XOR of the odd data bytes
my ($decryptedData, $singularRaceName, $pluralRaceName, $singularNameLength, $pluralNameLength) = @_;
my @decryptedData = @{ $decryptedData };
my ($checkSum1, $checkSum2);
my $datalength = scalar @decryptedData - (1 + $singularNameLength + 1 + $pluralNameLength + 1);
my @dData = @decryptedData[0..$datalength];
# get the ascii values of the Race names - singular
my @singularRaceNameOrd = unpack("C*", $singularRaceName); #array of ascii values
unshift (@singularRaceNameOrd, 0); # add a starting 0
for (my $i = scalar @singularRaceNameOrd; $i <= 15; $i++) {
push (@singularRaceNameOrd, 0); # Pad out the array
}
my @pluralRaceNameOrd = unpack("C*", $pluralRaceName); #array of ascii values
unshift (@pluralRaceNameOrd, 0); # add a starting 0
for (my $i = scalar @pluralRaceNameOrd; $i <= 15; $i++) {
push (@pluralRaceNameOrd, 0); # Pad out the array
}
for (my $i=0; $i <= 15 ; $i=$i+2) { # add ords to the array in pairs (as we do odd/even)
push (@dData, $singularRaceNameOrd[$i]);
push (@dData, $singularRaceNameOrd[$i+1]);
push (@dData, $pluralRaceNameOrd[$i]);
push (@dData, $pluralRaceNameOrd[$i+1]);
}
for (my $i = 0; $i < scalar @dData; $i=$i+2) {
$checkSum1 = $checkSum1^int($dData[$i]); # Force numification
}
# Checksum 2: Odd bytes
for (my $i = 1; $i < scalar @dData; $i=$i+2) {
$checkSum2 = $checkSum2^int($dData[$i]); # Force numification
}
return $checkSum1, $checkSum2;
}
[Updated on: Mon, 17 May 2021 19:08]
https://www.irelandbybicycle.com
http://totalhost.sinister.net:999
https://github.com/ricks03/TotalHostReport message to a moderator
|
|
| | | | | |
Goto Forum:
Current Time: Fri Apr 19 07:30:03 EDT 2024
|