Coverage Report

Created: 2026-08-31 07:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libexe/libexe/libexe_le_header.c
Line
Count
Source
1
/*
2
 * LE header functions
3
 *
4
 * Copyright (C) 2011-2026, 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 "libexe_le_header.h"
28
#include "libexe_libcerror.h"
29
#include "libexe_libcnotify.h"
30
31
#include "exe_le_header.h"
32
33
/* Creates a LE header
34
 * Make sure the value le_header is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libexe_le_header_initialize(
38
     libexe_le_header_t **le_header,
39
     libcerror_error_t **error )
40
1
{
41
1
  static char *function = "libexe_le_header_initialize";
42
43
1
  if( le_header == NULL )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49
0
     "%s: invalid LE header.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
1
  if( *le_header != NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
59
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60
0
     "%s: invalid LE header value already set.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
1
  *le_header = memory_allocate_structure(
66
1
                libexe_le_header_t );
67
68
1
  if( *le_header == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
73
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74
0
     "%s: unable to create LE header.",
75
0
     function );
76
77
0
    goto on_error;
78
0
  }
79
1
  if( memory_set(
80
1
       *le_header,
81
1
       0,
82
1
       sizeof( libexe_le_header_t ) ) == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
88
0
     "%s: unable to clear file.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
1
  return( 1 );
94
95
0
on_error:
96
0
  if( *le_header != NULL )
97
0
  {
98
0
    memory_free(
99
0
     *le_header );
100
101
0
    *le_header = NULL;
102
0
  }
103
0
  return( -1 );
104
1
}
105
106
/* Frees a LE header
107
 * Returns 1 if successful or -1 on error
108
 */
109
int libexe_le_header_free(
110
     libexe_le_header_t **le_header,
111
     libcerror_error_t **error )
112
1
{
113
1
  static char *function = "libexe_le_header_free";
114
115
1
  if( le_header == NULL )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
120
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
121
0
     "%s: invalid LE header.",
122
0
     function );
123
124
0
    return( -1 );
125
0
  }
126
1
  if( *le_header != NULL )
127
1
  {
128
1
    memory_free(
129
1
     *le_header );
130
131
1
    *le_header = NULL;
132
1
  }
133
1
  return( 1 );
134
1
}
135
136
/* Reads the LE header
137
 * Returns 1 if successful or -1 on error
138
 */
139
int libexe_le_header_read_data(
140
     libexe_le_header_t *le_header,
141
     const uint8_t *data,
142
     size_t data_size,
143
     libcerror_error_t **error )
144
1
{
145
1
  static char *function = "libexe_le_header_read_data";
146
147
1
  if( le_header == NULL )
148
0
  {
149
0
    libcerror_error_set(
150
0
     error,
151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
153
0
     "%s: invalid LE header.",
154
0
     function );
155
156
0
    return( -1 );
157
0
  }
158
1
  if( data == NULL )
159
0
  {
160
0
    libcerror_error_set(
161
0
     error,
162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
164
0
     "%s: invalid data.",
165
0
     function );
166
167
0
    return( -1 );
168
0
  }
169
1
  if( data_size < sizeof( exe_le_header_t ) )
170
0
  {
171
0
    libcerror_error_set(
172
0
     error,
173
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
174
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
175
0
     "%s: invalid data size value too small.",
176
0
     function );
177
178
0
    return( -1 );
179
0
  }
180
1
  if( data_size > (size_t) SSIZE_MAX )
181
0
  {
182
0
    libcerror_error_set(
183
0
     error,
184
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
185
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
186
0
     "%s: invalid data size value exceeds maximum.",
187
0
     function );
188
189
0
    return( -1 );
190
0
  }
191
#if defined( HAVE_DEBUG_OUTPUT )
192
  if( libcnotify_verbose != 0 )
193
  {
194
    libcnotify_printf(
195
     "%s: LE header:\n",
196
     function );
197
    libcnotify_print_data(
198
     data,
199
     sizeof( exe_le_header_t ),
200
     0 );
201
  }
202
#endif
203
1
  if( memory_compare(
204
1
       ( (exe_le_header_t *) data )->signature,
205
1
       EXE_LE_SIGNATURE,
206
1
       2 ) != 0 )
207
1
  {
208
1
    libcerror_error_set(
209
1
     error,
210
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
211
1
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
212
1
     "%s: invalid signature.",
213
1
     function );
214
215
1
    return( -1 );
216
1
  }
217
#if defined( HAVE_DEBUG_OUTPUT )
218
  if( libcnotify_verbose != 0 )
219
  {
220
    libcnotify_printf(
221
     "%s: signature\t\t\t\t: %c%c\n",
222
     function,
223
     ( (exe_le_header_t *) data )->signature[ 0 ],
224
     ( (exe_le_header_t *) data )->signature[ 1 ] );
225
/* TODO */
226
227
    libcnotify_printf(
228
     "\n" );
229
  }
230
#endif
231
0
  return( 1 );
232
1
}
233
234
/* Reads the LE header from a Basic File IO (bfio) handle
235
 * Returns 1 if successful or -1 on error
236
 */
237
int libexe_le_header_read_file_io_handle(
238
     libexe_le_header_t *le_header,
239
     libbfio_handle_t *file_io_handle,
240
     off64_t file_offset,
241
     libcerror_error_t **error )
242
1
{
243
1
  uint8_t data[ sizeof( exe_le_header_t ) ];
244
245
1
  static char *function = "libexe_le_header_read_file_io_handle";
246
1
  ssize_t read_count    = 0;
247
248
#if defined( HAVE_DEBUG_OUTPUT )
249
  if( libcnotify_verbose != 0 )
250
  {
251
    libcnotify_printf(
252
     "%s: reading LE header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
253
     function,
254
     file_offset,
255
     file_offset );
256
  }
257
#endif
258
1
  read_count = libbfio_handle_read_buffer_at_offset(
259
1
                file_io_handle,
260
1
                data,
261
1
                sizeof( exe_le_header_t ),
262
1
                file_offset,
263
1
                error );
264
265
1
  if( read_count != (ssize_t) sizeof( exe_le_header_t ) )
266
0
  {
267
0
    libcerror_error_set(
268
0
     error,
269
0
     LIBCERROR_ERROR_DOMAIN_IO,
270
0
     LIBCERROR_IO_ERROR_READ_FAILED,
271
0
     "%s: unable to read LE header data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
272
0
     function,
273
0
     file_offset,
274
0
     file_offset );
275
276
0
    return( -1 );
277
0
  }
278
1
  if( libexe_le_header_read_data(
279
1
       le_header,
280
1
       data,
281
1
       sizeof( exe_le_header_t ),
282
1
       error ) != 1 )
283
1
  {
284
1
    libcerror_error_set(
285
1
     error,
286
1
     LIBCERROR_ERROR_DOMAIN_IO,
287
1
     LIBCERROR_IO_ERROR_READ_FAILED,
288
1
     "%s: unable to read LE header at offset: %" PRIi64 " (0x%08" PRIx64 ").",
289
1
     function,
290
1
     file_offset,
291
1
     file_offset );
292
293
1
    return( -1 );
294
1
  }
295
0
  return( 1 );
296
1
}
297