Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.
Zero Tolerance for Disrespect

Siren 2 (2006, PS2) .rom and chunk files

Featured Replies

Siren 2 contains 8 chunk archives and a separate .rom file. The latter works as the game's table of contents and from what I can tell:

Archive header (0x20 bytes long):
4 - ID (SLPK)
4 - fairly long number that doesn't match with the chunk's filesize
4 - number of files within the game's archives
4 - offset to the game's tail
4 - null bytes
4 - unknown, could be related to the game's image's sectors
4 - fairly large number, around 2GB long
4 - fairly large number that's slightly smaller than the previous entry

File entry directory (0xA550 bytes long):
4 - relative filename offset inside tail, counts null byte as part of the filename
4 - unknown, number of different entries matches with number of archives, seems to identify each of the archive files
4 - possible file offset inside chunk file containing it
4 - possible filesize

Filename directory (starts on 0xA570 until EoF, contains 0xA55 entries):
Lists each rom.00X file in sequential order, followed by each of its files' full path filenames
Both the files and the rom.00X filenames end with a null byte

SPK.rom starts with the magic bytes SLPK, ROM.000-007 don't seem to have a header file and act exclusively as file archives. The game uses little endian ordering for its byte entries.

Zip contains SPK.rom as well as the first 16MBs of ROM.000 and ROM.004.

siren2.zip

Edited by ldvd

  • ldvd changed the title to Need help extracting Siren 2 (PS2) .rom and chunk files

The archive directory entry's first "unknown" is the archive filename offset:

image.png.23a83bb0d442e816ba6c54c51f17ce17.png

The "maybeFileSize" certainly seems likely given the corresponding filename extensions (PSS's are larger than WaveBank audio and TIM2 images).

The "maybeChunkOffset" is tough to gauge without knowing the full size of the archive files. How large is each one?

In ROM.000, there are multiple TIM2 files which you might be able to cross reference with offsets here:

  • 1F60h
  • 9FE0h
  • A160h
  • A2E0h
  • 12360h
  • 124E0h
  • 13560h

image.png.4cb1e635eece5bb71ab3a35cf14a6ad7.png

None of these offsets match records in ROM.000 though 🤔 (e.g. 00 E8 3E 1D):

image.png.28b9a66ff5ef59c67e2fb0f8fdada603.png

Maybe it's a bitfield? I tried shifting 0x1D3EE800 by multiple shifts though, and still none matched. Maybe each numbered archive actually has a relative base offset? It's also weird that the least significant byte would always be zero, because while some alignment is expected for data type alignment (often 4/8/16 bytes), 256 bytes of alignment feels wasteful (but maybe not 🤷) :

image.png.4db9cd243e41a5da2129f6b50b2afa54.png

010 Editor template:

LittleEndian();
BitfieldRightToLeft();

// define missing types
typedef char int8;
typedef char char8;
typedef wchar_t char16;
typedef uchar uint8;

// Archive header (0x20 bytes long)
struct ArchiveHeader
{
    char8 tag[4];           // 4 - ID (SLPK)
    uint32 unknown1;        // 4 - fairly long number that doesn't match with the chunk's filesize
    uint32 fileCount;       // 4 - number of files within the game's archives
    uint32 filenamesOffset; // 4 - offset to the list of filenames
    uint32 empty;           // 4 - null bytes
    uint32 unknown2;        // 4 - unknown, could be related to the game's image's sectors
    uint32 unknown3;        // 4 - fairly large number, around 2GB long
    uint32 unknown4;        // 4 - fairly large number that's slightly smaller than the previous entry
};

// File entry directory (16 bytes each, 0xA550 bytes total):
struct ArchiveDirectoryEntry(uint32 filenamesOffset)
{
    uint32 filenameOffset;          // 4 - relative filename offset inside tail, counts null byte as part of the filename
    uint32 archiveFilenameOffset;   // 4 - unknown, number of different entries matches with number of archives, seems to identify each of the archive files
    uint32 maybeChunkOffset;        // 4 - possible file offset inside chunk file containing it
    uint32 maybeFileSize;           // 4 - possible filesize

    local int64 originalFilePosition <hidden=true> = FTell();
    FSeek(filenamesOffset + filenameOffset);
    string filename;
    FSeek(filenamesOffset + archiveFilenameOffset);
    string externalArchiveFilename;
    FSeek(originalFilePosition);
};

ArchiveHeader header;
ArchiveDirectoryEntry entries(header.filenamesOffset)[header.fileCount] <optimize=false, open=true>;

 

Edited by piken

  • Author
7 hours ago, piken said:

The archive directory entry's first "unknown" is the archive filename offset:

Hadn't thought of that. Checked each archive's filename offset and they match with the address in that field.

How were you able to create those tables in your image? Were those done in HxD, or in that 010 Editor you've linked? Fresh off a single tutorial, all that's in the OP are wild guesses I hadn't checked thoroughly. Formatting entries like that would come in handy now that I know they can be done.

7 hours ago, piken said:

The "maybeChunkOffset" is tough to gauge without knowing the full size of the archive files. How large is each one?

ROM.000 is 537.675.840 bytes long, ROM.001 equals 550.553.664 bytes, ROM.002 574.061.760 bytes, ROM.003 549.920.704 bytes, ROM.004 537.743.872 bytes, ROM.005 581.976.128 bytes, ROM.006 538.966.080 bytes and ROM.007 597.037.120 bytes. I made that assumption because the chunk offset value never seems to be larger than the chunk's filesize.

7 hours ago, piken said:

None of these offsets match records in ROM.000 though

0x1D3EE800 in ROM.000 starts with the string TIM2.

HxD_4u0uWRjZot.png.6afafc1462199203f7cd7993c11057aa.png 

I've cross-referenced filenames in address A9B6 (ROM.000), AFB4 (ROM.001) and 1682A (ROM.004) by hand. Following these files' chunk offsets I've been similarly greeted with the string "TIM2", and all three of them ended with a similar tail mostly made of FF bytes per the field's filesize. I'm certain the file format's correct, and the sample files I provided were perhaps corrupted. Try this format out with the game's original files (JPN version).

Only thing we'd need now is to convert the file format into a QuickBMS script to extract the files with. I would do it, but my experience with QuickBMS is null and my programming skills are negligible.

Edited by ldvd

> Were those done in HxD, or in that 010 Editor you've linked?

Yep, 010 Editor is pretty useful for deeper inspection, enough that I bought it (but I also use free HxD for lighter tasks, and I tried imhex, but it feels kinda awkward 😅).

> I've cross-referenced filenames in address

Nice. Sounds like it is pretty well figured out now then (and maybe those other unknown fields can just safely stay unknown).

> my experience with QuickBMS is null

Likewise (it certainly looks different compared to all the other programming languages I've used 🤔). There's also Noesis that you could write a Python plugin for 🤷‍♂️. Good luck. 🤞

  • ldvd changed the title to Siren 2 (2006, PS2) .rom and chunk files
  • 1 year later...
  • 3 months later...
  • Localization

I added support for the SPK.ROM and the .pak & .edp files that are inside that in my extractor: https://github.com/smiRaphi/UniPyX

Maybe I'll add support for .d2b & .enc files at some point but they seem more complex (d2b seems to be some sort of config format, enc seems to be compressed)

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.