Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/010 Templates/crc32.1sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//------------------------------------------------
//--- 010 Editor v15.0.1 Script File
//
// File: crc32.1sc
// Authors: Petar
// Version: 1.0
// Purpose: Compute CRC32 and CRC16 checksum for NeFS blocks.
// Category: Checksum
// History:
//------------------------------------------------
local uint32 crcTable[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};

// 0xaf6d87d2
local uint32 crc = ~0;

while (!FEof()) {
crc = (crc >> 8) ^ crcTable[(ubyte)crc ^ ReadUByte()];

FSkip(1);
}

crc = ~crc;
Printf("Crc32: %x\n", crc);
Printf("Crc16: %x\n", (uint16)crc + (uint16)(crc >> 16));
166 changes: 90 additions & 76 deletions src/010 Templates/nefs1.6.bt
Original file line number Diff line number Diff line change
Expand Up @@ -12,100 +12,114 @@
//------------------------------------------------
LittleEndian();

struct {
char magic[4];
byte hash[32];
char aesKey[64];
uint version;
uint headerSize;
uint numItems;
uint unknown1;
uint unknown2;
uint unknown3;
uint unknown4;
} header;

struct
{
uint16 numVolumes;
uint16 hashBlockSizeHi;
uint16 blockSizeHi;
uint16 splitSizeHi;
local uint blockSize = (uint)blockSizeHi << 15;
local uint hashBlockSize = (uint32)hashBlockSize << 15;
if (hashBlockSize == 0)
struct TocHeader {
uint32 fourCC;
if ((fourCC & 0xFF) == 83)
{
hashBlockSize = 0x800000;
BigEndian();
}

uint part1;
uint part6;
uint part2;
uint part7;
uint part3;
uint part4;
uint part5;
uint part8;
ubyte hash[32];
char aesKey[64];
uint32 tocSize;
uint32 version;
uint32 numEntries;
uint32 userValue;
ubyte randomPadding1[10];
ubyte unused[2];

byte unknown1[0x58];
} toc;
uint16 numVolumes;
uint16 hashBlockSize;
uint16 blockSize;
uint16 splitSize;
uint32 entryTableStart;
uint32 writableEntryTableStart;
uint32 sharedEntryInfoTableStart;
uint32 writableSharedEntryInfoTableStart;
uint32 nameTableStart;
uint32 blockTableStart;
uint32 volumeInfoTableStart;
uint32 hashDigestTableStart;
ubyte randomPadding2[88];

local uint32 actualHashBlockSize = (uint32)hashBlockSize << 15;
local uint32 actualBlockSize = (uint32)blockSize << 15;
} header;

FSeek(toc.part1);
struct
FSeek(header.entryTableStart);
struct TocEntry
{
uint64 dataOffset;
uint32 indexP2;
uint32 indexP4;
uint32 id;
} hp1[header.numItems];
uint64 start;
//uint32 startA;
//uint32 startB;
uint32 sharedInfo;
uint32 firstBlock;
uint32 nextDuplicate;
} entryTable[header.numEntries] <read=Str("S: %lu | SI: %d | FB: %d | ND: %d", start, sharedInfo, firstBlock, nextDuplicate)>;

FSeek(toc.part2);
struct
FSeek(header.sharedEntryInfoTableStart);
struct TocSharedEntryInfo
{
uint32 parent;
uint32 firstChild;
uint32 nameOffset;
uint32 size;
uint32 firstDuplicate;
} sharedEntryInfoTable[(header.nameTableStart - header.sharedEntryInfoTableStart) / sizeof(TocSharedEntryInfo)] <read=readTocSharedEntryInfo>;
string readTocSharedEntryInfo(TocSharedEntryInfo &info)
{
uint32 parentId;
uint32 childId;
uint32 stringOffset;
uint32 extractedFileSize;
uint32 id;
} hp2[header.numItems];
string name = ReadString(header.nameTableStart + info.nameOffset, 100);
string ret;
SPrintf(ret, "FD: %d | PC: %d %d | %s", info.firstDuplicate, info.parent, info.firstChild, name);
return ret;
}

FSeek(toc.part3);
char hp3[toc.part4 - toc.part3];
FSeek(header.nameTableStart);
char nameTable[header.blockTableStart - header.nameTableStart];

FSeek(toc.part4);
struct
FSeek(header.blockTableStart);
struct TocBlock
{
uint32 totalBlockSize;
uint16 transformationType;
uint16 unknown;
} hp4[(toc.part5 - toc.part4) / 8];
uint32 end;
// transformation types
// 1 - lzss, 2 - huffman, 3 - rle, 4 - aes, 5 - custom, 6 - lzma, 7 - zlib
uint16 transformation;
uint16 checksum;
} blockTable[(header.volumeInfoTableStart - header.blockTableStart) / 8] <read=Str("%d %d", this.end, this.transformation)>;

FSeek(toc.part5);
struct
FSeek(header.volumeInfoTableStart);
struct TocVolumeInfo
{
uint64 dataSize;
uint32 nefsStringOffset;
uint64 size;
uint32 nameOffset;
uint32 dataOffset;
} hp5;
} volumeInfoTable[header.numVolumes];

FSeek(toc.part6);
struct
FSeek(header.writableEntryTableStart);
struct TocEntryWriteable
{
uint16 volume;
byte flags;
byte unknown;
} hp6[header.numItems];
// 1 - transformed, 2 - directory, 4 - duplicated, 8 - cacheable,
// 16 - lastSibling, 32 - patched
uint16 flags;
} writableEntryTable[header.numEntries];

FSeek(header.writableSharedEntryInfoTableStart);
struct TocSharedEntryInfoWritable
{
uint32 nextSibling;
uint32 patchedEntry;
} writableSharedEntryInfoTable[header.numEntries];

FSeek(toc.part7);
struct
local uint64 numHashDigests <hidden=true> = 0;
local uint32 iv <hidden=true>;
for (iv = 0; iv < header.numVolumes && header.hashBlockSize != 0; ++iv)
{
uint32 nextId;
uint32 id;
} hp7[header.numItems];
numHashDigests += (volumeInfoTable[iv].size - volumeInfoTable[iv].dataOffset + header.actualHashBlockSize - 1) / header.actualHashBlockSize;
}

//FSeek(toc.part8);
local uint64 dd = hp5.dataSize / toc.hashBlockSize;
struct
FSeek(header.hashDigestTableStart);
struct TocHashDigest
{
byte blockHash[32];
} hp8[(hp5.dataSize - hp5.dataOffset) / toc.hashBlockSize];
ubyte data[32];
} hashDigestTable[numHashDigests];
15 changes: 11 additions & 4 deletions src/010 Templates/nefs2.0.bt
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,24 @@ struct
} hp1[header.numItems];

FSeek(toc.part2);
struct
struct HP2
{
uint32 parentId;
uint32 childId;
uint32 stringOffset;
uint32 extractedFileSize;
uint32 id;
} hp2[header.numItems];
} hp2[header.numItems] <read=readTocSharedEntryInfo>;
string readTocSharedEntryInfo(HP2 &info)
{
string name = ReadString(toc.part3 + info.stringOffset, 100);
string ret;
SPrintf(ret, "FD: %d | PC: %d %d | %s", info.id, info.parentId, info.childId, name);
return ret;
}

FSeek(toc.part4);
uint cumulativeCompressedChunkSize[(toc.part5 - toc.part4) / 8];
uint cumulativeCompressedChunkSize[(toc.part5 - toc.part4) / 4];

FSeek(toc.part5);
struct
Expand All @@ -95,7 +102,7 @@ struct
uint32 id;
} hp7[header.numItems];

//FSeek(toc.part8);
FSeek(toc.part8);
local uint64 dd = hp5.dataSize / toc.hashBlockSize;
struct
{
Expand Down
Loading