Saints Row IV Is it hard-coded directly to the game exe?

Knobby, Raistin Kane has discovered that there are data structures in the zone files that contain pointers which are absolute offsets from the beginning of the zone file. Without the ability to parse and fixup these offsets, we are unable to add or remove objects from the zone file, because this moves the data that these offsets point to.

Would you be able to provide enough information on those data structures so that I can parse and fix up any absolute offsets when objects are added or removed from the zone file?

Raistin Kane has identified two zone file sections that break when they are moved, and therefore contain absolute offsets into the file:
  • 0x2247 - water volumes
  • 0x2250 - parking data
I don't know if there are other sections that have them, but these definitely do. I don't even need to parse out all the data -- just enough to fix up the file offsets if things are added/removed from earlier sections in the zone file.

If you can provide information on the data structures, I can update my SRZoneTool to parse and fix them up automatically.

Thank you so much!
 
Last edited:
I've just added an option to my SRZoneTool which will force zone file sections not to change size, and therefore make sure their offsets remain the same. Obviously, when you use this option, it won't let you increase the size of a section beyond the current size, but it will allow you to remove things and it will automatically pad the section with zeros at the end to make sure the size doesn't change.

So, if you want to add a navpoint, for example, you'd have to first remove some other object to make room. But, in theory anyway, if you can find some object to remove and then add your navpoint, this should fix the issues with the 0x2247 and 0x2250 section file offsets.

Let me know if you want this. I haven't released the changes to the tool yet, but it's all coded and ready if you want to try it.
 
Knobby, Raistin Kane has discovered that there are data structures in the zone files that contain pointers which are absolute offsets from the beginning of the zone file. Without the ability to parse and fixup these offsets, we are unable to add or remove objects from the zone file, because this moves the data that these offsets point to.

Would you be able to provide enough information on those data structures so that I can parse and fix up any absolute offsets when objects are added or removed from the zone file?

Raistin Kane has identified two zone file sections that break when they are moved, and therefore contain absolute offsets into the file:
  • 0x2247 - water volumes
  • 0x2250 - parking data
I don't know if there are other sections that have them, but these definitely do. I don't even need to parse out all the data -- just enough to fix up the file offsets if things are added/removed from earlier sections in the zone file.

If you can provide information on the data structures, I can update my SRZoneTool to parse and fix them up automatically.

Thank you so much!
I don't think this is the case. I think instead these sections have specific alignment requirements due to their data. It looks like water volumes are 16 byte aligned and parking is 4 byte aligned. Most sections actually require alignment. The only issue here is that this alignment isn't on the section itself, but the data inside the section. This means you have:

<section header data>
<random data possibly>
<alignment padding>
<more data>
<alignment padding>
<more data>

If you shift a section by like 15 bytes you'd need to go inside the thing and ensure the padding on the first thing ends up correct. This is complicated again by the code doing what it wants here. As an example, water volumes write out the number of volumes and then ensure 16-byte alignment on the water volume data. This might be difficult to accomplish well and we might have to rethink this a bit.
 
I don't think this is the case. I think instead these sections have specific alignment requirements due to their data. It looks like water volumes are 16 byte aligned and parking is 4 byte aligned. Most sections actually require alignment. The only issue here is that this alignment isn't on the section itself, but the data inside the section. This means you have:

<section header data>
<random data possibly>
<alignment padding>
<more data>
<alignment padding>
<more data>

If you shift a section by like 15 bytes you'd need to go inside the thing and ensure the padding on the first thing ends up correct. This is complicated again by the code doing what it wants here. As an example, water volumes write out the number of volumes and then ensure 16-byte alignment on the water volume data. This might be difficult to accomplish well and we might have to rethink this a bit.
The whole data alignment issue didn't even occur to me, but it makes perfect sense. Every time I try to add or remove something from a preceding section, it changes the offsets of the latter sections and the alignments get messed up, and the game crashes when it attempts to load the zone. I recalculate all the alignments of the zones I can parse, but it's the zones I can't parse that cause the problems. If I could know the alignment of each section, I could fix those up when I rebuild the zone file. Now you've given me the alignments of those 2 zones, and I thank you, but I'm thinking other zones will have the same issue.

I do think there is some merit to Raistin Kane's hypothesis, however, based on what I'm seeing in the zone file. Here's the zone file he used ("dlc1/1608^dlc1_3c/sr3_city~f1608^dlc1_3c.czn_pc"), after running it through my SRReadZone tool:
Code:
0003FCEC             SECTION #11:
0003FCEC  UInt32       Section ID:   0x80002247 (Water volumes)
0003FCF0  UInt32       CPU Size:     7440 bytes
0003FCF4  UInt32       GPU Size:     0 bytes
...
0003FCF8  UInt32       Count:        0x00000004
0003FCFC  Unit32       Offset #1:    0x0003FD10
0003FD00  Unit32       Offset #2:    0x00040650
0003FD04  Unit32       Offset #3:    0x00040F90
0003FD08  Unit32       Offset #4:    0x00041680

0003FD0C  Uint32       Unknown:      0x00000000 (likely to force a 16-byte alignment)
0003FD10  40 5C 90 44 B9 36 C4 41 A8 1C AE 44 A8 1C AE 44 40 FD E6 41 80 38 1B 3F C0 22 B9 41 C0 22 B9 41 62 00 00 00 58 FD 03 00 28 ...
...
00041A08             SECTION #12:
00041A08  UInt32       Section ID:   0x80002249 (Water surfaces)
00041A0C  UInt32       CPU Size:     20808 bytes
00041A10  UInt32       GPU Size:     0 bytes
The number in the left column represents the hex offset from the beginning of the zone file. The section from 0003FCF8 to 0003FD10 was formatted manually by me above to make it easier to read, based on Raintin's data structure, but the data values are right out of the zone file itself.

And here's a copy of the data structure he proposed (copied from his posting):
Code:
0x80002247
---
Signature(32bit) = [47 22 00 80]
Size of section(32bit)
???(32bit) = [00 00 00 00]
num of subsection(32bit)
FOR EACH SUBSECTION {
    start offset of the subsection(32bit)
}
???(32bit) = [00 00 00 00]
...
Those numbers really do look like zone file offsets, wouldn't you agree? (particularly Offset #1 which seems to point to the data immediately following the offsets)
 
Last edited:
Back
Top