1 /* file-elf.c
2 * Routines for Executable and Linkable Format
3 * Based on: SYSTEM V APPLICATION BINARY INTERFACE Edition 4.1
4 * https://www.sco.com/developers/devspecs/
5 * https://www.sco.com/developers/gabi/latest/contents.html
6 * https://refspecs.linuxfoundation.org/
7 * https://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
8 * http://dwarfstd.org/doc/DWARF4.pdf
9 *
10 * Copyright 2013, Michal Labedzki for Tieto Corporation
11 * Copyright (C) 2019 Peter Wu <peter@lekensteyn.nl>
12 *
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
16 *
17 * SPDX-License-Identifier: GPL-2.0-or-later
18 */
19
20 #include "config.h"
21
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/expert.h>
25
26 static dissector_handle_t elf_handle;
27
28 static int proto_elf = -1;
29
30 static int hf_elf_magic_bytes = -1;
31 static int hf_elf_file_size = -1;
32 static int hf_elf_header_segment_size = -1;
33 static int hf_elf_blackholes_size = -1;
34 static int hf_elf_blackhole_size = -1;
35 static int hf_elf_overlapping_size = -1;
36 static int hf_elf_segment = -1;
37 static int hf_elf_entry_bytes = -1;
38 static int hf_elf_file_class = -1;
39 static int hf_elf_data_encoding = -1;
40 static int hf_elf_file_version = -1;
41 static int hf_elf_os_abi = -1;
42 static int hf_elf_abi_version = -1;
43 static int hf_elf_file_padding = -1;
44 static int hf_elf_type = -1;
45 static int hf_elf_machine = -1;
46 static int hf_elf_version = -1;
47 static int hf_elf_entry = -1;
48 static int hf_elf_phoff = -1;
49 static int hf_elf_shoff = -1;
50 static int hf_elf64_entry = -1;
51 static int hf_elf64_phoff = -1;
52 static int hf_elf64_shoff = -1;
53 static int hf_elf_flags = -1;
54 static int hf_elf_ehsize = -1;
55 static int hf_elf_phentsize = -1;
56 static int hf_elf_phnum = -1;
57 static int hf_elf_shentsize = -1;
58 static int hf_elf_shnum = -1;
59 static int hf_elf_shstrndx = -1;
60 static int hf_elf_p_type = -1;
61 static int hf_elf_p_type_operating_system_specific = -1;
62 static int hf_elf_p_type_processor_specific = -1;
63 static int hf_elf_p_flags_execute = -1;
64 static int hf_elf_p_flags_write = -1;
65 static int hf_elf_p_flags_read = -1;
66 static int hf_elf_p_flags_reserved = -1;
67 static int hf_elf_p_flags_operating_system_specific = -1;
68 static int hf_elf_p_flags_processor_specific = -1;
69 static int hf_elf_p_offset = -1;
70 static int hf_elf64_p_offset = -1;
71 static int hf_elf_p_vaddr = -1;
72 static int hf_elf64_p_vaddr = -1;
73 static int hf_elf_p_paddr = -1;
74 static int hf_elf64_p_paddr = -1;
75 static int hf_elf_p_filesz = -1;
76 static int hf_elf64_p_filesz = -1;
77 static int hf_elf_p_memsz = -1;
78 static int hf_elf64_p_memsz = -1;
79 static int hf_elf_p_align = -1;
80 static int hf_elf64_p_align = -1;
81
82 static int hf_elf_sh_name = -1;
83 static int hf_elf_sh_type_user_specific = -1;
84 static int hf_elf_sh_type_operating_system_specific = -1;
85 static int hf_elf_sh_type_processor_specific = -1;
86 static int hf_elf_sh_type = -1;
87
88 static int hf_elf_sh_flags_processor_specific = -1;
89 static int hf_elf_sh_flags_operating_system_specific = -1;
90 static int hf_elf_sh_flags_reserved = -1;
91 static int hf_elf_sh_flags_tls = -1;
92 static int hf_elf_sh_flags_group = -1;
93 static int hf_elf_sh_flags_os_nonconforming = -1;
94 static int hf_elf_sh_flags_link_order = -1;
95 static int hf_elf_sh_flags_info_link = -1;
96 static int hf_elf_sh_flags_strings = -1;
97 static int hf_elf_sh_flags_merge = -1;
98 static int hf_elf_sh_flags_reserved_8 = -1;
99 static int hf_elf_sh_flags_exec_instr = -1;
100 static int hf_elf_sh_flags_alloc = -1;
101 static int hf_elf_sh_flags_write = -1;
102 static int hf_elf_sh_addr = -1;
103 static int hf_elf64_sh_addr = -1;
104
105 static int hf_elf_sh_offset = -1;
106 static int hf_elf64_sh_offset = -1;
107 static int hf_elf_sh_size = -1;
108 static int hf_elf64_sh_size = -1;
109 static int hf_elf_sh_link = -1;
110 static int hf_elf_sh_info = -1;
111 static int hf_elf_sh_addralign = -1;
112 static int hf_elf64_sh_addralign = -1;
113 static int hf_elf_sh_entsize = -1;
114 static int hf_elf64_sh_entsize = -1;
115
116 static int hf_elf_eh_frame_length = -1;
117 static int hf_elf_eh_frame_extended_length = -1;
118 static int hf_elf_eh_frame_cie_id = -1;
119 static int hf_elf_eh_frame_version = -1;
120 static int hf_elf_eh_frame_augmentation_string = -1;
121 static int hf_elf_eh_frame_code_alignment_factor = -1;
122 static int hf_elf_eh_frame_data_alignment_factor = -1;
123 static int hf_elf_eh_frame_return_address_register = -1;
124 static int hf_elf_eh_frame_augmentation_length = -1;
125 static int hf_elf_eh_frame_augmentation_data = -1;
126 static int hf_elf_eh_frame_initial_instructions = -1;
127
128 static int hf_elf_eh_frame_fde_length = -1;
129 static int hf_elf_eh_frame_fde_extended_length = -1;
130 static int hf_elf_eh_frame_fde_cie_pointer = -1;
131 static int hf_elf_eh_frame_fde_pc_begin = -1;
132 static int hf_elf_eh_frame_fde_pc_range = -1;
133 static int hf_elf_eh_frame_fde_augmentation_length = -1;
134 static int hf_elf_eh_frame_fde_augmentation_data = -1;
135 static int hf_elf_eh_frame_fde_call_frame_instructions = -1;
136
137 static int hf_elf_eh_frame_hdr_version = -1;
138 static int hf_elf_eh_frame_hdr_exception_frame_pointer_encoding = -1;
139 static int hf_elf_eh_frame_hdr_fde_count_encoding = -1;
140 static int hf_elf_eh_frame_hdr_binary_search_table_encoding = -1;
141 static int hf_elf_eh_frame_hdr_eh_frame_ptr = -1;
142 static int hf_elf_eh_frame_hdr_fde_count = -1;
143 static int hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location = -1;
144 static int hf_elf_eh_frame_hdr_binary_search_table_entry_address = -1;
145
146 static int hf_elf_symbol_table_name_index = -1;
147 static int hf_elf_symbol_table_value = -1;
148 static int hf_elf64_symbol_table_value = -1;
149 static int hf_elf_symbol_table_size = -1;
150 static int hf_elf64_symbol_table_size = -1;
151 static int hf_elf_symbol_table_info = -1;
152 static int hf_elf_symbol_table_info_bind = -1;
153 static int hf_elf_symbol_table_info_type = -1;
154 static int hf_elf_symbol_table_other = -1;
155 static int hf_elf_symbol_table_shndx = -1;
156
157 static int hf_elf_dynamic_tag = -1;
158 static int hf_elf_dynamic_value = -1;
159 static int hf_elf_dynamic_pointer = -1;
160 static int hf_elf_dynamic_ignored = -1;
161 static int hf_elf_dynamic_unspecified = -1;
162 static int hf_elf64_dynamic_tag = -1;
163 static int hf_elf64_dynamic_value = -1;
164 static int hf_elf64_dynamic_pointer = -1;
165 static int hf_elf64_dynamic_ignored = -1;
166 static int hf_elf64_dynamic_unspecified = -1;
167
168 static int hf_elf_string = -1;
169
170 static int hf_dwarf_omit = -1;
171 static int hf_dwarf_upper = -1;
172 static int hf_dwarf_format = -1;
173
174 static expert_field ei_invalid_segment_size = EI_INIT;
175 static expert_field ei_invalid_entry_size = EI_INIT;
176 static expert_field ei_cfi_extraneous_data = EI_INIT;
177 static expert_field ei_invalid_cie_length = EI_INIT;
178
179 static gint ett_elf = -1;
180 static gint ett_elf_header = -1;
181 static gint ett_elf_program_header = -1;
182 static gint ett_elf_program_header_entry = -1;
183 static gint ett_elf_section_header = -1;
184 static gint ett_elf_section_header_entry = -1;
185 static gint ett_elf_segment = -1;
186 static gint ett_elf_cfi_record = -1;
187 static gint ett_elf_cie_entry = -1;
188 static gint ett_elf_fde_entry = -1;
189 static gint ett_elf_cie_terminator = -1;
190 static gint ett_elf_info = -1;
191 static gint ett_elf_black_holes = -1;
192 static gint ett_elf_overlapping = -1;
193 static gint ett_dwarf_encoding = -1;
194 static gint ett_binary_table = -1;
195 static gint ett_binary_table_entry = -1;
196 static gint ett_symbol_table_entry = -1;
197 static gint ett_symbol_table_info = -1;
198
199 #define REGISTER_32_SIZE 4
200 #define REGISTER_64_SIZE 8
201
202 static const value_string class_vals[] = {
203 { 0x00, "Invalid class" },
204 { 0x01, "32-bit object" },
205 { 0x02, "64-bit object" },
206 { 0, NULL }
207 };
208
209 static const value_string data_encoding_vals[] = {
210 { 0x00, "None" },
211 { 0x01, "Least Significant Bit" },
212 { 0x02, "Most Significant Bit " },
213 { 0, NULL }
214 };
215
216 static const value_string version_vals[] = {
217 { 0x00, "None" },
218 { 0x01, "Current" },
219 { 0, NULL }
220 };
221
222 static const value_string type_vals[] = {
223 { 0x0000, "No file type" },
224 { 0x0001, "Relocatable file" },
225 { 0x0002, "Executable file" },
226 { 0x0003, "Shared object file" },
227 { 0x0004, "Core file" },
228 { 0xFE00, "Operating system-specific Lo" }, /* From Draft */
229 { 0xFEFF, "Operating system-specific Hi" }, /* From Draft */
230 { 0xFF00, "Processor Specific Lo" },
231 { 0xFFFF, "Processor Specific Hi" },
232 { 0, NULL }
233 };
234
235 /* From https://www.sco.com/developers/gabi/latest/ch4.eheader.html */
236 static const value_string machine_vals[] = {
237 { 0, "No machine" },
238 { 1, "AT&T WE 32100" },
239 { 2, "SPARC" },
240 { 3, "Intel 80386" },
241 { 4, "Motorola 68000" },
242 { 5, "Motorola 88000" },
243 { 6, "Intel MCU" },
244 { 7, "Intel 80860" },
245 { 8, "MIPS I Architecture" },
246 { 9, "IBM System/370 Processor" },
247 { 10, "MIPS RS3000 Little-endian" },
248 { 15, "Hewlett-Packard PA-RISC" },
249 { 17, "Fujitsu VPP500" },
250 { 18, "Enhanced instruction set SPARC" },
251 { 19, "Intel 80960" },
252 { 20, "PowerPC" },
253 { 21, "64-bit PowerPC" },
254 { 22, "IBM System/390 Processor" },
255 { 23, "IBM SPU/SPC" },
256 { 36, "NEC V800" },
257 { 37, "Fujitsu FR20" },
258 { 38, "TRW RH-32" },
259 { 39, "Motorola RCE" },
260 { 40, "ARM 32-bit architecture (AARCH32)" },
261 { 41, "Digital Alpha" },
262 { 42, "Hitachi SH" },
263 { 43, "SPARC Version 9" },
264 { 44, "Siemens TriCore embedded processor" },
265 { 45, "Argonaut RISC Core, Argonaut Technologies Inc." },
266 { 46, "Hitachi H8/300" },
267 { 47, "Hitachi H8/300H" },
268 { 48, "Hitachi H8S" },
269 { 49, "Hitachi H8/500" },
270 { 50, "Intel IA-64 processor architecture" },
271 { 51, "Stanford MIPS-X" },
272 { 52, "Motorola ColdFire" },
273 { 53, "Motorola M68HC12" },
274 { 54, "Fujitsu MMA Multimedia Accelerator" },
275 { 55, "Siemens PCP" },
276 { 56, "Sony nCPU embedded RISC processor" },
277 { 57, "Denso NDR1 microprocessor" },
278 { 58, "Motorola Star*Core processor" },
279 { 59, "Toyota ME16 processor" },
280 { 60, "STMicroelectronics ST100 processor" },
281 { 61, "Advanced Logic Corp. TinyJ embedded processor family" },
282 { 62, "AMD x86-64 architecture" },
283 { 63, "Sony DSP Processor" },
284 { 64, "Digital Equipment Corp. PDP-10" },
285 { 65, "Digital Equipment Corp. PDP-11" },
286 { 66, "Siemens FX66 microcontroller" },
287 { 67, "STMicroelectronics ST9+ 8/16 bit microcontroller" },
288 { 68, "STMicroelectronics ST7 8-bit microcontroller" },
289 { 69, "Motorola MC68HC16 Microcontroller" },
290 { 70, "Motorola MC68HC11 Microcontroller" },
291 { 71, "Motorola MC68HC08 Microcontroller" },
292 { 72, "Motorola MC68HC05 Microcontroller" },
293 { 73, "Silicon Graphics SVx" },
294 { 74, "STMicroelectronics ST19 8-bit microcontroller" },
295 { 75, "Digital VAX" },
296 { 76, "Axis Communications 32-bit embedded processor" },
297 { 77, "Infineon Technologies 32-bit embedded processor" },
298 { 78, "Element 14 64-bit DSP Processor" },
299 { 79, "LSI Logic 16-bit DSP Processor" },
300 { 80, "Donald Knuth's educational 64-bit processor" },
301 { 81, "Harvard University machine-independent object files" },
302 { 82, "SiTera Prism" },
303 { 83, "Atmel AVR 8-bit microcontroller" },
304 { 84, "Fujitsu FR30" },
305 { 85, "Mitsubishi D10V" },
306 { 86, "Mitsubishi D30V" },
307 { 87, "NEC v850" },
308 { 88, "Mitsubishi M32R" },
309 { 89, "Matsushita MN10300" },
310 { 90, "Matsushita MN10200" },
311 { 91, "picoJava" },
312 { 92, "OpenRISC 32-bit embedded processor" },
313 { 93, "ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)" },
314 { 94, "Tensilica Xtensa Architecture" },
315 { 95, "Alphamosaic VideoCore processor" },
316 { 96, "Thompson Multimedia General Purpose Processor" },
317 { 97, "National Semiconductor 32000 series" },
318 { 98, "Tenor Network TPC processor" },
319 { 99, "Trebia SNP 1000 processor" },
320 { 100, "STMicroelectronics (www.st.com) ST200 microcontroller" },
321 { 101, "Ubicom IP2xxx microcontroller family" },
322 { 102, "MAX Processor" },
323 { 103, "National Semiconductor CompactRISC microprocessor" },
324 { 104, "Fujitsu F2MC16" },
325 { 105, "Texas Instruments embedded microcontroller msp430" },
326 { 106, "Analog Devices Blackfin (DSP) processor" },
327 { 107, "S1C33 Family of Seiko Epson processors" },
328 { 108, "Sharp embedded microprocessor" },
329 { 109, "Arca RISC Microprocessor" },
330 { 110, "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University" },
331 { 111, "eXcess: 16/32/64-bit configurable embedded CPU" },
332 { 112, "Icera Semiconductor Inc. Deep Execution Processor" },
333 { 113, "Altera Nios II soft-core processor" },
334 { 114, "National Semiconductor CompactRISC CRX microprocessor" },
335 { 115, "Motorola XGATE embedded processor" },
336 { 116, "Infineon C16x/XC16x processor" },
337 { 117, "Renesas M16C series microprocessors" },
338 { 118, "Microchip Technology dsPIC30F Digital Signal Controller" },
339 { 119, "Freescale Communication Engine RISC core" },
340 { 120, "Renesas M32C series microprocessors" },
341 { 131, "Altium TSK3000 core" },
342 { 132, "Freescale RS08 embedded processor" },
343 { 133, "Analog Devices SHARC family of 32-bit DSP processors" },
344 { 134, "Cyan Technology eCOG2 microprocessor" },
345 { 135, "Sunplus S+core7 RISC processor" },
346 { 136, "New Japan Radio (NJR) 24-bit DSP Processor" },
347 { 137, "Broadcom VideoCore III processor" },
348 { 138, "RISC processor for Lattice FPGA architecture" },
349 { 139, "Seiko Epson C17 family" },
350 { 140, "The Texas Instruments TMS320C6000 DSP family" },
351 { 141, "The Texas Instruments TMS320C2000 DSP family" },
352 { 142, "The Texas Instruments TMS320C55x DSP family" },
353 { 143, "Texas Instruments Application Specific RISC Processor, 32bit fetch" },
354 { 144, "Texas Instruments Programmable Realtime Unit" },
355 { 160, "STMicroelectronics 64bit VLIW Data Signal Processor" },
356 { 161, "Cypress M8C microprocessor" },
357 { 162, "Renesas R32C series microprocessors" },
358 { 163, "NXP Semiconductors TriMedia architecture family" },
359 { 164, "QUALCOMM DSP6 Processor" },
360 { 165, "Intel 8051 and variants" },
361 { 166, "STMicroelectronics STxP7x family of configurable and extensible RISC processors" },
362 { 167, "Andes Technology compact code size embedded RISC processor family" },
363 { 168, "Cyan Technology eCOG1X family" },
364 { 168, "Cyan Technology eCOG1X family" },
365 { 169, "Dallas Semiconductor MAXQ30 Core Micro-controllers" },
366 { 170, "New Japan Radio (NJR) 16-bit DSP Processor" },
367 { 171, "M2000 Reconfigurable RISC Microprocessor" },
368 { 172, "Cray Inc. NV2 vector architecture" },
369 { 173, "Renesas RX family" },
370 { 174, "Imagination Technologies META processor architecture" },
371 { 175, "MCST Elbrus general purpose hardware architecture" },
372 { 176, "Cyan Technology eCOG16 family" },
373 { 177, "National Semiconductor CompactRISC CR16 16-bit microprocessor" },
374 { 178, "Freescale Extended Time Processing Unit" },
375 { 179, "Infineon Technologies SLE9X core" },
376 { 180, "Intel L10M" },
377 { 181, "Intel K10M" },
378 { 182, "Reserved for future Intel use" },
379 { 183, "ARM 64-bit architecture (AARCH64)" },
380 { 184, "Reserved for future ARM use" },
381 { 185, "Atmel Corporation 32-bit microprocessor family" },
382 { 186, "STMicroeletronics STM8 8-bit microcontroller" },
383 { 187, "Tilera TILE64 multicore architecture family" },
384 { 188, "Tilera TILEPro multicore architecture family" },
385 { 189, "Xilinx MicroBlaze 32-bit RISC soft processor core" },
386 { 190, "NVIDIA CUDA architecture" },
387 { 191, "Tilera TILE-Gx multicore architecture family" },
388 { 192, "CloudShield architecture family" },
389 { 193, "KIPO-KAIST Core-A 1st generation processor family" },
390 { 194, "KIPO-KAIST Core-A 2nd generation processor family" },
391 { 195, "Synopsys ARCompact V2" },
392 { 196, "Open8 8-bit RISC soft processor core" },
393 { 197, "Renesas RL78 family" },
394 { 198, "Broadcom VideoCore V processor" },
395 { 199, "Renesas 78KOR family" },
396 { 200, "Freescale 56800EX Digital Signal Controller (DSC)" },
397 { 201, "Beyond BA1 CPU architecture" },
398 { 202, "Beyond BA2 CPU architecture" },
399 { 203, "XMOS xCORE processor family" },
400 { 204, "Microchip 8-bit PIC(r) family" },
401 { 205, "Reserved by Intel" },
402 { 206, "Reserved by Intel" },
403 { 207, "Reserved by Intel" },
404 { 208, "Reserved by Intel" },
405 { 209, "Reserved by Intel" },
406 { 210, "KM211 KM32 32-bit processor" },
407 { 211, "KM211 KMX32 32-bit processor" },
408 { 212, "KM211 KMX16 16-bit processor" },
409 { 213, "KM211 KMX8 8-bit processor" },
410 { 214, "KM211 KVARC processor" },
411 { 215, "Paneve CDP architecture family" },
412 { 216, "Cognitive Smart Memory Processor" },
413 { 217, "Bluechip Systems CoolEngine" },
414 { 218, "Nanoradio Optimized RISC" },
415 { 219, "CSR Kalimba architecture family" },
416 { 220, "Zilog Z80" },
417 { 221, "Controls and Data Services VISIUMcore processor" },
418 { 222, "FTDI Chip FT32 high performance 32-bit RISC architecture" },
419 { 223, "Moxie processor family" },
420 { 224, "AMD GPU architecture" },
421 { 243, "RISC-V" },
422 { 247, "Linux kernel bpf virtual machine" }, /* From LLVM / glibc 2.24 */
423 { 252, "C-SKY" }, /* from glibc 2.30 elf/elf.h commit 5fbcd76351ee */
424 { 0, NULL }
425 };
426 static value_string_ext machine_vals_ext = VALUE_STRING_EXT_INIT(machine_vals);
427
428 /* From Draft */
429 static const value_string os_abi_vals[] = {
430 { 0x00, "No extensions or unspecified" },
431 { 0x01, "Hewlett-Packard HP-UX" },
432 { 0x02, "NetBSD" },
433 { 0x03, "GNU (historical alias: Linux)" },
434 { 0x06, "Sun Solaris" },
435 { 0x07, "AIX" },
436 { 0x08, "IRIX" },
437 { 0x09, "FreeBSD" },
438 { 0x0A, "Compaq TRU64 UNIX" },
439 { 0x0B, "Novell Modesto" },
440 { 0x0C, "Open BSD" },
441 { 0x0D, "Open VMS" },
442 { 0x0E, "Hewlett-Packard Non-Stop Kernel" },
443 { 0x0F, "Amiga Research OS" },
444 { 0x10, "The FenixOS highly scalable multi-core OS" },
445 { 0, NULL }
446 };
447 static value_string_ext os_abi_vals_ext = VALUE_STRING_EXT_INIT(os_abi_vals);
448
449 static const value_string p_type_vals[] = {
450 { 0, "PT_NULL" },
451 { 1, "PT_LOAD" },
452 { 2, "PT_DYNAMIC" },
453 { 3, "PT_INTERP" },
454 { 4, "PT_NOTE" },
455 { 5, "PT_SHLIB" },
456 { 6, "PT_PHDR" },
457 { 7, "PT_TLS" },
458 { 0, NULL }
459 };
460
461 static const value_string sh_type_vals[] = {
462 { 0, "SHT_NULL" },
463 { 1, "SHT_PROGBITS" },
464 { 2, "SHT_SYMTAB" },
465 { 3, "SHT_STRTAB" },
466 { 4, "SHT_RELA" },
467 { 5, "SHT_HASH" },
468 { 6, "SHT_DYNAMIC" },
469 { 7, "SHT_NOTE" },
470 { 8, "SHT_NOBITS" },
471 { 9, "SHT_REL" },
472 { 10, "SHT_SHLIB" },
473 { 11, "SHT_DYNSYM" },
474 { 14, "SHT_INIT_ARRAY" },
475 { 15, "SHT_FINI_ARRAY" },
476 { 16, "SHT_PREINIT_ARRAY" },
477 { 17, "SHT_GROUP" },
478 { 18, "SHT_SYMTAB_SHNDX" },
479 /* TODO: https://www.sco.com/developers/gabi/latest/ch4.sheader.html range_string? */
480 { 0, NULL }
481 };
482 static value_string_ext sh_type_vals_ext = VALUE_STRING_EXT_INIT(sh_type_vals);
483
484 static const value_string eh_dwarf_upper[] = {
485 { 0x0, "Normal Value" },
486 { 0x1, "Value is relative to the current program counter. (DW_EH_PE_pcrel)" },
487 { 0x2, "Value is relative to the beginning of the .text section. (DW_EH_PE_textrel)" },
488 { 0x3, "Value is relative to the beginning of the .got or .eh_frame_hdr section. (DW_EH_PE_datarel)" },
489 { 0x4, "Value is relative to the beginning of the function. (DW_EH_PE_funcrel)" },
490 { 0x5, "Value is aligned to an address unit sized boundary. (DW_EH_PE_aligned)" },
491 { 0, NULL }
492 };
493
494 static const value_string eh_dwarf_format[] = {
495 { 0x0, "The Value is a literal pointer whose size is determined by the architecture. (DW_EH_PE_absptr)" },
496 { 0x1, "Unsigned value is encoded using the Little Endian Base 128 (LEB128). (DW_EH_PE_uleb128)" },
497 { 0x2, "A 2 bytes unsigned value. (DW_EH_PE_udata2)" },
498 { 0x3, "A 4 bytes unsigned value. (DW_EH_PE_udata4)" },
499 { 0x4, "An 8 bytes unsigned value. (DW_EH_PE_udata8)" },
500 { 0x9, "Signed value is encoded using the Little Endian Base 128 (LEB128). (DW_EH_PE_sleb128)" },
501 { 0xA, "A 2 bytes signed value. (DW_EH_PE_sdata2)" },
502 { 0xB, "A 4 bytes signed value. (DW_EH_PE_sdata4)" },
503 { 0xC, "An 8 bytes signed value. (DW_EH_PE_sdata8)" },
504 { 0, NULL }
505 };
506
507 static const value_string symbol_table_other_vals[] = {
508 { 0, "Default" },
509 { 1, "Internal" },
510 { 2, "Hidden" },
511 { 3, "Protected" },
512 { 0, NULL }
513 };
514
515
516 static const value_string symbol_table_info_bind_vals[] = {
517 { 0, "Local" },
518 { 1, "Global" },
519 { 2, "Weak" },
520 { 10, "Operating System Specific" },
521 { 11, "Operating System Specific" },
522 { 12, "Operating System Specific" },
523 { 13, "Processor Specific" },
524 { 14, "Processor Specific" },
525 { 15, "Processor Specific" },
526 { 0, NULL }
527 };
528
529 static const value_string symbol_table_info_type_vals[] = {
530 { 0, "No Type" },
531 { 1, "Object" },
532 { 2, "Function" },
533 { 3, "Section" },
534 { 4, "File" },
535 { 5, "Common" },
536 { 6, "Thread-Local Storage" },
537 { 10, "Operating System Specific" },
538 { 11, "Operating System Specific" },
539 { 12, "Operating System Specific" },
540 { 13, "Processor Specific" },
541 { 14, "Processor Specific" },
542 { 15, "Processor Specific" },
543 { 0, NULL }
544 };
545 static value_string_ext symbol_table_info_type_vals_ext = VALUE_STRING_EXT_INIT(symbol_table_info_type_vals);
546
547 static const range_string symbol_table_shndx_rvals[] = {
548 { 0x0000, 0x0000, "Undefined" },
549 { 0x0001, 0xfeff, "Normal Section" },
550 { 0xff00, 0xff1f, "Processor Specific" },
551 { 0xff20, 0xff3f, "Operating System Specific" },
552 { 0xff40, 0xfff0, "Reserved" },
553 { 0xfff1, 0xfff1, "Absolute Value" },
554 { 0xfff2, 0xfff2, "Common" },
555 { 0xfff3, 0xfffe, "Reserved" },
556 { 0xffff, 0xffff, "Xindex" },
557 { 0, 0, NULL }
558 };
559
560 static const range_string dynamic_tag_rvals[] = {
561 { 0, 0, "NULL" },
562 { 1, 1, "Needed" },
563 { 2, 2, "Procedure Linkage Table Size" },
564 { 3, 3, "Procedure Linkage Table and/or the Global Offset Table Address" },
565 { 4, 4, "Hash" },
566
567 { 5, 5, "String Table Address" },
568 { 6, 6, "Symbol Table Address" },
569 { 7, 7, "Relocation Table Address" },
570 { 8, 8, "Relocation Table Size" },
571 { 9, 9, "Relocation Table Entry Size" },
572 { 10, 10, "String Table Size" },
573 { 11, 11, "Symbol Table Entry Size" },
574 { 12, 12, "Initialization Function Address" },
575 { 13, 13, "Termination Function Address" },
576 { 14, 14, "Shared Object Name Offset" },
577 { 15, 15, "Search Library Path (Rpath)" },
578 { 16, 16, "Symbolic" },
579 { 17, 17, "Relocation Table with Implicit Addends" },
580 { 18, 18, "Relocation Table with Implicit Addends Size" },
581 { 19, 19, "Relocation Table with Implicit Addends Entry Size" },
582 { 20, 20, "Procedure Linkage Table Relocation Entry Type" },
583 { 21, 21, "Debug" },
584 { 22, 22, "TEXT Relocation" },
585 { 23, 23, "Procedure Linkage Table Relocation Entries Address" },
586 { 24, 24, "Bind Now" },
587 { 25, 25, "Initialization Functions Array Address" },
588 { 26, 26, "Termination Functions Array Address" },
589 { 27, 27, "Initialization Functions Array Size" },
590 { 28, 28, "Termination Functions Array Size" },
591 { 29, 29, "Run Path" },
592 { 30, 30, "Flags" },
593 { 31, 31, "Preinitialization Functions Array Address" },
594 { 32, 32, "Preinitialization Functions Array Size" },
595 { 33, 33, "Encoding" },
596
597 { 0x6000000D, 0x6ffff000, "Operating System Specific" },
598 { 0x70000000, 0x7fffffff, "Processor Specific" },
599 { 0, 0, NULL }
600 };
601
602
603 typedef struct _segment_info_t {
604 guint64 offset;
605 guint64 size;
606 const char *name;
607 } segment_info_t;
608
609 void proto_register_elf(void);
610 void proto_reg_handoff_elf(void);
611
612 static gint
dissect_leb128(tvbuff_t * tvb,gint offset,gint64 * value)613 dissect_leb128(tvbuff_t *tvb, gint offset, gint64 *value)
614 {
615 guint start_offset = offset;
616 guint shift = 0;
617 guint8 byte;
618
619 *value = 0;
620
621 do {
622 byte = tvb_get_guint8(tvb, offset);
623 offset += 1;
624
625 *value |= ((guint64)(byte & 0x7F) << shift);
626 shift += 7;
627 } while ((byte & 0x80) && (shift < 64));
628
629 if (shift < 64 && byte & 0x40)
630 *value |= - ((gint64)1 << shift);
631
632 return offset - start_offset;
633 }
634
635 /* Wireshark support "offset" as gint, but ELF needed guint64 size, so check if there is no overflow */
636 static gint
value_guard(guint64 value)637 value_guard(guint64 value)
638 {
639 DISSECTOR_ASSERT_HINT(value <= G_MAXINT, "Too big file - not supported");
640
641 return (gint) value;
642 }
643
644 static guint8
dissect_dwarf_encoding(tvbuff_t * tvb,gint offset,proto_item * item)645 dissect_dwarf_encoding(tvbuff_t *tvb, gint offset, proto_item *item)
646 {
647 guint8 value;
648 proto_tree *tree;
649
650 tree = proto_item_add_subtree(item, ett_dwarf_encoding);
651
652 value = tvb_get_guint8(tvb, offset);
653
654 if (value == 0xFF) {
655 proto_tree_add_item(tree, hf_dwarf_omit, tvb, offset, 1, ENC_NA);
656 } else {
657 proto_tree_add_item(tree, hf_dwarf_upper, tvb, offset, 1, ENC_NA);
658 proto_tree_add_item(tree, hf_dwarf_format, tvb, offset, 1, ENC_NA);
659 }
660
661 return value;
662 }
663
664 #define LENGTH_LEB128 -1
665 #define LENGTH_ULEB128 -2
666
667 static gint8
get_dwarf_extension_length(guint8 format,guint register_size)668 get_dwarf_extension_length(guint8 format, guint register_size)
669 {
670 switch (format & 0x0F) {
671 case 0x0:
672 return register_size;
673 case 0x1:
674 return LENGTH_ULEB128;
675 case 0x2:
676 return 2;
677 case 0x3:
678 return 4;
679 case 0x4:
680 return 8;
681 case 0x9:
682 return LENGTH_LEB128;
683 case 0xA:
684 return 2;
685 case 0xB:
686 return 4;
687 case 0xC:
688 return 8;
689 }
690
691 return 0;
692 }
693
694 static const guint8 *
get_section_name_offset(tvbuff_t * tvb,guint64 shoff,guint16 shnum,guint16 shentsize,guint16 shndx,guint64 shstrtab_offset,guint machine_encoding)695 get_section_name_offset(tvbuff_t *tvb, guint64 shoff, guint16 shnum, guint16 shentsize, guint16 shndx, guint64 shstrtab_offset, guint machine_encoding)
696 {
697 gint offset;
698 guint32 sh_name;
699
700 if (shndx > shnum)
701 return NULL;
702
703 offset = value_guard(shoff + (guint32)shndx * (guint32)shentsize);
704 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
705 return tvb_get_const_stringz(tvb, value_guard(shstrtab_offset + sh_name), NULL);
706 }
707
708 #define MAX_TAG_TO_TYPE 34
709 static gint
dissect_dynamic(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * entry_tree,proto_item * entry_item,gint offset,gint register_size,guint machine_encoding)710 dissect_dynamic(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *entry_tree, proto_item *entry_item,
711 gint offset, gint register_size, guint machine_encoding)
712 {
713 enum enum_tag_type {
714 DYNAMIC_TYPE_VALUE,
715 DYNAMIC_TYPE_POINTER,
716 DYNAMIC_TYPE_IGNORED,
717 DYNAMIC_TYPE_UNSPECIFIED
718 };
719
720 guint64 tag;
721 static const enum enum_tag_type tag_to_type[MAX_TAG_TO_TYPE] = {
722 DYNAMIC_TYPE_IGNORED,
723 DYNAMIC_TYPE_VALUE,
724 DYNAMIC_TYPE_VALUE,
725 DYNAMIC_TYPE_POINTER,
726 DYNAMIC_TYPE_POINTER,
727 DYNAMIC_TYPE_POINTER,
728 DYNAMIC_TYPE_POINTER,
729 DYNAMIC_TYPE_POINTER,
730 DYNAMIC_TYPE_VALUE,
731 DYNAMIC_TYPE_VALUE,
732 DYNAMIC_TYPE_VALUE,
733 DYNAMIC_TYPE_VALUE,
734 DYNAMIC_TYPE_POINTER,
735 DYNAMIC_TYPE_POINTER,
736 DYNAMIC_TYPE_VALUE,
737 DYNAMIC_TYPE_VALUE,
738 DYNAMIC_TYPE_IGNORED,
739 DYNAMIC_TYPE_POINTER,
740 DYNAMIC_TYPE_VALUE,
741 DYNAMIC_TYPE_VALUE,
742 DYNAMIC_TYPE_VALUE,
743 DYNAMIC_TYPE_POINTER,
744 DYNAMIC_TYPE_IGNORED,
745 DYNAMIC_TYPE_POINTER,
746 DYNAMIC_TYPE_IGNORED,
747 DYNAMIC_TYPE_POINTER,
748 DYNAMIC_TYPE_POINTER,
749 DYNAMIC_TYPE_VALUE,
750 DYNAMIC_TYPE_VALUE,
751 DYNAMIC_TYPE_VALUE,
752 DYNAMIC_TYPE_VALUE,
753 DYNAMIC_TYPE_UNSPECIFIED,
754 DYNAMIC_TYPE_POINTER,
755 DYNAMIC_TYPE_VALUE
756 };
757
758 if (register_size == REGISTER_32_SIZE) {
759 proto_tree_add_item(entry_tree, hf_elf_dynamic_tag, tvb, offset, 4, machine_encoding);
760 tag = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
761 offset += 4;
762
763 if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_VALUE)
764 proto_tree_add_item(entry_tree, hf_elf_dynamic_value, tvb, offset, 4, machine_encoding);
765 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_POINTER)
766 proto_tree_add_item(entry_tree, hf_elf_dynamic_pointer, tvb, offset, 4, machine_encoding);
767 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_IGNORED)
768 proto_tree_add_item(entry_tree, hf_elf_dynamic_ignored, tvb, offset, 4, machine_encoding);
769 else
770 proto_tree_add_item(entry_tree, hf_elf_dynamic_unspecified, tvb, offset, 4, machine_encoding);
771 offset += 4;
772 } else {
773 proto_item *pitem;
774
775 pitem = proto_tree_add_item(entry_tree, hf_elf64_dynamic_tag, tvb, offset, 8, machine_encoding);
776 tag = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
777 proto_item_append_text(pitem, " (%s)", rval_to_str(value_guard(tag), dynamic_tag_rvals, "Unknown"));
778 offset += 8;
779
780 if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_VALUE)
781 proto_tree_add_item(entry_tree, hf_elf64_dynamic_value, tvb, offset, 8, machine_encoding);
782 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_POINTER)
783 proto_tree_add_item(entry_tree, hf_elf64_dynamic_pointer, tvb, offset, 8, machine_encoding);
784 else if (tag < MAX_TAG_TO_TYPE && tag_to_type[tag] == DYNAMIC_TYPE_IGNORED)
785 proto_tree_add_item(entry_tree, hf_elf64_dynamic_ignored, tvb, offset, 8, machine_encoding);
786 else
787 proto_tree_add_item(entry_tree, hf_elf64_dynamic_unspecified, tvb, offset, 8, machine_encoding);
788 offset += 8;
789 }
790
791 proto_item_append_text(entry_item, ": %s", rval_to_str(value_guard(tag), dynamic_tag_rvals, "Unknown"));
792
793 return offset;
794 }
795
796 static gint
dissect_symbol_table(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * entry_tree,proto_item * entry_item,gint offset,gint register_size,guint machine_encoding,guint64 strtab_offset,guint64 shoff,guint16 shnum,guint16 shentsize,guint64 shstrtab_offset)797 dissect_symbol_table(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *entry_tree, proto_item *entry_item,
798 gint offset, gint register_size, guint machine_encoding, guint64 strtab_offset,
799 guint64 shoff, guint16 shnum, guint16 shentsize, guint64 shstrtab_offset)
800 {
801 proto_item *pitem;
802 proto_item *info_item;
803 proto_tree *info_tree;
804 guint16 shndx;
805 guint32 name_index;
806 const guint8 *section_name;
807 const guint8 *name;
808 guint8 info_bind;
809 guint8 info_type;
810
811 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_name_index, tvb, offset, 4, machine_encoding);
812 if (strtab_offset) {
813 name_index = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
814 name = tvb_get_const_stringz(tvb, value_guard(strtab_offset + name_index), NULL);
815 if (name) {
816 proto_item_append_text(pitem, ": %s", name);
817 proto_item_append_text(entry_item, ": %s", name);
818 }
819 }
820 offset += 4;
821
822 if (register_size == REGISTER_32_SIZE) {
823 proto_tree_add_item(entry_tree, hf_elf_symbol_table_value, tvb, offset, 4, machine_encoding);
824 offset += 4;
825
826 proto_tree_add_item(entry_tree, hf_elf_symbol_table_size, tvb, offset, 4, machine_encoding);
827 offset += 4;
828
829 info_item = proto_tree_add_item(entry_tree, hf_elf_symbol_table_info, tvb, offset, 1, machine_encoding);
830 info_tree = proto_item_add_subtree(info_item, ett_symbol_table_info);
831 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_bind, tvb, offset, 1, machine_encoding);
832 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_type, tvb, offset, 1, machine_encoding);
833 info_bind = tvb_get_guint8(tvb, offset) >> 4;
834 info_type = tvb_get_guint8(tvb, offset) & 0x0F;
835 offset += 1;
836
837 proto_tree_add_item(entry_tree, hf_elf_symbol_table_other, tvb, offset, 1, machine_encoding);
838 offset += 1;
839
840 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_shndx, tvb, offset, 2, machine_encoding);
841 shndx = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
842 if (shndx <= shnum) {
843 section_name = get_section_name_offset(tvb, shoff, shnum, shentsize, shndx, shstrtab_offset, machine_encoding);
844 if (section_name && section_name[0] != '\0')
845 proto_item_append_text(pitem, " (%u: %s)", shndx, section_name);
846 } else {
847 proto_item_append_text(pitem, " (%u)", shndx);
848 }
849 offset += 2;
850 } else {
851 info_item = proto_tree_add_item(entry_tree, hf_elf_symbol_table_info, tvb, offset, 1, machine_encoding);
852 info_tree = proto_item_add_subtree(info_item, ett_symbol_table_info);
853 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_bind, tvb, offset, 1, machine_encoding);
854 proto_tree_add_item(info_tree, hf_elf_symbol_table_info_type, tvb, offset, 1, machine_encoding);
855 info_bind = tvb_get_guint8(tvb, offset) >> 4;
856 info_type = tvb_get_guint8(tvb, offset) & 0x0F;
857 offset += 1;
858
859 proto_tree_add_item(entry_tree, hf_elf_symbol_table_other, tvb, offset, 1, machine_encoding);
860 offset += 1;
861
862 pitem = proto_tree_add_item(entry_tree, hf_elf_symbol_table_shndx, tvb, offset, 2, machine_encoding);
863 shndx = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
864 if (shndx <= shnum) {
865 section_name = get_section_name_offset(tvb, shoff, shnum, shentsize, shndx, shstrtab_offset, machine_encoding);
866 if (section_name && section_name[0] != '\0')
867 proto_item_append_text(pitem, " (%u: %s)", shndx, section_name);
868 } else {
869 proto_item_append_text(pitem, " (%u)", shndx);
870 }
871 offset += 2;
872
873 proto_tree_add_item(entry_tree, hf_elf64_symbol_table_value, tvb, offset, 8, machine_encoding);
874 offset += 8;
875
876 proto_tree_add_item(entry_tree, hf_elf64_symbol_table_size, tvb, offset, 8, machine_encoding);
877 offset += 8;
878 }
879
880 proto_item_append_text(info_item, " (Bind: %s, Type: %s)",
881 val_to_str_const(info_bind, symbol_table_info_bind_vals, "Unknown"),
882 val_to_str_ext_const(info_type, &symbol_table_info_type_vals_ext, "Unknown"));
883
884 proto_item_append_text(entry_item, " (Bind: %s, Type: %s)",
885 val_to_str_const(info_bind, symbol_table_info_bind_vals, "Unknown"),
886 val_to_str_ext_const(info_type, &symbol_table_info_type_vals_ext, "Unknown"));
887
888 return offset;
889 }
890
891 static gint
dissect_eh_frame_hdr(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * segment_tree,gint offset,gint segment_size _U_,gint register_size,guint machine_encoding)892 dissect_eh_frame_hdr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *segment_tree,
893 gint offset, gint segment_size _U_, gint register_size, guint machine_encoding)
894 {
895 proto_item *item;
896 proto_tree *table_tree;
897 guint8 format;
898 gint efp_length;
899 gint fde_count_length;
900 gint table_entry_length;
901 guint64 fde_count;
902 guint i_entry;
903
904 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_version, tvb, offset, 1, machine_encoding);
905 offset += 1;
906
907 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_exception_frame_pointer_encoding, tvb, offset, 1, machine_encoding);
908 format = dissect_dwarf_encoding(tvb, offset, item);
909 efp_length = get_dwarf_extension_length(format, register_size);
910 offset += 1;
911
912 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_fde_count_encoding, tvb, offset, 1, machine_encoding);
913 format = dissect_dwarf_encoding(tvb, offset, item);
914 fde_count_length = get_dwarf_extension_length(format, register_size);
915 offset += 1;
916
917 item = proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_binary_search_table_encoding, tvb, offset, 1, machine_encoding);
918 format = dissect_dwarf_encoding(tvb, offset, item);
919 table_entry_length = get_dwarf_extension_length(format, register_size);
920 offset += 1;
921
922 if (efp_length == LENGTH_ULEB128) {
923 guint64 value;
924
925 efp_length = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &value, ENC_VARINT_PROTOBUF);
926 } else if (efp_length == LENGTH_LEB128) {
927 gint64 value;
928
929 efp_length = dissect_leb128(tvb, offset, &value);
930 }
931
932 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_eh_frame_ptr, tvb, offset, efp_length, machine_encoding);
933 offset += efp_length;
934
935
936 if (fde_count_length == LENGTH_ULEB128) {
937 fde_count_length = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &fde_count, ENC_VARINT_PROTOBUF);
938 } else if (fde_count_length == LENGTH_LEB128) {
939 gint64 value;
940
941 fde_count_length = dissect_leb128(tvb, offset, &value);
942 fde_count = (guint64) value;
943 } else {
944 if (fde_count_length == 0) fde_count_length = register_size;
945
946 switch(fde_count_length) {
947 case 2:
948 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
949 break;
950 case 4:
951 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
952 break;
953 case 8:
954 fde_count = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
955 break;
956 case 0:
957 default:
958 fde_count = 0;
959 break;
960 }
961 }
962
963 proto_tree_add_item(segment_tree, hf_elf_eh_frame_hdr_fde_count, tvb, offset,
964 fde_count_length, machine_encoding);
965 offset += fde_count_length;
966
967 if (table_entry_length == LENGTH_ULEB128) {
968 guint64 value;
969
970 table_entry_length = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &value, ENC_VARINT_PROTOBUF);
971 } else if (table_entry_length == LENGTH_LEB128) {
972 gint64 value;
973
974 table_entry_length = dissect_leb128(tvb, offset, &value);
975 }
976
977 i_entry = 0;
978
979 table_tree = proto_tree_add_subtree(segment_tree, tvb, offset, value_guard(fde_count * table_entry_length * 2),
980 ett_binary_table, NULL, "Binary Search Table");
981
982 while (++i_entry <= fde_count) {
983 proto_tree *entry_tree;
984
985 entry_tree = proto_tree_add_subtree_format(table_tree, tvb, offset, table_entry_length * 2, ett_binary_table_entry,
986 NULL, "Binary Table Entry #%u", i_entry);
987
988 proto_tree_add_item(entry_tree, hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location, tvb, offset, table_entry_length, machine_encoding);
989 offset += table_entry_length;
990
991 proto_tree_add_item(entry_tree, hf_elf_eh_frame_hdr_binary_search_table_entry_address, tvb, offset, table_entry_length, machine_encoding);
992 offset += table_entry_length;
993 }
994
995 return offset;
996 }
997
998
999 static gint
dissect_eh_frame(tvbuff_t * tvb,packet_info * pinfo,proto_tree * segment_tree,gint offset,gint segment_size,gint register_size _U_,guint machine_encoding)1000 dissect_eh_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *segment_tree,
1001 gint offset, gint segment_size, gint register_size _U_, guint machine_encoding)
1002 {
1003 proto_tree *cfi_tree = NULL;
1004 proto_item *cfi_tree_item = NULL;
1005 proto_tree *entry_tree;
1006 proto_item *pi = NULL;
1007 guint64 length;
1008 guint lengths_size;
1009 gboolean is_cie;
1010 guint entry_size, entry_end = 0;
1011 guint cfi_size = 0;
1012 guint64 unsigned_value;
1013 gint64 signed_value;
1014 gint size;
1015 const gchar *augmentation_string = "";
1016 gboolean is_extended_length;
1017 gint start_offset = offset;
1018 guint cfi_number = 0;
1019 gint entry_number = 0;
1020
1021 while (offset - start_offset < segment_size) {
1022 length = (machine_encoding == ENC_BIG_ENDIAN) ?
1023 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1024 is_extended_length = length == 0xFFFFFFFF;
1025 if (is_extended_length) {
1026 length = (machine_encoding == ENC_BIG_ENDIAN) ?
1027 tvb_get_ntoh64(tvb, offset + 4) :
1028 tvb_get_letoh64(tvb, offset + 4);
1029 }
1030 /* CIE ID/pointer is located after Length (4 bytes), or Length (4 bytes)
1031 * + Extended Length (8 bytes). Entry is CIE when field is 0. */
1032 lengths_size = is_extended_length ? 12 : 4;
1033 is_cie = length == 0 || tvb_get_ntohl(tvb, offset + lengths_size) == 0;
1034 entry_size = value_guard(length + lengths_size);
1035 entry_end = offset + entry_size;
1036
1037 if (length == 0) {
1038 /* CIE Terminator, add it directly under the Segment tree as we stop
1039 * processing after this item. */
1040 entry_tree = proto_tree_add_subtree(segment_tree,
1041 tvb, offset, entry_size,
1042 ett_elf_cie_terminator, NULL, "CIE Terminator");
1043 } else if (cfi_number == 0 || is_cie) {
1044 /* New CIE, so create a new CFI subtree and reset FDE Entry. */
1045 ++cfi_number;
1046 cfi_tree = proto_tree_add_subtree_format(segment_tree,
1047 tvb, offset, entry_size, ett_elf_cfi_record, &cfi_tree_item,
1048 "Call Frame Information Entry %i", cfi_number);
1049 entry_tree = proto_tree_add_subtree(cfi_tree, tvb, offset,
1050 entry_size, ett_elf_cie_entry, NULL, "Common Information Entry");
1051 cfi_size = entry_size;
1052 entry_number = 0;
1053 } else {
1054 /* FDE, add it in the CFI subtree. */
1055 ++entry_number;
1056 cfi_size += entry_size;
1057 proto_item_set_len(cfi_tree_item, cfi_size);
1058 entry_tree = proto_tree_add_subtree_format(cfi_tree,
1059 tvb, offset, entry_size, ett_elf_fde_entry, NULL,
1060 "Frame Description Entry %i", entry_number);
1061 }
1062
1063 pi = proto_tree_add_item(entry_tree, is_cie ?
1064 hf_elf_eh_frame_length :
1065 hf_elf_eh_frame_fde_length,
1066 tvb, offset, 4, machine_encoding);
1067 offset += 4;
1068
1069 if (is_extended_length) {
1070 pi = proto_tree_add_item(entry_tree, is_cie ?
1071 hf_elf_eh_frame_extended_length :
1072 hf_elf_eh_frame_fde_extended_length,
1073 tvb, offset, 8, machine_encoding);
1074 offset += 8;
1075 }
1076
1077 /* CIE terminator */
1078 if (length == 0)
1079 break;
1080
1081 /* CIE ID (8) + Augment. Str (1) + CAF+DAF+Aug.Len (3) = 12 (min. length) */
1082 if (length < 12 || entry_end - start_offset > (guint64)segment_size) {
1083 expert_add_info(pinfo, pi, &ei_invalid_cie_length);
1084 return offset;
1085 }
1086
1087 proto_tree_add_item(entry_tree, is_cie ?
1088 hf_elf_eh_frame_cie_id :
1089 hf_elf_eh_frame_fde_cie_pointer,
1090 tvb, offset, 4, machine_encoding);
1091 offset += 4;
1092 if (is_cie) {
1093 proto_tree_add_item(entry_tree, hf_elf_eh_frame_version,
1094 tvb, offset, 1, machine_encoding);
1095 offset += 1;
1096
1097 augmentation_string = (const gchar*)tvb_get_const_stringz(tvb, offset, &size);
1098 proto_tree_add_item(entry_tree, hf_elf_eh_frame_augmentation_string,
1099 tvb, offset, size, machine_encoding);
1100 offset += size;
1101
1102 proto_tree_add_item_ret_length(entry_tree, hf_elf_eh_frame_code_alignment_factor, tvb, offset, -1, ENC_LITTLE_ENDIAN|ENC_VARINT_PROTOBUF, &size);
1103 offset += size;
1104
1105 size = dissect_leb128(tvb, offset, &signed_value);
1106 proto_tree_add_int64(entry_tree, hf_elf_eh_frame_data_alignment_factor,
1107 tvb, offset, size, signed_value);
1108 offset += size;
1109
1110 /* according to DWARF v4 this is uLEB128 */
1111 proto_tree_add_item_ret_length(entry_tree, hf_elf_eh_frame_return_address_register, tvb, offset, -1, ENC_LITTLE_ENDIAN|ENC_VARINT_PROTOBUF, &size);
1112 offset += size;
1113 } else {
1114 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_pc_begin, tvb,
1115 offset, 4, machine_encoding);
1116 offset += 4;
1117
1118 proto_tree_add_item(entry_tree, hf_elf_eh_frame_fde_pc_range, tvb,
1119 offset, 4, machine_encoding);
1120 offset += 4;
1121 }
1122
1123 /* "A 'z' may be present as the first character of the string. If
1124 * present, the Augmentation Data field shall be present." (LSB 4.1) */
1125 if (augmentation_string[0] == 'z') {
1126 proto_tree_add_item_ret_varint(entry_tree, is_cie ? hf_elf_eh_frame_augmentation_length : hf_elf_eh_frame_fde_augmentation_length,
1127 tvb, offset, -1, ENC_LITTLE_ENDIAN|ENC_VARINT_PROTOBUF, &unsigned_value, &size);
1128 offset += size;
1129
1130 proto_tree_add_item(entry_tree, is_cie ?
1131 hf_elf_eh_frame_augmentation_data :
1132 hf_elf_eh_frame_fde_augmentation_data,
1133 tvb, offset, value_guard(unsigned_value),
1134 machine_encoding);
1135 offset += value_guard(unsigned_value);
1136 }
1137
1138 proto_tree_add_item(entry_tree, is_cie ?
1139 hf_elf_eh_frame_initial_instructions :
1140 hf_elf_eh_frame_fde_call_frame_instructions,
1141 tvb, offset, value_guard(entry_end - offset),
1142 machine_encoding);
1143 offset = value_guard(entry_end);
1144 }
1145
1146 if (entry_end - start_offset != (guint64)segment_size)
1147 expert_add_info(pinfo, pi, &ei_cfi_extraneous_data);
1148
1149 return offset;
1150 }
1151
1152 static int
dissect_elf(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1153 dissect_elf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1154 {
1155 static const guint8 magic[] = { 0x7F, 'E', 'L', 'F'};
1156 gint offset = 0;
1157 proto_tree *main_tree;
1158 proto_item *main_item, *ti;
1159 proto_tree *header_tree;
1160 proto_item *header_item;
1161 proto_tree *program_header_tree;
1162 proto_tree *section_header_tree;
1163 proto_tree *ph_entry_tree;
1164 proto_item *sh_entry_item;
1165 proto_tree *sh_entry_tree;
1166 proto_item *segment_item;
1167 proto_tree *segment_tree;
1168 proto_item *generated_item;
1169 proto_tree *generated_tree;
1170 proto_tree *overlapping_tree;
1171 proto_tree *blackhole_tree;
1172 proto_item *entry_item;
1173 proto_tree *entry_tree;
1174 guint machine_encoding = ENC_NA;
1175 gint register_size = 4;
1176 guint16 phentsize;
1177 guint16 phnum;
1178 guint16 shentsize;
1179 guint16 shnum;
1180 guint64 phoff;
1181 guint64 shoff;
1182 guint16 i_16;
1183 guint32 p_type;
1184 guint32 sh_type;
1185 guint16 shstrndx;
1186 guint64 shstrtab_offset;
1187 guint32 sh_name;
1188 const char *section_name;
1189 guint64 length;
1190 guint64 segment_offset;
1191 guint64 segment_size;
1192 guint64 file_size;
1193 guint64 p_offset;
1194 gint ehsize;
1195 guint area_counter = 0;
1196 segment_info_t *segment_info;
1197 guint i;
1198 guint i_next;
1199 gint next_offset;
1200 gint len;
1201 guint64 sh_entsize;
1202 guint64 strtab_offset = 0;
1203 guint64 dynstr_offset = 0;
1204
1205 if (tvb_captured_length(tvb) < 52)
1206 return 0;
1207
1208 if (tvb_memeql(tvb, 0, magic, sizeof(magic)) != 0)
1209 return 0;
1210
1211 main_item = proto_tree_add_item(tree, proto_elf, tvb, offset, -1, ENC_NA);
1212 main_tree = proto_item_add_subtree(main_item, ett_elf);
1213
1214 header_tree = proto_tree_add_subtree(main_tree, tvb, offset, 1, ett_elf_header, &header_item, "Header");
1215
1216 /* e_ident */
1217 proto_tree_add_item(header_tree, hf_elf_magic_bytes, tvb, offset, sizeof(magic), ENC_NA);
1218 offset += (int)sizeof(magic);
1219
1220 proto_tree_add_item(header_tree, hf_elf_file_class, tvb, offset, 1, ENC_NA);
1221 register_size *= tvb_get_guint8(tvb, offset);
1222 offset += 1;
1223
1224 proto_tree_add_item(header_tree, hf_elf_data_encoding, tvb, offset, 1, ENC_NA);
1225 if (tvb_get_guint8(tvb, offset) == 1)
1226 machine_encoding = ENC_LITTLE_ENDIAN;
1227 else
1228 machine_encoding = ENC_BIG_ENDIAN;
1229 offset += 1;
1230
1231 proto_tree_add_item(header_tree, hf_elf_file_version, tvb, offset, 1, ENC_NA);
1232 offset += 1;
1233
1234 /* From Draft */
1235 proto_tree_add_item(header_tree, hf_elf_os_abi, tvb, offset, 1, ENC_NA);
1236 offset += 1;
1237
1238 proto_tree_add_item(header_tree, hf_elf_abi_version, tvb, offset, 1, ENC_NA);
1239 offset += 1;
1240
1241 proto_tree_add_item(header_tree, hf_elf_file_padding, tvb, offset, 7, ENC_NA);
1242 offset += 7;
1243
1244 /* other */
1245
1246 proto_tree_add_item(header_tree, hf_elf_type, tvb, offset, 2, machine_encoding);
1247 offset += 2;
1248
1249 proto_tree_add_item(header_tree, hf_elf_machine, tvb, offset, 2, machine_encoding);
1250 offset += 2;
1251
1252 proto_tree_add_item(header_tree, hf_elf_version, tvb, offset, 4, machine_encoding);
1253 offset += 4;
1254
1255 proto_tree_add_item(header_tree,
1256 (register_size == REGISTER_32_SIZE) ? hf_elf_entry : hf_elf64_entry,
1257 tvb, offset, register_size, machine_encoding);
1258 offset += register_size;
1259
1260 if (register_size == REGISTER_32_SIZE) {
1261 proto_tree_add_item(header_tree, hf_elf_phoff, tvb, offset,
1262 register_size, machine_encoding);
1263 phoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1264 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1265 } else {
1266 proto_tree_add_item(header_tree, hf_elf64_phoff, tvb, offset,
1267 register_size, machine_encoding);
1268 phoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1269 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1270 }
1271 offset += register_size;
1272
1273
1274 if (register_size == REGISTER_32_SIZE) {
1275 proto_tree_add_item(header_tree, hf_elf_shoff, tvb, offset,
1276 register_size, machine_encoding);
1277 shoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1278 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1279 } else {
1280 proto_tree_add_item(header_tree, hf_elf64_shoff, tvb, offset,
1281 register_size, machine_encoding);
1282 shoff = (machine_encoding == ENC_BIG_ENDIAN) ?
1283 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1284 }
1285 offset += register_size;
1286
1287 proto_tree_add_item(header_tree, hf_elf_flags, tvb, offset, 4, machine_encoding);
1288 offset += 4;
1289
1290 proto_tree_add_item(header_tree, hf_elf_ehsize, tvb, offset, 2, machine_encoding);
1291 ehsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1292 proto_item_set_len(header_item, ehsize);
1293 offset += 2;
1294
1295 proto_tree_add_item(header_tree, hf_elf_phentsize, tvb, offset, 2, machine_encoding);
1296 phentsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1297 offset += 2;
1298
1299 proto_tree_add_item(header_tree, hf_elf_phnum, tvb, offset, 2, machine_encoding);
1300 phnum = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1301 offset += 2;
1302
1303 proto_tree_add_item(header_tree, hf_elf_shentsize, tvb, offset, 2, machine_encoding);
1304 shentsize = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1305 offset += 2;
1306
1307 proto_tree_add_item(header_tree, hf_elf_shnum, tvb, offset, 2, machine_encoding);
1308 shnum = (machine_encoding == ENC_BIG_ENDIAN) ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1309 offset += 2;
1310
1311 proto_tree_add_item(header_tree, hf_elf_shstrndx, tvb, offset, 2, machine_encoding);
1312 shstrndx = (machine_encoding == ENC_BIG_ENDIAN) ?
1313 tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset);
1314 /*offset += 2;*/
1315
1316 program_header_tree = proto_tree_add_subtree_format(main_tree, tvb, value_guard(phoff),
1317 phnum * phentsize, ett_elf_program_header, NULL, "Program Header Table [%d entries]", phnum);
1318
1319 section_header_tree = proto_tree_add_subtree_format(main_tree, tvb, value_guard(shoff),
1320 shnum * shentsize, ett_elf_section_header, NULL, "Section Header Table [%d entries]", shnum);
1321
1322 file_size = ehsize + (guint32)phnum * (guint32)phentsize + (guint32)shnum * (guint32)shentsize;
1323
1324 /* Collect infos for blackholes */
1325 segment_info = (segment_info_t *) wmem_alloc(pinfo->pool, sizeof(segment_info_t) * (shnum + phnum + 3));
1326
1327 segment_info[area_counter].offset = 0;
1328 segment_info[area_counter].size = ehsize;
1329 segment_info[area_counter].name = "Header";
1330 area_counter += 1;
1331
1332 if (phoff) {
1333 segment_info[area_counter].offset = phoff;
1334 segment_info[area_counter].size = (guint32)phnum * (guint32)phentsize;
1335 segment_info[area_counter].name = "ProgramHeader";
1336 area_counter += 1;
1337 }
1338
1339 if (shoff) {
1340 segment_info[area_counter].offset = shoff;
1341 segment_info[area_counter].size = (guint32)shnum * (guint32)shentsize;
1342 segment_info[area_counter].name = "SectionHeader";
1343 area_counter += 1;
1344 }
1345
1346 offset = value_guard(phoff);
1347
1348 i_16 = phnum;
1349 while (i_16-- > 0) {
1350 p_type = (machine_encoding == ENC_BIG_ENDIAN) ?
1351 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1352 if (p_type >= 0x60000000 && p_type <= 0x6FFFFFFF) {
1353 ph_entry_tree = proto_tree_add_subtree_format(program_header_tree,
1354 tvb, offset, phentsize, ett_elf_program_header_entry, NULL,
1355 "Entry #%d: Operating System Specific (0x%08x)", phnum - i_16 - 1, p_type);
1356 proto_tree_add_item(ph_entry_tree, hf_elf_p_type_operating_system_specific, tvb, offset, 4, machine_encoding);
1357 } else if (p_type >= 0x70000000 && p_type <= 0x7FFFFFFF) {
1358 ph_entry_tree = proto_tree_add_subtree_format(program_header_tree,
1359 tvb, offset, phentsize, ett_elf_program_header_entry, NULL,
1360 "Entry #%d: Processor Specific (0x%08x)", phnum - i_16 - 1, p_type);
1361 proto_tree_add_item(ph_entry_tree, hf_elf_p_type_processor_specific, tvb, offset, 4, machine_encoding);
1362 } else {
1363 ph_entry_tree = proto_tree_add_subtree_format(program_header_tree,
1364 tvb, offset, phentsize, ett_elf_program_header_entry, NULL,
1365 "Entry #%d: %s", phnum - i_16 - 1,
1366 val_to_str_const(p_type, p_type_vals, "Unknown"));
1367 proto_tree_add_item(ph_entry_tree, hf_elf_p_type, tvb, offset, 4, machine_encoding);
1368 }
1369 offset += 4;
1370
1371 if (register_size == REGISTER_64_SIZE) {
1372 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_processor_specific, tvb, offset, 4, machine_encoding);
1373 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1374 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_reserved, tvb, offset, 4, machine_encoding);
1375 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_read, tvb, offset, 4, machine_encoding);
1376 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_write, tvb, offset, 4, machine_encoding);
1377 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_execute, tvb, offset, 4, machine_encoding);
1378 offset += 4;
1379 }
1380
1381 proto_tree_add_item(ph_entry_tree,
1382 (register_size == REGISTER_32_SIZE) ? hf_elf_p_offset : hf_elf64_p_offset,
1383 tvb, offset, register_size, machine_encoding);
1384 if (register_size == REGISTER_32_SIZE) {
1385 p_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1386 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1387 } else {
1388 p_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1389 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1390 }
1391
1392 offset += register_size;
1393
1394 proto_tree_add_item(ph_entry_tree,
1395 (register_size == REGISTER_32_SIZE) ? hf_elf_p_vaddr : hf_elf64_p_vaddr,
1396 tvb, offset, register_size, machine_encoding);
1397 offset += register_size;
1398
1399 proto_tree_add_item(ph_entry_tree,
1400 (register_size == REGISTER_32_SIZE) ? hf_elf_p_paddr : hf_elf64_p_paddr,
1401 tvb, offset, register_size, machine_encoding);
1402 offset += register_size;
1403
1404 proto_tree_add_item(ph_entry_tree,
1405 (register_size == REGISTER_32_SIZE) ? hf_elf_p_filesz : hf_elf64_p_filesz,
1406 tvb, offset, register_size, machine_encoding);
1407 if (register_size == REGISTER_32_SIZE) {
1408 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1409 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1410 } else {
1411 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1412 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1413 }
1414 offset += register_size;
1415
1416 proto_tree_add_item(ph_entry_tree,
1417 (register_size == REGISTER_32_SIZE) ? hf_elf_p_memsz : hf_elf64_p_memsz,
1418 tvb, offset, register_size, machine_encoding);
1419 offset += register_size;
1420
1421 if (register_size == REGISTER_32_SIZE) {
1422 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_processor_specific, tvb, offset, 4, machine_encoding);
1423 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1424 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_reserved, tvb, offset, 4, machine_encoding);
1425 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_read, tvb, offset, 4, machine_encoding);
1426 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_write, tvb, offset, 4, machine_encoding);
1427 proto_tree_add_item(ph_entry_tree, hf_elf_p_flags_execute, tvb, offset, 4, machine_encoding);
1428 offset += 4;
1429 }
1430
1431 proto_tree_add_item(ph_entry_tree,
1432 (register_size == REGISTER_32_SIZE) ? hf_elf_p_align : hf_elf64_p_align,
1433 tvb, offset, register_size, machine_encoding);
1434 offset += register_size;
1435
1436 if (segment_size) {
1437 gchar *name;
1438
1439 name = wmem_strdup_printf(pinfo->pool, "ProgramHeaderEntry #%u", phnum - i_16 - 1);
1440
1441 proto_tree_add_bytes_format(ph_entry_tree, hf_elf_segment, tvb, value_guard(p_offset), value_guard(segment_size), NULL, "Segment");
1442
1443 file_size += segment_size;
1444
1445 segment_info[area_counter].offset = p_offset;
1446 segment_info[area_counter].size = segment_size;
1447 segment_info[area_counter].name = name;
1448
1449 area_counter += 1;
1450 }
1451 }
1452
1453 /* Find and save some information for later */
1454 offset = value_guard(shoff);
1455
1456 i_16 = shnum;
1457 while (i_16-- > 0) {
1458 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ?
1459 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1460
1461 offset += 4;
1462
1463 offset += 4;
1464
1465 length = shoff + (guint32)shstrndx * (guint32)shentsize + 2 * 4 + 2 * register_size;
1466 if (register_size == REGISTER_32_SIZE) {
1467 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1468 tvb_get_ntohl(tvb, value_guard(length)) : tvb_get_letohl(tvb, value_guard(length));
1469 } else {
1470 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1471 tvb_get_ntoh64(tvb, value_guard(length)) : tvb_get_letoh64(tvb, value_guard(length));
1472 }
1473
1474 section_name = (const char *)tvb_get_const_stringz(tvb, value_guard(shstrtab_offset + sh_name), NULL);
1475
1476 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_BIG_ENDIAN) {
1477 offset += 4;
1478 }
1479
1480 offset += 4;
1481
1482 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_LITTLE_ENDIAN) {
1483 offset += 4;
1484 }
1485
1486 offset += register_size;
1487
1488 if (register_size == REGISTER_32_SIZE) {
1489 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1490 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1491 } else {
1492 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1493 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1494 }
1495
1496 if (g_strcmp0(section_name, ".strtab") == 0) {
1497 strtab_offset = segment_offset;
1498 } else if (g_strcmp0(section_name, ".dynstr") == 0) {
1499 dynstr_offset = segment_offset;
1500 }
1501 offset += register_size;
1502 offset += register_size;
1503 offset += 4;
1504 offset += 4;
1505 offset += register_size;
1506 offset += register_size;
1507 }
1508
1509 /* Sections */
1510 offset = value_guard(shoff);
1511
1512 i_16 = shnum;
1513 while (i_16-- > 0) {
1514 sh_entry_tree = proto_tree_add_subtree_format(section_header_tree, tvb, offset, shentsize,
1515 ett_elf_section_header_entry, &sh_entry_item,
1516 "Entry #%d: ", shnum - i_16 - 1);
1517
1518 proto_tree_add_item(sh_entry_tree, hf_elf_sh_name, tvb, offset, 4, machine_encoding);
1519 sh_name = (machine_encoding == ENC_BIG_ENDIAN) ?
1520 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1521 offset += 4;
1522
1523 sh_type = (machine_encoding == ENC_BIG_ENDIAN) ?
1524 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1525 if (sh_type >= 0x60000000 && sh_type <= 0x6FFFFFFF) {
1526 proto_item_append_text(sh_entry_item, "Operating System Specific (0x%08x)", sh_type);
1527 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_operating_system_specific, tvb, offset, 4, machine_encoding);
1528 } else if (sh_type >= 0x70000000 && sh_type <= 0x7FFFFFFF) {
1529 proto_item_append_text(sh_entry_item, "Processor Specific (0x%08x)", sh_type);
1530 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_processor_specific, tvb, offset, 4, machine_encoding);
1531 } else if (sh_type >= 0x80000000) {
1532 proto_item_append_text(sh_entry_item, "User Specific (0x%08x)", sh_type);
1533 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type_user_specific, tvb, offset, 4, machine_encoding);
1534 }else {
1535 proto_item_append_text(sh_entry_item, "%s", val_to_str_ext_const(sh_type, &sh_type_vals_ext, "Unknown"));
1536 proto_tree_add_item(sh_entry_tree, hf_elf_sh_type, tvb, offset, 4, machine_encoding);
1537 }
1538 offset += 4;
1539
1540 length = shoff + (guint32)shstrndx * (guint32)shentsize + 2 * 4 + 2 * register_size;
1541 if (register_size == REGISTER_32_SIZE) {
1542 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1543 tvb_get_ntohl(tvb, value_guard(length)) : tvb_get_letohl(tvb, value_guard(length));
1544 } else {
1545 shstrtab_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1546 tvb_get_ntoh64(tvb, value_guard(length)) : tvb_get_letoh64(tvb, value_guard(length));
1547 }
1548
1549 section_name = (const char*)tvb_get_const_stringz(tvb, value_guard(shstrtab_offset + sh_name), NULL);
1550 if (section_name)
1551 proto_item_append_text(sh_entry_item, ": %s", section_name);
1552
1553 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_BIG_ENDIAN) {
1554 offset += 4;
1555 }
1556
1557 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_processor_specific, tvb, offset, 4, machine_encoding);
1558 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_operating_system_specific, tvb, offset, 4, machine_encoding);
1559 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_reserved, tvb, offset, 4, machine_encoding);
1560 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_tls, tvb, offset, 4, machine_encoding);
1561 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_group, tvb, offset, 4, machine_encoding);
1562 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_os_nonconforming, tvb, offset, 4, machine_encoding);
1563 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_link_order, tvb, offset, 4, machine_encoding);
1564 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_info_link, tvb, offset, 4, machine_encoding);
1565 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_strings, tvb, offset, 4, machine_encoding);
1566 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_merge, tvb, offset, 4, machine_encoding);
1567 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_reserved_8, tvb, offset, 4, machine_encoding);
1568 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_exec_instr, tvb, offset, 4, machine_encoding);
1569 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_alloc, tvb, offset, 4, machine_encoding);
1570 proto_tree_add_item(sh_entry_tree, hf_elf_sh_flags_write, tvb, offset, 4, machine_encoding);
1571 offset += 4;
1572
1573 if (register_size == REGISTER_64_SIZE && machine_encoding == ENC_LITTLE_ENDIAN) {
1574 offset += 4;
1575 }
1576
1577 proto_tree_add_item(sh_entry_tree,
1578 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_addr : hf_elf64_sh_addr,
1579 tvb, offset, register_size, machine_encoding);
1580 offset += register_size;
1581
1582 proto_tree_add_item(sh_entry_tree,
1583 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_offset : hf_elf64_sh_offset,
1584 tvb, offset, register_size, machine_encoding);
1585 if (register_size == REGISTER_32_SIZE) {
1586 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1587 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1588 } else {
1589 segment_offset = (machine_encoding == ENC_BIG_ENDIAN) ?
1590 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1591 }
1592 offset += register_size;
1593
1594 proto_tree_add_item(sh_entry_tree,
1595 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_size : hf_elf64_sh_size,
1596 tvb, offset, register_size, machine_encoding);
1597 if (register_size == REGISTER_32_SIZE) {
1598 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1599 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1600 } else {
1601 segment_size = (machine_encoding == ENC_BIG_ENDIAN) ?
1602 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1603 }
1604 offset += register_size;
1605
1606 proto_tree_add_item(sh_entry_tree, hf_elf_sh_link, tvb, offset, 4, machine_encoding);
1607 offset += 4;
1608
1609 proto_tree_add_item(sh_entry_tree, hf_elf_sh_info, tvb, offset, 4, machine_encoding);
1610 offset += 4;
1611
1612 proto_tree_add_item(sh_entry_tree,
1613 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_addralign : hf_elf64_sh_addralign,
1614 tvb, offset, register_size, machine_encoding);
1615 offset += register_size;
1616
1617 proto_tree_add_item(sh_entry_tree,
1618 (register_size == REGISTER_32_SIZE) ? hf_elf_sh_entsize : hf_elf64_sh_entsize,
1619 tvb, offset, register_size, machine_encoding);
1620 if (register_size == REGISTER_32_SIZE) {
1621 sh_entsize = (machine_encoding == ENC_BIG_ENDIAN) ?
1622 tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset);
1623 } else {
1624 sh_entsize = (machine_encoding == ENC_BIG_ENDIAN) ?
1625 tvb_get_ntoh64(tvb, offset) : tvb_get_letoh64(tvb, offset);
1626 }
1627 offset += register_size;
1628
1629 if (segment_size > 0 && sh_type != 8) { /* ! SHT_NOBITS */
1630 file_size += segment_size;
1631
1632 segment_info[area_counter].offset = segment_offset;
1633 segment_info[area_counter].size = segment_size;
1634 segment_info[area_counter].name = section_name;
1635 area_counter += 1;
1636
1637 segment_tree = proto_tree_add_subtree(sh_entry_tree, tvb, value_guard(segment_offset),
1638 value_guard(segment_size), ett_elf_segment, &segment_item, "Segment");
1639
1640 if (g_strcmp0(section_name, ".eh_frame") == 0) {
1641 next_offset = dissect_eh_frame(tvb, pinfo, segment_tree,
1642 value_guard(segment_offset), value_guard(segment_size), register_size,
1643 machine_encoding);
1644 if (next_offset != (gint) (segment_offset + segment_size))
1645 expert_add_info(pinfo, segment_item, &ei_invalid_segment_size);
1646 } else if (g_strcmp0(section_name, ".eh_frame_hdr") == 0) {
1647 next_offset = dissect_eh_frame_hdr(tvb, pinfo, segment_tree,
1648 value_guard(segment_offset), value_guard(segment_size), register_size,
1649 machine_encoding);
1650 if (next_offset != (gint) (segment_offset + segment_size))
1651 expert_add_info(pinfo, segment_item, &ei_invalid_segment_size);
1652 } else if (sh_type == 0x06) { /* SHT_DYNAMIC */
1653 if (sh_entsize > 0) {
1654 next_offset = value_guard(segment_offset);
1655 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1656 entry_tree = proto_tree_add_subtree_format(segment_tree, tvb, next_offset,
1657 value_guard(sh_entsize), ett_symbol_table_entry, &entry_item, "Entry #%d", i);
1658
1659 next_offset = dissect_dynamic(tvb, pinfo, entry_tree, entry_item,
1660 next_offset, register_size, machine_encoding);
1661 if (next_offset != (gint) (segment_offset + i * sh_entsize))
1662 expert_add_info(pinfo, segment_item, &ei_invalid_entry_size);
1663 }
1664 }
1665 } else if (sh_type == 0x02 || sh_type == 0x0b) { /* SHT_SYMTAB || SHT_DYNSYM */
1666 if (sh_entsize > 0) {
1667 next_offset = value_guard(segment_offset);
1668 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1669 entry_tree = proto_tree_add_subtree_format(segment_tree, tvb, next_offset,
1670 value_guard(sh_entsize), ett_symbol_table_entry, &entry_item, "Entry #%d", i);
1671
1672 next_offset = dissect_symbol_table(tvb, pinfo, entry_tree, entry_item,
1673 next_offset, register_size, machine_encoding, (sh_type == 0x02) ? strtab_offset : dynstr_offset,
1674 shoff, shnum, shentsize, shstrtab_offset);
1675 if (next_offset != (gint) (segment_offset + i * sh_entsize))
1676 expert_add_info(pinfo, segment_item, &ei_invalid_entry_size);
1677 }
1678 }
1679 } else if (sh_type == 0x03) { /* SHT_STRTAB */
1680 next_offset = value_guard(segment_offset);
1681 i = 1;
1682 while (next_offset < (gint) (segment_offset + segment_size)) {
1683 tvb_get_const_stringz(tvb, next_offset, &len);
1684 entry_item = proto_tree_add_item(segment_tree, hf_elf_string, tvb, next_offset, len, ENC_ASCII | ENC_NA);
1685 proto_item_append_text(entry_item, " (Number: %u, Index: %u, Length: %u)", (guint) i, (guint) (next_offset - segment_offset), len - 1);
1686 next_offset += len;
1687 i += 1;
1688 }
1689 } else {
1690 /* .debug_str sections have sh_entsize 1, displaying every byte
1691 * individually can explode the tree size, so require > 1. */
1692 if (sh_entsize > 1) {
1693 next_offset = value_guard(segment_offset);
1694 for (i = 1; i < (segment_size / sh_entsize) + 1; i += 1) {
1695 proto_tree_add_bytes_format(segment_tree, hf_elf_entry_bytes, tvb, next_offset,
1696 value_guard(sh_entsize), NULL, "Entry #%d ", i);
1697 next_offset += value_guard(sh_entsize);
1698 }
1699 }
1700 }
1701 }
1702 }
1703
1704 /* Try to detect blackholes and overlapping segments */
1705 generated_tree = proto_tree_add_subtree(main_tree, tvb, 0, 0, ett_elf_info, &generated_item, "Infos");
1706 proto_item_set_generated(generated_item);
1707
1708 blackhole_tree = proto_tree_add_subtree(generated_tree, tvb, 0, 0, ett_elf_black_holes, NULL, "Backholes");
1709 overlapping_tree = proto_tree_add_subtree(generated_tree, tvb, 0, 0, ett_elf_overlapping, NULL, "Overlapping");
1710
1711 /* sorting... */
1712 for (i = 0; i < area_counter; i += 1) {
1713 segment_info_t tmp_segment;
1714 segment_info_t *min_offset_segment;
1715
1716 min_offset_segment = &segment_info[i];
1717
1718 for (i_next = i + 1; i_next < area_counter; i_next += 1) {
1719 if (min_offset_segment->offset <= segment_info[i_next].offset) continue;
1720
1721 tmp_segment = *min_offset_segment;
1722 *min_offset_segment = segment_info[i_next];
1723 segment_info[i_next] = tmp_segment;
1724 }
1725 }
1726
1727 for (i = 1; i < area_counter; i += 1) {
1728 if (segment_info[i - 1].offset + segment_info[i - 1].size < segment_info[i].offset) {
1729 /* blackhole */
1730 len = (guint) (segment_info[i].offset - segment_info[i - 1].offset - segment_info[i - 1].size);
1731
1732 ti = proto_tree_add_uint_format(blackhole_tree, hf_elf_blackhole_size, tvb, value_guard(segment_info[i].offset - len), 1, len,
1733 "Blackhole between: %s and %s, size: %u", segment_info[i - 1].name, segment_info[i].name, len);
1734 proto_item_set_len(ti, len);
1735
1736 } else if (segment_info[i - 1].offset + segment_info[i - 1].size > segment_info[i].offset) {
1737 /* overlapping */
1738 len = (guint) (segment_info[i - 1].offset + segment_info[i - 1].size - segment_info[i].offset);
1739
1740 ti = proto_tree_add_uint_format(overlapping_tree, hf_elf_overlapping_size, tvb, value_guard(segment_info[i - 1].offset + segment_info[i - 1].size - len), 1, len,
1741 "Overlapping between: %s and %s, size: %u", segment_info[i - 1].name, segment_info[i].name, len);
1742 proto_item_set_len(ti, len);
1743
1744 file_size -= len;
1745 }
1746 }
1747
1748 if (segment_info[area_counter - 1].offset + segment_info[area_counter - 1].size < tvb_captured_length(tvb)) {
1749 len = tvb_captured_length(tvb) - (guint) (segment_info[area_counter - 1].offset - segment_info[area_counter - 1].size);
1750
1751 ti = proto_tree_add_uint_format(blackhole_tree, hf_elf_blackhole_size, tvb,
1752 value_guard(segment_info[area_counter - 1].offset +
1753 segment_info[area_counter - 1].size), 1,
1754 len, "Blackhole between: %s and <EOF>, size: %u",
1755 segment_info[area_counter - 1].name, len);
1756 proto_item_set_len(ti, len);
1757 }
1758
1759 proto_tree_add_uint(generated_tree, hf_elf_file_size, tvb, 0, 0, tvb_captured_length(tvb));
1760 proto_tree_add_uint(generated_tree, hf_elf_header_segment_size, tvb, 0, 0, (guint)file_size);
1761 proto_tree_add_uint(generated_tree, hf_elf_blackholes_size, tvb, 0, 0, tvb_captured_length(tvb) - (guint)file_size);
1762
1763 col_clear(pinfo->cinfo, COL_INFO);
1764 col_add_str(pinfo->cinfo, COL_INFO, "(ELF)");
1765
1766 /* We jumping around offsets, so treat as bytes as read */
1767 return tvb_captured_length(tvb);
1768 }
1769
1770 static gboolean
dissect_elf_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1771 dissect_elf_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1772 {
1773 return dissect_elf(tvb, pinfo, tree, NULL) > 0;
1774 }
1775
1776 void
proto_register_elf(void)1777 proto_register_elf(void)
1778 {
1779 module_t *module;
1780 expert_module_t *expert_module;
1781
1782 static hf_register_info hf[] = {
1783 /* Header */
1784 { &hf_elf_magic_bytes,
1785 { "Magic Bytes", "elf.magic_bytes",
1786 FT_BYTES, BASE_NONE, NULL, 0x00,
1787 NULL, HFILL }
1788 },
1789 { &hf_elf_file_size,
1790 { "File size", "elf.file_size",
1791 FT_UINT32, BASE_DEC, NULL, 0x00,
1792 NULL, HFILL }
1793 },
1794 { &hf_elf_header_segment_size,
1795 { "Header size + all segment size", "elf.header_segment_size",
1796 FT_UINT32, BASE_DEC, NULL, 0x00,
1797 NULL, HFILL }
1798 },
1799 { &hf_elf_blackholes_size,
1800 { "Total blackholes size", "elf.blackholes_size",
1801 FT_UINT32, BASE_DEC, NULL, 0x00,
1802 NULL, HFILL }
1803 },
1804 { &hf_elf_blackhole_size,
1805 { "Blackhole size", "elf.blackhole_size",
1806 FT_UINT32, BASE_DEC, NULL, 0x00,
1807 "Blackhole size between sections or program headers", HFILL }
1808 },
1809 { &hf_elf_overlapping_size,
1810 { "Overlapping size", "elf.overlapping_size",
1811 FT_UINT32, BASE_DEC, NULL, 0x00,
1812 "Overlapping size between sections or program headers", HFILL }
1813 },
1814 { &hf_elf_segment,
1815 { "Segment", "elf.segment",
1816 FT_BYTES, BASE_NONE, NULL, 0x00,
1817 NULL, HFILL }
1818 },
1819 { &hf_elf_entry_bytes,
1820 { "Entry", "elf.entry_bytes",
1821 FT_BYTES, BASE_NONE, NULL, 0x00,
1822 NULL, HFILL }
1823 },
1824 { &hf_elf_file_class,
1825 { "File Class", "elf.file_class",
1826 FT_UINT8, BASE_HEX, VALS(class_vals), 0x00,
1827 NULL, HFILL }
1828 },
1829 { &hf_elf_data_encoding,
1830 { "Data Encoding", "elf.data_encoding",
1831 FT_UINT8, BASE_HEX, VALS(data_encoding_vals), 0x00,
1832 NULL, HFILL }
1833 },
1834 { &hf_elf_file_version,
1835 { "File Version", "elf.file_version",
1836 FT_UINT8, BASE_HEX, VALS(version_vals), 0x00,
1837 NULL, HFILL }
1838 },
1839 { &hf_elf_os_abi,
1840 { "OS ABI", "elf.os_abi",
1841 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &os_abi_vals_ext, 0x00,
1842 NULL, HFILL }
1843 },
1844 { &hf_elf_abi_version,
1845 { "ABI Version", "elf.abi_version",
1846 FT_UINT8, BASE_HEX_DEC, NULL, 0x00,
1847 NULL, HFILL }
1848 },
1849 { &hf_elf_file_padding,
1850 { "File Padding", "elf.file_padding",
1851 FT_BYTES, BASE_NONE, NULL, 0x00,
1852 NULL, HFILL }
1853 },
1854 { &hf_elf_type,
1855 { "Type", "elf.type",
1856 FT_UINT16, BASE_HEX, VALS(type_vals), 0x00,
1857 NULL, HFILL }
1858 },
1859 { &hf_elf_machine,
1860 { "Machine", "elf.machine",
1861 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &machine_vals_ext, 0x00,
1862 NULL, HFILL }
1863 },
1864 { &hf_elf_version,
1865 { "Version", "elf.version",
1866 FT_UINT32, BASE_HEX, VALS(version_vals), 0x00,
1867 NULL, HFILL }
1868 },
1869 { &hf_elf_entry,
1870 { "Entry", "elf.entry",
1871 FT_UINT32, BASE_HEX, NULL, 0x00,
1872 "This member gives the virtual address to which the system first transfers control, thus starting the process. If the file has no associated entry point, this member holds zero. ", HFILL }
1873 },
1874 { &hf_elf64_entry,
1875 { "Entry", "elf.entry64",
1876 FT_UINT64, BASE_HEX, NULL, 0x00,
1877 "This member gives the virtual address to which the system first transfers control, thus starting the process. If the file has no associated entry point, this member holds zero. ", HFILL }
1878 },
1879 { &hf_elf_phoff,
1880 { "Program Header Table File Offset", "elf.phoff",
1881 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1882 "This member holds the program header table's file offset in bytes. If the file has no program header table, this member holds zero.", HFILL }
1883 },
1884 { &hf_elf64_phoff,
1885 { "Program Header Table File Offset", "elf.phoff64",
1886 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1887 "This member holds the program header table's file offset in bytes. If the file has no program header table, this member holds zero.", HFILL }
1888 },
1889 { &hf_elf_shoff,
1890 { "Section Header Table File Offset", "elf.shoff",
1891 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1892 "This member holds the section header table's file offset in bytes. If the file has no section header table, this member holds zero.", HFILL }
1893 },
1894 { &hf_elf64_shoff,
1895 { "Section Header Table File Offset", "elf.shoff64",
1896 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1897 "This member holds the section header table's file offset in bytes. If the file has no section header table, this member holds zero.", HFILL }
1898 },
1899 { &hf_elf_flags, /* TODO: dissect flags */
1900 { "Flags", "elf.flags",
1901 FT_UINT32, BASE_HEX, NULL, 0x00,
1902 "This member holds processor-specific flags associated with the file. Flag names take the form EF_machine_flag.", HFILL }
1903 },
1904 { &hf_elf_ehsize,
1905 { "ELF Header Size", "elf.ehsize",
1906 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1907 "This member holds the ELF header's size in bytes.", HFILL }
1908 },
1909 { &hf_elf_phentsize,
1910 { "Entry Size in Program Header Table", "elf.phentsize",
1911 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1912 "This member holds the size in bytes of one entry in the file's program header table; all entries are the same size.", HFILL }
1913 },
1914 { &hf_elf_phnum,
1915 { "Number of Entries in the Program Header Table", "elf.phnum",
1916 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1917 "This member holds the number of entries in the program header table. Thus the product of e_phentsize and e_phnum gives the table's size in bytes. If a file has no program header table, e_phnum holds the value zero.", HFILL }
1918 },
1919 { &hf_elf_shentsize,
1920 { "Entry Size in Section Header Table", "elf.shentsize",
1921 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1922 "This member holds a section header's size in bytes. A section header is one entry in the section header table; all entries are the same size.", HFILL }
1923 },
1924 { &hf_elf_shnum,
1925 { "Number of Entries in the Section Header Table", "elf.shnum",
1926 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1927 "This member holds the number of entries in the section header table. Thus the product of e_shentsize and e_shnum gives the section header table's size in bytes. If a file has no section header table, e_shnum holds the value zero.", HFILL }
1928 },
1929 { &hf_elf_shstrndx,
1930 { "Section Header Table String Index", "elf.shstrndx",
1931 FT_UINT16, BASE_DEC_HEX, NULL, 0x00,
1932 "This member holds the section header table index of the entry associated with the section name string table. If the file has no section name string table, this member holds the value SHN_UNDEF.", HFILL }
1933 },
1934 /* Program Header */
1935 { &hf_elf_p_type,
1936 { "Element Type", "elf.p_type",
1937 FT_UINT32, BASE_HEX_DEC, VALS(p_type_vals), 0x00,
1938 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1939 },
1940 { &hf_elf_p_type_operating_system_specific,
1941 { "Element Type: Operating System Specific", "elf.p_type",
1942 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1943 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1944 },
1945 { &hf_elf_p_type_processor_specific,
1946 { "Element Type: Processor Specific", "elf.p_type",
1947 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
1948 "This member tells what kind of segment this array element describes or how to interpret the array element's information.", HFILL }
1949 },
1950 { &hf_elf_p_offset,
1951 { "File Offset", "elf.p_offset",
1952 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1953 "This member gives the offset from the beginning of the file at which the first byte of the segment resides.", HFILL }
1954 },
1955 { &hf_elf64_p_offset,
1956 { "File Offset", "elf.p_offset64",
1957 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1958 "This member gives the offset from the beginning of the file at which the first byte of the segment resides.", HFILL }
1959 },
1960 { &hf_elf_p_vaddr,
1961 { "Virtual Address", "elf.p_vaddr",
1962 FT_UINT32, BASE_HEX, NULL, 0x00,
1963 "This member gives the virtual address at which the first byte of the segment resides in memory.", HFILL }
1964 },
1965 { &hf_elf64_p_vaddr,
1966 { "Virtual Address", "elf.p_vaddr64",
1967 FT_UINT64, BASE_HEX, NULL, 0x00,
1968 "This member gives the virtual address at which the first byte of the segment resides in memory.", HFILL }
1969 },
1970 { &hf_elf_p_paddr,
1971 { "Physical Address", "elf.p_paddr",
1972 FT_UINT32, BASE_HEX, NULL, 0x00,
1973 "On systems for which physical addressing is relevant, this member is reserved for the segment's physical address. Because System V ignores physical addressing for application programs, this member has unspecified contents for executable files and shared objects.", HFILL }
1974 },
1975 { &hf_elf64_p_paddr,
1976 { "Physical Address", "elf.p_paddr64",
1977 FT_UINT64, BASE_HEX, NULL, 0x00,
1978 "On systems for which physical addressing is relevant, this member is reserved for the segment's physical address. Because System V ignores physical addressing for application programs, this member has unspecified contents for executable files and shared objects.", HFILL }
1979 },
1980 { &hf_elf_p_filesz,
1981 { "File Image Size", "elf.p_filesz",
1982 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1983 "This member gives the number of bytes in the file image of the segment; it may be zero.", HFILL }
1984 },
1985 { &hf_elf64_p_filesz,
1986 { "File Image Size", "elf.p_filesz64",
1987 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1988 "This member gives the number of bytes in the file image of the segment; it may be zero.", HFILL }
1989 },
1990 { &hf_elf_p_memsz,
1991 { "Memory Image Size", "elf.p_memsz",
1992 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
1993 "This member gives the number of bytes in the memory image of the segment; it may be zero.", HFILL }
1994 },
1995 { &hf_elf64_p_memsz,
1996 { "Memory Image Size", "elf.p_memsz64",
1997 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
1998 "This member gives the number of bytes in the memory image of the segment; it may be zero.", HFILL }
1999 },
2000 { &hf_elf_p_flags_processor_specific,
2001 { "Processor Specific Flags", "elf.p_flags.maskproc",
2002 FT_BOOLEAN, 32, NULL, 0xF0000000,
2003 NULL, HFILL }
2004 },
2005 { &hf_elf_p_flags_operating_system_specific,
2006 { "Operating System Specific Flags", "elf.p_flags.maskos",
2007 FT_BOOLEAN, 32, NULL, 0x0FF00000,
2008 NULL, HFILL }
2009 },
2010 { &hf_elf_p_flags_reserved,
2011 { "Reserved Flags", "elf.p_flags.reserved",
2012 FT_BOOLEAN, 32, NULL, 0x000FFFF8,
2013 NULL, HFILL }
2014 },
2015 { &hf_elf_p_flags_read,
2016 { "Read Flag", "elf.p_flags.read",
2017 FT_BOOLEAN, 32, NULL, 0x00000004,
2018 NULL, HFILL }
2019 },
2020 { &hf_elf_p_flags_write,
2021 { "Write Flag", "elf.p_flags.write",
2022 FT_BOOLEAN, 32, NULL, 0x00000002,
2023 NULL, HFILL }
2024 },
2025 { &hf_elf_p_flags_execute,
2026 { "Execute Flag", "elf.p_flags.execute",
2027 FT_BOOLEAN, 32, NULL, 0x00000001,
2028 NULL, HFILL }
2029 },
2030 { &hf_elf_p_align,
2031 { "Align", "elf.p_align",
2032 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2033 "This member gives the value to which the segments are aligned in memory and in the file. Values 0 and 1 mean no alignment is required. Otherwise, p_align should be a positive, integral power of 2, and p_vaddr should equal p_offset, modulo p_align.", HFILL }
2034 },
2035 { &hf_elf64_p_align,
2036 { "Align", "elf.p_align64",
2037 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2038 "This member gives the value to which the segments are aligned in memory and in the file. Values 0 and 1 mean no alignment is required. Otherwise, p_align should be a positive, integral power of 2, and p_vaddr should equal p_offset, modulo p_align.", HFILL }
2039 },
2040 /* Section Header */
2041 { &hf_elf_sh_name,
2042 { "Name Index", "elf.sh_name",
2043 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2044 "Section Name. Its value is an index into the section header string table section, giving the location of a null-terminated string.", HFILL }
2045 },
2046 { &hf_elf_sh_type,
2047 { "Type", "elf.sh_type",
2048 FT_UINT32, BASE_HEX_DEC | BASE_EXT_STRING, &sh_type_vals_ext, 0x00,
2049 "This member categorizes the section's contents and semantics.", HFILL }
2050 },
2051 { &hf_elf_sh_type_operating_system_specific,
2052 { "Type: Operating System Specific", "elf.sh_type",
2053 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
2054 "This member categorizes the section's contents and semantics.", HFILL }
2055 },
2056 { &hf_elf_sh_type_processor_specific,
2057 { "Type: Processor Specific", "elf.sh_type",
2058 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
2059 "This member categorizes the section's contents and semantics.", HFILL }
2060 },
2061 { &hf_elf_sh_type_user_specific,
2062 { "Type: User Specific", "elf.sh_type",
2063 FT_UINT32, BASE_HEX_DEC, NULL, 0x00,
2064 "This member categorizes the section's contents and semantics.", HFILL }
2065 },
2066 { &hf_elf_sh_flags_processor_specific,
2067 { "Processor Specific Flags", "elf.sh_flags.maskproc",
2068 FT_BOOLEAN, 32, NULL, 0xF0000000,
2069 NULL, HFILL }
2070 },
2071 { &hf_elf_sh_flags_operating_system_specific,
2072 { "Operating System Specific Flags", "elf.sh_flags.maskos",
2073 FT_BOOLEAN, 32, NULL, 0x0FF00000,
2074 NULL, HFILL }
2075 },
2076 { &hf_elf_sh_flags_reserved,
2077 { "Reserved", "elf.sh_flags.reserved",
2078 FT_BOOLEAN, 32, NULL, 0x000FF800,
2079 NULL, HFILL }
2080 },
2081 { &hf_elf_sh_flags_tls,
2082 { "TLS Flag", "elf.sh_flags.tls",
2083 FT_BOOLEAN, 32, NULL, 0x00000400,
2084 "This section holds Thread-Local Storage, meaning that each separate execution flow has its own distinct instance of this data. Implementations need not support this flag.", HFILL }
2085 },
2086 { &hf_elf_sh_flags_group,
2087 { "Group Flag", "elf.sh_flags.group",
2088 FT_BOOLEAN, 32, NULL, 0x00000200,
2089 "This section is a member (perhaps the only one) of a section group.", HFILL }
2090 },
2091 { &hf_elf_sh_flags_os_nonconforming,
2092 { "OS NonConforming Flag", "elf.sh_flags.os_nonconforming",
2093 FT_BOOLEAN, 32, NULL, 0x00000100,
2094 "This section requires special OS-specific processing to avoid incorrect behavior.", HFILL }
2095 },
2096 { &hf_elf_sh_flags_link_order,
2097 { "Link Order Flag", "elf.sh_flags.link_order",
2098 FT_BOOLEAN, 32, NULL, 0x00000080,
2099 "This flag adds special ordering requirements for link editors.", HFILL }
2100 },
2101 { &hf_elf_sh_flags_info_link,
2102 { "Info Link Flag", "elf.sh_flags.info_link",
2103 FT_BOOLEAN, 32, NULL, 0x00000040,
2104 "The sh_info field of this section header holds a section header table index.", HFILL }
2105 },
2106 { &hf_elf_sh_flags_strings,
2107 { "Strings Flag", "elf.sh_flags.strings",
2108 FT_BOOLEAN, 32, NULL, 0x00000020,
2109 "The data elements in the section consist of null-terminated character strings. The size of each character is specified in the section header's sh_entsize field.", HFILL }
2110 },
2111 { &hf_elf_sh_flags_merge,
2112 { "Merge Flag", "elf.sh_flags.merge",
2113 FT_BOOLEAN, 32, NULL, 0x00000010,
2114 "The data in the section may be merged to eliminate duplication.", HFILL }
2115 },
2116 { &hf_elf_sh_flags_reserved_8,
2117 { "Reserved", "elf.sh_flags.reserved.8",
2118 FT_BOOLEAN, 32, NULL, 0x00000008,
2119 NULL, HFILL }
2120 },
2121 { &hf_elf_sh_flags_exec_instr,
2122 { "Exec Instr Flag", "elf.sh_flags.exec_instr",
2123 FT_BOOLEAN, 32, NULL, 0x00000004,
2124 "The section contains executable machine instructions.", HFILL }
2125 },
2126 { &hf_elf_sh_flags_alloc,
2127 { "Alloc Flag", "elf.sh_flags.alloc",
2128 FT_BOOLEAN, 32, NULL, 0x00000002,
2129 "The section occupies memory during process execution. Some control sections do not reside in the memory image of an object file; this attribute is off for those sections.", HFILL }
2130 },
2131 { &hf_elf_sh_flags_write,
2132 { "Write Flag", "elf.sh_flags.write",
2133 FT_BOOLEAN, 32, NULL, 0x00000001,
2134 "The section contains data that should be writable during process execution.", HFILL }
2135 },
2136 { &hf_elf_sh_addr,
2137 { "Address", "elf.sh_addr",
2138 FT_UINT32, BASE_HEX, NULL, 0x00,
2139 "If the section will appear in the memory image of a process, this member gives the address at which the section's first byte should reside. Otherwise, the member contains 0.", HFILL }
2140 },
2141 { &hf_elf64_sh_addr,
2142 { "Address", "elf.sh_addr64",
2143 FT_UINT64, BASE_HEX, NULL, 0x00,
2144 "If the section will appear in the memory image of a process, this member gives the address at which the section's first byte should reside. Otherwise, the member contains 0.", HFILL }
2145 },
2146 { &hf_elf_sh_offset,
2147 { "File Offset", "elf.sh_offset",
2148 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2149 "This member's value gives the byte offset from the beginning of the file to the first byte in the section. One section type, SHT_NOBITS, occupies no space in the file, and its sh_offset member locates the conceptual placement in the file.", HFILL }
2150 },
2151 { &hf_elf64_sh_offset,
2152 { "File Offset", "elf.sh_offset64",
2153 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2154 "This member's value gives the byte offset from the beginning of the file to the first byte in the section. One section type, SHT_NOBITS, occupies no space in the file, and its sh_offset member locates the conceptual placement in the file.", HFILL }
2155 },
2156 { &hf_elf_sh_size,
2157 { "Size", "elf.sh_size",
2158 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2159 "This member gives the section's size in bytes.", HFILL }
2160 },
2161 { &hf_elf64_sh_size,
2162 { "Size", "elf.sh_size64",
2163 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2164 "This member gives the section's size in bytes.", HFILL }
2165 },
2166
2167 { &hf_elf_sh_link,
2168 { "Link Index", "elf.sh_link",
2169 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2170 "This member holds a section header table index link, whose interpretation depends on the section type.", HFILL }
2171 },
2172 { &hf_elf_sh_info,
2173 { "Info", "elf.sh_info",
2174 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2175 "This member holds extra information, whose interpretation depends on the section type.", HFILL }
2176 },
2177 { &hf_elf_sh_addralign,
2178 { "Address Alignment", "elf.sh_addralign",
2179 FT_UINT32, BASE_HEX, NULL, 0x00,
2180 "Some sections have address alignment constraints. Currently, only 0 and positive integral powers of two are allowed. Values 0 and 1 mean the section has no alignment constraints.", HFILL }
2181 },
2182 { &hf_elf64_sh_addralign,
2183 { "Address Alignment", "elf.sh_addralign64",
2184 FT_UINT64, BASE_HEX, NULL, 0x00,
2185 "Some sections have address alignment constraints. Currently, only 0 and positive integral powers of two are allowed. Values 0 and 1 mean the section has no alignment constraints.", HFILL }
2186 },
2187 { &hf_elf_sh_entsize,
2188 { "Entry Size", "elf.sh_entsize",
2189 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2190 "Some sections hold a table of fixed-size entries, such as a symbol table. For such a section, this member gives the size in bytes of each entry. The member contains 0 if the section does not hold a table of fixed-size entries.", HFILL }
2191 },
2192 { &hf_elf64_sh_entsize,
2193 { "Entry Size", "elf.sh_entsize64",
2194 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2195 "Some sections hold a table of fixed-size entries, such as a symbol table. For such a section, this member gives the size in bytes of each entry. The member contains 0 if the section does not hold a table of fixed-size entries.", HFILL }
2196 },
2197 /* .eh_frame */
2198 { &hf_elf_eh_frame_length,
2199 { "Length", "elf.eh_frame.length",
2200 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2201 "Length of CIE. Zero indicates a terminator, 0xffffffff means that "
2202 "the Extended Length field contains the actual length.", HFILL }
2203 },
2204 { &hf_elf_eh_frame_extended_length,
2205 { "Extended Length", "elf.eh_frame.extended_length",
2206 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2207 "Extended Length of CIE.", HFILL }
2208 },
2209 { &hf_elf_eh_frame_cie_id,
2210 { "CIE ID", "elf.eh_frame.cie_id",
2211 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2212 "A 4 byte unsigned value that is used to distinguish CIE records from FDE records. This value shall always be 0, which indicates this record is a CIE.", HFILL }
2213 },
2214 { &hf_elf_eh_frame_version,
2215 { "Version", "elf.eh_frame.version",
2216 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2217 "A 1 byte value that identifies the version number of the frame information structure. This value shall be 1.", HFILL }
2218 },
2219 { &hf_elf_eh_frame_augmentation_string,
2220 { "Augmentation String", "elf.eh_frame.augmentation_string",
2221 FT_STRINGZ, BASE_NONE, NULL, 0x00,
2222 "This value is a NUL terminated string that identifies the augmentation to the CIE or to the FDEs associated with this CIE. A zero length string indicates that no augmentation data is present. The augmentation string is case sensitive.", HFILL }
2223 },
2224 { &hf_elf_eh_frame_code_alignment_factor,
2225 { "Code Alignment Factor", "elf.eh_frame.code_alignment_factor",
2226 FT_UINT64, BASE_DEC, NULL, 0x00,
2227 "An unsigned LEB128 encoded value that is factored out of all advance location instructions that are associated with this CIE or its FDEs. This value shall be multiplied by the delta argument of an adavance location instruction to obtain the new location value.", HFILL }
2228 },
2229 { &hf_elf_eh_frame_data_alignment_factor,
2230 { "Data Alignment Factor", "elf.eh_frame.data_alignment_factor",
2231 FT_INT64, BASE_DEC, NULL, 0x00,
2232 "A signed LEB128 encoded value that is factored out of all offset instructions that are associated with this CIE or its FDEs. This value shall be multiplied by the register offset argument of an offset instruction to obtain the new offset value.", HFILL }
2233 },
2234 { &hf_elf_eh_frame_return_address_register,
2235 { "Return Address Register", "elf.eh_frame.return_address_register",
2236 FT_UINT64, BASE_DEC, NULL, 0x00,
2237 "An unsigned LEB128 constant that indicates which column in the rule table represents the return address of the function. Note that this column might not correspond to an actual machine register.", HFILL }
2238 },
2239 { &hf_elf_eh_frame_augmentation_length,
2240 { "Augmentation Length", "elf.eh_frame.augmentation_length",
2241 FT_UINT64, BASE_DEC, NULL, 0x00,
2242 "An unsigned LEB128 encoded value indicating the length in bytes of the Augmentation Data. This field is only present if the Augmentation String contains the character 'z'.", HFILL }
2243 },
2244 { &hf_elf_eh_frame_augmentation_data,
2245 { "Augmentation Data", "elf.eh_frame.augmentation_data",
2246 FT_BYTES, BASE_NONE, NULL, 0x00,
2247 "A block of data whose contents are defined by the contents of the Augmentation String as described below. This field is only present if the Augmentation String contains the character 'z'.", HFILL }
2248 },
2249 { &hf_elf_eh_frame_initial_instructions,
2250 { "Initial Instructions", "elf.eh_frame.initial_instructions",
2251 FT_BYTES, BASE_NONE, NULL, 0x00,
2252 "Initial set of Call Frame Instructions.", HFILL }
2253 },
2254 /* .eh_frame fde */
2255 { &hf_elf_eh_frame_fde_length,
2256 { "Length", "elf.eh_frame.fde.length",
2257 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2258 "Length of FDE. Zero indicates a terminator, 0xffffffff means that "
2259 "the Extended Length field contains the actual length.", HFILL }
2260 },
2261 { &hf_elf_eh_frame_fde_extended_length,
2262 { "Extended Length", "elf.eh_frame.fde.extended_length",
2263 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2264 "Extended Length of FDE.", HFILL }
2265 },
2266 { &hf_elf_eh_frame_fde_cie_pointer,
2267 { "CIE Pointer", "elf.eh_frame.fde.cie_pointer",
2268 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2269 "A 4 byte unsigned value that when subtracted from the offset of the the CIE Pointer in the current FDE yields the offset of the start of the associated CIE. This value shall never be 0.", HFILL }
2270 },
2271 { &hf_elf_eh_frame_fde_pc_begin,
2272 { "PC Begin", "elf.eh_frame.fde.pc_begin",
2273 FT_UINT32, BASE_HEX, NULL, 0x00,
2274 "An encoded value that indicates the address of the initial location associated with this FDE. The encoding format is specified in the Augmentation Data.", HFILL }
2275 },
2276 { &hf_elf_eh_frame_fde_pc_range,
2277 { "PC Range", "elf.eh_frame.fde.pc_range",
2278 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2279 "An absolute value that indicates the number of bytes of instructions associated with this FDE.", HFILL }
2280 },
2281 { &hf_elf_eh_frame_fde_augmentation_length,
2282 { "Augmentation Length", "elf.eh_frame.fde.augmentation_length",
2283 FT_UINT64, BASE_DEC, NULL, 0x00,
2284 "An unsigned LEB128 encoded value indicating the length in bytes of the Augmentation Data.", HFILL }
2285 },
2286 { &hf_elf_eh_frame_fde_augmentation_data,
2287 { "Augmentation Data", "elf.eh_frame.fde.augmentation_data",
2288 FT_BYTES, BASE_NONE, NULL, 0x00,
2289 "Data as described by the Augmentation String in the CIE.", HFILL }
2290 },
2291 { &hf_elf_eh_frame_fde_call_frame_instructions,
2292 { "Call Frame Instructions", "elf.eh_frame.fde.call_frame_instructions",
2293 FT_BYTES, BASE_NONE, NULL, 0x00,
2294 "A set of Call Frame Instructions.", HFILL }
2295 },
2296 /* .eh_frame_hdr */
2297 { &hf_elf_eh_frame_hdr_version,
2298 { "Version", "elf.eh_frame_hdr.version",
2299 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2300 "Version of the .eh_frame_hdr format. This value shall be 1.", HFILL }
2301 },
2302 { &hf_elf_eh_frame_hdr_exception_frame_pointer_encoding,
2303 { "Exception Frame Pointer Encoding", "elf.eh_frame_hdr.eh_frame_ptr_enc",
2304 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2305 "The encoding format of the eh_frame_ptr field.", HFILL }
2306 },
2307 { &hf_elf_eh_frame_hdr_fde_count_encoding,
2308 { "FDE Count Encoding", "elf.eh_frame_hdr.fde_count_enc",
2309 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2310 "The encoding format of the fde_count field. A value of DW_EH_PE_omit indicates the binary search table is not present.", HFILL }
2311 },
2312 { &hf_elf_eh_frame_hdr_binary_search_table_encoding,
2313 { "Binary Search Table Encoding", "elf.eh_frame_hdr.binary_search_table_encoding",
2314 FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
2315 "The encoding format of the entries in the binary search table. A value of DW_EH_PE_omit indicates the binary search table is not present.", HFILL }
2316 },
2317
2318
2319 { &hf_elf_eh_frame_hdr_eh_frame_ptr,
2320 { "Exception Frame Pointer", "elf.eh_frame_hdr.eh_frame_ptr",
2321 FT_BYTES, BASE_NONE, NULL, 0x00,
2322 "Start of .eh_frame pointer", HFILL }
2323 },
2324 { &hf_elf_eh_frame_hdr_fde_count,
2325 { "Number of FDE entries", "elf.eh_frame_hdr.fde_count",
2326 FT_UINT64, BASE_DEC, NULL, 0x00,
2327 NULL, HFILL }
2328 },
2329 { &hf_elf_eh_frame_hdr_binary_search_table_entry_initial_location,
2330 { "Initial location", "elf.eh_frame_hdr.binary_search_table_entry.initial_location",
2331 FT_BYTES, BASE_NONE, NULL, 0x00,
2332 NULL, HFILL }
2333 },
2334 { &hf_elf_eh_frame_hdr_binary_search_table_entry_address,
2335 { "Address", "elf.eh_frame_hdr.binary_search_table_entry.address",
2336 FT_BYTES, BASE_NONE, NULL, 0x00,
2337 NULL, HFILL }
2338 },
2339
2340 /* symbol_table */
2341 { &hf_elf_symbol_table_name_index,
2342 { "Name Index", "elf.symbol_table.name_index",
2343 FT_UINT32, BASE_DEC, NULL, 0x00,
2344 NULL, HFILL }
2345 },
2346 { &hf_elf_symbol_table_info,
2347 { "Info", "elf.symbol_table.info",
2348 FT_UINT8, BASE_HEX, NULL, 0x00,
2349 NULL, HFILL }
2350 },
2351 { &hf_elf_symbol_table_info_bind,
2352 { "Bind", "elf.symbol_table.info.bind",
2353 FT_UINT8, BASE_HEX, VALS(symbol_table_info_bind_vals), 0xF0,
2354 NULL, HFILL }
2355 },
2356 { &hf_elf_symbol_table_info_type,
2357 { "Type", "elf.symbol_table.info.type",
2358 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &symbol_table_info_type_vals_ext, 0x0F,
2359 NULL, HFILL }
2360 },
2361 { &hf_elf_symbol_table_other,
2362 { "Other", "elf.symbol_table.other",
2363 FT_UINT8, BASE_HEX, VALS(symbol_table_other_vals), 0x00,
2364 NULL, HFILL }
2365 },
2366 { &hf_elf_symbol_table_shndx,
2367 { "Related Section Header Index", "elf.symbol_table.shndx",
2368 FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(symbol_table_shndx_rvals), 0x00,
2369 NULL, HFILL }
2370 },
2371 { &hf_elf_symbol_table_value,
2372 { "Value", "elf.symbol_table.value",
2373 FT_UINT32, BASE_HEX, NULL, 0x00,
2374 NULL, HFILL }
2375 },
2376 { &hf_elf64_symbol_table_value,
2377 { "Value", "elf.symbol_table.value64",
2378 FT_UINT64, BASE_HEX, NULL, 0x00,
2379 NULL, HFILL }
2380 },
2381 { &hf_elf_symbol_table_size,
2382 { "Size", "elf.symbol_table.size",
2383 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2384 NULL, HFILL }
2385 },
2386 { &hf_elf64_symbol_table_size,
2387 { "Size", "elf.symbol_table.size64",
2388 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2389 NULL, HFILL }
2390 },
2391
2392 /* dynamic */
2393 { &hf_elf_dynamic_tag,
2394 { "Tag", "elf.dynamic.tag",
2395 FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(dynamic_tag_rvals), 0x00,
2396 NULL, HFILL }
2397 },
2398 { &hf_elf_dynamic_value,
2399 { "Value", "elf.dynamic.value",
2400 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2401 NULL, HFILL }
2402 },
2403 { &hf_elf_dynamic_pointer,
2404 { "Pointer", "elf.dynamic.pointer",
2405 FT_UINT32, BASE_HEX, NULL, 0x00,
2406 NULL, HFILL }
2407 },
2408 { &hf_elf_dynamic_ignored,
2409 { "Ignored", "elf.dynamic.ignored",
2410 FT_UINT32, BASE_HEX, NULL, 0x00,
2411 NULL, HFILL }
2412 },
2413 { &hf_elf_dynamic_unspecified,
2414 { "Unspecified", "elf.dynamic.unspecified",
2415 FT_UINT32, BASE_DEC_HEX, NULL, 0x00,
2416 NULL, HFILL }
2417 },
2418 { &hf_elf64_dynamic_tag,
2419 { "Tag", "elf.dynamic.tag64",
2420 FT_UINT64, BASE_HEX /*| BASE_RANGE_STRING*/, NULL /*RVALS(dynamic_tag_rvals)*/, 0x00,
2421 NULL, HFILL }
2422 },
2423 { &hf_elf64_dynamic_value,
2424 { "Value", "elf.dynamic.value64",
2425 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2426 NULL, HFILL }
2427 },
2428 { &hf_elf64_dynamic_pointer,
2429 { "Pointer", "elf.dynamic.pointer64",
2430 FT_UINT64, BASE_HEX, NULL, 0x00,
2431 NULL, HFILL }
2432 },
2433 { &hf_elf64_dynamic_ignored,
2434 { "Ignored", "elf.dynamic.ignored64",
2435 FT_UINT64, BASE_HEX, NULL, 0x00,
2436 NULL, HFILL }
2437 },
2438 { &hf_elf64_dynamic_unspecified,
2439 { "Unspecified", "elf.dynamic.unspecified64",
2440 FT_UINT64, BASE_DEC_HEX, NULL, 0x00,
2441 NULL, HFILL }
2442 },
2443
2444 /* dwarf */
2445 { &hf_dwarf_omit,
2446 { "DW_EH_PE_omit", "elf.dwarf.omit",
2447 FT_UINT8, BASE_HEX, NULL, 0x00,
2448 "Used to indicate that no value is present.", HFILL }
2449 },
2450 { &hf_dwarf_upper,
2451 { "DWARF Exception Header application", "elf.dwarf.upper",
2452 FT_UINT8, BASE_HEX, VALS(eh_dwarf_upper), 0xF0,
2453 "The upper 4 bits indicate how the value is to be applied.", HFILL }
2454 },
2455 { &hf_dwarf_format,
2456 { "DWARF Exception Header value format", "elf.dwarf.format",
2457 FT_UINT8, BASE_HEX, VALS(eh_dwarf_format), 0x0F,
2458 "The lower 4 bits indicate the format of the data.", HFILL }
2459 },
2460 { &hf_elf_string,
2461 { "String", "elf.string",
2462 FT_STRINGZ, BASE_NONE, NULL, 0x00,
2463 NULL, HFILL }
2464 }
2465 };
2466
2467 static ei_register_info ei[] = {
2468 { &ei_invalid_segment_size, { "elf.invalid_segment_size", PI_PROTOCOL, PI_WARN, "Segment size is different then currently parsed bytes", EXPFILL }},
2469 { &ei_invalid_entry_size, { "elf.invalid_entry_size", PI_PROTOCOL, PI_WARN, "Entry size is different then currently parsed bytes", EXPFILL }},
2470 { &ei_cfi_extraneous_data, { "elf.cfi_extraneous_data", PI_PROTOCOL, PI_WARN, "Segment size is larger than CFI records combined", EXPFILL }},
2471 { &ei_invalid_cie_length, { "elf.invalid_cie_length", PI_PROTOCOL, PI_ERROR, "CIE length is too small or larger than segment size", EXPFILL }},
2472 };
2473
2474 static gint *ett[] = {
2475 &ett_elf,
2476 &ett_elf_header,
2477 &ett_elf_program_header,
2478 &ett_elf_program_header_entry,
2479 &ett_elf_section_header,
2480 &ett_elf_section_header_entry,
2481 &ett_elf_segment,
2482 &ett_elf_cfi_record,
2483 &ett_elf_cie_entry,
2484 &ett_elf_fde_entry,
2485 &ett_elf_cie_terminator,
2486 &ett_elf_info,
2487 &ett_elf_black_holes,
2488 &ett_elf_overlapping,
2489 &ett_dwarf_encoding,
2490 &ett_binary_table,
2491 &ett_binary_table_entry,
2492 &ett_symbol_table_entry,
2493 &ett_symbol_table_info
2494 };
2495
2496 proto_elf = proto_register_protocol("Executable and Linkable Format", "ELF", "elf");
2497 proto_register_field_array(proto_elf, hf, array_length(hf));
2498 proto_register_subtree_array(ett, array_length(ett));
2499
2500 elf_handle = register_dissector("elf", dissect_elf, proto_elf);
2501
2502 module = prefs_register_protocol(proto_elf, NULL);
2503 prefs_register_static_text_preference(module, "version",
2504 "ELF version: 4.1 DRAFT",
2505 "Version of file-format supported by this dissector.");
2506
2507 expert_module = expert_register_protocol(proto_elf);
2508 expert_register_field_array(expert_module, ei, array_length(ei));
2509 }
2510
2511 void
proto_reg_handoff_elf(void)2512 proto_reg_handoff_elf(void)
2513 {
2514 dissector_add_string("media_type", "application/x-executable", elf_handle);
2515 dissector_add_string("media_type", "application/x-coredump", elf_handle);
2516 dissector_add_string("media_type", "application/x-object", elf_handle);
2517 dissector_add_string("media_type", "application/x-sharedlib", elf_handle);
2518
2519 /* XXX - TEMPORARY HACK */
2520 dissector_add_uint("ftap_encap", 1234, elf_handle);
2521
2522 heur_dissector_add("wtap_file", dissect_elf_heur, "ELF file", "elf_wtap", proto_elf, HEURISTIC_ENABLE);
2523 }
2524
2525 /*
2526 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2527 *
2528 * Local variables:
2529 * c-basic-offset: 4
2530 * tab-width: 8
2531 * indent-tabs-mode: nil
2532 * End:
2533 *
2534 * vi: set shiftwidth=4 tabstop=8 expandtab:
2535 * :indentSize=4:tabSize=8:noTabs=true:
2536 */
2537