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 |
|
---|
8 | import argparse
|
---|
9 | from ctypes import *
|
---|
10 | import struct
|
---|
11 |
|
---|
12 | class 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 |
|
---|
33 | class 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 |
|
---|
70 | class 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 |
|
---|
94 | class 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 |
|
---|
115 | class 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 |
|
---|
152 | class 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 |
|
---|
176 | def 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 |
|
---|
192 | def 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 |
|
---|
203 | def 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 |
|
---|
238 | def 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 |
|
---|
247 | def 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 |
|
---|
253 | def 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 |
|
---|
259 | def 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 |
|
---|
291 | def 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 |
|
---|
322 | def 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 |
|
---|
403 | def 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 |
|
---|
438 | def 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 |
|
---|
542 | def 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 |
|
---|
646 | def 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 |
|
---|
741 | def 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 |
|
---|
834 | def 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
|
---|