Changeset 112


Ignore:
Timestamp:
05/03/08 20:22:50 (17 years ago)
Author:
tim
Message:

added path resolution to reglookup-recover

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r111 r112  
    213213  /* header information */
    214214  /* XXX: should we be looking for types other than the root key type? */
    215   uint16 key_type;     
     215  uint16 key_type;
    216216  uint8  magic[REC_HDR_SIZE];
    217217  NTTIME mtime;
  • trunk/lib/lru_cache.c

    r111 r112  
    5656}
    5757
    58 
     58#if 0
    5959static void lru_cache_print(lru_cache* ht)
    6060{
     
    9595  }
    9696}
    97 
     97#endif
    9898
    9999lru_cache* lru_cache_create(uint32_t max_keys, uint32_t secret, bool free_data)
  • trunk/src/reglookup-recover.c

    r111 r112  
    270270  free(quoted_buf);
    271271  return 0;
     272}
     273
     274
     275/* This function returns a properly quoted parent path or partial parent
     276 * path for a given key.  Returns NULL on error, "" if no path was available.
     277 * Paths returned must be free()d.
     278 */
     279/* TODO: This is not terribly efficient, as it may reparse many keys
     280 *       repeatedly.  Should try to add caching.  Also, piecing the path
     281 *       together is slow and redundant.
     282 */
     283char* getParentPath(REGF_FILE* f, REGF_NK_REC* nk)
     284{
     285  void_stack* path_stack = void_stack_new(REGF_MAX_DEPTH);
     286  REGF_HBIN* hbin;
     287  REGF_NK_REC* cur_ancestor;
     288  char* ret_val;
     289  char* path_element;
     290  char* tmp_str;
     291  uint32 virt_offset, i, stack_size, ret_val_size, ret_val_left, element_size;
     292  uint32 max_length;
     293
     294  virt_offset = nk->parent_off;
     295  while(virt_offset != REGF_OFFSET_NONE)
     296  { 
     297    /* TODO: Need to add checks for infinite loops and/or add depth limit */
     298    hbin = regfi_lookup_hbin(f, virt_offset);
     299    if(hbin == NULL)
     300      virt_offset = REGF_OFFSET_NONE;
     301    else
     302    {
     303      max_length = hbin->block_size + hbin->file_off
     304        - (virt_offset+REGF_BLOCKSIZE);
     305      cur_ancestor = regfi_parse_nk(f, virt_offset+REGF_BLOCKSIZE,
     306                                    max_length, true);
     307      if(cur_ancestor == NULL)
     308        virt_offset = REGF_OFFSET_NONE;
     309      else
     310      {
     311        if(cur_ancestor->key_type == NK_TYPE_ROOTKEY)
     312          virt_offset = REGF_OFFSET_NONE;
     313        else
     314          virt_offset = cur_ancestor->parent_off;
     315       
     316        path_element = quote_string(cur_ancestor->keyname, key_special_chars);
     317        if(path_element == NULL || !void_stack_push(path_stack, path_element))
     318        {
     319          free(cur_ancestor->keyname);
     320          free(cur_ancestor);
     321          void_stack_free_deep(path_stack);
     322          return NULL;
     323        }
     324
     325        regfi_key_free(cur_ancestor);
     326      }
     327    }
     328  }
     329 
     330  stack_size = void_stack_size(path_stack);
     331  ret_val_size = 16*stack_size;
     332  if(ret_val_size == 0)
     333    ret_val_size = 1;
     334  ret_val_left = ret_val_size;
     335  ret_val = malloc(ret_val_size);
     336  if(ret_val == NULL)
     337  {
     338    void_stack_free_deep(path_stack);
     339    return NULL;
     340  }
     341  ret_val[0] = '\0';
     342
     343  for(i=0; i<stack_size; i++)
     344  {
     345    path_element = void_stack_pop(path_stack);
     346    element_size = strlen(path_element);
     347    if(ret_val_left < element_size+2)
     348    {
     349      ret_val_size += element_size+16;
     350      ret_val_left += element_size+16;
     351      tmp_str = (char*)realloc(ret_val, ret_val_size);
     352      if(tmp_str == NULL)
     353      {
     354        free(ret_val);
     355        void_stack_free_deep(path_stack);
     356        return NULL;
     357      }
     358      ret_val = tmp_str;
     359    }
     360
     361    ret_val_left -= snprintf(ret_val+ret_val_size-ret_val_left,ret_val_left, "/%s", path_element);
     362    free(path_element);
     363  }
     364  void_stack_free(path_stack);
     365
     366  return ret_val;
    272367}
    273368
     
    595690  range_list* unalloc_values;
    596691  range_list* unalloc_sks;
     692  char** parent_paths;
     693  char* tmp_name;
     694  char* tmp_path;
    597695  REGF_NK_REC* tmp_key;
    598696  REGF_VK_REC* tmp_value;
    599   uint32 argi, arge, i, j, ret;
     697  uint32 argi, arge, i, j, ret, num_unalloc_keys;
    600698  /* uint32 test_offset;*/
    601699 
     
    647745           "NK_MTIME,NK_NVAL,VK_TYPE,VK_VALUE,VK_DATA_LEN,"
    648746           "SK_OWNER,SK_GROUP,SK_SACL,SK_DACL,RAW_CELL\n");
    649  
    650 /*
    651  * 1. Build a set of all empty cells.  May need to keep these in a
    652  *    sorted list based on offset.  May also need to have them in a hash
    653  *    table.
    654  *
    655  * 2. Scour all cells for NK records (regardless of signature offset),
    656  *    caching those records separately when they successfully parsed.
    657  *
    658  * 3. Follow each NK record's parent pointers up until a non-deleted key
    659  *    is found.  Associate this full path with the NK records somehow.
    660  *
    661  * 4. Follow each NK record's pointers to Value-Lists and attempt to
    662  *    recover VK/data records from remaining cells.  Associate good VK
    663  *    records with their full paths.
    664  *
    665  * 5. For each remaining cell or partial cell, attempt to identify the
    666  *    record type and parse it.
    667  *
    668  * At each step, claimed cells are removed from the global cell
    669  * list/hash.  If only part of a cell is claimed, it is removed from
    670  * the list and the remaining fragments are re-added.
    671  */
    672747
    673748  unalloc_cells = regfi_parse_unalloc_cells(f);
     
    712787  }
    713788
    714   /* TODO: Carve SKs */
    715789  /* Carve any SK records */
    716790  ret = extractSKs(f, unalloc_cells, unalloc_sks);
     
    721795  }
    722796
    723 
    724   for(i=0; i < range_list_size(unalloc_keys); i++)
     797  /* Now that we're done carving, associate recovered keys with parents,
     798   * if at all possible.
     799   */
     800  num_unalloc_keys = range_list_size(unalloc_keys);
     801  parent_paths = (char**)malloc(sizeof(char*)*num_unalloc_keys);
     802  if(parent_paths == NULL)
     803    return 10;
     804
     805  for(i=0; i < num_unalloc_keys; i++)
    725806  {
    726807    cur_elem = range_list_get(unalloc_keys, i);
    727808    tmp_key = (REGF_NK_REC*)cur_elem->data;
    728809
    729     printKey(f, tmp_key, "");
    730 
    731     for(j=0; j < tmp_key->num_values; j++)
    732     {
    733       tmp_value = tmp_key->values[j];
    734       if(tmp_value != NULL)
    735         printValue(f, tmp_value, tmp_key->keyname);
    736     }
    737   }
     810    if(tmp_key == NULL)
     811      return 20;
     812   
     813    parent_paths[i] = getParentPath(f, tmp_key);
     814    if(parent_paths[i] == NULL)
     815      return 20;
     816  }
     817 
     818  /* Now start the output */
     819
     820  for(i=0; i < num_unalloc_keys; i++)
     821  {
     822    cur_elem = range_list_get(unalloc_keys, i);
     823    tmp_key = (REGF_NK_REC*)cur_elem->data;
     824
     825    printKey(f, tmp_key, parent_paths[i]);
     826    if(tmp_key->num_values > 0)
     827    {
     828      tmp_name = quote_string(tmp_key->keyname, key_special_chars);
     829      tmp_path = (char*)malloc(strlen(parent_paths[i])+strlen(tmp_name)+2);
     830      if(tmp_path == NULL)
     831        return 10;
     832      sprintf(tmp_path, "%s/%s", parent_paths[i], tmp_name);
     833      for(j=0; j < tmp_key->num_values; j++)
     834      {
     835        tmp_value = tmp_key->values[j];
     836        if(tmp_value != NULL)
     837          printValue(f, tmp_value, tmp_path);
     838      }
     839      free(tmp_path);
     840      free(tmp_name);
     841      free(parent_paths[i]);
     842    }
     843  }
     844  free(parent_paths);
    738845
    739846  /* Print out orphaned values */
Note: See TracChangeset for help on using the changeset viewer.