July 8Jul 8 ▂ ▃ ▅ ▆ █ SAMPLES █ ▆ ▅ ▃ ▂A majority of the samples above are of the Rio movie game as that game seems to be the last Eurocom game to use the .edb archive files. Regarding GoldenEye 007 Reloaded on the other hand as the only other game I sampled from, it has a whole lot of .dat's and some .geo's in there as well. I've looked at Disney Universe as well and it was pretty much the same deal.Other than that tidbit, there is in fact a ripping tool for the Eurocom games called Eurochef but it only supports a number of uncompressed/unencrypted games throughout the 2000's. Not any before then and not any after the fact either, including the ones I've mentioned due to them being compressed/encrypted. It should probably help y'all in cracking at least Rio's .edb's and maybe GoldenEye if lucky Edited July 9Jul 9 by ColbyDash
Yesterday at 05:49 PM1 day Supporter So here is what i got so far. But still can't figure out compression algo. But it's compressed for sure.//------------------------------------------------ //--- 010 Editor v14.0 Binary Template // // File: // Authors: // Version: // Purpose: // Category: // File Mask: // ID Bytes: // History: //------------------------------------------------ BigEndian();OutputPaneClear(); local uint32 i,j,k,l; struct { char GEOMSign[4]; ubyte Unknown_0; ubyte Unknown_1; uint16 Unknown_2; uint32 Unknown_3; uint32 Unknown_4; uint32 Unknown_5; uint32 FileSize; uint32 Unknown_6; char Unknown_7[4]; uint32 Unknown_8; uint32 Unknown_9; uint32 ResourceDefOffset; uint32 EoF; uint32 Unknown_10; uint32 Unknown_11; uint32 Unknown_12; }Info; struct { uint32 TOCDataSize; byte TOCData[TOCDataSize - 4]; }UnknownTOC; FSeek(Info.ResourceDefOffset); struct { uint32 ResourceCount; uint32 Unknown_0; uint32 Unknown_1; uint32 ResourceTOCSize; uint32 ResourceNameDefOffset[ResourceCount]; struct { uint32 ResourceNameOffset; ubyte Unknown_0; ubyte Unknown_1; ubyte Unknown_2; ubyte Unknown_3; uint32 ResourceNameHash<format=hex>; uint32 Reserved; local uint32 cPos=FTell(); FSeek(startof(ResourceDefinition) + ResourceNameOffset); string ResourceName; FSeek(cPos); }ResourceDefinition[ResourceCount]<optimize=false>; }ResourceDefinition; FSeek(startof(UnknownTOC) + sizeof(UnknownTOC)); struct { uint32 Offset; uint32 Size; uint32 DecompressedSize; // 0 means uncompressed so it use Size uint32 Reserved; }ResourceDataDefinition[ResourceDefinition.ResourceCount];
Yesterday at 07:36 PM1 day Author 1 hour ago, h3x3r said:So here is what i got so far. But still can't figure out compression algo. But it's compressed for sure.//------------------------------------------------ //--- 010 Editor v14.0 Binary Template // // File: // Authors: // Version: // Purpose: // Category: // File Mask: // ID Bytes: // History: //------------------------------------------------ BigEndian();OutputPaneClear(); local uint32 i,j,k,l; struct { char GEOMSign[4]; ubyte Unknown_0; ubyte Unknown_1; uint16 Unknown_2; uint32 Unknown_3; uint32 Unknown_4; uint32 Unknown_5; uint32 FileSize; uint32 Unknown_6; char Unknown_7[4]; uint32 Unknown_8; uint32 Unknown_9; uint32 ResourceDefOffset; uint32 EoF; uint32 Unknown_10; uint32 Unknown_11; uint32 Unknown_12; }Info; struct { uint32 TOCDataSize; byte TOCData[TOCDataSize - 4]; }UnknownTOC; FSeek(Info.ResourceDefOffset); struct { uint32 ResourceCount; uint32 Unknown_0; uint32 Unknown_1; uint32 ResourceTOCSize; uint32 ResourceNameDefOffset[ResourceCount]; struct { uint32 ResourceNameOffset; ubyte Unknown_0; ubyte Unknown_1; ubyte Unknown_2; ubyte Unknown_3; uint32 ResourceNameHash<format=hex>; uint32 Reserved; local uint32 cPos=FTell(); FSeek(startof(ResourceDefinition) + ResourceNameOffset); string ResourceName; FSeek(cPos); }ResourceDefinition[ResourceCount]<optimize=false>; }ResourceDefinition; FSeek(startof(UnknownTOC) + sizeof(UnknownTOC)); struct { uint32 Offset; uint32 Size; uint32 DecompressedSize; // 0 means uncompressed so it use Size uint32 Reserved; }ResourceDataDefinition[ResourceDefinition.ResourceCount]; Appreciate the help so far! Suspected there was something about em that was either compressed or encrypted
23 hours ago23 hr Localization Compression should be Eurocom EDL2 with EDL 82 headers.Eurocom EDL2 decompression code can be found in QuickBMS GitHub repo:QuickBMS/src/unz.c at 5315ffe664b88dc09ae783ad17d9dfd252b1c927 · LittleBigBug/QuickBMSQuickBMS/src/unz.c at 5315ffe664b88dc09ae783ad17d9dfd252b1c927 · LittleBigBug/QuickBMSQuickBMS/src/perform.c at 5315ffe664b88dc09ae783ad17d9dfd252b1c927 · LittleBigBug/QuickBMS
14 hours ago14 hr Supporter Thank you but i have problems find compressed data offset. In file there is 4 bytes sign EDL 0x82 then compressed size and then decompressed size uint32. So offset should be at 0xC but it decompress only small portion of file. Maybe it 's chunked?Here is sample in case you wnat to try it. hud_loadingscreen_m03.7z Edited 14 hours ago14 hr by h3x3r
11 hours ago11 hr Localization 2 hours ago, h3x3r said:~ Snipped to preserve space ~Here is the binary template for 010 Editor I came up with://------------------------------------------------ // 010 Editor Binary Template //------------------------------------------------ BigEndian(); typedef struct { uint count; uint relative_offset <format=hex>; } ARRAY_DESCRIPTOR; string ArrayComment(ARRAY_DESCRIPTOR &item) { local uint target = (uint)(startof(item.relative_offset) + item.relative_offset); if (item.count == 0) return "empty"; return Str("%u item(s), absolute target 0x%08X", item.count, target); } typedef struct { char magic[4] <comment="GEOM">; uint file_hash <format=hex>; uint version; uint flags <format=hex>; uint unix_timestamp; uint total_file_size; uint partial_file_size; char project_code_raw[4] <comment="B57T / logical T75B">; uint platform_versions[5] <format=hex>; uint debug_start <format=hex>; uint debug_end <format=hex>; uint runtime_value <format=hex>; ARRAY_DESCRIPTOR sections <comment=ArrayComment>; ARRAY_DESCRIPTOR reference_pointers <comment=ArrayComment>; ARRAY_DESCRIPTOR entities <comment=ArrayComment>; ARRAY_DESCRIPTOR animations <comment=ArrayComment>; ARRAY_DESCRIPTOR animation_skins <comment=ArrayComment>; ARRAY_DESCRIPTOR scripts <comment=ArrayComment>; ARRAY_DESCRIPTOR maps <comment=ArrayComment>; ARRAY_DESCRIPTOR animation_modes <comment=ArrayComment>; ARRAY_DESCRIPTOR animation_sets <comment=ArrayComment>; ARRAY_DESCRIPTOR particles <comment=ArrayComment>; ARRAY_DESCRIPTOR swooshes <comment=ArrayComment>; ARRAY_DESCRIPTOR spreadsheets <comment=ArrayComment>; ARRAY_DESCRIPTOR fonts <comment=ArrayComment>; ARRAY_DESCRIPTOR textures <comment=ArrayComment>; } EDB_HEADER; typedef struct { char magic[3] <comment="EDL">; ubyte codec <format=hex,comment="0x82 = EDL2, big-endian stream words">; uint stored_size; uint decoded_size; if (stored_size >= 12) ubyte compressed_data[stored_size - 12] <format=hex>; } EDL2_BLOCK; string EdlComment(EDL2_BLOCK &block) { return Str("stored %u bytes, decodes to %u bytes", block.stored_size, block.decoded_size); } if (FileSize() < 0xB0 || ReadUByte(0) != 'G' || ReadUByte(1) != 'E' || ReadUByte(2) != 'O' || ReadUByte(3) != 'M') { Warning("This is not a Rio GEOM EDB file."); return -1; } EDB_HEADER header; local int64 scan = FTell(); local uint stored; local uint decoded; while (scan + 12 <= FileSize()) { if (ReadUByte(scan) == 'E' && ReadUByte(scan + 1) == 'D' && ReadUByte(scan + 2) == 'L' && (ReadUByte(scan + 3) == 0x02 || ReadUByte(scan + 3) == 0x82)) { stored = ReadUInt(scan + 4); decoded = ReadUInt(scan + 8); if (stored >= 12 && decoded > 0 && scan + stored <= FileSize()) { FSeek(scan); EDL2_BLOCK chunk <comment=EdlComment>; scan += stored; continue; } } scan++; } Here are some of the resources I found that aided me in my research:https://sphinxandthecursedmummy.fandom.com/wiki/EngineXhttps://sphinxandthecursedmummy.fandom.com/wiki/EDB Edited 10 hours ago10 hr by Falkrian
9 hours ago9 hr Localization 4 minutes ago, h3x3r said:Thanks mate. Now it's clear. So the compressed data starts at offset 0xC.No problem at all!Happy to be able to contribute.
9 hours ago9 hr Supporter So here it is.############################## get BaseFileName basename get TotalFileSize asize get FileExtension extension comtype edl2 endian big idstring GEOM get Unknown_0 ubyte get Unknown_1 ubyte get Unknown_2 ushort get Unknown_3 uint32 get Unknown_4 uint32 get Unknown_5 uint32 get FileSize uint32 get Unknown_6 uint32 getdstring Sign 0x4 get Unknown_8 uint32 get Unknown_9 uint32 get ResourceDefOffset uint32 get EoF uint32 get Unknown_10 uint32 get Unknown_11 uint32 get Unknown_12 uint32 get TOCDataSize uint32 math TOCDataSize - 4 getdstring TOCData TOCDataSize savepos TOCOffset goto ResourceDefOffset get ResourceCount uint32 get Unknown_0 uint32 get Unknown_1 uint32 get ResourceTOCSize uint32 for i = 0 < ResourceCount savepos ResourceNameDefOff[i] get ResourceNameDefOffset[i] uint32 math ResourceNameDefOffset[i] + ResourceNameDefOff[i] next i for i = 0 < ResourceCount goto ResourceNameDefOffset[i] savepos EntryPos get ResourceNameOffset uint32 get Unknown_0 ubyte get Unknown_1 ubyte get Unknown_2 ubyte get Unknown_3 ubyte get ResourceNameHash uint32 get Reserved uint32 savepos cPos math ResourceNameOffset + EntryPos goto ResourceNameOffset get ResourceName[i] string goto cPos next i goto TOCOffset for i = 0 < ResourceCount get Offset uint32 get Size uint32 get DecompressedSize uint32 get Reserved uint32 savepos EoEntry if DecompressedSize == 0 goto Offset getdstring Dummy 0x2 get FileType ushort if FileType == 0 set Extension string "material" elif FileType == 5 set Extension string "particle" elif FileType == 8 set Extension string "texture" elif FileType == 9 set Extension string "mesh" elif FileType == 341 set Extension string "font" else set Extension string FileType endif string Name p "%s/%s.%s" BaseFileName ResourceName[i] Extension log Name Offset Size goto EoEntry else goto Offset getdstring Sign 0x3 get Codec ubyte get CSize uint32 get Size uint32 math CSize - 12 savepos Offset clog MEMORY_FILE Offset CSize Size goto 0 -1 getdstring Dummy 0x2 -1 get FileType ushort -1 if FileType == 0 set Extension string "material" elif FileType == 5 set Extension string "particle" elif FileType == 8 set Extension string "texture" elif FileType == 9 set Extension string "mesh" elif FileType == 341 set Extension string "font" else set Extension string FileType endif string Name p "%s/%s.%s" BaseFileName ResourceName[i] Extension clog Name Offset CSize Size goto EoEntry endif next i Edited 8 hours ago8 hr by h3x3r
9 hours ago9 hr Supporter BTW do you know something about extension/file type? I put dat extension to all of em. But i saw some ubyte variables. Unknown_0, Unknown_1, Unknown_2, Unknown_3.Does some of them represents file type/extension? get ResourceNameOffset uint32 get Unknown_0 ubyte get Unknown_1 ubyte get Unknown_2 ubyte get Unknown_3 ubyte get ResourceNameHash uint32I think i got it. File type may be described in unpacked file at offset 0x3 ubyte. I checked textures and they are type 8. Materials 0. Meshes 9.Also i found a problem in bms. I will update it.EDiT: Updated bms script. I have defined some of file type but rest is how it is. Edited 8 hours ago8 hr by h3x3r
1 hour ago1 hr Author Awesome! I just tested it out and we now got some files spit outNow to figure out how to read them so that they can be opened, imported somewhere, and whatnot
1 hour ago1 hr Supporter And let's start with textures. If you find unknown pixel format just let me know.from inc_noesis import * import noesis import rapi import os def registerNoesisTypes(): handle = noesis.register("Rio The Video Game PS3", ".texture") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadRGBA(handle, noepyLoadRGBA) noesis.logPopup() return 1 def noepyCheckType(data): bs = NoeBitStream(data) if len(data) < 20: return 0 return 1 def noepyLoadRGBA(data, texList): bs = NoeBitStream(data,NOE_BIGENDIAN) BaseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName())) bs.read(36) UnknownSize = bs.readUInt() TextureWidth = bs.readUShort() TextureHeight = bs.readUShort() bs.read(3) PixelFormat = bs.readUByte() bs.read(32) UnknownOffset = bs.readUInt() bs.read(20) TextureDataSize = bs.readUInt() - UnknownSize bs.seek(UnknownOffset + UnknownSize, NOESEEK_ABS) data = bs.read(TextureDataSize) if PixelFormat == 3: texFmt = noesis.NOESISTEX_DXT1 print("Pixel Format > DXT1 >", PixelFormat) elif PixelFormat == 1 or PixelFormat == 12: texFmt = noesis.NOESISTEX_DXT5 print("Pixel Format > DXT5 >", PixelFormat) else: print("Unknown Pixel Format > ", PixelFormat) texList.append(NoeTexture(rapi.getInputName(), TextureWidth, TextureHeight, data, texFmt)) return 1I also checked meshes and seems to be easy. Indices are triangles. But i think there will be problem with materials.... But who knows... Edited 1 hour ago1 hr by h3x3r
1 hour ago1 hr Author Good thinking and starting point too. Will update this comment once I have tested the script outAlright, I have tested out the script and it's reading the textures without any issues so far. The only issue that I have noticed so far is with the filenamesAs you can see in the image above, the texture is of course being read but the filename looks to have been mislabeled by the EDB BMS script as it's not the right texture it's supposed to be referring to. Rather it should be the following texture:This is the same case for the rest of the textures present in Blu's texture directory and I imagine for the rest of the EDBs as well if this is anything to go byEDIT: Yeah, it does look to be the case after looking at some of the HUD textures. Definitely is a bug. Otherwise, still no issues with reading the textures ^^ Edited 38 minutes ago38 min by ColbyDash
Create an account or sign in to comment