Changeset 127 for trunk/lib


Ignore:
Timestamp:
09/01/08 19:20:50 (16 years ago)
Author:
tim
Message:

added preliminary support for 'ri' subkey lists.
cleaned up regfi API a bit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/regfi.c

    r126 r127  
    440440
    441441
    442 
    443442/*******************************************************************
    444443 *******************************************************************/
    445 REGF_HASH_LIST* regfi_load_hashlist(REGF_FILE* file, uint32 offset,
    446                                     uint32 num_keys, uint32 max_size,
    447                                     bool strict)
    448 {
    449   REGF_HASH_LIST* ret_val;
    450   uint32 i, cell_length, length;
     444REGF_SUBKEY_LIST* regfi_merge_subkeylists(uint16 num_lists,
     445                                          REGF_SUBKEY_LIST** lists,
     446                                          bool strict)
     447{
     448  uint32 i,j,k;
     449  REGF_SUBKEY_LIST* ret_val = (REGF_SUBKEY_LIST*)zalloc(sizeof(REGF_SUBKEY_LIST));
     450  if(ret_val == NULL || lists == NULL)
     451    return NULL;
     452 
     453  /* Obtain total number of elements */
     454  ret_val->num_keys = 0;
     455  for(i=0; i < num_lists; i++)
     456  {
     457    if(lists[i] == NULL)
     458    {
     459      ret_val->num_keys = 0;
     460      break;
     461    }
     462    ret_val->num_keys += lists[i]->num_keys;
     463  }
     464 
     465  if(ret_val->num_keys > 0)
     466  {
     467    ret_val->elements =
     468      (REGF_SUBKEY_LIST_ELEM*)zalloc(sizeof(REGF_SUBKEY_LIST_ELEM)
     469                                     * ret_val->num_keys);
     470    k=0;
     471    if(ret_val->elements != NULL)
     472    {
     473      for(i=0; i<num_lists; i++)
     474        for(j=0; j<lists[i]->num_keys; j++)
     475        {
     476          ret_val->elements[k].hash=lists[i]->elements[j].hash;
     477          ret_val->elements[k++].nk_off=lists[i]->elements[j].nk_off;
     478        }
     479    }
     480  }
     481 
     482  for(i=0; i < num_lists; i++)
     483    regfi_subkeylist_free(lists[i]);
     484  free(lists);
     485
     486  return ret_val;
     487}
     488
     489
     490
     491/*******************************************************************
     492 *******************************************************************/
     493REGF_SUBKEY_LIST* regfi_load_subkeylist(REGF_FILE* file, uint32 offset,
     494                                        uint32 num_keys, uint32 max_size,
     495                                        bool strict)
     496{
     497  REGF_SUBKEY_LIST* ret_val;
     498  REGF_SUBKEY_LIST** sublists;
     499  REGF_HBIN* sublist_hbin;
     500  uint32 i, cell_length, length, num_sublists, off, max_length;
    451501  uint8* hashes;
    452   uint8 buf[REGFI_HASH_LIST_MIN_LENGTH];
     502  uint8 buf[REGFI_SUBKEY_LIST_MIN_LEN];
    453503  bool unalloc;
    454504
    455   if(!regfi_parse_cell(file->fd, offset, buf, REGFI_HASH_LIST_MIN_LENGTH,
     505  if(!regfi_parse_cell(file->fd, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN,
    456506                       &cell_length, &unalloc))
    457507    return NULL;
    458508
    459   ret_val = (REGF_HASH_LIST*)zalloc(sizeof(REGF_HASH_LIST));
    460   if(ret_val == NULL)
    461     return NULL;
    462 
    463   ret_val->offset = offset;
    464509  if(cell_length > max_size)
    465510  {
     
    468513    cell_length = max_size & 0xFFFFFFF8;
    469514  }
     515
     516  if(buf[0] == 'r' && buf[1] == 'i')
     517  {
     518    num_sublists = SVAL(buf, 0x2);
     519
     520    /* XXX: check cell_length vs num_sublists vs max_length */
     521    length = num_sublists*sizeof(uint32);
     522    hashes = (uint8*)zalloc(length);
     523    if(hashes == NULL)
     524      return NULL;
     525
     526    if(regfi_read(file->fd, hashes, &length) != 0
     527       || length != num_sublists*sizeof(uint32))
     528    {
     529      free(hashes);
     530      return NULL;
     531    }
     532
     533    sublists = (REGF_SUBKEY_LIST**)zalloc(num_sublists*sizeof(REGF_SUBKEY_LIST*));   
     534    for(i=0; i < num_sublists; i++)
     535    {
     536      off = IVAL(hashes, i*4)+REGF_BLOCKSIZE;
     537      sublist_hbin = regfi_lookup_hbin(file, IVAL(hashes, i*4));
     538      max_length = sublist_hbin->block_size + sublist_hbin->file_off - off;
     539
     540      /* XXX: Need to add a recursion depth limit of some kind. */
     541      sublists[i] = regfi_load_subkeylist(file, off, 0, max_length, strict);
     542    }
     543
     544    return regfi_merge_subkeylists(num_sublists, sublists, strict);
     545  }
     546
     547  ret_val = (REGF_SUBKEY_LIST*)zalloc(sizeof(REGF_SUBKEY_LIST));
     548  if(ret_val == NULL)
     549    return NULL;
     550
     551  ret_val->offset = offset;
    470552  ret_val->cell_size = cell_length;
    471553
    472   if((buf[0] != 'l' || buf[1] != 'f') && (buf[0] != 'l' || buf[1] != 'h')
    473      && (buf[0] != 'r' || buf[1] != 'i'))
     554  if((buf[0] != 'l' || buf[1] != 'f') && (buf[0] != 'l' || buf[1] != 'h'))
    474555  {
    475556    /*printf("DEBUG: lf->header=%c%c\n", buf[0], buf[1]);*/
     
    478559  }
    479560
    480   if(buf[0] == 'r' && buf[1] == 'i')
    481   {
    482     fprintf(stderr, "WARNING: ignoring encountered \"ri\" record.\n");
    483     free(ret_val);
    484     return NULL;
    485   }
    486 
    487561  ret_val->magic[0] = buf[0];
    488562  ret_val->magic[1] = buf[1];
     
    491565  if(num_keys != ret_val->num_keys)
    492566  {
    493     if(strict)
    494     {
    495       free(ret_val);
    496       return NULL;
    497     }
    498     /* XXX: Not sure which should be authoritative, the number from the
    499      *      NK record, or the number in the hash list.  Go with the larger
    500      *      of the two to ensure all keys are found.  Note the length checks
    501      *      on the cell later ensure that there won't be any critical errors.
     567    /*  Not sure which should be authoritative, the number from the
     568     *  NK record, or the number in the subkey list.  Go with the larger
     569     *  of the two to ensure all keys are found, since in 'ri' records,
     570     *  there is no authoritative parent count for a leaf subkey list. 
     571     *  Note the length checks on the cell later ensure that there won't
     572     *  be any critical errors.
    502573     */
    503574    if(num_keys < ret_val->num_keys)
     
    507578  }
    508579
    509   if(cell_length - REGFI_HASH_LIST_MIN_LENGTH - sizeof(uint32)
    510      < ret_val->num_keys*sizeof(REGF_HASH_LIST_ELEM))
    511     return NULL;
    512 
    513   length = sizeof(REGF_HASH_LIST_ELEM)*ret_val->num_keys;
    514   ret_val->hashes = (REGF_HASH_LIST_ELEM*)zalloc(length);
    515   if(ret_val->hashes == NULL)
     580  if(cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32)
     581     < ret_val->num_keys*sizeof(REGF_SUBKEY_LIST_ELEM))
     582    return NULL;
     583
     584  length = sizeof(REGF_SUBKEY_LIST_ELEM)*ret_val->num_keys;
     585  ret_val->elements = (REGF_SUBKEY_LIST_ELEM*)zalloc(length);
     586  if(ret_val->elements == NULL)
    516587  {
    517588    free(ret_val);
     
    522593  if(hashes == NULL)
    523594  {
    524     free(ret_val->hashes);
     595    free(ret_val->elements);
    525596    free(ret_val);
    526597    return NULL;
     
    528599
    529600  if(regfi_read(file->fd, hashes, &length) != 0
    530      || length != sizeof(REGF_HASH_LIST_ELEM)*ret_val->num_keys)
    531   {
    532     free(ret_val->hashes);
     601     || length != sizeof(REGF_SUBKEY_LIST_ELEM)*ret_val->num_keys)
     602  {
     603    free(ret_val->elements);
    533604    free(ret_val);
    534605    return NULL;
     
    537608  for (i=0; i < ret_val->num_keys; i++)
    538609  {
    539     ret_val->hashes[i].nk_off = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM));
    540     ret_val->hashes[i].hash = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM)+4);
     610    ret_val->elements[i].nk_off = IVAL(hashes, i*sizeof(REGF_SUBKEY_LIST_ELEM));
     611    ret_val->elements[i].hash = IVAL(hashes, i*sizeof(REGF_SUBKEY_LIST_ELEM)+4);
    541612  }
    542613  free(hashes);
     
    818889      off = nk->subkeys_off + REGF_BLOCKSIZE;
    819890      max_length = sub_hbin->block_size + sub_hbin->file_off - off;
    820       nk->subkeys = regfi_load_hashlist(file, off, nk->num_subkeys,
    821                                         max_length, true);
     891      nk->subkeys = regfi_load_subkeylist(file, off, nk->num_subkeys,
     892                                          max_length, true);
    822893      if(nk->subkeys == NULL)
    823894      {
     
    10031074  }
    10041075
     1076  regfi_subkeylist_free(nk->subkeys);
     1077
    10051078  if(nk->keyname != NULL)
    10061079    free(nk->keyname);
     
    10111084  /* XXX: not freeing sec_desc because these are cached.  This needs to be reviewed. */
    10121085  free(nk);
     1086}
     1087
     1088
     1089/******************************************************************************
     1090 *****************************************************************************/
     1091void regfi_subkeylist_free(REGF_SUBKEY_LIST* list)
     1092{
     1093  if(list != NULL)
     1094  {
     1095    free(list->elements);
     1096    free(list);
     1097  }
    10131098}
    10141099
     
    12691354    return NULL;
    12701355
    1271   nk_offset = i->cur_key->subkeys->hashes[i->cur_subkey].nk_off;
     1356  nk_offset = i->cur_key->subkeys->elements[i->cur_subkey].nk_off;
    12721357 
    12731358  return regfi_load_key(i->f, nk_offset+REGF_BLOCKSIZE, true);
Note: See TracChangeset for help on using the changeset viewer.