Blame SOURCES/0001-generate_binary-Add-NX-COMPAT-flag-manually-when-gen.patch

75fbaf
From cfd61f6958a46d5e9687f87caf04c94680382a9f Mon Sep 17 00:00:00 2001
75fbaf
From: Nicolas Frayer <nfrayer@redhat.com>
75fbaf
Date: Wed, 1 Feb 2023 12:13:45 +0100
75fbaf
Subject: [PATCH] generate_binary: Add NX COMPAT flag manually when genpeimg
75fbaf
 missing
75fbaf
75fbaf
When genpeimg or python3-pefile is missing, add the NX COMPAT flag
75fbaf
manually by setting bit8 of the DllCharacteristics in the optional
75fbaf
header, clear the TimeDateStamp and update the checksum.
75fbaf
---
75fbaf
 efi/generate_binary.py | 50 ++++++++++++++++++++++++++++++++++++++++--
75fbaf
 1 file changed, 48 insertions(+), 2 deletions(-)
75fbaf
75fbaf
diff --git a/efi/generate_binary.py b/efi/generate_binary.py
75fbaf
index 7b802e7..10ab0b3 100755
75fbaf
--- a/efi/generate_binary.py
75fbaf
+++ b/efi/generate_binary.py
75fbaf
@@ -10,6 +10,13 @@
75fbaf
 import subprocess
75fbaf
 import sys
75fbaf
 import argparse
75fbaf
+import os
75fbaf
+import struct
75fbaf
+
75fbaf
+COFF_HDR_OFFSET = 0x80
75fbaf
+OPTIONALHDR_CHECKSUM = COFF_HDR_OFFSET + 0x58
75fbaf
+OPTIONALHDR_DLLCHARACTERISTICS = COFF_HDR_OFFSET + 0x5E
75fbaf
+PEHEADER_TIMEDATASTAMP = COFF_HDR_OFFSET + 0x8
75fbaf
 
75fbaf
 
75fbaf
 def _run_objcopy(args):
75fbaf
@@ -66,6 +73,27 @@ def _run_genpeimg(args):
75fbaf
         sys.exit(1)
75fbaf
 
75fbaf
 
75fbaf
+def generate_checksum(data):
75fbaf
+    checksum_offset: int = OPTIONALHDR_CHECKSUM
75fbaf
+    checksum: int = 0
75fbaf
+    remainder: int = len(data) % 4
75fbaf
+    data_len: int = len(data) + ((4 - remainder) * (remainder != 0))
75fbaf
+    for i in range(int(data_len / 4)):
75fbaf
+        if i == int(checksum_offset / 4):
75fbaf
+            continue
75fbaf
+        if i + 1 == (int(data_len / 4)) and remainder:
75fbaf
+            dword = struct.unpack("I", data[i * 4 :] + (b"\0" * (4 - remainder)))[0]
75fbaf
+        else:
75fbaf
+            dword = struct.unpack("I", data[i * 4 : i * 4 + 4])[0]
75fbaf
+        checksum += dword
75fbaf
+        if checksum >= 2**32:
75fbaf
+            checksum = (checksum & 0xFFFFFFFF) + (checksum >> 32)
75fbaf
+    checksum = (checksum & 0xFFFF) + (checksum >> 16)
75fbaf
+    checksum = checksum + (checksum >> 16)
75fbaf
+    checksum = checksum & 0xFFFF
75fbaf
+    return checksum + len(data)
75fbaf
+
75fbaf
+
75fbaf
 def _add_nx_pefile(args):
75fbaf
     # unnecessary if we have genpeimg
75fbaf
     if args.genpeimg:
75fbaf
@@ -73,8 +101,26 @@ def _add_nx_pefile(args):
75fbaf
     try:
75fbaf
         import pefile
75fbaf
     except ImportError:
75fbaf
-        print("Unable to add NX support to binaries without genpeimg or python3-pefile")
75fbaf
-        sys.exit(1)
75fbaf
+        print("Adding NX support manually to the binary")
75fbaf
+        with open(args.outfile, "r+b") as fh:
75fbaf
+            buf = bytearray(fh.read(os.path.getsize(args.outfile)))
75fbaf
+            fh.seek(0)
75fbaf
+            DllCharacteristics = struct.unpack_from(
75fbaf
+                "
75fbaf
+            )[0]
75fbaf
+            DllCharacteristics |= 0x100
75fbaf
+            struct.pack_into(
75fbaf
+                "
75fbaf
+            )
75fbaf
+
75fbaf
+            # set the timestamp to 0
75fbaf
+            struct.pack_into("
75fbaf
+
75fbaf
+            # as we have set the NX COMPAT bit, regenerate the checksum
75fbaf
+            struct.pack_into("
75fbaf
+            fh.write(buf)
75fbaf
+
75fbaf
+        return
75fbaf
 
75fbaf
     pe = pefile.PE(args.outfile)
75fbaf
     pe.OPTIONAL_HEADER.DllCharacteristics |= pefile.DLL_CHARACTERISTICS[
75fbaf
-- 
75fbaf
2.39.1
75fbaf