public static ChunkyCollection ReadChunkyChunks(byte[] chunkBytes) { MemoryStream ms = new MemoryStream(chunkBytes, false); RelicBinaryReader br = new RelicBinaryReader(ms); remaining = new byte[0]; int pos = 0; int fileLength = chunkBytes.Length; ChunkyCollection col = new ChunkyCollection(); while (pos<fileLength && (fileLength-pos)>20) //check that there's a reasonable amount remaining so that the app doesn't choke on the extra bytes //added to the end of files like Relic's Chunky Viewer does on SpookyRAT extracted files { string type = br.ReadString(4); if (type == "FOLD" || type=="DATA") { string id = br.ReadString(4); int version = br.ReadInt32(); int dataLength = br.ReadInt32(); int nameLength = br.ReadInt32(); string name = br.ReadString(nameLength); byte[] innerData = br.ReadBytes(dataLength); if (type == "FOLD") { col.Add(new ChunkyFolder(id, version, name, innerData)); } else { col.Add(CreateChunkyChunk(id, "", version, name, innerData)); } pos+= dataLength+nameLength+20; } else if (type == "Reli") { br.BaseStream.Seek(-4, SeekOrigin.Current); remaining = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position)); //we've hit another chunk, so stop the reading break; } else if (type=="") { //HACK: drop out with REC files rather than exceptioning, as the trailing info doesn't seem to be Chunkified remaining = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position)); break; } else { throw new InvalidChunkException("Chunk was not of type FOLD or DATA"); } } return col; }
public static ChunkyChunk ReadChunkyChunk(byte[] chunkBytes, string parentID) { MemoryStream ms = new MemoryStream(chunkBytes, false); RelicBinaryReader br = new RelicBinaryReader(ms); string type = br.ReadString(0,4); string id = br.ReadString(4); int version = br.ReadInt32(); int dataLength = br.ReadInt32(); int nameLength = br.ReadInt32(); string name = br.ReadString(nameLength); byte[] innerData = br.ReadBytes(dataLength); if (type=="FOLD") { return new ChunkyFolder(id, version, name, innerData); } else if (type=="DATA") { return CreateChunkyChunk(id, parentID, version, name, innerData); } else { throw new InvalidChunkException("Chunk was not of type FOLD or DATA"); } }