VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/UefiPayloadPkg/Tools/ElfFv.py@ 109019

Last change on this file since 109019 was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 47.0 KB
Line 
1## @file
2# OBJCOPY parser, it's used to replace FV
3#
4# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
5# SPDX-License-Identifier: BSD-2-Clause-Patent
6##
7
8import argparse
9from ctypes import *
10import struct
11
12class ElfSectionHeader64:
13 def __init__(self, sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link, sh_info, sh_addralign, sh_entsize):
14 self.sh_name = sh_name
15 self.sh_type = sh_type
16 self.sh_flags = sh_flags
17 self.sh_addr = sh_addr
18 self.sh_offset = sh_offset
19 self.sh_size = sh_size
20 self.sh_link = sh_link
21 self.sh_info = sh_info
22 self.sh_addralign = sh_addralign
23 self.sh_entsize = sh_entsize
24
25 def pack(self):
26 return struct.pack('<IIQQQQIIQQ', self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize)
27
28 @classmethod
29 def unpack(cls, data):
30 unpacked_data = struct.unpack('<IIQQQQIIQQ', data)
31 return cls(*unpacked_data)
32
33class ElfHeader64:
34 def __init__(self, data):
35 # Parse the ELF identification bytes
36 self.e_ident = struct.unpack('16s', data[:16])[0]
37 self.e_type = struct.unpack('H', data[16:18])[0]
38 self.e_machine = struct.unpack('H', data[18:20])[0]
39 self.e_version = struct.unpack('I', data[20:24])[0]
40 self.e_entry = struct.unpack('Q', data[24:32])[0]
41 self.e_phoff = struct.unpack('Q', data[32:40])[0]
42 self.e_shoff = struct.unpack('Q', data[40:48])[0]
43 self.e_flags = struct.unpack('I', data[48:52])[0]
44 self.e_ehsize = struct.unpack('H', data[52:54])[0]
45 self.e_phentsize = struct.unpack('H', data[54:56])[0]
46 self.e_phnum = struct.unpack('H', data[56:58])[0]
47 self.e_shentsize = struct.unpack('H', data[58:60])[0]
48 self.e_shnum = struct.unpack('H', data[60:62])[0]
49 self.e_shstrndx = struct.unpack('H', data[62:64])[0]
50
51 def pack(self):
52 # Pack the ELF header data into a binary string
53 data = b''
54 data += struct.pack('16s', self.e_ident)
55 data += struct.pack('H', self.e_type)
56 data += struct.pack('H', self.e_machine)
57 data += struct.pack('I', self.e_version)
58 data += struct.pack('Q', self.e_entry)
59 data += struct.pack('Q', self.e_phoff)
60 data += struct.pack('Q', self.e_shoff)
61 data += struct.pack('I', self.e_flags)
62 data += struct.pack('H', self.e_ehsize)
63 data += struct.pack('H', self.e_phentsize)
64 data += struct.pack('H', self.e_phnum)
65 data += struct.pack('H', self.e_shentsize)
66 data += struct.pack('H', self.e_shnum)
67 data += struct.pack('H', self.e_shstrndx)
68 return data
69
70class Elf64_Phdr:
71 def __init__(self, data):
72 self.p_type = struct.unpack("<L", data[0:4])[0]
73 self.p_flags = struct.unpack("<L", data[4:8])[0]
74 self.p_offset = struct.unpack("<Q", data[8:16])[0]
75 self.p_vaddr = struct.unpack("<Q", data[16:24])[0]
76 self.p_paddr = struct.unpack("<Q", data[24:32])[0]
77 self.p_filesz = struct.unpack("<Q", data[32:40])[0]
78 self.p_memsz = struct.unpack("<Q", data[40:48])[0]
79 self.p_align = struct.unpack("<Q", data[48:56])[0]
80
81 def pack(self):
82 # Pack the Program header table into a binary string
83 data = b''
84 data += struct.pack('<L', self.p_type)
85 data += struct.pack('<L', self.p_flags)
86 data += struct.pack('<Q', self.p_offset)
87 data += struct.pack('<Q', self.p_vaddr)
88 data += struct.pack('<Q', self.p_paddr)
89 data += struct.pack('<Q', self.p_filesz)
90 data += struct.pack('<Q', self.p_memsz)
91 data += struct.pack('<Q', self.p_align)
92 return data
93
94class ElfSectionHeader32:
95 def __init__(self, sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link, sh_info, sh_addralign, sh_entsize):
96 self.sh_name = sh_name
97 self.sh_type = sh_type
98 self.sh_flags = sh_flags
99 self.sh_addr = sh_addr
100 self.sh_offset = sh_offset
101 self.sh_size = sh_size
102 self.sh_link = sh_link
103 self.sh_info = sh_info
104 self.sh_addralign = sh_addralign
105 self.sh_entsize = sh_entsize
106
107 def pack(self):
108 return struct.pack('<IIIIIIIIII', self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize)
109
110 @classmethod
111 def unpack(cls, data):
112 unpacked_data = struct.unpack('<IIIIIIIIII', data)
113 return cls(*unpacked_data)
114
115class ElfHeader32:
116 def __init__(self, data):
117 # Parse the ELF identification bytes
118 self.e_ident = struct.unpack('16s', data[:16])[0]
119 self.e_type = struct.unpack('H', data[16:18])[0]
120 self.e_machine = struct.unpack('H', data[18:20])[0]
121 self.e_version = struct.unpack('I', data[20:24])[0]
122 self.e_entry = struct.unpack('I', data[24:28])[0]
123 self.e_phoff = struct.unpack('I', data[28:32])[0]
124 self.e_shoff = struct.unpack('I', data[32:36])[0]
125 self.e_flags = struct.unpack('I', data[36:40])[0]
126 self.e_ehsize = struct.unpack('H', data[40:42])[0]
127 self.e_phentsize = struct.unpack('H', data[42:44])[0]
128 self.e_phnum = struct.unpack('H', data[44:46])[0]
129 self.e_shentsize = struct.unpack('H', data[46:48])[0]
130 self.e_shnum = struct.unpack('H', data[48:50])[0]
131 self.e_shstrndx = struct.unpack('H', data[50:52])[0]
132
133 def pack(self):
134 # Pack the ELF header data into a binary string
135 data = b''
136 data += struct.pack('16s', self.e_ident)
137 data += struct.pack('H', self.e_type)
138 data += struct.pack('H', self.e_machine)
139 data += struct.pack('I', self.e_version)
140 data += struct.pack('I', self.e_entry)
141 data += struct.pack('I', self.e_phoff)
142 data += struct.pack('I', self.e_shoff)
143 data += struct.pack('I', self.e_flags)
144 data += struct.pack('H', self.e_ehsize)
145 data += struct.pack('H', self.e_phentsize)
146 data += struct.pack('H', self.e_phnum)
147 data += struct.pack('H', self.e_shentsize)
148 data += struct.pack('H', self.e_shnum)
149 data += struct.pack('H', self.e_shstrndx)
150 return data
151
152class Elf32_Phdr:
153 def __init__(self, data):
154 self.p_type = struct.unpack("<L", data[0:4])[0]
155 self.p_offset = struct.unpack("<L", data[4:8])[0]
156 self.p_vaddr = struct.unpack("<L", data[8:12])[0]
157 self.p_paddr = struct.unpack("<L", data[12:16])[0]
158 self.p_filesz = struct.unpack("<L", data[16:20])[0]
159 self.p_memsz = struct.unpack("<L", data[20:24])[0]
160 self.p_flags = struct.unpack("<L", data[24:28])[0]
161 self.p_align = struct.unpack("<L", data[28:32])[0]
162
163 def pack(self):
164 # Pack the Program header table into a binary string
165 data = b''
166 data += struct.pack('<L', self.p_type)
167 data += struct.pack('<L', self.p_offset)
168 data += struct.pack('<L', self.p_vaddr)
169 data += struct.pack('<L', self.p_paddr)
170 data += struct.pack('<L', self.p_filesz)
171 data += struct.pack('<L', self.p_memsz)
172 data += struct.pack('<L', self.p_flags)
173 data += struct.pack('<L', self.p_align)
174 return data
175
176def SectionAlignment(NewUPLEntry, AlignmentIndex):
177 # Section entry Alignment
178 # Alignment is transfer to integer if AlignmentIndex is string.
179 if isinstance(AlignmentIndex, str):
180 int_num = int(AlignmentIndex, 16)
181 int_num = 10 * (int_num//16) + int_num % 16
182 else:
183 int_num = AlignmentIndex
184 if (int_num != 0 or int_num != 1):
185 if ((len(NewUPLEntry) % int_num) != 0):
186 AlignNumber = int_num - (len(NewUPLEntry) % int_num)
187 if (AlignNumber != 0):
188 for x in range(AlignNumber):
189 NewUPLEntry = NewUPLEntry + bytearray(b'\0')
190 return NewUPLEntry
191
192def SectionEntryFill(SectionEntry, Alignment, Value, Offset):
193 # Alignment
194 n = 0
195 if (len (Value) < Alignment):
196 Value = Value.zfill(Alignment)
197 for x in range(0, (Alignment//2)):
198 Index = '0x' + Value[n] + Value[n + 1]
199 SectionEntry[Offset - x] = int(Index,16)
200 n += 2
201 return SectionEntry
202
203def ElfHeaderParser(UPLEntry):
204 # Read EI_CLASS, it stores information that elf with 32-bit or 64-bit architectures.
205 EI_CLASS = UPLEntry[4]
206 # If Elf is 64-bit objects.
207 if (EI_CLASS == 2):
208 # Elf header is stored at 0x0-0x40 in 64-bits objects
209 ElfHeaderData = UPLEntry[:64]
210 # If Elf is 32-bit objects.
211 else:
212 # Elf header is stored at 0x0-0x34 in 32-bits objects
213 ElfHeaderData = UPLEntry[:53]
214 # If Elf is 64-bit objects.
215 if (EI_CLASS == 2):
216 elf_header = ElfHeader64(ElfHeaderData)
217 ElfHeaderOffset = elf_header.e_shoff
218 SectionHeaderEntryNumber = elf_header.e_shnum
219 StringIndexNumber = elf_header.e_shstrndx
220 SectionHeaderEntrySize = elf_header.e_shentsize
221 StringIndexEntryOffset = ElfHeaderOffset + (StringIndexNumber * SectionHeaderEntrySize)
222 unpacked_header = ElfSectionHeader64.unpack(UPLEntry[StringIndexEntryOffset: (StringIndexEntryOffset + SectionHeaderEntrySize)])
223 StringIndexSize = unpacked_header.sh_size
224 StringIndexOffset = unpacked_header.sh_offset
225 # If elf is 32-bit objects.
226 else:
227 elf_header = ElfHeader32(ElfHeaderData)
228 ElfHeaderOffset = elf_header.e_shoff
229 SectionHeaderEntryNumber = elf_header.e_shnum
230 StringIndexNumber = elf_header.e_shstrndx
231 SectionHeaderEntrySize = elf_header.e_shentsize
232 StringIndexEntryOffset = ElfHeaderOffset + (StringIndexNumber * SectionHeaderEntrySize)
233 unpacked_header = ElfSectionHeader32.unpack(UPLEntry[StringIndexEntryOffset: (StringIndexEntryOffset + SectionHeaderEntrySize)])
234 StringIndexSize = unpacked_header.sh_size
235 StringIndexOffset = unpacked_header.sh_offset
236 return ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, StringIndexEntryOffset, StringIndexSize, SectionHeaderEntrySize, StringIndexOffset, EI_CLASS
237
238def FindSection(UPLEntry, SectionName):
239 ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, StringIndexSize, SectionHeaderEntrySize, StringIndexOffset, EI_CLASS = ElfHeaderParser(UPLEntry)
240 # StringIndex is String Index section
241 StringIndex = UPLEntry[StringIndexOffset:StringIndexOffset+StringIndexSize]
242 # Section header isn't exist if SectionNameOffset = -1.
243 StringIndex = StringIndex.decode('utf-8', errors='ignore')
244 SectionNameOffset = StringIndex.find(SectionName)
245 return SectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexOffset, StringIndexNumber, EI_CLASS
246
247def AddNewSectionEntry64(LastUPLEntrylen, StringIndexValue, SectionSize, Alignment):
248 # If elf is 64-bit objects.
249 NewSectionEntry = ElfSectionHeader64 (StringIndexValue, 1, 0, 0, LastUPLEntrylen, SectionSize, 0, 0, Alignment, 0)
250 sh_bytes = NewSectionEntry.pack()
251 return sh_bytes
252
253def AddNewSectionEntry32(LastUPLEntrylen, StringIndexValue, SectionSize, Alignment):
254 # If elf is 32-bit objects.
255 NewSectionEntry = ElfSectionHeader32 (StringIndexValue, 1, 0, 0, LastUPLEntrylen, SectionSize, 0, 0, Alignment, 0)
256 sh_bytes = NewSectionEntry.pack()
257 return sh_bytes
258
259def AddSectionHeader64(SHentry, NewUPLEntrylen, SectionHeaderEntrySize, Index, RemoveNameOffset, SectionName, StringIndexNumber):
260 SHentry = bytearray(SHentry)
261 unpacked_header = ElfSectionHeader64.unpack(SHentry[(Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
262 # Section header of section 0 shows 0. It don't modify any offset.
263 if (Index != 0):
264 # read section offset.
265 unpacked_header.sh_offset = NewUPLEntrylen
266 # Modify offset of name in section entry
267 # if RemoveNameOffset != 0 that is remove function.
268 if (RemoveNameOffset != 0):
269 if (unpacked_header.sh_name > RemoveNameOffset):
270 unpacked_header.sh_name -= len (SectionName)
271 # Modify size of name string section entry in section entry.
272 if (Index == StringIndexNumber):
273 unpacked_header.sh_size -= len (SectionName)
274 # added section
275 else :
276 if (Index == StringIndexNumber):
277 unpacked_header.sh_size += len (SectionName)
278 NewSHentry = ElfSectionHeader64 (
279 unpacked_header.sh_name,
280 unpacked_header.sh_type,
281 unpacked_header.sh_flags,
282 unpacked_header.sh_addr,
283 unpacked_header.sh_offset,
284 unpacked_header.sh_size,
285 unpacked_header.sh_link,
286 unpacked_header.sh_info,
287 unpacked_header.sh_addralign,
288 unpacked_header.sh_entsize).pack()
289 return NewSHentry
290
291def AddSectionHeader32(SHentry, NewUPLEntrylen, SectionHeaderEntrySize, Index, RemoveNameOffset, SectionName, StringIndexNumber):
292 SHentry = bytearray(SHentry)
293 unpacked_header = ElfSectionHeader32.unpack(SHentry[(Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
294 if (Index != 0):
295 NewSHentry = SHentry[(Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize)]
296 unpacked_header.sh_offset = NewUPLEntrylen
297 # Modify offset of name in section entry
298 # if RemoveNameOffset != 0 that is remove function.
299 if (RemoveNameOffset != 0):
300 if (unpacked_header.sh_name > RemoveNameOffset):
301 unpacked_header.sh_name -= len (SectionName)
302 # Modify size of name string section entry in section entry.
303 if (Index == StringIndexNumber):
304 unpacked_header.sh_size -= len (SectionName)
305 # added section
306 else :
307 if (Index == StringIndexNumber):
308 unpacked_header.sh_size += len (SectionName)
309 NewSHentry = ElfSectionHeader32 (
310 unpacked_header.sh_name,
311 unpacked_header.sh_type,
312 unpacked_header.sh_flags,
313 unpacked_header.sh_addr,
314 unpacked_header.sh_offset,
315 unpacked_header.sh_size,
316 unpacked_header.sh_link,
317 unpacked_header.sh_info,
318 unpacked_header.sh_addralign,
319 unpacked_header.sh_entsize).pack()
320 return NewSHentry
321
322def ModifyPHSegmentOffset64(NewUPLEntry, ElfHeaderOffset, PHSegmentName):
323 # Modify offset and address of program header tables.
324 elf_header = ElfHeader64(NewUPLEntry[:64])
325 SHentry = NewUPLEntry[ElfHeaderOffset:]
326 # Elf program header tables start from 0x40 in 64-bits objects
327 PHentry = NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_phentsize)]
328 PHdrs = []
329 SHdrs = []
330 for i in range(elf_header.e_shnum):
331 SHData = SHentry[(i * elf_header.e_shentsize): (i * elf_header.e_shentsize) + elf_header.e_shentsize]
332 unpacked_SectionHeader = ElfSectionHeader64.unpack(SHData)
333 SHdrs.append(unpacked_SectionHeader)
334
335 # retrieve the .shstrtab section for parsing rest of the sections
336 shstrtab_section = NewUPLEntry[SHdrs[elf_header.e_shstrndx].sh_offset:SHdrs[elf_header.e_shstrndx].sh_offset+SHdrs[elf_header.e_shstrndx].sh_size]
337 shstrtab_strings = shstrtab_section.decode('utf-8', errors='ignore')
338 for i in range(elf_header.e_phnum):
339 PHData = PHentry[(i * elf_header.e_phentsize): (i * elf_header.e_phentsize) + elf_header.e_phentsize]
340 unpacked_ProgramHeader = Elf64_Phdr(PHData)
341 PHdrs.append(unpacked_ProgramHeader)
342
343 section_name_found = shstrtab_strings.find(PHSegmentName)
344 section_found = False
345 for i in range(elf_header.e_shnum):
346 if SHdrs[i].sh_name == section_name_found:
347 section_offset_found = SHdrs[i].sh_offset
348 section_addr_found = SHdrs[i].sh_addr
349 section_found = True
350
351 if section_found:
352 # syncup segment and section data
353 # there might be multiple segments pointing to the same offset of text or dymamic segments
354 # the syncup process will align those segments which pointing to the same offset.
355 text_segment_found = False
356 text_segment_offset_found = 0
357 dynamic_segment_found = False
358 dynamic_Segment_offset_found = 0
359 for i in range (elf_header.e_phnum):
360 # text segment type = PT_LOAD(1) and flags has E(1)
361 if PHdrs[i].p_type == 1 and (PHdrs[i].p_flags & 1) == 1:
362 text_segment_found = True
363 text_segment_offset_found = PHdrs[i].p_offset
364 # dynamic segment type = PT_DYNAMIC(2)
365 elif PHdrs[i].p_type == 2:
366 dynamic_segment_found = True
367 dynamic_Segment_offset_found = PHdrs[i].p_offset
368
369 if (PHSegmentName == '.text') and text_segment_found:
370 print ('sync text segment and section:')
371 for i in range (elf_header.e_phnum):
372 if PHdrs[i].p_offset == text_segment_offset_found:
373 PHdrs[i].p_offset = section_offset_found
374 PHdrs[i].p_paddr = section_addr_found
375 print ("PHdrs[%d].p_offset %x" % (i, PHdrs[i].p_offset))
376 print ("PHdrs[%d].p_paddr %x" % (i, PHdrs[i].p_paddr))
377 elif (PHSegmentName == '.dynamic') and dynamic_segment_found:
378 print ('sync dynamic segment and section:')
379 for i in range (elf_header.e_phnum):
380 if PHdrs[i].p_offset == dynamic_Segment_offset_found:
381 PHdrs[i].p_offset = section_offset_found
382 PHdrs[i].p_paddr = section_addr_found
383 print ("PHdrs[%d].p_offset %x" % (i, PHdrs[i].p_offset))
384 print ("PHdrs[%d].p_paddr %x" % (i, PHdrs[i].p_paddr))
385 elif (PHSegmentName == '.data'):
386 print ('sync data segment and section:')
387 for i in range (elf_header.e_phnum):
388 # data segment type = PT_LOAD(1) and flags = R(4) + W(2) = 6
389 if PHdrs[i].p_type == 1 and PHdrs[i].p_flags == 6:
390 if PHdrs[i].p_offset != dynamic_Segment_offset_found:
391 PHdrs[i].p_offset = section_offset_found
392 PHdrs[i].p_paddr = section_addr_found
393 print ("PHdrs[%d].p_offset %x" % (i, PHdrs[i].p_offset))
394 print ("PHdrs[%d].p_paddr %x" % (i, PHdrs[i].p_paddr))
395
396 packed_PHData = b''
397 for phdr in PHdrs:
398 packed_PHData += phdr.pack()
399 NewUPLEntry = bytearray(NewUPLEntry)
400 NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_phentsize)] = packed_PHData
401 return NewUPLEntry
402
403def ModifyPHSegmentOffset32(NewUPLEntry, ElfHeaderOffset, PHSegmentName):
404 # Modify offset and address of program header tables.
405 # Elf header is stored at 0x0-0x34 in 32-bits objects
406 elf_header = ElfHeader32(NewUPLEntry[:52])
407 SHentry = NewUPLEntry[ElfHeaderOffset:]
408 # Elf program header tables start from 0x34 in 32-bits objects
409 PHentry = NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_phentsize)]
410 PHdrs = []
411 SHdrs = []
412 for i in range(elf_header.e_shnum):
413 SHData = SHentry[(i * elf_header.e_shentsize): (i * elf_header.e_shentsize) + elf_header.e_shentsize]
414 unpacked_SectionHeader = ElfSectionHeader32.unpack(SHData)
415 SHdrs.append(unpacked_SectionHeader)
416 for i in range(elf_header.e_phnum):
417 PHData = PHentry[(i * elf_header.e_phentsize): (i * elf_header.e_phentsize) + elf_header.e_phentsize]
418 unpacked_ProgramHeader = Elf32_Phdr(PHData)
419 PHdrs.append(unpacked_ProgramHeader)
420 if (PHSegmentName == '.text'):
421 PHdrs[0].p_offset = SHdrs[1].sh_offset
422 PHdrs[0].p_paddr = SHdrs[1].sh_addr
423 PHdrs[0].p_vaddr = SHdrs[1].sh_addr
424 PHdrs[2].p_offset = SHdrs[1].sh_offset
425 PHdrs[2].p_paddr = SHdrs[1].sh_addr
426 PHdrs[0].p_vaddr = SHdrs[1].sh_addr
427 elif (PHSegmentName == '.data'):
428 PHdrs[1].p_offset = SHdrs[2].sh_offset
429 PHdrs[1].p_paddr = SHdrs[2].sh_addr
430 PHdrs[1].p_vaddr = SHdrs[2].sh_addr
431 packed_PHData = b''
432 for phdr in PHdrs:
433 packed_PHData += phdr.pack()
434 NewUPLEntry = bytearray(NewUPLEntry)
435 NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_phentsize)] = packed_PHData
436 return NewUPLEntry
437
438def RemoveSection64(UniversalPayloadEntry, RemoveSectionName):
439 # If elf is 64-bit objects.
440 # Get offsets as follows:
441 # 1. Section name which will remove in section name string.
442 # 2. Section which will remove.
443 # 3. Section header which will remove.
444 with open(UniversalPayloadEntry,'rb') as f:
445 UPLEntry = f.read()
446 RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, _ = FindSection(UPLEntry, RemoveSectionName)
447 if (RemoveSectionNameOffset == -1):
448 raise argparse.ArgumentTypeError ('Section: {} not found.'.format (RemoveSectionNameOffset))
449 # Read section header entry
450 SHentry = UPLEntry[ElfHeaderOffset:]
451 # find deleted fv section offset.
452 # Elf header is stored at 0x0-0x40 in 64-bits objects
453 elf_header = ElfHeader64(UPLEntry[:64])
454 Counter = 0
455 RemoveIndex = 0
456 RemoveNameOffset = 0
457 for Index in range(0, elf_header.e_shnum):
458 # Read Index of section header.
459 unpacked_SectionHeader = ElfSectionHeader64.unpack(SHentry[(Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_header.e_shentsize)])
460 # Find offset of section name which is removed.
461 if (unpacked_SectionHeader.sh_name == RemoveSectionNameOffset):
462 RemoveIndex = Counter
463 Counter += 1
464 else:
465 Counter += 1
466 # Elf header is recombined.
467 # Elf header and program header table in front of first section are reserved.
468 # Elf header size is 0x40 with 64-bit object.
469 ElfHeaderSize = 64
470 ElfHandPH = ElfHeaderSize + (elf_header.e_phnum * elf_header.e_phentsize)
471 NewUPLEntry = UPLEntry[:ElfHandPH]
472 # Keep Section header and program header table, RemoveSection64() only recombined section and section header.
473 NewUPLEntry = bytearray(NewUPLEntry)
474 # Sections is recombined.
475 # 1. name of deleted section is removed in name string section.
476 # 2. deleted section is removed in dll file.
477 # 3. re-align sections before and after deleted section.
478 NewUPLEntrylen = []
479 for Index in range(0, (SectionHeaderEntryNumber)):
480 unpacked_SectionHeader = ElfSectionHeader64.unpack(SHentry[(Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
481 NewUPLEntrylen.append(len(NewUPLEntry))
482 if (Index == 0):
483 # Address alignment, section will align with alignment of next section.
484 AlignmentIndex = 8
485 if (SectionHeaderEntryNumber > 2):
486 unpacked_NextSectionHeader = ElfSectionHeader64.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
487 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
488 # Section in front of removed section
489 elif (Index + 1 == RemoveIndex):
490 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
491 # Read section address alignment
492 # If section that will be removed in .dll is not first and last one .
493 # Address alignment, section will align with alignment of section after deleted section.
494 # Check next and the section after next are not end of section.
495 if ((Index + 2) < (SectionHeaderEntryNumber - 1)):
496 unpacked_Next2SectionHeader = ElfSectionHeader64.unpack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
497 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_Next2SectionHeader.sh_addralign)
498 else:
499 # It is align 8 bytes if next section or the section after next is last one.
500 AlignmentIndex = 8
501 NewUPLEntry = SectionAlignment(NewUPLEntry, AlignmentIndex)
502 # section is Deleted section
503 elif (Index == RemoveIndex):
504 # Don't add removed section to elf.
505 # Find offset of section name.
506 RemoveNameOffset = unpacked_SectionHeader.sh_name
507 # section is name string section.
508 elif (Index == StringIndexNumber):
509 # StringIndex is String Index section
510 StringIndex = UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
511 # Remove name of removed section in name string section.
512 # Section header isn't exist if RemoveSectionNameOffset equal to -1.
513 StringIndex = bytearray(StringIndex)
514 RemoveSectionName = bytearray(RemoveSectionName, encoding='utf-8')
515 RemoveSectionName = RemoveSectionName + bytes('\0', encoding='utf-8')
516 StringIndex = StringIndex.replace(RemoveSectionName,b'')
517 NewUPLEntry += StringIndex
518 # other sections.
519 else:
520 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
521 # Address alignment, section will align with alignment of next section.
522 if (Index < (SectionHeaderEntryNumber - 1)):
523 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
524 else:
525 # If section is last one.
526 AlignmentIndex = 8
527 NewUPLEntry = SectionAlignment(NewUPLEntry, AlignmentIndex)
528 SectionHeaderOffset = len(NewUPLEntry)
529 # Add section header
530 for Number in range(0, (SectionHeaderEntryNumber)):
531 if (Number != RemoveIndex):
532 NewSHentry = AddSectionHeader64(SHentry, NewUPLEntrylen[Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionName, StringIndexNumber)
533 NewUPLEntry += NewSHentry
534 # Modify number of sections and offset of section header in Elf header.
535 elf_header.e_shoff = SectionHeaderOffset
536 elf_header.e_shnum -= 1
537 NewUPLEntry = elf_header.pack() + NewUPLEntry[64:]
538 # write to Elf.
539 with open(UniversalPayloadEntry,'wb') as f:
540 f.write(NewUPLEntry)
541
542def RemoveSection32(UniversalPayloadEntry, RemoveSectionName):
543 # If elf is 32-bit objects.
544 # Get offsets as follows:
545 # 1. Section name which will remove in section name string.
546 # 2. Section which will remove.
547 # 3. Section header which will remove.
548 with open(UniversalPayloadEntry,'rb') as f:
549 UPLEntry = f.read()
550 RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, EI_CLASS = FindSection(UPLEntry, RemoveSectionName)
551 if (RemoveSectionNameOffset == -1):
552 raise argparse.ArgumentTypeError ('Section: {} not found.'.format (RemoveSectionNameOffset))
553 # Read section header entry
554 SHentry = UPLEntry[ElfHeaderOffset:]
555 # find deleted fv section offset.
556 # Elf header is stored at 0x0-0x34 in 32-bits objects
557 elf_header = ElfHeader32(UPLEntry[:52])
558 Counter = 0
559 RemoveIndex = 0
560 RemoveNameOffset = 0
561 for Index in range(0, elf_header.e_shnum):
562 # Read Index of section header.
563 unpacked_SectionHeader = ElfSectionHeader32.unpack(SHentry[(Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_header.e_shentsize)])
564 # Find offset of section name which is removed.
565 if (unpacked_SectionHeader.sh_name == RemoveSectionNameOffset):
566 RemoveIndex = Counter
567 Counter += 1
568 else:
569 Counter += 1
570 # Elf header is recombined.
571 # Elf header and program header table in front of first section are reserved.
572 # Elf header size is 0x34 with 32-bit object.
573 ElfHeaderSize = 52
574 ElfHandPH = ElfHeaderSize + (elf_header.e_phnum * elf_header.e_phentsize)
575 NewUPLEntry = UPLEntry[:ElfHandPH]
576 # Keep Section header and program header table, RemoveSection32() only recombined section and section header.
577 NewUPLEntry = bytearray(NewUPLEntry)
578 # Sections is recombined.
579 # 1. name of deleted section is removed in name string section.
580 # 2. deleted section is removed in dll file.
581 # 3. re-align sections before and after deleted section.
582 NewUPLEntrylen = []
583 for Index in range(0, (SectionHeaderEntryNumber)):
584 unpacked_SectionHeader = ElfSectionHeader32.unpack(SHentry[(Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
585 NewUPLEntrylen.append(len(NewUPLEntry))
586 if (Index == 0):
587 # Address alignment, section will align with alignment of next section.
588 AlignmentIndex = 8
589 if (SectionHeaderEntryNumber > 2):
590 unpacked_NextSectionHeader = ElfSectionHeader32.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
591 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
592 # Section in front of removed section
593 elif (Index + 1 == RemoveIndex):
594 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
595 # Read section address alignment
596 # If section that will be removed in .dll is not first and last one .
597 # Address alignment, section will align with alignment of section after deleted section.
598 # Check next and the section after next are not end of section.
599 if ((Index + 2) < (SectionHeaderEntryNumber - 1)):
600 unpacked_Next2SectionHeader = ElfSectionHeader32.unpack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
601 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_Next2SectionHeader.sh_addralign)
602 else:
603 # It is align 8 bytes if next section or the section after next is last one.
604 AlignmentIndex = 8
605 NewUPLEntry = SectionAlignment(NewUPLEntry, AlignmentIndex)
606 # section is Deleted section
607 elif (Index == RemoveIndex):
608 # Don't add removed section to elf.
609 # Find offset of section name.
610 RemoveNameOffset = unpacked_SectionHeader.sh_name
611 # section is name string section.
612 elif (Index == StringIndexNumber):
613 # StringIndex is String Index section
614 StringIndex = UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
615 # Remove name of removed section in name string section.
616 # Section header isn't exist if RemoveSectionNameOffset equal to -1.
617 StringIndex = bytearray(StringIndex)
618 RemoveSectionName = bytearray(RemoveSectionName, encoding='utf-8')
619 RemoveSectionName = RemoveSectionName + bytes('\0', encoding='utf-8')
620 StringIndex = StringIndex.replace(RemoveSectionName,b'')
621 NewUPLEntry += StringIndex
622 # other sections.
623 else:
624 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
625 # Address alignment, section will align with alignment of next section.
626 if (Index < (SectionHeaderEntryNumber - 1)):
627 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
628 else:
629 # If section is last one.
630 AlignmentIndex = 8
631 NewUPLEntry = SectionAlignment(NewUPLEntry, AlignmentIndex)
632 SectionHeaderOffset = len(NewUPLEntry)
633 # Add section header
634 for Number in range(0, (SectionHeaderEntryNumber)):
635 if (Number != RemoveIndex):
636 NewSHentry = AddSectionHeader32(SHentry, NewUPLEntrylen[Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionName, StringIndexNumber)
637 NewUPLEntry += NewSHentry
638 # Modify number of sections and offset of section header in Elf header.
639 elf_header.e_shoff = SectionHeaderOffset
640 elf_header.e_shnum -= 1
641 NewUPLEntry = elf_header.pack() + NewUPLEntry[52:]
642 # write to Elf.
643 with open(UniversalPayloadEntry,'wb') as f:
644 f.write(NewUPLEntry)
645
646def AddSection64(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBinary, Alignment):
647 with open(UniversalPayloadEntry,'rb+') as f:
648 UPLEntry = f.read()
649 fFileBinary = open(FileBinary, 'rb')
650 Binary_File = fFileBinary.read()
651 ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _, SectionHeaderEntrySize, _, _ = ElfHeaderParser(UPLEntry)
652 # Read section header entry
653 SHentry = UPLEntry[ElfHeaderOffset:]
654 # Elf header is recombined.
655 # Elf header and program header table in front of first section are reserved.
656 # Elf header is stored at 0x0-0x40 in 64-bits objects
657 elf_header = ElfHeader64(UPLEntry[:64])
658 # Elf header size is 0x40 with 64-bit object.
659 ElfHeaderSize = 64
660 ElfHandPH = ElfHeaderSize + (elf_header.e_phnum * elf_header.e_phentsize)
661 NewUPLEntry = UPLEntry[:ElfHandPH]
662 # Keep Section header and program header table, AddSection64() only recombined section and section header.
663 NewUPLEntry = bytearray(NewUPLEntry)
664 # Sections is recombined.
665 # 1. name of added section is added in name string section.
666 # 2. added section is added in dll file.
667 # 3. re-align sections before and after added section.
668 NewUPLEntrylen = []
669 StringIndexValue = 0
670 for Index in range(0, SectionHeaderEntryNumber):
671 NewUPLEntrylen.append(len(NewUPLEntry))
672 unpacked_SectionHeader = ElfSectionHeader64.unpack(SHentry[(Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
673 # Sections is recombined.
674 if (Index == 0):
675 # Address alignment, section will align with alignment of next section.
676 AlignmentIndex = 8
677 if (SectionHeaderEntryNumber > 2):
678 unpacked_NextSectionHeader = ElfSectionHeader64.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
679 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
680 # Section is last one.
681 elif (Index == (SectionHeaderEntryNumber - 1)):
682 # Add new section at the end.
683 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
684 NewUPLEntry = SectionAlignment(NewUPLEntry, Alignment)
685 LastUPLEntrylen = len(NewUPLEntry)
686 NewUPLEntry += Binary_File
687 # Address alignment, section will align with alignment of next section.
688 AlignmentIndex = 8
689 NewUPLEntry = SectionAlignment(NewUPLEntry, AlignmentIndex)
690 # section is name string section.
691 elif (Index == StringIndexNumber):
692 # StringIndex is String Index section
693 StringIndex = UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
694 # Read name of added Section after StringIndex is transform into string.
695 StringIndex = bytearray(StringIndex)
696 StringIndexValue = len(StringIndex)
697 AddSectionName = bytearray(AddSectionName, encoding='utf-8') + bytes('\0', encoding='utf-8')
698 StringIndex += AddSectionName
699 NewUPLEntry += StringIndex
700 # section after name string section but not last one.
701 elif ((Index > StringIndexNumber) and (Index < (SectionHeaderEntryNumber - 1))):
702 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
703 # Address alignment, section will align with alignment of next section.
704 unpacked_NextSectionHeader = ElfSectionHeader64.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
705 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
706 # Section before name string section.
707 else:
708 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
709 # Address alignment, section will align with alignment of next section.
710 if (Index < (SectionHeaderEntryNumber - 1)):
711 unpacked_NextSectionHeader = ElfSectionHeader64.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
712 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
713 SectionHeaderOffset = len(NewUPLEntry)
714 RemoveNameOffset = 0
715 # Add section header
716 for Number in range(0, (SectionHeaderEntryNumber)):
717 NewSHentry = AddSectionHeader64(SHentry, NewUPLEntrylen[Number], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, StringIndexNumber)
718 NewUPLEntry += NewSHentry
719 NewUPLEntry += bytearray(AddNewSectionEntry64(LastUPLEntrylen, StringIndexValue, len(Binary_File), Alignment))
720 # Modify number of sections and offset of section header in Elf header.
721 # Modify offset in in Elf header.
722 elf_header.e_shoff = SectionHeaderOffset
723 elf_header.e_shnum += 1
724 elf_header = elf_header.pack()
725 UPLEntryBin = elf_header + NewUPLEntry[64:]
726 # Modify offsets and address of program header table in elf.
727 PHSegmentName = '.text'
728 _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, _ = FindSection(UPLEntryBin, PHSegmentName)
729 UPLEntryBin = ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffset, PHSegmentName)
730 # Modify offsets and address of program header table in elf.
731 PHSegmentName = '.dynamic'
732 _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, _ = FindSection(UPLEntryBin, PHSegmentName)
733 UPLEntryBin = ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffset, PHSegmentName)
734 # Modify offsets and address of program header table in elf.
735 PHSegmentName = '.data'
736 _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, _ = FindSection(UPLEntryBin, PHSegmentName)
737 UPLEntryBin = ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffset, PHSegmentName)
738 fFileBinary.close()
739 return UPLEntryBin
740
741def AddSection32(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBinary, Alignment):
742 with open(UniversalPayloadEntry,'rb+') as f:
743 # Read Elf and binary which will be write to elf.
744 UPLEntry = f.read()
745 fFileBinary = open(FileBinary, 'rb')
746 Binary_File = fFileBinary.read()
747 ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _, SectionHeaderEntrySize, _, _ = ElfHeaderParser(UPLEntry)
748 # Read section header entry
749 SHentry = UPLEntry[ElfHeaderOffset:]
750 # Elf header is recombined.
751 # Elf header and program header table in front of first section are reserved.
752 # Elf header is stored at 0x0-0x34 in 32-bits objects
753 elf_header = ElfHeader32(UPLEntry[:52])
754 # Elf header size is 0x34 with 32-bit object.
755 ElfHeaderSize = 52
756 ElfHandPH = ElfHeaderSize + (elf_header.e_phnum * elf_header.e_phentsize)
757 NewUPLEntry = UPLEntry[:ElfHandPH]
758 # Keep Section header and program header table, AddSection32() only recombined section and section header.
759 NewUPLEntry = bytearray(NewUPLEntry)
760 # Sections is recombined.
761 # 1. name of added section is added in name string section.
762 # 2. added section is added in dll file.
763 # 3. re-align sections before and after added section.
764 NewUPLEntrylen = []
765 StringIndexValue = 0
766 for Index in range(0, SectionHeaderEntryNumber):
767 NewUPLEntrylen.append(len(NewUPLEntry))
768 unpacked_SectionHeader = ElfSectionHeader32.unpack(SHentry[(Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
769 # Sections is recombined.
770 if (Index == 0):
771 # Address alignment, section will align with alignment of next section.
772 AlignmentIndex = 8
773 if (SectionHeaderEntryNumber > 2):
774 unpacked_NextSectionHeader = ElfSectionHeader32.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
775 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
776 # Section is last one.
777 elif (Index == (SectionHeaderEntryNumber - 1)):
778 # Add new section at the end.
779 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
780 NewUPLEntry = SectionAlignment(NewUPLEntry, Alignment)
781 LastUPLEntrylen = len(NewUPLEntry)
782 NewUPLEntry += Binary_File
783 # Address alignment, section will align with alignment of next section.
784 AlignmentIndex = 8
785 NewUPLEntry = SectionAlignment(NewUPLEntry, AlignmentIndex)
786 # section is name string section.
787 elif (Index == StringIndexNumber):
788 # StringIndex is String Index section
789 StringIndex = UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
790 # Read name of added Section after StringIndex is transform into string.
791 StringIndex = bytearray(StringIndex)
792 StringIndexValue = len(StringIndex)
793 AddSectionName = bytearray(AddSectionName, encoding='utf-8') + bytes('\0', encoding='utf-8')
794 StringIndex += AddSectionName
795 NewUPLEntry += StringIndex
796 # section after name string section but not last one.
797 elif ((Index > StringIndexNumber) and (Index < (SectionHeaderEntryNumber - 1))):
798 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
799 # Address alignment, section will align with alignment of next section.
800 unpacked_NextSectionHeader = ElfSectionHeader32.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
801 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
802 # Section before name string section.
803 else:
804 NewUPLEntry += UPLEntry[unpacked_SectionHeader.sh_offset:(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]
805 # Address alignment, section will align with alignment of next section.
806 if (Index < (SectionHeaderEntryNumber - 1)):
807 unpacked_NextSectionHeader = ElfSectionHeader32.unpack(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeaderEntrySize) + SectionHeaderEntrySize)])
808 NewUPLEntry = SectionAlignment(NewUPLEntry, unpacked_NextSectionHeader.sh_addralign)
809 SectionHeaderOffset = len(NewUPLEntry)
810 RemoveNameOffset = 0
811 # Add section header
812 for Number in range(0, (SectionHeaderEntryNumber)):
813 NewSHentry = AddSectionHeader32(SHentry, NewUPLEntrylen[Number], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, StringIndexNumber)
814 NewUPLEntry += NewSHentry
815 NewUPLEntry += bytearray(AddNewSectionEntry32(LastUPLEntrylen, StringIndexValue, len(Binary_File), Alignment))
816 # Modify number of sections and offset of section header in Elf header.
817 # Modify offset in in Elf header.
818 elf_header.e_shoff = SectionHeaderOffset
819 elf_header.e_shnum += 1
820 PHTableSize = elf_header.e_phentsize
821 elf_header = elf_header.pack()
822 UPLEntryBin = elf_header + NewUPLEntry[52:]
823 # Modify offsets and address of program header table in elf.
824 PHSegmentName = '.text'
825 _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, _ = FindSection(UPLEntryBin, PHSegmentName)
826 UPLEntryBin = ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffset, PHSegmentName)
827 # Modify offsets and address of program header table in elf. Its are stored at 0x08-0x0F and 0x10-0x17
828 PHSegmentName = '.data'
829 _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, _ = FindSection(UPLEntryBin, PHSegmentName)
830 UPLEntryBin = ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffset, PHSegmentName)
831 fFileBinary.close()
832 return UPLEntryBin
833
834def ReplaceFv (UniversalPayloadEntry, FileBinary, AddSectionName, Alignment = 16):
835 with open(UniversalPayloadEntry,'rb+') as f:
836 UPLEntry = f.read()
837 SectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, _, StringIndexNumber, EI_CLASS = FindSection(UPLEntry, AddSectionName)
838 # If elf is 64-bit objects.
839 if (EI_CLASS == 2):
840 # Remove section if it exists.
841 if (SectionNameOffset != -1):
842 RemoveSection64(UniversalPayloadEntry, AddSectionName)
843 # Add section.
844 NewUPLEntry = AddSection64(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBinary, Alignment)
845 # If elf is 32-bit objects.
846 else:
847 # Remove section if it exists.
848 if (SectionNameOffset != -1):
849 RemoveSection32(UniversalPayloadEntry, AddSectionName)
850 # Add section.
851 NewUPLEntry = AddSection32(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBinary, Alignment)
852 with open(UniversalPayloadEntry,'wb') as f:
853 f.write(NewUPLEntry)
854 return 0
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette