From 665ff99504ab85f209bbec75a56f2465af5ac277 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 14 Feb 2025 14:10:35 +0100 Subject: [PATCH] Some GDI fixes --- src/common/platform/kernel_mapped.hpp | 2 +- src/common/platform/process.hpp | 5 ++++ src/windows-emulator/emulator_utils.hpp | 32 ++++++++++++++++++++----- src/windows-emulator/syscalls.cpp | 10 ++++++-- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/common/platform/kernel_mapped.hpp b/src/common/platform/kernel_mapped.hpp index 9a18cb21..2dae3215 100644 --- a/src/common/platform/kernel_mapped.hpp +++ b/src/common/platform/kernel_mapped.hpp @@ -289,7 +289,7 @@ typedef struct _PEB64 ULONG MaximumNumberOfHeaps; std::uint64_t** ProcessHeaps; // PHEAP - std::uint64_t* GdiSharedHandleTable; // PGDI_SHARED_MEMORY + std::uint64_t GdiSharedHandleTable; // PGDI_SHARED_MEMORY std::uint64_t* ProcessStarterHelper; ULONG GdiDCAttributeList; diff --git a/src/common/platform/process.hpp b/src/common/platform/process.hpp index 1c057788..8b989f65 100644 --- a/src/common/platform/process.hpp +++ b/src/common/platform/process.hpp @@ -846,8 +846,13 @@ struct GDI_HANDLE_ENTRY64 struct GDI_SHARED_MEMORY64 { GDI_HANDLE_ENTRY64 Handles[GDI_MAX_HANDLE_COUNT]; + char pad[0xC8]; + uint64_t Objects[0x20]; + uint64_t Data[0x200]; // ? }; +static_assert(offsetof(GDI_SHARED_MEMORY64, Objects) == 0x1800B0); + struct CLIENT_ID64 { DWORD64 UniqueProcess; diff --git a/src/windows-emulator/emulator_utils.hpp b/src/windows-emulator/emulator_utils.hpp index dfe5e5c6..11d87d01 100644 --- a/src/windows-emulator/emulator_utils.hpp +++ b/src/windows-emulator/emulator_utils.hpp @@ -117,14 +117,24 @@ class emulator_object } template - void access(const F& accessor, const size_t index = 0) const + void access_safe(const F& accessor, const size_t index = 0) const { - T obj{}; - this->memory_->read_memory(this->address_ + index * this->size(), &obj, sizeof(obj)); - - accessor(obj); + auto obj = std::make_unique(); + this->access_object(accessor, *obj, index); + } - this->write(obj, index); + template + void access(const F& accessor, const size_t index = 0) const + { + if constexpr (sizeof(T) < 0x4000) + { + T obj{}; + this->access_object(accessor, obj, index); + } + else + { + this->access_safe(accessor, index); + } } void serialize(utils::buffer_serializer& buffer) const @@ -145,6 +155,16 @@ class emulator_object private: memory_interface* memory_{}; uint64_t address_{}; + + template + void access_object(const F& accessor, T& obj, const size_t index = 0) const + { + this->memory_->read_memory(this->address_ + index * this->size(), &obj, sizeof(obj)); + + accessor(obj); + + this->write(obj, index); + } }; // TODO: warning emulator_utils is hardcoded for 64bit unicode_string usage diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index c539d4c3..98c2d45b 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -2669,8 +2669,14 @@ namespace c.proc.peb.access([&](PEB64& peb) { if (!peb.GdiSharedHandleTable) { - peb.GdiSharedHandleTable = reinterpret_cast::PVOID*>( - c.proc.base_allocator.reserve().ptr()); + const auto shared_memory = c.proc.base_allocator.reserve(); + + shared_memory.access([](GDI_SHARED_MEMORY64& mem) { + mem.Objects[0x12] = 1; + mem.Objects[0x13] = 1; + }); + + peb.GdiSharedHandleTable = shared_memory.value(); } });