/src/libfsntfs/libfsntfs/libfsntfs_fixup_values.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Fix-up values functions |
3 | | * |
4 | | * Copyright (C) 2010-2024, Joachim Metz <joachim.metz@gmail.com> |
5 | | * |
6 | | * Refer to AUTHORS for acknowledgements. |
7 | | * |
8 | | * This program is free software: you can redistribute it and/or modify |
9 | | * it under the terms of the GNU Lesser General Public License as published by |
10 | | * the Free Software Foundation, either version 3 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
20 | | */ |
21 | | |
22 | | #include <common.h> |
23 | | #include <byte_stream.h> |
24 | | #include <types.h> |
25 | | |
26 | | #include "libfsntfs_fixup_values.h" |
27 | | #include "libfsntfs_libcerror.h" |
28 | | #include "libfsntfs_libcnotify.h" |
29 | | |
30 | | /* Applies the fix-up values to the data |
31 | | * Returns 1 if successful or -1 on error |
32 | | */ |
33 | | int libfsntfs_fixup_values_apply( |
34 | | uint8_t *data, |
35 | | size_t data_size, |
36 | | uint16_t fixup_values_offset, |
37 | | uint16_t number_of_fixup_values, |
38 | | libcerror_error_t **error ) |
39 | 14.4k | { |
40 | 14.4k | static char *function = "libfsntfs_fixup_values_apply"; |
41 | 14.4k | size_t data_offset = 0; |
42 | 14.4k | size_t fixup_placeholder_offset = 0; |
43 | 14.4k | size_t fixup_value_offset = 0; |
44 | 14.4k | size_t fixup_values_size = 0; |
45 | 14.4k | uint16_t fixup_value_index = 0; |
46 | | |
47 | | #if defined( HAVE_DEBUG_OUTPUT ) |
48 | | uint16_t value_16bit = 0; |
49 | | #endif |
50 | | |
51 | 14.4k | if( data == NULL ) |
52 | 0 | { |
53 | 0 | libcerror_error_set( |
54 | 0 | error, |
55 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
56 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
57 | 0 | "%s: invalid MFT entry.", |
58 | 0 | function ); |
59 | |
|
60 | 0 | return( -1 ); |
61 | 0 | } |
62 | 14.4k | if( data_size > (size_t) SSIZE_MAX ) |
63 | 0 | { |
64 | 0 | libcerror_error_set( |
65 | 0 | error, |
66 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
67 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
68 | 0 | "%s: invalid data size value out of bounds.", |
69 | 0 | function ); |
70 | |
|
71 | 0 | return( -1 ); |
72 | 0 | } |
73 | 14.4k | if( fixup_values_offset >= data_size ) |
74 | 12 | { |
75 | 12 | libcerror_error_set( |
76 | 12 | error, |
77 | 12 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
78 | 12 | LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, |
79 | 12 | "%s: invalid fix-up values offset value out of bounds.", |
80 | 12 | function ); |
81 | | |
82 | 12 | return( -1 ); |
83 | 12 | } |
84 | 14.4k | fixup_values_size = 2 + ( (size_t) number_of_fixup_values * 2 ); |
85 | | |
86 | 14.4k | if( ( number_of_fixup_values == 0 ) |
87 | 14.4k | || ( fixup_values_size > ( data_size - fixup_values_offset ) ) ) |
88 | 65 | { |
89 | 65 | libcerror_error_set( |
90 | 65 | error, |
91 | 65 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
92 | 65 | LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, |
93 | 65 | "%s: invalide number of fix-up values value out of bounds.", |
94 | 65 | function ); |
95 | | |
96 | 65 | return( -1 ); |
97 | 65 | } |
98 | | #if defined( HAVE_DEBUG_OUTPUT ) |
99 | | if( libcnotify_verbose != 0 ) |
100 | | { |
101 | | libcnotify_printf( |
102 | | "%s: fix-up values data:\n", |
103 | | function ); |
104 | | libcnotify_print_data( |
105 | | &( data[ fixup_values_offset ] ), |
106 | | fixup_values_size, |
107 | | 0 ); |
108 | | } |
109 | | #endif |
110 | 14.4k | fixup_placeholder_offset = (size_t) fixup_values_offset; |
111 | | |
112 | | #if defined( HAVE_DEBUG_OUTPUT ) |
113 | | if( libcnotify_verbose != 0 ) |
114 | | { |
115 | | byte_stream_copy_to_uint16_little_endian( |
116 | | &( data[ fixup_placeholder_offset ] ), |
117 | | value_16bit ); |
118 | | libcnotify_printf( |
119 | | "%s: fix-up placeholder value\t\t\t: 0x%04" PRIx16 "\n", |
120 | | function, |
121 | | value_16bit ); |
122 | | } |
123 | | #endif |
124 | 14.4k | fixup_value_offset = fixup_placeholder_offset + 2; |
125 | 14.4k | data_offset = 510; |
126 | | |
127 | 14.4k | for( fixup_value_index = 0; |
128 | 1.37M | fixup_value_index < number_of_fixup_values; |
129 | 1.36M | fixup_value_index++ ) |
130 | 1.36M | { |
131 | | #if defined( HAVE_DEBUG_OUTPUT ) |
132 | | if( libcnotify_verbose != 0 ) |
133 | | { |
134 | | byte_stream_copy_to_uint16_little_endian( |
135 | | &( data[ fixup_value_offset ] ), |
136 | | value_16bit ); |
137 | | libcnotify_printf( |
138 | | "%s: fix-up value: %" PRIu16 "\t\t\t\t: 0x%04" PRIx16 "\n", |
139 | | function, |
140 | | fixup_value_index, |
141 | | value_16bit ); |
142 | | } |
143 | | #endif |
144 | 1.36M | if( ( data_offset + 1 ) < data_size ) |
145 | 34.1k | { |
146 | 34.1k | if( ( data[ data_offset ] != data[ fixup_placeholder_offset ] ) |
147 | 34.1k | && ( data[ data_offset + 1 ] != data[ fixup_placeholder_offset + 1 ] ) ) |
148 | 14.0k | { |
149 | | #if defined( HAVE_DEBUG_OUTPUT ) |
150 | | if( libcnotify_verbose != 0 ) |
151 | | { |
152 | | byte_stream_copy_to_uint16_little_endian( |
153 | | &( data[ data_offset ] ), |
154 | | value_16bit ); |
155 | | libcnotify_printf( |
156 | | "%s: corruption detected - mismatch between placeholder and value at offset: %" PRIzd " (0x%04" PRIx16 ")\n", |
157 | | function, |
158 | | data_offset, |
159 | | value_16bit ); |
160 | | } |
161 | | #endif |
162 | | /* TODO handle error */ |
163 | 14.0k | } |
164 | | #if defined( HAVE_DEBUG_OUTPUT ) |
165 | | if( libcnotify_verbose != 0 ) |
166 | | { |
167 | | libcnotify_printf( |
168 | | "%s: applying fix-up value: %" PRIu16 "\t\t\t: (offset: %" PRIzd ") 0x%02" PRIx8 "%02" PRIx8 " => (offset: %" PRIzd ") 0x%02" PRIx8 "%02" PRIx8 "\n", |
169 | | function, |
170 | | fixup_value_index, |
171 | | data_offset, |
172 | | data[ data_offset + 1 ], |
173 | | data[ data_offset ], |
174 | | fixup_value_offset, |
175 | | data[ fixup_value_offset + 1 ], |
176 | | data[ fixup_value_offset ] ); |
177 | | } |
178 | | #endif |
179 | 34.1k | data[ data_offset ] = data[ fixup_value_offset ]; |
180 | 34.1k | data[ data_offset + 1 ] = data[ fixup_value_offset + 1 ]; |
181 | 34.1k | } |
182 | 1.36M | fixup_value_offset += 2; |
183 | 1.36M | data_offset += 512; |
184 | 1.36M | } |
185 | | #if defined( HAVE_DEBUG_OUTPUT ) |
186 | | if( libcnotify_verbose != 0 ) |
187 | | { |
188 | | libcnotify_printf( |
189 | | "\n" ); |
190 | | } |
191 | | #endif |
192 | 14.4k | return( 1 ); |
193 | 14.4k | } |
194 | | |