Changeset 104


Ignore:
Timestamp:
04/03/08 19:22:39 (17 years ago)
Author:
tim
Message:

replaced lf (hash list) parsing code

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r103 r104  
    8787#define REGFI_VK_MIN_LENGTH     0x14
    8888#define REGFI_SK_MIN_LENGTH     0x14
     89#define REGFI_HASH_LIST_MIN_LENGTH     0x4
    8990
    9091/* Flags for the vk records */
     
    135136{
    136137  uint32 nk_off;
    137   uint8 keycheck[4];
    138 } REGF_HASH_REC;
    139 
    140 
    141 typedef struct
    142 {
     138  uint32 hash;
     139} REGF_HASH_LIST_ELEM;
     140
     141
     142typedef struct
     143{
     144  uint32 offset;        /* Real offset of this record's cell in the file */
     145  uint32 cell_size;      /* ((start_offset - end_offset) & 0xfffffff8) */
    143146  REGF_HBIN* hbin;       /* pointer to HBIN record (in memory) containing
    144147                          * this nk record
    145148                          */
    146   REGF_HASH_REC* hashes;
    147149  uint32 hbin_off;       /* offset from beginning of this hbin block */
    148   uint32 cell_size;      /* ((start_offset - end_offset) & 0xfffffff8) */
    149  
    150   uint8 header[REC_HDR_SIZE];
     150  REGF_HASH_LIST_ELEM* hashes;
     151 
     152  uint8 magic[REC_HDR_SIZE];
    151153  uint16 num_keys;
    152 } REGF_LF_REC;
     154} REGF_HASH_LIST;
    153155
    154156
     
    204206
    205207
    206 /* Key Name */ 
    207 typedef struct 
     208/* Key Name */
     209typedef struct
    208210{
    209211  uint32 offset;        /* Real offset of this record's cell in the file */
     
    215217  REGF_VK_REC** values;
    216218  REGF_SK_REC* sec_desc;
    217   REGF_LF_REC subkeys;
     219  REGF_HASH_LIST* subkeys;
    218220 
    219221  /* header information */
     
    382384/* Experimental */
    383385/****************/
     386REGF_HASH_LIST* regfi_load_hashlist(REGF_FILE* file, uint32 offset,
     387                                    uint32 num_keys, bool strict);
    384388
    385389REGF_VK_REC** regfi_load_valuelist(REGF_FILE* file, uint32 offset,
  • trunk/lib/regfi.c

    r103 r104  
    476476
    477477
     478
    478479/*******************************************************************
    479480 *******************************************************************/
    480 static bool prs_hash_rec( const char *desc, prs_struct *ps, int depth, REGF_HASH_REC *hash )
    481 {
    482   depth++;
    483 
    484   if ( !prs_uint32( "nk_off", ps, depth, &hash->nk_off ))
    485     return false;
    486   if ( !prs_uint8s("keycheck", ps, depth, hash->keycheck, sizeof( hash->keycheck )) )
    487     return false;
    488        
    489   return true;
    490 }
    491 
    492 
    493 /*******************************************************************
    494  *******************************************************************/
    495 static bool hbin_prs_lf_records(const char *desc, REGF_HBIN *hbin,
    496                                 int depth, REGF_NK_REC *nk)
    497 {
    498   int i;
    499   REGF_LF_REC *lf = &nk->subkeys;
    500   uint32 data_size, start_off, end_off;
    501 
    502   depth++;
    503 
    504   /* check if we have anything to do first */
    505        
    506   if ( nk->num_subkeys == 0 )
    507     return true;
    508 
    509   /* move to the LF record */
    510 
    511   if ( !prs_set_offset( &hbin->ps, nk->subkeys_off + HBIN_MAGIC_SIZE - hbin->first_hbin_off ) )
    512     return false;
    513 
    514   /* backup and get the data_size */
    515        
    516   if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) )
    517     return false;
    518   start_off = hbin->ps.data_offset;
    519   if ( !prs_uint32( "cell_size", &hbin->ps, depth, &lf->cell_size ))
    520     return false;
    521 
    522   if(!prs_uint8s("header", &hbin->ps, depth,
    523                  lf->header, sizeof(lf->header)))
    524     return false;
    525 
    526   /*fprintf(stdout, "DEBUG: lf->header=%c%c\n", lf->header[0], lf->header[1]);*/
    527 
    528   if ( !prs_uint16( "num_keys", &hbin->ps, depth, &lf->num_keys))
    529     return false;
    530 
    531   if ( hbin->ps.io ) {
    532     if ( !(lf->hashes = (REGF_HASH_REC*)zcalloc(sizeof(REGF_HASH_REC), lf->num_keys )) )
    533       return false;
    534   }
    535 
    536   for ( i=0; i<lf->num_keys; i++ ) {
    537     if ( !prs_hash_rec( "hash_rec", &hbin->ps, depth, &lf->hashes[i] ) )
    538       return false;
    539   }
    540 
    541   end_off = hbin->ps.data_offset;
    542 
    543   /* data_size must be divisible by 8 and large enough to hold the original record */
    544 
    545   data_size = ((start_off - end_off) & 0xfffffff8 );
    546   /*  if ( data_size > lf->cell_size )*/
    547     /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->cell_size));*/
    548 
    549   return true;
     481REGF_HASH_LIST* regfi_load_hashlist(REGF_FILE* file, uint32 offset,
     482                                    uint32 num_keys, bool strict)
     483{
     484  REGF_HASH_LIST* ret_val;
     485  uint32 i, cell_length, length;
     486  uint8* hashes;
     487  uint8 buf[REGFI_HASH_LIST_MIN_LENGTH];
     488  bool unalloc;
     489
     490  if(!regfi_parse_cell(file->fd, offset, buf, REGFI_HASH_LIST_MIN_LENGTH,
     491                       &cell_length, &unalloc))
     492    return NULL;
     493
     494  ret_val = (REGF_HASH_LIST*)zalloc(sizeof(REGF_HASH_LIST));
     495  if(ret_val == NULL)
     496    return NULL;
     497
     498  ret_val->offset = offset;
     499  ret_val->cell_size = cell_length;
     500
     501  if((buf[0] != 'l' || buf[1] != 'f') && (buf[0] != 'l' || buf[1] != 'h')
     502     && (buf[0] != 'r' || buf[1] != 'i'))
     503  {
     504    /*printf("DEBUG: lf->header=%c%c\n", buf[0], buf[1]);*/
     505    free(ret_val);
     506    return NULL;
     507  }
     508
     509  if(buf[0] == 'r' && buf[1] == 'i')
     510  {
     511    fprintf(stderr, "WARNING: ignoring encountered \"ri\" record.\n");
     512    free(ret_val);
     513    return NULL;
     514  }
     515
     516  ret_val->magic[0] = buf[0];
     517  ret_val->magic[1] = buf[1];
     518
     519  ret_val->num_keys = SVAL(buf, 0x2);
     520  if(num_keys != ret_val->num_keys)
     521  {
     522    if(strict)
     523    {
     524      free(ret_val);
     525      return NULL;
     526    }
     527    /* TODO: Not sure which should be authoritative, the number from the
     528     *       NK record, or the number in the hash list.  Go with the larger
     529     *       of the two to ensure all keys are found.  Note the length checks
     530     *       on the cell later ensure that there won't be any critical errors.
     531     */
     532    if(num_keys < ret_val->num_keys)
     533      num_keys = ret_val->num_keys;
     534    else
     535      ret_val->num_keys = num_keys;
     536  }
     537
     538  if(cell_length - REGFI_HASH_LIST_MIN_LENGTH - sizeof(uint32)
     539     < ret_val->num_keys*sizeof(REGF_HASH_LIST_ELEM))
     540    return NULL;
     541
     542  length = sizeof(REGF_HASH_LIST_ELEM)*ret_val->num_keys;
     543  ret_val->hashes = (REGF_HASH_LIST_ELEM*)zalloc(length);
     544  if(ret_val->hashes == NULL)
     545  {
     546    free(ret_val);
     547    return NULL;
     548  }
     549
     550  hashes = (uint8*)zalloc(length);
     551  if(hashes == NULL)
     552  {
     553    free(ret_val->hashes);
     554    free(ret_val);
     555    return NULL;
     556  }
     557
     558  if(regfi_read(file->fd, hashes, &length) != 0
     559     || length != sizeof(REGF_HASH_LIST_ELEM)*ret_val->num_keys)
     560  {
     561    free(ret_val->hashes);
     562    free(ret_val);
     563    return NULL;
     564  }
     565
     566  for (i=0; i < ret_val->num_keys; i++)
     567  {
     568    ret_val->hashes[i].nk_off = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM));
     569    ret_val->hashes[i].hash = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM)+4);
     570  }
     571  free(hashes);
     572
     573  return ret_val;
    550574}
    551575
     
    782806      }
    783807    }
    784    
    785     if (!hbin_prs_lf_records("lf_rec", sub_hbin, depth, nk))
    786       return NULL;
     808
     809    nk->subkeys = regfi_load_hashlist(file, nk->subkeys_off + REGF_BLOCKSIZE,
     810                                      nk->num_subkeys, true);
     811    if (nk->subkeys == NULL)
     812    {
     813      /* TODO: temporary hack to get around 'ri' records */
     814      nk->num_subkeys = 0;
     815    }
    787816  }
    788817
     
    12031232    return NULL;
    12041233
    1205   nk_offset = i->cur_key->subkeys.hashes[i->cur_subkey].nk_off;
     1234  nk_offset = i->cur_key->subkeys->hashes[i->cur_subkey].nk_off;
    12061235
    12071236  /* find the HBIN block which should contain the nk record */
     
    12111240    /* XXX: should print out some kind of error message every time here */
    12121241    /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing offset [0x%x]\n",
    1213       i->cur_key->subkeys.hashes[i->cur_subkey].nk_off));*/
     1242      i->cur_key->subkeys->hashes[i->cur_subkey].nk_off));*/
    12141243    return NULL;
    12151244  }
Note: See TracChangeset for help on using the changeset viewer.