- Timestamp:
- 04/03/08 19:22:39 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/regfi.c
r103 r104 476 476 477 477 478 478 479 /******************************************************************* 479 480 *******************************************************************/ 480 static bool prs_hash_rec( const char *desc, prs_struct *ps, int depth, REGF_HASH_REC *hash ) 481 { 482 depth++; 483 484 if ( !prs_uint32( "nk_off", ps, depth, &hash->nk_off )) 485 return false; 486 if ( !prs_uint8s("keycheck", ps, depth, hash->keycheck, sizeof( hash->keycheck )) ) 487 return false; 488 489 return true; 490 } 491 492 493 /******************************************************************* 494 *******************************************************************/ 495 static bool hbin_prs_lf_records(const char *desc, REGF_HBIN *hbin, 496 int depth, REGF_NK_REC *nk) 497 { 498 int i; 499 REGF_LF_REC *lf = &nk->subkeys; 500 uint32 data_size, start_off, end_off; 501 502 depth++; 503 504 /* check if we have anything to do first */ 505 506 if ( nk->num_subkeys == 0 ) 507 return true; 508 509 /* move to the LF record */ 510 511 if ( !prs_set_offset( &hbin->ps, nk->subkeys_off + HBIN_MAGIC_SIZE - hbin->first_hbin_off ) ) 512 return false; 513 514 /* backup and get the data_size */ 515 516 if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) ) 517 return false; 518 start_off = hbin->ps.data_offset; 519 if ( !prs_uint32( "cell_size", &hbin->ps, depth, &lf->cell_size )) 520 return false; 521 522 if(!prs_uint8s("header", &hbin->ps, depth, 523 lf->header, sizeof(lf->header))) 524 return false; 525 526 /*fprintf(stdout, "DEBUG: lf->header=%c%c\n", lf->header[0], lf->header[1]);*/ 527 528 if ( !prs_uint16( "num_keys", &hbin->ps, depth, &lf->num_keys)) 529 return false; 530 531 if ( hbin->ps.io ) { 532 if ( !(lf->hashes = (REGF_HASH_REC*)zcalloc(sizeof(REGF_HASH_REC), lf->num_keys )) ) 533 return false; 534 } 535 536 for ( i=0; i<lf->num_keys; i++ ) { 537 if ( !prs_hash_rec( "hash_rec", &hbin->ps, depth, &lf->hashes[i] ) ) 538 return false; 539 } 540 541 end_off = hbin->ps.data_offset; 542 543 /* data_size must be divisible by 8 and large enough to hold the original record */ 544 545 data_size = ((start_off - end_off) & 0xfffffff8 ); 546 /* if ( data_size > lf->cell_size )*/ 547 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->cell_size));*/ 548 549 return true; 481 REGF_HASH_LIST* regfi_load_hashlist(REGF_FILE* file, uint32 offset, 482 uint32 num_keys, bool strict) 483 { 484 REGF_HASH_LIST* ret_val; 485 uint32 i, cell_length, length; 486 uint8* hashes; 487 uint8 buf[REGFI_HASH_LIST_MIN_LENGTH]; 488 bool unalloc; 489 490 if(!regfi_parse_cell(file->fd, offset, buf, REGFI_HASH_LIST_MIN_LENGTH, 491 &cell_length, &unalloc)) 492 return NULL; 493 494 ret_val = (REGF_HASH_LIST*)zalloc(sizeof(REGF_HASH_LIST)); 495 if(ret_val == NULL) 496 return NULL; 497 498 ret_val->offset = offset; 499 ret_val->cell_size = cell_length; 500 501 if((buf[0] != 'l' || buf[1] != 'f') && (buf[0] != 'l' || buf[1] != 'h') 502 && (buf[0] != 'r' || buf[1] != 'i')) 503 { 504 /*printf("DEBUG: lf->header=%c%c\n", buf[0], buf[1]);*/ 505 free(ret_val); 506 return NULL; 507 } 508 509 if(buf[0] == 'r' && buf[1] == 'i') 510 { 511 fprintf(stderr, "WARNING: ignoring encountered \"ri\" record.\n"); 512 free(ret_val); 513 return NULL; 514 } 515 516 ret_val->magic[0] = buf[0]; 517 ret_val->magic[1] = buf[1]; 518 519 ret_val->num_keys = SVAL(buf, 0x2); 520 if(num_keys != ret_val->num_keys) 521 { 522 if(strict) 523 { 524 free(ret_val); 525 return NULL; 526 } 527 /* TODO: Not sure which should be authoritative, the number from the 528 * NK record, or the number in the hash list. Go with the larger 529 * of the two to ensure all keys are found. Note the length checks 530 * on the cell later ensure that there won't be any critical errors. 531 */ 532 if(num_keys < ret_val->num_keys) 533 num_keys = ret_val->num_keys; 534 else 535 ret_val->num_keys = num_keys; 536 } 537 538 if(cell_length - REGFI_HASH_LIST_MIN_LENGTH - sizeof(uint32) 539 < ret_val->num_keys*sizeof(REGF_HASH_LIST_ELEM)) 540 return NULL; 541 542 length = sizeof(REGF_HASH_LIST_ELEM)*ret_val->num_keys; 543 ret_val->hashes = (REGF_HASH_LIST_ELEM*)zalloc(length); 544 if(ret_val->hashes == NULL) 545 { 546 free(ret_val); 547 return NULL; 548 } 549 550 hashes = (uint8*)zalloc(length); 551 if(hashes == NULL) 552 { 553 free(ret_val->hashes); 554 free(ret_val); 555 return NULL; 556 } 557 558 if(regfi_read(file->fd, hashes, &length) != 0 559 || length != sizeof(REGF_HASH_LIST_ELEM)*ret_val->num_keys) 560 { 561 free(ret_val->hashes); 562 free(ret_val); 563 return NULL; 564 } 565 566 for (i=0; i < ret_val->num_keys; i++) 567 { 568 ret_val->hashes[i].nk_off = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM)); 569 ret_val->hashes[i].hash = IVAL(hashes, i*sizeof(REGF_HASH_LIST_ELEM)+4); 570 } 571 free(hashes); 572 573 return ret_val; 550 574 } 551 575 … … 782 806 } 783 807 } 784 785 if (!hbin_prs_lf_records("lf_rec", sub_hbin, depth, nk)) 786 return NULL; 808 809 nk->subkeys = regfi_load_hashlist(file, nk->subkeys_off + REGF_BLOCKSIZE, 810 nk->num_subkeys, true); 811 if (nk->subkeys == NULL) 812 { 813 /* TODO: temporary hack to get around 'ri' records */ 814 nk->num_subkeys = 0; 815 } 787 816 } 788 817 … … 1203 1232 return NULL; 1204 1233 1205 nk_offset = i->cur_key->subkeys .hashes[i->cur_subkey].nk_off;1234 nk_offset = i->cur_key->subkeys->hashes[i->cur_subkey].nk_off; 1206 1235 1207 1236 /* find the HBIN block which should contain the nk record */ … … 1211 1240 /* XXX: should print out some kind of error message every time here */ 1212 1241 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing offset [0x%x]\n", 1213 i->cur_key->subkeys .hashes[i->cur_subkey].nk_off));*/1242 i->cur_key->subkeys->hashes[i->cur_subkey].nk_off));*/ 1214 1243 return NULL; 1215 1244 }
Note: See TracChangeset
for help on using the changeset viewer.