8000 [ENV] Refactored file-mapping handling by ksco · Pull Request #2612 · ptitSeb/box64 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[ENV] Refactored file-mapping handling #2612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/tools/env.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "fileutils.h"
#include "box64context.h"
#include "rbtree.h"
#include "wine_tools.h"
#include "pe_tools.h"

box64env_t box64env = { 0 };

Expand Down Expand Up @@ -614,6 +616,10 @@ void RecordEnvMappings(uintptr_t addr, size_t length, int fd)
mapping_t* mapping = NULL;
khint_t k = kh_get(mapping_entry, mapping_entries, lowercase_filename);
if(k == kh_end(mapping_entries)) {
// First time we see this file
if (box64_wine && BOX64ENV(unityplayer)) DetectUnityPlayer(lowercase_filename+1);
if (box64_wine && BOX64ENV(dynarec_volatile_metadata)) ParseVolatileMetadata(fullname, (void*)addr);

mapping = box_calloc(1, sizeof(mapping_t));
mapping->filename = box_strdup(lowercase_filename);
mapping->fullname = box_strdup(fullname);
Expand Down
75 changes: 24 additions & 51 deletions src/tools/pe_tools.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,19 +187,9 @@ typedef struct _IMAGE_VOLATILE_RANGE_METADATA {
KHASH_SET_INIT_STR(string);
KHASH_SET_INIT_INT64(volatileopcode);

static kh_string_t* dllNames = NULL; // never freed
static kh_volatileopcode_t* volatileOpcodes = NULL; // never freed

static rbtree_t* volatileRanges = NULL; // never freed

static int HasSuffix(const char* str, const char* suffix)
{
size_t lenstr = strlen(str);
size_t lensuffix = strlen(suffix);
if (lensuffix > lenstr) return 0;
return strcmp(str + lenstr - lensuffix, suffix) == 0;
}

DWORD RVAToFileOffset(PIMAGE_SECTION_HEADER sections, DWORD numberOfSections, DWORD rva, BYTE* fileBuffer, size_t fileSize)
{
for (DWORD i = 0; i < numberOfSections; i++) {
Expand All @@ -216,12 +206,6 @@ DWORD RVAToFileOffset(PIMAGE_SECTION_HEADER sections, DWORD numberOfSections, DW

void ParseVolatileMetadata(char* filename, void* addr)
{
if (!filename) return;
if (!HasSuffix(filename, ".dll")) {
return;
}

if (!dllNames) dllNames = kh_init(string);
if (!volatileOpcodes) volatileOpcodes = kh_init(volatileopcode);
if (!volatileRanges) volatileRanges = rbtree_init("volatileRanges");

Expand All @@ -231,14 +215,31 @@ void ParseVolatileMetadata(char* filename, void* addr)
else
baseName++;

khint_t k = kh_get(string, dllNames, baseName);
if (k != kh_end(dllNames)) return;
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)addr;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) return;

PIMAGE_NT_HEADERS64 ntHeaders64 = (PIMAGE_NT_HEADERS64)(addr + dosHeader->e_lfanew);
if (ntHeaders64->Signature != IMAGE_NT_SIGNATURE || ntHeaders64->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) return;

int numberOfSections = ntHeaders64->FileHeader.NumberOfSections;
if (numberOfSections <= 0) {
return;
}
IMAGE_DATA_DIRECTORY loadConfigDir = ntHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
if (loadConfigDir.VirtualAddress == 0 || loadConfigDir.Size == 0) {
return;
}

int ret;
k = kh_put(string, dllNames, strdup(baseName), &ret);
PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)((void*)ntHeaders64 + sizeof(IMAGE_NT_HEADERS64)); // immediately follows the optional header, if any.
DWORD loadConfigOffset = RVAToFileOffset(sectionHeaders, numberOfSections, loadConfigDir.VirtualAddress, (BYTE*)addr, ntHeaders64->OptionalHeader.SizeOfImage);
if (loadConfigOffset == 0) {
return;
}

FILE* file = fopen(filename, "rb");
if (!file) return;
if (!file) {
return;
}

fseek(file, 0, SEEK_END);
long size = ftell(file);
Expand All @@ -257,36 +258,6 @@ void ParseVolatileMetadata(char* filename, void* addr)
}
fclose(file);

IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)buffer;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
free(buffer);
return;
}

PIMAGE_NT_HEADERS64 ntHeaders64 = (PIMAGE_NT_HEADERS64)(buffer + dosHeader->e_lfanew);
if (ntHeaders64->Signature != IMAGE_NT_SIGNATURE || ntHeaders64->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
free(buffer);
return;
}

int numberOfSections = ntHeaders64->FileHeader.NumberOfSections;
if (numberOfSections <= 0) {
free(buffer);
return;
}
IMAGE_DATA_DIRECTORY loadConfigDir = ntHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
if (loadConfigDir.VirtualAddress == 0 || loadConfigDir.Size == 0) {
free(buffer);
return;
}

PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)((void*)ntHeaders64 + sizeof(IMAGE_NT_HEADERS64)); // immediately follows the optional header, if any.
DWORD loadConfigOffset = RVAToFileOffset(sectionHeaders, numberOfSections, loadConfigDir.VirtualAddress, (BYTE*)buffer, ntHeaders64->OptionalHeader.SizeOfImage);
if (loadConfigOffset == 0) {
free(buffer);
return;
}

PIMAGE_LOAD_CONFIG_DIRECTORY64 loadConfig = (PIMAGE_LOAD_CONFIG_DIRECTORY64)(buffer + loadConfigOffset);
if (loadConfig->Size < offsetof(IMAGE_LOAD_CONFIG_DIRECTORY64, VolatileMetadataPointer) + sizeof(ULONGLONG)) {
free(buffer);
Expand Down Expand Up @@ -342,6 +313,8 @@ void ParseVolatileMetadata(char* filename, void* addr)
printf_log(LOG_DEBUG, "Volatile range metadata [%d]: %08lX-%08lX\n", i, rva, rva + size);
}
}
free(buffer);
return;
}

int VolatileRangesContains(uintptr_t addr)
Expand Down
16 changes: 7 additions & 9 deletions src/tools/wine_tools.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,14 @@ void dynarec_wine_prereserve()
void DetectUnityPlayer(char* filename)
{
static int unityplayer_detected = 0;
if (!filename && BOX64ENV(unityplayer) && !unityplayer_detected) {
if (strlen(filename) > strlen("UnityPlayer.dll") && !strcasecmp(filename + strlen(filename) - strlen("UnityPlayer.dll"), "UnityPlayer.dll")) {
printf_log(LOG_NONE, "Detected UnityPlayer.dll\n");
if (filename && BOX64ENV(unityplayer) && !unityplayer_detected && !strcmp(filename, "unityplayer.dll")) {
printf_log(LOG_INFO, "Detected UnityPlayer.dll\n");
#ifdef DYNAREC
if (!BOX64ENV(dynarec_strongmem)) {
SET_BOX64ENV(dynarec_strongmem, 1);
PrintEnvVariables(&box64env, LOG_INFO);
}
#endif
unityplayer_detected = 1;
if (!BOX64ENV(dynarec_strongmem)) {
SET_BOX64ENV(dynarec_strongmem, 1);
PrintEnvVariables(&box64env, LOG_INFO);
}
#endif
unityplayer_detected = 1;
}
}
12 changes: 1 addition & 11 deletions src/wrapped/wrappedlibc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3032,17 +3032,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, size_t length, int prot, int f
}
#endif
if(ret!=MAP_FAILED) {
if(emu && !(flags&MAP_ANONYMOUS) && (fd>0)) {
if ((box64_wine && BOX64ENV(dynarec_volatile_metadata)) || BOX64ENV(unityplayer)) {
char filename[4096];
char buf[128];
sprintf(buf, "/proc/self/fd/%d", fd);
ssize_t r = readlink(buf, filename, sizeof(filename) - 1);
if (r != -1) filename[r] = 0;

if (BOX64ENV(unityplayer)) DetectUnityPlayer(filename);
if (box64_wine && BOX64ENV(dynarec_volatile_metadata)) ParseVolatileMetadata(filename, addr);
}
if (emu && !(flags & MAP_ANONYMOUS) && (fd > 0)) {
// the last_mmap will allow mmap created by wine, even those that have hole, to be fully tracked as one single mmap
if((ret>=last_mmap_addr[0]) && ret+length<(last_mmap_addr[0]+last_mmap_len[0]))
RecordEnvMappings((uintptr_t)last_mmap_addr[0], last_mmap_len[0], fd);
Expand Down
0