Hi list, while diving into wine sources i've noticed that wine does not apply relocation to section not aligned to page boundary. Is there any reason for this behaviour? If it is wrong i've put up a little patch that solves the issue.
Greetings, Alessandro Pignotti -- Vi Veri Veniversum Vivus Vici -Dr. Faustus - Marlowe Public GPG Key ID 0x650B3ED9 on subkeys.gpg.net Key Fingerprint 6243 AAD3 E3EC 52D8 DFAA 2A2F 9FCD 0457 650B 3ED9 Encrypted mails are welcome
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 21da9af..fec5c67 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1006,6 +1006,8 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz if (nt->OptionalHeader.SectionAlignment <= page_mask) { + IMAGE_BASE_RELOCATION *rel, *end; + const IMAGE_DATA_DIRECTORY *relocs; /* unaligned sections, this happens for native subsystem binaries */ /* in that case Windows simply maps in the whole file */ @@ -1024,7 +1026,26 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz VIRTUAL_SetProt( view, ptr, total_size, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC ); - /* no relocations are performed on non page-aligned binaries */ + if (!(nt->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)) + { + relocs = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + rel = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress); + end = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress + relocs->Size); + delta = ptr - base; + while (rel < end - 1 && rel->SizeOfBlock) + { + if (rel->VirtualAddress >= total_size) + { + WARN_(module)( "invalid address %p in relocation %p\n", ptr + rel->VirtualAddress, rel ); + status = STATUS_ACCESS_VIOLATION; + goto error; + } + rel = LdrProcessRelocationBlock( ptr + rel->VirtualAddress, + (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT), + (USHORT *)(rel + 1), delta ); + if (!rel) goto error; + } + } goto done; }
signature.asc
Description: This is a digitally signed message part.