mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
patterns/refs: Added Structure for MinStoreB+ node, missing GlobalRootNode Names & parses all Superblocks (#236)
[+] Added Structure for MinStoreB+ node, Missing GlobalRootNode Names
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#pragma author 5h4rrK
|
||||
#pragma description ReFS-File-System
|
||||
#pragma author 5h4rrK // https://www.github.com/5h4rrK
|
||||
#pragma organization temabi0s // (https://bi0s.in)
|
||||
#pragma description ReFS-File-System
|
||||
|
||||
#pragma array_limit 10000
|
||||
|
||||
import type.types.win32;
|
||||
import type.guid;
|
||||
@@ -25,19 +28,46 @@ enum BLOCK : u32 {
|
||||
MSBPlus = 0x2b42534d
|
||||
};
|
||||
|
||||
struct SELF_DESCRIPTOR{
|
||||
u32 start = $;
|
||||
u64 LCN1[[name("FirstLCN")]];
|
||||
u64 LCN2[[name("SecondLCN")]];
|
||||
u64 LCN3[[name("ThirdLCN")]];
|
||||
u64 LCN4[[name("FourthLCN")]];
|
||||
$ = $+2;
|
||||
u8 checksumtype[[name("ChecksumType")]];
|
||||
u8 checksumoffset[[name("ChecksumOffset")]];
|
||||
u16 checksumlen[[name("CheckSumLength")]];
|
||||
$ = $+2;
|
||||
if(checksumtype == 2){
|
||||
u64 chksum[[comment("Crc64"),name("CRC64-CheckSum") ]];}
|
||||
else if(checksumtype == 1){
|
||||
u32 chksum[[comment("Crc32"),name("CRC32-CheckSum") ]];
|
||||
}
|
||||
u32 rem = this.parent.lenselfdescriptor - ($ - start);
|
||||
BYTE buff[rem];
|
||||
};
|
||||
|
||||
struct META_HEADERS {
|
||||
BLOCK Signature[[comment("Block Signature"), name("BlockSignature")]];
|
||||
u32 unk[[comment("Fixed Value 0x02"), name("Unknown")]];
|
||||
$ = $ + (0x8 + 0x10);
|
||||
u32 zero[[name("AlwaysZero")]];
|
||||
u32 volsig[[name("VolumeSignature")]];
|
||||
u128 blockNo[[comment("Most Recent Block"), name("PageRecency")]];
|
||||
u64 LCN1[[comment("MetaPage 1st LogicalClusterNumber"), name("FirstLCN")]];
|
||||
u64 LCN2[[comment("MetaPage 2nd LogicalClusterNumber"), name("SecondLCN")]];
|
||||
u64 LCN3[[comment("MetaPage 3rd LogicalClusterNumber"), name("ThirdLCN")]];
|
||||
u64 LCN4[[comment("MetaPage 4th LogicalClusterNumber"), name("FourthLCN")]];
|
||||
u64 _Objid;
|
||||
u64 ObjId;
|
||||
u64 tableidlo[[name("TableIdentifierHigh")]];
|
||||
u64 tableidhi[[name("TableIdentifierLow")]];
|
||||
|
||||
};
|
||||
|
||||
struct OFFSET_ENTRIES{
|
||||
u16 offset[[name("Offset")]];
|
||||
u16 unk[[name("Ignore")]];
|
||||
};
|
||||
|
||||
struct ATTRIBUTE {
|
||||
u64 LCN1[[name("FirstLCN")]];
|
||||
u64 LCN2[[name("SecondLCN")]];
|
||||
@@ -49,52 +79,129 @@ struct ATTRIBUTE {
|
||||
BYTE ZeroPadding[56][[name("Padding")]];
|
||||
};
|
||||
|
||||
enum NodeType : BYTE {
|
||||
InnerNode = 0x01,
|
||||
RootNode = 0x02,
|
||||
StreamNode = 0x03,
|
||||
};
|
||||
|
||||
struct INDEX_HEADER {
|
||||
u32 size[[name("DataStartOffset")]];
|
||||
u32 dataendoff[[name("DataAreaEndOffset")]];
|
||||
u32 freebuff[[name("FreeBuff")]];
|
||||
BYTE height[[name("Height")]];
|
||||
NodeType ntype[[name("NodeType")]];
|
||||
u16 unused1[[name("UnUsed")]];
|
||||
u32 keyindxoff[[name("KeyIndexOffset")]];
|
||||
u32 keycount[[name("KeysCount")]];
|
||||
u64 unused2[[name("UnUsed")]];
|
||||
u32 end[[name("KeyIndexEnd")]];
|
||||
u32 align[[name("Alignment")]];
|
||||
$ = this.parent.start_pos + 0x50 + this.parent.rootsize + keyindxoff;
|
||||
OFFSET_ENTRIES entries[keycount][[name("KeyEntries")]];
|
||||
|
||||
};
|
||||
|
||||
enum Flags : u16 {
|
||||
RightMost = 0x02,
|
||||
DeletedEntry = 0x04,
|
||||
StreamIndexEntry = 0x40,
|
||||
};
|
||||
|
||||
struct INDEX_ENTRY_STRUCTURE {
|
||||
u32 start_pos = $;
|
||||
u32 indxentlen[[name("IndxEntryLen")]];
|
||||
u16 keyoff[[name("KeyOffset")]];
|
||||
u16 keylen[[name("KeyLen")]];
|
||||
Flags flag[[name("Flags")]];
|
||||
u16 valoff[[name("ValOffset")]];
|
||||
u16 vallen[[name("ValLen")]];
|
||||
$ = start_pos + keyoff;
|
||||
char key[keylen][[name("Key")]];
|
||||
$ = start_pos + valoff;
|
||||
char value[vallen][[name("Value")]];
|
||||
$ = start_pos + indxentlen;
|
||||
};
|
||||
|
||||
struct ROOT_NODE{
|
||||
u32 start_pos = $;
|
||||
META_HEADERS pagehdr[[name("PageHeader")]];
|
||||
u32 rootsize[[name("RootSize")]];
|
||||
u16 fixed[[name("Fixed(0x28)")]];
|
||||
u16 unk1[[name("Unknown")]];
|
||||
u16 unk2[[name("Unknown")]];
|
||||
u16 unk3[[name("Unknown")]];
|
||||
u16 schema[[name("TableSchema")]];
|
||||
u16 unk4[[name("Unknown")]];
|
||||
u16 schemadup[[name("TableSchema")]];
|
||||
u16 unk5[[name("Unknown")]];
|
||||
u16 unk6[[name("Unknown")]];
|
||||
u16 unk7[[name("Unknown")]];
|
||||
u64 noofextends[[name("ExtendCount")]];
|
||||
u64 noofrows[[name("RowsCount")]];
|
||||
char comps[rootsize - ($ - start_pos) + 0x50][[name("Components")]];
|
||||
$ = (start_pos + 0x50 + rootsize);
|
||||
INDEX_HEADER indxhdr[[name("IndexHeader")]];
|
||||
// $ = start_pos + 0x50 + rootsize + indxhdr.keyindxoff;
|
||||
$ = (start_pos + 0x50 + rootsize + indxhdr.size);
|
||||
INDEX_ENTRY_STRUCTURE indxentrystruct[indxhdr.keycount][[name("IndexEntry")]];
|
||||
};
|
||||
|
||||
u32 keeptrack = 0;
|
||||
|
||||
struct EntryArray {
|
||||
u32 AttrOffsetEntry;
|
||||
struct GLOBALROOTNODE {
|
||||
u32 GlobalElemEntryOff;
|
||||
u32 prev = $;
|
||||
$ = (0x1000 * ($ / 0x1000));
|
||||
$ = $ + AttrOffsetEntry;
|
||||
$ = $ + GlobalElemEntryOff;
|
||||
keeptrack += 1;
|
||||
if (keeptrack == 1) {
|
||||
ATTRIBUTE ObjectTable;
|
||||
ATTRIBUTE ObjectIDTable;
|
||||
}
|
||||
else if (keeptrack == 2) {
|
||||
ATTRIBUTE UNKNOWN1;
|
||||
ATTRIBUTE MediumAllocatorTable;
|
||||
}
|
||||
else if (keeptrack == 3) {
|
||||
ATTRIBUTE UNKNOWN2;
|
||||
ATTRIBUTE ContainerAllocatorTable;
|
||||
}
|
||||
else if (keeptrack == 4) {
|
||||
ATTRIBUTE AttributeList;
|
||||
ATTRIBUTE SchemaTable;
|
||||
}
|
||||
else if (keeptrack == 5) {
|
||||
ATTRIBUTE DirectoryTree;
|
||||
ATTRIBUTE ParentChildTable[[comment("Parent Child Table")]];
|
||||
}
|
||||
else if (keeptrack == 6) {
|
||||
ATTRIBUTE UNKNOWN3;
|
||||
ATTRIBUTE ObjectIDDup;
|
||||
}
|
||||
else if (keeptrack == 7) {
|
||||
ATTRIBUTE UNKNOWN4;
|
||||
ATTRIBUTE BlockCountTable;
|
||||
}
|
||||
else if (keeptrack == 8) {
|
||||
ATTRIBUTE ContainerTable;
|
||||
u32 prev_pos = $;
|
||||
ROOT_NODE node1 @ (ContainerTable.LCN1 * clustersz)[[name("ContainerNode")]];
|
||||
$ = prev_pos;
|
||||
}
|
||||
else if (keeptrack == 9) {
|
||||
ATTRIBUTE ContainerTableDup;
|
||||
u32 prev_pos = $;
|
||||
ROOT_NODE node1 @ (ContainerTableDup.LCN1 * clustersz)[[name("ContainerDupNode")]];
|
||||
$ = prev_pos;
|
||||
}
|
||||
else if (keeptrack == 10) {
|
||||
ATTRIBUTE UNKNOWN5;
|
||||
ATTRIBUTE SchemaTableDup;
|
||||
}
|
||||
else if (keeptrack == 11) {
|
||||
ATTRIBUTE AllocatorLarge;
|
||||
ATTRIBUTE ContainerIndexTable;
|
||||
}
|
||||
else if (keeptrack == 12) {
|
||||
ATTRIBUTE UNKNOWN6;
|
||||
ATTRIBUTE IntegrityStateTable;
|
||||
}
|
||||
else if (keeptrack == 13) {
|
||||
ATTRIBUTE UNKNOWN7;
|
||||
ATTRIBUTE SmallAllocatorTable;
|
||||
u32 prev_pos = $;
|
||||
ROOT_NODE node1 @ (SmallAllocatorTable.LCN1 * clustersz)[[name("SmallAllocatorNode")]];
|
||||
$ = prev_pos;
|
||||
}
|
||||
$ = prev;
|
||||
};
|
||||
@@ -103,29 +210,31 @@ struct CHECKPOINT {
|
||||
META_HEADERS CheckPointMetaHeader[[name("FSPageMetaHeader")]];
|
||||
$ += (0x04);
|
||||
CheckPoint_REFS_Version ReFSVersion;
|
||||
u32 EntryOffset;
|
||||
u32 EntrySz[[name("EntrySize")]];
|
||||
u64 blockno[[name("BlockNumber")]];
|
||||
u32 offsetselfdescriptor[[comment("Self Descriptor Offset")]];
|
||||
u32 lenselfdescriptor[[comment("Self Descriptor Size"),name("SelfDescriptorSz")]];
|
||||
u64 blockno[[comment("Most Recent CheckPoint") , name("BlockNumber")]];
|
||||
u32 prev_pos = $;
|
||||
$ = ($ / clustersz) *clustersz + offsetselfdescriptor;
|
||||
SELF_DESCRIPTOR selfdes[[name("SelfDescriptor")]];
|
||||
$ = prev_pos;
|
||||
$ += (0x28);
|
||||
u32 NumOfEntries;
|
||||
EntryArray AttributeEntries[NumOfEntries];
|
||||
GLOBALROOTNODE GlobalRootNodes[NumOfEntries];
|
||||
$ += (0x08);
|
||||
u64 LCN1dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupFirstLCN")]];
|
||||
u64 LCN2dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupSecondLCN")]];
|
||||
u64 LCN3dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupThirdLCN")]];
|
||||
u64 LCN4dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupFourthLCN")]];;
|
||||
};
|
||||
|
||||
struct SUPERBLOCK {
|
||||
META_HEADERS SuperBlockMetaHeader[[name("FSPageMetaHeader")]];
|
||||
type::GUID GUID;
|
||||
$ = $ + (0x10 * 0x06);
|
||||
$ = $ + (0x10 * 0x01);
|
||||
u32 checkpointOffset[[name("CheckPointOffset")]];
|
||||
u32 noofcheckpoint[[name("NoOfCheckPointEntry")]];
|
||||
u32 offsetselfdescriptor[[name("SelfDescriptorOffset")]];
|
||||
u32 lenselfdescriptor[[name("SelfDescriptorLength")]];
|
||||
$ = $ + (0x10 * 0x04);
|
||||
u64 primarychekpoint[[name("PrimaryCheckPoint")]];
|
||||
u64 secondaychekpoint[[name("SecondaryCheckPoint")]];
|
||||
u64 LCN1dup[[name("DupFirstLCN")]];
|
||||
u64 LCN2dup[[name("DupSecondtLCN")]];
|
||||
u64 LCN3dup[[name("DupThirdLCN")]];
|
||||
u64 LCN4dup[[name("DupFourthLCN")]];
|
||||
SELF_DESCRIPTOR selfdes[[name("SelfDescriptor")]];
|
||||
};
|
||||
|
||||
struct VOLUME_BOOT_RECORD {
|
||||
@@ -141,22 +250,37 @@ struct VOLUME_BOOT_RECORD {
|
||||
ReFS_Version ReFSVersion;
|
||||
BYTE UnknownBuff[0x0e][[name("Unknown")]];
|
||||
u64 SerialNo[[name("SerialNumber")]];
|
||||
u64 BytesPerContainer[[name("BytesPerContainer")]];
|
||||
|
||||
};
|
||||
|
||||
struct REFS_FILE_SYSTEM {
|
||||
u64 checkVal = std::mem::read_unsigned($+3, 8);
|
||||
$ = 0;
|
||||
if(checkVal == FILESYSTEM::ReFS){
|
||||
VOLUME_BOOT_RECORD vbr @ 0x00[[name("VolumeBootRecord")]];
|
||||
SUPERBLOCK SuperBlock @ (0x1e * 0x1000);
|
||||
SUPERBLOCK SuperBlock1 @ (0x1e * 0x1000)[[name("SuperBlock1")]];
|
||||
u32 cluster_size = vbr.BytesPerSec * vbr.SectorPerCluster;
|
||||
|
||||
CHECKPOINT PrimaryCheckPoint @(SuperBlock.primarychekpoint * 0x1000);
|
||||
CHECKPOINT PrimaryCheckPoint @(SuperBlock1.primarychekpoint * cluster_size)[[name("PrimaryCheckPoint1")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT SecondaryCheckPoint @(SuperBlock.secondaychekpoint * 0x1000);
|
||||
CHECKPOINT SecondaryCheckPoint @(SuperBlock1.secondaychekpoint * cluster_size)[[name("SecondaryCheckPoint1")]];
|
||||
|
||||
SUPERBLOCK SuperBlock2 @(((vbr.TotalNoOfSectors / vbr.SectorPerCluster) - 3) * cluster_size)[[name("SuperBlock2")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT PrimaryCheckPoint2 @(SuperBlock2.primarychekpoint * cluster_size)[[name("PrimaryCheckPoint2")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT SecondaryCheckPoint2 @(SuperBlock2.secondaychekpoint * cluster_size)[[name("SecondaryCheckPoint2")]];
|
||||
|
||||
SUPERBLOCK SuperBlock3 @(((vbr.TotalNoOfSectors / vbr.SectorPerCluster) - 2) * cluster_size)[[name("SuperBlock3")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT PrimaryCheckPoint3 @(SuperBlock3.primarychekpoint * cluster_size)[[name("PrimaryCheckPoint3")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT SecondaryCheckPoint3 @(SuperBlock3.secondaychekpoint * cluster_size)[[name("SecondaryCheckPoint3")]];
|
||||
}
|
||||
else{
|
||||
break;
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
u32 clustersz = std::mem::read_unsigned($ + 0x20, $+4) * std::mem::read_unsigned($ + 0x24, $+4);
|
||||
REFS_FILE_SYSTEM ReFSFileSystem @0x00;
|
||||
|
||||
Reference in New Issue
Block a user