diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97a6d831..5f06e03d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -151,6 +151,7 @@ jobs: fail-fast: false matrix: platform: + - Windows x86 - Windows x86_64 - Linux x86_64 GCC - Linux x86_64 GCC Sanitizer @@ -168,8 +169,12 @@ jobs: preset: debug - configuration: Release preset: release + - platform: Windows x86 + runner: windows-latest + devcmd_arch: x86 - platform: Windows x86_64 runner: windows-latest + devcmd_arch: x64 - platform: Linux x86_64 GCC Sanitizer runner: ubuntu-24.04 cmake-options: "-DMOMO_ENABLE_SANITIZER=On" @@ -224,6 +229,8 @@ jobs: - name: Enable Developer Command Prompt uses: ilammy/msvc-dev-cmd@v1.13.0 if: ${{ startsWith(matrix.platform, 'Windows') }} + with: + arch: ${{ matrix.devcmd_arch }} - uses: nttld/setup-ndk@v1 id: setup-ndk @@ -262,6 +269,7 @@ jobs: fail-fast: false matrix: platform: + - Windows x86 - Windows x86_64 - Linux x86_64 GCC - Linux x86_64 GCC Sanitizer @@ -283,6 +291,8 @@ jobs: preset: debug - configuration: Release preset: release + - platform: Windows x86 + runner: windows-latest - platform: Windows x86_64 runner: windows-latest - platform: Linux x86_64 GCC @@ -336,6 +346,7 @@ jobs: run: cp build/${{matrix.preset}}/artifacts/test-sample.exe build/${{matrix.preset}}/artifacts/root/filesys/c/ - name: CMake Test + if: ${{ matrix.emulator != 'Icicle' || matrix.platform != 'Windows x86' }} run: cd build/${{matrix.preset}} && ctest --verbose -j env: EMULATOR_ROOT: ${{github.workspace}}/build/${{matrix.preset}}/artifacts/root diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a8713ad..4492d05c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,7 @@ if (NOT MOMO_BUILD_AS_LIBRARY) add_subdirectory(fuzzing-engine) add_subdirectory(fuzzer) add_subdirectory(windows-emulator-test) - if(WIN32) + if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8) momo_add_subdirectory_and_get_targets("tools" TOOL_TARGETS) momo_targets_set_folder("tools" ${TOOL_TARGETS}) diff --git a/src/analyzer/object_watching.hpp b/src/analyzer/object_watching.hpp index df8ab871..4d700d4c 100644 --- a/src/analyzer/object_watching.hpp +++ b/src/analyzer/object_watching.hpp @@ -10,7 +10,7 @@ emulator_hook* watch_object(windows_emulator& emu, const std::set info{}; return emu.emu().hook_memory_read( - object.value(), object.size(), + object.value(), static_cast(object.size()), [i = std::move(info), object, &emu, cache_logging, modules](const uint64_t address, const void*, size_t) { const auto rip = emu.emu().read_instruction_pointer(); const auto* mod = emu.mod_manager.find_by_address(rip); @@ -33,6 +33,7 @@ emulator_hook* watch_object(windows_emulator& emu, const std::setname.c_str() : ""); + i.get_member_name(static_cast(offset)).c_str(), rip, + mod ? mod->name.c_str() : ""); }); } diff --git a/src/analyzer/reflect_type_info.hpp b/src/analyzer/reflect_type_info.hpp index 0bfd8075..0a6059a9 100644 --- a/src/analyzer/reflect_type_info.hpp +++ b/src/analyzer/reflect_type_info.hpp @@ -11,9 +11,18 @@ #pragma clang diagnostic ignored "-Wunused-private-field" #endif +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4308) +#endif + #include "reflect_extension.hpp" #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #if defined(__clang__) #pragma clang diagnostic pop #endif diff --git a/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt b/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt index 4836948a..73ea9f1d 100644 --- a/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt +++ b/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt @@ -13,7 +13,9 @@ endif() set(CARGO_TRIPLE) set(CARGO_OPTIONS) -if(CMAKE_SYSTEM_NAME STREQUAL "iOS") +if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4) + set(CARGO_TRIPLE "i686-pc-windows-msvc") +elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") set(CARGO_TRIPLE "aarch64-apple-ios") elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") diff --git a/src/backends/unicorn-emulator/unicorn_x64_emulator.cpp b/src/backends/unicorn-emulator/unicorn_x64_emulator.cpp index cd8a94cb..955fca63 100644 --- a/src/backends/unicorn-emulator/unicorn_x64_emulator.cpp +++ b/src/backends/unicorn-emulator/unicorn_x64_emulator.cpp @@ -207,8 +207,8 @@ namespace unicorn #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif - - uce(uc_ctl_set_tcg_buffer_size(this->uc_, 2 << 30 /* 2 gb */)); + constexpr auto is_64_bit = sizeof(void*) >= 8; + uce(uc_ctl_set_tcg_buffer_size(this->uc_, (is_64_bit ? 2 : 1) << 30 /* 2 gb */)); #ifndef OS_WINDOWS #pragma GCC diagnostic pop @@ -264,8 +264,8 @@ namespace unicorn struct msr_value { - uint32_t id; - uint64_t value; + uint64_t id{}; + uint64_t value{}; }; msr_value msr_val{ diff --git a/src/common/platform/compiler.hpp b/src/common/platform/compiler.hpp index 34c1cc4d..5cece6a8 100644 --- a/src/common/platform/compiler.hpp +++ b/src/common/platform/compiler.hpp @@ -2,6 +2,13 @@ #if defined(_WIN32) || defined(_WIN64) #define OS_WINDOWS + +#if defined(_WIN64) +#define OS_WINDOWS_64 +#else +#define OS_WINDOWS_32 +#endif + #elif defined(__APPLE__) || defined(__MACH__) #define OS_MAC #elif defined(__linux__) diff --git a/src/common/platform/kernel_mapped.hpp b/src/common/platform/kernel_mapped.hpp index 83dd548e..931c5d35 100644 --- a/src/common/platform/kernel_mapped.hpp +++ b/src/common/platform/kernel_mapped.hpp @@ -19,13 +19,13 @@ typedef struct _EMU_NT_TIB64 { - struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList; - std::uint64_t* StackBase; - std::uint64_t* StackLimit; - std::uint64_t* SubSystemTib; - std::uint64_t* FibreData; - std::uint64_t* ArbitraryUserPointer; - struct _EMU_NT_TIB64* Self; + EMULATOR_CAST(std::uint64_t, struct _EXCEPTION_REGISTRATION_RECORD*) ExceptionList; + std::uint64_t StackBase; + std::uint64_t StackLimit; + std::uint64_t SubSystemTib; + std::uint64_t FibreData; + std::uint64_t ArbitraryUserPointer; + EMULATOR_CAST(std::uint64_t, struct _EMU_NT_TIB64*) Self; } EMU_NT_TIB64; typedef EMU_NT_TIB64* PEMU_NT_TIB64; @@ -51,8 +51,8 @@ union PEB_BITFIELD_UNION typedef struct _LIST_ENTRY64 { - struct _LIST_ENTRY* Flink; - struct _LIST_ENTRY* Blink; + ULONGLONG Flink; + ULONGLONG Blink; } LIST_ENTRY64, *PLIST_ENTRY64, *RESTRICTED_POINTER PRLIST_ENTRY64; #endif @@ -65,17 +65,14 @@ typedef struct _PEB_LDR_DATA64 LIST_ENTRY64 InLoadOrderModuleList; LIST_ENTRY64 InMemoryOrderModuleList; LIST_ENTRY64 InInitializationOrderModuleList; - std::uint64_t* EntryInProgress; + std::uint64_t EntryInProgress; BOOLEAN ShutdownInProgress; EmulatorTraits::HANDLE ShutdownThreadId; } PEB_LDR_DATA64, *PPEB_LDR_DATA64; -typedef struct _STRING64 -{ - USHORT Length; - USHORT MaximumLength; - char16_t* Buffer; -} STRING64, *PSTRING64, ANSI_STRING64, *PANSI_STRING64, OEM_STRING64, *POEM_STRING64; +using STRING64 = UNICODE_STRING>; +using ANSI_STRING64 = STRING64; +using OEM_STRING64 = STRING64; typedef struct _RTL_DRIVE_LETTER_CURDIR64 { @@ -118,7 +115,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS64 UNICODE_STRING> DllPath; UNICODE_STRING> ImagePathName; UNICODE_STRING> CommandLine; - std::uint64_t* Environment; + std::uint64_t Environment; ULONG StartingX; ULONG StartingY; @@ -136,21 +133,23 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS64 UNICODE_STRING> RuntimeData; ARRAY_CONTAINER CurrentDirectories; - std::uint64_t* EnvironmentSize; - std::uint64_t* EnvironmentVersion; + std::uint64_t EnvironmentSize; + std::uint64_t EnvironmentVersion; - std::uint64_t* PackageDependencyData; + std::uint64_t PackageDependencyData; ULONG ProcessGroupId; ULONG LoaderThreads; UNICODE_STRING> RedirectionDllName; // REDSTONE4 UNICODE_STRING> HeapPartitionName; // 19H1 - std::uint64_t* DefaultThreadpoolCpuSetMasks; + std::uint64_t DefaultThreadpoolCpuSetMasks; ULONG DefaultThreadpoolCpuSetMaskCount; ULONG DefaultThreadpoolThreadMaximum; ULONG HeapMemoryTypeMask; // WIN11 } RTL_USER_PROCESS_PARAMETERS64, *PRTL_USER_PROCESS_PARAMETERS64; +static_assert(sizeof(RTL_USER_PROCESS_PARAMETERS64) == 0x448); + union PEB_CROSS_PROCESS_FLAGS_UNION { ULONG CrossProcessFlags; @@ -171,8 +170,8 @@ union PEB_CROSS_PROCESS_FLAGS_UNION union PEB_KERNEL_CALLBACK_TABLE_UNION64 { - void* KernelCallbackTable; - void* UserSharedInfoPtr; + std::uint64_t KernelCallbackTable; + std::uint64_t UserSharedInfoPtr; }; typedef struct _API_SET_NAMESPACE @@ -188,9 +187,9 @@ typedef struct _API_SET_NAMESPACE union PEB_CONTEXT_DATA_UNION64 { - void* pContextData; // WIN7 - void* pUnused; // WIN10 - void* EcCodeBitMap; // WIN11 + std::uint64_t pContextData; // WIN7 + std::uint64_t pUnused; // WIN10 + std::uint64_t EcCodeBitMap; // WIN11 }; union PEB_TRACING_FLAGS_UNION @@ -229,18 +228,18 @@ typedef struct _CPTABLEINFO USHORT TransUniDefaultChar; USHORT DBCSCodePage; UCHAR LeadByte[MAXIMUM_LEADBYTES]; - USHORT* MultiByteTable; - void* WideCharTable; - USHORT* DBCSRanges; - USHORT* DBCSOffsets; + EMULATOR_CAST(uint64_t, USHORT*) MultiByteTable; + EMULATOR_CAST(uint64_t, void*) WideCharTable; + EMULATOR_CAST(uint64_t, USHORT*) DBCSRanges; + EMULATOR_CAST(uint64_t, USHORT*) DBCSOffsets; } CPTABLEINFO, *PCPTABLEINFO; typedef struct _NLSTABLEINFO { CPTABLEINFO OemTableInfo; CPTABLEINFO AnsiTableInfo; - USHORT* UpperCaseTable; - USHORT* LowerCaseTable; + EMULATOR_CAST(uint64_t, USHORT*) UpperCaseTable; + EMULATOR_CAST(uint64_t, USHORT*) LowerCaseTable; } NLSTABLEINFO, *PNLSTABLEINFO; typedef struct _PEB64 @@ -253,26 +252,26 @@ typedef struct _PEB64 EmulatorTraits::HANDLE Mutant; std::uint64_t ImageBaseAddress; - PPEB_LDR_DATA64 Ldr; - PRTL_USER_PROCESS_PARAMETERS64 ProcessParameters; - std::uint64_t* SubSystemData; - std::uint64_t* ProcessHeap; - EMULATOR_CAST(void*, PRTL_CRITICAL_SECTION) FastPebLock; - EMULATOR_CAST(void*, PSLIST_HEADER) AtlThunkSListPtr; - std::uint64_t* IFEOKey; + EMULATOR_CAST(std::uint64_t, PPEB_LDR_DATA64) Ldr; + EMULATOR_CAST(std::uint64_t, PRTL_USER_PROCESS_PARAMETERS64) ProcessParameters; + std::uint64_t SubSystemData; + std::uint64_t ProcessHeap; + EMULATOR_CAST(std::uint64_t, PRTL_CRITICAL_SECTION) FastPebLock; + EMULATOR_CAST(std::uint64_t, PSLIST_HEADER) AtlThunkSListPtr; + std::uint64_t IFEOKey; PEB_CROSS_PROCESS_FLAGS_UNION CrossProcessFlags; PEB_KERNEL_CALLBACK_TABLE_UNION64 KernelCallbackTable; ULONG SystemReserved; ULONG AtlThunkSListPtr32; - PAPI_SET_NAMESPACE ApiSetMap; + EMULATOR_CAST(std::uint64_t, PAPI_SET_NAMESPACE) ApiSetMap; ULONG TlsExpansionCounter; - EMULATOR_CAST(void*, PRTL_BITMAP) TlsBitmap; + EMULATOR_CAST(std::uint64_t, PRTL_BITMAP) TlsBitmap; ARRAY_CONTAINER TlsBitmapBits; // TLS_MINIMUM_AVAILABLE - void* ReadOnlySharedMemoryBase; - EMULATOR_CAST(void*, PSILO_USER_SHARED_DATA) SharedData; // HotpatchInformation - std::uint64_t** ReadOnlyStaticServerData; + std::uint64_t ReadOnlySharedMemoryBase; + EMULATOR_CAST(std::uint64_t, PSILO_USER_SHARED_DATA) SharedData; // HotpatchInformation + std::uint64_t ReadOnlyStaticServerData; EMULATOR_CAST(EmulatorTraits::PVOID, PCPTABLEINFO) AnsiCodePageData; // PCPTABLEINFO EMULATOR_CAST(EmulatorTraits::PVOID, PCPTABLEINFO) OemCodePageData; // PCPTABLEINFO @@ -289,13 +288,13 @@ typedef struct _PEB64 ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; - std::uint64_t** ProcessHeaps; // PHEAP + std::uint64_t ProcessHeaps; // PHEAP std::uint64_t GdiSharedHandleTable; // PGDI_SHARED_MEMORY - std::uint64_t* ProcessStarterHelper; + std::uint64_t ProcessStarterHelper; ULONG GdiDCAttributeList; - EMULATOR_CAST(void*, PRTL_CRITICAL_SECTION) LoaderLock; + EMULATOR_CAST(std::uint64_t, PRTL_CRITICAL_SECTION) LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; @@ -307,30 +306,30 @@ typedef struct _PEB64 ULONG ImageSubsystemMinorVersion; EMULATOR_CAST(std::uint64_t, KAFFINITY) ActiveProcessAffinityMask; ARRAY_CONTAINER GdiHandleBuffer; - std::uint64_t* PostProcessInitRoutine; + std::uint64_t PostProcessInitRoutine; - EMULATOR_CAST(void*, PRTL_BITMAP) TlsExpansionBitmap; + EMULATOR_CAST(std::uint64_t, PRTL_BITMAP) TlsExpansionBitmap; ARRAY_CONTAINER TlsExpansionBitmapBits; // TLS_EXPANSION_SLOTS ULONG SessionId; ULARGE_INTEGER AppCompatFlags; // KACF_* ULARGE_INTEGER AppCompatFlagsUser; - std::uint64_t* pShimData; - std::uint64_t* AppCompatInfo; // APPCOMPAT_EXE_DATA + std::uint64_t pShimData; + std::uint64_t AppCompatInfo; // APPCOMPAT_EXE_DATA UNICODE_STRING> CSDVersion; - EMULATOR_CAST(void*, PACTIVATION_CONTEXT_DATA) ActivationContextData; - EMULATOR_CAST(void*, PASSEMBLY_STORAGE_MAP) ProcessAssemblyStorageMap; - EMULATOR_CAST(void*, PACTIVATION_CONTEXT_DATA) SystemDefaultActivationContextData; - EMULATOR_CAST(void*, PASSEMBLY_STORAGE_MAP) SystemAssemblyStorageMap; + EMULATOR_CAST(std::uint64_t, PACTIVATION_CONTEXT_DATA) ActivationContextData; + EMULATOR_CAST(std::uint64_t, PASSEMBLY_STORAGE_MAP) ProcessAssemblyStorageMap; + EMULATOR_CAST(std::uint64_t, PACTIVATION_CONTEXT_DATA) SystemDefaultActivationContextData; + EMULATOR_CAST(std::uint64_t, PASSEMBLY_STORAGE_MAP) SystemAssemblyStorageMap; - EMULATOR_CAST(std::int64_t, SIZE_T) MinimumStackCommit; + EMULATOR_CAST(std::uint64_t, SIZE_T) MinimumStackCommit; - ARRAY_CONTAINER SparePointers; // 19H1 (previously FlsCallback to FlsHighIndex) - std::uint64_t* PatchLoaderData; - std::uint64_t* ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO + ARRAY_CONTAINER SparePointers; // 19H1 (previously FlsCallback to FlsHighIndex) + std::uint64_t PatchLoaderData; + std::uint64_t ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO ULONG AppModelFeatureState; ARRAY_CONTAINER SpareUlongs; @@ -340,40 +339,42 @@ typedef struct _PEB64 USHORT UseCaseMapping; USHORT UnusedNlsField; - std::uint64_t* WerRegistrationData; - std::uint64_t* WerShipAssertPtr; + std::uint64_t WerRegistrationData; + std::uint64_t WerShipAssertPtr; PEB_CONTEXT_DATA_UNION64 ContextData; - std::uint64_t* pImageHeaderHash; + std::uint64_t pImageHeaderHash; PEB_TRACING_FLAGS_UNION TracingFlags; ULONGLONG CsrServerReadOnlySharedMemoryBase; - EMULATOR_CAST(void*, PRTL_CRITICAL_SECTION) TppWorkerpListLock; + EMULATOR_CAST(std::uint64_t, PRTL_CRITICAL_SECTION) TppWorkerpListLock; LIST_ENTRY64 TppWorkerpList; - ARRAY_CONTAINER WaitOnAddressHashTable; - EMULATOR_CAST(void*, PTELEMETRY_COVERAGE_HEADER) TelemetryCoverageHeader; // REDSTONE3 + ARRAY_CONTAINER WaitOnAddressHashTable; + EMULATOR_CAST(std::uint64_t, PTELEMETRY_COVERAGE_HEADER) TelemetryCoverageHeader; // REDSTONE3 ULONG CloudFileFlags; ULONG CloudFileDiagFlags; // REDSTONE4 CHAR PlaceholderCompatibilityMode; ARRAY_CONTAINER PlaceholderCompatibilityModeReserved; - EMULATOR_CAST(void*, PLEAP_SECOND_DATA) LeapSecondData; // REDSTONE5 + EMULATOR_CAST(std::uint64_t, PLEAP_SECOND_DATA) LeapSecondData; // REDSTONE5 PEB_LEAP_SECONDS_FLAG_UNION LeapSecondFlags; ULONG NtGlobalFlag2; ULONGLONG ExtendedFeatureDisableMask; // since WIN11 } PEB64, *PPEB64; +static_assert(sizeof(PEB64) == 0x7D0); + typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME64 { struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous; - EMULATOR_CAST(void*, ACTIVATION_CONTEXT) ActivationContext; + EMULATOR_CAST(std::uint64_t, ACTIVATION_CONTEXT) ActivationContext; ULONG Flags; // RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_* } RTL_ACTIVATION_CONTEXT_STACK_FRAME64, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME64; typedef struct _ACTIVATION_CONTEXT_STACK64 { - PRTL_ACTIVATION_CONTEXT_STACK_FRAME64 ActiveFrame; + EMULATOR_CAST(std::uint64_t, PRTL_ACTIVATION_CONTEXT_STACK_FRAME64) ActiveFrame; LIST_ENTRY64 FrameListCache; ULONG Flags; // ACTIVATION_CONTEXT_STACK_FLAG_* ULONG NextCookieSequenceNumber; @@ -383,7 +384,7 @@ typedef struct _ACTIVATION_CONTEXT_STACK64 typedef struct _GDI_TEB_BATCH64 { ULONG Offset; - std::uint64_t* HDC; + std::uint64_t HDC; ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; } GDI_TEB_BATCH64, *PGDI_TEB_BATCH64; @@ -458,25 +459,25 @@ typedef struct _TEB64 { EMU_NT_TIB64 NtTib; - std::uint64_t* EnvironmentPointer; + std::uint64_t EnvironmentPointer; CLIENT_ID64 ClientId; - std::uint64_t* ActiveRpcHandle; - std::uint64_t* ThreadLocalStoragePointer; - PPEB64 ProcessEnvironmentBlock; + std::uint64_t ActiveRpcHandle; + std::uint64_t ThreadLocalStoragePointer; + EMULATOR_CAST(std::uint64_t, PPEB64) ProcessEnvironmentBlock; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; - std::uint64_t* CsrClientThread; - std::uint64_t* Win32ThreadInfo; + std::uint64_t CsrClientThread; + std::uint64_t Win32ThreadInfo; ARRAY_CONTAINER User32Reserved; ARRAY_CONTAINER UserReserved; - std::uint64_t* WOW32Reserved; + std::uint64_t WOW32Reserved; LCID CurrentLocale; ULONG FpSoftwareStatusRegister; - ARRAY_CONTAINER ReservedForDebuggerInstrumentation; - ARRAY_CONTAINER SystemReserved1; - std::uint64_t* HeapFlsData; - ARRAY_CONTAINER RngState; + ARRAY_CONTAINER ReservedForDebuggerInstrumentation; + ARRAY_CONTAINER SystemReserved1; + std::uint64_t HeapFlsData; + ARRAY_CONTAINER RngState; CHAR PlaceholderCompatibilityMode; BOOLEAN PlaceholderHydrationAlwaysExplicit; ARRAY_CONTAINER PlaceholderReserved; @@ -488,10 +489,10 @@ typedef struct _TEB64 NTSTATUS ExceptionCode; - PACTIVATION_CONTEXT_STACK64 ActivationContextStackPointer; - std::uint64_t* InstrumentationCallbackSp; - std::uint64_t* InstrumentationCallbackPreviousPc; - std::uint64_t* InstrumentationCallbackPreviousSp; + EMULATOR_CAST(std::uint64_t, PACTIVATION_CONTEXT_STACK64) ActivationContextStackPointer; + std::uint64_t InstrumentationCallbackSp; + std::uint64_t InstrumentationCallbackPreviousPc; + std::uint64_t InstrumentationCallbackPreviousSp; ULONG TxFsContext; BOOLEAN InstrumentationCallbackDisabled; BOOLEAN UnalignedLoadStoreExceptions; @@ -500,90 +501,92 @@ typedef struct _TEB64 EmulatorTraits::HANDLE GdiCachedProcessHandle; ULONG GdiClientPID; ULONG GdiClientTID; - std::uint64_t* GdiThreadLocalInfo; - ARRAY_CONTAINER Win32ClientInfo; + std::uint64_t GdiThreadLocalInfo; + ARRAY_CONTAINER Win32ClientInfo; - ARRAY_CONTAINER glDispatchTable; - ARRAY_CONTAINER glReserved1; - std::uint64_t* glReserved2; - std::uint64_t* glSectionInfo; - std::uint64_t* glSection; - std::uint64_t* glTable; - std::uint64_t* glCurrentRC; - std::uint64_t* glContext; + ARRAY_CONTAINER glDispatchTable; + ARRAY_CONTAINER glReserved1; + std::uint64_t glReserved2; + std::uint64_t glSectionInfo; + std::uint64_t glSection; + std::uint64_t glTable; + std::uint64_t glCurrentRC; + std::uint64_t glContext; NTSTATUS LastStatusValue; UNICODE_STRING> StaticUnicodeString; ARRAY_CONTAINER StaticUnicodeBuffer; - std::uint64_t* DeallocationStack; + std::uint64_t DeallocationStack; - ARRAY_CONTAINER TlsSlots; + ARRAY_CONTAINER TlsSlots; LIST_ENTRY64 TlsLinks; - std::uint64_t* Vdm; - std::uint64_t* ReservedForNtRpc; - ARRAY_CONTAINER DbgSsReserved; + std::uint64_t Vdm; + std::uint64_t ReservedForNtRpc; + ARRAY_CONTAINER DbgSsReserved; ULONG HardErrorMode; - ARRAY_CONTAINER Instrumentation; + ARRAY_CONTAINER Instrumentation; GUID ActivityId; - std::uint64_t* SubProcessTag; - std::uint64_t* PerflibData; - std::uint64_t* EtwTraceData; - std::uint64_t* WinSockData; + std::uint64_t SubProcessTag; + std::uint64_t PerflibData; + std::uint64_t EtwTraceData; + std::uint64_t WinSockData; ULONG GdiBatchCount; TEB_CURRENT_IDEAL_PROCESSOR_UNION CurrentIdealProcessor; ULONG GuaranteedStackBytes; - std::uint64_t* ReservedForPerf; - std::uint64_t* ReservedForOle; // tagSOleTlsData + std::uint64_t ReservedForPerf; + std::uint64_t ReservedForOle; // tagSOleTlsData ULONG WaitingOnLoaderLock; - std::uint64_t* SavedPriorityState; - std::uint64_t* ReservedForCodeCoverage; - std::uint64_t* ThreadPoolData; - std::uint64_t** TlsExpansionSlots; - std::uint64_t* ChpeV2CpuAreaInfo; // CHPEV2_CPUAREA_INFO // previously DeallocationBStore - std::uint64_t* Unused; // previously BStoreLimit + std::uint64_t SavedPriorityState; + std::uint64_t ReservedForCodeCoverage; + std::uint64_t ThreadPoolData; + std::uint64_t TlsExpansionSlots; + std::uint64_t ChpeV2CpuAreaInfo; // CHPEV2_CPUAREA_INFO // previously DeallocationBStore + std::uint64_t Unused; // previously BStoreLimit ULONG MuiGeneration; ULONG IsImpersonating; - std::uint64_t* NlsCache; - std::uint64_t* pShimData; + std::uint64_t NlsCache; + std::uint64_t pShimData; ULONG HeapData; EmulatorTraits::HANDLE CurrentTransactionHandle; - EMULATOR_CAST(void*, PTEB_ACTIVE_FRAME) ActiveFrame; - std::uint64_t* FlsData; + EMULATOR_CAST(std::uint64_t, PTEB_ACTIVE_FRAME) ActiveFrame; + std::uint64_t FlsData; - std::uint64_t* PreferredLanguages; - std::uint64_t* UserPrefLanguages; - std::uint64_t* MergedPrefLanguages; + std::uint64_t PreferredLanguages; + std::uint64_t UserPrefLanguages; + std::uint64_t MergedPrefLanguages; ULONG MuiImpersonation; TEB_CROSS_TEB_FLAGS_UNION CrossTebFlags; TEB_SAME_TEB_FLAGS_UNION SameTebFlags; - std::uint64_t* TxnScopeEnterCallback; - std::uint64_t* TxnScopeExitCallback; - std::uint64_t* TxnScopeContext; + std::uint64_t TxnScopeEnterCallback; + std::uint64_t TxnScopeExitCallback; + std::uint64_t TxnScopeContext; ULONG LockCount; LONG WowTebOffset; - std::uint64_t* ResourceRetValue; - std::uint64_t* ReservedForWdf; + std::uint64_t ResourceRetValue; + std::uint64_t ReservedForWdf; ULONGLONG ReservedForCrt; GUID EffectiveContainerId; ULONGLONG LastSleepCounter; // Win11 ULONG SpinCallCount; ULONGLONG ExtendedFeatureDisableMask; - std::uint64_t* SchedulerSharedDataSlot; // 24H2 - std::uint64_t* HeapWalkContext; + std::uint64_t SchedulerSharedDataSlot; // 24H2 + std::uint64_t HeapWalkContext; EMU_GROUP_AFFINITY64 PrimaryGroupAffinity; ARRAY_CONTAINER Rcu; } TEB64, *PTEB64; -#ifdef OS_WINDOWS +static_assert(sizeof(TEB64) == 0x1878); + +#if defined(OS_WINDOWS) && defined(_WIN64) inline TEB64* NtCurrentTeb64() { return reinterpret_cast(__readgsqword(FIELD_OFFSET(EMU_NT_TIB64, Self))); @@ -838,7 +841,7 @@ struct PS_ATTRIBUTE typename Traits::PVOID ValuePtr; }; - typename Traits::SIZE_T* ReturnLength; + EMULATOR_CAST(uint64_t, typename Traits::SIZE_T*) ReturnLength; }; template @@ -862,7 +865,7 @@ typedef struct _SYSTEM_TIMEOFDAY_INFORMATION64 typedef struct _PROCESS_BASIC_INFORMATION64 { NTSTATUS ExitStatus; - PPEB64 PebBaseAddress; + EMULATOR_CAST(uint64_t, PPEB64) PebBaseAddress; EMULATOR_CAST(std::uint64_t, KAFFINITY) AffinityMask; EMULATOR_CAST(std::uint32_t, KPRIORITY) BasePriority; EMULATOR_CAST(std::uint64_t, HANDLE) UniqueProcessId; @@ -883,7 +886,7 @@ struct THREAD_TLS_INFO union { - EmulatorTraits::PVOID* TlsVector; + EmulatorTraits::PVOID TlsVector; EmulatorTraits::PVOID TlsModulePointer; }; diff --git a/src/common/platform/memory.hpp b/src/common/platform/memory.hpp index bf213b91..8f6023cd 100644 --- a/src/common/platform/memory.hpp +++ b/src/common/platform/memory.hpp @@ -66,8 +66,8 @@ typedef enum _SECTION_INHERIT typedef struct DECLSPEC_ALIGN(16) _EMU_MEMORY_BASIC_INFORMATION64 { - void* BaseAddress; - void* AllocationBase; + uint64_t BaseAddress; + uint64_t AllocationBase; DWORD AllocationProtect; WORD PartitionId; std::int64_t RegionSize; @@ -78,7 +78,7 @@ typedef struct DECLSPEC_ALIGN(16) _EMU_MEMORY_BASIC_INFORMATION64 typedef struct _MEMORY_IMAGE_INFORMATION64 { - void* ImageBase; + uint64_t ImageBase; std::int64_t SizeOfImage; union @@ -98,7 +98,7 @@ typedef struct _MEMORY_IMAGE_INFORMATION64 typedef struct _MEMORY_REGION_INFORMATION { - void* AllocationBase; + uint64_t AllocationBase; ULONG AllocationProtect; union diff --git a/src/common/platform/process.hpp b/src/common/platform/process.hpp index 85b1a1a0..e02d8f99 100644 --- a/src/common/platform/process.hpp +++ b/src/common/platform/process.hpp @@ -553,13 +553,15 @@ struct SYSTEM_PROCESSOR_INFORMATION64 ULONG ProcessorFeatureBits; }; -#ifndef OS_WINDOWS +#if !defined(OS_WINDOWS) || !defined(_WIN64) +#if !defined(OS_WINDOWS) typedef struct _M128A { ULONGLONG Low; LONGLONG High; } M128A, *PM128A; +#endif typedef struct _XMM_SAVE_AREA32 { diff --git a/src/common/platform/threading.hpp b/src/common/platform/threading.hpp index de430220..4fe7deaf 100644 --- a/src/common/platform/threading.hpp +++ b/src/common/platform/threading.hpp @@ -76,7 +76,7 @@ struct THREAD_NAME_INFORMATION typedef struct _THREAD_BASIC_INFORMATION64 { NTSTATUS ExitStatus; - PTEB64 TebBaseAddress; + EMULATOR_CAST(uint64_t, PTEB64) TebBaseAddress; CLIENT_ID64 ClientId; EMULATOR_CAST(std::uint64_t, KAFFINITY) AffinityMask; EMULATOR_CAST(std::uint32_t, KPRIORITY) Priority; diff --git a/src/emulator/serialization.hpp b/src/emulator/serialization.hpp index 981d3b51..8bf66af7 100644 --- a/src/emulator/serialization.hpp +++ b/src/emulator/serialization.hpp @@ -378,7 +378,7 @@ namespace utils { const auto size = this->read(); result.clear(); - result.reserve(size); + result.reserve(static_cast(size)); for (uint64_t i = 0; i < size; ++i) { @@ -447,7 +447,7 @@ namespace utils const auto size = this->read(); result.clear(); - result.reserve(size); + result.reserve(static_cast(size)); for (uint64_t i = 0; i < size; ++i) { diff --git a/src/fuzzer/main.cpp b/src/fuzzer/main.cpp index 237d357c..24f9fc9f 100644 --- a/src/fuzzer/main.cpp +++ b/src/fuzzer/main.cpp @@ -5,6 +5,10 @@ #include "utils/finally.hpp" +#ifdef _MSC_VER +#pragma warning(disable : 4702) +#endif + bool use_gdb = false; namespace @@ -63,12 +67,6 @@ namespace utils::buffer_deserializer deserializer{emulator_data}; emu.deserialize(deserializer); emu.save_snapshot(); - - const auto ret = emu.emu().read_stack(0); - - emu.emu().hook_memory_execution(ret, [&](uint64_t) { - emu.emu().stop(); // - }); } void restore_emulator() @@ -87,8 +85,9 @@ namespace restore_emulator(); - const auto memory = emu.memory.allocate_memory(page_align_up(std::max(data.size(), static_cast(1))), - memory_permission::read_write); + const auto memory = emu.memory.allocate_memory( + static_cast(page_align_up(std::max(data.size(), static_cast(1)))), + memory_permission::read_write); emu.emu().write_memory(memory, data.data(), data.size()); emu.emu().reg(x64_register::rcx, memory); diff --git a/src/tools/dump-apiset/dump-apiset.cpp b/src/tools/dump-apiset/dump-apiset.cpp index 548e0bec..8b18741f 100644 --- a/src/tools/dump-apiset/dump-apiset.cpp +++ b/src/tools/dump-apiset/dump-apiset.cpp @@ -22,7 +22,7 @@ int main() printf("------------\n\n"); const auto peb = static_cast(GetCurrentProcessPeb()); - const auto api_set_map = peb->ApiSetMap; + const auto api_set_map = reinterpret_cast(peb->ApiSetMap); printf("APISET: 0x%p\n", api_set_map); printf("Version: %d\n", api_set_map->Version); diff --git a/src/windows-emulator-test/CMakeLists.txt b/src/windows-emulator-test/CMakeLists.txt index 7bf36845..8bea4b26 100644 --- a/src/windows-emulator-test/CMakeLists.txt +++ b/src/windows-emulator-test/CMakeLists.txt @@ -16,7 +16,7 @@ target_link_libraries(windows-emulator-test PRIVATE windows-emulator ) -if(WIN32) +if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8) add_dependencies(windows-emulator-test test-sample) endif() diff --git a/src/windows-emulator-test/emulation_test.cpp b/src/windows-emulator-test/emulation_test.cpp index dc600f92..d5c60363 100644 --- a/src/windows-emulator-test/emulation_test.cpp +++ b/src/windows-emulator-test/emulation_test.cpp @@ -34,7 +34,7 @@ namespace test constexpr auto offset = 1; const auto instructionsToExecute = executedInstructions - offset; - new_emu.start(instructionsToExecute); + new_emu.start(static_cast(instructionsToExecute)); ASSERT_EQ(new_emu.get_executed_instructions(), instructionsToExecute); ASSERT_NOT_TERMINATED(new_emu); diff --git a/src/windows-emulator-test/emulation_test_utils.hpp b/src/windows-emulator-test/emulation_test_utils.hpp index 5437aec1..a399702c 100644 --- a/src/windows-emulator-test/emulation_test_utils.hpp +++ b/src/windows-emulator-test/emulation_test_utils.hpp @@ -155,7 +155,7 @@ namespace test return s1.get_diff(s2).has_value(); }; - if (!has_diff_after_count(limit)) + if (!has_diff_after_count(static_cast(limit))) { puts("Emulation has no diff"); } @@ -170,7 +170,7 @@ namespace test const auto diff = (upper_bound - lower_bound); const auto pivot = lower_bound + (diff / 2); - const auto has_diff = has_diff_after_count(pivot); + const auto has_diff = has_diff_after_count(static_cast(pivot)); auto* bound = has_diff ? &upper_bound : &lower_bound; *bound = pivot; @@ -178,7 +178,7 @@ namespace test printf("Bounds: %" PRIx64 " - %" PRIx64 "\n", lower_bound, upper_bound); } - (void)get_state_for_count(lower_bound); + (void)get_state_for_count(static_cast(lower_bound)); const auto rip = emu.emu().read_instruction_pointer(); diff --git a/src/windows-emulator/apiset/apiset.cpp b/src/windows-emulator/apiset/apiset.cpp index d0b32c7e..53492205 100644 --- a/src/windows-emulator/apiset/apiset.cpp +++ b/src/windows-emulator/apiset/apiset.cpp @@ -57,12 +57,13 @@ namespace apiset { switch (location) { -#ifdef OS_WINDOWS +#ifdef OS_WINDOWS_64 case location::host: { - const auto apiSetMap = - reinterpret_cast(NtCurrentTeb64()->ProcessEnvironmentBlock->ApiSetMap); - const auto* dataPtr = reinterpret_cast(apiSetMap); - return {dataPtr, dataPtr + apiSetMap->Size}; + const auto* teb = NtCurrentTeb64(); + const auto* peb = reinterpret_cast(teb->ProcessEnvironmentBlock); + const auto* api_set_map = reinterpret_cast(peb->ApiSetMap); + const auto* data_ptr = reinterpret_cast(api_set_map); + return {data_ptr, data_ptr + api_set_map->Size}; } #else case location::host: diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index 144bcbcd..c3f86a34 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -93,7 +93,7 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context& suspended(suspended), last_registers(context.default_register_set) { - this->stack_base = memory.allocate_memory(this->stack_size, memory_permission::read_write); + this->stack_base = memory.allocate_memory(static_cast(this->stack_size), memory_permission::read_write); this->gs_segment = emulator_allocator{ memory, @@ -111,10 +111,10 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context& teb_obj.ClientId.UniqueProcess = 1ul; teb_obj.ClientId.UniqueThread = static_cast(this->id); - teb_obj.NtTib.StackLimit = reinterpret_cast(this->stack_base); - teb_obj.NtTib.StackBase = reinterpret_cast(this->stack_base + this->stack_size); - teb_obj.NtTib.Self = &this->teb->ptr()->NtTib; - teb_obj.ProcessEnvironmentBlock = context.peb.ptr(); + teb_obj.NtTib.StackLimit = this->stack_base; + teb_obj.NtTib.StackBase = this->stack_base + this->stack_size; + teb_obj.NtTib.Self = this->teb->value(); + teb_obj.ProcessEnvironmentBlock = context.peb.value(); }); } @@ -214,7 +214,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context& throw std::runtime_error("Missing GS segment"); } - setup_stack(emu, this->stack_base, this->stack_size); + setup_stack(emu, this->stack_base, static_cast(this->stack_size)); emu.set_segment_base(x64_register::gs, this->gs_segment->get_base()); CONTEXT64 ctx{}; diff --git a/src/windows-emulator/emulator_thread.hpp b/src/windows-emulator/emulator_thread.hpp index eab80c8c..07e3ed12 100644 --- a/src/windows-emulator/emulator_thread.hpp +++ b/src/windows-emulator/emulator_thread.hpp @@ -227,7 +227,7 @@ class emulator_thread : public ref_counted_object throw std::runtime_error("Emulator was never assigned!"); } - this->memory_ptr->release_memory(this->stack_base, this->stack_size); + this->memory_ptr->release_memory(this->stack_base, static_cast(this->stack_size)); this->stack_base = 0; } diff --git a/src/windows-emulator/emulator_utils.hpp b/src/windows-emulator/emulator_utils.hpp index b0e71ece..ba0932be 100644 --- a/src/windows-emulator/emulator_utils.hpp +++ b/src/windows-emulator/emulator_utils.hpp @@ -95,11 +95,6 @@ class emulator_object return this->value() + this->size(); } - T* ptr() const - { - return reinterpret_cast(this->address_); - } - explicit operator bool() const { return this->address_ != 0; @@ -221,11 +216,11 @@ class emulator_allocator return emulator_object(*this->memory_, potential_start); } - char16_t* copy_string(const std::u16string_view str) + uint64_t copy_string(const std::u16string_view str) { UNICODE_STRING> uc_str{}; this->make_unicode_string(uc_str, str); - return reinterpret_cast(uc_str.Buffer); + return uc_str.Buffer; } void make_unicode_string(UNICODE_STRING>& result, const std::u16string_view str, @@ -300,7 +295,8 @@ class emulator_allocator { if (this->address_ && this->size_) { - manager.release_memory(this->address_, this->size_); + // TODO: Make all sizes uint64_t + manager.release_memory(this->address_, static_cast(this->size_)); this->address_ = 0; this->size_ = 0; } @@ -356,7 +352,7 @@ inline std::u16string read_unicode_string(const emulator& emu, return read_unicode_string(emu, ucs); } -inline std::u16string read_unicode_string(emulator& emu, const UNICODE_STRING>* uc_string) +inline std::u16string read_unicode_string(emulator& emu, const uint64_t uc_string) { return read_unicode_string(emu, emulator_object>>{emu, uc_string}); } diff --git a/src/windows-emulator/exception_dispatch.cpp b/src/windows-emulator/exception_dispatch.cpp index 96c5b9e8..b3bd0b3f 100644 --- a/src/windows-emulator/exception_dispatch.cpp +++ b/src/windows-emulator/exception_dispatch.cpp @@ -33,7 +33,7 @@ namespace } record_obj.access([&](exception_record& r) { - r.ExceptionRecord = reinterpret_cast::PVOID>(nested_record_obj.ptr()); + r.ExceptionRecord = nested_record_obj.value(); // }); } @@ -109,7 +109,7 @@ namespace assert(total_size >= allocation_size); std::vector zero_memory{}; - zero_memory.resize(total_size, 0); + zero_memory.resize(static_cast(total_size), 0); emu.write_memory(new_sp, zero_memory.data(), zero_memory.size()); diff --git a/src/windows-emulator/kusd_mmio.cpp b/src/windows-emulator/kusd_mmio.cpp index 856d7187..95eadfa5 100644 --- a/src/windows-emulator/kusd_mmio.cpp +++ b/src/windows-emulator/kusd_mmio.cpp @@ -144,7 +144,7 @@ void kusd_mmio::read(const uint64_t addr, void* data, const size_t size) const auto real_size = valid_end - addr; const auto* kusd_buffer = reinterpret_cast(&this->kusd_); - memcpy(data, kusd_buffer + addr, real_size); + memcpy(data, kusd_buffer + addr, static_cast(real_size)); } uint64_t kusd_mmio::address() diff --git a/src/windows-emulator/memory_manager.cpp b/src/windows-emulator/memory_manager.cpp index 7c1a3de8..98268bef 100644 --- a/src/windows-emulator/memory_manager.cpp +++ b/src/windows-emulator/memory_manager.cpp @@ -22,9 +22,10 @@ namespace const auto first_length = split_point - i->first; const auto second_length = i->second.length - first_length; - i->second.length = first_length; + i->second.length = static_cast(first_length); - regions[split_point] = memory_manager::committed_region{second_length, i->second.permissions}; + regions[split_point] = + memory_manager::committed_region{static_cast(second_length), i->second.permissions}; } } } @@ -312,8 +313,8 @@ bool memory_manager::commit_memory(const uint64_t address, const size_t size, co if (map_length > 0) { - this->map_memory(map_start, map_length, permissions); - committed_regions[map_start] = committed_region{map_length, permissions}; + this->map_memory(map_start, static_cast(map_length), permissions); + committed_regions[map_start] = committed_region{static_cast(map_length), permissions}; } last_region_start = sub_region.first; @@ -326,8 +327,8 @@ bool memory_manager::commit_memory(const uint64_t address, const size_t size, co const auto map_start = last_region ? (last_region_start + last_region->length) : address; const auto map_length = end - map_start; - this->map_memory(map_start, map_length, permissions); - committed_regions[map_start] = committed_region{map_length, permissions}; + this->map_memory(map_start, static_cast(map_length), permissions); + committed_regions[map_start] = committed_region{static_cast(map_length), permissions}; } merge_regions(committed_regions); @@ -398,7 +399,7 @@ bool memory_manager::release_memory(const uint64_t address, size_t size) size = entry->second.length; } - size = page_align_up(size); + size = static_cast(page_align_up(size)); if (size > entry->second.length) { @@ -498,7 +499,7 @@ region_info memory_manager::get_region_info(const uint64_t address) { region_info result{}; result.start = MIN_ALLOCATION_ADDRESS; - result.length = MAX_ALLOCATION_ADDRESS - result.start; + result.length = static_cast(MAX_ALLOCATION_ADDRESS - result.start); result.permissions = memory_permission::none; result.initial_permissions = memory_permission::none; result.allocation_base = {}; @@ -514,7 +515,7 @@ region_info memory_manager::get_region_info(const uint64_t address) auto upper_bound = this->reserved_regions_.upper_bound(address); if (upper_bound == this->reserved_regions_.begin()) { - result.length = upper_bound->first - result.start; + result.length = static_cast(upper_bound->first - result.start); return result; } @@ -523,7 +524,7 @@ region_info memory_manager::get_region_info(const uint64_t address) if (lower_end <= address) { result.start = lower_end; - result.length = MAX_ALLOCATION_ADDRESS - result.start; + result.length = static_cast(MAX_ALLOCATION_ADDRESS - result.start); return result; } @@ -546,7 +547,7 @@ region_info memory_manager::get_region_info(const uint64_t address) auto committed_bound = committed_regions.upper_bound(address); if (committed_bound == committed_regions.begin()) { - result.length = committed_bound->first - result.start; + result.length = static_cast(committed_bound->first - result.start); return result; } @@ -555,7 +556,7 @@ region_info memory_manager::get_region_info(const uint64_t address) if (committed_lower_end <= address) { result.start = committed_lower_end; - result.length = lower_end - result.start; + result.length = static_cast(lower_end - result.start); return result; } diff --git a/src/windows-emulator/module/module_manager.cpp b/src/windows-emulator/module/module_manager.cpp index 3c1b10d4..6e20e135 100644 --- a/src/windows-emulator/module/module_manager.cpp +++ b/src/windows-emulator/module/module_manager.cpp @@ -107,7 +107,7 @@ mapped_module* module_manager::map_module(const windows_path& file, const logger mapped_module* module_manager::map_local_module(const std::filesystem::path& file, const logger& logger, const bool is_static) { - auto local_file = canonical(absolute(file)); + auto local_file = weakly_canonical(absolute(file)); for (auto& mod : this->modules_ | std::views::values) { diff --git a/src/windows-emulator/module/module_mapping.cpp b/src/windows-emulator/module/module_mapping.cpp index 939705e8..84c3ccd0 100644 --- a/src/windows-emulator/module/module_mapping.cpp +++ b/src/windows-emulator/module/module_mapping.cpp @@ -10,9 +10,9 @@ namespace uint64_t get_first_section_offset(const PENTHeaders_t& nt_headers, const uint64_t nt_headers_offset) { const auto* nt_headers_addr = reinterpret_cast(&nt_headers); - size_t optional_header_offset = + const size_t optional_header_offset = reinterpret_cast(&(nt_headers.OptionalHeader)) - reinterpret_cast(&nt_headers); - size_t optional_header_size = nt_headers.FileHeader.SizeOfOptionalHeader; + const size_t optional_header_size = nt_headers.FileHeader.SizeOfOptionalHeader; const auto* first_section_addr = nt_headers_addr + optional_header_offset + optional_header_size; const auto first_section_absolute = reinterpret_cast(first_section_addr); @@ -23,7 +23,7 @@ namespace std::vector read_mapped_memory(const memory_manager& memory, const mapped_module& binary) { std::vector mem{}; - mem.resize(binary.size_of_image); + mem.resize(static_cast(binary.size_of_image)); memory.read_memory(binary.image_base, mem.data(), mem.size()); return mem; @@ -73,7 +73,7 @@ namespace void apply_relocation(const utils::safe_buffer_accessor buffer, const uint64_t offset, const uint64_t delta) { - const auto obj = buffer.as(offset); + const auto obj = buffer.as(static_cast(offset)); const auto value = obj.get(); const auto new_value = value + static_cast(delta); obj.set(new_value); @@ -146,7 +146,7 @@ namespace const PENTHeaders_t& nt_headers, const uint64_t nt_headers_offset) { const auto first_section_offset = get_first_section_offset(nt_headers, nt_headers_offset); - const auto sections = buffer.as(first_section_offset); + const auto sections = buffer.as(static_cast(first_section_offset)); for (size_t i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { @@ -179,11 +179,11 @@ namespace const auto size_of_section = page_align_up(std::max(section.SizeOfRawData, section.Misc.VirtualSize)); - memory.protect_memory(target_ptr, size_of_section, permissions, nullptr); + memory.protect_memory(target_ptr, static_cast(size_of_section), permissions, nullptr); mapped_section section_info{}; section_info.region.start = target_ptr; - section_info.region.length = size_of_section; + section_info.region.length = static_cast(size_of_section); section_info.region.permissions = permissions; for (size_t j = 0; j < sizeof(section.Name) && section.Name[j]; ++j) @@ -219,21 +219,22 @@ mapped_module map_module_from_data(memory_manager& memory, const std::span(binary.size_of_image), memory_permission::all)) { - binary.image_base = memory.find_free_allocation_base(binary.size_of_image); + binary.image_base = memory.find_free_allocation_base(static_cast(binary.size_of_image)); const auto is_dll = nt_headers.FileHeader.Characteristics & IMAGE_FILE_DLL; const auto has_dynamic_base = optional_header.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; const auto is_relocatable = is_dll || has_dynamic_base; - if (!is_relocatable || !memory.allocate_memory(binary.image_base, binary.size_of_image, memory_permission::all)) + if (!is_relocatable || !memory.allocate_memory(binary.image_base, static_cast(binary.size_of_image), + memory_permission::all)) { throw std::runtime_error("Memory range not allocatable"); } } // TODO: Make sure to match kernel allocation patterns to attain correct initial permissions! - memory.protect_memory(binary.image_base, binary.size_of_image, memory_permission::read); + memory.protect_memory(binary.image_base, static_cast(binary.size_of_image), memory_permission::read); binary.entry_point = binary.image_base + optional_header.AddressOfEntryPoint; @@ -266,5 +267,5 @@ mapped_module map_module_from_file(memory_manager& memory, std::filesystem::path bool unmap_module(memory_manager& memory, const mapped_module& mod) { - return memory.release_memory(mod.image_base, mod.size_of_image); + return memory.release_memory(mod.image_base, static_cast(mod.size_of_image)); } diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index bb720ec4..b8d22677 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -65,7 +65,7 @@ void process_context::setup(x64_emulator& emu, memory_manager& memory, const app proc_params.StandardInput = STDIN_HANDLE.h; proc_params.StandardError = proc_params.StandardOutput; - proc_params.Environment = reinterpret_cast(allocator.copy_string(u"=::=::\\")); + proc_params.Environment = allocator.copy_string(u"=::=::\\"); allocator.copy_string(u"EMULATOR=1"); allocator.copy_string(u"COMPUTERNAME=momo"); allocator.copy_string(u"SystemRoot=C:\\WINDOWS"); @@ -95,11 +95,11 @@ void process_context::setup(x64_emulator& emu, memory_manager& memory, const app this->peb.access([&](PEB64& p) { p.BeingDebugged = 0; p.ImageBaseAddress = executable.image_base; - p.ProcessParameters = this->process_params.ptr(); - p.ApiSetMap = apiset::clone(emu, allocator, apiset_container).ptr(); + p.ProcessParameters = this->process_params.value(); + p.ApiSetMap = apiset::clone(emu, allocator, apiset_container).value(); - p.ProcessHeap = nullptr; - p.ProcessHeaps = nullptr; + p.ProcessHeap = 0; + p.ProcessHeaps = 0; p.HeapSegmentReserve = 0x0000000000100000; // TODO: Read from executable p.HeapSegmentCommit = 0x0000000000002000; p.HeapDeCommitTotalFreeThreshold = 0x0000000000010000; @@ -235,4 +235,4 @@ handle process_context::create_thread(memory_manager& memory, const uint64_t sta auto [h, thr] = this->threads.store_and_get(std::move(t)); this->callbacks_->on_create_thread(h, *thr); return h; -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscall_utils.hpp b/src/windows-emulator/syscall_utils.hpp index eb61b630..697e13e8 100644 --- a/src/windows-emulator/syscall_utils.hpp +++ b/src/windows-emulator/syscall_utils.hpp @@ -54,7 +54,8 @@ inline std::optional extract_syscall_id(const exported_symbol& symbol, const auto instruction_rva = symbol.rva + instruction_offset; - if (data.size() < (instruction_rva + instruction_size) || data[instruction_rva] != instruction_opcode) + if (data.size() < (instruction_rva + instruction_size) || + data[static_cast(instruction_rva)] != instruction_opcode) { return std::nullopt; } diff --git a/src/windows-emulator/syscalls/event.cpp b/src/windows-emulator/syscalls/event.cpp index 64aa329a..2f1f90fd 100644 --- a/src/windows-emulator/syscalls/event.cpp +++ b/src/windows-emulator/syscalls/event.cpp @@ -62,8 +62,7 @@ namespace syscalls const auto attributes = object_attributes.read(); if (attributes.ObjectName) { - name = read_unicode_string( - c.emu, reinterpret_cast>*>(attributes.ObjectName)); + name = read_unicode_string(c.emu, attributes.ObjectName); } } @@ -99,8 +98,7 @@ namespace syscalls const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); - const auto name = - read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); + const auto name = read_unicode_string(c.emu, attributes.ObjectName); c.win_emu.log.print(color::dark_gray, "--> Event name: %s\n", u16_to_u8(name).c_str()); if (name == u"\\KernelObjects\\SystemErrorPortReady") @@ -133,4 +131,4 @@ namespace syscalls return STATUS_NOT_FOUND; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 0cad972c..006e3ba2 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -130,7 +130,7 @@ namespace syscalls auto& enum_state = *f->enumeration_state; - size_t current_offset{0}; + uint64_t current_offset{0}; emulator_object object{c.emu}; size_t current_index = enum_state.current_index; @@ -400,7 +400,8 @@ namespace syscalls std::cin.readsome(temp_buffer.data(), static_cast(temp_buffer.size())); const auto count = std::max(read_count, static_cast(0)); - commit_file_data(std::string_view(temp_buffer.data(), count), c.emu, io_status_block, buffer); + commit_file_data(std::string_view(temp_buffer.data(), static_cast(count)), c.emu, io_status_block, + buffer); return STATUS_SUCCESS; } @@ -551,8 +552,7 @@ namespace syscalls uint64_t ea_buffer, ULONG ea_length) { const auto attributes = object_attributes.read(); - auto filename = - read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); + auto filename = read_unicode_string(c.emu, attributes.ObjectName); auto printer = utils::finally([&] { c.win_emu.log.print(color::dark_gray, "--> Opening file: %s\n", u16_to_u8(filename).c_str()); // @@ -756,8 +756,7 @@ namespace syscalls const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); - const auto object_name = - read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); + const auto object_name = read_unicode_string(c.emu, attributes.ObjectName); if (object_name == u"\\KnownDlls") { @@ -779,8 +778,7 @@ namespace syscalls const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); - const auto object_name = - read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); + const auto object_name = read_unicode_string(c.emu, attributes.ObjectName); if (object_name == u"KnownDllPath") { @@ -848,4 +846,4 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/locale.cpp b/src/windows-emulator/syscalls/locale.cpp index 418993bb..c1768148 100644 --- a/src/windows-emulator/syscalls/locale.cpp +++ b/src/windows-emulator/syscalls/locale.cpp @@ -17,7 +17,7 @@ namespace syscalls return STATUS_FILE_INVALID; } - const auto size = page_align_up(locale_file.size()); + const auto size = static_cast(page_align_up(locale_file.size())); const auto base = c.win_emu.memory.allocate_memory(size, memory_permission::read); c.emu.write_memory(base, locale_file.data(), locale_file.size()); @@ -58,4 +58,4 @@ namespace syscalls { return STATUS_NOT_SUPPORTED; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/memory.cpp b/src/windows-emulator/syscalls/memory.cpp index 7e12521d..768f6791 100644 --- a/src/windows-emulator/syscalls/memory.cpp +++ b/src/windows-emulator/syscalls/memory.cpp @@ -41,8 +41,8 @@ namespace syscalls assert(!region_info.is_committed || region_info.is_reserved); const auto state = region_info.is_reserved ? MEM_RESERVE : MEM_FREE; image_info.State = region_info.is_committed ? MEM_COMMIT : state; - image_info.BaseAddress = reinterpret_cast(region_info.start); - image_info.AllocationBase = reinterpret_cast(region_info.allocation_base); + image_info.BaseAddress = region_info.start; + image_info.AllocationBase = region_info.allocation_base; image_info.PartitionId = 0; image_info.RegionSize = static_cast(region_info.length); @@ -76,7 +76,7 @@ namespace syscalls const emulator_object info{c.emu, memory_information}; info.access([&](MEMORY_IMAGE_INFORMATION64& image_info) { - image_info.ImageBase = reinterpret_cast(mod->image_base); + image_info.ImageBase = mod->image_base; image_info.SizeOfImage = static_cast(mod->size_of_image); image_info.ImageFlags = 0; }); @@ -107,7 +107,7 @@ namespace syscalls info.access([&](MEMORY_REGION_INFORMATION64& image_info) { memset(&image_info, 0, sizeof(image_info)); - image_info.AllocationBase = reinterpret_cast(region_info.allocation_base); + image_info.AllocationBase = region_info.allocation_base; image_info.AllocationProtect = map_emulator_to_nt_protection(region_info.initial_permissions); // image_info.PartitionId = 0; image_info.RegionSize = static_cast(region_info.allocation_length); @@ -151,7 +151,8 @@ namespace syscalls try { - c.win_emu.memory.protect_memory(aligned_start, aligned_length, requested_protection, &old_protection_value); + c.win_emu.memory.protect_memory(aligned_start, static_cast(aligned_length), requested_protection, + &old_protection_value); } catch (...) { @@ -183,7 +184,7 @@ namespace syscalls auto potential_base = base_address.read(); if (!potential_base) { - potential_base = c.win_emu.memory.find_free_allocation_base(allocation_bytes); + potential_base = c.win_emu.memory.find_free_allocation_base(static_cast(allocation_bytes)); } if (!potential_base) @@ -203,7 +204,8 @@ namespace syscalls throw std::runtime_error("Unsupported allocation type!"); } - if (commit && !reserve && c.win_emu.memory.commit_memory(potential_base, allocation_bytes, protection)) + if (commit && !reserve && + c.win_emu.memory.commit_memory(potential_base, static_cast(allocation_bytes), protection)) { c.win_emu.log.print(color::dark_gray, "--> Committed 0x%" PRIx64 " - 0x%" PRIx64 "\n", potential_base, potential_base + allocation_bytes); @@ -214,7 +216,8 @@ namespace syscalls c.win_emu.log.print(color::dark_gray, "--> Allocated 0x%" PRIx64 " - 0x%" PRIx64 "\n", potential_base, potential_base + allocation_bytes); - return c.win_emu.memory.allocate_memory(potential_base, allocation_bytes, protection, !commit) + return c.win_emu.memory.allocate_memory(potential_base, static_cast(allocation_bytes), protection, + !commit) ? STATUS_SUCCESS : STATUS_MEMORY_NOT_ALLOCATED; } @@ -242,14 +245,16 @@ namespace syscalls if (free_type & MEM_RELEASE) { - return c.win_emu.memory.release_memory(allocation_base, allocation_size) ? STATUS_SUCCESS - : STATUS_MEMORY_NOT_ALLOCATED; + return c.win_emu.memory.release_memory(allocation_base, static_cast(allocation_size)) + ? STATUS_SUCCESS + : STATUS_MEMORY_NOT_ALLOCATED; } if (free_type & MEM_DECOMMIT) { - return c.win_emu.memory.decommit_memory(allocation_base, allocation_size) ? STATUS_SUCCESS - : STATUS_MEMORY_NOT_ALLOCATED; + return c.win_emu.memory.decommit_memory(allocation_base, static_cast(allocation_size)) + ? STATUS_SUCCESS + : STATUS_MEMORY_NOT_ALLOCATED; } throw std::runtime_error("Bad free type"); @@ -284,4 +289,4 @@ namespace syscalls { return STATUS_NOT_SUPPORTED; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/port.cpp b/src/windows-emulator/syscalls/port.cpp index 28e91e8b..bfade094 100644 --- a/src/windows-emulator/syscalls/port.cpp +++ b/src/windows-emulator/syscalls/port.cpp @@ -27,7 +27,8 @@ namespace syscalls } client_shared_memory.access([&](PORT_VIEW64& view) { - p.view_base = c.win_emu.memory.allocate_memory(view.ViewSize, memory_permission::read_write); + p.view_base = + c.win_emu.memory.allocate_memory(static_cast(view.ViewSize), memory_permission::read_write); view.ViewBase = p.view_base; view.ViewRemoteBase = view.ViewBase; }); @@ -76,4 +77,4 @@ namespace syscalls { return STATUS_NOT_SUPPORTED; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/process.cpp b/src/windows-emulator/syscalls/process.cpp index 7075fa34..dc648a8d 100644 --- a/src/windows-emulator/syscalls/process.cpp +++ b/src/windows-emulator/syscalls/process.cpp @@ -212,7 +212,7 @@ namespace syscalls const emulator_object info{c.emu, process_information}; info.access([&](PROCESS_BASIC_INFORMATION64& basic_info) { - basic_info.PebBaseAddress = c.proc.peb.ptr(); + basic_info.PebBaseAddress = c.proc.peb.value(); basic_info.UniqueProcessId = 1; }); @@ -306,11 +306,12 @@ namespace syscalls thread_iterator->second.teb->access([&](TEB64& teb) { entry.ThreadId = teb.ClientId.UniqueThread; - auto* tls_vector = teb.ThreadLocalStoragePointer; + const auto tls_vector = teb.ThreadLocalStoragePointer; + constexpr auto ptr_size = sizeof(EmulatorTraits::PVOID); if (tls_info.TlsRequest == ProcessTlsReplaceIndex) { - auto* tls_entry_ptr = tls_vector + tls_info.TlsIndex; + const auto tls_entry_ptr = tls_vector + (tls_info.TlsIndex * ptr_size); const auto old_entry = c.emu.read_memory::PVOID>(tls_entry_ptr); c.emu.write_memory::PVOID>(tls_entry_ptr, entry.TlsModulePointer); @@ -319,12 +320,12 @@ namespace syscalls } else if (tls_info.TlsRequest == ProcessTlsReplaceVector) { - auto* new_tls_vector = entry.TlsVector; + const auto new_tls_vector = entry.TlsVector; for (uint32_t index = 0; index < tls_info.TlsVectorLength; ++index) { - auto* old_entry = c.emu.read_memory(tls_vector + index); - c.emu.write_memory(new_tls_vector + index, old_entry); + const auto old_entry = c.emu.read_memory(tls_vector + index * ptr_size); + c.emu.write_memory(new_tls_vector + index * ptr_size, old_entry); } teb.ThreadLocalStoragePointer = new_tls_vector; @@ -386,4 +387,4 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/registry.cpp b/src/windows-emulator/syscalls/registry.cpp index 2dcaf779..d383335a 100644 --- a/src/windows-emulator/syscalls/registry.cpp +++ b/src/windows-emulator/syscalls/registry.cpp @@ -11,8 +11,7 @@ namespace syscalls const emulator_object>> object_attributes) { const auto attributes = object_attributes.read(); - auto key = - read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); + auto key = read_unicode_string(c.emu, attributes.ObjectName); if (attributes.RootDirectory) { @@ -247,4 +246,4 @@ namespace syscalls { return STATUS_NOT_SUPPORTED; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/section.cpp b/src/windows-emulator/syscalls/section.cpp index 415206dd..3bcaaa90 100644 --- a/src/windows-emulator/syscalls/section.cpp +++ b/src/windows-emulator/syscalls/section.cpp @@ -29,8 +29,7 @@ namespace syscalls const auto attributes = object_attributes.read(); if (attributes.ObjectName) { - auto name = read_unicode_string( - c.emu, reinterpret_cast>*>(attributes.ObjectName)); + auto name = read_unicode_string(c.emu, attributes.ObjectName); c.win_emu.log.print(color::dark_gray, "--> Section with name %s\n", u16_to_u8(name).c_str()); s.name = std::move(name); } @@ -60,8 +59,7 @@ namespace syscalls { const auto attributes = object_attributes.read(); - auto filename = - read_unicode_string(c.emu, reinterpret_cast>*>(attributes.ObjectName)); + auto filename = read_unicode_string(c.emu, attributes.ObjectName); c.win_emu.log.print(color::dark_gray, "--> Opening section: %s\n", u16_to_u8(filename).c_str()); if (filename == u"\\Windows\\SharedSection") @@ -227,7 +225,7 @@ namespace syscalls const auto reserve_only = section_entry->allocation_attributes == SEC_RESERVE; const auto protection = map_nt_to_emulator_protection(section_entry->section_page_protection); - const auto address = c.win_emu.memory.allocate_memory(size, protection, reserve_only); + const auto address = c.win_emu.memory.allocate_memory(static_cast(size), protection, reserve_only); if (!reserve_only && !file_data.empty()) { @@ -289,4 +287,4 @@ namespace syscalls { return handle_NtUnmapViewOfSection(c, process_handle, base_address); } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/semaphore.cpp b/src/windows-emulator/syscalls/semaphore.cpp index 6b482a17..8e27e607 100644 --- a/src/windows-emulator/syscalls/semaphore.cpp +++ b/src/windows-emulator/syscalls/semaphore.cpp @@ -78,8 +78,7 @@ namespace syscalls const auto attributes = object_attributes.read(); if (attributes.ObjectName) { - s.name = read_unicode_string( - c.emu, reinterpret_cast>*>(attributes.ObjectName)); + s.name = read_unicode_string(c.emu, attributes.ObjectName); } } @@ -101,4 +100,4 @@ namespace syscalls return STATUS_SUCCESS; } -} \ No newline at end of file +} diff --git a/src/windows-emulator/syscalls/thread.cpp b/src/windows-emulator/syscalls/thread.cpp index 3cc470a7..827dc0e1 100644 --- a/src/windows-emulator/syscalls/thread.cpp +++ b/src/windows-emulator/syscalls/thread.cpp @@ -73,7 +73,7 @@ namespace syscalls t.teb->access([&](TEB64& teb) { if (tls_cell < TLS_MINIMUM_AVAILABLE) { - teb.TlsSlots.arr[tls_cell] = nullptr; + teb.TlsSlots.arr[tls_cell] = 0; } else if (teb.TlsExpansionSlots) { @@ -136,7 +136,7 @@ namespace syscalls const emulator_object info{c.emu, thread_information}; info.access([&](THREAD_BASIC_INFORMATION64& i) { - i.TebBaseAddress = thread->teb->ptr(); + i.TebBaseAddress = thread->teb->value(); i.ClientId = thread->teb->read().ClientId; }); @@ -542,7 +542,7 @@ namespace syscalls } else if (type == PsAttributeTebAddress) { - write_attribute(c.emu, attribute, thread->teb->ptr()); + write_attribute(c.emu, attribute, thread->teb->value()); } else { diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 30bf3123..4cb8b45f 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -341,8 +341,8 @@ void windows_emulator::setup_process(const application_settings& app_settings) this->process.setup(this->emu(), this->memory, app_settings, *executable, *ntdll, apiset_data); - const auto ntdll_data = emu.read_memory(ntdll->image_base, ntdll->size_of_image); - const auto win32u_data = emu.read_memory(win32u->image_base, win32u->size_of_image); + const auto ntdll_data = emu.read_memory(ntdll->image_base, static_cast(ntdll->size_of_image)); + const auto win32u_data = emu.read_memory(win32u->image_base, static_cast(win32u->size_of_image)); this->dispatcher.setup(ntdll->exports, ntdll_data, win32u->exports, win32u_data); @@ -601,7 +601,7 @@ void windows_emulator::start(size_t count) break; } - count = target_instructions - current_instructions; + count = static_cast(target_instructions - current_instructions); } } } diff --git a/src/windows-gdb-stub/x64_gdb_stub_handler.hpp b/src/windows-gdb-stub/x64_gdb_stub_handler.hpp index aa519acd..3fb33992 100644 --- a/src/windows-gdb-stub/x64_gdb_stub_handler.hpp +++ b/src/windows-gdb-stub/x64_gdb_stub_handler.hpp @@ -10,7 +10,7 @@ struct breakpoint_key { - size_t addr{}; + uint64_t addr{}; size_t size{}; gdb_stub::breakpoint_type type{}; @@ -25,7 +25,7 @@ struct std::hash { std::size_t operator()(const breakpoint_key& k) const noexcept { - return ((std::hash()(k.addr) ^ (std::hash()(k.size) << 1)) >> 1) ^ + return ((std::hash()(k.addr) ^ (std::hash()(k.size) << 1)) >> 1) ^ (std::hash()(static_cast(k.type)) << 1); } };