- Timestamp:
- 05/03/08 20:22:50 (17 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfi.h
r111 r112 213 213 /* header information */ 214 214 /* XXX: should we be looking for types other than the root key type? */ 215 uint16 key_type; 215 uint16 key_type; 216 216 uint8 magic[REC_HDR_SIZE]; 217 217 NTTIME mtime; -
trunk/lib/lru_cache.c
r111 r112 56 56 } 57 57 58 58 #if 0 59 59 static void lru_cache_print(lru_cache* ht) 60 60 { … … 95 95 } 96 96 } 97 97 #endif 98 98 99 99 lru_cache* lru_cache_create(uint32_t max_keys, uint32_t secret, bool free_data) -
trunk/src/reglookup-recover.c
r111 r112 270 270 free(quoted_buf); 271 271 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 */ 283 char* 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; 272 367 } 273 368 … … 595 690 range_list* unalloc_values; 596 691 range_list* unalloc_sks; 692 char** parent_paths; 693 char* tmp_name; 694 char* tmp_path; 597 695 REGF_NK_REC* tmp_key; 598 696 REGF_VK_REC* tmp_value; 599 uint32 argi, arge, i, j, ret ;697 uint32 argi, arge, i, j, ret, num_unalloc_keys; 600 698 /* uint32 test_offset;*/ 601 699 … … 647 745 "NK_MTIME,NK_NVAL,VK_TYPE,VK_VALUE,VK_DATA_LEN," 648 746 "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 a652 * sorted list based on offset. May also need to have them in a hash653 * 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 key659 * 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 to662 * recover VK/data records from remaining cells. Associate good VK663 * records with their full paths.664 *665 * 5. For each remaining cell or partial cell, attempt to identify the666 * record type and parse it.667 *668 * At each step, claimed cells are removed from the global cell669 * list/hash. If only part of a cell is claimed, it is removed from670 * the list and the remaining fragments are re-added.671 */672 747 673 748 unalloc_cells = regfi_parse_unalloc_cells(f); … … 712 787 } 713 788 714 /* TODO: Carve SKs */715 789 /* Carve any SK records */ 716 790 ret = extractSKs(f, unalloc_cells, unalloc_sks); … … 721 795 } 722 796 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++) 725 806 { 726 807 cur_elem = range_list_get(unalloc_keys, i); 727 808 tmp_key = (REGF_NK_REC*)cur_elem->data; 728 809 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); 738 845 739 846 /* Print out orphaned values */
Note: See TracChangeset
for help on using the changeset viewer.