//-------------------------------------- //--- 010 Editor v6.0.1 Binary Template // // File: RegistryHive.bt // Author: Eric R. Zimmerman saericzimmerman@gmail.com // Revision: 1.2 // Purpose: Parses Registry structures including Header, nk, vk, sk, and list records. Data node records are skipped //-------------------------------------- LittleEndian(); // Defines a header record typedef struct { // Header for the file char HeaderSignature[4] ; int PrimarySequenceNumber; int SecondarySequenceNumber; FILETIME LastWriteTime ; int MajorVersion ; int MinorVersion ; int FileType; int Unknown; int RootKeyOffset ; int HbinTotalSize ; int Unknown2; wchar_t EmbeddedFilename[32] ; char Unknown3[396]; int Checksum; } REGISTRYHEADER ; typedef struct (int recordSize) { int Size; char Signature[2] ; short Flags ; FILETIME LastWriteTime ; int Spare; int ParentCellOffset; int SubkeyCountStable ; int SubkeyCountVolatile; int SubkeyListOffsetStable ; int SubkeyListOffsetVolatile; int ValueCount ; int ValuelistOffset ; int SecurityKeyOffset; int ClassOffset; short MaxNameLength; byte UserVirtFlags; byte Debug; int MaxClassLength; int MaxValueNameLength; int MaxValueDataLength; int WorkVar; short NameLength ; short ClassLength; char Name[NameLength] ; local int PaddingSize = recordSize - 0x50 - NameLength; if (PaddingSize > 0) { char Padding[recordSize - 0x50 - NameLength]; } } NKCELL ; string ReadNKCell( NKCELL &nk ) { return nk.Name; } typedef struct (int recordSize) { int Size; char Signature[2] ; short NameLength ; int DataLength; int DataOffset; int Type; short Flags ; short Spare; if (NameLength>0) { char Name[NameLength] ; } local int PaddingSize = recordSize - 0x18 - NameLength; if (PaddingSize > 0) { char Padding [recordSize - 0x18 - NameLength]; } } VKCELL ; string ReadVKCell( VKCELL &vk ) { if (vk.NameLength > 0) { return vk.Name; } else { return "(Default)"; } } typedef struct (int recordSize) { byte AceType; byte AceFlags; short AceSize; int Mask ; char SID[AceSize - 8]; //account for 2 bytes, short, and int } ACE ; typedef struct (int recordSize) { byte AclRevision; byte Sbz1; short AclSize; short AceCount; short Sbz2; if (AclSize > 0) { local int aceSize = 0; local int i; for (i = 0; i < AceCount; i++) { aceSize=ReadInt(FTell()+2); ACE Ace(aceSize); } } } ACL ; typedef struct (int recordSize) { byte Revision; byte Spare; short ControlFlag ; int OffsetToOwner; int OffsetToGroup; int OffsetToSACL; int OffsetToDACL; local int sizeSACL = OffsetToDACL - OffsetToSACL; local int sizeDACL = OffsetToOwner - OffsetToDACL; local int sizeOwnerSid = OffsetToGroup - OffsetToOwner; local int sizeGroupSid = recordSize - OffsetToGroup; if ((ControlFlag & 0x010) == 0x010) //0x010 == SeSaclPresent { ACL SACL(sizeSACL); } if ((ControlFlag & 0x004) == 0x004) //0x004 == SeDaclPresent { ACL DACL(sizeDACL); } char OwnerSID[sizeOwnerSid]; char GroupSID[sizeGroupSid]; } DESCRIPTOR ; typedef struct (int recordSize) { int Size; char Signature[2] ; short Reserved; int Flink; int Blink; int ReferenceCount; int DescriptorLength; if (DescriptorLength) { DESCRIPTOR Descriptor(DescriptorLength); } local int PaddingSize = recordSize - 0x18 - DescriptorLength; if (PaddingSize > 0) { char Padding[recordSize - 0x18 - DescriptorLength]; } } SKCELL ; typedef struct { int Offset; char Hash[4]; } LXOFFSET ; typedef struct (int recordSize) { int Size; char Signature[2] ; short NumberOfOffsets; if (NumberOfOffsets > 0) { LXOFFSET offsets[NumberOfOffsets]; } local int PaddingSize = recordSize-8-(8*NumberOfOffsets); if (PaddingSize > 0) { char Padding[recordSize-8-(8*NumberOfOffsets)]; } } LXLIST ; typedef struct (int recordSize) { int Size; char Signature[2] ; short NumberOfOffsets; LXOFFSET offsets[NumberOfOffsets]; } LILIST ; typedef struct { char HbinSignature[4] ; int RelativeOffset; int SizeOfHbin; int Unknown1; int Unknown2; FILETIME Timestamp ; int unknown3; local string sig; local int index = 0; local int cellSize = ReadInt(FTell()); while (index < SizeOfHbin) { sig = GetCellSignature(); cellSize = ReadInt(FTell()); if (cellSize == 0) { break; //safety net } switch( sig ) { case "nk" : NKCELL nk(Abs(cellSize)); break; case "sk" : SKCELL sk(Abs(cellSize)); break; case "vk" : VKCELL vk(Abs(cellSize)); break; case "li" : LILIST li(Abs(cellSize)); break; case "lf" : LXLIST lf(Abs(cellSize)); break; case "lh" : LXLIST lh(Abs(cellSize)); break; default : //Printf("Sig = %s \n",sig); //print out signatures of unknowns FSkip(Abs(cellSize)); //skip data cells } index+=Abs(cellSize); } } HBINRECORD ; int SizeHbinRecord( HBINRECORD &r) { return ReadInt(startof(r)+8); } char[] GetCellSignature() { //Read 4 bytes away from current to get the signature string return ReadString(FTell() + 4, 2); } REGISTRYHEADER Header ; local int indexPosition = FTell(); local int indexPosStart = indexPosition; local int absoluteEndPosition = Header.HbinTotalSize + 0x1000; while (indexPosition < absoluteEndPosition) { HBINRECORD Hbin ; indexPosition+= Hbin.SizeOfHbin; }