Bug Summary

File:builds/wireshark/wireshark/wiretap/procmon.c
Warning:line 540, column 21
Use of memory after it is released

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name procmon.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D wiretap_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -I /builds/wireshark/wireshark/build/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-09-18-100359-3660-1 -x c /builds/wireshark/wireshark/wiretap/procmon.c
1/** procmon.c
2 *
3 * Implements reading of MS Procmon files
4 * Used a lot of information from https://github.com/eronnen/procmon-parser
5 *
6 * Wiretap Library
7 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12#include "config.h"
13#define WS_LOG_DOMAIN"Wiretap" LOG_DOMAIN_WIRETAP"Wiretap"
14
15#include "procmon.h"
16#include "file_wrappers.h"
17#include "wtap_module.h"
18#include "pcapng_module.h"
19
20#include <wsutil/buffer.h>
21
22// To do:
23// - Figure out module timestamps
24// - Read the ports array? Is there any advantage to doing that vs our built in
25// port number resolution?
26// - Disable compression and mmap the file? That's probably what Process Monitor
27// itself does.
28
29#pragma pack(push,1)
30typedef struct procmon_header_s {
31 uint32_t signature; // Magic Signature - 'PML_'
32 uint32_t version; // Version of the PML file. 9 in the current version.
33 uint32_t system_bitness; // System bitness: 1 if the system is 64 bit, 0 otherwise.
34 uint16_t computer_name[16]; // Name of the computer (that did the capture).
35 uint16_t system_root_path[260]; // System root path (e.g. "C:\Windows").
36 uint32_t num_events; // Total number of events in the log file.
37 uint64_t unused; // ? (seems to be unused)
38 uint64_t start_events_offset; // File offset to the start of the events array.
39 uint64_t event_offsets_array_offset;// File offset to an array of offsets to all the events.
40 uint64_t process_array_offset; // File offset to the array of processes.
41 uint64_t string_array_offset; // File offset to the array of strings.
42 uint64_t icon_array_offset; // File offset to the icons array.
43 uint64_t maximum_user_address; // SYSTEM_INFO.lpMaximumApplicationAddress: Maximum User Address
44 uint32_t os_version_info_size; // OSVERSIONINFOEXW.dwOSVersionInfoSize: sizeof(OSVERSIONINFOEXW)
45 uint32_t major_version; // OSVERSIONINFOEXW.dwMajorVersion: Major version number of the operating system.
46 uint32_t minor_version; // OSVERSIONINFOEXW.dwMinorVersion: Minor version number of the operating system.
47 uint32_t build_number; // OSVERSIONINFOEXW.dwBuildNumber: Build number of the operating system.
48 uint32_t platform_id; // OSVERSIONINFOEXW.dwPlatformId: Operating system platform.
49 uint16_t csd_version[128]; // OSVERSIONINFOEXW.szCSDVersion: Indicates the latest Service Pack installed.
50 uint16_t service_pack_major; // OSVERSIONINFOEXW.wServicePackMajor: Major version number of the latest Service Pack.
51 uint16_t service_pack_minor; // OSVERSIONINFOEXW.wServicePackMinor: Minor version number of the latest Service Pack.
52 uint16_t suite_mask; // OSVERSIONINFOEXW.wSuiteMask: Bit mask that identifies the product suites available.
53 uint8_t product_type; // OSVERSIONINFOEXW.wProductType: Additional information about the system.
54 uint8_t version_reserved; // OSVERSIONINFOEXW.wReserved: Reserved for future use.
55 uint32_t num_processors; // SYSTEM_INFO.dwNumberOfProcessors: Number of logical processors.
56 uint64_t total_physical_memory; // MEMORYSTATUSEX.ullTotalPhys: Total physical memory (in bytes).
57 uint64_t start_events_offset_dup; // File offset to the start of the events array (again).
58 uint64_t host_port_array_offset; // File offset to hosts and ports arrays.
59} procmon_header_t;
60
61typedef enum {
62 PROCMON_EVENT_TYPE_UNKNOWN = 0,
63 PROCMON_EVENT_TYPE_PROCESS = 1,
64 PROCMON_EVENT_TYPE_REGISTRY = 2,
65 PROCMON_EVENT_TYPE_FILE_SYSTEM = 3,
66 PROCMON_EVENT_TYPE_PROFILING = 4,
67 PROCMON_EVENT_TYPE_NETWORK = 5,
68} procmon_event_class_type_t;
69
70typedef struct procmon_event_header_s {
71 uint32_t process_index; // The index to the process of the event.
72 uint32_t thread_id; // Thread Id.
73 uint32_t event_class; // Event class (of type procmon_event_class_type_t)
74 uint16_t operation_type; // Operation type (dependent on the event class)
75 uint8_t unknown[6]; // Unknown
76 uint64_t duration; // Duration of the operation in 100 nanoseconds interval.
77 uint64_t timestamp; // The time when the event was captured (in FILETIME format)
78 uint32_t event_result; // The value of the event result.
79 uint16_t stack_trace_depth; // The depth of the captured stack trace.
80 uint16_t unknown3; // Unknown
81 uint32_t details_size; // The size of the specific detail structure (contains path and other details)
82 uint32_t extra_details_offset; // The offset from the start of the event to extra detail structure (not necessarily continuous with this structure).
83
84} procmon_event_header_t;
85#pragma pack(pop)
86
87typedef struct {
88 uint32_t process_index;
89 uint32_t process_id;
90 uint32_t parent_process_id;
91 uint32_t parent_process_index;
92 uint64_t authentication_id;
93 uint32_t session_number;
94 uint32_t unknown1;
95 uint64_t start_time; // FILETIME
96 uint64_t end_time; // FILETIME
97 uint32_t is_virtualized;
98 uint32_t is_64_bit;
99 uint32_t integrity_si;
100 uint32_t user_name_si;
101 uint32_t process_name_si;
102 uint32_t image_path_si;
103 uint32_t command_line_si;
104 uint32_t company_si;
105 uint32_t version_si;
106 uint32_t description_si;
107 uint32_t icon_index_big;
108 uint32_t icon_index_small;
109} procmon_raw_process_t;
110
111typedef struct {
112 uint32_t unknown1;
113 uint32_t base_address;
114 uint32_t size;
115 uint32_t image_path_si;
116 uint32_t version_si;
117 uint32_t company_si;
118 uint32_t description_si;
119 uint32_t timestamp;
120 uint64_t unknown2[3];
121} procmon_raw_module_32_t;
122
123typedef struct {
124 uint64_t unknown1;
125 uint64_t base_address;
126 uint32_t size;
127 uint32_t image_path_si;
128 uint32_t version_si;
129 uint32_t company_si;
130 uint32_t description_si;
131 uint32_t timestamp;
132 uint64_t unknown2[3];
133} procmon_raw_module_64_t;
134
135typedef struct {
136 procmon_header_t header;
137 uint32_t *event_offsets;
138 uint32_t cur_event;
139 const char **string_array;
140 size_t string_array_size;
141 uint32_t *process_index_map; /* Map of process index to process array index */
142 size_t process_index_map_size;
143 struct procmon_process_t *process_array;
144 size_t process_array_size;
145} procmon_file_info_t;
146
147#define COMMON_EVENT_STRUCT_SIZE52 52
148// Most of these are arbitrary. Care should be taken to ensure that we don't
149// allocate too much memory.
150#define MAX_PROCMON_EVENTS(50 * 1000 * 1000) (50 * 1000 * 1000) // * uint32_t = 200 MB
151#define MAX_PROCMON_STRINGS(1000 * 1000) (1000 * 1000)
152#define MAX_PROCMON_STRING_LENGTH8192 8192
153#define MAX_PROCMON_PROCESSES(500 * 1000) (500 * 1000)
154#define MAX_PROCMON_MODULES1000 1000
155#define MAX_PROCMON_EVENT_SIZE262144U WTAP_MAX_PACKET_SIZE_STANDARD262144U
156
157static int procmon_file_type_subtype = -1;
158
159void register_procmon(void);
160
161static void file_info_cleanup(procmon_file_info_t* file_info)
162{
163 g_free(file_info->event_offsets)(__builtin_object_size ((file_info->event_offsets), 0) != (
(size_t) - 1)) ? g_free_sized (file_info->event_offsets, __builtin_object_size
((file_info->event_offsets), 0)) : (g_free) (file_info->
event_offsets)
;
11
Assuming the condition is false
12
'?' condition is false
164 if (file_info->string_array) {
13
Assuming field 'string_array' is null
165 for (size_t idx = 0; idx < file_info->string_array_size; idx++) {
166 g_free((char *)file_info->string_array[idx])(__builtin_object_size (((char *)file_info->string_array[idx
]), 0) != ((size_t) - 1)) ? g_free_sized ((char *)file_info->
string_array[idx], __builtin_object_size (((char *)file_info->
string_array[idx]), 0)) : (g_free) ((char *)file_info->string_array
[idx])
;
167 }
168 g_free(file_info->string_array)(__builtin_object_size ((file_info->string_array), 0) != (
(size_t) - 1)) ? g_free_sized (file_info->string_array, __builtin_object_size
((file_info->string_array), 0)) : (g_free) (file_info->
string_array)
;
169 }
170 g_free(file_info->process_index_map)(__builtin_object_size ((file_info->process_index_map), 0)
!= ((size_t) - 1)) ? g_free_sized (file_info->process_index_map
, __builtin_object_size ((file_info->process_index_map), 0
)) : (g_free) (file_info->process_index_map)
;
14
Taking false branch
15
Assuming the condition is false
16
'?' condition is false
171 if (file_info->process_array) {
17
Assuming field 'process_array' is null
172 for (size_t idx = 0; idx < file_info->process_array_size; idx++) {
173 g_free(file_info->process_array[idx].modules)(__builtin_object_size ((file_info->process_array[idx].modules
), 0) != ((size_t) - 1)) ? g_free_sized (file_info->process_array
[idx].modules, __builtin_object_size ((file_info->process_array
[idx].modules), 0)) : (g_free) (file_info->process_array[idx
].modules)
;
174 }
175 g_free(file_info->process_array)(__builtin_object_size ((file_info->process_array), 0) != (
(size_t) - 1)) ? g_free_sized (file_info->process_array, __builtin_object_size
((file_info->process_array), 0)) : (g_free) (file_info->
process_array)
;
176 }
177 g_free(file_info)(__builtin_object_size ((file_info), 0) != ((size_t) - 1)) ? g_free_sized
(file_info, __builtin_object_size ((file_info), 0)) : (g_free
) (file_info)
;
18
Taking false branch
19
Assuming the condition is false
20
'?' condition is false
21
Memory is released
178}
179
180static const char *procmon_string(procmon_file_info_t* file_info, uint32_t str_index)
181{
182 if (str_index >= file_info->string_array_size) {
183 return "<unknown>";
184 }
185 return file_info->string_array[str_index];
186}
187
188static char *procmon_read_string(FILE_T fh, gunichar2 *str_buf, int *err, char **err_info)
189{
190 uint32_t cur_str_size;
191 if (!wtap_read_bytes_or_eof(fh, &cur_str_size, sizeof(cur_str_size), err, err_info))
192 {
193 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 193, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
194 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
195 {
196 // Short read or EOF.
197 *err = 0;
198 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
199 *err_info = NULL((void*)0);
200 }
201 return NULL((void*)0);
202 }
203 cur_str_size = GUINT32_FROM_LE(cur_str_size)(((guint32) (cur_str_size)));
204 if (cur_str_size > MAX_PROCMON_STRING_LENGTH8192)
205 {
206 if (file_seek(fh, cur_str_size - MAX_PROCMON_STRING_LENGTH8192, SEEK_CUR1, err) == -1)
207 {
208 ws_debug("Failed to skip excess string data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 208, __func__, "Failed to skip excess string data"); } } while
(0)
;
209 return NULL((void*)0);
210 }
211 ws_debug("Truncating string from %u bytes to %u", cur_str_size, MAX_PROCMON_STRING_LENGTH)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 211, __func__, "Truncating string from %u bytes to %u", cur_str_size
, 8192); } } while (0)
;
212 cur_str_size = MAX_PROCMON_STRING_LENGTH8192;
213 }
214 if (!wtap_read_bytes_or_eof(fh, str_buf, cur_str_size, err, err_info))
215 {
216 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 216, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
217 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
218 {
219 // Short read or EOF.
220 *err = 0;
221 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
222 *err_info = NULL((void*)0);
223 }
224 return NULL((void*)0);
225 }
226 char *utf8_str = g_convert_with_fallback((const char *)str_buf, cur_str_size, "UTF-8", "UTF-16LE", "?", NULL((void*)0), NULL((void*)0), NULL((void*)0));
227 return utf8_str ? utf8_str : g_strdup("<invalid>")g_strdup_inline ("<invalid>");
228}
229
230// Read the hosts array. Assume failures here are non-fatal.
231static void procmon_read_hosts(wtap *wth, int64_t host_port_array_offset, int *err, char **err_info)
232{
233 if (!(wth->add_new_ipv4 && wth->add_new_ipv6)) {
234 return;
235 }
236
237 if (file_seek(wth->fh, host_port_array_offset, SEEK_SET0, err) == -1)
238 {
239 ws_debug("Failed to locate procmon hosts+ports data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 239, __func__, "Failed to locate procmon hosts+ports data")
; } } while (0)
;
240 return;
241 }
242 uint32_t num_hosts;
243 if (!wtap_read_bytes_or_eof(wth->fh, &num_hosts, sizeof(num_hosts), err, err_info))
244 {
245 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 245, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
246 return;
247 }
248 num_hosts = GUINT32_FROM_LE(num_hosts)(((guint32) (num_hosts)));
249 if (num_hosts > MAX_PROCMON_STRINGS(1000 * 1000))
250 {
251 ws_debug("Truncating hosts from %u to %u", num_hosts, MAX_PROCMON_STRINGS)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 251, __func__, "Truncating hosts from %u to %u", num_hosts,
(1000 * 1000)); } } while (0)
;
252 num_hosts = MAX_PROCMON_STRINGS(1000 * 1000);
253 }
254 gunichar2 *str_buf = g_new(gunichar2, MAX_PROCMON_STRING_LENGTH)((gunichar2 *) g_malloc_n ((8192), sizeof (gunichar2)));
255 // Procmon appears to use the hosts table to store ASCII representations of
256 // addresses, so skip those.
257 GRegex *numeric_re = g_regex_new("^([0-9.]+|.*:.*)$", (GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_RAW | G_REGEX_OPTIMIZE), (GRegexMatchFlags)0, NULL((void*)0));
258 for (unsigned idx = 0; idx < num_hosts; idx++)
259 {
260 ws_in6_addr addr;
261 if (!wtap_read_bytes_or_eof(wth->fh, &addr, sizeof(addr), err, err_info))
262 {
263 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 263, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
264 g_regex_unref(numeric_re);
265 g_free(str_buf)(__builtin_object_size ((str_buf), 0) != ((size_t) - 1)) ? g_free_sized
(str_buf, __builtin_object_size ((str_buf), 0)) : (g_free) (
str_buf)
;
266 return;
267 }
268 char *name = procmon_read_string(wth->fh, str_buf, err, err_info);
269 if (!name) {
270 continue;
271 }
272 if (g_regex_match(numeric_re, name, (GRegexMatchFlags)0, NULL((void*)0)))
273 {
274 g_free(name)(__builtin_object_size ((name), 0) != ((size_t) - 1)) ? g_free_sized
(name, __builtin_object_size ((name), 0)) : (g_free) (name)
;
275 continue;
276 }
277 // The PML format gives us a 16 byte blob with no indication as to
278 // whether or not the blob is a v4 or v6 address. Given that there are
279 // several pingable v6 addresses that end with 12 bytes of zeroes (at
280 // the time of this writing 2600::, 2409::, 2a09::, and 2a11:: are all
281 // pingable), let's assume that all addresses are v6 and ones that end
282 // with 12 bytes of zeroes are also v4.
283 wth->add_new_ipv6(&addr, name, false0);
284 if (!*(uint32_t*)(&addr.bytes[4]) && !*(uint64_t*)(&addr.bytes[8])) {
285 ws_in4_addr v4addr = *(uint32_t *)(&addr.bytes[4]);
286 wth->add_new_ipv4(v4addr, name, false0);
287 }
288 g_free(name)(__builtin_object_size ((name), 0) != ((size_t) - 1)) ? g_free_sized
(name, __builtin_object_size ((name), 0)) : (g_free) (name)
;
289 }
290 g_regex_unref(numeric_re);
291 g_free(str_buf)(__builtin_object_size ((str_buf), 0) != ((size_t) - 1)) ? g_free_sized
(str_buf, __builtin_object_size ((str_buf), 0)) : (g_free) (
str_buf)
;
292}
293
294static void procmon_close(wtap* wth) {
295 if (wth && wth->priv) {
296 procmon_file_info_t* file_info = (procmon_file_info_t*)wth->priv;
297 file_info_cleanup(file_info);
298 wth->priv = NULL((void*)0);
299 }
300}
301
302static bool_Bool procmon_read_event(FILE_T fh, wtap_rec* rec, procmon_file_info_t* file_info, int* err, char** err_info)
303{
304 wtapng_block_t wblock;
305 procmon_event_header_t event_header;
306
307 wblock.rec = rec;
308
309 wblock.block = wtap_block_create(WTAP_BLOCK_FT_SPECIFIC_EVENT);
310
311 wblock.rec->presence_flags = WTAP_HAS_CAP_LEN0x00000002;
312 wblock.rec->tsprec = WTAP_TSPREC_NSEC9;
313
314 /* Read the event header */
315 if (!wtap_read_bytes(fh, &event_header, sizeof event_header, err, err_info)) {
316 ws_debug("Failed to read procmon process index")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 316, __func__, "Failed to read procmon process index"); } }
while (0)
;
317 return false0;
318 }
319
320 /* Append the raw data of the event header */
321 ws_buffer_append(&wblock.rec->data, (const uint8_t*)&event_header, sizeof event_header);
322
323 /* The event header is dissection data, so we byte swap local variables here. */
324 uint32_t eh_event_class = GUINT32_FROM_LE(event_header.event_class)(((guint32) (event_header.event_class)));
325 uint64_t eh_timestamp = GUINT64_FROM_LE(event_header.timestamp)(((guint64) (event_header.timestamp)));
326 uint16_t eh_stack_trace_depth = GUINT16_FROM_LE(event_header.stack_trace_depth)(((guint16) (event_header.stack_trace_depth)));
327 uint32_t eh_details_size = GUINT32_FROM_LE(event_header.details_size)(((guint32) (event_header.details_size)));
328 uint32_t eh_extra_details_offset = GUINT32_FROM_LE(event_header.extra_details_offset)(((guint32) (event_header.extra_details_offset)));
329
330
331 wblock.rec->presence_flags |= WTAP_HAS_TS0x00000001;
332 filetime_to_nstime(&wblock.rec->ts, eh_timestamp);
333
334 /* Read stack trace data */
335 uint32_t sizeof_stacktrace = eh_stack_trace_depth * (file_info->header.system_bitness ? 8 : 4);
336
337 uint64_t event_size = sizeof(event_header) + sizeof(sizeof_stacktrace) + sizeof_stacktrace + eh_details_size;
338 if (event_size > MAX_PROCMON_EVENT_SIZE262144U) {
339 *err = WTAP_ERR_BAD_FILE-13;
340 *err_info = ws_strdup_printf("procmon: partial event length is too large: %" PRIu64 " bytes", event_size)wmem_strdup_printf(((void*)0), "procmon: partial event length is too large: %"
"l" "u" " bytes", event_size)
;
341 return false0;
342 }
343
344 /* Append the size of the stack trace data so the dissector doesn't need to know about system bitness */
345 ws_buffer_append(&wblock.rec->data, (const uint8_t*)&sizeof_stacktrace, sizeof sizeof_stacktrace);
346
347 if (!wtap_read_bytes_buffer(fh, &wblock.rec->data, sizeof_stacktrace, err, err_info)) {
348 ws_debug("Failed to read procmon stack trace data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 348, __func__, "Failed to read procmon stack trace data"); }
} while (0)
;
349 return false0;
350 }
351
352 /* Read detail data */
353 if (!wtap_read_bytes_buffer(fh, &wblock.rec->data, eh_details_size, err, err_info)) {
354 ws_debug("Failed to read procmon detail data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 354, __func__, "Failed to read procmon detail data"); } } while
(0)
;
355 return false0;
356 }
357
358 if (eh_extra_details_offset > 0)
359 {
360 int64_t current_offset = file_tell(fh);
361
362 /* The extra details structure surprisingly can be separated from the event structure */
363 int64_t real_details_offset = eh_extra_details_offset - (COMMON_EVENT_STRUCT_SIZE52 + eh_details_size + sizeof_stacktrace);
364 if (file_seek(fh, real_details_offset, SEEK_CUR1, err) == -1) {
365 ws_debug("Failed to locate procmon extra details data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 365, __func__, "Failed to locate procmon extra details data"
); } } while (0)
;
366 return false0;
367 }
368 /* However, pass the record data up as if it's consecutive */
369 uint16_t extra_details_stream_size;
370 if (!wtap_read_bytes(fh, &extra_details_stream_size, sizeof extra_details_stream_size, err, err_info)) {
371 ws_debug("Failed to read procmon extra details offset")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 371, __func__, "Failed to read procmon extra details offset"
); } } while (0)
;
372 return false0;
373 }
374 extra_details_stream_size = GUINT16_FROM_LE(extra_details_stream_size)(((guint16) (extra_details_stream_size)));
375
376 event_size += sizeof(extra_details_stream_size) + extra_details_stream_size;
377 if (event_size > MAX_PROCMON_EVENT_SIZE262144U) {
378 *err = WTAP_ERR_BAD_FILE-13;
379 *err_info = ws_strdup_printf("procmon: full event length is too large: %" PRIu64 " bytes", event_size)wmem_strdup_printf(((void*)0), "procmon: full event length is too large: %"
"l" "u" " bytes", event_size)
;
380 return false0;
381 }
382
383 ws_buffer_append(&wblock.rec->data, (const uint8_t*)&extra_details_stream_size, sizeof extra_details_stream_size);
384
385 if (!wtap_read_bytes_buffer(fh, &wblock.rec->data, extra_details_stream_size, err, err_info)) {
386 ws_debug("Failed to read procmon extra detail data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 386, __func__, "Failed to read procmon extra detail data");
} } while (0)
;
387 return false0;
388 }
389
390 /* If the extra data doesn't immediately follow the other data */
391 if (real_details_offset != 0)
392 {
393 if (file_seek(fh, current_offset, SEEK_SET0, err) == -1) {
394 ws_debug("Failed to restore procmon event data location")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 394, __func__, "Failed to restore procmon event data location"
); } } while (0)
;
395 return false0;
396 }
397 }
398 }
399
400 /*
401 * We return these to the caller in procmon_read().
402 */
403 wtap_setup_ft_specific_event_rec(wblock.rec, procmon_file_type_subtype, eh_event_class);
404 wblock.rec->rec_header.ft_specific_header.record_len = (uint32_t)ws_buffer_length(&wblock.rec->data);
405 wblock.rec->rec_header.ft_specific_header.pseudo_header.procmon.process_index_map = file_info->process_index_map;
406 wblock.rec->rec_header.ft_specific_header.pseudo_header.procmon.process_index_map_size = file_info->process_index_map_size;
407 wblock.rec->rec_header.ft_specific_header.pseudo_header.procmon.process_array = file_info->process_array;
408 wblock.rec->rec_header.ft_specific_header.pseudo_header.procmon.process_array_size = file_info->process_array_size;
409 wblock.rec->rec_header.ft_specific_header.pseudo_header.procmon.system_bitness = (file_info->header.system_bitness != 0);
410 wblock.internal = false0;
411
412 /*
413 * We want dissectors (particularly packet_frame) to be able to
414 * access packet comments and whatnot that are in the block. wblock->block
415 * will be unref'd by procmon_seek_read(), so move the block to where
416 * dissectors can find it.
417 */
418 wblock.rec->block = wblock.block;
419 wblock.block = NULL((void*)0);
420 return true1;
421}
422
423static bool_Bool procmon_read(wtap *wth, wtap_rec *rec,
424 int *err, char **err_info, int64_t *data_offset)
425{
426 procmon_file_info_t* file_info = (procmon_file_info_t*)wth->priv;
427
428 // file.c and strato.c call wtap_set_cb_new_ipv{4,6} after calling
429 // wtap_open_offline, so read our hosts array here.
430 if (file_info->cur_event == 0) {
431 procmon_read_hosts(wth, file_info->header.host_port_array_offset, err, err_info);
432 }
433
434 /* Stop processing once our offset reaches past events (or the file is malformed) */
435 if (file_info->cur_event >= file_info->header.num_events)
436 {
437 ws_debug("end of events")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 437, __func__, "end of events"); } } while (0)
;
438 return false0;
439 }
440
441 *data_offset = file_info->event_offsets[file_info->cur_event];
442 ws_noisy("file offset is %" PRId64 " array offset is %" PRId64, file_tell(wth->fh), *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/procmon.c"
, 442, __func__, "file offset is %" "l" "d" " array offset is %"
"l" "d", file_tell(wth->fh), *data_offset); } } while (0)
;
443
444 if (file_seek(wth->fh, *data_offset, SEEK_SET0, err) == -1)
445 {
446 ws_debug("Failed to seek to event %u at offsets %" PRId64, file_info->cur_event, *data_offset)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 446, __func__, "Failed to seek to event %u at offsets %" "l"
"d", file_info->cur_event, *data_offset); } } while (0)
;
447 return false0;
448 }
449
450 file_info->cur_event++;
451
452 // if (*data_offset+COMMON_EVENT_STRUCT_SIZE >= (int64_t)file_info->header.event_offsets_array_offset) {
453 // *err = WTAP_ERR_BAD_FILE;
454 // *err_info = ws_strdup_printf("procmon: Not enough room for event content at offset %" PRIi64, *data_offset);
455 // return false;
456 // }
457
458 return procmon_read_event(wth->fh, rec, file_info, err, err_info);
459}
460
461static bool_Bool procmon_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec,
462 int *err, char **err_info)
463{
464 procmon_file_info_t* file_info = (procmon_file_info_t*)wth->priv;
465
466 /* seek to the right file position */
467 if (file_seek(wth->random_fh, seek_off, SEEK_SET0, err) < 0) {
468 return false0; /* Seek error */
469 }
470 ws_noisy("reading at offset %" PRIu64, seek_off)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_NOISY, "wiretap/procmon.c"
, 470, __func__, "reading at offset %" "l" "u", seek_off); } }
while (0)
;
471
472 return procmon_read_event(wth->random_fh, rec, file_info, err, err_info);
473}
474
475static const uint8_t procmon_magic[] = { 'P', 'M', 'L', '_' };
476
477wtap_open_return_val procmon_open(wtap *wth, int *err, char **err_info)
478{
479 procmon_file_info_t* file_info = g_new0(procmon_file_info_t, 1)((procmon_file_info_t *) g_malloc0_n ((1), sizeof (procmon_file_info_t
)))
;
1
Memory is allocated
480 procmon_header_t* header = &file_info->header;
481
482 ws_debug("opening file")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 482, __func__, "opening file"); } } while (0)
;
2
Taking true branch
3
Loop condition is false. Exiting loop
483 /*
484 * First, try to read the procmon header.
485 */
486 if (!wtap_read_bytes_or_eof(wth->fh, header, sizeof(procmon_header_t), err, err_info))
4
Assuming the condition is false
5
Taking false branch
487 {
488 file_info_cleanup(file_info);
489 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 489, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
490 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12) {
491 /*
492 * Short read or EOF.
493 *
494 * We're reading this as part of an open, so
495 * the file is too short to be a procmon file.
496 */
497 *err = 0;
498 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
499 *err_info = NULL((void*)0);
500 }
501 return WTAP_OPEN_NOT_MINE;
502 }
503
504 if (memcmp(&header->signature, procmon_magic, sizeof(procmon_magic)))
6
Assuming the condition is false
7
Taking false branch
505 {
506 file_info_cleanup(file_info);
507 return WTAP_OPEN_NOT_MINE;
508 }
509
510#if G_BYTE_ORDER1234 == G_BIG_ENDIAN4321
511 header->version = GUINT32_SWAP_LE_BE(header->version)(((guint32) ( (((guint32) (header->version) & (guint32
) 0x000000ffU) << 24) | (((guint32) (header->version
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (header
->version) & (guint32) 0x00ff0000U) >> 8) | (((guint32
) (header->version) & (guint32) 0xff000000U) >> 24
))))
;
512 header->system_bitness = GUINT32_SWAP_LE_BE(header->system_bitness)(((guint32) ( (((guint32) (header->system_bitness) & (
guint32) 0x000000ffU) << 24) | (((guint32) (header->
system_bitness) & (guint32) 0x0000ff00U) << 8) | ((
(guint32) (header->system_bitness) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (header->system_bitness) &
(guint32) 0xff000000U) >> 24))))
;
513 header->num_events = GUINT32_SWAP_LE_BE(header->num_events)(((guint32) ( (((guint32) (header->num_events) & (guint32
) 0x000000ffU) << 24) | (((guint32) (header->num_events
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (header
->num_events) & (guint32) 0x00ff0000U) >> 8) | (
((guint32) (header->num_events) & (guint32) 0xff000000U
) >> 24))))
;
514 header->start_events_offset = GUINT64_SWAP_LE_BE(header->start_events_offset)(((guint64) ( (((guint64) (header->start_events_offset) &
(guint64) (0x00000000000000ffUL)) << 56) | (((guint64)
(header->start_events_offset) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->start_events_offset
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->start_events_offset) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->start_events_offset)
& (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->start_events_offset) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->start_events_offset
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->start_events_offset) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
515 header->event_offsets_array_offset = GUINT64_SWAP_LE_BE(header->event_offsets_array_offset)(((guint64) ( (((guint64) (header->event_offsets_array_offset
) & (guint64) (0x00000000000000ffUL)) << 56) | (((guint64
) (header->event_offsets_array_offset) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->event_offsets_array_offset
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->event_offsets_array_offset) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->event_offsets_array_offset
) & (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->event_offsets_array_offset) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->event_offsets_array_offset
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->event_offsets_array_offset) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
516 header->process_array_offset = GUINT64_SWAP_LE_BE(header->process_array_offset)(((guint64) ( (((guint64) (header->process_array_offset) &
(guint64) (0x00000000000000ffUL)) << 56) | (((guint64)
(header->process_array_offset) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->process_array_offset
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->process_array_offset) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->process_array_offset
) & (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->process_array_offset) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->process_array_offset
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->process_array_offset) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
517 header->string_array_offset = GUINT64_SWAP_LE_BE(header->string_array_offset)(((guint64) ( (((guint64) (header->string_array_offset) &
(guint64) (0x00000000000000ffUL)) << 56) | (((guint64)
(header->string_array_offset) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->string_array_offset
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->string_array_offset) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->string_array_offset)
& (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->string_array_offset) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->string_array_offset
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->string_array_offset) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
518 header->icon_array_offset = GUINT64_SWAP_LE_BE(header->icon_array_offset)(((guint64) ( (((guint64) (header->icon_array_offset) &
(guint64) (0x00000000000000ffUL)) << 56) | (((guint64)
(header->icon_array_offset) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->icon_array_offset) &
(guint64) (0x0000000000ff0000UL)) << 24) | (((guint64)
(header->icon_array_offset) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->icon_array_offset) &
(guint64) (0x000000ff00000000UL)) >> 8) | (((guint64) (
header->icon_array_offset) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->icon_array_offset) &
(guint64) (0x00ff000000000000UL)) >> 40) | (((guint64)
(header->icon_array_offset) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
519 header->maximum_user_address = GUINT64_SWAP_LE_BE(header->maximum_user_address)(((guint64) ( (((guint64) (header->maximum_user_address) &
(guint64) (0x00000000000000ffUL)) << 56) | (((guint64)
(header->maximum_user_address) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->maximum_user_address
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->maximum_user_address) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->maximum_user_address
) & (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->maximum_user_address) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->maximum_user_address
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->maximum_user_address) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
520 header->os_version_info_size = GUINT32_SWAP_LE_BE(header->os_version_info_size)(((guint32) ( (((guint32) (header->os_version_info_size) &
(guint32) 0x000000ffU) << 24) | (((guint32) (header->
os_version_info_size) & (guint32) 0x0000ff00U) << 8
) | (((guint32) (header->os_version_info_size) & (guint32
) 0x00ff0000U) >> 8) | (((guint32) (header->os_version_info_size
) & (guint32) 0xff000000U) >> 24))))
;
521 header->major_version = GUINT32_SWAP_LE_BE(header->major_version)(((guint32) ( (((guint32) (header->major_version) & (guint32
) 0x000000ffU) << 24) | (((guint32) (header->major_version
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (header
->major_version) & (guint32) 0x00ff0000U) >> 8) |
(((guint32) (header->major_version) & (guint32) 0xff000000U
) >> 24))))
;
522 header->minor_version = GUINT32_SWAP_LE_BE(header->minor_version)(((guint32) ( (((guint32) (header->minor_version) & (guint32
) 0x000000ffU) << 24) | (((guint32) (header->minor_version
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (header
->minor_version) & (guint32) 0x00ff0000U) >> 8) |
(((guint32) (header->minor_version) & (guint32) 0xff000000U
) >> 24))))
;
523 header->build_number = GUINT32_SWAP_LE_BE(header->build_number)(((guint32) ( (((guint32) (header->build_number) & (guint32
) 0x000000ffU) << 24) | (((guint32) (header->build_number
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (header
->build_number) & (guint32) 0x00ff0000U) >> 8) |
(((guint32) (header->build_number) & (guint32) 0xff000000U
) >> 24))))
;
524 header->platform_id = GUINT32_SWAP_LE_BE(header->platform_id)(((guint32) ( (((guint32) (header->platform_id) & (guint32
) 0x000000ffU) << 24) | (((guint32) (header->platform_id
) & (guint32) 0x0000ff00U) << 8) | (((guint32) (header
->platform_id) & (guint32) 0x00ff0000U) >> 8) | (
((guint32) (header->platform_id) & (guint32) 0xff000000U
) >> 24))))
;
525 header->service_pack_major = GUINT16_SWAP_LE_BE(header->service_pack_major)(((guint16) ( (guint16) ((guint16) (header->service_pack_major
) >> 8) | (guint16) ((guint16) (header->service_pack_major
) << 8))))
;
526 header->service_pack_minor = GUINT16_SWAP_LE_BE(header->service_pack_minor)(((guint16) ( (guint16) ((guint16) (header->service_pack_minor
) >> 8) | (guint16) ((guint16) (header->service_pack_minor
) << 8))))
;
527 header->suite_mask = GUINT16_SWAP_LE_BE(header->suite_mask)(((guint16) ( (guint16) ((guint16) (header->suite_mask) >>
8) | (guint16) ((guint16) (header->suite_mask) << 8
))))
;
528 header->num_processors = GUINT32_SWAP_LE_BE(header->num_processors)(((guint32) ( (((guint32) (header->num_processors) & (
guint32) 0x000000ffU) << 24) | (((guint32) (header->
num_processors) & (guint32) 0x0000ff00U) << 8) | ((
(guint32) (header->num_processors) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (header->num_processors) &
(guint32) 0xff000000U) >> 24))))
;
529 header->total_physical_memory = GUINT64_SWAP_LE_BE(header->total_physical_memory)(((guint64) ( (((guint64) (header->total_physical_memory) &
(guint64) (0x00000000000000ffUL)) << 56) | (((guint64)
(header->total_physical_memory) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->total_physical_memory
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->total_physical_memory) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->total_physical_memory
) & (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->total_physical_memory) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->total_physical_memory
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->total_physical_memory) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
530 header->start_events_offset_dup = GUINT64_SWAP_LE_BE(header->start_events_offset_dup)(((guint64) ( (((guint64) (header->start_events_offset_dup
) & (guint64) (0x00000000000000ffUL)) << 56) | (((guint64
) (header->start_events_offset_dup) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->start_events_offset_dup
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->start_events_offset_dup) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->start_events_offset_dup
) & (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->start_events_offset_dup) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->start_events_offset_dup
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->start_events_offset_dup) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
531 header->host_port_array_offset = GUINT64_SWAP_LE_BE(header->host_port_array_offset)(((guint64) ( (((guint64) (header->host_port_array_offset)
& (guint64) (0x00000000000000ffUL)) << 56) | (((guint64
) (header->host_port_array_offset) & (guint64) (0x000000000000ff00UL
)) << 40) | (((guint64) (header->host_port_array_offset
) & (guint64) (0x0000000000ff0000UL)) << 24) | (((guint64
) (header->host_port_array_offset) & (guint64) (0x00000000ff000000UL
)) << 8) | (((guint64) (header->host_port_array_offset
) & (guint64) (0x000000ff00000000UL)) >> 8) | (((guint64
) (header->host_port_array_offset) & (guint64) (0x0000ff0000000000UL
)) >> 24) | (((guint64) (header->host_port_array_offset
) & (guint64) (0x00ff000000000000UL)) >> 40) | (((guint64
) (header->host_port_array_offset) & (guint64) (0xff00000000000000UL
)) >> 56))))
;
532#endif
533
534 if (header->num_events > MAX_PROCMON_EVENTS(50 * 1000 * 1000)) {
8
Assuming the condition is true
9
Taking true branch
535 // If we need to read more events and the file is uncompressed, we could
536 // use g_mapped_file_new instead.
537 file_info_cleanup(file_info);
10
Calling 'file_info_cleanup'
22
Returning; memory was released via 1st parameter
538 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 538, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
23
Taking true branch
24
Loop condition is false. Exiting loop
539 *err = WTAP_ERR_BAD_FILE-13;
540 *err_info = ws_strdup_printf("Too many events: %u (max %u)", header->num_events, MAX_PROCMON_EVENTS)wmem_strdup_printf(((void*)0), "Too many events: %u (max %u)"
, header->num_events, (50 * 1000 * 1000))
;
25
Use of memory after it is released
541 return WTAP_OPEN_ERROR;
542 }
543
544 // Read the event offsets array, which we use in procmon_read(). It's not clear
545 // if we really need this; in a test capture here the offsets in the array were
546 // identical to the file positions we end up with if we just read sequentially.
547 if (file_seek(wth->fh, header->event_offsets_array_offset, SEEK_SET0, err) == -1)
548 {
549 file_info_cleanup(file_info);
550 ws_debug("Failed to locate event offsets data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 550, __func__, "Failed to locate event offsets data"); } } while
(0)
;
551 return WTAP_OPEN_NOT_MINE;
552 }
553 file_info->event_offsets = g_new(uint32_t, header->num_events)((uint32_t *) g_malloc_n ((header->num_events), sizeof (uint32_t
)))
;
554 for (unsigned idx = 0; idx < header->num_events; idx++) {
555 uint32_t event_offset;
556 // Each offset entry is a uint32_t offset followed by a uint8_t maybe-flags
557 if (!wtap_read_bytes_or_eof(wth->fh, &event_offset, sizeof(event_offset), err, err_info))
558 {
559 file_info_cleanup(file_info);
560 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 560, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
561 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
562 {
563 // Short read or EOF.
564 *err = 0;
565 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
566 *err_info = NULL((void*)0);
567 }
568 return WTAP_OPEN_NOT_MINE;
569 }
570 if (file_seek(wth->fh, 1, SEEK_CUR1, err) == -1)
571 {
572 file_info_cleanup(file_info);
573 ws_debug("Failed to skip flags")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 573, __func__, "Failed to skip flags"); } } while (0)
;
574 return WTAP_OPEN_NOT_MINE;
575 }
576 file_info->event_offsets[idx] = GUINT32_FROM_LE(event_offset)(((guint32) (event_offset)));
577 }
578
579 if (file_seek(wth->fh, header->string_array_offset, SEEK_SET0, err) == -1)
580 {
581 ws_debug("Failed to locate procmon string data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 581, __func__, "Failed to locate procmon string data"); } }
while (0)
;
582 return WTAP_OPEN_NOT_MINE;
583 }
584
585 uint32_t num_strings;
586 if (!wtap_read_bytes_or_eof(wth->fh, &num_strings, sizeof(num_strings), err, err_info))
587 {
588 file_info_cleanup(file_info);
589 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 589, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
590 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
591 {
592 // Short read or EOF.
593 *err = 0;
594 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
595 *err_info = NULL((void*)0);
596 }
597 return WTAP_OPEN_NOT_MINE;
598 }
599 num_strings = GUINT32_FROM_LE(num_strings)(((guint32) (num_strings)));
600 if (num_strings > MAX_PROCMON_STRINGS(1000 * 1000)) {
601 ws_debug("Truncating strings from %u to %u", num_strings, MAX_PROCMON_STRINGS)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 601, __func__, "Truncating strings from %u to %u", num_strings
, (1000 * 1000)); } } while (0)
;
602 num_strings = MAX_PROCMON_STRINGS(1000 * 1000);
603 }
604
605 // Strings aren't necessarily contiguous (or even in order?)
606 uint32_t *str_offsets = g_new(uint32_t, num_strings)((uint32_t *) g_malloc_n ((num_strings), sizeof (uint32_t)));
607 if (!wtap_read_bytes_or_eof(wth->fh, str_offsets, sizeof(uint32_t) * num_strings, err, err_info))
608 {
609 file_info_cleanup(file_info);
610 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 610, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
611 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
612 {
613 // Short read or EOF.
614 *err = 0;
615 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
616 *err_info = NULL((void*)0);
617 }
618 g_free(str_offsets)(__builtin_object_size ((str_offsets), 0) != ((size_t) - 1)) ?
g_free_sized (str_offsets, __builtin_object_size ((str_offsets
), 0)) : (g_free) (str_offsets)
;
619 return WTAP_OPEN_NOT_MINE;
620 }
621#if G_BYTE_ORDER1234 == G_BIG_ENDIAN4321
622 for (unsigned idx = 0; idx < num_strings; idx++)
623 {
624 str_offsets[idx] = GUINT32_SWAP_LE_BE(str_offsets[idx])(((guint32) ( (((guint32) (str_offsets[idx]) & (guint32) 0x000000ffU
) << 24) | (((guint32) (str_offsets[idx]) & (guint32
) 0x0000ff00U) << 8) | (((guint32) (str_offsets[idx]) &
(guint32) 0x00ff0000U) >> 8) | (((guint32) (str_offsets
[idx]) & (guint32) 0xff000000U) >> 24))))
;
625 }
626#endif
627
628 file_info->string_array_size = num_strings;
629 file_info->string_array = g_new0(const char *, num_strings)((const char * *) g_malloc0_n ((num_strings), sizeof (const char
*)))
;
630 gunichar2 *str_buf = g_new(gunichar2, MAX_PROCMON_STRING_LENGTH)((gunichar2 *) g_malloc_n ((8192), sizeof (gunichar2)));
631 for (unsigned idx = 0; idx < num_strings; idx++) {
632 if (file_seek(wth->fh, header->string_array_offset + str_offsets[idx], SEEK_SET0, err) == -1)
633 {
634 file_info_cleanup(file_info);
635 g_free(str_offsets)(__builtin_object_size ((str_offsets), 0) != ((size_t) - 1)) ?
g_free_sized (str_offsets, __builtin_object_size ((str_offsets
), 0)) : (g_free) (str_offsets)
;
636 g_free(str_buf)(__builtin_object_size ((str_buf), 0) != ((size_t) - 1)) ? g_free_sized
(str_buf, __builtin_object_size ((str_buf), 0)) : (g_free) (
str_buf)
;
637 ws_debug("Failed to locate procmon string %u", idx)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 637, __func__, "Failed to locate procmon string %u", idx); }
} while (0)
;
638 return WTAP_OPEN_NOT_MINE;
639 }
640
641 const char *cur_str = procmon_read_string(wth->fh, str_buf, err, err_info);
642 if (!cur_str) {
643 file_info_cleanup(file_info);
644 g_free(str_offsets)(__builtin_object_size ((str_offsets), 0) != ((size_t) - 1)) ?
g_free_sized (str_offsets, __builtin_object_size ((str_offsets
), 0)) : (g_free) (str_offsets)
;
645 g_free(str_buf)(__builtin_object_size ((str_buf), 0) != ((size_t) - 1)) ? g_free_sized
(str_buf, __builtin_object_size ((str_buf), 0)) : (g_free) (
str_buf)
;
646 ws_debug("Failed to read procmon string %u", idx)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 646, __func__, "Failed to read procmon string %u", idx); } }
while (0)
;
647 return WTAP_OPEN_NOT_MINE;
648 }
649
650 file_info->string_array[idx] = cur_str;
651 }
652 g_free(str_offsets)(__builtin_object_size ((str_offsets), 0) != ((size_t) - 1)) ?
g_free_sized (str_offsets, __builtin_object_size ((str_offsets
), 0)) : (g_free) (str_offsets)
;
653 g_free(str_buf)(__builtin_object_size ((str_buf), 0) != ((size_t) - 1)) ? g_free_sized
(str_buf, __builtin_object_size ((str_buf), 0)) : (g_free) (
str_buf)
;
654
655 if (file_seek(wth->fh, header->process_array_offset, SEEK_SET0, err) == -1)
656 {
657 file_info_cleanup(file_info);
658 ws_debug("Failed to locate procmon process data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 658, __func__, "Failed to locate procmon process data"); } }
while (0)
;
659 return WTAP_OPEN_NOT_MINE;
660 }
661
662 uint32_t num_processes;
663 if (!wtap_read_bytes_or_eof(wth->fh, &num_processes, sizeof(num_processes), err, err_info))
664 {
665 file_info_cleanup(file_info);
666 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 666, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
667 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
668 {
669 // Short read or EOF.
670 *err = 0;
671 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
672 *err_info = NULL((void*)0);
673 }
674 return WTAP_OPEN_NOT_MINE;
675 }
676 num_processes = GUINT32_FROM_LE(num_processes)(((guint32) (num_processes)));
677 if (num_processes > MAX_PROCMON_PROCESSES(500 * 1000)) {
678 ws_debug("Truncating processes from %u to %u", num_processes, MAX_PROCMON_PROCESSES)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 678, __func__, "Truncating processes from %u to %u", num_processes
, (500 * 1000)); } } while (0)
;
679 num_processes = MAX_PROCMON_PROCESSES(500 * 1000);
680 }
681
682 uint32_t *process_indices = g_new(uint32_t, num_processes)((uint32_t *) g_malloc_n ((num_processes), sizeof (uint32_t))
)
;
683 if (!wtap_read_bytes_or_eof(wth->fh, process_indices, sizeof(uint32_t) * num_processes, err, err_info))
684 {
685 file_info_cleanup(file_info);
686 g_free(process_indices)(__builtin_object_size ((process_indices), 0) != ((size_t) - 1
)) ? g_free_sized (process_indices, __builtin_object_size ((process_indices
), 0)) : (g_free) (process_indices)
;
687 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 687, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
688 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
689 {
690 // Short read or EOF.
691 *err = 0;
692 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
693 *err_info = NULL((void*)0);
694 }
695 return WTAP_OPEN_NOT_MINE;
696 }
697
698 uint32_t max_process_index = 0;
699 for (unsigned idx = 0; idx < num_processes; idx++) {
700 process_indices[idx] = GUINT32_FROM_LE(process_indices[idx])(((guint32) (process_indices[idx])));
701 max_process_index = MAX(max_process_index, process_indices[idx])(((max_process_index) > (process_indices[idx])) ? (max_process_index
) : (process_indices[idx]))
;
702 }
703 g_free(process_indices)(__builtin_object_size ((process_indices), 0) != ((size_t) - 1
)) ? g_free_sized (process_indices, __builtin_object_size ((process_indices
), 0)) : (g_free) (process_indices)
;
704 if (max_process_index > MAX_PROCMON_PROCESSES(500 * 1000) * 2) {
705 ws_debug("Truncating max process index from %u to %u", max_process_index, MAX_PROCMON_PROCESSES * 2)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 705, __func__, "Truncating max process index from %u to %u"
, max_process_index, (500 * 1000) * 2); } } while (0)
;
706 max_process_index = MAX_PROCMON_PROCESSES(500 * 1000) * 2;
707 }
708 file_info->process_index_map = g_new(uint32_t, max_process_index + 1)((uint32_t *) g_malloc_n ((max_process_index + 1), sizeof (uint32_t
)))
;
709 // Try to make invalid entries obvious.
710 memset(file_info->process_index_map, 0xff, sizeof(uint32_t) * (max_process_index + 1));
711 file_info->process_index_map_size = max_process_index + 1;
712
713 uint32_t *proc_offsets = g_new(uint32_t, num_processes)((uint32_t *) g_malloc_n ((num_processes), sizeof (uint32_t))
)
;
714 if (!wtap_read_bytes_or_eof(wth->fh, proc_offsets, sizeof(uint32_t) * num_processes, err, err_info))
715 {
716 file_info_cleanup(file_info);
717 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
718 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 718, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
719 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
720 {
721 // Short read or EOF.
722 *err = 0;
723 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
724 *err_info = NULL((void*)0);
725 }
726 return WTAP_OPEN_NOT_MINE;
727 }
728
729 file_info->process_array = g_new0(procmon_process_t, num_processes)((procmon_process_t *) g_malloc0_n ((num_processes), sizeof (
procmon_process_t)))
;
730 file_info->process_array_size = num_processes;
731 for (unsigned idx = 0; idx < num_processes; idx++) {
732 if (file_seek(wth->fh, header->process_array_offset + proc_offsets[idx], SEEK_SET0, err) == -1)
733 {
734 file_info_cleanup(file_info);
735 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
736 ws_debug("Failed to locate procmon process %u", idx)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 736, __func__, "Failed to locate procmon process %u", idx);
} } while (0)
;
737 return WTAP_OPEN_NOT_MINE;
738 }
739 procmon_raw_process_t cur_raw_process;
740 if (!wtap_read_bytes_or_eof(wth->fh, &cur_raw_process, sizeof(cur_raw_process), err, err_info))
741 {
742 file_info_cleanup(file_info);
743 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
744 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 744, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
745 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
746 {
747 // Short read or EOF.
748 *err = 0;
749 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
750 *err_info = NULL((void*)0);
751 }
752 return WTAP_OPEN_NOT_MINE;
753 }
754 uint32_t process_index = GUINT32_FROM_LE(cur_raw_process.process_index)(((guint32) (cur_raw_process.process_index)));
755 if (process_index <= max_process_index) {
756 file_info->process_index_map[process_index] = idx;
757 } else {
758 ws_debug("Process %u index %u exceeds max process index %u", idx, process_index, max_process_index)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 758, __func__, "Process %u index %u exceeds max process index %u"
, idx, process_index, max_process_index); } } while (0)
;
759 }
760 procmon_process_t *cur_process = &file_info->process_array[idx];
761 cur_raw_process.start_time = GUINT64_FROM_LE(cur_raw_process.start_time)(((guint64) (cur_raw_process.start_time)));
762 cur_raw_process.end_time = GUINT64_FROM_LE(cur_raw_process.end_time)(((guint64) (cur_raw_process.end_time)));
763 uint64_t filetime = GUINT64_FROM_LE(cur_raw_process.start_time)(((guint64) (cur_raw_process.start_time)));
764 filetime_to_nstime(&cur_process->start_time, filetime);
765 filetime = GUINT64_FROM_LE(cur_raw_process.end_time)(((guint64) (cur_raw_process.end_time)));
766 filetime_to_nstime(&cur_process->end_time, filetime);
767
768 cur_process->process_id = GUINT32_FROM_LE(cur_raw_process.process_id)(((guint32) (cur_raw_process.process_id)));
769 cur_process->parent_process_id = GUINT32_FROM_LE(cur_raw_process.parent_process_id)(((guint32) (cur_raw_process.parent_process_id)));
770 cur_process->parent_process_index = MAX(GUINT32_FROM_LE(cur_raw_process.parent_process_index), max_process_index)((((((guint32) (cur_raw_process.parent_process_index)))) >
(max_process_index)) ? ((((guint32) (cur_raw_process.parent_process_index
)))) : (max_process_index))
;
771 cur_process->authentication_id = GUINT64_FROM_LE(cur_raw_process.authentication_id)(((guint64) (cur_raw_process.authentication_id)));
772 cur_process->session_number = GUINT32_FROM_LE(cur_raw_process.session_number)(((guint32) (cur_raw_process.session_number)));
773 cur_process->is_virtualized = cur_raw_process.is_virtualized != 0;
774 cur_process->is_64_bit = cur_raw_process.is_64_bit != 0;
775 cur_process->integrity = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.integrity_si)(((guint32) (cur_raw_process.integrity_si))));
776 cur_process->user_name = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.user_name_si)(((guint32) (cur_raw_process.user_name_si))));
777 cur_process->process_name = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.process_name_si)(((guint32) (cur_raw_process.process_name_si))));
778 cur_process->image_path = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.image_path_si)(((guint32) (cur_raw_process.image_path_si))));
779 cur_process->command_line = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.command_line_si)(((guint32) (cur_raw_process.command_line_si))));
780 cur_process->company = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.company_si)(((guint32) (cur_raw_process.company_si))));
781 cur_process->version = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.version_si)(((guint32) (cur_raw_process.version_si))));
782 cur_process->description = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_process.description_si)(((guint32) (cur_raw_process.description_si))));
783 if (file_seek(wth->fh, header->system_bitness ? 8 : 4, SEEK_CUR1, err) == -1)
784 {
785 file_info_cleanup(file_info);
786 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
787 ws_debug("Failed to locate number of modules %u", idx)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 787, __func__, "Failed to locate number of modules %u", idx
); } } while (0)
;
788 return WTAP_OPEN_NOT_MINE;
789 }
790 uint32_t num_modules;
791 if (!wtap_read_bytes_or_eof(wth->fh, &num_modules, sizeof(num_modules), err, err_info))
792 {
793 file_info_cleanup(file_info);
794 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
795 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 795, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
796 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
797 {
798 // Short read or EOF.
799 *err = 0;
800 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
801 *err_info = NULL((void*)0);
802 }
803 return WTAP_OPEN_NOT_MINE;
804 }
805
806 cur_process->num_modules = MIN(GUINT32_FROM_LE(num_modules), MAX_PROCMON_MODULES)((((((guint32) (num_modules)))) < (1000)) ? ((((guint32) (
num_modules)))) : (1000))
;
807 if (cur_process->num_modules > 0) {
808 cur_process->modules = g_new(procmon_module_t, cur_process->num_modules)((procmon_module_t *) g_malloc_n ((cur_process->num_modules
), sizeof (procmon_module_t)))
;
809 for (unsigned mod_idx = 0; mod_idx < cur_process->num_modules; mod_idx++) {
810 if (cur_process->is_64_bit) {
811 procmon_raw_module_64_t cur_raw_module;
812 if (!wtap_read_bytes_or_eof(wth->fh, &cur_raw_module, sizeof(cur_raw_module), err, err_info)) {
813 file_info_cleanup(file_info);
814 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
815 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 815, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
816 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
817 {
818 // Short read or EOF.
819 *err = 0;
820 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
821 *err_info = NULL((void*)0);
822 }
823 return WTAP_OPEN_NOT_MINE;
824 }
825 procmon_module_t *cur_module = &cur_process->modules[mod_idx];
826 cur_module->base_address = GUINT64_FROM_LE(cur_raw_module.base_address)(((guint64) (cur_raw_module.base_address)));
827 cur_module->size = GUINT32_FROM_LE(cur_raw_module.size)(((guint32) (cur_raw_module.size)));
828 cur_module->image_path = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.image_path_si)(((guint32) (cur_raw_module.image_path_si))));
829 cur_module->version = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.version_si)(((guint32) (cur_raw_module.version_si))));
830 cur_module->company = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.company_si)(((guint32) (cur_raw_module.company_si))));
831 cur_module->description = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.description_si)(((guint32) (cur_raw_module.description_si))));
832 // filetime = GUINT64_FROM_LE(cur_raw_module.timestamp);
833 // filetime_to_nstime(&cur_module->timestamp, filetime);
834 } else {
835 procmon_raw_module_32_t cur_raw_module;
836 if (!wtap_read_bytes_or_eof(wth->fh, &cur_raw_module, sizeof(cur_raw_module), err, err_info)) {
837 file_info_cleanup(file_info);
838 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
839 ws_debug("wtap_read_bytes_or_eof() failed, err = %d.", *err)do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 839, __func__, "wtap_read_bytes_or_eof() failed, err = %d."
, *err); } } while (0)
;
840 if (*err == 0 || *err == WTAP_ERR_SHORT_READ-12)
841 {
842 // Short read or EOF.
843 *err = 0;
844 g_free(*err_info)(__builtin_object_size ((*err_info), 0) != ((size_t) - 1)) ? g_free_sized
(*err_info, __builtin_object_size ((*err_info), 0)) : (g_free
) (*err_info)
;
845 *err_info = NULL((void*)0);
846 }
847 return WTAP_OPEN_NOT_MINE;
848 }
849 procmon_module_t *cur_module = &cur_process->modules[mod_idx];
850 cur_module->base_address = GUINT32_FROM_LE(cur_raw_module.base_address)(((guint32) (cur_raw_module.base_address)));
851 cur_module->size = GUINT32_FROM_LE(cur_raw_module.size)(((guint32) (cur_raw_module.size)));
852 cur_module->image_path = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.image_path_si)(((guint32) (cur_raw_module.image_path_si))));
853 cur_module->version = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.version_si)(((guint32) (cur_raw_module.version_si))));
854 cur_module->company = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.company_si)(((guint32) (cur_raw_module.company_si))));
855 cur_module->description = procmon_string(file_info, GUINT32_FROM_LE(cur_raw_module.description_si)(((guint32) (cur_raw_module.description_si))));
856 // filetime = GUINT64_FROM_LE(cur_raw_module.timestamp);
857 // filetime_to_nstime(&cur_module->timestamp, filetime);
858 }
859 }
860 } else {
861 cur_process->modules = NULL((void*)0);
862 }
863 }
864 g_free(proc_offsets)(__builtin_object_size ((proc_offsets), 0) != ((size_t) - 1))
? g_free_sized (proc_offsets, __builtin_object_size ((proc_offsets
), 0)) : (g_free) (proc_offsets)
;
865
866 if (file_seek(wth->fh, header->start_events_offset, SEEK_SET0, err) == -1)
867 {
868 ws_debug("Failed to locate procmon events data")do { if (1) { ws_log_full("Wiretap", LOG_LEVEL_DEBUG, "wiretap/procmon.c"
, 868, __func__, "Failed to locate procmon events data"); } }
while (0)
;
869 return WTAP_OPEN_NOT_MINE;
870 }
871
872 wth->meta_events = g_array_new(false0, false0, sizeof(wtap_block_t));
873
874 wth->priv = file_info;
875 wth->file_type_subtype = procmon_file_type_subtype;
876 wth->file_encap = WTAP_ENCAP_PROCMON227;
877
878 wth->snapshot_length = 0;
879 wth->file_tsprec = WTAP_TSPREC_SEC0;
880
881 wth->subtype_read = procmon_read;
882 wth->subtype_seek_read = procmon_seek_read;
883
884 wth->subtype_close = procmon_close;
885
886 return WTAP_OPEN_MINE;
887}
888
889/* Options for meta event blocks. */
890static const struct supported_option_type ft_specific_event_block_options_supported[] = {
891 { OPT_COMMENT1, MULTIPLE_OPTIONS_SUPPORTED },
892 { OPT_CUSTOM_STR_COPY2988, MULTIPLE_OPTIONS_SUPPORTED },
893 { OPT_CUSTOM_BIN_COPY2989, MULTIPLE_OPTIONS_SUPPORTED },
894 { OPT_CUSTOM_STR_NO_COPY19372, MULTIPLE_OPTIONS_SUPPORTED },
895 { OPT_CUSTOM_BIN_NO_COPY19373, MULTIPLE_OPTIONS_SUPPORTED }
896};
897
898static const struct supported_block_type procmon_blocks_supported[] = {
899
900 /* Multiple file-type specific events (including local ones). */
901 { WTAP_BLOCK_FT_SPECIFIC_EVENT, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(ft_specific_event_block_options_supported)(sizeof (ft_specific_event_block_options_supported) / sizeof (
ft_specific_event_block_options_supported)[0]), ft_specific_event_block_options_supported
},
902
903 /* Multiple custom blocks. */
904 { WTAP_BLOCK_CUSTOM, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED0, ((void*)0) },
905};
906
907static const struct file_type_subtype_info procmon_info = {
908 "MS Procmon files", "procmon", NULL((void*)0), NULL((void*)0),
909 false0, BLOCKS_SUPPORTED(procmon_blocks_supported)(sizeof (procmon_blocks_supported) / sizeof (procmon_blocks_supported
)[0]), procmon_blocks_supported
,
910 NULL((void*)0), NULL((void*)0), NULL((void*)0)
911};
912
913void register_procmon(void)
914{
915 procmon_file_type_subtype = wtap_register_file_type_subtype(&procmon_info);
916
917 /*
918 * Register name for backwards compatibility with the
919 * wtap_filetypes table in Lua.
920 */
921 wtap_register_backwards_compatibility_lua_name("Procmon", procmon_file_type_subtype);
922}
923
924/*
925 * Editor modelines - https://www.wireshark.org/tools/modelines.html
926 *
927 * Local Variables:
928 * c-basic-offset: 4
929 * tab-width: 8
930 * indent-tabs-mode: nil
931 * End:
932 *
933 * vi: set shiftwidth=4 tabstop=8 expandtab:
934 * :indentSize=4:tabSize=8:noTabs=true:
935 */