From 0e4b8aa15b0d743dd1bdc91aceceee4e831a7c42 Mon Sep 17 00:00:00 2001 From: Woniuke Date: Thu, 19 Aug 2021 14:34:11 +0800 Subject: [PATCH 1/2] =?UTF-8?q?add=20new=20value=20in=203.3.=20Volume=20sh?= =?UTF-8?q?ell=20item=EF=BC=8Cfix=20some=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- documentation/Windows Shell Item format.asciidoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/documentation/Windows Shell Item format.asciidoc b/documentation/Windows Shell Item format.asciidoc index ad1c058..0c1caf0 100644 --- a/documentation/Windows Shell Item format.asciidoc +++ b/documentation/Windows Shell Item format.asciidoc @@ -297,6 +297,7 @@ sub-type or flags. | 0x02 | | [yellow-background]*Unknown (0x23 C:, 0x2f C: or D:, 0x2a J:)* | 0x04 | | [yellow-background]*Unknown (0x23 C:, 0x25 D:)* | 0x08 | | Is removable media (0x23 C:, 0x29 A:, 0x2a J:) +| 0x0E | | CLSID Item |=== Values that have been seen: 0x23, 0x25, 0x29, 0x2a, 0x2e, 0x2f @@ -313,10 +314,10 @@ Includes the 2 bytes of the size itself 0x20 after applying a bitmask of 0x70 4+| _If class type indicator flag 0x01 (has name) is not set_ | 3 | 1 | [yellow-background]*Unknown (Flags)* -[yellow-background]*Seen 0x00, 0x1e, 0x80* +[yellow-background]*Seen 0x00, 0x1e, 0x80* | | 4 | 16 | [yellow-background]*Volume identifier?* + -Contains a GUID + -Control Panel and Printers folder identifier seen in windows 95 lnk +Contains a GUID + +Control Panel and Printers folder identifier seen in windows 95 lnk | 4+| _If class type indicator flag 0x01 (has name) is set_ | 3 | 20 | | Volume name + ASCII string with end-of-string character + From 1537de1982a96795bbc12e3c3087fe70a49121f9 Mon Sep 17 00:00:00 2001 From: Woniuke Date: Thu, 19 Aug 2021 15:34:56 +0800 Subject: [PATCH 2/2] Add implementation for parser control panel cpl file --- .../libfwsi_control_panel_cpl_file_values.c | 68 +++++++++++++-- .../libfwsi_control_panel_cpl_file_values.h | 82 ++++++++++++++++++- libfwsi/libfwsi_item.c | 10 +++ 3 files changed, 152 insertions(+), 8 deletions(-) diff --git a/libfwsi/libfwsi_control_panel_cpl_file_values.c b/libfwsi/libfwsi_control_panel_cpl_file_values.c index 155cd2b..4fdefbc 100644 --- a/libfwsi/libfwsi_control_panel_cpl_file_values.c +++ b/libfwsi/libfwsi_control_panel_cpl_file_values.c @@ -62,8 +62,7 @@ int libfwsi_control_panel_cpl_file_values_initialize( return( -1 ); } - *control_panel_cpl_file_values = memory_allocate_structure( - libfwsi_control_panel_cpl_file_values_t ); + *control_panel_cpl_file_values = memory_allocate_structure(libfwsi_control_panel_cpl_file_values_t); if( *control_panel_cpl_file_values == NULL ) { @@ -79,7 +78,7 @@ int libfwsi_control_panel_cpl_file_values_initialize( if( memory_set( *control_panel_cpl_file_values, 0, - sizeof( libfwsi_control_panel_cpl_file_values_t ) ) == NULL ) + sizeof(libfwsi_control_panel_cpl_file_values_t)) == NULL ) { libcerror_error_set( error, @@ -125,6 +124,11 @@ int libfwsi_control_panel_cpl_file_values_free( } if( *control_panel_cpl_file_values != NULL ) { + if ( (*control_panel_cpl_file_values)->string_buffer != NULL) + { + memory_free((*control_panel_cpl_file_values)->string_buffer); + } + memory_free( *control_panel_cpl_file_values ); @@ -146,6 +150,9 @@ int libfwsi_control_panel_cpl_file_values_read_data( size_t data_offset = 0; size_t string_size = 0; uint32_t signature = 0; + size_t string_buffer_length = 0; + uint16_t name_offset = 0; + uint16_t comments_offset = 0; #if defined( HAVE_DEBUG_OUTPUT ) uint32_t value_32bit = 0; @@ -194,13 +201,64 @@ int libfwsi_control_panel_cpl_file_values_read_data( /* Do not try to parse unsupported shell item signatures */ byte_stream_copy_to_uint32_little_endian( - &( data[ 4 ] ), + &( data[ 12 ] ), signature ); - if( signature != 0xffffff38UL ) + if( signature != 0x00006a00UL ) { return( 0 ); } + + byte_stream_copy_to_uint16_little_endian( + data, + control_panel_cpl_file_values->size + ); + + control_panel_cpl_file_values->class_type = data[2]; + + byte_stream_copy_to_uint32_little_endian( + &(data[4]), + control_panel_cpl_file_values->signature + ); + byte_stream_copy_to_uint32_little_endian( + &(data[12]), + control_panel_cpl_file_values->signature2 + ); + + string_buffer_length = data_size - 24; + if (string_buffer_length >= 0) + { + control_panel_cpl_file_values->string_buffer = + (uint16_t*)memory_allocate(string_buffer_length + 2); + } + if (control_panel_cpl_file_values->string_buffer != NULL) + { + memory_set(control_panel_cpl_file_values->string_buffer, 0, string_buffer_length + 2); + + memory_copy(control_panel_cpl_file_values->string_buffer, &(data[24]), string_buffer_length); + control_panel_cpl_file_values->cpl_path = control_panel_cpl_file_values->string_buffer; + + byte_stream_copy_to_uint16_little_endian( + &(data[20]), + name_offset + ); + byte_stream_copy_to_uint16_little_endian( + &(data[22]), + comments_offset + ); + if (name_offset * 2 < string_buffer_length) + { + control_panel_cpl_file_values->name = + control_panel_cpl_file_values->string_buffer + name_offset; + } + if (comments_offset * 2 < string_buffer_length) + { + control_panel_cpl_file_values->comments = + control_panel_cpl_file_values->string_buffer + comments_offset; + } + } + return(1); + #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { diff --git a/libfwsi/libfwsi_control_panel_cpl_file_values.h b/libfwsi/libfwsi_control_panel_cpl_file_values.h index f72fdea..3066c39 100644 --- a/libfwsi/libfwsi_control_panel_cpl_file_values.h +++ b/libfwsi/libfwsi_control_panel_cpl_file_values.h @@ -33,11 +33,87 @@ extern "C" { typedef struct libfwsi_control_panel_cpl_file_values libfwsi_control_panel_cpl_file_values_t; +//original data struct define +#pragma pack(push, 1) +struct libfwsi_control_panel_cpl_file_values_original +{ + /*offset 0*/ + uint16_t size; + + /*offset 2*/ + /*must be zero*/ + uint8_t class_type; + + /*offset 3*/ + /*seen as zero*/ + uint8_t unknown1; + + /*seen as follow + *0x00000000 + *0xffffee79 + *0xfffff444 + *0xffffff36 + *0xffffff37 + *0xffffff38 + *0xffffff9a + *0xffffff9c + *0xffffffff + */ + /*offset 4*/ + uint32_t signature; + + /*seen as zero*/ + /*offset 8*/ + uint32_t unknown2; + + /*0x00006a00*/ + /*offset 12*/ + uint32_t signature2; + + /*seen as zero*/ + /*offset 16*/ + uint32_t unknown3; + + /*offset 20*/ + uint16_t name_offset; + /*offset 22*/ + uint16_t comments_offset; + + /* + * bytes size = size - 0x18 + * .cpl file path + * name string + * comments string + */ + /*offset 24*/ + uint16_t string[0]; +}; +#pragma pack(pop) + struct libfwsi_control_panel_cpl_file_values { - /* Dummy - */ - int dummy; + + uint16_t size; + /*class_type must be zero*/ + uint8_t class_type; + /*signature seen as + *0x00000000 + *0xffffee79 + *0xfffff444 + *0xffffff36 + *0xffffff37 + *0xffffff38 + *0xffffff9a + *0xffffff9c + *0xffffffff + */ + uint32_t signature; + uint32_t signature2; //seen as 0x00006a00 + + uint16_t* string_buffer; + uint16_t* cpl_path; + uint16_t* name; + uint16_t* comments; }; int libfwsi_control_panel_cpl_file_values_initialize( diff --git a/libfwsi/libfwsi_item.c b/libfwsi/libfwsi_item.c index 4176d9a..62ad67a 100644 --- a/libfwsi/libfwsi_item.c +++ b/libfwsi/libfwsi_item.c @@ -515,6 +515,16 @@ int libfwsi_item_copy_from_byte_stream( break; } } + if( (internal_item->type == 0) + && (internal_item->data_size >= 28)) + { + byte_stream_copy_to_uint32_little_endian( + &(byte_stream[12]), + signature); + if (signature == 0x00006a00) + internal_item->type = LIBFWSI_ITEM_TYPE_CONTROL_PANEL_CPL_FILE; + + } if( ( internal_item->type == 0 ) && ( internal_item->data_size >= 38 ) ) {