Skip to content

Commit

Permalink
[hack] ntdll: Fix SKSE usage for Skyrim/Fallout4
Browse files Browse the repository at this point in the history
These are patches to get Fallout 4 Script Extender working in wine. f4se
allocates memory for trampolines in the spaces before the Fallout4 exe
image and the f4se dll image. These patches:

1. Fix VirtualQuery rejecting any blocks before the image as already
   allocated (it looks like get_free_mem_state_callback sees blocks before
   the exe base address as overlapping the exe base from calculating the
   block end address as block start address + size, ie a 256 byte block
   starting at 0x100 would "end" at 0x200).

2. Switches dlls not loaded at their preferred address to be loaded at high
   addresses rather than low ones to work around code in f4se that gives up
   allocating the trampolines (it compares the address being queried to a
   lowest acceptable address computed by subtracting 0x78000000 from the
   module address, which will wrap around and fail with lower addresses
   even if there's free space).

Apparently these patches also get SkyrimSE script extender working, but I
don't own that so I can't test that.

Github-Link: https://github.com/hdmap/wine-hackery/tree/master/f4se
Github-Link: ValveSoftware#7
Github-Link: ValveSoftware/Proton#170
Signed-off-by: Kai Krakow <kai@kaishome.de>
  • Loading branch information
hdmap authored and kakra committed Feb 4, 2019
1 parent a254200 commit 1d8a1f3
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions dlls/ntdll/virtual.c
Original file line number Diff line number Diff line change
Expand Up @@ -1387,11 +1387,11 @@ static NTSTATUS map_image( HANDLE hmapping, ACCESS_MASK access, int fd, SIZE_T m
server_enter_uninterrupted_section( &csVirtual, &sigset );

if (base >= (char *)address_space_start) /* make sure the DOS area remains free */
status = map_view( &view, base, total_size, mask, FALSE, SEC_IMAGE | SEC_FILE |
status = map_view( &view, base, total_size, mask, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY );

if (status != STATUS_SUCCESS)
status = map_view( &view, NULL, total_size, mask, FALSE, SEC_IMAGE | SEC_FILE |
status = map_view( &view, NULL, total_size, mask, TRUE, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY );

if (status != STATUS_SUCCESS) goto error;
Expand Down Expand Up @@ -2774,7 +2774,7 @@ static int get_free_mem_state_callback( void *start, size_t size, void *arg )
MEMORY_BASIC_INFORMATION *info = arg;
void *end = (char *)start + size;

if ((char *)info->BaseAddress + info->RegionSize < (char *)start) return 0;
if ((char *)info->BaseAddress + info->RegionSize <= (char *)start) return 0;

if (info->BaseAddress >= end)
{
Expand Down

0 comments on commit 1d8a1f3

Please sign in to comment.