[PATCH] kernel32: Adjust data directories in UpdateResource API.

David Collett david.collett at gmail.com
Wed Nov 22 23:02:55 CST 2017


When adding resources to a PE file using the UpdateResource API and
the resource section is not the last section (i.e. we had to move
existing sections), ensure any data directory entries pointing into
moved sections is adjusted.

Fixes issue where binaries commonly have relocations section after
the resource section. If the resources section is extended, the
base relocations data directory entry will no longer be valid and
the binary will fail to be loaded (assuming relocation is required).

Signed-off-by: David Collett <david.collett at gmail.com>
---
 dlls/kernel32/resource.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/dlls/kernel32/resource.c b/dlls/kernel32/resource.c
index c88c921..d526b39 100644
--- a/dlls/kernel32/resource.c
+++ b/dlls/kernel32/resource.c
@@ -1615,15 +1615,29 @@ static BOOL write_raw_resources( QUEUEDUPDATES *updates )
         sec->SizeOfRawData = section_size;
         sec->Misc.VirtualSize = virtual_section_size;
         if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+            DWORD i;
             nt64->OptionalHeader.SizeOfImage += rva_delta;
             nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = sec->VirtualAddress;
             nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = res_size.total_size;
             nt64->OptionalHeader.SizeOfInitializedData = get_init_data_size( write_map->base, mapping_size );
+
+            for (i=0; i<nt64->OptionalHeader.NumberOfRvaAndSizes; i++) {
+                if (nt64->OptionalHeader.DataDirectory[i].VirtualAddress > sec->VirtualAddress) {
+                    nt64->OptionalHeader.DataDirectory[i].VirtualAddress += rva_delta;
+                }
+            }
         } else {
+            DWORD i;
             nt->OptionalHeader.SizeOfImage += rva_delta;
             nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = sec->VirtualAddress;
             nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = res_size.total_size;
             nt->OptionalHeader.SizeOfInitializedData = get_init_data_size( write_map->base, mapping_size );
+
+            for (i=0; i<nt->OptionalHeader.NumberOfRvaAndSizes; i++) {
+                if (nt->OptionalHeader.DataDirectory[i].VirtualAddress > sec->VirtualAddress) {
+                    nt->OptionalHeader.DataDirectory[i].VirtualAddress += rva_delta;
+                }
+            }
         }
     }
 
-- 
2.7.4




More information about the wine-devel mailing list