- Timestamp:
- 03/03/08 19:38:48 (17 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfi.h
r97 r99 48 48 #include "smb_deps.h" 49 49 #include "void_stack.h" 50 #include "range_list.h" 50 51 51 52 /******************************************************************************/ … … 83 84 84 85 #define REGF_OFFSET_NONE 0xffffffff 86 #define REGFI_NK_MIN_LENGTH 0x50 85 87 86 88 /* Flags for the vk records */ … … 116 118 * Should be a multiple of 4096 (0x1000) 117 119 */ 118 uint32 next_block; /* relative offset to next block. Should be 119 * exactly the same as block_size. Stored just 120 * in case this is found to be different in the 121 * future. 120 uint32 next_block; /* relative offset to next block. 121 * NOTE: This value may be unreliable! 122 122 */ 123 123 … … 142 142 REGF_HASH_REC* hashes; 143 143 uint32 hbin_off; /* offset from beginning of this hbin block */ 144 uint32 rec_size; /* ((start_offset - end_offset) & 0xfffffff8) */144 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 145 145 146 146 uint8 header[REC_HDR_SIZE]; … … 158 158 uint8* data; 159 159 uint32 hbin_off; /* offset from beginning of this hbin block */ 160 uint32 rec_size; /* ((start_offset - end_offset) & 0xfffffff8) */160 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 161 161 uint32 rec_off; /* offset stored in the value list */ 162 162 … … 181 181 SEC_DESC* sec_desc; 182 182 uint32 hbin_off; /* offset from beginning of this hbin block */ 183 uint32 rec_size; /* ((start_offset - end_offset) & 0xfffffff8) */183 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 184 184 185 185 uint32 sk_off; /* offset parsed from NK record used as a key … … 198 198 typedef struct 199 199 { 200 uint32 hbin_off; /* offset from beginning of this hbin block*/201 uint32 rec_size; /* ((start_offset - end_offset) & 0xfffffff8) */202 REGF_HBIN *hbin; /* pointer to HBIN record (in memory) containing203 * this nk record */200 uint32 offset; /* Real offset of this record's cell in the file */ 201 uint32 cell_size; /* Actual or estimated length of the cell. 202 * Always in multiples of 8. 203 */ 204 204 205 205 /* link in the other records here */ … … 213 213 uint8 header[REC_HDR_SIZE]; 214 214 NTTIME mtime; 215 uint16 name_length; 216 uint16 classname_length; 215 217 char* classname; 216 218 char* keyname; … … 225 227 226 228 /* unknowns */ 229 uint32 unknown1; 230 uint32 unknown2; 231 uint32 unknown3; 227 232 uint32 unk_index; /* nigel says run time index ? */ 228 233 … … 246 251 void* mem_ctx; /* memory context for run-time file access information */ 247 252 REGF_HBIN* block_list; /* list of open hbin blocks */ 248 253 254 /* Experimental hbin lists */ 255 range_list* hbins; 256 range_list* unalloc_cells; 257 249 258 /* file format information */ 250 259 REGF_SK_REC* sec_desc_list; /* list of security descriptors referenced … … 298 307 /******************************************************************************/ 299 308 /* Function Declarations */ 300 309 /* Main API */ 301 310 const char* regfi_type_val2str(unsigned int val); 302 311 int regfi_type_str2val(const char* str); … … 331 340 const REGF_VK_REC* regfi_iterator_next_value(REGFI_ITERATOR* i); 332 341 342 /************************************/ 343 /* Low-layer data structure access */ 344 /************************************/ 345 REGF_FILE* regfi_parse_regf(int fd, bool strict); 346 REGF_HBIN* regfi_parse_hbin(REGF_FILE* file, uint32 offset, 347 bool strict, bool save_unalloc); 348 349 350 /* regfi_parse_nk: Parses an NK record. 351 * 352 * Arguments: 353 * f -- the registry file structure 354 * offset -- the offset of the cell (not the record) to be parsed. 355 * max_size -- the maximum size the NK cell could be. (for validation) 356 * strict -- if true, rejects any malformed records. Otherwise, 357 * tries to minimally validate integrity. 358 * Returns: 359 * A newly allocated NK record structure, or NULL on failure. 360 */ 361 REGF_NK_REC* regfi_parse_nk(REGF_FILE* file, uint32 offset, 362 uint32 max_size, bool strict); 363 333 364 334 365 /* Private Functions */ 335 366 REGF_NK_REC* regfi_rootkey(REGF_FILE* file); 336 367 void regfi_key_free(REGF_NK_REC* nk); 368 uint32 regfi_read(int fd, uint8* buf, uint32* length); 337 369 338 370 … … 341 373 /* Experimental */ 342 374 /****************/ 343 typedef struct 344 { 345 uint32 offset; 346 uint32 size; 347 } REGFI_CELL_INFO; 348 349 typedef struct 350 { 351 uint32 count; 352 REGFI_CELL_INFO** cells; 353 } REGFI_CELL_LIST; 354 355 356 REGF_FILE* regfi_parse_regf(int fd, bool strict); 357 REGFI_CELL_LIST* regfi_get_unallocated_cells(REGF_FILE* file); 358 REGF_HBIN* regfi_parse_hbin(REGF_FILE* file, uint32 offset, 359 bool strict, bool save_unalloc); 360 REGF_NK_REC* regfi_parse_nk(REGF_FILE* f, uint32); 361 uint32 regfi_read(int fd, uint8* buf, uint32* length); 375 362 376 363 377 #endif /* _REGFI_H */ -
trunk/lib/range_list.c
r98 r99 18 18 */ 19 19 20 #include <stdio.h> 20 21 #include <math.h> 21 22 #include "../include/range_list.h" … … 26 27 /*******************/ 27 28 #define RANGE_LIST_ALLOC_SIZE 256 29 30 31 static void range_list_print(const range_list* rl) 32 { 33 uint32_t i; 34 for(i=0; i<rl->size; i++) 35 fprintf(stderr, " %d=%p,%d,%d,%p", i, (void*)rl->elements[i], 36 rl->elements[i]->offset, rl->elements[i]->length, 37 rl->elements[i]->data); 38 fprintf(stderr, "\n"); 39 } 40 28 41 29 42 /* … … 40 53 if(rl->size == rl->elem_alloced) 41 54 { 42 tmp = (range_list_element**)realloc(rl->elements, rl->elem_alloced+RANGE_LIST_ALLOC_SIZE); 55 tmp = (range_list_element**)realloc(rl->elements, 56 (rl->elem_alloced+RANGE_LIST_ALLOC_SIZE) 57 * sizeof(range_list_element*)); 43 58 if(tmp == NULL) 44 59 return false; … … 90 105 cur_elem = rl->elements[cur_idx]; 91 106 92 if((offset >= cur_elem->offset) && (offset < (cur_elem+1)->offset))107 if((offset >= cur_elem->offset) && (offset < rl->elements[cur_idx+1]->offset)) 93 108 return cur_idx; 94 109 … … 116 131 rl->elements = (range_list_element**)malloc(sizeof(range_list_element*) 117 132 * RANGE_LIST_ALLOC_SIZE); 133 118 134 if(rl->elements == NULL) 119 135 { … … 152 168 range_list_element* elem; 153 169 range_list_element* prev_elem; 154 170 /*fprintf(stderr, "DEBUG: rl->size=%d\n", rl->size);*/ 155 171 /* Sorry, limited to 2**31-1 elements. */ 156 172 if(rl->size >= 0x7FFFFFFF) … … 215 231 216 232 /* Try to keep memory usage down */ 217 if(rl->size < (rl->elem_alloced - 2 *RANGE_LIST_ALLOC_SIZE))233 if(rl->size < (rl->elem_alloced - 2 * RANGE_LIST_ALLOC_SIZE)) 218 234 { 219 235 tmp = (range_list_element**)realloc(rl->elements, 220 rl->elem_alloced - 2*RANGE_LIST_ALLOC_SIZE); 236 (rl->elem_alloced-2*RANGE_LIST_ALLOC_SIZE) 237 * sizeof(range_list_element*)); 221 238 if(tmp != NULL) 222 239 { -
trunk/lib/regfi.c
r97 r99 337 337 338 338 339 340 /*******************************************************************341 *******************************************************************/342 static bool prs_nk_rec( const char *desc, prs_struct *ps,343 int depth, REGF_NK_REC *nk )344 {345 uint16 class_length, name_length;346 uint32 start;347 uint32 data_size, start_off, end_off;348 uint32 unknown_off = REGF_OFFSET_NONE;349 350 nk->hbin_off = ps->data_offset;351 start = nk->hbin_off;352 353 depth++;354 355 /* back up and get the data_size */356 if ( !prs_set_offset( ps, ps->data_offset-sizeof(uint32)) )357 return false;358 start_off = ps->data_offset;359 if ( !prs_uint32( "rec_size", ps, depth, &nk->rec_size ))360 return false;361 362 if (!prs_uint8s("header", ps, depth, nk->header, sizeof(nk->header)))363 return false;364 365 if ( !prs_uint16( "key_type", ps, depth, &nk->key_type ))366 return false;367 if ( !smb_io_time( "mtime", &nk->mtime, ps, depth ))368 return false;369 370 if ( !prs_set_offset( ps, start+0x0010 ) )371 return false;372 if ( !prs_uint32( "parent_off", ps, depth, &nk->parent_off ))373 return false;374 if ( !prs_uint32( "num_subkeys", ps, depth, &nk->num_subkeys ))375 return false;376 377 if ( !prs_set_offset( ps, start+0x001c ) )378 return false;379 if ( !prs_uint32( "subkeys_off", ps, depth, &nk->subkeys_off ))380 return false;381 if ( !prs_uint32( "unknown_off", ps, depth, &unknown_off) )382 return false;383 384 if ( !prs_set_offset( ps, start+0x0024 ) )385 return false;386 if ( !prs_uint32( "num_values", ps, depth, &nk->num_values ))387 return false;388 if ( !prs_uint32( "values_off", ps, depth, &nk->values_off ))389 return false;390 if ( !prs_uint32( "sk_off", ps, depth, &nk->sk_off ))391 return false;392 if ( !prs_uint32( "classname_off", ps, depth, &nk->classname_off ))393 return false;394 395 if (!prs_uint32("max_bytes_subkeyname", ps, depth, &nk->max_bytes_subkeyname))396 return false;397 if ( !prs_uint32( "max_bytes_subkeyclassname", ps,398 depth, &nk->max_bytes_subkeyclassname))399 { return false; }400 if ( !prs_uint32( "max_bytes_valuename", ps, depth, &nk->max_bytes_valuename))401 return false;402 if ( !prs_uint32( "max_bytes_value", ps, depth, &nk->max_bytes_value))403 return false;404 if ( !prs_uint32( "unknown index", ps, depth, &nk->unk_index))405 return false;406 407 name_length = nk->keyname ? strlen(nk->keyname) : 0 ;408 class_length = nk->classname ? strlen(nk->classname) : 0 ;409 if ( !prs_uint16( "name_length", ps, depth, &name_length ))410 return false;411 if ( !prs_uint16( "class_length", ps, depth, &class_length ))412 return false;413 414 if ( class_length )415 {416 /* XXX: why isn't this parsed? */417 ;;418 }419 420 if ( name_length )421 {422 if(ps->io && !(nk->keyname = (char*)zcalloc(sizeof(char), name_length+1)))423 return false;424 425 if(!prs_uint8s("name", ps, depth, (uint8*)nk->keyname, name_length))426 return false;427 428 if(ps->io)429 nk->keyname[name_length] = '\0';430 }431 432 end_off = ps->data_offset;433 434 /* data_size must be divisible by 8 and large enough to hold435 the original record */436 437 data_size = ((start_off - end_off) & 0xfffffff8 );438 /*if ( data_size > nk->rec_size )439 DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, nk->rec_size));*/440 441 return true;442 }443 444 445 339 /******************************************************************* 446 340 Input a randon offset and receive the correpsonding HBIN … … 548 442 return false; 549 443 start_off = hbin->ps.data_offset; 550 if ( !prs_uint32( " rec_size", &hbin->ps, depth, &lf->rec_size ))444 if ( !prs_uint32( "cell_size", &hbin->ps, depth, &lf->cell_size )) 551 445 return false; 552 446 … … 573 467 574 468 data_size = ((start_off - end_off) & 0xfffffff8 ); 575 /* if ( data_size > lf-> rec_size )*/576 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf-> rec_size));*/469 /* if ( data_size > lf->cell_size )*/ 470 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->cell_size));*/ 577 471 578 472 return true; … … 599 493 return false; 600 494 start_off = hbin->ps.data_offset; 601 if ( !prs_uint32( " rec_size", &hbin->ps, depth, &sk->rec_size ))495 if ( !prs_uint32( "cell_size", &hbin->ps, depth, &sk->cell_size )) 602 496 return false; 603 497 … … 624 518 625 519 data_size = ((start_off - end_off) & 0xfffffff8 ); 626 /* if ( data_size > sk-> rec_size )*/627 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk-> rec_size));*/520 /* if ( data_size > sk->cell_size )*/ 521 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->cell_size));*/ 628 522 629 523 return true; … … 648 542 return false; 649 543 start_off = hbin->ps.data_offset; 650 if ( !prs_uint32( " rec_size", &hbin->ps, depth, &vk->rec_size ))544 if ( !prs_uint32( "cell_size", &hbin->ps, depth, &vk->cell_size )) 651 545 return false; 652 546 … … 741 635 data_size = ((start_off - end_off ) & 0xfffffff8 ); 742 636 /* XXX: should probably print a warning here */ 743 /*if ( data_size != vk-> rec_size )744 DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk-> rec_size));*/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));*/ 745 639 746 640 return true; … … 803 697 sub_hbin = lookup_hbin_block( file, nk->values[i].rec_off ); 804 698 if ( !sub_hbin ) 805 {806 /*DEBUG(0,("hbin_prs_vk_records: Failed to find HBIN block containing offset [0x%x]\n",807 nk->values[i].hbin_off));*/808 699 return false; 809 }810 700 } 811 701 … … 858 748 /******************************************************************* 859 749 *******************************************************************/ 860 static bool hbin_prs_key( REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk ) 861 { 750 static REGF_NK_REC* hbin_prs_key(REGF_FILE *file, REGF_HBIN *hbin) 751 { 752 REGF_HBIN* sub_hbin; 753 REGF_NK_REC* nk; 754 uint32 nk_cell_offset; 755 uint32 nk_max_length; 862 756 int depth = 0; 863 REGF_HBIN *sub_hbin; 864 757 865 758 depth++; 866 759 867 760 /* get the initial nk record */ 868 if (!prs_nk_rec("nk_rec", &hbin->ps, depth, nk)) 869 return false; 761 nk_cell_offset = hbin->file_off + hbin->ps.data_offset - sizeof(uint32); 762 nk_max_length = hbin->block_size - hbin->ps.data_offset + sizeof(uint32); 763 if ((nk = regfi_parse_nk(file, nk_cell_offset, nk_max_length, true)) == NULL) 764 return NULL; 870 765 871 766 /* fill in values */ … … 880 775 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing value_list_offset [0x%x]\n", 881 776 nk->values_off));*/ 882 return false;777 return NULL; 883 778 } 884 779 } 885 780 886 781 if(!hbin_prs_vk_records("vk_rec", sub_hbin, depth, nk, file)) 887 return false;782 return NULL; 888 783 } 889 784 … … 899 794 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing subkey_offset [0x%x]\n", 900 795 nk->subkeys_off));*/ 901 return false;796 return NULL; 902 797 } 903 798 } 904 799 905 800 if (!hbin_prs_lf_records("lf_rec", sub_hbin, depth, nk)) 906 return false;801 return NULL; 907 802 } 908 803 … … 916 811 { 917 812 sub_hbin = lookup_hbin_block( file, nk->sk_off ); 918 if ( !sub_hbin ) { 813 if ( !sub_hbin ) 814 { 815 free(nk); 919 816 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing sk_offset [0x%x]\n", 920 817 nk->subkeys_off));*/ 921 return false;818 return NULL; 922 819 } 923 820 } 924 821 925 822 if ( !(nk->sec_desc = (REGF_SK_REC*)zalloc(sizeof(REGF_SK_REC) )) ) 926 return false;823 return NULL; 927 824 nk->sec_desc->sk_off = nk->sk_off; 928 825 if ( !hbin_prs_sk_rec( "sk_rec", sub_hbin, depth, nk->sec_desc )) 929 return false;826 return NULL; 930 827 931 828 /* add to the list of security descriptors (ref_count has been read from the files) */ … … 935 832 DLIST_ADD( file->sec_desc_list, nk->sec_desc ); 936 833 } 937 938 return true;834 835 return nk; 939 836 } 940 837 … … 1003 900 /******************************************************************* 1004 901 *******************************************************************/ 1005 static bool next_nk_record(REGF_FILE *file, REGF_HBIN *hbin, 1006 REGF_NK_REC *nk, bool *eob) 1007 { 1008 if (next_record(hbin, "nk", eob) 1009 && hbin_prs_key(file, hbin, nk)) 1010 return true; 1011 1012 return false; 902 static REGF_NK_REC* next_nk_record(REGF_FILE *file, REGF_HBIN *hbin, bool *eob) 903 { 904 REGF_NK_REC* ret_val; 905 if(next_record(hbin, "nk", eob) 906 && (ret_val = hbin_prs_key(file, hbin)) != NULL) 907 return ret_val; 908 909 fprintf(stderr, "ACK!"); 910 return NULL; 1013 911 } 1014 912 … … 1030 928 return NULL; 1031 929 } 1032 930 1033 931 /* read in an existing file */ 1034 932 if ((rb = regfi_parse_regf(fd, true)) == NULL) … … 1038 936 return NULL; 1039 937 } 1040 938 939 rb->hbins = range_list_new(); 940 rb->unalloc_cells = range_list_new(); 941 if((rb->hbins == NULL) || (rb->unalloc_cells == NULL)) 942 { 943 close(fd); 944 free(rb); 945 return NULL; 946 } 947 1041 948 /* success */ 1042 949 return rb; 1043 }1044 1045 1046 /*******************************************************************1047 XXX: should this be nuked?1048 *******************************************************************/1049 static void regfi_mem_free( REGF_FILE *file )1050 {1051 /* free any zalloc()'d memory */1052 1053 /* if ( file && file->mem_ctx )1054 free(file->mem_ctx);1055 */1056 950 } 1057 951 … … 1063 957 int fd; 1064 958 1065 regfi_mem_free( file );1066 1067 959 /* nothing to do if there is no open file */ 1068 1069 if ( !file || (file->fd == -1) ) 960 if ((file == NULL) || (file->fd == -1)) 1070 961 return 0; 1071 962 1072 963 fd = file->fd; 1073 964 file->fd = -1; 1074 SAFE_FREE( file ); 965 range_list_free(file->hbins); 966 range_list_free(file->unalloc_cells); 967 free(file); 1075 968 1076 969 return close( fd ); … … 1089 982 bool found = false; 1090 983 bool eob; 1091 1092 if ( !file ) 1093 return NULL; 1094 1095 if ( !(nk = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC) )) ) { 1096 /*DEBUG(0,("regfi_rootkey: zalloc() failed!\n"));*/ 1097 return NULL; 1098 } 1099 984 985 if(!file) 986 return NULL; 987 1100 988 /* scan through the file on HBIN block at a time looking 1101 989 for an NK record with a type == 0x002c. … … 1103 991 block (but I'm not assuming that for now) */ 1104 992 1105 while ( (hbin = regfi_parse_hbin(file, offset, true, false)) ) { 993 while((hbin = regfi_parse_hbin(file, offset, true, false))) 994 { 1106 995 eob = false; 1107 996 1108 while ( !eob) { 1109 if ( next_nk_record( file, hbin, nk, &eob ) ) { 1110 if ( nk->key_type == NK_TYPE_ROOTKEY ) { 997 while(!eob) 998 { 999 if((nk = next_nk_record(file, hbin, &eob)) != NULL) 1000 { 1001 if ( nk->key_type == NK_TYPE_ROOTKEY ) 1002 { 1111 1003 found = true; 1112 1004 break; … … 1120 1012 } 1121 1013 1122 if ( found)1014 if(found) 1123 1015 break; 1124 1016 1125 1017 offset += hbin->block_size; 1126 1018 } 1127 1128 if ( !found) {1019 1020 if (!found) { 1129 1021 /*DEBUG(0,("regfi_rootkey: corrupt registry file ? No root key record located\n"));*/ 1130 1022 return NULL; … … 1394 1286 return NULL; 1395 1287 1396 if(!(subkey = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC)))) 1397 return NULL; 1398 1399 if(!hbin_prs_key(i->f, hbin, subkey)) 1400 { 1401 regfi_key_free(subkey); 1402 return NULL; 1403 } 1288 if((subkey = hbin_prs_key(i->f, hbin)) == NULL) 1289 return NULL; 1404 1290 1405 1291 return subkey; … … 1613 1499 int32 cell_len; 1614 1500 bool is_unalloc; 1615 1616 if(!(hbin = (REGF_HBIN*)zalloc(sizeof(REGF_HBIN)))) 1617 return NULL; 1618 hbin->file_off = offset; 1619 1501 1502 if(offset >= file->file_length) 1503 return NULL; 1504 1620 1505 if(lseek(file->fd, offset, SEEK_SET) == -1) 1621 1506 return NULL; … … 1626 1511 return NULL; 1627 1512 1513 1628 1514 if(lseek(file->fd, offset, SEEK_SET) == -1) 1629 1515 return NULL; 1516 1517 if(!(hbin = (REGF_HBIN*)zalloc(sizeof(REGF_HBIN)))) 1518 return NULL; 1519 hbin->file_off = offset; 1630 1520 1631 1521 memcpy(hbin->magic, hbin_header, 4); 1632 1522 if(strict && (memcmp(hbin->magic, "hbin", 4) != 0)) 1633 return NULL; 1523 { 1524 free(hbin); 1525 return NULL; 1526 } 1634 1527 1635 1528 hbin->first_hbin_off = IVAL(hbin_header, 0x4); … … 1637 1530 /* this should be the same thing as hbin->block_size but just in case */ 1638 1531 hbin->next_block = IVAL(hbin_header, 0x1C); 1639 1640 1641 /* TODO: This check is this more of a way to determine if they are ever1642 * not the same than to really do sanity checking. This may need1643 * to be changed or removed once these fields are better understood. */1644 if(strict && (hbin->block_size != hbin->next_block))1645 {1646 fprintf(stderr, "DEBUG: hbin->block_size != hbin->next_block\n");1647 return NULL;1648 }1649 1532 1650 1533 … … 1656 1539 if((offset + hbin->block_size > file->file_length) 1657 1540 || (hbin->block_size & 0xFFFFF000) != hbin->block_size) 1658 return NULL; 1659 1541 { 1542 free(hbin); 1543 return NULL; 1544 } 1660 1545 1661 1546 /* TODO: need to get rid of this, but currently lots depends on the … … 1663 1548 */ 1664 1549 if(!prs_init(&hbin->ps, hbin->block_size, file->mem_ctx, UNMARSHALL)) 1665 return NULL; 1550 { 1551 free(hbin); 1552 return NULL; 1553 } 1666 1554 length = hbin->block_size; 1667 1555 if((regfi_read(file->fd, (uint8*)hbin->ps.data_p, &length) != 0) 1668 1556 || length != hbin->block_size) 1669 return NULL; 1557 { 1558 free(hbin); 1559 return NULL; 1560 } 1670 1561 1671 1562 1672 1563 if(save_unalloc) 1673 1564 { 1674 is_unalloc = false;1675 1565 cell_len = 0; 1676 1566 curr_off = HBIN_HEADER_REC_SIZE; 1677 1567 while ( curr_off < hbin->block_size ) 1678 1568 { 1569 is_unalloc = false; 1679 1570 cell_len = IVALS(hbin->ps.data_p, curr_off); 1680 1681 1571 if(cell_len > 0) 1682 1572 is_unalloc = true; … … 1696 1586 1697 1587 if(is_unalloc) 1698 /* TODO: save cell info */ 1588 range_list_add(file->unalloc_cells, hbin->file_off+curr_off, 1589 cell_len, NULL); 1699 1590 1700 1591 curr_off = curr_off+cell_len; … … 1710 1601 return hbin; 1711 1602 } 1603 1604 1605 REGF_NK_REC* regfi_parse_nk(REGF_FILE* file, uint32 offset, 1606 uint32 max_size, bool strict) 1607 { 1608 uint8 nk_header[REGFI_NK_MIN_LENGTH]; 1609 REGF_NK_REC* ret_val; 1610 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; 1618 1619 /* A bit of validation before bothering to allocate memory */ 1620 if(strict && ((nk_header[0x4] != 'n') || (nk_header[0x5] != 'k'))) 1621 return NULL; 1622 1623 ret_val = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC)); 1624 if(ret_val == NULL) 1625 return NULL; 1626 1627 ret_val->offset = offset; 1628 ret_val->cell_size = IVAL(nk_header, 0x0); 1629 if(ret_val->cell_size > max_size) 1630 ret_val->cell_size = max_size & 0xFFFFFFF8; 1631 if((ret_val->cell_size < REGFI_NK_MIN_LENGTH) 1632 || (strict && ret_val->cell_size != (ret_val->cell_size & 0xFFFFFFF8))) 1633 { 1634 free(ret_val); 1635 return NULL; 1636 } 1637 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))) 1644 { 1645 free(ret_val); 1646 return NULL; 1647 } 1648 1649 ret_val->mtime.low = IVAL(nk_header, 0x8); 1650 ret_val->mtime.high = IVAL(nk_header, 0xC); 1651 1652 ret_val->unknown1 = IVAL(nk_header, 0x10); 1653 ret_val->parent_off = IVAL(nk_header, 0x14); 1654 ret_val->num_subkeys = IVAL(nk_header, 0x18); 1655 ret_val->unknown2 = IVAL(nk_header, 0x1C); 1656 ret_val->subkeys_off = IVAL(nk_header, 0x20); 1657 ret_val->unknown3 = IVAL(nk_header, 0x24); 1658 ret_val->num_values = IVAL(nk_header, 0x28); 1659 ret_val->values_off = IVAL(nk_header, 0x2C); 1660 ret_val->sk_off = IVAL(nk_header, 0x30); 1661 /* TODO: currently we do nothing with class names. Need to investigate. */ 1662 ret_val->classname_off = IVAL(nk_header, 0x34); 1663 1664 ret_val->max_bytes_subkeyname = IVAL(nk_header, 0x38); 1665 ret_val->max_bytes_subkeyclassname = IVAL(nk_header, 0x3C); 1666 ret_val->max_bytes_valuename = IVAL(nk_header, 0x40); 1667 ret_val->max_bytes_value = IVAL(nk_header, 0x44); 1668 ret_val->unk_index = IVAL(nk_header, 0x48); 1669 1670 ret_val->name_length = SVAL(nk_header, 0x4C); 1671 ret_val->classname_length = SVAL(nk_header, 0x4E); 1672 1673 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; 1675 1676 ret_val->keyname = (char*)zalloc(sizeof(char)*(ret_val->name_length+1)); 1677 if(ret_val->keyname == NULL) 1678 { 1679 free(ret_val); 1680 return NULL; 1681 } 1682 1683 /* Don't need to seek, should be at the right offset */ 1684 length = ret_val->name_length; 1685 if((regfi_read(file->fd, ret_val->keyname, &length) != 0) 1686 || length != ret_val->name_length) 1687 { 1688 free(ret_val->keyname); 1689 free(ret_val); 1690 return NULL; 1691 } 1692 ret_val->keyname[ret_val->name_length] = '\0'; 1693 1694 return ret_val; 1695 } 1696 1712 1697 1713 1698
Note: See TracChangeset
for help on using the changeset viewer.