Changeset 99 for trunk


Ignore:
Timestamp:
03/03/08 19:38:48 (17 years ago)
Author:
tim
Message:

fixed a range_list bug

replaced NK parsing routine

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r97 r99  
    4848#include "smb_deps.h"
    4949#include "void_stack.h"
     50#include "range_list.h"
    5051
    5152/******************************************************************************/
     
    8384
    8485#define REGF_OFFSET_NONE        0xffffffff
     86#define REGFI_NK_MIN_LENGTH     0x50
    8587
    8688/* Flags for the vk records */
     
    116118                          * Should be a multiple of 4096 (0x1000)
    117119                          */
    118   uint32 next_block;     /* relative offset to next block.  Should be
    119                           * exactly the same as block_size.  Stored just
    120                           * in case this is found to be different in the
    121                           * future.
     120  uint32 next_block;     /* relative offset to next block. 
     121                          * NOTE: This value may be unreliable!
    122122                          */
    123123
     
    142142  REGF_HASH_REC* hashes;
    143143  uint32 hbin_off;       /* offset from beginning of this hbin block */
    144   uint32 rec_size;       /* ((start_offset - end_offset) & 0xfffffff8) */
     144  uint32 cell_size;      /* ((start_offset - end_offset) & 0xfffffff8) */
    145145 
    146146  uint8 header[REC_HDR_SIZE];
     
    158158  uint8* data;
    159159  uint32 hbin_off;      /* offset from beginning of this hbin block */
    160   uint32 rec_size;      /* ((start_offset - end_offset) & 0xfffffff8) */
     160  uint32 cell_size;     /* ((start_offset - end_offset) & 0xfffffff8) */
    161161  uint32 rec_off;       /* offset stored in the value list */
    162162 
     
    181181  SEC_DESC* sec_desc;
    182182  uint32 hbin_off;      /* offset from beginning of this hbin block */
    183   uint32 rec_size;      /* ((start_offset - end_offset) & 0xfffffff8) */
     183  uint32 cell_size;     /* ((start_offset - end_offset) & 0xfffffff8) */
    184184 
    185185  uint32 sk_off;        /* offset parsed from NK record used as a key
     
    198198typedef struct
    199199{
    200   uint32 hbin_off;      /* offset from beginning of this hbin block */
    201   uint32 rec_size;      /* ((start_offset - end_offset) & 0xfffffff8) */
    202   REGF_HBIN *hbin;      /* pointer to HBIN record (in memory) containing
    203                          * this nk record */
     200  uint32 offset;        /* Real offset of this record's cell in the file */
     201  uint32 cell_size;     /* Actual or estimated length of the cell. 
     202                         * Always in multiples of 8.
     203                         */
    204204
    205205  /* link in the other records here */
     
    213213  uint8  header[REC_HDR_SIZE];
    214214  NTTIME mtime;
     215  uint16 name_length;
     216  uint16 classname_length;
    215217  char* classname;
    216218  char* keyname;
     
    225227 
    226228  /* unknowns */
     229  uint32 unknown1;
     230  uint32 unknown2;
     231  uint32 unknown3;
    227232  uint32 unk_index;                 /* nigel says run time index ? */
    228233 
     
    246251  void* mem_ctx;  /* memory context for run-time file access information */
    247252  REGF_HBIN* block_list; /* list of open hbin blocks */
    248  
     253
     254  /* Experimental hbin lists */
     255  range_list* hbins;
     256  range_list* unalloc_cells;
     257
    249258  /* file format information */
    250259  REGF_SK_REC* sec_desc_list;   /* list of security descriptors referenced
     
    298307/******************************************************************************/
    299308/* Function Declarations */
    300 
     309/*  Main API */
    301310const char*           regfi_type_val2str(unsigned int val);
    302311int                   regfi_type_str2val(const char* str);
     
    331340const REGF_VK_REC*    regfi_iterator_next_value(REGFI_ITERATOR* i);
    332341
     342/************************************/
     343/*  Low-layer data structure access */
     344/************************************/
     345REGF_FILE*            regfi_parse_regf(int fd, bool strict);
     346REGF_HBIN*            regfi_parse_hbin(REGF_FILE* file, uint32 offset,
     347                                       bool strict, bool save_unalloc);
     348
     349
     350/* regfi_parse_nk: Parses an NK record.
     351 *
     352 * Arguments:
     353 *   f        -- the registry file structure
     354 *   offset   -- the offset of the cell (not the record) to be parsed.
     355 *   max_size -- the maximum size the NK cell could be. (for validation)
     356 *   strict   -- if true, rejects any malformed records.  Otherwise,
     357 *               tries to minimally validate integrity.
     358 * Returns:
     359 *   A newly allocated NK record structure, or NULL on failure.
     360 */
     361REGF_NK_REC*          regfi_parse_nk(REGF_FILE* file, uint32 offset,
     362                                     uint32 max_size, bool strict);
     363
    333364
    334365/* Private Functions */
    335366REGF_NK_REC*          regfi_rootkey(REGF_FILE* file);
    336367void                  regfi_key_free(REGF_NK_REC* nk);
     368uint32                regfi_read(int fd, uint8* buf, uint32* length);
    337369
    338370
     
    341373/* Experimental */
    342374/****************/
    343 typedef struct
    344 {
    345   uint32 offset;
    346   uint32 size;
    347 } REGFI_CELL_INFO;
    348 
    349 typedef struct
    350 {
    351   uint32 count;
    352   REGFI_CELL_INFO** cells;
    353 } REGFI_CELL_LIST;
    354 
    355 
    356 REGF_FILE* regfi_parse_regf(int fd, bool strict);
    357 REGFI_CELL_LIST* regfi_get_unallocated_cells(REGF_FILE* file);
    358 REGF_HBIN* regfi_parse_hbin(REGF_FILE* file, uint32 offset,
    359                             bool strict, bool save_unalloc);
    360 REGF_NK_REC* regfi_parse_nk(REGF_FILE* f, uint32);
    361 uint32 regfi_read(int fd, uint8* buf, uint32* length);
     375
    362376
    363377#endif  /* _REGFI_H */
  • trunk/lib/range_list.c

    r98 r99  
    1818 */
    1919
     20#include <stdio.h>
    2021#include <math.h>
    2122#include "../include/range_list.h"
     
    2627/*******************/
    2728#define RANGE_LIST_ALLOC_SIZE 256
     29
     30
     31static void range_list_print(const range_list* rl)
     32{
     33  uint32_t i;
     34  for(i=0; i<rl->size; i++)
     35    fprintf(stderr, " %d=%p,%d,%d,%p", i, (void*)rl->elements[i],
     36            rl->elements[i]->offset, rl->elements[i]->length,
     37            rl->elements[i]->data);
     38  fprintf(stderr, "\n");
     39}
     40
    2841
    2942/*
     
    4053  if(rl->size == rl->elem_alloced)
    4154  {
    42     tmp = (range_list_element**)realloc(rl->elements, rl->elem_alloced+RANGE_LIST_ALLOC_SIZE);
     55    tmp = (range_list_element**)realloc(rl->elements,
     56                                        (rl->elem_alloced+RANGE_LIST_ALLOC_SIZE)
     57                                        * sizeof(range_list_element*));
    4358    if(tmp == NULL)
    4459      return false;
     
    90105    cur_elem = rl->elements[cur_idx];
    91106
    92     if((offset >= cur_elem->offset) && (offset < (cur_elem+1)->offset))
     107    if((offset >= cur_elem->offset) && (offset < rl->elements[cur_idx+1]->offset))
    93108      return cur_idx;
    94109   
     
    116131  rl->elements = (range_list_element**)malloc(sizeof(range_list_element*)
    117132                                              * RANGE_LIST_ALLOC_SIZE);
     133
    118134  if(rl->elements == NULL)
    119135  {
     
    152168  range_list_element* elem;
    153169  range_list_element* prev_elem;
    154 
     170  /*fprintf(stderr, "DEBUG: rl->size=%d\n", rl->size);*/
    155171  /* Sorry, limited to 2**31-1 elements. */
    156172  if(rl->size >= 0x7FFFFFFF)
     
    215231
    216232  /* Try to keep memory usage down */
    217   if(rl->size < (rl->elem_alloced - 2*RANGE_LIST_ALLOC_SIZE))
     233  if(rl->size < (rl->elem_alloced - 2 * RANGE_LIST_ALLOC_SIZE))
    218234  {
    219235    tmp = (range_list_element**)realloc(rl->elements,
    220                                         rl->elem_alloced - 2*RANGE_LIST_ALLOC_SIZE);
     236                                        (rl->elem_alloced-2*RANGE_LIST_ALLOC_SIZE)
     237                                        * sizeof(range_list_element*));
    221238    if(tmp != NULL)
    222239    {
  • trunk/lib/regfi.c

    r97 r99  
    337337
    338338
    339 
    340 /*******************************************************************
    341  *******************************************************************/
    342 static bool prs_nk_rec( const char *desc, prs_struct *ps,
    343                         int depth, REGF_NK_REC *nk )
    344 {
    345   uint16 class_length, name_length;
    346   uint32 start;
    347   uint32 data_size, start_off, end_off;
    348   uint32 unknown_off = REGF_OFFSET_NONE;
    349 
    350   nk->hbin_off = ps->data_offset;
    351   start = nk->hbin_off;
    352        
    353   depth++;
    354        
    355   /* back up and get the data_size */   
    356   if ( !prs_set_offset( ps, ps->data_offset-sizeof(uint32)) )
    357     return false;
    358   start_off = ps->data_offset;
    359   if ( !prs_uint32( "rec_size", ps, depth, &nk->rec_size ))
    360     return false;
    361        
    362   if (!prs_uint8s("header", ps, depth, nk->header, sizeof(nk->header)))
    363     return false;
    364                
    365   if ( !prs_uint16( "key_type", ps, depth, &nk->key_type ))
    366     return false;
    367   if ( !smb_io_time( "mtime", &nk->mtime, ps, depth ))
    368     return false;
    369                
    370   if ( !prs_set_offset( ps, start+0x0010 ) )
    371     return false;
    372   if ( !prs_uint32( "parent_off", ps, depth, &nk->parent_off ))
    373     return false;
    374   if ( !prs_uint32( "num_subkeys", ps, depth, &nk->num_subkeys ))
    375     return false;
    376                
    377   if ( !prs_set_offset( ps, start+0x001c ) )
    378     return false;
    379   if ( !prs_uint32( "subkeys_off", ps, depth, &nk->subkeys_off ))
    380     return false;
    381   if ( !prs_uint32( "unknown_off", ps, depth, &unknown_off) )
    382     return false;
    383                
    384   if ( !prs_set_offset( ps, start+0x0024 ) )
    385     return false;
    386   if ( !prs_uint32( "num_values", ps, depth, &nk->num_values ))
    387     return false;
    388   if ( !prs_uint32( "values_off", ps, depth, &nk->values_off ))
    389     return false;
    390   if ( !prs_uint32( "sk_off", ps, depth, &nk->sk_off ))
    391     return false;
    392   if ( !prs_uint32( "classname_off", ps, depth, &nk->classname_off ))
    393     return false;
    394 
    395   if (!prs_uint32("max_bytes_subkeyname", ps, depth, &nk->max_bytes_subkeyname))
    396     return false;
    397   if ( !prs_uint32( "max_bytes_subkeyclassname", ps,
    398                     depth, &nk->max_bytes_subkeyclassname))
    399   { return false; }
    400   if ( !prs_uint32( "max_bytes_valuename", ps, depth, &nk->max_bytes_valuename))
    401     return false;
    402   if ( !prs_uint32( "max_bytes_value", ps, depth, &nk->max_bytes_value))
    403     return false;
    404   if ( !prs_uint32( "unknown index", ps, depth, &nk->unk_index))
    405     return false;
    406 
    407   name_length = nk->keyname ? strlen(nk->keyname) : 0 ;
    408   class_length = nk->classname ? strlen(nk->classname) : 0 ;
    409   if ( !prs_uint16( "name_length", ps, depth, &name_length ))
    410     return false;
    411   if ( !prs_uint16( "class_length", ps, depth, &class_length ))
    412     return false;       
    413                
    414   if ( class_length )
    415   {
    416     /* XXX: why isn't this parsed? */
    417     ;;
    418   }
    419        
    420   if ( name_length )
    421   {
    422     if(ps->io && !(nk->keyname = (char*)zcalloc(sizeof(char), name_length+1)))
    423         return false;
    424 
    425     if(!prs_uint8s("name", ps, depth, (uint8*)nk->keyname, name_length))
    426       return false;
    427 
    428     if(ps->io)
    429       nk->keyname[name_length] = '\0';
    430   }
    431 
    432   end_off = ps->data_offset;
    433 
    434   /* data_size must be divisible by 8 and large enough to hold
    435      the original record */
    436 
    437   data_size = ((start_off - end_off) & 0xfffffff8 );
    438   /*if ( data_size > nk->rec_size )
    439       DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, nk->rec_size));*/
    440 
    441   return true;
    442 }
    443 
    444 
    445339/*******************************************************************
    446340 Input a randon offset and receive the correpsonding HBIN
     
    548442    return false;
    549443  start_off = hbin->ps.data_offset;
    550   if ( !prs_uint32( "rec_size", &hbin->ps, depth, &lf->rec_size ))
     444  if ( !prs_uint32( "cell_size", &hbin->ps, depth, &lf->cell_size ))
    551445    return false;
    552446
     
    573467
    574468  data_size = ((start_off - end_off) & 0xfffffff8 );
    575   /*  if ( data_size > lf->rec_size )*/
    576     /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->rec_size));*/
     469  /*  if ( data_size > lf->cell_size )*/
     470    /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->cell_size));*/
    577471
    578472  return true;
     
    599493    return false;
    600494  start_off = hbin->ps.data_offset;
    601   if ( !prs_uint32( "rec_size", &hbin->ps, depth, &sk->rec_size ))
     495  if ( !prs_uint32( "cell_size", &hbin->ps, depth, &sk->cell_size ))
    602496    return false;
    603497
     
    624518
    625519  data_size = ((start_off - end_off) & 0xfffffff8 );
    626   /*  if ( data_size > sk->rec_size )*/
    627     /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->rec_size));*/
     520  /*  if ( data_size > sk->cell_size )*/
     521    /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->cell_size));*/
    628522
    629523  return true;
     
    648542    return false;
    649543  start_off = hbin->ps.data_offset;
    650   if ( !prs_uint32( "rec_size", &hbin->ps, depth, &vk->rec_size ))
     544  if ( !prs_uint32( "cell_size", &hbin->ps, depth, &vk->cell_size ))
    651545    return false;
    652546
     
    741635  data_size = ((start_off - end_off ) & 0xfffffff8 );
    742636  /* XXX: should probably print a warning here */
    743   /*if ( data_size !=  vk->rec_size )
    744     DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk->rec_size));*/
     637  /*if ( data_size !=  vk->cell_size )
     638    DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk->cell_size));*/
    745639
    746640  return true;
     
    803697      sub_hbin = lookup_hbin_block( file, nk->values[i].rec_off );
    804698      if ( !sub_hbin )
    805       {
    806         /*DEBUG(0,("hbin_prs_vk_records: Failed to find HBIN block containing offset [0x%x]\n",
    807           nk->values[i].hbin_off));*/
    808699        return false;
    809       }
    810700    }
    811701       
     
    858748/*******************************************************************
    859749 *******************************************************************/
    860 static bool hbin_prs_key( REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk )
    861 {
     750static REGF_NK_REC* hbin_prs_key(REGF_FILE *file, REGF_HBIN *hbin)
     751{
     752  REGF_HBIN* sub_hbin;
     753  REGF_NK_REC* nk;
     754  uint32 nk_cell_offset;
     755  uint32 nk_max_length;
    862756  int depth = 0;
    863   REGF_HBIN *sub_hbin;
    864  
     757
    865758  depth++;
    866759
    867760  /* get the initial nk record */
    868   if (!prs_nk_rec("nk_rec", &hbin->ps, depth, nk))
    869     return false;
     761  nk_cell_offset = hbin->file_off + hbin->ps.data_offset - sizeof(uint32);
     762  nk_max_length = hbin->block_size - hbin->ps.data_offset + sizeof(uint32);
     763  if ((nk = regfi_parse_nk(file, nk_cell_offset, nk_max_length, true)) == NULL)
     764    return NULL;
    870765
    871766  /* fill in values */
     
    880775        /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing value_list_offset [0x%x]\n",
    881776          nk->values_off));*/
    882         return false;
     777        return NULL;
    883778      }
    884779    }
    885780               
    886781    if(!hbin_prs_vk_records("vk_rec", sub_hbin, depth, nk, file))
    887       return false;
     782      return NULL;
    888783  }
    889784               
     
    899794        /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing subkey_offset [0x%x]\n",
    900795          nk->subkeys_off));*/
    901         return false;
     796        return NULL;
    902797      }
    903798    }
    904799               
    905800    if (!hbin_prs_lf_records("lf_rec", sub_hbin, depth, nk))
    906       return false;
     801      return NULL;
    907802  }
    908803
     
    916811    {
    917812      sub_hbin = lookup_hbin_block( file, nk->sk_off );
    918       if ( !sub_hbin ) {
     813      if ( !sub_hbin )
     814      {
     815        free(nk);
    919816        /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing sk_offset [0x%x]\n",
    920817          nk->subkeys_off));*/
    921         return false;
     818        return NULL;
    922819      }
    923820    }
    924                
     821   
    925822    if ( !(nk->sec_desc = (REGF_SK_REC*)zalloc(sizeof(REGF_SK_REC) )) )
    926       return false;
     823      return NULL;
    927824    nk->sec_desc->sk_off = nk->sk_off;
    928825    if ( !hbin_prs_sk_rec( "sk_rec", sub_hbin, depth, nk->sec_desc ))
    929       return false;
     826      return NULL;
    930827                       
    931828    /* add to the list of security descriptors (ref_count has been read from the files) */
     
    935832    DLIST_ADD( file->sec_desc_list, nk->sec_desc );
    936833  }
    937                
    938   return true;
     834 
     835  return nk;
    939836}
    940837
     
    1003900/*******************************************************************
    1004901 *******************************************************************/
    1005 static bool next_nk_record(REGF_FILE *file, REGF_HBIN *hbin,
    1006                            REGF_NK_REC *nk, bool *eob)
    1007 {
    1008   if (next_record(hbin, "nk", eob)
    1009       && hbin_prs_key(file, hbin, nk))
    1010     return true;
    1011        
    1012   return false;
     902static REGF_NK_REC* next_nk_record(REGF_FILE *file, REGF_HBIN *hbin, bool *eob)
     903{
     904  REGF_NK_REC* ret_val;
     905  if(next_record(hbin, "nk", eob)
     906     && (ret_val = hbin_prs_key(file, hbin)) != NULL)
     907    return ret_val;
     908
     909fprintf(stderr, "ACK!");
     910  return NULL;
    1013911}
    1014912
     
    1030928    return NULL;
    1031929  }
    1032        
     930 
    1033931  /* read in an existing file */
    1034932  if ((rb = regfi_parse_regf(fd, true)) == NULL)
     
    1038936    return NULL;
    1039937  }
    1040        
     938 
     939  rb->hbins = range_list_new();
     940  rb->unalloc_cells = range_list_new();
     941  if((rb->hbins == NULL) || (rb->unalloc_cells == NULL))
     942  {
     943    close(fd);
     944    free(rb);
     945    return NULL;
     946  }
     947
    1041948  /* success */
    1042949  return rb;
    1043 }
    1044 
    1045 
    1046 /*******************************************************************
    1047 XXX: should this be nuked?
    1048  *******************************************************************/
    1049 static void regfi_mem_free( REGF_FILE *file )
    1050 {
    1051   /* free any zalloc()'d memory */
    1052        
    1053   /*    if ( file && file->mem_ctx )
    1054     free(file->mem_ctx);
    1055   */
    1056950}
    1057951
     
    1063957  int fd;
    1064958
    1065   regfi_mem_free( file );
    1066 
    1067959  /* nothing to do if there is no open file */
    1068 
    1069   if ( !file || (file->fd == -1) )
     960  if ((file == NULL) || (file->fd == -1))
    1070961    return 0;
    1071                
     962
    1072963  fd = file->fd;
    1073964  file->fd = -1;
    1074   SAFE_FREE( file );
     965  range_list_free(file->hbins);
     966  range_list_free(file->unalloc_cells);
     967  free(file);
    1075968
    1076969  return close( fd );
     
    1089982  bool        found = false;
    1090983  bool        eob;
    1091        
    1092   if ( !file )
    1093     return NULL;
    1094                
    1095   if ( !(nk = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC) )) ) {
    1096     /*DEBUG(0,("regfi_rootkey: zalloc() failed!\n"));*/
    1097     return NULL;
    1098   }
    1099        
     984 
     985  if(!file)
     986    return NULL;
     987
    1100988  /* scan through the file on HBIN block at a time looking
    1101989     for an NK record with a type == 0x002c.
     
    1103991     block (but I'm not assuming that for now) */
    1104992       
    1105   while ( (hbin = regfi_parse_hbin(file, offset, true, false)) ) {
     993  while((hbin = regfi_parse_hbin(file, offset, true, false)))
     994  {
    1106995    eob = false;
    1107996
    1108     while ( !eob) {
    1109       if ( next_nk_record( file, hbin, nk, &eob ) ) {
    1110         if ( nk->key_type == NK_TYPE_ROOTKEY ) {
     997    while(!eob)
     998    {
     999      if((nk = next_nk_record(file, hbin, &eob)) != NULL)
     1000      {
     1001        if ( nk->key_type == NK_TYPE_ROOTKEY )
     1002        {
    11111003          found = true;
    11121004          break;
     
    11201012    }
    11211013               
    1122     if ( found )
     1014    if(found)
    11231015      break;
    11241016
    11251017    offset += hbin->block_size;
    11261018  }
    1127        
    1128   if ( !found ) {
     1019 
     1020  if (!found) {
    11291021    /*DEBUG(0,("regfi_rootkey: corrupt registry file ?  No root key record located\n"));*/
    11301022    return NULL;
     
    13941286    return NULL;
    13951287               
    1396   if(!(subkey = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC))))
    1397     return NULL;
    1398 
    1399   if(!hbin_prs_key(i->f, hbin, subkey))
    1400   {
    1401     regfi_key_free(subkey);
    1402     return NULL;
    1403   }
     1288  if((subkey = hbin_prs_key(i->f, hbin)) == NULL)
     1289    return NULL;
    14041290
    14051291  return subkey;
     
    16131499  int32 cell_len;
    16141500  bool is_unalloc;
    1615 
    1616   if(!(hbin = (REGF_HBIN*)zalloc(sizeof(REGF_HBIN))))
    1617     return NULL;
    1618   hbin->file_off = offset;
    1619  
     1501 
     1502  if(offset >= file->file_length)
     1503    return NULL;
     1504
    16201505  if(lseek(file->fd, offset, SEEK_SET) == -1)
    16211506    return NULL;
     
    16261511    return NULL;
    16271512
     1513
    16281514  if(lseek(file->fd, offset, SEEK_SET) == -1)
    16291515    return NULL;
     1516
     1517  if(!(hbin = (REGF_HBIN*)zalloc(sizeof(REGF_HBIN))))
     1518    return NULL;
     1519  hbin->file_off = offset;
    16301520
    16311521  memcpy(hbin->magic, hbin_header, 4);
    16321522  if(strict && (memcmp(hbin->magic, "hbin", 4) != 0))
    1633     return NULL;
     1523  {
     1524    free(hbin);
     1525    return NULL;
     1526  }
    16341527
    16351528  hbin->first_hbin_off = IVAL(hbin_header, 0x4);
     
    16371530  /* this should be the same thing as hbin->block_size but just in case */
    16381531  hbin->next_block = IVAL(hbin_header, 0x1C);
    1639 
    1640 
    1641   /* TODO: This check is this more of a way to determine if they are ever
    1642    *       not the same than to really do sanity checking.  This may need
    1643    *       to be changed or removed once these fields are better understood. */
    1644   if(strict && (hbin->block_size != hbin->next_block))
    1645   {
    1646     fprintf(stderr, "DEBUG: hbin->block_size != hbin->next_block\n");
    1647     return NULL;
    1648   }
    16491532
    16501533
     
    16561539  if((offset + hbin->block_size > file->file_length)
    16571540     || (hbin->block_size & 0xFFFFF000) != hbin->block_size)
    1658     return NULL;
    1659 
     1541  {
     1542    free(hbin);
     1543    return NULL;
     1544  }
    16601545
    16611546  /* TODO: need to get rid of this, but currently lots depends on the
     
    16631548   */
    16641549  if(!prs_init(&hbin->ps, hbin->block_size, file->mem_ctx, UNMARSHALL))
    1665     return NULL;
     1550  {
     1551    free(hbin);
     1552    return NULL;
     1553  }
    16661554  length = hbin->block_size;
    16671555  if((regfi_read(file->fd, (uint8*)hbin->ps.data_p, &length) != 0)
    16681556     || length != hbin->block_size)
    1669     return NULL;
     1557  {
     1558    free(hbin);
     1559    return NULL;
     1560  }
    16701561
    16711562
    16721563  if(save_unalloc)
    16731564  {
    1674     is_unalloc = false;
    16751565    cell_len = 0;
    16761566    curr_off = HBIN_HEADER_REC_SIZE;
    16771567    while ( curr_off < hbin->block_size )
    16781568    {
     1569      is_unalloc = false;
    16791570      cell_len = IVALS(hbin->ps.data_p, curr_off);
    1680      
    16811571      if(cell_len > 0)
    16821572        is_unalloc = true;
     
    16961586
    16971587      if(is_unalloc)
    1698         /* TODO: save cell info */
     1588        range_list_add(file->unalloc_cells, hbin->file_off+curr_off,
     1589          cell_len, NULL);
    16991590
    17001591      curr_off = curr_off+cell_len;
     
    17101601  return hbin;
    17111602}
     1603
     1604
     1605REGF_NK_REC* regfi_parse_nk(REGF_FILE* file, uint32 offset,
     1606                            uint32 max_size, bool strict)
     1607{
     1608  uint8 nk_header[REGFI_NK_MIN_LENGTH];
     1609  REGF_NK_REC* ret_val;
     1610  uint32 length;
     1611  if(lseek(file->fd, offset, SEEK_SET) == -1)
     1612    return NULL;
     1613
     1614  length = REGFI_NK_MIN_LENGTH;
     1615  if((regfi_read(file->fd, nk_header, &length) != 0)
     1616     || length != REGFI_NK_MIN_LENGTH)
     1617    return NULL;
     1618 
     1619  /* A bit of validation before bothering to allocate memory */
     1620  if(strict && ((nk_header[0x4] != 'n') || (nk_header[0x5] != 'k')))
     1621    return NULL;
     1622
     1623  ret_val = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC));
     1624  if(ret_val == NULL)
     1625    return NULL;
     1626
     1627  ret_val->offset = offset;
     1628  ret_val->cell_size = IVAL(nk_header, 0x0);
     1629  if(ret_val->cell_size > max_size)
     1630    ret_val->cell_size = max_size & 0xFFFFFFF8;
     1631  if((ret_val->cell_size < REGFI_NK_MIN_LENGTH)
     1632     || (strict && ret_val->cell_size != (ret_val->cell_size & 0xFFFFFFF8)))
     1633  {
     1634    free(ret_val);
     1635    return NULL;
     1636  }
     1637
     1638  ret_val->header[0] = nk_header[0x4];
     1639  ret_val->header[1] = nk_header[0x5];
     1640  ret_val->key_type = SVAL(nk_header, 0x6);
     1641  if(strict && ((ret_val->key_type != NK_TYPE_NORMALKEY)
     1642                && (ret_val->key_type != NK_TYPE_ROOTKEY)
     1643                && (ret_val->key_type != NK_TYPE_LINKKEY)))
     1644  {
     1645    free(ret_val);
     1646    return NULL;
     1647  }
     1648 
     1649  ret_val->mtime.low = IVAL(nk_header, 0x8);
     1650  ret_val->mtime.high = IVAL(nk_header, 0xC);
     1651 
     1652  ret_val->unknown1 = IVAL(nk_header, 0x10);
     1653  ret_val->parent_off = IVAL(nk_header, 0x14);
     1654  ret_val->num_subkeys = IVAL(nk_header, 0x18);
     1655  ret_val->unknown2 = IVAL(nk_header, 0x1C);
     1656  ret_val->subkeys_off = IVAL(nk_header, 0x20);
     1657  ret_val->unknown3 = IVAL(nk_header, 0x24);
     1658  ret_val->num_values = IVAL(nk_header, 0x28);
     1659  ret_val->values_off = IVAL(nk_header, 0x2C);
     1660  ret_val->sk_off = IVAL(nk_header, 0x30);
     1661  /* TODO: currently we do nothing with class names.  Need to investigate. */
     1662  ret_val->classname_off = IVAL(nk_header, 0x34);
     1663
     1664  ret_val->max_bytes_subkeyname = IVAL(nk_header, 0x38);
     1665  ret_val->max_bytes_subkeyclassname = IVAL(nk_header, 0x3C);
     1666  ret_val->max_bytes_valuename = IVAL(nk_header, 0x40);
     1667  ret_val->max_bytes_value = IVAL(nk_header, 0x44);
     1668  ret_val->unk_index = IVAL(nk_header, 0x48);
     1669
     1670  ret_val->name_length = SVAL(nk_header, 0x4C);
     1671  ret_val->classname_length = SVAL(nk_header, 0x4E);
     1672
     1673  if(ret_val->name_length + REGFI_NK_MIN_LENGTH > ret_val->cell_size)
     1674    ret_val->name_length = ret_val->cell_size - REGFI_NK_MIN_LENGTH;
     1675
     1676  ret_val->keyname = (char*)zalloc(sizeof(char)*(ret_val->name_length+1));
     1677  if(ret_val->keyname == NULL)
     1678  {
     1679    free(ret_val);
     1680    return NULL;
     1681  }
     1682
     1683  /* Don't need to seek, should be at the right offset */
     1684  length = ret_val->name_length;
     1685  if((regfi_read(file->fd, ret_val->keyname, &length) != 0)
     1686     || length != ret_val->name_length)
     1687  {
     1688    free(ret_val->keyname);
     1689    free(ret_val);
     1690    return NULL;
     1691  }
     1692  ret_val->keyname[ret_val->name_length] = '\0';
     1693
     1694  return ret_val;
     1695}
     1696
    17121697
    17131698
Note: See TracChangeset for help on using the changeset viewer.