Changeset 127
- Timestamp:
- 09/01/08 19:20:50 (16 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfi.h
r126 r127 86 86 #define REGFI_VK_MIN_LENGTH 0x14 87 87 #define REGFI_SK_MIN_LENGTH 0x14 88 #define REGFI_ HASH_LIST_MIN_LENGTH0x488 #define REGFI_SUBKEY_LIST_MIN_LEN 0x4 89 89 90 90 /* Constants used for validation */ … … 138 138 139 139 140 /* HashList -- list of key offsets and hashed names for consistency */140 /* Subkey List -- list of key offsets and hashed names for consistency */ 141 141 typedef struct 142 142 { 143 143 uint32 nk_off; 144 144 uint32 hash; 145 } REGF_ HASH_LIST_ELEM;145 } REGF_SUBKEY_LIST_ELEM; 146 146 147 147 … … 150 150 uint32 offset; /* Real offset of this record's cell in the file */ 151 151 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 152 REGF_HBIN* hbin; /* pointer to HBIN record (in memory) containing 153 * this nk record 154 */ 155 uint32 hbin_off; /* offset from beginning of this hbin block */ 156 REGF_HASH_LIST_ELEM* hashes; 152 uint32 num_keys; 153 REGF_SUBKEY_LIST_ELEM* elements; 157 154 158 155 uint8 magic[REC_HDR_SIZE]; 159 uint16 num_keys; 160 } REGF_HASH_LIST; 156 } REGF_SUBKEY_LIST; 161 157 162 158 … … 219 215 /* link in the other records here */ 220 216 REGF_VK_REC** values; 221 REGF_ HASH_LIST* subkeys;217 REGF_SUBKEY_LIST* subkeys; 222 218 223 219 /* header information */ … … 246 242 /* children */ 247 243 uint32 num_subkeys; 248 uint32 subkeys_off; /* hash records that point to NK records */244 uint32 subkeys_off; /* offset of subkey list that points to NK records */ 249 245 uint32 num_values; 250 246 uint32 values_off; /* value lists which point to VK records */ 251 uint32 sk_off; /* offset to SK record */ 247 uint32 sk_off; /* offset to SK record */ 252 248 } REGF_NK_REC; 253 249 … … 347 343 const REGF_VK_REC* regfi_iterator_cur_value(REGFI_ITERATOR* i); 348 344 const REGF_VK_REC* regfi_iterator_next_value(REGFI_ITERATOR* i); 345 346 347 /********************************************************/ 348 /* Middle-layer structure caching, loading, and linking */ 349 /********************************************************/ 350 REGF_HBIN* regfi_lookup_hbin(REGF_FILE* file, uint32 offset); 351 352 REGF_NK_REC* regfi_load_key(REGF_FILE* file, uint32 offset, bool strict); 353 354 REGF_SUBKEY_LIST* regfi_load_subkeylist(REGF_FILE* file, uint32 offset, 355 uint32 num_keys, uint32 max_size, 356 bool strict); 357 358 REGF_VK_REC** regfi_load_valuelist(REGF_FILE* file, uint32 offset, 359 uint32 num_values, uint32 max_size, 360 bool strict); 361 362 REGF_SUBKEY_LIST* regfi_merge_subkeylists(uint16 num_lists, 363 REGF_SUBKEY_LIST** lists, 364 bool strict); 349 365 350 366 /************************************/ … … 370 386 uint32 max_size, bool strict); 371 387 388 REGF_VK_REC* regfi_parse_vk(REGF_FILE* file, uint32 offset, 389 uint32 max_size, bool strict); 390 391 uint8* regfi_parse_data(REGF_FILE* file, uint32 offset, 392 uint32 length, bool strict); 393 394 REGF_SK_REC* regfi_parse_sk(REGF_FILE* file, uint32 offset, uint32 max_size, bool strict); 395 396 range_list* regfi_parse_unalloc_cells(REGF_FILE* file); 397 398 bool regfi_parse_cell(int fd, uint32 offset, uint8* hdr, uint32 hdr_len, 399 uint32* cell_length, bool* unalloc); 400 401 char* regfi_parse_classname(REGF_FILE* file, uint32 offset, 402 uint16* name_length, bool strict); 403 372 404 373 405 /* Private Functions */ 374 406 REGF_NK_REC* regfi_rootkey(REGF_FILE* file); 375 407 void regfi_key_free(REGF_NK_REC* nk); 408 void regfi_subkeylist_free(REGF_SUBKEY_LIST* list); 376 409 uint32 regfi_read(int fd, uint8* buf, uint32* length); 377 410 378 411 379 380 /****************/381 /* Experimental */382 /****************/383 REGF_NK_REC* regfi_load_key(REGF_FILE* file, uint32 offset, bool strict);384 385 REGF_HASH_LIST* regfi_load_hashlist(REGF_FILE* file, uint32 offset,386 uint32 num_keys, uint32 max_size,387 bool strict);388 389 REGF_VK_REC** regfi_load_valuelist(REGF_FILE* file, uint32 offset,390 uint32 num_values, uint32 max_size,391 bool strict);392 393 REGF_VK_REC* regfi_parse_vk(REGF_FILE* file, uint32 offset,394 uint32 max_size, bool strict);395 396 uint8* regfi_parse_data(REGF_FILE* file, uint32 offset,397 uint32 length, bool strict);398 399 REGF_SK_REC* regfi_parse_sk(REGF_FILE* file, uint32 offset, uint32 max_size, bool strict);400 401 range_list* regfi_parse_unalloc_cells(REGF_FILE* file);402 403 REGF_HBIN* regfi_lookup_hbin(REGF_FILE* file, uint32 offset);404 405 bool regfi_parse_cell(int fd, uint32 offset, uint8* hdr, uint32 hdr_len,406 uint32* cell_length, bool* unalloc);407 408 char* regfi_parse_classname(REGF_FILE* file, uint32 offset,409 uint16* name_length, bool strict);410 411 412 #endif /* _REGFI_H */ -
trunk/lib/regfi.c
r126 r127 440 440 441 441 442 443 442 /******************************************************************* 444 443 *******************************************************************/ 445 REGF_HASH_LIST* regfi_load_hashlist(REGF_FILE* file, uint32 offset, 446 uint32 num_keys, uint32 max_size, 447 bool strict) 448 { 449 REGF_HASH_LIST* ret_val; 450 uint32 i, cell_length, length; 444 REGF_SUBKEY_LIST* regfi_merge_subkeylists(uint16 num_lists, 445 REGF_SUBKEY_LIST** lists, 446 bool strict) 447 { 448 uint32 i,j,k; 449 REGF_SUBKEY_LIST* ret_val = (REGF_SUBKEY_LIST*)zalloc(sizeof(REGF_SUBKEY_LIST)); 450 if(ret_val == NULL || lists == NULL) 451 return NULL; 452 453 /* Obtain total number of elements */ 454 ret_val->num_keys = 0; 455 for(i=0; i < num_lists; i++) 456 { 457 if(lists[i] == NULL) 458 { 459 ret_val->num_keys = 0; 460 break; 461 } 462 ret_val->num_keys += lists[i]->num_keys; 463 } 464 465 if(ret_val->num_keys > 0) 466 { 467 ret_val->elements = 468 (REGF_SUBKEY_LIST_ELEM*)zalloc(sizeof(REGF_SUBKEY_LIST_ELEM) 469 * ret_val->num_keys); 470 k=0; 471 if(ret_val->elements != NULL) 472 { 473 for(i=0; i<num_lists; i++) 474 for(j=0; j<lists[i]->num_keys; j++) 475 { 476 ret_val->elements[k].hash=lists[i]->elements[j].hash; 477 ret_val->elements[k++].nk_off=lists[i]->elements[j].nk_off; 478 } 479 } 480 } 481 482 for(i=0; i < num_lists; i++) 483 regfi_subkeylist_free(lists[i]); 484 free(lists); 485 486 return ret_val; 487 } 488 489 490 491 /******************************************************************* 492 *******************************************************************/ 493 REGF_SUBKEY_LIST* regfi_load_subkeylist(REGF_FILE* file, uint32 offset, 494 uint32 num_keys, uint32 max_size, 495 bool strict) 496 { 497 REGF_SUBKEY_LIST* ret_val; 498 REGF_SUBKEY_LIST** sublists; 499 REGF_HBIN* sublist_hbin; 500 uint32 i, cell_length, length, num_sublists, off, max_length; 451 501 uint8* hashes; 452 uint8 buf[REGFI_ HASH_LIST_MIN_LENGTH];502 uint8 buf[REGFI_SUBKEY_LIST_MIN_LEN]; 453 503 bool unalloc; 454 504 455 if(!regfi_parse_cell(file->fd, offset, buf, REGFI_ HASH_LIST_MIN_LENGTH,505 if(!regfi_parse_cell(file->fd, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN, 456 506 &cell_length, &unalloc)) 457 507 return NULL; 458 508 459 ret_val = (REGF_HASH_LIST*)zalloc(sizeof(REGF_HASH_LIST));460 if(ret_val == NULL)461 return NULL;462 463 ret_val->offset = offset;464 509 if(cell_length > max_size) 465 510 { … … 468 513 cell_length = max_size & 0xFFFFFFF8; 469 514 } 515 516 if(buf[0] == 'r' && buf[1] == 'i') 517 { 518 num_sublists = SVAL(buf, 0x2); 519 520 /* XXX: check cell_length vs num_sublists vs max_length */ 521 length = num_sublists*sizeof(uint32); 522 hashes = (uint8*)zalloc(length); 523 if(hashes == NULL) 524 return NULL; 525 526 if(regfi_read(file->fd, hashes, &length) != 0 527 || length != num_sublists*sizeof(uint32)) 528 { 529 free(hashes); 530 return NULL; 531 } 532 533 sublists = (REGF_SUBKEY_LIST**)zalloc(num_sublists*sizeof(REGF_SUBKEY_LIST*)); 534 for(i=0; i < num_sublists; i++) 535 { 536 off = IVAL(hashes, i*4)+REGF_BLOCKSIZE; 537 sublist_hbin = regfi_lookup_hbin(file, IVAL(hashes, i*4)); 538 max_length = sublist_hbin->block_size + sublist_hbin->file_off - off; 539 540 /* XXX: Need to add a recursion depth limit of some kind. */ 541 sublists[i] = regfi_load_subkeylist(file, off, 0, max_length, strict); 542 } 543 544 return regfi_merge_subkeylists(num_sublists, sublists, strict); 545 } 546 547 ret_val = (REGF_SUBKEY_LIST*)zalloc(sizeof(REGF_SUBKEY_LIST)); 548 if(ret_val == NULL) 549 return NULL; 550 551 ret_val->offset = offset; 470 552 ret_val->cell_size = cell_length; 471 553 472 if((buf[0] != 'l' || buf[1] != 'f') && (buf[0] != 'l' || buf[1] != 'h') 473 && (buf[0] != 'r' || buf[1] != 'i')) 554 if((buf[0] != 'l' || buf[1] != 'f') && (buf[0] != 'l' || buf[1] != 'h')) 474 555 { 475 556 /*printf("DEBUG: lf->header=%c%c\n", buf[0], buf[1]);*/ … … 478 559 } 479 560 480 if(buf[0] == 'r' && buf[1] == 'i')481 {482 fprintf(stderr, "WARNING: ignoring encountered \"ri\" record.\n");483 free(ret_val);484 return NULL;485 }486 487 561 ret_val->magic[0] = buf[0]; 488 562 ret_val->magic[1] = buf[1]; … … 491 565 if(num_keys != ret_val->num_keys) 492 566 { 493 if(strict) 494 { 495 free(ret_val); 496 return NULL; 497 } 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. 567 /* Not sure which should be authoritative, the number from the 568 * NK record, or the number in the subkey list. Go with the larger 569 * of the two to ensure all keys are found, since in 'ri' records, 570 * there is no authoritative parent count for a leaf subkey list. 571 * Note the length checks on the cell later ensure that there won't 572 * be any critical errors. 502 573 */ 503 574 if(num_keys < ret_val->num_keys) … … 507 578 } 508 579 509 if(cell_length - REGFI_ HASH_LIST_MIN_LENGTH- sizeof(uint32)510 < ret_val->num_keys*sizeof(REGF_ HASH_LIST_ELEM))511 return NULL; 512 513 length = sizeof(REGF_ HASH_LIST_ELEM)*ret_val->num_keys;514 ret_val-> hashes = (REGF_HASH_LIST_ELEM*)zalloc(length);515 if(ret_val-> hashes == NULL)580 if(cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32) 581 < ret_val->num_keys*sizeof(REGF_SUBKEY_LIST_ELEM)) 582 return NULL; 583 584 length = sizeof(REGF_SUBKEY_LIST_ELEM)*ret_val->num_keys; 585 ret_val->elements = (REGF_SUBKEY_LIST_ELEM*)zalloc(length); 586 if(ret_val->elements == NULL) 516 587 { 517 588 free(ret_val); … … 522 593 if(hashes == NULL) 523 594 { 524 free(ret_val-> hashes);595 free(ret_val->elements); 525 596 free(ret_val); 526 597 return NULL; … … 528 599 529 600 if(regfi_read(file->fd, hashes, &length) != 0 530 || length != sizeof(REGF_ HASH_LIST_ELEM)*ret_val->num_keys)531 { 532 free(ret_val-> hashes);601 || length != sizeof(REGF_SUBKEY_LIST_ELEM)*ret_val->num_keys) 602 { 603 free(ret_val->elements); 533 604 free(ret_val); 534 605 return NULL; … … 537 608 for (i=0; i < ret_val->num_keys; i++) 538 609 { 539 ret_val-> hashes[i].nk_off = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM));540 ret_val-> hashes[i].hash = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM)+4);610 ret_val->elements[i].nk_off = IVAL(hashes, i*sizeof(REGF_SUBKEY_LIST_ELEM)); 611 ret_val->elements[i].hash = IVAL(hashes, i*sizeof(REGF_SUBKEY_LIST_ELEM)+4); 541 612 } 542 613 free(hashes); … … 818 889 off = nk->subkeys_off + REGF_BLOCKSIZE; 819 890 max_length = sub_hbin->block_size + sub_hbin->file_off - off; 820 nk->subkeys = regfi_load_ hashlist(file, off, nk->num_subkeys,821 max_length, true);891 nk->subkeys = regfi_load_subkeylist(file, off, nk->num_subkeys, 892 max_length, true); 822 893 if(nk->subkeys == NULL) 823 894 { … … 1003 1074 } 1004 1075 1076 regfi_subkeylist_free(nk->subkeys); 1077 1005 1078 if(nk->keyname != NULL) 1006 1079 free(nk->keyname); … … 1011 1084 /* XXX: not freeing sec_desc because these are cached. This needs to be reviewed. */ 1012 1085 free(nk); 1086 } 1087 1088 1089 /****************************************************************************** 1090 *****************************************************************************/ 1091 void regfi_subkeylist_free(REGF_SUBKEY_LIST* list) 1092 { 1093 if(list != NULL) 1094 { 1095 free(list->elements); 1096 free(list); 1097 } 1013 1098 } 1014 1099 … … 1269 1354 return NULL; 1270 1355 1271 nk_offset = i->cur_key->subkeys-> hashes[i->cur_subkey].nk_off;1356 nk_offset = i->cur_key->subkeys->elements[i->cur_subkey].nk_off; 1272 1357 1273 1358 return regfi_load_key(i->f, nk_offset+REGF_BLOCKSIZE, true);
Note: See TracChangeset
for help on using the changeset viewer.