Coverage Report

Created: 2024-06-12 07:07

/src/libregf/libregf/libregf_hive_bin_header.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Hive bin header functions
3
 *
4
 * Copyright (C) 2009-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 <memory.h>
25
#include <types.h>
26
27
#include "libregf_debug.h"
28
#include "libregf_hive_bin_header.h"
29
#include "libregf_io_handle.h"
30
#include "libregf_libcerror.h"
31
#include "libregf_libcnotify.h"
32
#include "libregf_libfdatetime.h"
33
34
#include "regf_hive_bin.h"
35
36
const char *regf_hive_bin_signature = "hbin";
37
38
/* Creates hive bin header
39
 * Make sure the value hive_bin_header is referencing, is set to NULL
40
 * Returns 1 if successful or -1 on error
41
 */
42
int libregf_hive_bin_header_initialize(
43
     libregf_hive_bin_header_t **hive_bin_header,
44
     libcerror_error_t **error )
45
6.70k
{
46
6.70k
  static char *function = "libregf_hive_bin_header_initialize";
47
48
6.70k
  if( hive_bin_header == NULL )
49
0
  {
50
0
    libcerror_error_set(
51
0
     error,
52
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
53
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
54
0
     "%s: invalid hive bin header.",
55
0
     function );
56
57
0
    return( -1 );
58
0
  }
59
6.70k
  if( *hive_bin_header != NULL )
60
0
  {
61
0
    libcerror_error_set(
62
0
     error,
63
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
64
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
65
0
     "%s: invalid hive bin header value already set.",
66
0
     function );
67
68
0
    return( -1 );
69
0
  }
70
6.70k
  *hive_bin_header = memory_allocate_structure(
71
6.70k
                      libregf_hive_bin_header_t );
72
73
6.70k
  if( *hive_bin_header == NULL )
74
0
  {
75
0
    libcerror_error_set(
76
0
     error,
77
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
78
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
79
0
     "%s: unable to create hive bin header.",
80
0
     function );
81
82
0
    goto on_error;
83
0
  }
84
6.70k
  if( memory_set(
85
6.70k
       *hive_bin_header,
86
6.70k
       0,
87
6.70k
       sizeof( libregf_hive_bin_header_t ) ) == NULL )
88
0
  {
89
0
    libcerror_error_set(
90
0
     error,
91
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
92
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
93
0
     "%s: unable to clear hive bin header.",
94
0
     function );
95
96
0
    goto on_error;
97
0
  }
98
6.70k
  return( 1 );
99
100
0
on_error:
101
0
  if( *hive_bin_header != NULL )
102
0
  {
103
0
    memory_free(
104
0
     *hive_bin_header );
105
106
0
    *hive_bin_header = NULL;
107
0
  }
108
0
  return( -1 );
109
6.70k
}
110
111
/* Frees hive bin header
112
 * Returns 1 if successful or -1 on error
113
 */
114
int libregf_hive_bin_header_free(
115
     libregf_hive_bin_header_t **hive_bin_header,
116
     libcerror_error_t **error )
117
6.70k
{
118
6.70k
  static char *function = "libregf_hive_bin_header_free";
119
120
6.70k
  if( hive_bin_header == NULL )
121
0
  {
122
0
    libcerror_error_set(
123
0
     error,
124
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
125
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
126
0
     "%s: invalid hive bin header.",
127
0
     function );
128
129
0
    return( -1 );
130
0
  }
131
6.70k
  if( *hive_bin_header != NULL )
132
6.70k
  {
133
6.70k
    memory_free(
134
6.70k
     *hive_bin_header );
135
136
6.70k
    *hive_bin_header = NULL;
137
6.70k
  }
138
6.70k
  return( 1 );
139
6.70k
}
140
141
/* Reads the hive bin header data
142
 * Returns 1 if successful, 0 if no hive bin signature was found or -1 on error
143
 */
144
int libregf_hive_bin_header_read_data(
145
     libregf_hive_bin_header_t *hive_bin_header,
146
     const uint8_t *data,
147
     size_t data_size,
148
     libcerror_error_t **error )
149
2.16M
{
150
2.16M
  static char *function = "libregf_hive_bin_header_read_data";
151
152
#if defined( HAVE_DEBUG_OUTPUT )
153
  uint32_t value_32bit  = 0;
154
#endif
155
156
2.16M
  if( hive_bin_header == NULL )
157
0
  {
158
0
    libcerror_error_set(
159
0
     error,
160
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
161
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
162
0
     "%s: invalid hive bin header.",
163
0
     function );
164
165
0
    return( -1 );
166
0
  }
167
2.16M
  if( data == NULL )
168
0
  {
169
0
    libcerror_error_set(
170
0
     error,
171
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
172
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
173
0
     "%s: invalid data.",
174
0
     function );
175
176
0
    return( -1 );
177
0
  }
178
2.16M
  if( data_size < sizeof( regf_hive_bin_header_t ) )
179
0
  {
180
0
    libcerror_error_set(
181
0
     error,
182
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
183
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
184
0
     "%s: invalid data size value too small.",
185
0
     function );
186
187
0
    return( -1 );
188
0
  }
189
2.16M
  if( data_size > (size_t) SSIZE_MAX )
190
0
  {
191
0
    libcerror_error_set(
192
0
     error,
193
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
194
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
195
0
     "%s: invalid data size value exceeds maximum.",
196
0
     function );
197
198
0
    return( -1 );
199
0
  }
200
#if defined( HAVE_DEBUG_OUTPUT )
201
  if( libcnotify_verbose != 0 )
202
  {
203
    libcnotify_printf(
204
     "%s: hive bin header:\n",
205
     function );
206
    libcnotify_print_data(
207
     data,
208
     sizeof( regf_hive_bin_header_t ),
209
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
210
  }
211
#endif
212
2.16M
  if( memory_compare(
213
2.16M
       ( (regf_hive_bin_header_t *) data )->signature,
214
2.16M
       regf_hive_bin_signature,
215
2.16M
       4 ) != 0 )
216
240k
  {
217
240k
    return( 0 );
218
240k
  }
219
1.92M
  byte_stream_copy_to_uint32_little_endian(
220
1.92M
   ( (regf_hive_bin_header_t *) data )->hive_bin_offset,
221
1.92M
   hive_bin_header->offset );
222
223
1.92M
  byte_stream_copy_to_uint32_little_endian(
224
1.92M
   ( (regf_hive_bin_header_t *) data )->size,
225
1.92M
   hive_bin_header->size );
226
227
#if defined( HAVE_DEBUG_OUTPUT )
228
  if( libcnotify_verbose != 0 )
229
  {
230
    libcnotify_printf(
231
     "%s: signature\t\t\t\t: %c%c%c%c\n",
232
     function,
233
     ( (regf_hive_bin_header_t *) data )->signature[ 0 ],
234
     ( (regf_hive_bin_header_t *) data )->signature[ 1 ],
235
     ( (regf_hive_bin_header_t *) data )->signature[ 2 ],
236
     ( (regf_hive_bin_header_t *) data )->signature[ 3 ] );
237
238
    libcnotify_printf(
239
     "%s: hive bin offset\t\t\t: %" PRIu32 " (0x%08" PRIx32 ")\n",
240
     function,
241
     hive_bin_header->offset,
242
     hive_bin_header->offset );
243
244
    libcnotify_printf(
245
     "%s: size\t\t\t\t\t: %" PRIu32 " bytes\n",
246
     function,
247
     hive_bin_header->size );
248
249
    byte_stream_copy_to_uint32_little_endian(
250
     ( (regf_hive_bin_header_t *) data )->unknown1,
251
     value_32bit );
252
    libcnotify_printf(
253
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
254
     function,
255
     value_32bit,
256
     value_32bit );
257
258
    byte_stream_copy_to_uint32_little_endian(
259
     ( (regf_hive_bin_header_t *) data )->unknown2,
260
     value_32bit );
261
    libcnotify_printf(
262
     "%s: unknown2\t\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
263
     function,
264
     value_32bit,
265
     value_32bit );
266
267
    if( libregf_debug_print_filetime_value(
268
         function,
269
         "unknown time\t\t\t\t",
270
         ( (regf_hive_bin_header_t *) data )->unknown_time,
271
         8,
272
         LIBFDATETIME_ENDIAN_LITTLE,
273
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
274
         error ) != 1 )
275
    {
276
      libcerror_error_set(
277
       error,
278
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
279
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
280
       "%s: unable to print filetime value.",
281
       function );
282
283
      return( -1 );
284
    }
285
    byte_stream_copy_to_uint32_little_endian(
286
     ( (regf_hive_bin_header_t *) data )->unknown_spare,
287
     value_32bit );
288
    libcnotify_printf(
289
     "%s: unknown spare\t\t\t: 0x%08" PRIx32 " (%" PRIu32 ")\n",
290
     function,
291
     value_32bit,
292
     value_32bit );
293
294
    libcnotify_printf(
295
     "\n" );
296
  }
297
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
298
299
1.92M
  return( 1 );
300
2.16M
}
301
302
/* Reads the hive bin header
303
 * Returns 1 if successful, 0 if no hive bin signature was found or -1 on error
304
 */
305
int libregf_hive_bin_header_read_file_io_handle(
306
     libregf_hive_bin_header_t *hive_bin_header,
307
     libbfio_handle_t *file_io_handle,
308
     off64_t file_offset,
309
     libcerror_error_t **error )
310
2.17M
{
311
2.17M
  uint8_t hive_bin_header_data[ sizeof( regf_hive_bin_header_t ) ];
312
313
2.17M
  static char *function = "libregf_hive_bin_header_read_file_io_handle";
314
2.17M
  ssize_t read_count    = 0;
315
2.17M
  int result            = 0;
316
317
2.17M
  if( hive_bin_header == NULL )
318
0
  {
319
0
    libcerror_error_set(
320
0
     error,
321
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
322
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
323
0
     "%s: invalid hive bin header.",
324
0
     function );
325
326
0
    return( -1 );
327
0
  }
328
#if defined( HAVE_DEBUG_OUTPUT )
329
  if( libcnotify_verbose != 0 )
330
  {
331
    libcnotify_printf(
332
     "%s: reading hive bin header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
333
     function,
334
     file_offset,
335
     file_offset );
336
  }
337
#endif
338
2.17M
  read_count = libbfio_handle_read_buffer_at_offset(
339
2.17M
                file_io_handle,
340
2.17M
                hive_bin_header_data,
341
2.17M
                sizeof( regf_hive_bin_header_t ),
342
2.17M
                file_offset,
343
2.17M
                error );
344
345
2.17M
  if( read_count != (ssize_t) sizeof( regf_hive_bin_header_t ) )
346
878
  {
347
878
    libcerror_error_set(
348
878
     error,
349
878
     LIBCERROR_ERROR_DOMAIN_IO,
350
878
     LIBCERROR_IO_ERROR_READ_FAILED,
351
878
     "%s: unable to read hive bin header data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
352
878
     function,
353
878
     file_offset,
354
878
     file_offset );
355
356
878
    return( -1 );
357
878
  }
358
2.16M
  result = libregf_hive_bin_header_read_data(
359
2.16M
            hive_bin_header,
360
2.16M
            hive_bin_header_data,
361
2.16M
            sizeof( regf_hive_bin_header_t ),
362
2.16M
            error );
363
364
2.16M
  if( result == -1 )
365
0
  {
366
0
    libcerror_error_set(
367
0
     error,
368
0
     LIBCERROR_ERROR_DOMAIN_IO,
369
0
     LIBCERROR_IO_ERROR_READ_FAILED,
370
0
     "%s: unable to read hive bin header.",
371
0
     function );
372
373
0
    return( -1 );
374
0
  }
375
2.16M
  return( result );
376
2.16M
}
377