Now to save this script for further use later.
import struct
import zlib
"""
struct SDCHeader {
u32 GroupTotal;
u32 EntryTotal;
u32 BulkDataSize;
u32 SanityCheck;
};
"""
class SDCHeader:
def __init__(self, data):
self.GroupTotal, self.EntryTotal, self.BulkDataSize, self.SanityCheck = struct.unpack("<IIII", data)
"""
struct SDCEntry {
u32 EntryID;
u32 UncompressedSize;
padding [4];
};
"""
class SDCEntry:
def __init__(self, data):
self.EntryID, self.UncompressedSize = struct.unpack("<II", data[:8])
"""
struct SDCGroup {
u32 GroupBulkDataSize;
u32 GroupEntryTotal;
SDCEntry Entry [GroupEntryTotal];
}
"""
class SDCGroup:
def __init__(self, data):
self.GroupBulkDataSize, self.GroupEntryTotal = struct.unpack("<II", data[:8])
self.Entries = []
entry_data = data[8:]
for i in range(self.GroupEntryTotal):
entry = SDCEntry(entry_data)
self.Entries.append(entry)
entry_data = entry_data[12:]
"""
struct SDC {
SDCHeader Header;
SDCGroup Group [Header.GroupTotal];
u8 BulkData [Header.BulkDataSize];
}
"""
class SDC:
def __init__(self, data):
self.Header = SDCHeader(data[:16])
self.Groups = []
offset = 16
for i in range(self.Header.GroupTotal):
group = SDCGroup(data[offset:])
self.Groups.append(group)
offset += 8 + group.GroupEntryTotal * 12
self.BulkData = data[offset:]
def extract(self, filename):
with open(filename, "wb") as f:
f.write(self.BulkData)
def extract_all(self):
offset = 0
for i, group in enumerate(self.Groups):
zlib_data = self.BulkData[offset:offset+group.GroupBulkDataSize]
offset += group.GroupBulkDataSize
data = zlib.decompress(zlib_data)
for j, entry in enumerate(group.Entries):
with open(f"{i}_{hex(entry.EntryID)}.bin", "wb") as f:
f.write(data[:entry.UncompressedSize])
data = data[entry.UncompressedSize:]
def main():
with open("./test.scd", "rb") as f:
data = f.read()
scd = SDC(data)
scd.extract_all()
if __name__ == "__main__":
main()