Coverage Report

Created: 2024-06-12 07:07

/src/libfwevt/libfwevt/libfwevt_keyword.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Keyword functions
3
 *
4
 * Copyright (C) 2011-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 <narrow_string.h>
26
#include <system_string.h>
27
#include <types.h>
28
#include <wide_string.h>
29
30
#include "libfwevt_debug.h"
31
#include "libfwevt_keyword.h"
32
#include "libfwevt_libcerror.h"
33
#include "libfwevt_libcnotify.h"
34
#include "libfwevt_libuna.h"
35
#include "libfwevt_types.h"
36
37
#include "fwevt_template.h"
38
39
/* Creates a keyword
40
 * Make sure the value keyword is referencing, is set to NULL
41
 * Returns 1 if successful or -1 on error
42
 */
43
int libfwevt_keyword_initialize(
44
     libfwevt_keyword_t **keyword,
45
     libcerror_error_t **error )
46
37.7k
{
47
37.7k
  libfwevt_internal_keyword_t *internal_keyword = NULL;
48
37.7k
  static char *function                         = "libfwevt_keyword_initialize";
49
50
37.7k
  if( keyword == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid keyword.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
37.7k
  if( *keyword != NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
66
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67
0
     "%s: invalid keyword value already set.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
37.7k
  internal_keyword = memory_allocate_structure(
73
37.7k
                      libfwevt_internal_keyword_t );
74
75
37.7k
  if( internal_keyword == NULL )
76
0
  {
77
0
    libcerror_error_set(
78
0
     error,
79
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
80
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
81
0
     "%s: unable to create keyword.",
82
0
     function );
83
84
0
    goto on_error;
85
0
  }
86
37.7k
  if( memory_set(
87
37.7k
       internal_keyword,
88
37.7k
       0,
89
37.7k
       sizeof( libfwevt_internal_keyword_t ) ) == NULL )
90
0
  {
91
0
    libcerror_error_set(
92
0
     error,
93
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
94
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
95
0
     "%s: unable to clear keyword.",
96
0
     function );
97
98
0
    goto on_error;
99
0
  }
100
37.7k
  *keyword = (libfwevt_keyword_t *) internal_keyword;
101
102
37.7k
  return( 1 );
103
104
0
on_error:
105
0
  if( internal_keyword != NULL )
106
0
  {
107
0
    memory_free(
108
0
     internal_keyword );
109
0
  }
110
0
  return( -1 );
111
37.7k
}
112
113
/* Frees a keyword
114
 * Returns 1 if successful or -1 on error
115
 */
116
int libfwevt_keyword_free(
117
     libfwevt_keyword_t **keyword,
118
     libcerror_error_t **error )
119
0
{
120
0
  static char *function = "libfwevt_keyword_free";
121
122
0
  if( keyword == NULL )
123
0
  {
124
0
    libcerror_error_set(
125
0
     error,
126
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
127
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
128
0
     "%s: invalid keyword.",
129
0
     function );
130
131
0
    return( -1 );
132
0
  }
133
0
  if( *keyword != NULL )
134
0
  {
135
0
    *keyword = NULL;
136
0
  }
137
0
  return( 1 );
138
0
}
139
140
/* Frees a keyword
141
 * Returns 1 if successful or -1 on error
142
 */
143
int libfwevt_internal_keyword_free(
144
     libfwevt_internal_keyword_t **internal_keyword,
145
     libcerror_error_t **error )
146
37.7k
{
147
37.7k
  static char *function = "libfwevt_internal_keyword_free";
148
149
37.7k
  if( internal_keyword == NULL )
150
0
  {
151
0
    libcerror_error_set(
152
0
     error,
153
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
154
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
155
0
     "%s: invalid keyword.",
156
0
     function );
157
158
0
    return( -1 );
159
0
  }
160
37.7k
  if( *internal_keyword != NULL )
161
37.7k
  {
162
37.7k
    memory_free(
163
37.7k
     *internal_keyword );
164
165
37.7k
    *internal_keyword = NULL;
166
37.7k
  }
167
37.7k
  return( 1 );
168
37.7k
}
169
170
/* Reads the keyword
171
 * Returns 1 if successful or -1 on error
172
 */
173
int libfwevt_keyword_read_data(
174
     libfwevt_keyword_t *keyword,
175
     const uint8_t *data,
176
     size_t data_size,
177
     size_t data_offset,
178
     libcerror_error_t **error )
179
37.7k
{
180
37.7k
  fwevt_template_keyword_t *wevt_keyword = NULL;
181
37.7k
  static char *function                  = "libfwevt_keyword_read_data";
182
37.7k
  uint32_t keyword_data_offset           = 0;
183
37.7k
  uint32_t keyword_data_size             = 0;
184
185
#if defined( HAVE_DEBUG_OUTPUT )
186
  uint64_t value_64bit                   = 0;
187
  uint32_t value_32bit                   = 0;
188
#endif
189
190
37.7k
  if( keyword == NULL )
191
0
  {
192
0
    libcerror_error_set(
193
0
     error,
194
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
195
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
196
0
     "%s: invalid keyword.",
197
0
     function );
198
199
0
    return( -1 );
200
0
  }
201
37.7k
  if( data == NULL )
202
0
  {
203
0
    libcerror_error_set(
204
0
     error,
205
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
206
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
207
0
     "%s: invalid data.",
208
0
     function );
209
210
0
    return( -1 );
211
0
  }
212
37.7k
  if( data_size > (size_t) SSIZE_MAX )
213
0
  {
214
0
    libcerror_error_set(
215
0
     error,
216
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
217
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
218
0
     "%s: invalid data size value exceeds maximum.",
219
0
     function );
220
221
0
    return( -1 );
222
0
  }
223
37.7k
  if( data_offset >= data_size )
224
0
  {
225
0
    libcerror_error_set(
226
0
     error,
227
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
228
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
229
0
     "%s: invalid data offset value out of bounds.",
230
0
     function );
231
232
0
    return( -1 );
233
0
  }
234
37.7k
  if( ( data_size < sizeof( fwevt_template_keyword_t ) )
235
37.7k
   || ( data_offset > ( data_size - sizeof( fwevt_template_keyword_t ) ) ) )
236
0
  {
237
0
    libcerror_error_set(
238
0
     error,
239
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
240
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
241
0
     "%s: invalid data value too small.",
242
0
     function );
243
244
0
    return( -1 );
245
0
  }
246
37.7k
  wevt_keyword = (fwevt_template_keyword_t *) &( data[ data_offset ] );
247
248
#if defined( HAVE_DEBUG_OUTPUT )
249
  if( libcnotify_verbose != 0 )
250
  {
251
    libcnotify_printf(
252
     "%s: keyword data:\n",
253
     function );
254
    libcnotify_print_data(
255
     (uint8_t *) wevt_keyword,
256
     sizeof( fwevt_template_keyword_t ),
257
     0 );
258
  }
259
#endif
260
37.7k
  byte_stream_copy_to_uint32_little_endian(
261
37.7k
   wevt_keyword->data_offset,
262
37.7k
   keyword_data_offset );
263
264
#if defined( HAVE_DEBUG_OUTPUT )
265
  if( libcnotify_verbose != 0 )
266
  {
267
    byte_stream_copy_to_uint64_little_endian(
268
     wevt_keyword->identifier,
269
     value_64bit );
270
    libcnotify_printf(
271
     "%s: identifier\t\t\t\t\t: 0x%08" PRIx64 "\n",
272
     function,
273
     value_64bit );
274
275
    byte_stream_copy_to_uint32_little_endian(
276
     wevt_keyword->message_identifier,
277
     value_32bit );
278
    libcnotify_printf(
279
     "%s: message identifier\t\t\t\t: 0x%08" PRIx32 "\n",
280
     function,
281
     value_32bit );
282
283
    libcnotify_printf(
284
     "%s: data offset\t\t\t\t\t: 0x%08" PRIx32 "\n",
285
     function,
286
     keyword_data_offset );
287
  }
288
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
289
290
37.7k
  if( keyword_data_offset > 0 )
291
723
  {
292
723
    if( keyword_data_offset >= ( data_size - 4 ) )
293
97
    {
294
97
      libcerror_error_set(
295
97
       error,
296
97
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
297
97
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
298
97
       "%s: invalid keyword data offset value out of bounds.",
299
97
       function );
300
301
97
      return( -1 );
302
97
    }
303
626
    byte_stream_copy_to_uint32_little_endian(
304
626
     &( data[ keyword_data_offset ] ),
305
626
     keyword_data_size );
306
307
626
    if( ( data_size < keyword_data_size )
308
626
     || ( keyword_data_offset > ( data_size - keyword_data_size ) ) )
309
80
    {
310
80
      libcerror_error_set(
311
80
       error,
312
80
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
313
80
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
314
80
       "%s: invalid keyword data size value out of bounds.",
315
80
       function );
316
317
80
      return( -1 );
318
80
    }
319
#if defined( HAVE_DEBUG_OUTPUT )
320
    if( libcnotify_verbose != 0 )
321
    {
322
      libcnotify_printf(
323
       "%s: data:\n",
324
       function );
325
      libcnotify_print_data(
326
       &( data[ keyword_data_offset ] ),
327
       keyword_data_size,
328
       0 );
329
    }
330
#endif
331
#if defined( HAVE_DEBUG_OUTPUT )
332
    if( libcnotify_verbose != 0 )
333
    {
334
      libcnotify_printf(
335
       "%s: data size\t\t\t\t\t: %" PRIu32 "\n",
336
       function,
337
       keyword_data_size );
338
    }
339
#endif
340
546
    if( keyword_data_size >= 4 )
341
221
    {
342
221
      keyword_data_offset += 4;
343
221
      keyword_data_size   -= 4;
344
345
#if defined( HAVE_DEBUG_OUTPUT )
346
      if( libcnotify_verbose != 0 )
347
      {
348
        if( libfwevt_debug_print_utf16_string_value(
349
             function,
350
             "name\t\t\t\t\t\t",
351
             &( data[ keyword_data_offset ] ),
352
             keyword_data_size,
353
             LIBUNA_ENDIAN_LITTLE,
354
             error ) != 1 )
355
        {
356
          libcerror_error_set(
357
           error,
358
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
359
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
360
           "%s: unable to print UTF-16 string value.",
361
           function );
362
363
          return( -1 );
364
        }
365
      }
366
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
367
221
    }
368
546
  }
369
#if defined( HAVE_DEBUG_OUTPUT )
370
  if( libcnotify_verbose != 0 )
371
  {
372
    libcnotify_printf(
373
     "\n" );
374
  }
375
#endif
376
37.5k
  return( 1 );
377
37.7k
}
378