Tools: scripts: Add PIE support in firmware_version_decoder

Calculate pointer offset for PIE (Position Independent Executables) binaries.

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
This commit is contained in:
Patrick José Pereira 2021-08-25 15:14:41 -04:00 committed by Andrew Tridgell
parent bcfb07b39f
commit 47d2021780

View File

@ -6,6 +6,7 @@ import sys
import struct import struct
from argparse import ArgumentParser from argparse import ArgumentParser
from dataclasses import dataclass from dataclasses import dataclass
from elftools.elf.elffile import ELFFile
from typing import Any from typing import Any
@ -137,6 +138,7 @@ class Decoder:
self.fwversion = FWVersion() self.fwversion = FWVersion()
self.byteorder = "" self.byteorder = ""
self.pointer_size = 0 self.pointer_size = 0
self.elffile = None
def unpack(self, struct_format: str) -> Any: def unpack(self, struct_format: str) -> Any:
struct_format = f"{self.byteorder}{struct_format}" struct_format = f"{self.byteorder}{struct_format}"
@ -151,6 +153,9 @@ class Decoder:
if address == 0: if address == 0:
return "" return ""
# Calculate address offset for PIE (Position Independent Executables) binaries
address = next(self.elffile.address_offsets(address))
current_address = self.bytesio.seek(0, io.SEEK_CUR) current_address = self.bytesio.seek(0, io.SEEK_CUR)
self.bytesio.seek(address) self.bytesio.seek(address)
string = [] string = []
@ -193,8 +198,10 @@ class Decoder:
self.fwversion.os_hash_string = self.unpack_string_from_pointer() self.fwversion.os_hash_string = self.unpack_string_from_pointer()
def process(self, filename) -> None: def process(self, filename) -> None:
with open(filename, "rb") as file: # We need the file open for ELFFile
data = file.read() file = open(filename, "rb")
data = file.read()
self.elffile = ELFFile(file)
if not data: if not data:
raise RuntimeError("Failed to find FWVersion.") raise RuntimeError("Failed to find FWVersion.")