Coverage Report

Created: 2024-10-02 06:58

/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