Support mapping non page-aligned binaries for SEC_IMAGE mappings.
This commit is contained in:
parent
2835633789
commit
646ab89f0a
|
@ -882,6 +882,41 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, DWORD total_size
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for non page-aligned binary */
|
||||||
|
|
||||||
|
if (nt->OptionalHeader.SectionAlignment <= page_mask)
|
||||||
|
{
|
||||||
|
/* unaligned sections, this happens for native subsystem binaries */
|
||||||
|
/* in that case Windows simply maps in the whole file */
|
||||||
|
|
||||||
|
if (map_file_into_view( view, fd, 0, total_size, 0, VPROT_COMMITTED | VPROT_READ,
|
||||||
|
removable ) != STATUS_SUCCESS) goto error;
|
||||||
|
|
||||||
|
/* check that all sections are loaded at the right offset */
|
||||||
|
for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
|
||||||
|
{
|
||||||
|
if (sec[i].VirtualAddress != sec[i].PointerToRawData)
|
||||||
|
goto error; /* Windows refuses to load in that case too */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the image protections */
|
||||||
|
VIRTUAL_SetProt( view, ptr, total_size,
|
||||||
|
VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
|
||||||
|
|
||||||
|
/* perform relocations if necessary */
|
||||||
|
/* FIXME: not 100% compatible, Windows doesn't do this for non page-aligned binaries */
|
||||||
|
if (ptr != base)
|
||||||
|
{
|
||||||
|
const IMAGE_DATA_DIRECTORY *relocs;
|
||||||
|
relocs = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||||
|
if (relocs->VirtualAddress && relocs->Size)
|
||||||
|
do_relocations( ptr, relocs, ptr - base, total_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* map all the sections */
|
/* map all the sections */
|
||||||
|
|
||||||
for (i = pos = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
|
for (i = pos = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
|
||||||
|
@ -994,11 +1029,6 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, DWORD total_size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!removable) /* don't keep handle open on removable media */
|
|
||||||
NtDuplicateObject( GetCurrentProcess(), hmapping,
|
|
||||||
GetCurrentProcess(), &view->mapping,
|
|
||||||
0, 0, DUPLICATE_SAME_ACCESS );
|
|
||||||
|
|
||||||
/* set the image protections */
|
/* set the image protections */
|
||||||
|
|
||||||
sec = (IMAGE_SECTION_HEADER*)((char *)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader);
|
sec = (IMAGE_SECTION_HEADER*)((char *)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader);
|
||||||
|
@ -1011,6 +1041,13 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, DWORD total_size
|
||||||
if (sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) vprot |= VPROT_EXEC;
|
if (sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) vprot |= VPROT_EXEC;
|
||||||
VIRTUAL_SetProt( view, ptr + sec->VirtualAddress, size, vprot );
|
VIRTUAL_SetProt( view, ptr + sec->VirtualAddress, size, vprot );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (!removable) /* don't keep handle open on removable media */
|
||||||
|
NtDuplicateObject( GetCurrentProcess(), hmapping,
|
||||||
|
GetCurrentProcess(), &view->mapping,
|
||||||
|
0, 0, DUPLICATE_SAME_ACCESS );
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &csVirtual );
|
RtlLeaveCriticalSection( &csVirtual );
|
||||||
|
|
||||||
*addr_ptr = ptr;
|
*addr_ptr = ptr;
|
||||||
|
|
|
@ -103,8 +103,10 @@ static void init_page_size(void)
|
||||||
#define ROUND_ADDR(addr) \
|
#define ROUND_ADDR(addr) \
|
||||||
((int)(addr) & ~page_mask)
|
((int)(addr) & ~page_mask)
|
||||||
|
|
||||||
#define ROUND_SIZE(addr,size) \
|
#define ROUND_SIZE_MASK(addr,size,mask) \
|
||||||
(((int)(size) + ((int)(addr) & page_mask) + page_mask) & ~page_mask)
|
(((int)(size) + ((int)(addr) & (mask)) + (mask)) & ~(mask))
|
||||||
|
|
||||||
|
#define ROUND_SIZE(addr,size) ROUND_SIZE_MASK( addr, size, page_mask )
|
||||||
|
|
||||||
|
|
||||||
/* find the shared PE mapping for a given mapping */
|
/* find the shared PE mapping for a given mapping */
|
||||||
|
@ -236,7 +238,8 @@ static int get_image_params( struct mapping *mapping )
|
||||||
mapping->size_low = ROUND_SIZE( 0, nt.OptionalHeader.SizeOfImage );
|
mapping->size_low = ROUND_SIZE( 0, nt.OptionalHeader.SizeOfImage );
|
||||||
mapping->size_high = 0;
|
mapping->size_high = 0;
|
||||||
mapping->base = (void *)nt.OptionalHeader.ImageBase;
|
mapping->base = (void *)nt.OptionalHeader.ImageBase;
|
||||||
mapping->header_size = ROUND_SIZE( mapping->base, nt.OptionalHeader.SizeOfHeaders );
|
mapping->header_size = ROUND_SIZE_MASK( mapping->base, nt.OptionalHeader.SizeOfHeaders,
|
||||||
|
nt.OptionalHeader.SectionAlignment - 1 );
|
||||||
mapping->protect = VPROT_IMAGE;
|
mapping->protect = VPROT_IMAGE;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
|
|
Loading…
Reference in New Issue