- Timestamp:
- 03/28/08 20:46:37 (17 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfi.h
r99 r101 6 6 * Windows NT registry I/O library 7 7 * 8 * Copyright (C) 2005-200 7Timothy D. Morgan8 * Copyright (C) 2005-2008 Timothy D. Morgan 9 9 * Copyright (C) 2005 Gerald (Jerry) Carter 10 10 * … … 84 84 85 85 #define REGF_OFFSET_NONE 0xffffffff 86 #define REGFI_NK_MIN_LENGTH 0x50 86 #define REGFI_NK_MIN_LENGTH 0x4C 87 #define REGFI_VK_MIN_LENGTH 0x14 87 88 88 89 /* Flags for the vk records */ … … 97 98 #define NK_TYPE_NORMALKEY 0x0020 98 99 #define NK_TYPE_ROOTKEY 0x002c 100 /* TODO: Unknown type that shows up in Vista registries */ 101 #define NK_TYPE_UNKNOWN1 0x1020 99 102 100 103 #define HBIN_STORE_REF(x, y) { x->hbin = y; y->ref_count++ }; … … 152 155 typedef struct 153 156 { 157 uint32 offset; /* Real offset of this record's cell in the file */ 158 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 159 154 160 REGF_HBIN* hbin; /* pointer to HBIN record (in memory) containing 155 161 * this nk record 156 162 */ 163 uint8* data; 164 uint16 name_length; 157 165 char* valuename; 158 uint8* data;159 166 uint32 hbin_off; /* offset from beginning of this hbin block */ 160 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */161 uint32 rec_off; /* offset stored in the value list */162 167 163 168 uint32 data_size; 164 uint32 data_off; 169 uint32 data_off; /* offset of data cell (virtual) */ 165 170 uint32 type; 166 uint8 header[REC_HDR_SIZE];171 uint8 magic[REC_HDR_SIZE]; 167 172 uint16 flag; 173 uint16 unknown1; 168 174 } REGF_VK_REC; 169 175 … … 204 210 205 211 /* link in the other records here */ 206 REGF_VK_REC* values;212 REGF_VK_REC** values; 207 213 REGF_SK_REC* sec_desc; 208 214 REGF_LF_REC subkeys; … … 211 217 /* XXX: should we be looking for types other than the root key type? */ 212 218 uint16 key_type; 213 uint8 header[REC_HDR_SIZE];219 uint8 magic[REC_HDR_SIZE]; 214 220 NTTIME mtime; 215 221 uint16 name_length; … … 374 380 /****************/ 375 381 382 REGF_VK_REC* regfi_parse_vk(REGF_FILE* file, uint32 offset, 383 uint32 max_size, bool strict); 384 uint8* regfi_parse_data(REGF_FILE* file, uint32 offset, 385 uint32 length, bool strict); 386 376 387 377 388 #endif /* _REGFI_H */ -
trunk/lib/regfi.c
r99 r101 337 337 338 338 339 /***************************************************************************** 340 * This function is just like read(2), except that it continues to 341 * re-try reading from the file descriptor if EINTR or EAGAIN is received. 342 * regfi_read will attempt to read length bytes from fd and write them to buf. 343 * 344 * On success, 0 is returned. Upon failure, an errno code is returned. 345 * 346 * The number of bytes successfully read is returned through the length 347 * parameter by reference. If both the return value and length parameter are 348 * returned as 0, then EOF was encountered immediately 349 *****************************************************************************/ 350 uint32 regfi_read(int fd, uint8* buf, uint32* length) 351 { 352 uint32 rsize = 0; 353 uint32 rret = 0; 354 355 do 356 { 357 rret = read(fd, buf + rsize, *length - rsize); 358 if(rret > 0) 359 rsize += rret; 360 }while(*length - rsize > 0 361 && (rret > 0 || (rret == -1 && (errno == EAGAIN || errno == EINTR)))); 362 363 *length = rsize; 364 if (rret == -1 && errno != EINTR && errno != EAGAIN) 365 return errno; 366 367 return 0; 368 } 369 370 371 /***************************************************************************** 372 * 373 *****************************************************************************/ 374 static bool regfi_parse_cell(int fd, uint32 offset, uint8* hdr, uint32 hdr_len, 375 uint32* cell_length, bool* unalloc) 376 { 377 uint32 length; 378 int32 raw_length; 379 uint8 tmp[4]; 380 381 if(lseek(fd, offset, SEEK_SET) == -1) 382 return false; 383 384 length = 4; 385 if((regfi_read(fd, tmp, &length) != 0) || length != 4) 386 return false; 387 raw_length = IVALS(tmp, 0); 388 389 if(hdr_len > 0) 390 { 391 length = hdr_len; 392 if((regfi_read(fd, hdr, &length) != 0) || length != hdr_len) 393 return false; 394 } 395 396 if(raw_length < 0) 397 { 398 (*cell_length) = raw_length*(-1); 399 (*unalloc) = false; 400 } 401 else 402 { 403 (*cell_length) = raw_length; 404 (*unalloc) = true; 405 } 406 407 return true; 408 } 409 410 339 411 /******************************************************************* 340 Input a rando noffset and receive the correpsonding HBIN412 Input a random offset and receive the correpsonding HBIN 341 413 block for it 342 414 *******************************************************************/ … … 448 520 lf->header, sizeof(lf->header))) 449 521 return false; 450 522 523 /*fprintf(stdout, "DEBUG: lf->header=%c%c\n", lf->header[0], lf->header[1]);*/ 524 451 525 if ( !prs_uint16( "num_keys", &hbin->ps, depth, &lf->num_keys)) 452 526 return false; … … 524 598 } 525 599 526 527 /*******************************************************************528 *******************************************************************/529 static bool hbin_prs_vk_rec( const char *desc, REGF_HBIN *hbin, int depth,530 REGF_VK_REC *vk, REGF_FILE *file )531 {532 uint32 offset;533 uint16 name_length;534 prs_struct *ps = &hbin->ps;535 uint32 data_size, start_off, end_off;536 537 depth++;538 539 /* backup and get the data_size */540 541 if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) )542 return false;543 start_off = hbin->ps.data_offset;544 if ( !prs_uint32( "cell_size", &hbin->ps, depth, &vk->cell_size ))545 return false;546 547 if ( !prs_uint8s("header", ps, depth, vk->header, sizeof( vk->header )) )548 return false;549 550 if ( !hbin->ps.io )551 name_length = strlen(vk->valuename);552 553 if ( !prs_uint16( "name_length", ps, depth, &name_length ))554 return false;555 if ( !prs_uint32( "data_size", ps, depth, &vk->data_size ))556 return false;557 if ( !prs_uint32( "data_off", ps, depth, &vk->data_off ))558 return false;559 if ( !prs_uint32( "type", ps, depth, &vk->type))560 return false;561 if ( !prs_uint16( "flag", ps, depth, &vk->flag))562 return false;563 564 offset = ps->data_offset;565 offset += 2; /* skip 2 bytes */566 prs_set_offset( ps, offset );567 568 /* get the name */569 570 if ( vk->flag&VK_FLAG_NAME_PRESENT ) {571 572 if ( hbin->ps.io ) {573 if ( !(vk->valuename = (char*)zcalloc(sizeof(char), name_length+1 )))574 return false;575 }576 if ( !prs_uint8s("name", ps, depth,577 (uint8*)vk->valuename, name_length) )578 return false;579 }580 581 end_off = hbin->ps.data_offset;582 583 /* get the data if necessary */584 585 if ( vk->data_size != 0 )586 {587 /* the data is stored in the offset if the size <= 4 */588 if ( !(vk->data_size & VK_DATA_IN_OFFSET) )589 {590 REGF_HBIN *hblock = hbin;591 uint32 data_rec_size;592 593 if ( hbin->ps.io )594 {595 if ( !(vk->data = (uint8*)zcalloc(sizeof(uint8), vk->data_size) ) )596 return false;597 }598 599 /* this data can be in another hbin */600 if ( !hbin_contains_offset( hbin, vk->data_off ) )601 {602 if ( !(hblock = lookup_hbin_block( file, vk->data_off )) )603 return false;604 }605 if (!(prs_set_offset(&hblock->ps,606 (vk->data_off607 + HBIN_MAGIC_SIZE608 - hblock->first_hbin_off)609 - sizeof(uint32))))610 { return false; }611 612 if ( !hblock->ps.io )613 {614 data_rec_size = ( (vk->data_size+sizeof(uint32)) & 0xfffffff8 ) + 8;615 data_rec_size = ( data_rec_size - 1 ) ^ 0xFFFFFFFF;616 }617 if ( !prs_uint32( "data_rec_size", &hblock->ps, depth, &data_rec_size ))618 return false;619 if(!prs_uint8s("data", &hblock->ps, depth,620 vk->data, vk->data_size))621 return false;622 623 }624 else625 {626 if(!(vk->data = zcalloc(sizeof(uint8), 4)))627 return false;628 SIVAL( vk->data, 0, vk->data_off );629 }630 631 }632 633 /* data_size must be divisible by 8 and large enough to hold the original record */634 635 data_size = ((start_off - end_off ) & 0xfffffff8 );636 /* XXX: should probably print a warning here */637 /*if ( data_size != vk->cell_size )638 DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk->cell_size));*/639 640 return true;641 }642 600 643 601 … … 646 604 in the prs_struct *ps. 647 605 *******************************************************************/ 648 static bool hbin_prs_vk_records(const char *desc, REGF_HBIN *hbin,649 int depth, REGF_NK_REC *nk, REGF_FILE *file)606 static bool hbin_prs_vk_records(const char* desc, REGF_HBIN* hbin, 607 int depth, REGF_NK_REC* nk, REGF_FILE* file) 650 608 { 651 609 int i; 652 uint32 record_size; 610 uint32 record_size, vk_raw_offset, vk_offset, vk_max_length; 611 REGF_HBIN* sub_hbin; 653 612 654 613 depth++; … … 660 619 if(hbin->ps.io) 661 620 { 662 if (!(nk->values = (REGF_VK_REC* )zcalloc(sizeof(REGF_VK_REC),621 if (!(nk->values = (REGF_VK_REC**)zcalloc(sizeof(REGF_VK_REC*), 663 622 nk->num_values ))) 664 623 return false; … … 684 643 for ( i=0; i<nk->num_values; i++ ) 685 644 { 686 if ( !prs_uint32( "vk_off", &hbin->ps, depth, & nk->values[i].rec_off) )645 if ( !prs_uint32( "vk_off", &hbin->ps, depth, &vk_raw_offset) ) 687 646 return false; 688 } 689 690 for ( i=0; i<nk->num_values; i++ ) 691 { 692 REGF_HBIN *sub_hbin = hbin; 693 uint32 new_offset; 694 695 if ( !hbin_contains_offset( hbin, nk->values[i].rec_off ) ) 647 648 if(hbin_contains_offset(hbin, vk_raw_offset)) 649 sub_hbin = hbin; 650 else 696 651 { 697 sub_hbin = lookup_hbin_block( file, nk->values[i].rec_off);698 if ( !sub_hbin )652 sub_hbin = lookup_hbin_block( file, vk_raw_offset ); 653 if (!sub_hbin) 699 654 return false; 700 655 } 701 656 702 new_offset = nk->values[i].rec_off 703 + HBIN_MAGIC_SIZE 704 - sub_hbin->first_hbin_off; 705 706 if (!prs_set_offset(&sub_hbin->ps, new_offset)) 707 return false; 708 if (!hbin_prs_vk_rec("vk_rec", sub_hbin, depth, &nk->values[i], file)) 657 vk_offset = vk_raw_offset + REGF_BLOCKSIZE; 658 vk_max_length = sub_hbin->block_size - vk_offset + sizeof(uint32); 659 if((nk->values[i] = regfi_parse_vk(file, vk_offset, vk_max_length, true)) 660 == NULL) 709 661 return false; 710 662 } … … 762 714 nk_max_length = hbin->block_size - hbin->ps.data_offset + sizeof(uint32); 763 715 if ((nk = regfi_parse_nk(file, nk_cell_offset, nk_max_length, true)) == NULL) 764 return NULL; 716 { 717 fprintf(stderr, "DEBUG: regfi_parse_nk returned NULL!\n"); 718 return NULL; 719 } 765 720 766 721 /* fill in values */ … … 1040 995 for(i=0; i < nk->num_values; i++) 1041 996 { 1042 if(nk->values[i].valuename != NULL) 1043 free(nk->values[i].valuename); 1044 if(nk->values[i].data != NULL) 1045 free(nk->values[i].data); 997 if(nk->values[i]->valuename != NULL) 998 free(nk->values[i]->valuename); 999 if(nk->values[i]->data != NULL) 1000 free(nk->values[i]->data); 1001 free(nk->values[i]); 1046 1002 } 1047 1003 free(nk->values); … … 1352 1308 REGF_VK_REC* ret_val = NULL; 1353 1309 if(i->cur_value < i->cur_key->num_values) 1354 ret_val = &(i->cur_key->values[i->cur_value]);1310 ret_val = i->cur_key->values[i->cur_value]; 1355 1311 1356 1312 return ret_val; … … 1603 1559 1604 1560 1561 1605 1562 REGF_NK_REC* regfi_parse_nk(REGF_FILE* file, uint32 offset, 1606 1563 uint32 max_size, bool strict) … … 1609 1566 REGF_NK_REC* ret_val; 1610 1567 uint32 length; 1611 if(lseek(file->fd, offset, SEEK_SET) == -1) 1612 return NULL; 1613 1614 length = REGFI_NK_MIN_LENGTH; 1615 if((regfi_read(file->fd, nk_header, &length) != 0) 1616 || length != REGFI_NK_MIN_LENGTH) 1617 return NULL; 1568 uint32 cell_length; 1569 bool unalloc = false; 1570 1571 if(!regfi_parse_cell(file->fd, offset, nk_header, REGFI_NK_MIN_LENGTH, 1572 &cell_length, &unalloc)) 1573 return NULL; 1618 1574 1619 1575 /* A bit of validation before bothering to allocate memory */ 1620 if(strict && ((nk_header[0x4] != 'n') || (nk_header[0x5] != 'k'))) 1621 return NULL; 1576 if((nk_header[0x0] != 'n') || (nk_header[0x1] != 'k')) 1577 { 1578 /* TODO: deal with subkey-lists that reference other subkey-lists. */ 1579 /*fprintf(stderr, "DEBUG: magic check failed! \"%c%c\"\n", nk_header[0x0], nk_header[0x1]);*/ 1580 return NULL; 1581 } 1622 1582 1623 1583 ret_val = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC)); … … 1626 1586 1627 1587 ret_val->offset = offset; 1628 ret_val->cell_size = IVAL(nk_header, 0x0); 1588 ret_val->cell_size = cell_length; 1589 1629 1590 if(ret_val->cell_size > max_size) 1630 1591 ret_val->cell_size = max_size & 0xFFFFFFF8; … … 1636 1597 } 1637 1598 1638 ret_val->header[0] = nk_header[0x4]; 1639 ret_val->header[1] = nk_header[0x5]; 1640 ret_val->key_type = SVAL(nk_header, 0x6); 1641 if(strict && ((ret_val->key_type != NK_TYPE_NORMALKEY) 1642 && (ret_val->key_type != NK_TYPE_ROOTKEY) 1643 && (ret_val->key_type != NK_TYPE_LINKKEY))) 1599 ret_val->magic[0] = nk_header[0x0]; 1600 ret_val->magic[1] = nk_header[0x1]; 1601 ret_val->key_type = SVAL(nk_header, 0x2); 1602 if((ret_val->key_type != NK_TYPE_NORMALKEY) 1603 && (ret_val->key_type != NK_TYPE_ROOTKEY) 1604 && (ret_val->key_type != NK_TYPE_LINKKEY) 1605 && (ret_val->key_type != NK_TYPE_UNKNOWN1)) 1644 1606 { 1645 1607 free(ret_val); 1646 1608 return NULL; 1647 1609 } 1648 1649 ret_val->mtime.low = IVAL(nk_header, 0x 8);1650 ret_val->mtime.high = IVAL(nk_header, 0x C);1651 1652 ret_val->unknown1 = IVAL(nk_header, 0x 10);1653 ret_val->parent_off = IVAL(nk_header, 0x1 4);1654 ret_val->num_subkeys = IVAL(nk_header, 0x1 8);1655 ret_val->unknown2 = IVAL(nk_header, 0x1 C);1656 ret_val->subkeys_off = IVAL(nk_header, 0x 20);1657 ret_val->unknown3 = IVAL(nk_header, 0x2 4);1658 ret_val->num_values = IVAL(nk_header, 0x2 8);1659 ret_val->values_off = IVAL(nk_header, 0x2 C);1660 ret_val->sk_off = IVAL(nk_header, 0x 30);1610 1611 ret_val->mtime.low = IVAL(nk_header, 0x4); 1612 ret_val->mtime.high = IVAL(nk_header, 0x8); 1613 1614 ret_val->unknown1 = IVAL(nk_header, 0xC); 1615 ret_val->parent_off = IVAL(nk_header, 0x10); 1616 ret_val->num_subkeys = IVAL(nk_header, 0x14); 1617 ret_val->unknown2 = IVAL(nk_header, 0x18); 1618 ret_val->subkeys_off = IVAL(nk_header, 0x1C); 1619 ret_val->unknown3 = IVAL(nk_header, 0x20); 1620 ret_val->num_values = IVAL(nk_header, 0x24); 1621 ret_val->values_off = IVAL(nk_header, 0x28); 1622 ret_val->sk_off = IVAL(nk_header, 0x2C); 1661 1623 /* TODO: currently we do nothing with class names. Need to investigate. */ 1662 ret_val->classname_off = IVAL(nk_header, 0x3 4);1663 1664 ret_val->max_bytes_subkeyname = IVAL(nk_header, 0x3 8);1665 ret_val->max_bytes_subkeyclassname = IVAL(nk_header, 0x3 C);1666 ret_val->max_bytes_valuename = IVAL(nk_header, 0x 40);1667 ret_val->max_bytes_value = IVAL(nk_header, 0x4 4);1668 ret_val->unk_index = IVAL(nk_header, 0x4 8);1669 1670 ret_val->name_length = SVAL(nk_header, 0x4 C);1671 ret_val->classname_length = SVAL(nk_header, 0x4 E);1624 ret_val->classname_off = IVAL(nk_header, 0x30); 1625 1626 ret_val->max_bytes_subkeyname = IVAL(nk_header, 0x34); 1627 ret_val->max_bytes_subkeyclassname = IVAL(nk_header, 0x38); 1628 ret_val->max_bytes_valuename = IVAL(nk_header, 0x3C); 1629 ret_val->max_bytes_value = IVAL(nk_header, 0x40); 1630 ret_val->unk_index = IVAL(nk_header, 0x44); 1631 1632 ret_val->name_length = SVAL(nk_header, 0x48); 1633 ret_val->classname_length = SVAL(nk_header, 0x4A); 1672 1634 1673 1635 if(ret_val->name_length + REGFI_NK_MIN_LENGTH > ret_val->cell_size) 1674 ret_val->name_length = ret_val->cell_size - REGFI_NK_MIN_LENGTH; 1636 { 1637 if(strict) 1638 { 1639 free(ret_val); 1640 return NULL; 1641 } 1642 else 1643 ret_val->name_length = ret_val->cell_size - REGFI_NK_MIN_LENGTH; 1644 } 1645 else if (unalloc) 1646 { /* Truncate cell_size if it's much larger than the apparent total record length. */ 1647 /* Round up to the next multiple of 8 */ 1648 length = (ret_val->name_length + REGFI_NK_MIN_LENGTH) & 0xFFFFFFF8; 1649 if(length < ret_val->name_length + REGFI_NK_MIN_LENGTH) 1650 length+=8; 1651 1652 /* If cell_size is still greater, truncate. */ 1653 if(length < ret_val->cell_size) 1654 ret_val->cell_size = length; 1655 } 1675 1656 1676 1657 ret_val->keyname = (char*)zalloc(sizeof(char)*(ret_val->name_length+1)); … … 1683 1664 /* Don't need to seek, should be at the right offset */ 1684 1665 length = ret_val->name_length; 1685 if((regfi_read(file->fd, ret_val->keyname, &length) != 0)1666 if((regfi_read(file->fd, (uint8*)ret_val->keyname, &length) != 0) 1686 1667 || length != ret_val->name_length) 1687 1668 { … … 1697 1678 1698 1679 1699 /***************************************************************************** 1700 * This function is just like read(2), except that it continues to 1701 * re-try reading from the file descriptor if EINTR or EAGAIN is received. 1702 * regfi_read will attempt to read length bytes from fd and write them to buf. 1703 * 1704 * On success, 0 is returned. Upon failure, an errno code is returned. 1705 * 1706 * The number of bytes successfully read is returned through the length 1707 * parameter by reference. If both the return value and length parameter are 1708 * returned as 0, then EOF was encountered immediately 1709 *****************************************************************************/ 1710 uint32 regfi_read(int fd, uint8* buf, uint32* length) 1711 { 1712 uint32 rsize = 0; 1713 uint32 rret = 0; 1714 1715 do 1716 { 1717 rret = read(fd, buf + rsize, *length - rsize); 1718 if(rret > 0) 1719 rsize += rret; 1720 }while(*length - rsize > 0 1721 && (rret > 0 || (rret == -1 && (errno == EAGAIN || errno == EINTR)))); 1722 1723 *length = rsize; 1724 if (rret == -1 && errno != EINTR && errno != EAGAIN) 1725 return errno; 1726 1727 return 0; 1728 } 1680 /******************************************************************* 1681 *******************************************************************/ 1682 REGF_VK_REC* regfi_parse_vk(REGF_FILE* file, uint32 offset, 1683 uint32 max_size, bool strict) 1684 { 1685 REGF_VK_REC* ret_val; 1686 uint8 vk_header[REGFI_VK_MIN_LENGTH]; 1687 uint32 raw_data_size, length, cell_length; 1688 bool unalloc = false; 1689 1690 if(!regfi_parse_cell(file->fd, offset, vk_header, REGFI_VK_MIN_LENGTH, 1691 &cell_length, &unalloc)) 1692 return NULL; 1693 1694 ret_val = (REGF_VK_REC*)zalloc(sizeof(REGF_VK_REC)); 1695 if(ret_val == NULL) 1696 return NULL; 1697 1698 ret_val->offset = offset; 1699 ret_val->cell_size = cell_length; 1700 1701 if(ret_val->cell_size > max_size) 1702 ret_val->cell_size = max_size & 0xFFFFFFF8; 1703 if((ret_val->cell_size < REGFI_VK_MIN_LENGTH) 1704 || (strict && ret_val->cell_size != (ret_val->cell_size & 0xFFFFFFF8))) 1705 { 1706 free(ret_val); 1707 return NULL; 1708 } 1709 1710 ret_val->magic[0] = vk_header[0x0]; 1711 ret_val->magic[1] = vk_header[0x1]; 1712 if((ret_val->magic[0] != 'v') || (ret_val->magic[1] != 'k')) 1713 { 1714 free(ret_val); 1715 return NULL; 1716 } 1717 1718 ret_val->name_length = SVAL(vk_header, 0x2); 1719 raw_data_size = IVAL(vk_header, 0x4); 1720 ret_val->data_size = raw_data_size & ~VK_DATA_IN_OFFSET; 1721 ret_val->data_off = IVAL(vk_header, 0x8); 1722 ret_val->type = IVAL(vk_header, 0xC); 1723 ret_val->flag = SVAL(vk_header, 0x10); 1724 ret_val->unknown1 = SVAL(vk_header, 0x12); 1725 1726 if(ret_val->flag & VK_FLAG_NAME_PRESENT) 1727 { 1728 if(ret_val->name_length + REGFI_VK_MIN_LENGTH > ret_val->cell_size) 1729 { 1730 if(strict) 1731 { 1732 free(ret_val); 1733 return NULL; 1734 } 1735 else 1736 ret_val->name_length = ret_val->cell_size - REGFI_VK_MIN_LENGTH; 1737 } 1738 1739 /* Round up to the next multiple of 8 */ 1740 length = (ret_val->name_length + REGFI_NK_MIN_LENGTH) & 0xFFFFFFF8; 1741 if(length < ret_val->name_length + REGFI_NK_MIN_LENGTH) 1742 length+=8; 1743 1744 ret_val->valuename = (char*)zalloc(sizeof(char)*(ret_val->name_length+1)); 1745 if(ret_val->valuename == NULL) 1746 { 1747 free(ret_val); 1748 return NULL; 1749 } 1750 1751 /* Don't need to seek, should be at the right offset */ 1752 length = ret_val->name_length; 1753 if((regfi_read(file->fd, (uint8*)ret_val->valuename, &length) != 0) 1754 || length != ret_val->name_length) 1755 { 1756 free(ret_val->valuename); 1757 free(ret_val); 1758 return NULL; 1759 } 1760 ret_val->valuename[ret_val->name_length] = '\0'; 1761 } 1762 else 1763 length = REGFI_VK_MIN_LENGTH; 1764 1765 if(unalloc) 1766 { 1767 /* If cell_size is still greater, truncate. */ 1768 if(length < ret_val->cell_size) 1769 ret_val->cell_size = length; 1770 } 1771 1772 if(ret_val->data_size == 0) 1773 ret_val->data = NULL; 1774 else 1775 { 1776 ret_val->data = regfi_parse_data(file, ret_val->data_off+REGF_BLOCKSIZE, 1777 raw_data_size, strict); 1778 if(strict && (ret_val->data == NULL)) 1779 { 1780 free(ret_val->valuename); 1781 free(ret_val); 1782 return NULL; 1783 } 1784 } 1785 1786 return ret_val; 1787 } 1788 1789 1790 uint8* regfi_parse_data(REGF_FILE* file, uint32 offset, uint32 length, bool strict) 1791 { 1792 uint8* ret_val; 1793 uint32 read_length, cell_length; 1794 bool unalloc; 1795 1796 /* The data is stored in the offset if the size <= 4 */ 1797 if (length & VK_DATA_IN_OFFSET) 1798 { 1799 length = length & ~VK_DATA_IN_OFFSET; 1800 if(length > 4) 1801 return NULL; 1802 1803 if((ret_val = (uint8*)zalloc(sizeof(uint8)*length)) == NULL) 1804 return NULL; 1805 memcpy(ret_val, &offset, length); 1806 } 1807 else 1808 { 1809 if(!regfi_parse_cell(file->fd, offset, NULL, 0, 1810 &cell_length, &unalloc)) 1811 return NULL; 1812 1813 if(cell_length < 8 || ((cell_length & 0xFFFFFFF8) != cell_length)) 1814 return NULL; 1815 1816 if(cell_length - 4 < length) 1817 { 1818 if(strict) 1819 return NULL; 1820 else 1821 length = cell_length - 4; 1822 } 1823 1824 /* TODO: There is currently no check to ensure the data 1825 * cell doesn't cross HBIN boundary. 1826 */ 1827 1828 if((ret_val = (uint8*)zalloc(sizeof(uint8)*length)) == NULL) 1829 return NULL; 1830 1831 read_length = length; 1832 if((regfi_read(file->fd, ret_val, &read_length) != 0) 1833 || read_length != length) 1834 { 1835 free(ret_val); 1836 return NULL; 1837 } 1838 } 1839 1840 return ret_val; 1841 }
Note: See TracChangeset
for help on using the changeset viewer.