ZVISION: Add xor encryption handling to ZfsArchive class

This commit is contained in:
richiesams 2013-06-12 22:06:05 -05:00
parent 179f5de498
commit ef37f14d53
2 changed files with 45 additions and 12 deletions

View File

@ -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

View File

@ -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