mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-05 09:49:14 +00:00
ZVISION: Add xor encryption handling to ZfsArchive class
This commit is contained in:
parent
179f5de498
commit
ef37f14d53
@ -55,16 +55,17 @@ ZfsArchive::~ZfsArchive() {
|
||||
}
|
||||
|
||||
void ZfsArchive::readHeaders(Common::SeekableReadStream *stream) {
|
||||
ZfsHeader header;
|
||||
|
||||
// Don't do a straight struct cast since we can't guarantee endianness
|
||||
header.magic = stream->readUint32LE();
|
||||
header.unknown1 = stream->readUint32LE();
|
||||
header.unknown2 = stream->readUint32LE();
|
||||
header.filesPerBlock = stream->readUint32LE();
|
||||
header.fileCount = stream->readUint32LE();
|
||||
header.xorKey = stream->readUint32LE();
|
||||
header.fileSectionOffset = stream->readUint32LE();
|
||||
_header.magic = stream->readUint32LE();
|
||||
_header.unknown1 = stream->readUint32LE();
|
||||
_header.maxNameLength = stream->readUint32LE();
|
||||
_header.filesPerBlock = stream->readUint32LE();
|
||||
_header.fileCount = stream->readUint32LE();
|
||||
_header.xorKey[0] = stream->readByte();
|
||||
_header.xorKey[1] = stream->readByte();
|
||||
_header.xorKey[2] = stream->readByte();
|
||||
_header.xorKey[3] = stream->readByte();
|
||||
_header.fileSectionOffset = stream->readUint32LE();
|
||||
|
||||
uint32 nextOffset;
|
||||
|
||||
@ -73,7 +74,7 @@ void ZfsArchive::readHeaders(Common::SeekableReadStream *stream) {
|
||||
nextOffset = stream->readUint32LE();
|
||||
|
||||
// Read in each entry header
|
||||
for (int i = 0; i < header.filesPerBlock; i++) {
|
||||
for (int i = 0; i < _header.filesPerBlock; i++) {
|
||||
ZfsEntryHeader entryHeader;
|
||||
|
||||
entryHeader.name = readEntryName(stream);
|
||||
@ -135,10 +136,18 @@ Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::
|
||||
|
||||
byte* buffer = new byte[entryHeader->size];
|
||||
zfsArchive.read(buffer, entryHeader->size);
|
||||
// Decrypt the data in place
|
||||
if (_header.xorKey != 0)
|
||||
unXor(buffer, entryHeader->size, _header.xorKey);
|
||||
|
||||
return new Common::MemoryReadStream(buffer, entryHeader->size, DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
void ZfsArchive::unXor(byte *buffer, int length, const byte *xorKey) const {
|
||||
for (uint32 i = 0; i < length; i++)
|
||||
buffer[i] ^= xorKey[i % 4];
|
||||
}
|
||||
|
||||
} // End namespace ZVision
|
||||
|
||||
|
||||
|
@ -32,10 +32,10 @@ namespace ZVision {
|
||||
struct ZfsHeader {
|
||||
uint32 magic;
|
||||
uint32 unknown1;
|
||||
uint32 unknown2;
|
||||
uint32 maxNameLength;
|
||||
uint32 filesPerBlock;
|
||||
uint32 fileCount;
|
||||
uint32 xorKey;
|
||||
byte xorKey[4];
|
||||
uint32 fileSectionOffset;
|
||||
};
|
||||
|
||||
@ -85,10 +85,34 @@ public:
|
||||
|
||||
private:
|
||||
const Common::String _fileName;
|
||||
ZfsHeader _header;
|
||||
ZfsEntryHeaderMap _entryHeaders;
|
||||
|
||||
/**
|
||||
* Parses the zfs file into file entry headers that can be used later
|
||||
* to get the entry data.
|
||||
*
|
||||
* @param stream The contents of the zfs file
|
||||
*/
|
||||
void readHeaders(Common::SeekableReadStream *stream);
|
||||
|
||||
/**
|
||||
* Entry names are contained within a 16 byte block. This reads the block
|
||||
* and converts it the name to a Common::String
|
||||
*
|
||||
* @param stream The zfs file stream
|
||||
* @return The entry file name
|
||||
*/
|
||||
Common::String readEntryName(Common::SeekableReadStream *stream) const;
|
||||
|
||||
/**
|
||||
* ZFS file entries can be encrypted using XOR encoding. This method
|
||||
* decodes the buffer in place using the supplied xorKey.
|
||||
*
|
||||
* @param buffer The data to decode
|
||||
* @param length Length of buffer
|
||||
*/
|
||||
void unXor(byte *buffer, int length, const byte *xorKey) const;
|
||||
};
|
||||
|
||||
} // End of namespace Common
|
||||
|
Loading…
x
Reference in New Issue
Block a user