Changeset 152 for trunk/lib


Ignore:
Timestamp:
06/02/09 16:00:38 (16 years ago)
Author:
tim
Message:

preliminary support for big data records

switched to using key flags rather than incorrect key types

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/regfi.c

    r151 r152  
    966966    if(ret_val->data_in_offset)
    967967    {
    968       data = regfi_parse_data(file, ret_val->type, ret_val->data_off,
     968      data = regfi_load_data(file, ret_val->type, ret_val->data_off,
    969969                              ret_val->data_size, 4,
    970970                              ret_val->data_in_offset, strict);
     
    979979        data_offset = ret_val->data_off+REGFI_REGF_SIZE;
    980980        data_maxsize = hbin->block_size + hbin->file_off - data_offset;
    981         data = regfi_parse_data(file, ret_val->type, data_offset,
     981        data = regfi_load_data(file, ret_val->type, data_offset,
    982982                                ret_val->data_size, data_maxsize,
    983983                                ret_val->data_in_offset, strict);
     
    999999      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse data record"
    10001000                        " while parsing VK record at offset 0x%.8X.",
    1001                         ret_val->offset);
     1001                        ret_val->offset, ret_val->valuename);
    10021002    }
    10031003    else
     
    12041204      if(nk != NULL)
    12051205      {
    1206         if((nk->key_type == REGFI_NK_TYPE_ROOTKEY1)
    1207            || (nk->key_type == REGFI_NK_TYPE_ROOTKEY2))
     1206        if(nk->key_type & REGFI_NK_FLAG_ROOT)
    12081207        {
    12091208          found = true;
     
    17771776  ret_val->thaw_rm_id = winsec_parse_uuid(ret_val, file_header+0xFD8, 16);
    17781777  ret_val->thaw_log_id = winsec_parse_uuid(ret_val, file_header+0xFE8, 16);
    1779   ret_val->boot_type = IVAL(file_header, 0x90);
    1780   ret_val->boot_recover = IVAL(file_header, 0x90);
     1778  ret_val->boot_type = IVAL(file_header, 0xFF8);
     1779  ret_val->boot_recover = IVAL(file_header, 0xFFC);
    17811780
    17821781  return ret_val;
     
    19181917  ret_val->magic[1] = nk_header[0x1];
    19191918  ret_val->key_type = SVAL(nk_header, 0x2);
    1920   if((ret_val->key_type != REGFI_NK_TYPE_NORMALKEY)
    1921      && (ret_val->key_type != REGFI_NK_TYPE_ROOTKEY1)
    1922      && (ret_val->key_type != REGFI_NK_TYPE_ROOTKEY2)
    1923      && (ret_val->key_type != REGFI_NK_TYPE_LINKKEY)
    1924      && (ret_val->key_type != REGFI_NK_TYPE_UNKNOWN1)
    1925      && (ret_val->key_type != REGFI_NK_TYPE_UNKNOWN2)
    1926      && (ret_val->key_type != REGFI_NK_TYPE_UNKNOWN3))
    1927   {
    1928     regfi_add_message(file, REGFI_MSG_WARN, "Unknown key type (0x%.4X) while"
     1919 
     1920  if((ret_val->key_type & ~REGFI_NK_KNOWN_FLAGS) != 0)
     1921  {
     1922    regfi_add_message(file, REGFI_MSG_WARN, "Unknown key flags (0x%.4X) while"
    19291923                      " parsing NK record at offset 0x%.8X.",
    1930                       ret_val->key_type, offset);
     1924                      (ret_val->key_type & ~REGFI_NK_KNOWN_FLAGS), offset);
    19311925  }
    19321926
     
    19641958  ret_val->classname_length = SVAL(nk_header, 0x4A);
    19651959
    1966 
    19671960  if(ret_val->name_length + REGFI_NK_MIN_LENGTH > ret_val->cell_size)
    19681961  {
     
    21062099
    21072100
    2108 /*******************************************************************
    2109  *******************************************************************/
     2101/******************************************************************************
     2102*******************************************************************************/
    21102103REGFI_VK_REC* regfi_parse_vk(REGFI_FILE* file, uint32 offset,
    21112104                             uint32 max_size, bool strict)
     
    22212214
    22222215
    2223 REGFI_BUFFER regfi_parse_data(REGFI_FILE* file,
    2224                               uint32 data_type, uint32 offset,
    2225                               uint32 length, uint32 max_size,
    2226                               bool data_in_offset, bool strict)
     2216/******************************************************************************
     2217*******************************************************************************/
     2218REGFI_BUFFER regfi_load_data(REGFI_FILE* file,
     2219                             uint32 data_type, uint32 offset,
     2220                             uint32 length, uint32 max_size,
     2221                             bool data_in_offset, bool strict)
    22272222{
    22282223  REGFI_BUFFER ret_val;
     
    22802275    if(cell_length - 4 < length)
    22812276    {
    2282       /* XXX: This strict condition has been triggered in multiple registries.
    2283        *      Not sure the cause, but the data length values are very large,
    2284        *      such as 53392.  For now, we're truncating the size and returning
    2285        *      what we can, since this issue is so common.
    2286        */
    2287       regfi_add_message(file, REGFI_MSG_WARN, "Data length (0x%.8X) larger than"
    2288                         " remaining cell length (0x%.8X)"
    2289                         " while parsing data record at offset 0x%.8X.",
    2290                         length, cell_length - 4, offset);
    2291       /*
    2292       if(strict)
    2293         goto fail;
     2277      if (file->major_version >= 1 && file->minor_version >= 5)
     2278      {
     2279        /* Attempt to parse a big data record */
     2280        return regfi_load_big_data(file, offset, length, cell_length, strict);
     2281      }
    22942282      else
    2295       */
    2296       length = cell_length - 4;
     2283      {
     2284        regfi_add_message(file, REGFI_MSG_WARN, "Data length (0x%.8X) larger than"
     2285                          " remaining cell length (0x%.8X)"
     2286                          " while parsing data record at offset 0x%.8X.",
     2287                          length, cell_length - 4, offset);
     2288        if(strict)
     2289          goto fail;
     2290        else
     2291          length = cell_length - 4;
     2292      }
    22972293    }
    22982294
     
    23142310  return ret_val;
    23152311
     2312 fail:
     2313  ret_val.buf = NULL;
     2314  ret_val.len = 0;
     2315  return ret_val;
     2316}
     2317
     2318
     2319/******************************************************************************
     2320*******************************************************************************/
     2321REGFI_BUFFER regfi_load_big_data(REGFI_FILE* file,
     2322                                 uint32 offset, uint32 data_length,
     2323                                 uint32 cell_length, bool strict)
     2324{
     2325  REGFI_BUFFER ret_val;
     2326  uint16 num_chunks, i;
     2327  uint32 indirect_offset, indirect_length, chunk_length, chunk_offset;
     2328  uint32 read_length, data_left;
     2329  bool unalloc;
     2330  uint32* indirect_ptrs;
     2331  uint8* big_data_cell = (uint8*)malloc(cell_length*sizeof(uint8));
     2332  if(big_data_cell == NULL)
     2333    goto fail;
     2334
     2335  if(!regfi_parse_cell(file->fd, offset, big_data_cell, cell_length-4,
     2336                       &cell_length, &unalloc))
     2337  {
     2338    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
     2339                      " parsing big data record at offset 0x%.8X.", offset);
     2340    free(big_data_cell);
     2341    goto fail;
     2342  }
     2343 
     2344  if((big_data_cell[0] != 'd') || (big_data_cell[1] != 'b'))
     2345  {
     2346    regfi_add_message(file, REGFI_MSG_WARN, "Unknown magic number"
     2347                      " (0x%.2X, 0x%.2X) encountered while parsing"
     2348                      " big data record at offset 0x%.8X.",
     2349                      big_data_cell[0], big_data_cell[1], offset);
     2350    free(big_data_cell);
     2351    goto fail;
     2352  }
     2353  num_chunks = SVAL(big_data_cell, 0x2);
     2354  /* XXX: Should check sanity of pointers here and in the indirect
     2355   *      block.  At least ensure they are a multiple of 8.
     2356   */
     2357  indirect_offset = IVAL(big_data_cell, 0x4) + REGFI_REGF_SIZE;
     2358  free(big_data_cell);
     2359
     2360  indirect_ptrs = (uint32*)malloc(num_chunks*sizeof(uint32));
     2361  if(indirect_ptrs == NULL)
     2362    goto fail;
     2363
     2364  if(!regfi_parse_cell(file->fd, indirect_offset, (uint8*)indirect_ptrs,
     2365                       num_chunks*sizeof(uint32),
     2366                       &indirect_length, &unalloc))
     2367  {
     2368    regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
     2369                      " parsing big data indirect record at offset 0x%.8X.",
     2370                      offset);
     2371    free(indirect_ptrs);
     2372    goto fail;
     2373  }
     2374 
     2375  if((ret_val.buf = talloc_array(NULL, uint8_t, data_length)) == NULL)
     2376  {
     2377    free(indirect_ptrs);
     2378    goto fail;
     2379  }
     2380  data_left = data_length;
     2381
     2382  for(i=0; (i<num_chunks) && (data_left>0); i++)
     2383  {
     2384    /* Fix endianness of pointer and convert to physical offset */
     2385    chunk_offset = IVAL(indirect_ptrs, i*4) + REGFI_REGF_SIZE;
     2386    if(!regfi_parse_cell(file->fd, chunk_offset, NULL, 0,
     2387                         &chunk_length, &unalloc))
     2388    {
     2389      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while"
     2390                        " parsing big data chunk at offset 0x%.8X.",
     2391                        chunk_offset);
     2392      if(strict)
     2393        goto chunk_fail;
     2394      else
     2395        break;
     2396    }
     2397
     2398    if(chunk_length-4 > data_left)
     2399      read_length = data_left;
     2400    else
     2401      read_length = chunk_length-4;
     2402
     2403    if(regfi_read(file->fd, ret_val.buf+(data_length-data_left),
     2404                  &read_length) != 0)
     2405    {
     2406      regfi_add_message(file, REGFI_MSG_WARN, "Could not read data chunk while"
     2407                        " constructing big data at offset 0x%.8X.",
     2408                        chunk_offset);
     2409      if(strict)
     2410        goto chunk_fail;
     2411      else
     2412        break;
     2413    }
     2414
     2415    data_left -= read_length;
     2416  }
     2417
     2418  free(indirect_ptrs);
     2419  ret_val.len = data_length-data_left;
     2420  return ret_val;
     2421
     2422 chunk_fail:
     2423  free(indirect_ptrs);
     2424  talloc_free(ret_val.buf);
    23162425 fail:
    23172426  ret_val.buf = NULL;
Note: See TracChangeset for help on using the changeset viewer.