📄 libewf_section.c
字号:
libewf_common_free( table ); return( NULL ); }#ifdef HAVE_DEBUG_OUTPUT LIBEWF_VERBOSE_EXEC( libewf_dump_data( table->padding, 16 ); );#endif /* The table size contains the size of the CRC (4 bytes) */ if( ewf_crc_calculate( &calculated_crc, (uint8_t *) table, ( EWF_TABLE_SIZE - EWF_CRC_SIZE ), 1 ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to calculate CRC.\n" ); libewf_common_free( table ); return( NULL ); } if( libewf_endian_convert_32bit( &stored_crc, table->crc ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to convert stored CRC value.\n" ); libewf_common_free( table ); return( NULL ); } if( stored_crc != calculated_crc ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: CRC does not match (in file: %" PRIu32 ", calculated: %" PRIu32 ").\n", stored_crc, calculated_crc ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { libewf_common_free( table ); return( NULL ); } } if( libewf_endian_convert_32bit( amount_of_chunks, table->amount_of_chunks ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to convert amount of chunks value.\n" ); libewf_common_free( table ); return( NULL ); } libewf_common_free( table ); LIBEWF_VERBOSE_PRINT( "libewf_offset_table_read: table is of size %" PRIu32 " chunks CRC %" PRIu32 " (%" PRIu32 ").\n", *amount_of_chunks, stored_crc, calculated_crc ); size -= EWF_TABLE_SIZE; if( *amount_of_chunks == 0 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: table contains no offsets.\n" ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { return( NULL ); } } else { /* Check if the maximum amount of offsets is not exceeded */ if( *amount_of_chunks > EWF_MAXIMUM_OFFSETS_IN_TABLE ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: table contains more than %d offsets!.\n", EWF_MAXIMUM_OFFSETS_IN_TABLE ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { return( NULL ); } } offsets = (EWF_TABLE_OFFSET *) libewf_common_alloc( EWF_TABLE_OFFSET_SIZE * *amount_of_chunks ); if( offsets == NULL ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to allocated table offsets.\n" ); return( NULL ); } if( ewf_table_offsets_read( offsets, file_descriptor, *amount_of_chunks ) <= -1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to read table offsets.\n" ); libewf_common_free( offsets ); return( NULL ); } size -= ( EWF_TABLE_OFFSET_SIZE * *amount_of_chunks ); /* The EWF-S01 format does not contain a CRC after the offsets */ if( ewf_format != EWF_FORMAT_S01 ) { /* Check if the offset table CRC matches */ if( ewf_crc_calculate( &calculated_crc, (uint8_t *) offsets, ( EWF_TABLE_OFFSET_SIZE * *amount_of_chunks ), 1 ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to calculate CRC.\n" ); libewf_common_free( offsets ); return( NULL ); } if( ewf_crc_read( &stored_crc, file_descriptor ) != (int32_t) EWF_CRC_SIZE ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to read CRC from file descriptor.\n" ); libewf_common_free( offsets ); return( NULL ); } if( stored_crc != calculated_crc ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: CRC does not match (in file: %" PRIu32 ", calculated: %" PRIu32 ").\n", stored_crc, calculated_crc ); if( error_tollerance < LIBEWF_ERROR_TOLLERANCE_COMPENSATE ) { libewf_common_free( offsets ); return( NULL ); } } size -= EWF_CRC_SIZE; } reallocation = libewf_fill_offset_table( offset_table, offsets, *amount_of_chunks, file_descriptor, segment_number, error_tollerance ); libewf_common_free( offsets ); if( reallocation == NULL ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to fill offset table.\n" ); return( NULL ); } offset_table = reallocation; if( libewf_calculate_last_offset( offset_table, section_list, file_descriptor, segment_number, error_tollerance ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to calculate last offset.\n" ); return( NULL ); } } /* Skip the chunk data within the section */ if( ( size > 0 ) && ( size <= (uint64_t) INT32_MAX ) ) { if( libewf_common_lseek( file_descriptor, size, SEEK_CUR ) == -1 ) { LIBEWF_WARNING_PRINT( "libewf_offset_table_read: unable to align with next section.\n" ); return( NULL ); } } return( offset_table );}/* Compare the offsets in tabel and table2 sections * Returns a 0 if table differ */uint8_t libewf_compare_offset_tables( LIBEWF_OFFSET_TABLE *offset_table1, LIBEWF_OFFSET_TABLE *offset_table2 ){ uint64_t iterator = 0; if( ( offset_table1 == NULL ) || ( offset_table2 == NULL ) ) { LIBEWF_WARNING_PRINT( "libewf_compare_offset_tables: invalid offset table.\n" ); return( 0 ); } /* Check if table and table2 are the same */ if( offset_table1->amount != offset_table2->amount ) { LIBEWF_VERBOSE_PRINT( "libewf_compare_offset_tables: offset tables differ in size.\n" ); return( 0 ); } else { for( iterator = 0; iterator < offset_table1->amount; iterator++ ) { if( offset_table1->offset[ iterator ] != offset_table2->offset[ iterator ] ) { LIBEWF_VERBOSE_PRINT( "libewf_compare_offset_tables: offset tables differ in offset for chunk: %" PRIu64 " (table1: %" PRIu64 ", table2: %" PRIu64 ").\n", iterator, offset_table1->offset[ iterator ], offset_table2->offset[ iterator ] ); return( 0 ); } } } return( 1 );}/* Reads a table section * Returns the amount of bytes read, or -1 on error */ssize_t libewf_section_table_read( LIBEWF_INTERNAL_HANDLE *internal_handle, int file_descriptor, size_t size, LIBEWF_SECTION_LIST *section_list, uint16_t segment_number ){ LIBEWF_OFFSET_TABLE *reallocation = NULL; uint32_t amount_of_chunks = 0; if( internal_handle == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_read: invalid handle.\n" ); return( -1 ); } if( internal_handle->media == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_read: invalid handle - missing subhandle media.\n" ); return( -1 ); } if( internal_handle->segment_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_read: invalid handle - missing segment table.\n" ); return( -1 ); } if( section_list == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_read: invalid section list.\n" ); return( -1 ); } if( internal_handle->offset_table == NULL ) { internal_handle->offset_table = libewf_offset_table_alloc( internal_handle->media->amount_of_chunks ); if( internal_handle->offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_read: unable to create offset table.\n" ); return( -1 ); } } reallocation = libewf_offset_table_read( internal_handle->offset_table, section_list, &amount_of_chunks, file_descriptor, segment_number, size, internal_handle->ewf_format, internal_handle->error_tollerance ); if( reallocation == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_read: unable to read offset table.\n" ); return( -1 ); } internal_handle->offset_table = reallocation; internal_handle->segment_table->amount_of_chunks[ segment_number ] += amount_of_chunks; return( (int32_t) size );}/* Write a table or table2 section to file * Returns the amount of bytes written, or -1 on error */ssize_t libewf_section_table_write( LIBEWF_INTERNAL_HANDLE *internal_handle, int file_descriptor, off_t start_offset, LIBEWF_OFFSET_TABLE *offset_table, uint32_t offset_table_index, uint32_t amount_of_offsets, EWF_CHAR *section_header, size_t additional_size ){ EWF_TABLE *table = NULL; EWF_TABLE_OFFSET *offsets = NULL; ssize_t section_write_count = 0; ssize_t table_write_count = 0; ssize_t table_offsets_write_count = 0; size_t size = 0; uint32_t offset_value = 0; uint32_t iterator = 0; uint8_t write_crc = 0; if( internal_handle == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: invalid handle.\n" ); return( -1 ); } if( offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: invalid offset table.\n" ); return( -1 ); } size = EWF_TABLE_SIZE + ( EWF_TABLE_OFFSET_SIZE * amount_of_offsets ) + additional_size; if( internal_handle->ewf_format != EWF_FORMAT_S01 ) { write_crc = 1; size += EWF_CRC_SIZE; } table = (EWF_TABLE *) libewf_common_alloc( EWF_TABLE_SIZE ); if( table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to create table.\n" ); return( -1 ); } if( libewf_common_memset( table, 0, EWF_TABLE_SIZE ) == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to clear table.\n" ); libewf_common_free( table ); return( -1 ); } offsets = (EWF_TABLE_OFFSET *) libewf_common_alloc( EWF_TABLE_OFFSET_SIZE * amount_of_offsets ); if( offsets == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to create offsets.\n" ); libewf_common_free( table ); return( -1 ); } if( libewf_endian_revert_32bit( amount_of_offsets, table->amount_of_chunks ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to revert amount of chunks value.\n" ); libewf_common_free( table ); libewf_common_free( offsets ); return( -1 ); } for( iterator = 0; iterator < amount_of_offsets; iterator++ ) { offset_value = offset_table->offset[ offset_table_index + iterator ]; if( offset_table->compressed[ offset_table_index + iterator ] != 0 ) { offset_value |= EWF_OFFSET_COMPRESSED_WRITE_MASK; } if( libewf_endian_revert_32bit( offset_value, (uint8_t *) offsets[ iterator ].offset ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to revert start offset.\n" ); libewf_common_free( table ); libewf_common_free( offsets ); return( -1 ); } } section_write_count = libewf_section_start_write( internal_handle, file_descriptor, section_header, size, start_offset ); if( section_write_count == -1 ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to write section to file.\n" ); libewf_common_free( table ); libewf_common_free( offsets ); return( -1 ); } table_write_count = ewf_table_write( table, file_descriptor ); table_offsets_write_count = ewf_table_offsets_write( offsets, file_descriptor, amount_of_offsets, write_crc ); libewf_common_free( table ); libewf_common_free( offsets ); if( table_write_count == -1 ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to write table to file.\n" ); return( -1 ); } if( table_offsets_write_count == -1 ) { LIBEWF_WARNING_PRINT( "libewf_section_table_write: unable to write table offsets to file.\n" ); return( -1 ); } return( section_write_count + table_write_count + table_offsets_write_count );}/* Reads a table2 section * Returns the amount of bytes read, or -1 on error */ssize_t libewf_section_table2_read( LIBEWF_INTERNAL_HANDLE *internal_handle, int file_descriptor, size_t size, LIBEWF_SECTION_LIST *section_list, uint16_t segment_number ){ LIBEWF_OFFSET_TABLE *reallocation = NULL; uint32_t amount_of_chunks = 0; if( internal_handle == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table2_read: invalid handle.\n" ); return( -1 ); } if( section_list == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table2_read: invalid section list.\n" ); return( -1 ); } if( size > (size_t) SSIZE_MAX ) { LIBEWF_WARNING_PRINT( "libewf_section_table2_read: invalid size only values below 2^32 are supported.\n" ); return( -1 ); } if( internal_handle->secondary_offset_table == NULL ) { internal_handle->secondary_offset_table = libewf_offset_table_alloc( internal_handle->media->amount_of_chunks ); if( internal_handle->secondary_offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table2_read: unable to create secondairy offset table.\n" ); return( -1 ); } } reallocation = libewf_offset_table_read( internal_handle->secondary_offset_table, section_list, &amount_of_chunks, file_descriptor, segment_number, size, internal_handle->ewf_format, internal_handle->error_tollerance ); if( reallocation == NULL ) { LIBEWF_WARNING_PRINT( "libewf_section_table2_read: unable to read offset table.\n" ); return( -1 ); } internal_handle->secondary_offset_table = reallocation; if( libewf_compare_offset_tables( internal_handle->offset_table, internal_handle->secondary_offset_table ) == 0 ) { LIBEWF_WARNING_PRINT( "libewf_section_table2_read: table1 and table2 differ.\n" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -