📄 libewf_section.c
字号:
count = libewf_section_volume_e01_read( internal_handle, file_descriptor, size ); } else { LIBEWF_WARNING_PRINT( "libewf_section_volume_read: mismatch in section data size.\n" ); return( -1 ); } if( ( count <= -1 ) || ( count != (int32_t) size ) ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_read: unable to read volume section.\n" ); return( -1 ); } if( internal_handle->media->amount_of_chunks == 0 ) { internal_handle->ewf_format = EWF_FORMAT_L01; } return( count );}/* Write an EWF-E01 (EnCase) volume section to file * Returns the amount of bytes read, or -1 on error */ssize_t libewf_section_volume_e01_write( LIBEWF_INTERNAL_HANDLE *internal_handle, int file_descriptor, off_t start_offset ){ EWF_VOLUME *volume = NULL; ssize_t section_write_count = 0; ssize_t volume_write_count = 0; size_t size = EWF_VOLUME_SIZE; if( internal_handle == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: invalid handle.\n" ); return( -1 ); } if( internal_handle->media == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: invalid handle - missing subhandle media.\n" ); return( -1 ); } volume = (EWF_VOLUME *) libewf_common_alloc( size ); if( volume == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to create volume.\n" ); return( -1 ); } if( libewf_common_memset( volume, 0, size ) == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_write: unable to clear volume.\n" ); libewf_common_free( volume ); return( -1 ); } if( internal_handle->format == LIBEWF_FORMAT_FTK ) { volume->media_type = 0x01; } else { volume->media_type = internal_handle->media->media_type; } volume->media_flags = internal_handle->media->media_flags; if( libewf_endian_revert_32bit( internal_handle->media->amount_of_chunks, volume->amount_of_chunks ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to revert amount of chunks value.\n" ); libewf_common_free( volume ); return( -1 ); } if( libewf_endian_revert_32bit( internal_handle->media->sectors_per_chunk, volume->sectors_per_chunk ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to revert sectors per chunk value.\n" ); libewf_common_free( volume ); return( -1 ); } if( libewf_endian_revert_32bit( internal_handle->media->bytes_per_sector, volume->bytes_per_sector ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to revert bytes per sector value.\n" ); libewf_common_free( volume ); return( -1 ); } if( libewf_endian_revert_32bit( internal_handle->media->amount_of_sectors, volume->amount_of_sectors ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to revert amount of sectors value.\n" ); libewf_common_free( volume ); return( -1 ); } LIBEWF_VERBOSE_PRINT( "libewf_section_volume_e01_write: amount_of_chunks: %" PRIu32 ", sectors_per_chunk: %" PRIu32 ", bytes_per_sector: %" PRIu32 ", amount_of_sectors: %" PRIu32 ".\n", internal_handle->media->amount_of_chunks, internal_handle->media->sectors_per_chunk, internal_handle->media->bytes_per_sector, internal_handle->media->amount_of_sectors ); if( ( internal_handle->format == LIBEWF_FORMAT_ENCASE5 ) || ( internal_handle->format == LIBEWF_FORMAT_ENCASE6 ) || ( internal_handle->format == LIBEWF_FORMAT_LINEN5 ) || ( internal_handle->format == LIBEWF_FORMAT_LINEN6 ) || ( internal_handle->format == LIBEWF_FORMAT_EWFX ) ) { volume->compression_level = (uint8_t) internal_handle->compression_level; if( libewf_common_memcpy( volume->guid, internal_handle->guid, 16 ) == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to set GUID.\n" ); libewf_common_free( volume ); return( -1 ); } if( libewf_endian_revert_32bit( internal_handle->media->error_granularity, volume->error_granularity ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to revert error granularity value.\n" ); libewf_common_free( volume ); return( -1 ); } } section_write_count = libewf_section_start_write( internal_handle, file_descriptor, (EWF_CHAR *) "volume", size, start_offset ); if( section_write_count == -1 ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to write section to file.\n" ); libewf_common_free( volume ); return( -1 ); } volume_write_count = ewf_volume_write( volume, file_descriptor ); libewf_common_free( volume ); if( volume_write_count == -1 ) { LIBEWF_WARNING_PRINT( "libewf_section_volume_e01_write: unable to write volume to file.\n" ); return( -1 ); } return( section_write_count + volume_write_count );}/* Fills the offset table * Returns the pointer to the offset table, or NULL on error */LIBEWF_OFFSET_TABLE *libewf_fill_offset_table( LIBEWF_OFFSET_TABLE *offset_table, EWF_TABLE_OFFSET *offsets, uint32_t amount_of_chunks, int file_descriptor, uint16_t segment_number, uint8_t error_tollerance ){ uint32_t chunk_size = 0; uint32_t current_offset = 0; uint32_t next_offset = 0; uint32_t raw_offset = 0; uint32_t iterator = 0; uint8_t compressed = 0; if( offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: invalid offset table.\n" ); return( NULL ); } /* Correct the last offset, to fill the table it should point to the first empty entry * the the last filled entry */ if( offset_table->last > 0 ) { offset_table->last++; } /* Allocate additional entries in the offset table if needed * - a single reallocation saves processing time */ if( offset_table->amount < ( offset_table->last + amount_of_chunks ) ) { offset_table = libewf_offset_table_realloc( offset_table, ( offset_table->last + amount_of_chunks ) ); if( offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: unable to reallocate offset table.\n" ); return( NULL ); } } /* Read the offsets from file */ if( libewf_endian_convert_32bit( &raw_offset, offsets[ iterator ].offset ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: unable to convert raw offset value.\n" ); return( NULL ); } /* The size of the last chunk must be determined differently */ while( iterator < ( amount_of_chunks - 1 ) ) { compressed = (uint8_t) ( raw_offset >> 31 ); current_offset = raw_offset & EWF_OFFSET_COMPRESSED_READ_MASK; if( libewf_endian_convert_32bit( &raw_offset, offsets[ iterator + 1 ].offset ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: unable to convert raw offset value.\n" ); return( NULL ); } next_offset = raw_offset & EWF_OFFSET_COMPRESSED_READ_MASK; if( next_offset < current_offset ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: invalid chunk offset larger than next.\n" ); return( NULL ); } chunk_size = next_offset - current_offset; if( current_offset > (uint32_t) INT32_MAX ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: invalid chunk offset only values below 2^32 are supported.\n" ); return( NULL ); } if( chunk_size == 0 ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: invalid chunk size - size is zero.\n" ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { return( NULL ); } } if( chunk_size > (uint32_t) INT32_MAX ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: invalid chunk size only values below 2^32 are supported.\n" ); return( NULL ); } if( libewf_offset_table_set_values( offset_table, offset_table->last, file_descriptor, compressed, (off_t) current_offset, (size_t) chunk_size, segment_number ) == -1 ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: unable to set value in offset table.\n" ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { return( NULL ); } } offset_table->last++; if( compressed == 0 ) { LIBEWF_VERBOSE_PRINT( "libewf_fill_offset_table: uncompressed chunk %" PRIu32 " read with offset %" PRIu32 " and size %" PRIu32 ".\n", offset_table->last, current_offset, chunk_size ); } else { LIBEWF_VERBOSE_PRINT( "libewf_fill_offset_table: compressed chunk %" PRIu32 " read with offset %" PRIu32 " and size %" PRIu32 ".\n", offset_table->last, current_offset, chunk_size ); } current_offset = next_offset; iterator++; } if( libewf_endian_convert_32bit( &raw_offset, offsets[ iterator ].offset ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: unable to convert raw offset value.\n" ); return( NULL ); } compressed = (uint8_t) ( raw_offset >> 31 ); current_offset = raw_offset & EWF_OFFSET_COMPRESSED_READ_MASK; if( current_offset > (uint32_t) INT32_MAX ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: invalid chunk offset only values below 2^32 are supported.\n" ); return( NULL ); } if( libewf_offset_table_set_values( offset_table, offset_table->last, file_descriptor, compressed, current_offset, 0, segment_number ) == -1 ) { LIBEWF_WARNING_PRINT( "libewf_fill_offset_table: unable to set value in offset table.\n" ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { return( NULL ); } } if( compressed == 0 ) { LIBEWF_VERBOSE_PRINT( "libewf_fill_offset_table: uncompressed last chunk %" PRIu32 " read with offset %" PRIu32 ".\n", ( offset_table->last + 1 ), current_offset ); } else { LIBEWF_VERBOSE_PRINT( "libewf_fill_offset_table: compressed last chunk %" PRIu32 " read with offset %" PRIu64 ".\n", ( offset_table->last + 1 ), current_offset ); } return( offset_table );}/* Calculate the last offset * Returns 1 if successful, -1 on error */int8_t libewf_calculate_last_offset( LIBEWF_OFFSET_TABLE *offset_table, LIBEWF_SECTION_LIST *section_list, int file_descriptor, uint16_t segment_number, uint8_t error_tollerance ){ LIBEWF_SECTION_LIST_ENTRY *section_list_entry = NULL; off_t last_offset = 0; size_t chunk_size = 0; if( offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_calculate_last_offset: invalid offset table.\n" ); return( -1 ); } if( section_list == NULL ) { LIBEWF_WARNING_PRINT( "libewf_calculate_last_offset: invalid section list.\n" ); return( -1 ); } /* * There is no indication how large the last chunk is. The only thing known is where it starts. * However it can be determined where the next section starts within the file. * The size of the last chunk is determined by subtracting the last offset from the offset of the section that follows. */ section_list_entry = section_list->first; last_offset = offset_table->offset[ offset_table->last ]; while( section_list_entry != NULL ) {#ifdef HAVE_DEBUG_OUTPUT LIBEWF_VERBOSE_PRINT( "libewf_calculate_last_offset: start offset: %jd last offset: %jd.\n", section_list_entry->start_offset, last_offset );#endif if( ( section_list_entry->start_offset < last_offset ) && ( last_offset < section_list_entry->end_offset ) ) { chunk_size = section_list_entry->end_offset - last_offset; if( last_offset > (off_t) INT32_MAX ) { LIBEWF_WARNING_PRINT( "libewf_calculate_last_offset: invalid last chunk offset only values below 2^32 are supported.\n" ); return( -1 ); } if( chunk_size == 0 ) { LIBEWF_WARNING_PRINT( "libewf_calculate_last_offset: invalid chunk size - size is zero.\n" ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { return( -1 ); } } if( chunk_size > (size_t) INT32_MAX ) { LIBEWF_WARNING_PRINT( "libewf_calculate_last_offset: invalid chunk size only values below 2^32 are supported.\n" ); return( -1 ); } if( libewf_offset_table_set_values( offset_table, offset_table->last, file_descriptor, offset_table->compressed[ offset_table->last ], last_offset, chunk_size, segment_number ) == -1 ) { LIBEWF_WARNING_PRINT( "libewf_calculate_last_offset: unable to set value in offset table.\n" ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { return( -1 ); } } LIBEWF_VERBOSE_PRINT( "libewf_calculate_last_offset: last chunk %" PRIu32 " calculated with offset: %jd and size %zu.\n", ( offset_table->last + 1 ), last_offset, chunk_size ); break; } section_list_entry = section_list_entry->next; } return( 1 );}/* Reads an offset table * Returns the pointer to the offset table, or NULL on error */LIBEWF_OFFSET_TABLE *libewf_offset_table_read( LIBEWF_OFFSET_TABLE *offset_table, LIBEWF_SECTION_LIST *section_list, uint32_t *amount_of_chunks, int file_descriptor, uint16_t segment_number, size_t size, uint8_t ewf_format, uint8_t error_tollerance ){ LIBEWF_OFFSET_TABLE *reallocation = NULL; EWF_TABLE *table = NULL; EWF_TABLE_OFFSET *offsets = NULL; EWF_CRC calculated_crc = 0; EWF_CRC stored_crc = 0; if( offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: invalid offset table.\n" ); return( NULL ); } if( section_list == NULL ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: invalid section list.\n" ); return( NULL ); } if( amount_of_chunks == NULL ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: invalid amount of chunks.\n" ); return( NULL ); } table = (EWF_TABLE *) libewf_common_alloc( EWF_TABLE_SIZE ); if( table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to allocate table.\n" ); return( NULL ); } if( ewf_table_read( table, file_descriptor ) <= -1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to read table.\n" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -