Repository: d3dave/cough

Issue:
Exception when adding an uninitialized section before an initialized section
file.py:133 is inconsistent with file.py:144

Discussion:

Patch:
diff --git a/cough/file.py b/cough/file.py
index 84338e7..d96aa8a 100644
--- a/cough/file.py
+++ b/cough/file.py
@@ -125,25 +125,17 @@ class ObjectModule:
         return bytes(body_buffer)
 
     def dump_sections(self):
+        data_buf_offset = FileHeader.struct.size + 40 * len(self.sections)
+        hdrs_buf = bytearray()
         data_buf = bytearray()
-        sections_offsets = []
-        reloc_offsets = []
         for sec in self.sections:
             if sec.data:
-                sections_offsets.append(len(data_buf))
+                sec.pointer_to_raw_data = data_buf_offset + len(data_buf)
                 data_buf += sec.data
             if sec.relocations:
-                reloc_offsets.append(len(data_buf))
+                sec.pointer_to_relocations = data_buf_offset + len(data_buf)
                 for reloc in sec.relocations:
                     data_buf += reloc.pack()
+            hdrs_buf += sec.get_header()
 
-        sections_buffer_offset = FileHeader.struct.size + 40 * len(self.sections)
-        hdrs_and_data_buf = bytearray()
-        for i, sec in enumerate(self.sections):
-            if sec.data:
-                sec.pointer_to_raw_data = sections_buffer_offset + sections_offsets[i]
-            if sec.relocations:
-                sec.pointer_to_relocations = sections_buffer_offset + reloc_offsets[i]
-            hdrs_and_data_buf += sec.get_header()
-        hdrs_and_data_buf += data_buf
-        return bytes(hdrs_and_data_buf)
+        return bytes(hdrs_buf + data_buf)


Test patch:
diff --git a/tests/test_coff.py b/tests/test_coff.py
index 8ca9ce4..2193214 100644
--- a/tests/test_coff.py
+++ b/tests/test_coff.py
@@ -63,3 +63,16 @@ def test_reloc():
     subprocess.run(['PowerShell.exe', BUILD_SCRIPT, file.name, '/out:' + '"' + exe_path + '"'], check=True)
     proc = subprocess.run([exe_path], stdout=subprocess.PIPE, check=True)
     assert proc.stdout == b'A'
+
+
+def test_uninit_before_init():
+    module = cough.ObjectModule()
+
+    sec_uninit = cough.Section(b'uninit', cough.SectionFlags.CNT_UNINITIALIZED_DATA)
+    sec_uninit.size_of_raw_data = 0x400
+    module.sections.append(sec_uninit)
+
+    sec_init = cough.Section(b'init', 0, b'\xAA\xBB\xCC\xDD')
+    module.sections.append(sec_init)
+
+    assert module.get_buffer()