@@ -95,6 +95,7 @@ class _ELFBase(StructHandler):
9595
9696 EXTRACTOR = ELFKernelExtractor ()
9797 SECTION_HEADER_STRUCT = "elf_shdr_t"
98+ PROGRAM_HEADER_STRUCT = "elf_phdr_t"
9899
99100 @staticmethod
100101 def _check_field (field , value ):
@@ -143,12 +144,30 @@ def get_last_section_end(
143144
144145 return last_section_end
145146
147+ def get_last_program_end (
148+ self , file : File , programs_start_offset : int , programs_num : int , endian
149+ ) -> int :
150+ last_program_end = 0
151+ file .seek (programs_start_offset )
152+
153+ for _ in range (programs_num ):
154+ program_header = self ._struct_parser .parse (
155+ self .PROGRAM_HEADER_STRUCT , file , endian
156+ )
157+
158+ program_end = program_header .p_offset + program_header .p_filesz
159+ if program_end > last_program_end :
160+ last_program_end = program_end
161+
162+ return last_program_end
163+
146164 def get_end_offset (
147165 self , file : File , start_offset : int , header : Instance , endian
148166 ) -> int :
149167 # Usually the section header is the last, but in some cases the program headers are
150168 # put to the end of the file, and in some cases sections header and actual sections
151- # can be also intermixed, so we need also to check the end of the last section.
169+ # can be also intermixed, so we need also to check the end of the last section and
170+ # also the last program segment.
152171 # We check which one is the last and use it as a file size.
153172 section_headers_end = (
154173 start_offset + header .e_shoff + (header .e_shnum * header .e_shentsize )
@@ -161,7 +180,13 @@ def get_end_offset(
161180 file , start_offset + header .e_shoff , header .e_shnum , endian
162181 )
163182
164- return max (section_headers_end , program_headers_end , last_section_end )
183+ last_program_end = self .get_last_program_end (
184+ file , start_offset + header .e_phoff , header .e_phnum , endian
185+ )
186+
187+ return max (
188+ section_headers_end , program_headers_end , last_section_end , last_program_end
189+ )
165190
166191 def calculate_chunk (self , file : File , start_offset : int ) -> Optional [ValidChunk ]:
167192 endian = self .get_endianness (file , start_offset )
@@ -231,6 +256,17 @@ class ELF32Handler(_ELFBase):
231256 uint32 sh_addralign;
232257 uint32 sh_entsize;
233258 } elf_shdr_t;
259+
260+ typedef struct elf32_phdr {
261+ uint32 p_type;
262+ uint32 p_offset;
263+ uint32 p_vaddr;
264+ uint32 p_paddr;
265+ uint32 p_filesz;
266+ uint32 p_memsz;
267+ uint32 p_flags;
268+ uint32 p_align;
269+ } elf_phdr_t;
234270 """
235271 HEADER_STRUCT = "elf_header_32_t"
236272
@@ -290,5 +326,16 @@ class ELF64Handler(_ELFBase):
290326 uint64 sh_addralign;
291327 uint64 sh_entsize;
292328 } elf_shdr_t;
329+
330+ typedef struct elf64_phdr {
331+ uint32 p_type;
332+ uint32 p_flags;
333+ uint64 p_offset;
334+ uint64 p_vaddr;
335+ uint64 p_paddr;
336+ uint64 p_filesz;
337+ uint64 p_memsz;
338+ uint64 p_align;
339+ } elf_phdr_t;
293340 """
294341 HEADER_STRUCT = "elf_header_64_t"
0 commit comments