📄 regfio.c
字号:
previous 4 bytes contains the amount of free space remaining in the hbin block. */ /* remember that the record_size is in the 4 bytes preceeding the record itself */ if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE-sizeof(uint32) ) ) return False; record_size = 0; header = 0; curr_off = prs_offset( &hbin->ps ); while ( header != 0xffffffff ) { /* not done yet so reset the current offset to the next record_size field */ curr_off = curr_off+record_size; /* for some reason the record_size of the last record in an hbin block can extend past the end of the block even though the record fits within the remaining space....aaarrrgggghhhhhh */ if ( curr_off >= block_size ) { record_size = -1; curr_off = -1; break; } if ( !prs_set_offset( &hbin->ps, curr_off) ) return False; if ( !prs_uint32( "rec_size", &hbin->ps, 0, &record_size ) ) return False; if ( !prs_uint32( "header", &hbin->ps, 0, &header ) ) return False; SMB_ASSERT( record_size != 0 ); if ( record_size & 0x80000000 ) { /* absolute_value(record_size) */ record_size = (record_size ^ 0xffffffff) + 1; } } /* save the free space offset */ if ( header == 0xffffffff ) { /* account for the fact that the curr_off is 4 bytes behind the actual record header */ hbin->free_off = curr_off + sizeof(uint32); hbin->free_size = record_size; } DEBUG(10,("read_hbin_block: free space offset == 0x%x\n", hbin->free_off)); if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE ) ) return False; return hbin;}/******************************************************************* Input a random offset and receive the corresponding HBIN block for it*******************************************************************/static BOOL hbin_contains_offset( REGF_HBIN *hbin, uint32 offset ){ if ( !hbin ) return False; if ( (offset > hbin->first_hbin_off) && (offset < (hbin->first_hbin_off+hbin->block_size)) ) return True; return False;}/******************************************************************* Input a random offset and receive the corresponding HBIN block for it*******************************************************************/static REGF_HBIN* lookup_hbin_block( REGF_FILE *file, uint32 offset ){ REGF_HBIN *hbin = NULL; uint32 block_off; /* start with the open list */ for ( hbin=file->block_list; hbin; hbin=hbin->next ) { DEBUG(10,("lookup_hbin_block: address = 0x%x [0x%lx]\n", hbin->file_off, (unsigned long)hbin )); if ( hbin_contains_offset( hbin, offset ) ) return hbin; } if ( !hbin ) { /* start at the beginning */ block_off = REGF_BLOCKSIZE; do { /* cleanup before the next round */ if ( hbin ) prs_mem_free( &hbin->ps ); hbin = read_hbin_block( file, block_off ); if ( hbin ) block_off = hbin->file_off + hbin->block_size; } while ( hbin && !hbin_contains_offset( hbin, offset ) ); } if ( hbin ) DLIST_ADD( file->block_list, hbin ); return hbin;}/**************************************************************************************************************************************/static BOOL prs_hash_rec( const char *desc, prs_struct *ps, int depth, REGF_HASH_REC *hash ){ prs_debug(ps, depth, desc, "prs_hash_rec"); depth++; if ( !prs_uint32( "nk_off", ps, depth, &hash->nk_off )) return False; if ( !prs_uint8s( True, "keycheck", ps, depth, hash->keycheck, sizeof( hash->keycheck )) ) return False; return True;}/**************************************************************************************************************************************/static BOOL hbin_prs_lf_records( const char *desc, REGF_HBIN *hbin, int depth, REGF_NK_REC *nk ){ int i; REGF_LF_REC *lf = &nk->subkeys; uint32 data_size, start_off, end_off; prs_debug(&hbin->ps, depth, desc, "prs_lf_records"); depth++; /* check if we have anything to do first */ if ( nk->num_subkeys == 0 ) return True; /* move to the LF record */ if ( !prs_set_offset( &hbin->ps, nk->subkeys_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) return False; /* backup and get the data_size */ if ( !prs_set_offset( &hbin->ps, prs_offset(&hbin->ps)-sizeof(uint32)) ) return False; start_off = prs_offset( &hbin->ps ); if ( !prs_uint32( "rec_size", &hbin->ps, depth, &lf->rec_size )) return False; if ( !prs_uint8s( True, "header", &hbin->ps, depth, (uint8*)lf->header, sizeof( lf->header )) ) return False; if ( !prs_uint16( "num_keys", &hbin->ps, depth, &lf->num_keys)) return False; if ( UNMARSHALLING(&hbin->ps) ) { if ( !(lf->hashes = PRS_ALLOC_MEM( &hbin->ps, REGF_HASH_REC, lf->num_keys )) ) return False; } for ( i=0; i<lf->num_keys; i++ ) { if ( !prs_hash_rec( "hash_rec", &hbin->ps, depth, &lf->hashes[i] ) ) return False; } end_off = prs_offset( &hbin->ps ); /* data_size must be divisible by 8 and large enough to hold the original record */ data_size = ((start_off - end_off) & 0xfffffff8 ); if ( data_size > lf->rec_size ) DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->rec_size)); if ( MARSHALLING(&hbin->ps) ) hbin->dirty = True; return True;}/**************************************************************************************************************************************/static BOOL hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_SK_REC *sk ){ prs_struct *ps = &hbin->ps; uint16 tag = 0xFFFF; uint32 data_size, start_off, end_off; prs_debug(ps, depth, desc, "hbin_prs_sk_rec"); depth++; if ( !prs_set_offset( &hbin->ps, sk->sk_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) return False; /* backup and get the data_size */ if ( !prs_set_offset( &hbin->ps, prs_offset(&hbin->ps)-sizeof(uint32)) ) return False; start_off = prs_offset( &hbin->ps ); if ( !prs_uint32( "rec_size", &hbin->ps, depth, &sk->rec_size )) return False; if ( !prs_uint8s( True, "header", ps, depth, (uint8*)sk->header, sizeof( sk->header )) ) return False; if ( !prs_uint16( "tag", ps, depth, &tag)) return False; if ( !prs_uint32( "prev_sk_off", ps, depth, &sk->prev_sk_off)) return False; if ( !prs_uint32( "next_sk_off", ps, depth, &sk->next_sk_off)) return False; if ( !prs_uint32( "ref_count", ps, depth, &sk->ref_count)) return False; if ( !prs_uint32( "size", ps, depth, &sk->size)) return False; if ( !sec_io_desc( "sec_desc", &sk->sec_desc, ps, depth )) return False; end_off = prs_offset( &hbin->ps ); /* data_size must be divisible by 8 and large enough to hold the original record */ data_size = ((start_off - end_off) & 0xfffffff8 ); if ( data_size > sk->rec_size ) DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->rec_size)); if ( MARSHALLING(&hbin->ps) ) hbin->dirty = True; return True;}/**************************************************************************************************************************************/static BOOL hbin_prs_vk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_VK_REC *vk, REGF_FILE *file ){ uint32 offset; uint16 name_length; prs_struct *ps = &hbin->ps; uint32 data_size, start_off, end_off; prs_debug(ps, depth, desc, "prs_vk_rec"); depth++; /* backup and get the data_size */ if ( !prs_set_offset( &hbin->ps, prs_offset(&hbin->ps)-sizeof(uint32)) ) return False; start_off = prs_offset( &hbin->ps ); if ( !prs_uint32( "rec_size", &hbin->ps, depth, &vk->rec_size )) return False; if ( !prs_uint8s( True, "header", ps, depth, (uint8*)vk->header, sizeof( vk->header )) ) return False; if ( MARSHALLING(&hbin->ps) ) name_length = strlen(vk->valuename); if ( !prs_uint16( "name_length", ps, depth, &name_length )) return False; if ( !prs_uint32( "data_size", ps, depth, &vk->data_size )) return False; if ( !prs_uint32( "data_off", ps, depth, &vk->data_off )) return False; if ( !prs_uint32( "type", ps, depth, &vk->type)) return False; if ( !prs_uint16( "flag", ps, depth, &vk->flag)) return False; offset = prs_offset( ps ); offset += 2; /* skip 2 bytes */ prs_set_offset( ps, offset ); /* get the name */ if ( vk->flag&VK_FLAG_NAME_PRESENT ) { if ( UNMARSHALLING(&hbin->ps) ) { if ( !(vk->valuename = PRS_ALLOC_MEM( ps, char, name_length+1 ))) return False; } if ( !prs_uint8s( True, "name", ps, depth, (uint8*)vk->valuename, name_length ) ) return False; } end_off = prs_offset( &hbin->ps ); /* get the data if necessary */ if ( vk->data_size != 0 ) { BOOL charmode = False; if ( (vk->type == REG_SZ) || (vk->type == REG_MULTI_SZ) ) charmode = True; /* the data is stored in the offset if the size <= 4 */ if ( !(vk->data_size & VK_DATA_IN_OFFSET) ) { REGF_HBIN *hblock = hbin; uint32 data_rec_size; if ( UNMARSHALLING(&hbin->ps) ) { if ( !(vk->data = PRS_ALLOC_MEM( ps, uint8, vk->data_size) ) ) return False; } /* this data can be in another hbin */ if ( !hbin_contains_offset( hbin, vk->data_off ) ) { if ( !(hblock = lookup_hbin_block( file, vk->data_off )) ) return False; } if ( !(prs_set_offset( &hblock->ps, (vk->data_off+HBIN_HDR_SIZE-hblock->first_hbin_off)-sizeof(uint32) )) ) return False; if ( MARSHALLING(&hblock->ps) ) { data_rec_size = ( (vk->data_size+sizeof(uint32)) & 0xfffffff8 ) + 8; data_rec_size = ( data_rec_size - 1 ) ^ 0xFFFFFFFF; } if ( !prs_uint32( "data_rec_size", &hblock->ps, depth, &data_rec_size )) return False; if ( !prs_uint8s( charmode, "data", &hblock->ps, depth, vk->data, vk->data_size) ) return False; if ( MARSHALLING(&hblock->ps) ) hblock->dirty = True; } else { if ( !(vk->data = PRS_ALLOC_MEM( ps, uint8, 4 ) ) ) return False; SIVAL( vk->data, 0, vk->data_off ); } } /* data_size must be divisible by 8 and large enough to hold the original record */ data_size = ((start_off - end_off ) & 0xfffffff8 ); if ( data_size != vk->rec_size ) DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk->rec_size)); if ( MARSHALLING(&hbin->ps) ) hbin->dirty = True; return True;}/******************************************************************* read a VK record which is contained in the HBIN block stored in the prs_struct *ps.*******************************************************************/static BOOL hbin_prs_vk_records( const char *desc, REGF_HBIN *hbin, int depth, REGF_NK_REC *nk, REGF_FILE *file ){ int i; uint32 record_size; prs_debug(&hbin->ps, depth, desc, "prs_vk_records"); depth++; /* check if we have anything to do first */ if ( nk->num_values == 0 ) return True; if ( UNMARSHALLING(&hbin->ps) ) { if ( !(nk->values = PRS_ALLOC_MEM( &hbin->ps, REGF_VK_REC, nk->num_values ) ) ) return False; } /* convert the offset to something relative to this HBIN block */ if ( !prs_set_offset( &hbin->ps, nk->values_off+HBIN_HDR_SIZE-hbin->first_hbin_off-sizeof(uint32)) ) return False; if ( MARSHALLING( &hbin->ps) ) { record_size = ( ( nk->num_values * sizeof(uint32) ) & 0xfffffff8 ) + 8; record_size = (record_size - 1) ^ 0xFFFFFFFF; } if ( !prs_uint32( "record_size", &hbin->ps, depth, &record_size ) ) return False; for ( i=0; i<nk->num_values; i++ ) { if ( !prs_uint32( "vk_off", &hbin->ps, depth, &nk->values[i].rec_off ) ) return False; } for ( i=0; i<nk->num_values; i++ ) { REGF_HBIN *sub_hbin = hbin; uint32 new_offset; if ( !hbin_contains_offset( hbin, nk->values[i].rec_off ) ) { sub_hbin = lookup_hbin_block( file, nk->values[i].rec_off ); if ( !sub_hbin ) { DEBUG(0,("hbin_prs_vk_records: Failed to find HBIN block containing offset [0x%x]\n", nk->values[i].hbin_off)); return False; } } new_offset = nk->values[i].rec_off + HBIN_HDR_SIZE - sub_hbin->first_hbin_off; if ( !prs_set_offset( &sub_hbin->ps, new_offset ) ) return False; if ( !hbin_prs_vk_rec( "vk_rec", sub_hbin, depth, &nk->values[i], file ) ) return False; } if ( MARSHALLING(&hbin->ps) ) hbin->dirty = True; return True;}/**************************************************************************************************************************************/static REGF_SK_REC* find_sk_record_by_offset( REGF_FILE *file, uint32 offset ){ REGF_SK_REC *p_sk; for ( p_sk=file->sec_desc_list; p_sk; p_sk=p_sk->next ) { if ( p_sk->sk_off == offset ) return p_sk; } return NULL;}/**************************************************************************************************************************************/static REGF_SK_REC* find_sk_record_by_sec_desc( REGF_FILE *file, SEC_DESC *sd ){ REGF_SK_REC *p; for ( p=file->sec_desc_list; p; p=p->next ) { if ( sec_desc_equal( p->sec_desc, sd ) ) return p; } /* failure */ return NULL;}/**************************************************************************************************************************************/static BOOL hbin_prs_key( REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -