diff --git a/SabreTools.Serialization/Models/SpoonInstaller/FileEntry.cs b/SabreTools.Serialization/Models/SpoonInstaller/FileEntry.cs
new file mode 100644
index 00000000..8cab74d3
--- /dev/null
+++ b/SabreTools.Serialization/Models/SpoonInstaller/FileEntry.cs
@@ -0,0 +1,40 @@
+namespace SabreTools.Data.Models.SpoonInstaller
+{
+ ///
+ /// Single entry in the file table
+ ///
+ /// Entry data is BZ2-compressed
+ public class FileEntry
+ {
+ ///
+ /// File offset relative to the start of the file
+ ///
+ public uint FileOffset { get; set; }
+
+ ///
+ /// Compressed size of the entry
+ ///
+ /// Includes headers
+ public uint CompressedSize { get; set; }
+
+ ///
+ /// Uncompressed size of the entry
+ ///
+ public uint UncompressedSize { get; set; }
+
+ ///
+ /// CRC-32(?)
+ ///
+ public uint Crc32 { get; set; }
+
+ ///
+ /// Length of
+ ///
+ public byte FilenameLength { get; set; }
+
+ ///
+ /// ASCII filename
+ ///
+ public string? Filename { get; set; }
+ }
+}
diff --git a/SabreTools.Serialization/Models/SpoonInstaller/Footer.cs b/SabreTools.Serialization/Models/SpoonInstaller/Footer.cs
new file mode 100644
index 00000000..dda82e08
--- /dev/null
+++ b/SabreTools.Serialization/Models/SpoonInstaller/Footer.cs
@@ -0,0 +1,55 @@
+namespace SabreTools.Data.Models.SpoonInstaller
+{
+ ///
+ /// Structure similar to the end of central directory
+ /// header in PKZIP files
+ ///
+ public class Footer
+ {
+ ///
+ /// Unknown
+ ///
+ ///
+ /// Observed values:
+ /// - 81 83 DA 2F
+ ///
+ public uint Unknown0 { get; set; }
+
+ ///
+ /// Unknown
+ ///
+ ///
+ /// Observed values:
+ /// - 6A 00 00 00
+ ///
+ public uint Unknown1 { get; set; }
+
+ ///
+ /// Offset of the start of the file table
+ ///
+ public uint TablePointer { get; set; }
+
+ ///
+ /// Number of entries that preceed the footer
+ ///
+ public uint EntryCount { get; set; }
+
+ ///
+ /// Unknown
+ ///
+ ///
+ /// Observed values:
+ /// - 83 52 34 03
+ ///
+ public uint Unknown2 { get; set; }
+
+ ///
+ /// Unknown, signature?
+ ///
+ ///
+ /// Observed values:
+ /// - 43 F3 FF 0E
+ ///
+ public uint Unknown3 { get; set; }
+ }
+}
diff --git a/SabreTools.Serialization/Models/SpoonInstaller/SFX.cs b/SabreTools.Serialization/Models/SpoonInstaller/SFX.cs
new file mode 100644
index 00000000..ce68cd98
--- /dev/null
+++ b/SabreTools.Serialization/Models/SpoonInstaller/SFX.cs
@@ -0,0 +1,28 @@
+namespace SabreTools.Data.Models.SpoonInstaller
+{
+ ///
+ /// Represents the structure at the end of a Spoon Installer
+ /// SFX file. These SFX files store all files bz2-compressed
+ /// sequentially in the overlay of an executable.
+ ///
+ /// The design is similar to the end of central directory
+ /// in a PKZIP file. The footer needs to be read before
+ /// the entry table as both the pointer to the start of
+ /// the table as well as the entry count are included there.
+ ///
+ /// The layout of this is derived from the layout in the
+ /// physical file.
+ ///
+ public class SFX
+ {
+ ///
+ /// Set of file entries
+ ///
+ public FileEntry[]? Entries { get; set; }
+
+ ///
+ /// Footer representing the central directory
+ ///
+ public Footer? Footer { get; set; }
+ }
+}