Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Agreement:
- ==========
- The author of this document will not be responsible for any damage and/or
- license violation that may occur. The information within this document is
- provided "as is" without warranty of any kind...
- This information was "collected" during sleepless nights, and is NOT
- officially released by Microsoft! It shall give you a peek at the Windows(tm)
- internals to give you a chance to recover from corrupted data.
- The author has nothing to do with Microsoft, except that he uses their
- products...
- If you don't agree with this, stop reading this document, and delete it at
- once!
- History:
- ========
- What is the registry? Where did it came from? Two questions, which I will try to
- answer here. The registry is a database (at least microsoft thinks so:)
- which contains configuration information about the system.
- It mainly is a memory dump which is saved to one or more files on the windows
- host drive. It is loaded every system-boot and remains resident until
- shutdown. Since parts of it are not used during normal operation it will be
- swapped out very soon. The registry appeared with windows 3.?? (sorry, I can't
- remember any earlier version :-), where it was used for file associations and
- the "OLE" functions (the conection between ole-id's and the applications).
- This is a critical information and since the registry has (almost) NO
- CHECKSUM information (!), it sometimes gets corrupted. This is the main
- reason for this doc.
- Using windows 3.x, almost every configuration was done using good old ".INI"-
- files, which were readable but slow and limited in size (64k). In windows 95
- (and NT), the registry was used instead of these files. So, to edit a
- particular setting, you would have to run the application which manages these
- settings. :( but what if this app won't start? MS included a tool named
- REGEDIT in windows 3.?? and 95, and a REGEDT32 in windows NT. You can use
- these apps to edit ALL contents of the registry (in windows NT the registry
- supports security, as well as it provides the security for the whole system!)
- An application can open a "key", write values (variables) to it and fill them
- with data. Each key represents also a value called "default" and can contain
- any number of sub-keys. This will form a tree-structure as you can see at
- the left half of REGEDIT. (note: REGEDIT from windows 3.?? has to be started
- with /V or /Y, I can't remember now)
- Where can I find the registry???
- ================================
- That differs for each windows-version:
- Version File(s) Contents
- 3.1x REG.DAT Complete windows 3.?? Registry
- 95 SYSTEM.DAT System-values (HKEY_LOCAL_MACHINE)
- USER.DAT User-values (HKEY_USERS)
- NT SYSTEM32\CONFIG\SAM SAM-part of the registry (=NT Security)
- SYSTEM32\CONFIG\SOFTWARE Software-Specific part
- (HKEY_LOCAL_MACHINE\SOFTWARE)
- SYSTEM32\CONFIG\SYSTEM System-specific part
- (HKEY_LOCAL_MACHINE\System)
- PROFILES\%USERNAME%\NTUSER.DAT User-Specific part
- (HKEY_CURRENT_USER\{S-1-xxx...})
- PROFILES\%USERNAME%\NTUSER.MAN like NTUSER.DAT but a
- MANDATORY-profile
- If you are using a ROAMING-profile with windows NT, NTUSER.xxx can be on
- a network-share as well...
- Terms
- =====
- The registry consists of the following elements:
- Hive: strating point of the structure. The name of an hive starts
- with the "HKEY_"-prefix. Can be seen as a "drive" in a file
- system.
- Hive name Beschreibung 3.1 95 NT4
- HKEY_CLASSES_ROOT Points to the "class" key in
- the "HKEY_LOCAL_MACHINE" hive,
- the only hive in windows 3.?? X X X
- HKEY_CURRENT_USER Information and settings valid
- for the currently logged in
- user. (Points to the correct X X
- key under "HKEY_USERS")
- HKEY_CURRENT_CONFIG Settings for the currently
- active hardware profile.
- Points to "HKEY_LOCAL_MACHINE\ X X
- CONTROL\CONTROLSETxxx
- HKEY_USERS Contains all currently active
- user settings. Since NT is a
- single user system, there
- will be only one key (the S-ID X X
- of the active user), and a
- ".DEFUALT" key (The settings
- for the CTRL-ALT-DEL environment)
- HKEY_LOCALMACHINE All local settings X X
- HKEY_DYN_DATA As the name says, here you'll find X
- dynamic data (CPU-usage,...)
- Key: A key to the registry can be seen as a directory in a file
- system.
- Value: can be seen as the registrys "file"
- Data: is the actual setting, can be seen as the contents of a
- file
- Windows 3.x
- ===========
- This registry is the easiest one. It consists of 3 blocks, which are not
- "signed" at all:
- Block Position Size
- Header 0 32 Bytes
- Navigation-Info 0x00000020 ???
- Data-Block ??? ???
- The "???" marked values can be read from the header.
- Header
- ======
- Offset Size Description
- 0x0000 8 Byte ASCII-Text: "SHCC3.10"
- 0x0008 D-Word ?
- 0x000C D-Word ? (always equal the D-Word at 0x0008)
- 0x0010 D-Word Number of entrys in the navigation-block
- 0x0014 D-Word Offset of the data-block
- 0x0018 D-Word Size of the data-block
- 0x001C Word ?
- 0x001E Word ?
- Values marked "?" are not important for a read-access, and therefore unknown
- to me...
- Navigation-Block
- ================
- This is where chaos rules! It consists of two different, 8 byte long blocks:
- * Navigation-Info-Record,
- * Text-Info-Record
- The first record in the navigation block is a navigation info record.
- Navigation-Info-Record
- Offset Size Contents
- 0x00 Word Next Key (same level)
- 0x02 Word First Sub-Key (one level deeper)
- 0x04 Word Text-Info-Record Key-Namens
- 0x06 Word Text-Info-Record Key-Value (default)
- The values are the locical number of the block inside the file:
- offset=blocksize*blocknumber+headersize
- since 2 of this values are constant:
- offset=8*blocknumber+0x20
- Text-Info-Record
- ================
- Offset Size Contents
- 0x00 Word ?
- 0x02 Word number of references to this text
- 0x04 Word Text-length
- 0x06 Word Offset of the text-string inside the data-block
- To get the text-offset inside the file you have to add this offset to the
- data-offset inside the header.
- Data-Block
- ==========
- The data-block only consists of a collection of text-strings. Right in front
- of every text is a word which may or may not have a meaning. The offset in
- the text-info record points directly to the text, the text-size has to be
- defined in the text-info record too.
- Windows 95
- ==========
- the Windows95-Registry Files:
- inside the windows-directory (default: C:\WINDOWS) are 2 files which are
- loaded to form the registry:
- SYSTEM.DAT
- and
- USER.DAT
- This files are mapped to the following hives:
- HKEY_LOCAL_MACHINE in SYSTEM.DAT
- and
- HKEY_USERS in USER.DAT
- The file structure:
- ===================
- Both files have the same structure. Each of them consists of 3 blocks where
- 1 of these blocks can be repeated.
- Every block has a 4 byte long signature to help identify its contents.
- ID Block-contents Max. size
- CREG Header 32 Bytes @ Offset 0
- RGKN Directory information
- (Tree-structure) ??? @ Offset 32
- RGDB The real data
- (Values and data) max. 65535 Bytes an Offset ??
- these blocks are "sticked together" with no space between them, but always
- a multiple of 16 in size.
- the CREG-Block
- ==============
- Offset Size Inhalt
- 0x00000000 D-Word ASCII-"CREG" = 0x47455243
- 0x00000008 D-Word Offset of 1st RGDB-block
- 0x00000010 D-Word # of RGDB-blocks
- all other values are not needed to read the registry...
- the RGKN-Block
- ==============
- I assume that RGKN stands for ReGistry-Key-Navigation. This block contains
- the information needed to built the tree-structure of the registry. This
- block will be larger then 65536 bytes (0xFFFF)!
- All offset-values are RELATIVE to the RGKN-block!
- Offset Size Contents
- 0x00000000 D-Word ASCII-"RGKN" = 0x4E4B4752
- 0x00000004 D-Word Size of the RGKN-block in bytes
- 0x00000008 D-Word Rel. Offset of the root-record
- 0x00000020 ???? Tree-Records (often the 1st Record)
- the Tree-Record
- ===============
- The tree-record is a "complete" registry-key. It contains the "hash"-info
- for the real data stored in this key.
- Offset Size Contents
- 0x0000 D-Word Always 0
- 0x0004 D-Word Hash of the key-name
- 0x0008 D-Word Always -1 (0xFFFFFFFF)
- 0x000C D-Word Offset of the owner (parent)-records
- 0x0010 D-Word Offset of the 1st sub-sey record
- 0x0014 D-Word Offset of the next record in this level
- 0x0018 D-Word ID-number of the real key
- the 1st entry in a "usual" registry file is a nul-entry with subkeys: the
- hive itself. It looks the same like other keys. Even the ID-number can
- be any value.
- The "hash"-value is a value representing the key's name. Windows will not
- search for the name, but for a matching hash-value. if it finds one, it
- will compare the actual string info, otherwise continue with the next key.
- End of list-pointers are filled with -1 (0xFFFFFFFF)
- The ID-field has the following format:
- Bits 31..16: Number of the corresponding RGDB-blocks
- Bits 15..0: continuous number inside this RGDB-block.
- The hash-method:
- ================
- you are looking for the key: Software\Microsoft
- first you take the first part of the string and convert it to upper case
- SOFTWARE
- The "\" is used as a seperator only and has no meaning here.
- Next you initialize a D-Word with 0 and add all ASCII-values of the string
- which are smaller than 0x80 (128) to this D-Word.
- SOFTWARE = 0x0000026B
- Now you can start looking for this hash-value in the tree-record.
- If you want to modify key names, also modify the hash-values, since they
- cannot be found again (although they would be displayed in REGEDIT)
- the RGDB-Block
- ==============
- Header:
- Offset Size Contents
- 0x0000 D-Word ASCII-"RGDB" = 0x42444752
- 0x0004 D-Word Size of this RGDB-block
- 0x0020 ???? RGDB Records
- RGDB-Record (Key-Information)
- =============================
- Offset Size Contents
- 0x0000 D-Word record length in bytes
- 0x0004 D-Word ID-number
- 0x0008 D-Word ??? Size ???
- 0x000C Word text length of key name
- 0x000E Word Number of values inside this key
- 0x0010 D-Word always 0
- 0x0014 ???? Key-name
- 0x???? ???? Values
- The first size (record length) can be used to find the next record.
- The second size value is only correct if the key has at least one value,
- otherwise it is a little lower.
- The key-name is not 0-terminated, its length is defined by the key-
- text length field. The values are stored as records.
- Value-Record
- ============
- Offset Size Contents
- 0x0000 D-Word Type of data
- 0x0004 D-Word always 0
- 0x0008 Word length of value-name
- 0x000A Word length of value-data
- 0x000C ???? value-name
- 0x???? ???? data
- Data-Types
- ==========
- value Contents
- 0x00000001 RegSZ - 0-terminated string (sometimes without the 0!)
- 0x00000003 RegBin - binary value (a simple data-block)
- 0x00000004 RegDWord - D-Word (always 4 bytes in size)
- Windows NT (Version 4.0)
- ========================
- Whoever thought that the registry of windows 95 and windows nt are similar
- will be surprised! They only look much the same, but have completely other
- structures!
- Since the RGDB-blocks in the windows 95 registry are not larger than
- 0xFFFF, we can see that it is optimized for a 16-bit OS...
- Windows NT stores its registry in a page-oriented format with blocks
- of 4kb (4096 = 0x1000 bytes)
- The windows NT registry has 2 different blocks, where one can occure many
- times...
- the "regf"-Block
- ================
- "regf" is obviosly the abbreviation for "Registry file". "regf" is the
- signature of the header-block which is always 4kb in size, although only
- the first 64 bytes seem to be used and a checksum is calculated over
- the first 0x200 bytes only!
- Offset Size Contents
- 0x00000000 D-Word ID: ASCII-"regf" = 0x66676572
- 0x00000004 D-Word ????
- 0x00000008 D-Word ???? Always the same value as at 0x00000004
- 0x0000000C Q-Word last modify date in WinNT date-format
- 0x00000014 D-Word 1
- 0x00000018 D-Word 3
- 0x0000001C D-Word 0
- 0x00000020 D-Word 1
- 0x00000024 D-Word Offset of 1st key record
- 0x00000028 D-Word Size of the data-blocks (Filesize-4kb)
- 0x0000002C D-Word 1
- 0x000001FC D-Word Sum of all D-Words from 0x00000000 to 0x000001FB
- I have analyzed more registry files (from multiple machines running
- NT 4.0 german version) and could not find an explanation for the values
- marked with ???? the rest of the first 4kb page is not important...
- the "hbin"-Block
- ================
- I don't know what "hbin" stands for, but this block is always a multiple
- of 4kb in size.
- Inside these hbin-blocks the different records are placed. The memory-
- management looks like a C-compiler heap management to me...
- hbin-Header
- ===========
- Offset Size Contents
- 0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268
- 0x0004 D-Word Offset from the 1st hbin-Block
- 0x0008 D-Word Offset to the next hbin-Block
- 0x001C D-Word Block-size
- The values in 0x0008 and 0x001C should be the same, so I don't know
- if they are correct or swapped...
- From offset 0x0020 inside a hbin-block data is stored with the following
- format:
- Offset Size Contents
- 0x0000 D-Word Data-block size
- 0x0004 ???? Data
- If the size field is negative (bit 31 set), the corresponding block
- is free and has a size of -blocksize!
- The data is stored as one record per block. Block size is a multiple
- of 4 and the last block reaches the next hbin-block, leaving no room.
- Records in the hbin-blocks
- ==========================
- nk-Record
- The nk-record can be treated as a kombination of tree-record and
- key-record of the win 95 registry.
- lf-Record
- The lf-record is the counterpart to the RGKN-record (the hash-function)
- vk-Record
- The vk-record consists information to a single value.
- sk-Record
- sk (? Security Key ?) is the ACL of the registry.
- Value-Lists
- The value-lists contain information about which values are inside a
- sub-key and don't have a header.
- Datas
- The datas of the registry are (like the value-list) stored without a
- header.
- All offset-values are relative to the first hbin-block and point to the block-
- size field of the record-entry. to get the file offset, you have to add
- the header size (4kb) and the size field (4 bytes)...
- the nk-Record
- =============
- Offset Size Contents
- 0x0000 Word ID: ASCII-"nk" = 0x6B6E
- 0x0002 Word for the root-key: 0x2C, otherwise 0x20
- 0x0004 Q-Word write-date/time in windows nt notation
- 0x0010 D-Word Offset of Owner/Parent key
- 0x0014 D-Word number of sub-Keys
- 0x001C D-Word Offset of the sub-key lf-Records
- 0x0024 D-Word number of values
- 0x0028 D-Word Offset of the Value-List
- 0x002C D-Word Offset of the sk-Record
- 0x0030 D-Word Offset of the Class-Name
- 0x0044 D-Word Unused (data-trash)
- 0x0048 Word name-length
- 0x004A Word class-name length
- 0x004C ???? key-name
- the Value-List
- ==============
- Offset Size Contents
- 0x0000 D-Word Offset 1st Value
- 0x0004 D-Word Offset 2nd Value
- 0x???? D-Word Offset nth Value
- To determine the number of values, you have to look at the
- owner-nk-record!
- Der vk-Record
- =============
- Offset Size Contents
- 0x0000 Word ID: ASCII-"vk" = 0x6B76
- 0x0002 Word name length
- 0x0004 D-Word length of the data
- 0x0008 D-Word Offset of Data
- 0x000C D-Word Type of value
- 0x0010 Word Flag
- 0x0012 Word Unused (data-trash)
- 0x0014 ???? Name
- If bit 0 of the flag-word is set, a name is present, otherwise the
- value has no name (=default)
- If the data-size is lower 5, the data-offset value is used to store
- the data itself!
- The data-types
- ==============
- Wert Beteutung
- 0x0001 RegSZ: character string (in UNICODE!)
- 0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!)
- 0x0003 RegBin: raw-binary value
- 0x0004 RegDWord: Dword
- 0x0007 RegMultiSZ: multiple strings, seperated with 0
- (UNICODE!)
- The "lf"-record
- ===============
- Offset Size Contents
- 0x0000 Word ID: ASCII-"lf" = 0x666C
- 0x0002 Word number of keys
- 0x0004 ???? Hash-Records
- Hash-Record
- ===========
- Offset Size Contents
- 0x0000 D-Word Offset of corresponding "nk"-Record
- 0x0004 D-Word ASCII: the first 4 characters of the key-name,
- padded with 0's. Case sensitiv!
- Keep in mind, that the value at 0x0004 is used for checking the
- data-consistency! If you change the key-name you have to change the
- hash-value too!
- The "sk"-block
- ==============
- (due to the complexity of the SAM-info, not clear jet)
- Offset Size Contents
- 0x0000 Word ID: ASCII-"sk" = 0x6B73
- 0x0002 Word Unused
- 0x0004 D-Word Offset of previous "sk"-Record
- 0x0008 D-Word Offset of next "sk"-Record
- 0x000C D-Word usage-counter
- 0x0010 D-Word Size of "sk"-record in bytes
- ????
- ???? ???? Security and auditing settings...
- ????
- The usage counter counts the number of references to this
- "sk"-record. You can use one "sk"-record for the entire registry!
- Windows nt date/time format
- ===========================
- The time-format is a 64-bit integer which is incremented every
- 0,0000001 seconds by 1 (I don't know how accurate it realy is!)
- It starts with 0 at the 1st of january 1601 0:00! All values are
- stored in GMT time! The time-zone is important to get the real
- time!
- Common values for win95 and win-nt
- ==================================
- Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF).
- If a value has no name (length=0, flag(bit 0)=0), it is treated as the
- "Default" entry...
- If a value has no data (length=0), it is displayed as empty.
- simplyfied win-3.?? registry:
- =============================
- +-----------+
- | next rec. |---+ +-----> +------------+
- | first sub | | | | Usage cnt. |
- | name | | +--> +------------+ | | length |
- | value | | | | next rec. | | | text |-------> +-------+
- +-----------+ | | | name rec. |--+ +------------+ | xxxxx |
- +------------+ | | value rec. |--------> +------------+ +-------+
- v | +------------+ | Usage cnt. |
- +-----------+ | | length |
- | next rec. | | | text |-------> +-------+
- | first sub |------+ +------------+ | xxxxx |
- | name | +-------+
- | value |
- +-----------+
- Greatly simplyfied structure of the nt-registry:
- ================================================
- +-------------------------------------------------------------------------+
- v |
- +---------------+ +-------------> +-----------+ +------> +---------+ |
- | "nk" | | | lf-rec. | | | nk-rec. | |
- | ID | | | # of keys | | | parent |---+
- | Date | | | 1st key |--+ | .... |
- | parent | | +-----------+ +---------+
- | suk-keys |-------+
- | values |---------------------> +----------+
- | SK-rec. |---------------+ | 1. value |--> +----------+
- | class |--+ | +----------+ | vk-rec. |
- +---------------+ | | | .... |
- v | | data |--> +-------+
- +------------+ | +----------+ | xxxxx |
- | Class name | | +-------+
- +------------+ |
- v
- +---------+ +---------+
- +-----> | next sk |---> | Next sk |--+
- | +---| prev sk | <---| prev sk | |
- | | | .... | | ... | |
- | | +---------+ +---------+ |
- | | ^ |
- | +--------------------+ |
- +------------------------------------+
- --------------------------------------------------------------------------------
- Hope this helps.... (Although it was "fun" for me to uncover this things,
- it took me several sleepless nights ;)
- B.D.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement