Changeset 139
- Timestamp:
- 02/08/09 22:06:16 (16 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfi.h
r138 r139 82 82 #define REGFI_OFFSET_NONE 0xffffffff 83 83 84 /* XXX: This is totally arbitrary right now. */ 85 #define REGFI_MAX_SUBKEY_DEPTH 255 86 84 87 /* Header sizes and magic number lengths for various records */ 85 88 #define REGFI_REGF_MAGIC_SIZE 4 … … 171 174 typedef struct 172 175 { 173 uint32 nk_off; 176 /* Virtual offset of NK record or additional subkey list, 177 * depending on this list's type. 178 */ 179 uint32 offset; 180 174 181 uint32 hash; 175 182 } REGFI_SUBKEY_LIST_ELEM; … … 178 185 typedef struct 179 186 { 180 uint32 offset; /* Real offset of this record's cell in the file */ 181 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 182 uint32 num_keys; 187 /* Real offset of this record's cell in the file */ 188 uint32 offset; 189 190 uint32 cell_size; 191 192 /* Number of immediate children */ 193 uint32 num_children; 194 195 /* Total number of keys referenced by this list and it's children */ 196 uint32 num_keys; 197 183 198 REGFI_SUBKEY_LIST_ELEM* elements; 184 185 199 uint8 magic[REGFI_CELL_MAGIC_SIZE]; 200 201 /* Set if the magic indicates this subkey list points to child subkey lists */ 202 bool recursive_type; 186 203 } REGFI_SUBKEY_LIST; 187 204 … … 427 444 uint32 max_size, bool strict); 428 445 446 REGFI_SUBKEY_LIST* regfi_parse_subkeylist(REGFI_FILE* file, uint32 offset, 447 uint32 max_size, bool strict); 448 429 449 REGFI_VK_REC* regfi_parse_vk(REGFI_FILE* file, uint32 offset, 430 450 uint32 max_size, bool strict); … … 467 487 REGFI_SUBKEY_LIST** lists, 468 488 bool strict); 489 REGFI_SUBKEY_LIST* regfi_load_subkeylist_aux(REGFI_FILE* file, uint32 offset, 490 uint32 max_size, bool strict, 491 uint8 depth_left); 469 492 void regfi_add_message(REGFI_FILE* file, uint16 msg_type, 470 493 const char* fmt, ...); -
trunk/lib/regfi.c
r138 r139 508 508 509 509 510 511 /****************************************************************************** 512 ******************************************************************************/ 513 REGFI_SUBKEY_LIST* regfi_load_subkeylist(REGFI_FILE* file, uint32 offset, 514 uint32 num_keys, uint32 max_size, 515 bool strict) 516 { 517 REGFI_SUBKEY_LIST* ret_val; 518 519 ret_val = regfi_load_subkeylist_aux(file, offset, max_size, strict, 520 REGFI_MAX_SUBKEY_DEPTH); 521 522 if(num_keys != ret_val->num_keys) 523 { 524 /* Not sure which should be authoritative, the number from the 525 * NK record, or the number in the subkey list. Just emit a warning for 526 * now if they don't match. 527 */ 528 regfi_add_message(file, REGFI_MSG_WARN, "Number of subkeys listed in parent" 529 " (%d) did not match number found in subkey list/tree (%d)" 530 " while parsing subkey list/tree at offset 0x%.8X.", 531 num_keys, ret_val->num_keys, offset); 532 } 533 534 return ret_val; 535 } 536 537 538 /****************************************************************************** 539 ******************************************************************************/ 540 REGFI_SUBKEY_LIST* regfi_load_subkeylist_aux(REGFI_FILE* file, uint32 offset, 541 uint32 max_size, bool strict, 542 uint8 depth_left) 543 { 544 REGFI_SUBKEY_LIST* ret_val; 545 REGFI_SUBKEY_LIST** sublists; 546 REGFI_HBIN* sublist_hbin; 547 uint32 i, num_sublists, off, max_length; 548 549 if(depth_left == 0) 550 { 551 regfi_add_message(file, REGFI_MSG_WARN, "Maximum depth reached" 552 " while parsing subkey list/tree at offset 0x%.8X.", 553 offset); 554 return NULL; 555 } 556 557 ret_val = regfi_parse_subkeylist(file, offset, max_size, strict); 558 if(ret_val == NULL) 559 return NULL; 560 561 if(ret_val->recursive_type) 562 { 563 num_sublists = ret_val->num_children; 564 sublists = (REGFI_SUBKEY_LIST**)zalloc(num_sublists 565 * sizeof(REGFI_SUBKEY_LIST*)); 566 for(i=0; i < num_sublists; i++) 567 { 568 off = ret_val->elements[i].offset + REGFI_REGF_SIZE; 569 sublist_hbin = regfi_lookup_hbin(file, ret_val->elements[i].offset); 570 if(sublist_hbin == NULL) 571 sublists[i] = NULL; 572 else 573 { 574 max_length = sublist_hbin->block_size + sublist_hbin->file_off - off; 575 sublists[i] = regfi_load_subkeylist_aux(file, off, max_length, strict, 576 depth_left-1); 577 } 578 } 579 free(ret_val); 580 581 return regfi_merge_subkeylists(num_sublists, sublists, strict); 582 } 583 584 return ret_val; 585 } 586 587 588 /****************************************************************************** 589 ******************************************************************************/ 590 REGFI_SUBKEY_LIST* regfi_parse_subkeylist(REGFI_FILE* file, uint32 offset, 591 uint32 max_size, bool strict) 592 { 593 REGFI_SUBKEY_LIST* ret_val; 594 uint32 i, cell_length, length, elem_size; 595 uint8* elements; 596 uint8 buf[REGFI_SUBKEY_LIST_MIN_LEN]; 597 bool unalloc; 598 bool recursive_type; 599 600 if(!regfi_parse_cell(file->fd, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN, 601 &cell_length, &unalloc)) 602 { 603 regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell while " 604 "parsing subkey-list at offset 0x%.8X.", offset); 605 return NULL; 606 } 607 608 if(cell_length > max_size) 609 { 610 regfi_add_message(file, REGFI_MSG_WARN, "Cell size longer than max_size" 611 " while parsing subkey-list at offset 0x%.8X.", offset); 612 if(strict) 613 return NULL; 614 cell_length = max_size & 0xFFFFFFF8; 615 } 616 617 recursive_type = false; 618 if(buf[0] == 'r' && buf[1] == 'i') 619 { 620 recursive_type = true; 621 elem_size = sizeof(uint32); 622 } 623 else if(buf[0] == 'l' && buf[1] == 'i') 624 elem_size = sizeof(uint32); 625 else if((buf[0] == 'l') && (buf[1] == 'f' || buf[1] == 'h')) 626 elem_size = sizeof(REGFI_SUBKEY_LIST_ELEM); 627 else 628 { 629 regfi_add_message(file, REGFI_MSG_ERROR, "Unknown magic number" 630 " (0x%.2X, 0x%.2X) encountered while parsing" 631 " subkey-list at offset 0x%.8X.", buf[0], buf[1], offset); 632 return NULL; 633 } 634 635 ret_val = (REGFI_SUBKEY_LIST*)zalloc(sizeof(REGFI_SUBKEY_LIST)); 636 if(ret_val == NULL) 637 return NULL; 638 639 ret_val->offset = offset; 640 ret_val->cell_size = cell_length; 641 ret_val->magic[0] = buf[0]; 642 ret_val->magic[1] = buf[1]; 643 ret_val->recursive_type = recursive_type; 644 ret_val->num_children = SVAL(buf, 0x2); 645 646 if(!recursive_type) 647 ret_val->num_keys = ret_val->num_children; 648 649 length = elem_size*ret_val->num_children; 650 if(cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32) < length) 651 { 652 regfi_add_message(file, REGFI_MSG_WARN, "Number of elements too large for" 653 " cell while parsing subkey-list at offset 0x%.8X.", 654 offset); 655 if(strict) 656 { 657 free(ret_val); 658 return NULL; 659 } 660 length = cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32); 661 } 662 663 ret_val->elements 664 = (REGFI_SUBKEY_LIST_ELEM*)zalloc(ret_val->num_children 665 * sizeof(REGFI_SUBKEY_LIST_ELEM)); 666 if(ret_val->elements == NULL) 667 { 668 free(ret_val); 669 return NULL; 670 } 671 672 elements = (uint8*)zalloc(length); 673 if(elements == NULL) 674 { 675 free(ret_val->elements); 676 free(ret_val); 677 return NULL; 678 } 679 680 if(regfi_read(file->fd, elements, &length) != 0 681 || length != elem_size*ret_val->num_children) 682 { 683 free(ret_val->elements); 684 free(ret_val); 685 return NULL; 686 } 687 688 if(elem_size == sizeof(uint32)) 689 { 690 for (i=0; i < ret_val->num_children; i++) 691 { 692 ret_val->elements[i].offset = IVAL(elements, i*elem_size); 693 ret_val->elements[i].hash = 0; 694 } 695 } 696 else 697 { 698 for (i=0; i < ret_val->num_children; i++) 699 { 700 ret_val->elements[i].offset = IVAL(elements, i*elem_size); 701 ret_val->elements[i].hash = IVAL(elements, i*elem_size+4); 702 } 703 } 704 free(elements); 705 706 return ret_val; 707 } 708 709 510 710 /******************************************************************* 511 711 *******************************************************************/ 512 712 REGFI_SUBKEY_LIST* regfi_merge_subkeylists(uint16 num_lists, 513 REGFI_SUBKEY_LIST** lists,514 bool strict)713 REGFI_SUBKEY_LIST** lists, 714 bool strict) 515 715 { 516 716 uint32 i,j,k; … … 528 728 for(i=0; i < num_lists; i++) 529 729 { 530 if(lists[i] == NULL) 531 { 532 free(ret_val); 533 free(lists); 534 return NULL; 535 } 536 ret_val->num_keys += lists[i]->num_keys; 537 } 538 730 if(lists[i] != NULL) 731 ret_val->num_keys += lists[i]->num_children; 732 } 733 ret_val->num_children = ret_val->num_keys; 734 539 735 if(ret_val->num_keys > 0) 540 736 { … … 546 742 if(ret_val->elements != NULL) 547 743 { 548 for(i=0; i<num_lists; i++) 549 for(j=0; j<lists[i]->num_keys; j++) 744 for(i=0; i < num_lists; i++) 745 { 746 if(lists[i] != NULL) 550 747 { 551 ret_val->elements[k].hash=lists[i]->elements[j].hash; 552 ret_val->elements[k++].nk_off=lists[i]->elements[j].nk_off; 748 for(j=0; j < lists[i]->num_keys; j++) 749 { 750 ret_val->elements[k].hash=lists[i]->elements[j].hash; 751 ret_val->elements[k++].offset=lists[i]->elements[j].offset; 752 } 553 753 } 754 } 554 755 } 555 756 } … … 561 762 return ret_val; 562 763 } 563 564 565 566 /*******************************************************************567 *******************************************************************/568 REGFI_SUBKEY_LIST* regfi_load_subkeylist(REGFI_FILE* file, uint32 offset,569 uint32 num_keys, uint32 max_size,570 bool strict)571 {572 REGFI_SUBKEY_LIST* ret_val;573 REGFI_SUBKEY_LIST** sublists;574 REGFI_HBIN* sublist_hbin;575 uint32 i, cell_length, length, num_sublists, off, max_length, elem_size;576 uint8* hashes;577 uint8 buf[REGFI_SUBKEY_LIST_MIN_LEN];578 bool unalloc;579 580 if(!regfi_parse_cell(file->fd, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN,581 &cell_length, &unalloc))582 return NULL;583 584 if(cell_length > max_size)585 {586 if(strict)587 return NULL;588 cell_length = max_size & 0xFFFFFFF8;589 }590 591 if(buf[0] == 'r' && buf[1] == 'i')592 {593 num_sublists = SVAL(buf, 0x2);594 595 /* XXX: check cell_length vs num_sublists vs max_length */596 length = num_sublists*sizeof(uint32);597 hashes = (uint8*)zalloc(length);598 if(hashes == NULL)599 return NULL;600 601 if(regfi_read(file->fd, hashes, &length) != 0602 || length != num_sublists*sizeof(uint32))603 {604 free(hashes);605 return NULL;606 }607 608 sublists = (REGFI_SUBKEY_LIST**)zalloc(num_sublists*sizeof(REGFI_SUBKEY_LIST*));609 for(i=0; i < num_sublists; i++)610 {611 off = IVAL(hashes, i*4)+REGFI_REGF_SIZE;612 sublist_hbin = regfi_lookup_hbin(file, IVAL(hashes, i*4));613 max_length = sublist_hbin->block_size + sublist_hbin->file_off - off;614 615 /* XXX: Need to add a recursion depth limit of some kind. */616 sublists[i] = regfi_load_subkeylist(file, off, 0, max_length, strict);617 }618 free(hashes);619 620 return regfi_merge_subkeylists(num_sublists, sublists, strict);621 }622 623 if(buf[0] == 'l' && buf[1] == 'i')624 elem_size = sizeof(uint32);625 else if((buf[0] == 'l') && (buf[1] == 'f' || buf[1] == 'h'))626 elem_size = sizeof(REGFI_SUBKEY_LIST_ELEM);627 else628 {629 /* fprintf(stderr, "DEBUG: lf->header=%c%c\n", buf[0], buf[1]);*/630 return NULL;631 }632 633 ret_val = (REGFI_SUBKEY_LIST*)zalloc(sizeof(REGFI_SUBKEY_LIST));634 if(ret_val == NULL)635 return NULL;636 637 ret_val->offset = offset;638 ret_val->cell_size = cell_length;639 ret_val->magic[0] = buf[0];640 ret_val->magic[1] = buf[1];641 642 ret_val->num_keys = SVAL(buf, 0x2);643 if(num_keys != ret_val->num_keys)644 {645 /* Not sure which should be authoritative, the number from the646 * NK record, or the number in the subkey list. Go with the larger647 * of the two to ensure all keys are found, since in 'ri' records,648 * there is no authoritative parent count for a leaf subkey list.649 * Note the length checks on the cell later ensure that there won't650 * be any critical errors.651 */652 if(num_keys < ret_val->num_keys)653 num_keys = ret_val->num_keys;654 else655 ret_val->num_keys = num_keys;656 }657 658 if(cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32)659 < ret_val->num_keys*elem_size)660 {661 free(ret_val);662 return NULL;663 }664 665 length = elem_size*ret_val->num_keys;666 ret_val->elements667 = (REGFI_SUBKEY_LIST_ELEM*)zalloc(ret_val->num_keys668 * sizeof(REGFI_SUBKEY_LIST_ELEM));669 if(ret_val->elements == NULL)670 {671 free(ret_val);672 return NULL;673 }674 675 hashes = (uint8*)zalloc(length);676 if(hashes == NULL)677 {678 free(ret_val->elements);679 free(ret_val);680 return NULL;681 }682 683 if(regfi_read(file->fd, hashes, &length) != 0684 || length != elem_size*ret_val->num_keys)685 {686 free(ret_val->elements);687 free(ret_val);688 return NULL;689 }690 691 if(buf[0] == 'l' && buf[1] == 'i')692 {693 for (i=0; i < ret_val->num_keys; i++)694 {695 ret_val->elements[i].nk_off = IVAL(hashes, i*elem_size);696 ret_val->elements[i].hash = 0;697 }698 }699 else700 {701 for (i=0; i < ret_val->num_keys; i++)702 {703 ret_val->elements[i].nk_off = IVAL(hashes, i*elem_size);704 ret_val->elements[i].hash = IVAL(hashes, i*elem_size+4);705 }706 }707 free(hashes);708 709 return ret_val;710 }711 712 764 713 765 … … 1504 1556 return NULL; 1505 1557 1506 nk_offset = i->cur_key->subkeys->elements[i->cur_subkey]. nk_off;1558 nk_offset = i->cur_key->subkeys->elements[i->cur_subkey].offset; 1507 1559 1508 1560 return regfi_load_key(i->f, nk_offset+REGFI_REGF_SIZE, true);
Note: See TracChangeset
for help on using the changeset viewer.