- Timestamp:
- 11/22/09 19:47:22 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/reglookup-recover.c
r152 r157 258 258 { 259 259 void_stack* path_stack = void_stack_new(REGFI_MAX_DEPTH); 260 const REGFI_HBIN* hbin;261 260 REGFI_NK_REC* cur_ancestor; 262 261 char* ret_val; 263 uint32 virt_offset, i, stack_size, ret_val_size, ret_val_used ;264 uint32 max_length;262 uint32 virt_offset, i, stack_size, ret_val_size, ret_val_used, offset; 263 int32 max_size; 265 264 REGFI_BUFFER* path_element; 266 265 … … 269 268 ret_val_size = 1; /* NUL */ 270 269 while(virt_offset != REGFI_OFFSET_NONE) 271 { 272 hbin = regfi_lookup_hbin(f, virt_offset); 273 if(hbin == NULL) 270 { 271 offset = virt_offset+REGFI_REGF_SIZE; 272 max_size = regfi_calc_maxsize(f, offset); 273 if(max_size < 0) 274 274 virt_offset = REGFI_OFFSET_NONE; 275 275 else 276 276 { 277 max_length = hbin->block_size + hbin->file_off 278 - (virt_offset+REGFI_REGF_SIZE); 279 cur_ancestor = regfi_parse_nk(f, virt_offset+REGFI_REGF_SIZE, 280 max_length, true); 277 cur_ancestor = regfi_parse_nk(f, offset, max_size, true); 281 278 printMsgs(f); 282 279 … … 456 453 457 454 458 int extractDataCells(REGFI_FILE* f ,455 int extractDataCells(REGFI_FILE* file, 459 456 range_list* unalloc_cells, 460 457 range_list* unalloc_values) … … 462 459 const range_list_element* cur_elem; 463 460 REGFI_VK_REC* vk; 464 const REGFI_HBIN* hbin;461 range_list* bd_cells; 465 462 REGFI_BUFFER data; 466 uint32 i, off, data_offset, data_maxsize; 463 uint32 i, j, offset, cell_length, length; 464 int32 max_size; 465 bool unalloc; 466 467 bd_cells = range_list_new(); 468 if(bd_cells == NULL) 469 return 10; 467 470 468 471 for(i=0; i<range_list_size(unalloc_values); i++) … … 471 474 vk = (REGFI_VK_REC*)cur_elem->data; 472 475 if(vk == NULL) 473 return 40;474 475 if(vk->data_size == 0)476 477 else478 { 479 off = vk->data_off+REGFI_REGF_SIZE;476 return 11; 477 478 length = vk->data_size; 479 vk->data = NULL; 480 if(vk->data_size != 0) 481 { 482 offset = vk->data_off+REGFI_REGF_SIZE; 480 483 481 484 if(vk->data_in_offset) 485 data = regfi_parse_little_data(file, vk->data_off, 486 length, false); 487 else 482 488 { 483 data = regfi_load_data(f, vk->type, vk->data_off, 484 vk->data_size, 4, 485 vk->data_in_offset, false); 489 max_size = regfi_calc_maxsize(file, offset); 490 if(max_size >= 0 491 && regfi_parse_cell(file->fd, offset, NULL, 0, 492 &cell_length, &unalloc) 493 && (cell_length & 0x00000007) == 0 494 && cell_length <= max_size) 495 { 496 if(cell_length - 4 < length) 497 { 498 /* Multi-cell "big data" */ 499 500 /* XXX: All big data records thus far have been 16 bytes long. 501 * Should we check for this precise size instead of just 502 * relying upon the above check? 503 */ 504 if (file->major_version >= 1 && file->minor_version >= 5) 505 { 506 /* Attempt to parse a big data record */ 507 data = regfi_load_big_data(file, offset, length, 508 cell_length, bd_cells, false); 509 510 /* XXX: if this turns out NULL, should fall back to truncating cell */ 511 if(data.buf != NULL) 512 { 513 for(j=0; j<range_list_size(bd_cells); j++) 514 { 515 cur_elem = range_list_get(bd_cells, j); 516 if(cur_elem == NULL) 517 return 20; 518 if(!range_list_has_range(unalloc_cells, 519 cur_elem->offset, 520 cur_elem->length)) 521 { 522 fprintf(stderr, 523 "WARN: Successfully parsed big data at offset" 524 " 0x%.8X was rejected because some substructure" 525 " (offset=0x%.8X) is allocated or used in other" 526 " recovered structures.\n", 527 offset, cur_elem->offset); 528 talloc_free(data.buf); 529 data.buf = NULL; 530 data.len = 0; 531 break; 532 } 533 } 534 535 if(data.buf != NULL) 536 { 537 for(j=0; j<range_list_size(bd_cells); j++) 538 { 539 cur_elem = range_list_get(bd_cells, j); 540 if(cur_elem == NULL) 541 return 21; 542 543 if(!removeRange(unalloc_cells, 544 cur_elem->offset, 545 cur_elem->length)) 546 { return 22; } 547 } 548 } 549 } 550 551 } 552 else 553 { 554 fprintf(stderr, 555 "WARN: Data length (0x%.8X)" 556 " larger than remaining cell length (0x%.8X)" 557 " while parsing data record at offset 0x%.8X." 558 " Truncating...\n", 559 length, cell_length - 4, offset); 560 length = cell_length - 4; 561 } 562 } 563 564 /* Typical 1-cell data */ 565 if(range_list_has_range(unalloc_cells, offset, length)) 566 { 567 data = regfi_parse_data(file, offset, length, false); 568 if(data.buf != NULL) 569 if(!removeRange(unalloc_cells, offset, length)) 570 return 30; 571 } 572 } 573 486 574 vk->data = data.buf; 487 575 vk->data_size = data.len; 488 576 } 489 else if(range_list_has_range(unalloc_cells, off, vk->data_size)) 490 { 491 hbin = regfi_lookup_hbin(f, vk->data_off); 492 if(hbin) 493 { 494 data_offset = vk->data_off+REGFI_REGF_SIZE; 495 data_maxsize = hbin->block_size + hbin->file_off - data_offset; 496 data = regfi_load_data(f, vk->type, data_offset, 497 vk->data_size, data_maxsize, 498 vk->data_in_offset, false); 499 vk->data = data.buf; 500 vk->data_size = data.len; 501 502 if(vk->data != NULL) 503 { 504 /* XXX: The following may not make sense now in light of big data 505 * records. 506 */ 507 /* XXX: This strict checking prevents partial recovery of data 508 * cells. Also, see code for regfi_load_data and note that 509 * lengths indicated in VK records are sometimes just plain 510 * wrong. Need a feedback mechanism to be more fuzzy with 511 * data cell lengths and the ranges removed. 512 * 513 * The introduction of REGFI_BUFFER in regfi_load_data has 514 * fixed some of this. Should review again with respect to 515 * the other issues mentioned above though. 516 */ 517 /* A data record was recovered. Remove from unalloc_cells. */ 518 if(!removeRange(unalloc_cells, off, vk->data_size)) 519 return 50; 520 } 521 } 522 else 523 vk->data = NULL; 524 } 525 } 526 } 527 577 } 578 } 579 580 range_list_free(bd_cells); 528 581 return 0; 529 582 } … … 590 643 REGFI_NK_REC* nk; 591 644 REGFI_VK_REC* vk; 592 const REGFI_HBIN* hbin;593 645 const range_list_element* cur_elem; 594 uint32 i, j, num_keys, off, values_length, max_length; 646 uint32 i, j, num_keys, off, values_length; 647 int32 max_size; 595 648 596 649 num_keys=range_list_size(unalloc_keys); … … 604 657 if(nk->num_values && (nk->values_off!=REGFI_OFFSET_NONE)) 605 658 { 606 hbin = regfi_lookup_hbin(f, nk->values_off);607 608 if( hbin != NULL)659 off = nk->values_off + REGFI_REGF_SIZE; 660 max_size = regfi_calc_maxsize(f, off); 661 if(max_size >= 0) 609 662 { 610 off = nk->values_off + REGFI_REGF_SIZE;611 max_length = hbin->block_size + hbin->file_off - off;612 663 nk->values = regfi_load_valuelist(f, off, nk->num_values, 613 max_ length, false);664 max_size, false); 614 665 if(nk->values != NULL && nk->values->elements != NULL) 615 666 {
Note: See TracChangeset
for help on using the changeset viewer.