Click here to Skip to main content
11,926,429 members (54,266 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


60 bookmarked

How to read/dump/compare registry hives

, 11 Nov 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Malware can hide from win32 api but not from this tool since we are dumping reg hives directly


Well recently I had nasty worm/rootkit problem and naturally I wanted to know what he changed in my system. So i started seeking for some tool to detect registry changes. some simple tool to dump complete registry content to text file before infection and after and by simple text diff i would be able to see the changes fast. I was not very lucky thou. Since all reg tools i found were using win32 api to get data which that clever rootkit redirected to himself and thus stayed hidden. Also as i later found out malware don't even need to be that clever to hide things in registry from standard api.

So now I had physical clean registry files from system restore point and dirty ones from my infected system. And I didn't stop poking in the hives until I did come up with simple tool to dump and compare their real contents in simple text format. I also needed full reg path at each entry so in case I use text diff on those dumps I see where the change happened.


Hive format

NT/XP registry files (binary hives not textual reg files) are actually very simple. tey are just bunch of 4k blocks where each block contain variable sized blocks . Each of those starts with

usual 4b size and 2b type.


And thats about it . thats ms registry hive format. Oh and I nearly forgot. First 1k of first block is hive header with no usefull info as far as i know

Now whats inside of those variable sized blocks

The simplest way to describe registry is to think of it as a file system where keys are directories and values are files. And as we allready know both directories and files have names except that each file can also contain data.

So there are 2 basic blocks one for keys and one for values. what's nice is that MS decided to use human readable 2 char strings in the block type field i mentioned earlier. so if you open hive in hex viewer jou can clearly see "nk" for key block and "vk" for value block.

Using the code

And here is actual code to dump registry hives. I used portable c code so it should be compilable on unix too without much change.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

struct offsets { 
    long  block_size;
    char  block_type[2]; // "lf" "il" "ri"
    short count;   
    long  first; 
    long  hash; 

struct key_block  { 
    long  block_size;
    char  block_type[2]; // "nk"
    char  dummya[18];
    int   subkey_count;
    char  dummyb[4];
    int   subkeys;
    char  dummyc[4];
    int   value_count;
    int   offsets;
    char  dummyd[28];
    short len;
    short du;
    char  name; 

struct value_block {
    long  block_size;
    char  block_type[2]; // "vk"
    short name_len;
    long  size;
    long  offset;
    long  value_type;
    short flags;
    short dummy;
    char  name; 

void walk ( char* path,   key_block* key ) {
    static  char* root=(char*)key-0x20, *full=path;
    // add current key name to printed path
    memcpy(path++,"/",2); memcpy(path,&key->name,key->len); path+=key->len;

    // print all contained values
    for(int o=0;o<key->value_count;o++){
        value_block* val = (value_block*)(((int*)(key->offsets+root+4))[o]+root); 
        // we skip nodes without values
        if(!val->offset)  continue;
        // data are usually in separate blocks without types
        char* data = root+val->offset+4;
        // but for small values MS added optimization where 
        // if bit 31 is set data are contained wihin the key itself to save space
        if(val->size&1<<31) {
              data = (char*)&val->offset;
        // notice that we use memcopy for key/value names everywhere instead of strcat
        // reason is that malware/wiruses often write non nulterminated strings to
        // hide from win32 api
        *path='/'; if(!val->name_len) *path=' '; 
        memcpy(path+1,&val->name,val->name_len); path[val->name_len+1]=0;

        printf("%s [%d] = ",full,val->value_type);
        for(int i=0;i<(val->size&0xffff);i++) {
            // print types 1 and 7 as unicode strings  
            if(val->value_type==1||val->value_type==7) {
                if(data[i]) putchar(data[i]);
            // and rest dump as binary data         
            } else {
    // for simplicity we can imagine keys as directories in filesystem and values
    // as files.
    // and since we already dumped values for this dir we will now iterate 
    // thru subdirectories in the same way

    offsets* item = (offsets*)(root+key->subkeys);
    for(int i=0;i<item->count;i++){
        // in case of too many subkeys this list contain just other lists
        offsets* subitem = (offsets*)((&item->first)[i]+root);

        // usual directory traversal  
        if(item->block_type[1]=='f'||item->block_type[1]=='h') {
            // for now we skip hash codes (used by regedit for faster search)
        } else for(int j=0;j<subitem->count;j++) {
            // also ms had chosen to skip hashes altogether in this case 

int main(int argc, char** argv) {
    char path[0x1000]={0}, *data; FILE* f; int size;  
    if(argc<2||!(f=fopen(argv[1],"rb"))) return printf("hive path err");
    if(!(size=ftell(f))) return printf("empty file");
    rewind(f); data=(char*)malloc(size); 

    // we just skip 1k header and start walking root key tree
    return 0;

Points of Interest

Remember it will dump values that you normally don't even have access to so be careful.

It's prerfect to just dump the hives before and after software installation and just compare changes with text diff (for example commandline version from UnixUtils is great) .


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Ladislav Nevery
Software Developer (Senior)
Slovakia Slovakia
Past Projects:
[]Mobile network software: HLR-Inovation for (Corba)
Medical software: CorRea module for CT scanner
[]Computer Games:XboxLive/net code for Conan, Knights of the temple II, GeneTroopers, CivilWar, Soldier of fortune II
[]Computer Games:XboxLive/net code for Elveon game based on Unreal Engine 3
ESET Reasearch.
Looking for job

You may also be interested in...

Comments and Discussions

SuggestionACL-Permissions Pin
fr0937a27-Dec-12 4:50
memberfr0937a27-Dec-12 4:50 
Bugbif bug Pin
nissan123418-Nov-12 18:27
membernissan123418-Nov-12 18:27 
QuestionLadislav Nevery's regdmp Pin
Member 88837943-Oct-12 5:24
memberMember 88837943-Oct-12 5:24 
QuestionData Execution Prevention Pin
rec-on-tcp28-Nov-11 13:11
memberrec-on-tcp28-Nov-11 13:11 
GeneralMy vote of 3 Pin
zinajoonjooni22-Nov-11 21:57
memberzinajoonjooni22-Nov-11 21:57 
Although the i didnt understand many things from this article but i think its realy useful
Questionrun this code on linux Pin
mohsen.secure3-Sep-11 10:06
membermohsen.secure3-Sep-11 10:06 
QuestionWindows 7 Support Pin
Silvos122-Jul-11 10:05
memberSilvos122-Jul-11 10:05 
AnswerRe: Windows 7 Support [modified] Pin
Rui Morais6-Aug-11 11:31
memberRui Morais6-Aug-11 11:31 
QuestionAnother possible folder to get registry from and how to save? Pin
J Corliss5-Apr-10 3:30
memberJ Corliss5-Apr-10 3:30 
AnswerRe: Another possible folder to get registry from and how to save? Pin
Rui Morais13-Apr-10 6:44
memberRui Morais13-Apr-10 6:44 
Generalbugfix Pin
Jakub Daubner8-Mar-10 3:54
memberJakub Daubner8-Mar-10 3:54 
GeneralRe: bugfix Pin
Spockester10-Mar-10 17:32
memberSpockester10-Mar-10 17:32 
GeneralRe: bugfix Pin
Spockester10-Mar-10 17:33
memberSpockester10-Mar-10 17:33 
GeneralBuggy Pin
Spockester2-Mar-10 3:57
memberSpockester2-Mar-10 3:57 
GeneralA big thanks!! Pin
Bill Gord16-Nov-09 13:00
memberBill Gord16-Nov-09 13:00 
GeneralSomething is wrong with the download link Pin
Avis p11-Nov-09 3:25
memberAvis p11-Nov-09 3:25 
GeneralRe: Something is wrong with the download link Pin
Ladislav Nevery11-Nov-09 4:40
memberLadislav Nevery11-Nov-09 4:40 
GeneralThe format is not as simple, as you want [modified] Pin
bofur9-Nov-09 2:43
memberbofur9-Nov-09 2:43 
GeneralRe: The format is not as simple, as you want Pin
Ladislav Nevery10-Nov-09 8:33
memberLadislav Nevery10-Nov-09 8:33 
GeneralExcellent job... Pin
Naren Neelamegam23-Jul-09 21:36
memberNaren Neelamegam23-Jul-09 21:36 
QuestionHow did you find out the hive format? Pin
Chaz Zeromus2-Jun-09 10:29
memberChaz Zeromus2-Jun-09 10:29 
Questionexecution error Pin
Rodaro Angelo5-May-09 6:24
memberRodaro Angelo5-May-09 6:24 
AnswerRe: execution error Pin
Ladislav Nevery10-Nov-09 8:47
memberLadislav Nevery10-Nov-09 8:47 
Questionnoob here... parameter syntax? Pin
vigrond12-Dec-08 18:30
membervigrond12-Dec-08 18:30 
AnswerRe: noob here... parameter syntax? Pin
vigrond12-Dec-08 18:44
membervigrond12-Dec-08 18:44 
GeneralRe: noob here... parameter syntax? Pin
abcdrtnvfdk7-Jan-09 0:42
memberabcdrtnvfdk7-Jan-09 0:42 
GeneralRe: noob here... parameter syntax? Pin
Rui Morais11-Oct-09 8:12
memberRui Morais11-Oct-09 8:12 
GeneralRe: noob here... parameter syntax? Pin
Ladislav Nevery10-Nov-09 8:43
memberLadislav Nevery10-Nov-09 8:43 
GeneralRe: noob here... parameter syntax? Pin
Rui Morais1-Dec-09 7:54
memberRui Morais1-Dec-09 7:54 
Generalyour codes are damnly sh*t. Pin
abcdrtnvfdk30-Nov-08 5:17
memberabcdrtnvfdk30-Nov-08 5:17 
QuestionHive to reg with cmd Pin
Rui Morais2-Oct-08 13:40
memberRui Morais2-Oct-08 13:40 
AnswerRe: Hive to reg with cmd Pin
Chaz Zeromus2-Jun-09 10:28
memberChaz Zeromus2-Jun-09 10:28 
GeneralRe: Hive to reg with cmd Pin
Rui Morais11-Oct-09 8:13
memberRui Morais11-Oct-09 8:13 
GeneralRe: Hive to reg with cmd Pin
Chaz Zeromus11-Oct-09 8:48
memberChaz Zeromus11-Oct-09 8:48 
GeneralVery minor correction Pin
MeNot13-Jul-08 6:52
memberMeNot13-Jul-08 6:52 
GeneralThis is Great! how about VB.NET Pin
CsiSteve2-Apr-08 10:45
memberCsiSteve2-Apr-08 10:45 
GeneralOne other thought Pin
Jim Crafton17-Mar-08 12:04
memberJim Crafton17-Mar-08 12:04 
GeneralRe: One other thought Pin
Jacob Skjoet17-Mar-08 20:20
memberJacob Skjoet17-Mar-08 20:20 
QuestionRegistry internal format parser served on silver plate and you guys complain about source formatting ? Pin
lufty17-Mar-08 3:37
memberlufty17-Mar-08 3:37 
AnswerRe: Registry internal format parser served on silver plate and you guys complain about source formatting ? Pin
Jim Crafton17-Mar-08 8:15
memberJim Crafton17-Mar-08 8:15 
GeneralYou were right. I reformated it a bit. I hope it' now better readable. Pin
Ladislav Nevery17-Mar-08 2:56
memberLadislav Nevery17-Mar-08 2:56 
GeneralSorry Pin
Jim Crafton16-Mar-08 17:40
memberJim Crafton16-Mar-08 17:40 
GeneralArticle not readable Pin
Jerry Evans16-Mar-08 16:08
memberJerry Evans16-Mar-08 16:08 
GeneralCode not readable Pin
Independent12316-Mar-08 12:41
memberIndependent12316-Mar-08 12:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.151126.1 | Last Updated 11 Nov 2009
Article Copyright 2008 by Ladislav Nevery
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid