/* Parses an SHA1 hash for its value * Returns 1 if successful or -1 on error */ int libewf_hash_values_parse_sha1_hash( libfvalue_table_t *hash_values, const uint8_t *sha1_hash, size_t sha1_hash_size, libcerror_error_t **error ) { uint8_t sha1_hash_string[ 41 ]; libfvalue_value_t *hash_value = NULL; static char *function = "libewf_hash_values_parse_sha1_hash"; size_t sha1_hash_index = 0; size_t sha1_hash_string_index = 0; int result = 0; uint8_t sha1_digit = 0; if( hash_values == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid hash values.", function ); return( -1 ); } if( sha1_hash == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid SHA1 hash.", function ); return( -1 ); } if( sha1_hash_size < 20 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: SHA1 hash too small.", function ); return( -1 ); } result = libfvalue_table_get_value_by_identifier( hash_values, (uint8_t *) "SHA1", 5, &hash_value, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve if hash value: SHA1.", function ); goto on_error; } else if( result == 0 ) { for( sha1_hash_index = 0; sha1_hash_index < sha1_hash_size; sha1_hash_index++ ) { sha1_digit = sha1_hash[ sha1_hash_index ] / 16; if( sha1_digit <= 9 ) { sha1_hash_string[ sha1_hash_string_index++ ] = (uint8_t) '0' + sha1_digit; } else { sha1_hash_string[ sha1_hash_string_index++ ] = (uint8_t) 'a' + ( sha1_digit - 10 ); } sha1_digit = sha1_hash[ sha1_hash_index ] % 16; if( sha1_digit <= 9 ) { sha1_hash_string[ sha1_hash_string_index++ ] = (uint8_t) '0' + sha1_digit; } else { sha1_hash_string[ sha1_hash_string_index++ ] = (uint8_t) 'a' + ( sha1_digit - 10 ); } } sha1_hash_string[ sha1_hash_string_index++ ] = 0; if( libfvalue_value_type_initialize( &hash_value, LIBFVALUE_VALUE_TYPE_STRING_UTF8, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create hash value.", function ); goto on_error; } if( libfvalue_value_set_identifier( hash_value, (uint8_t *) "SHA1", 5, LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set hash value: SHA1 identifier.", function ); goto on_error; } if( libfvalue_value_set_data( hash_value, (uint8_t *) sha1_hash_string, 41, LIBFVALUE_CODEPAGE_UTF8, LIBFVALUE_VALUE_DATA_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set hash value: SHA1 data.", function ); goto on_error; } if( libfvalue_table_set_value( hash_values, hash_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set hash value: SHA1 in table.", function ); goto on_error; } hash_value = NULL; } return( 1 ); on_error: if( hash_value != NULL ) { libfvalue_value_free( &hash_value, NULL ); } return( -1 ); }
/* Parses a MD5 hash for its value * Returns 1 if successful or -1 on error */ int libewf_hash_values_parse_md5_hash( libfvalue_table_t *hash_values, const uint8_t *md5_hash, size_t md5_hash_size, libcerror_error_t **error ) { uint8_t md5_hash_string[ 33 ]; libfvalue_value_t *hash_value = NULL; static char *function = "libewf_hash_values_parse_md5_hash"; size_t md5_hash_index = 0; size_t md5_hash_string_index = 0; uint8_t md5_digit = 0; int result = 0; if( md5_hash == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid MD5 hash.", function ); return( -1 ); } if( md5_hash_size < 16 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: MD5 hash too small.", function ); return( -1 ); } result = libfvalue_table_get_value_by_identifier( hash_values, (uint8_t *) "MD5", 4, &hash_value, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve if hash value: MD5.", function ); goto on_error; } else if( result == 0 ) { for( md5_hash_index = 0; md5_hash_index < md5_hash_size; md5_hash_index++ ) { md5_digit = md5_hash[ md5_hash_index ] / 16; if( md5_digit <= 9 ) { md5_hash_string[ md5_hash_string_index++ ] = (uint8_t) '0' + md5_digit; } else { md5_hash_string[ md5_hash_string_index++ ] = (uint8_t) 'a' + ( md5_digit - 10 ); } md5_digit = md5_hash[ md5_hash_index ] % 16; if( md5_digit <= 9 ) { md5_hash_string[ md5_hash_string_index++ ] = (uint8_t) '0' + md5_digit; } else { md5_hash_string[ md5_hash_string_index++ ] = (uint8_t) 'a' + ( md5_digit - 10 ); } } md5_hash_string[ md5_hash_string_index++ ] = 0; if( libfvalue_value_type_initialize( &hash_value, LIBFVALUE_VALUE_TYPE_STRING_UTF8, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create hash value.", function ); goto on_error; } if( libfvalue_value_set_identifier( hash_value, (uint8_t *) "MD5", 4, LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set hash value: MD5 identifier.", function ); goto on_error; } if( libfvalue_value_set_data( hash_value, (uint8_t *) md5_hash_string, 33, LIBFVALUE_CODEPAGE_UTF8, LIBFVALUE_VALUE_DATA_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set hash value: MD5 data.", function ); goto on_error; } if( libfvalue_table_set_value( hash_values, hash_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set hash value: MD5 in table.", function ); goto on_error; } hash_value = NULL; } return( 1 ); on_error: if( hash_value != NULL ) { libfvalue_value_free( &hash_value, NULL ); } return( -1 ); }
/* Reads string values * Returns 1 if successful or -1 on error */ int libwrc_string_values_read( libwrc_language_entry_t *language_entry, libwrc_io_handle_t *io_handle, libbfio_handle_t *file_io_handle, uint32_t identifier, libwrc_data_descriptor_t *data_descriptor, libcerror_error_t **error ) { libfvalue_value_t *string_value = NULL; uint8_t *resource_data = NULL; uint8_t *string_resource_data = NULL; static char *function = "libwrc_string_values_read"; off64_t file_offset = 0; size_t resource_data_size = 0; ssize_t read_count = 0; uint32_t string_identifier = 0; uint32_t string_index = 0; uint32_t string_size = 0; int value_index = 0; if( language_entry == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid language entry.", function ); return( -1 ); } if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( data_descriptor == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data descriptor.", function ); return( -1 ); } file_offset = data_descriptor->virtual_address - io_handle->virtual_address; if( libbfio_handle_seek_offset( file_io_handle, file_offset, SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek resource data offset: %" PRIi64 ".", function, file_offset ); goto on_error; } resource_data_size = (size_t) data_descriptor->size; resource_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * resource_data_size ); if( resource_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create resource data.", function ); goto on_error; } read_count = libbfio_handle_read_buffer( file_io_handle, resource_data, resource_data_size, error ); if( read_count != (ssize_t) resource_data_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read resource data.", function ); goto on_error; } string_resource_data = resource_data; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: resource data:\n", function ); libcnotify_print_data( string_resource_data, resource_data_size, 0 ); } #endif while( resource_data_size > 0 ) { byte_stream_copy_to_uint16_little_endian( string_resource_data, string_size ); string_resource_data += sizeof( uint16_t ); resource_data_size -= sizeof( uint16_t ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: string: %02" PRIu32 " length\t\t\t\t: %" PRIu32 "\n", function, string_index, string_size ); } #endif if( string_size > 0 ) { string_identifier = ( identifier << 4 ) | string_index; string_size *= 2; if( string_size > resource_data_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: string size value out of bound.", function ); goto on_error; } if( libfvalue_value_type_initialize( &string_value, LIBFVALUE_VALUE_TYPE_STRING_UTF16, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create string value.", function ); goto on_error; } if( libfvalue_value_set_identifier( string_value, (uint8_t *) &string_identifier, 4, LIBFVALUE_VALUE_FLAG_IDENTIFIER_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to set identifier of string value.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: string: %02" PRIu32 " data:\n", function, string_index ); libcnotify_print_data( string_resource_data, (size_t) string_size, 0 ); } #endif if( libfvalue_value_set_data( string_value, string_resource_data, (size_t) string_size, LIBFVALUE_CODEPAGE_UTF16_LITTLE_ENDIAN, LIBFVALUE_VALUE_DATA_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set data of string value.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: string: %02" PRIu32 " value\t\t\t\t: ", function, string_index ); if( libfvalue_value_print( string_value, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print string value.", function ); goto on_error; } libcnotify_printf( "\n" ); } #endif string_resource_data += (size_t) string_size; resource_data_size -= (size_t) string_size; if( libwrc_language_entry_append_value( language_entry, &value_index, (intptr_t *) string_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append string value.", function ); goto on_error; } string_value = NULL; } #if defined( HAVE_DEBUG_OUTPUT ) else if( libcnotify_verbose != 0 ) { libcnotify_printf( "\n" ); } #endif string_index++; } memory_free( resource_data ); /* TODO validate if number of strings is 16 ? */ return( 1 ); on_error: if( string_value != NULL ) { libfvalue_value_free( &string_value, NULL ); } if( resource_data != NULL ) { memory_free( resource_data ); } return( -1 ); }