Implement kernel32::FlushViewOfFile and ntdll::memset

This commit is contained in:
2025-10-15 18:33:26 -06:00
parent 0f3b98462e
commit 2e2128b4ac
4 changed files with 85 additions and 0 deletions

View File

@@ -400,6 +400,8 @@ void *resolveByName(const char *name) {
return (void *)kernel32::MapViewOfFileEx; return (void *)kernel32::MapViewOfFileEx;
if (strcmp(name, "UnmapViewOfFile") == 0) if (strcmp(name, "UnmapViewOfFile") == 0)
return (void *)kernel32::UnmapViewOfFile; return (void *)kernel32::UnmapViewOfFile;
if (strcmp(name, "FlushViewOfFile") == 0)
return (void *)kernel32::FlushViewOfFile;
if (strcmp(name, "DeleteFileA") == 0) if (strcmp(name, "DeleteFileA") == 0)
return (void *)kernel32::DeleteFileA; return (void *)kernel32::DeleteFileA;
if (strcmp(name, "DeleteFileW") == 0) if (strcmp(name, "DeleteFileW") == 0)

View File

@@ -708,6 +708,81 @@ BOOL WIN_FUNC UnmapViewOfFile(LPCVOID lpBaseAddress) {
return TRUE; return TRUE;
} }
BOOL WIN_FUNC FlushViewOfFile(LPCVOID lpBaseAddress, SIZE_T dwNumberOfBytesToFlush) {
HOST_CONTEXT_GUARD();
DEBUG_LOG("FlushViewOfFile(%p, %zu)\n", lpBaseAddress, dwNumberOfBytesToFlush);
if (!lpBaseAddress) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
uintptr_t address = reinterpret_cast<uintptr_t>(lpBaseAddress);
uintptr_t viewBase = 0;
size_t viewLength = 0;
uintptr_t allocationBase = 0;
size_t allocationLength = 0;
{
std::lock_guard guard(g_viewInfoMutex);
auto it = g_viewInfo.upper_bound(address);
if (it == g_viewInfo.begin()) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
--it;
const auto &view = it->second;
if (address < view.viewBase || address >= view.viewBase + view.viewLength) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
viewBase = view.viewBase;
viewLength = view.viewLength;
allocationBase = view.allocationBase;
allocationLength = view.allocationLength;
}
size_t offsetIntoView = static_cast<size_t>(address - viewBase);
size_t bytesToFlush = dwNumberOfBytesToFlush;
size_t maxFlush = viewLength - offsetIntoView;
if (bytesToFlush == 0 || bytesToFlush > maxFlush) {
bytesToFlush = maxFlush;
}
if (bytesToFlush == 0) {
return TRUE;
}
uintptr_t flushStart = address;
uintptr_t flushEnd = flushStart + bytesToFlush;
const size_t pageSize = systemPageSize();
uintptr_t alignedStart = alignDown(flushStart, pageSize);
uintptr_t alignedEnd = alignUp(flushEnd, pageSize);
if (alignedEnd == std::numeric_limits<uintptr_t>::max()) {
alignedEnd = flushEnd;
}
uintptr_t mappingEnd = allocationBase + allocationLength;
if (alignedEnd > mappingEnd) {
alignedEnd = mappingEnd;
}
if (alignedEnd < alignedStart) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
size_t length = static_cast<size_t>(alignedEnd - alignedStart);
if (length == 0) {
length = pageSize;
}
if (msync(reinterpret_cast<void *>(alignedStart), length, MS_SYNC) != 0) {
wibo::lastError = wibo::winErrorFromErrno(errno);
return FALSE;
}
return TRUE;
}
LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) { LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("VirtualAlloc(%p, %zu, %u, %u)\n", lpAddress, dwSize, flAllocationType, flProtect); DEBUG_LOG("VirtualAlloc(%p, %zu, %u, %u)\n", lpAddress, dwSize, flAllocationType, flProtect);

View File

@@ -26,6 +26,7 @@ LPVOID WIN_FUNC MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess,
LPVOID WIN_FUNC MapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, LPVOID WIN_FUNC MapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress); DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress);
BOOL WIN_FUNC UnmapViewOfFile(LPCVOID lpBaseAddress); BOOL WIN_FUNC UnmapViewOfFile(LPCVOID lpBaseAddress);
BOOL WIN_FUNC FlushViewOfFile(LPCVOID lpBaseAddress, SIZE_T dwNumberOfBytesToFlush);
LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
BOOL WIN_FUNC VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType); BOOL WIN_FUNC VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);

View File

@@ -124,6 +124,11 @@ namespace ntdll {
constexpr LARGE_INTEGER FILE_WRITE_TO_END_OF_FILE = static_cast<LARGE_INTEGER>(-1); constexpr LARGE_INTEGER FILE_WRITE_TO_END_OF_FILE = static_cast<LARGE_INTEGER>(-1);
constexpr LARGE_INTEGER FILE_USE_FILE_POINTER_POSITION = static_cast<LARGE_INTEGER>(-2); constexpr LARGE_INTEGER FILE_USE_FILE_POINTER_POSITION = static_cast<LARGE_INTEGER>(-2);
void *WIN_ENTRY memset(void *dest, int ch, size_t count) {
VERBOSE_LOG("ntdll::memset(%p, %i, %zu)\n", dest, ch, count);
return std::memset(dest, ch, count);
}
NTSTATUS WIN_FUNC NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, NTSTATUS WIN_FUNC NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset,
PULONG Key) { PULONG Key) {
@@ -420,6 +425,8 @@ static void *resolveByName(const char *name) {
return (void *)ntdll::RtlGetVersion; return (void *)ntdll::RtlGetVersion;
if (strcmp(name, "NtQueryInformationProcess") == 0) if (strcmp(name, "NtQueryInformationProcess") == 0)
return (void *)ntdll::NtQueryInformationProcess; return (void *)ntdll::NtQueryInformationProcess;
if (strcmp(name, "memset") == 0)
return (void *)ntdll::memset;
return nullptr; return nullptr;
} }