Changeset 116 for trunk/lib


Ignore:
Timestamp:
08/03/08 15:34:27 (16 years ago)
Author:
tim
Message:

fixed major bug in reglookup-recover; now recovers much more data
rolled back release version to 0.9.0
added date range checking in regfi's NK parsing for deleted records

Location:
trunk/lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/range_list.c

    r113 r116  
    1818 */
    1919
    20 #include <stdio.h>
    2120#include <math.h>
    2221#include "../include/range_list.h"
     
    2928
    3029#if 0
     30#include <stdio.h>
    3131static void range_list_print(const range_list* rl)
    3232{
  • trunk/lib/regfi.c

    r113 r116  
    442442
    443443/*******************************************************************
    444  TODO: not currently validating against max_size
    445444 *******************************************************************/
    446445REGF_HASH_LIST* regfi_load_hashlist(REGF_FILE* file, uint32 offset,
     
    463462
    464463  ret_val->offset = offset;
     464  if(cell_length > max_size)
     465  {
     466    if(strict)
     467      return NULL;
     468    cell_length = max_size & 0xFFFFFFF8;
     469  }
    465470  ret_val->cell_size = cell_length;
    466471
     
    491496      return NULL;
    492497    }
    493     /* TODO: Not sure which should be authoritative, the number from the
    494      *       NK record, or the number in the hash list.  Go with the larger
    495      *       of the two to ensure all keys are found.  Note the length checks
    496      *       on the cell later ensure that there won't be any critical errors.
     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.
    497502     */
    498503    if(num_keys < ret_val->num_keys)
     
    565570
    566571  ret_val->offset = offset;
    567   /* TODO: is there a way to be more conservative (shorter) with
    568    *       cell length when cell is unallocated?
     572  /* XXX: Is there a way to be more conservative (shorter) with
     573   *      cell length when cell is unallocated?
    569574   */
    570575  ret_val->cell_size = cell_length;
     
    582587  ret_val->magic[1] = sk_header[1];
    583588
    584   /* TODO: can additional validation be added here? */
     589  /* XXX: Can additional validation be added here? */
    585590  ret_val->unknown_tag = SVAL(sk_header, 0x2);
    586591  ret_val->prev_sk_off = IVAL(sk_header, 0x4);
     
    595600  }
    596601
    597   /* TODO: need to get rid of this, but currently the security descriptor
     602  /* XXX: need to get rid of this, but currently the security descriptor
    598603   * code depends on the ps structure.
    599604   */
     
    678683
    679684/******************************************************************************
    680  * If !strict, the list may contain NULLs and VK records may point to NULL data.
     685 * If !strict, the list may contain NULLs, VK records may point to NULL.
    681686 ******************************************************************************/
    682687REGF_VK_REC** regfi_load_valuelist(REGF_FILE* file, uint32 offset,
     
    686691  REGF_VK_REC** ret_val;
    687692  REGF_HBIN* hbin;
    688   uint32 i, vk_offset, vk_max_length;
     693  uint32 i, vk_offset, vk_max_length, usable_num_values;
    689694  uint32* voffsets;
    690695
    691696  if((num_values+1) * sizeof(uint32) > max_size)
    692     return NULL;
    693 
    694   /* TODO: For now, everything strict seems to make sense on this call.
    695    *       Maybe remove the parameter or use it for other things.
    696    */
    697   voffsets = regfi_parse_valuelist(file, offset, num_values, true);
     697  {
     698    if(strict)
     699      return NULL;
     700    usable_num_values = max_size/sizeof(uint32) - sizeof(uint32);
     701  }
     702  else
     703    usable_num_values = num_values;
     704
     705  voffsets = regfi_parse_valuelist(file, offset, usable_num_values, strict);
    698706  if(voffsets == NULL)
    699707    return NULL;
     
    706714  }
    707715 
    708   for(i=0; i < num_values; i++)
     716  for(i=0; i < usable_num_values; i++)
    709717  {
    710718    hbin = regfi_lookup_hbin(file, voffsets[i]);
     
    739747
    740748/*******************************************************************
    741  * TODO: Need to add full key caching using a
    742  *       custom cache structure.
     749 * XXX: Need to add full key caching using a
     750 *      custom cache structure.
    743751 *******************************************************************/
    744752REGF_NK_REC* regfi_load_key(REGF_FILE* file, uint32 offset, bool strict)
     
    800808      if(strict)
    801809      {
    802         free(nk);
    803         /* TODO: need convenient way to free nk->values deeply in all cases. */
     810        regfi_key_free(nk);
    804811        return NULL;
    805812      }
     
    815822      if(nk->subkeys == NULL)
    816823      {
    817         /* TODO: temporary hack to get around 'ri' records */
     824        /* XXX: Temporary hack to get around 'ri' records */
    818825        nk->num_subkeys = 0;
    819826      }
     
    10311038  }
    10321039
    1033   /* TODO: come up with a better secret. */
    1034   ret_val->sk_recs = lru_cache_create(127, 0xDEADBEEF, true);
     1040  /* This secret isn't very secret, but we don't need a good one.  This
     1041   * secret is just designed to prevent someone from trying to blow our
     1042   * caching and make things slow.
     1043   */
     1044  ret_val->sk_recs = lru_cache_create(127, 0x15DEAD05^time(NULL)
     1045                                           ^(getpid()<<16)^(getppid()<<8),
     1046                                      true);
    10351047
    10361048  ret_val->f = fh;
     
    13671379
    13681380/*******************************************************************
    1369  * TODO: add way to return more detailed error information.
     1381 * XXX: Add way to return more detailed error information.
    13701382 *******************************************************************/
    13711383REGF_FILE* regfi_parse_regf(int fd, bool strict)
     
    14411453 * along with it's associated cells.
    14421454 *******************************************************************/
    1443 /* TODO: Need a way to return types of errors.  Also need to free
    1444  *       the hbin/ps when an error occurs.
     1455/* XXX: Need a way to return types of errors.
    14451456 */
    14461457REGF_HBIN* regfi_parse_hbin(REGF_FILE* file, uint32 offset, bool strict)
     
    14851496   * the end of the file.
    14861497   */
    1487   /* TODO: This may need to be relaxed for dealing with
    1488    *       partial or corrupt files. */
     1498  /* XXX: This may need to be relaxed for dealing with
     1499   *      partial or corrupt files.
     1500   */
    14891501  if((offset + hbin->block_size > file->file_length)
    14901502     || (hbin->block_size & 0xFFFFF000) != hbin->block_size)
     
    15151527  if((nk_header[0x0] != 'n') || (nk_header[0x1] != 'k'))
    15161528  {
    1517     /* TODO: deal with subkey-lists that reference other subkey-lists. */
     1529    /* XXX: Deal with subkey-lists that reference other subkey-lists
     1530     *      (e.g. 'ri' records).
     1531     */
    15181532    return NULL;
    15191533  }
     
    15491563  ret_val->mtime.low = IVAL(nk_header, 0x4);
    15501564  ret_val->mtime.high = IVAL(nk_header, 0x8);
    1551  
     1565  /* If the key is unallocated and the MTIME is earlier than Jan 1, 1990
     1566   * or later than Jan 1, 2290, we consider this a bad key.  This helps
     1567   * weed out some false positives during deleted data recovery.
     1568   */
     1569  if(unalloc
     1570     && ((ret_val->mtime.high < REGFI_MTIME_MIN_HIGH
     1571          && ret_val->mtime.low < REGFI_MTIME_MIN_LOW)
     1572         || (ret_val->mtime.high > REGFI_MTIME_MAX_HIGH
     1573             && ret_val->mtime.low > REGFI_MTIME_MAX_LOW)))
     1574    return NULL;
     1575
    15521576  ret_val->unknown1 = IVAL(nk_header, 0xC);
    15531577  ret_val->parent_off = IVAL(nk_header, 0x10);
     
    15591583  ret_val->values_off = IVAL(nk_header, 0x28);
    15601584  ret_val->sk_off = IVAL(nk_header, 0x2C);
    1561   /* TODO: currently we do nothing with class names.  Need to investigate. */
     1585  /* XXX: currently we do nothing with class names.  Need to investigate. */
    15621586  ret_val->classname_off = IVAL(nk_header, 0x30);
    15631587
     
    17581782    if(cell_length - 4 < length)
    17591783    {
    1760       /* TODO: This strict condition has been triggered in multiple registries.
    1761        *       Not sure the cause, but the data length values are very large,
    1762        *       such as 53392.
     1784      /* XXX: This strict condition has been triggered in multiple registries.
     1785       *      Not sure the cause, but the data length values are very large,
     1786       *      such as 53392.
    17631787       */
    17641788      if(strict)
     
    17681792    }
    17691793
    1770     /* TODO: There is currently no check to ensure the data
    1771      *       cell doesn't cross HBIN boundary.
     1794    /* XXX: There is currently no check to ensure the data
     1795     *      cell doesn't cross HBIN boundary.
    17721796     */
    17731797
     
    18161840     
    18171841      if((cell_len == 0) || ((cell_len & 0xFFFFFFF8) != cell_len))
    1818         /* TODO: should report an error here. */
     1842        /* XXX: should report an error here. */
    18191843        break;
    18201844     
Note: See TracChangeset for help on using the changeset viewer.