mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 11:13:57 +00:00
Support emulation on 32 bit Windows (#203)
Emulation of 32 bit Windows applications is still unsupported.
This commit is contained in:
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
@@ -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
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ emulator_hook* watch_object(windows_emulator& emu, const std::set<std::string, s
|
||||
const reflect_type_info<T> info{};
|
||||
|
||||
return emu.emu().hook_memory_read(
|
||||
object.value(), object.size(),
|
||||
object.value(), static_cast<size_t>(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::set<std::string, s
|
||||
const auto offset = address - object.value();
|
||||
emu.log.print(is_main_access ? color::green : color::dark_gray,
|
||||
"Object access: %s - 0x%llX (%s) at 0x%llX (%s)\n", i.get_type_name().c_str(), offset,
|
||||
i.get_member_name(offset).c_str(), rip, mod ? mod->name.c_str() : "<N/A>");
|
||||
i.get_member_name(static_cast<size_t>(offset)).c_str(), rip,
|
||||
mod ? mod->name.c_str() : "<N/A>");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 <reflect>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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<Emu64>::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<EmulatorTraits<Emu64>>;
|
||||
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<EmulatorTraits<Emu64>> DllPath;
|
||||
UNICODE_STRING<EmulatorTraits<Emu64>> ImagePathName;
|
||||
UNICODE_STRING<EmulatorTraits<Emu64>> 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<EmulatorTraits<Emu64>> RuntimeData;
|
||||
ARRAY_CONTAINER<RTL_DRIVE_LETTER_CURDIR64, RTL_MAX_DRIVE_LETTERS> 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<EmulatorTraits<Emu64>> RedirectionDllName; // REDSTONE4
|
||||
UNICODE_STRING<EmulatorTraits<Emu64>> 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<Emu64>::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<ULONG, 2> 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<Emu64>::PVOID, PCPTABLEINFO) AnsiCodePageData; // PCPTABLEINFO
|
||||
EMULATOR_CAST(EmulatorTraits<Emu64>::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<ULONG, GDI_HANDLE_BUFFER_SIZE64> 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<ULONG, 32> 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<EmulatorTraits<Emu64>> 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<std::uint64_t*, 2> SparePointers; // 19H1 (previously FlsCallback to FlsHighIndex)
|
||||
std::uint64_t* PatchLoaderData;
|
||||
std::uint64_t* ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO
|
||||
ARRAY_CONTAINER<std::uint64_t, 2> SparePointers; // 19H1 (previously FlsCallback to FlsHighIndex)
|
||||
std::uint64_t PatchLoaderData;
|
||||
std::uint64_t ChpeV2ProcessInfo; // _CHPEV2_PROCESS_INFO
|
||||
|
||||
ULONG AppModelFeatureState;
|
||||
ARRAY_CONTAINER<ULONG, 2> 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<std::uint64_t*, 128> WaitOnAddressHashTable;
|
||||
EMULATOR_CAST(void*, PTELEMETRY_COVERAGE_HEADER) TelemetryCoverageHeader; // REDSTONE3
|
||||
ARRAY_CONTAINER<std::uint64_t, 128> WaitOnAddressHashTable;
|
||||
EMULATOR_CAST(std::uint64_t, PTELEMETRY_COVERAGE_HEADER) TelemetryCoverageHeader; // REDSTONE3
|
||||
ULONG CloudFileFlags;
|
||||
ULONG CloudFileDiagFlags; // REDSTONE4
|
||||
CHAR PlaceholderCompatibilityMode;
|
||||
ARRAY_CONTAINER<CHAR, 7> 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<ULONG, 26> User32Reserved;
|
||||
ARRAY_CONTAINER<ULONG, 5> UserReserved;
|
||||
std::uint64_t* WOW32Reserved;
|
||||
std::uint64_t WOW32Reserved;
|
||||
LCID CurrentLocale;
|
||||
ULONG FpSoftwareStatusRegister;
|
||||
ARRAY_CONTAINER<void*, 16> ReservedForDebuggerInstrumentation;
|
||||
ARRAY_CONTAINER<void*, 25> SystemReserved1;
|
||||
std::uint64_t* HeapFlsData;
|
||||
ARRAY_CONTAINER<std::uint64_t*, 4> RngState;
|
||||
ARRAY_CONTAINER<std::uint64_t, 16> ReservedForDebuggerInstrumentation;
|
||||
ARRAY_CONTAINER<std::uint64_t, 25> SystemReserved1;
|
||||
std::uint64_t HeapFlsData;
|
||||
ARRAY_CONTAINER<std::uint64_t, 4> RngState;
|
||||
CHAR PlaceholderCompatibilityMode;
|
||||
BOOLEAN PlaceholderHydrationAlwaysExplicit;
|
||||
ARRAY_CONTAINER<CHAR, 10> 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<Emu64>::HANDLE GdiCachedProcessHandle;
|
||||
ULONG GdiClientPID;
|
||||
ULONG GdiClientTID;
|
||||
std::uint64_t* GdiThreadLocalInfo;
|
||||
ARRAY_CONTAINER<std::uint64_t*, WIN32_CLIENT_INFO_LENGTH> Win32ClientInfo;
|
||||
std::uint64_t GdiThreadLocalInfo;
|
||||
ARRAY_CONTAINER<std::uint64_t, WIN32_CLIENT_INFO_LENGTH> Win32ClientInfo;
|
||||
|
||||
ARRAY_CONTAINER<void*, 233> glDispatchTable;
|
||||
ARRAY_CONTAINER<std::uint64_t*, 29> 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<std::uint64_t, 233> glDispatchTable;
|
||||
ARRAY_CONTAINER<std::uint64_t, 29> 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<EmulatorTraits<Emu64>> StaticUnicodeString;
|
||||
ARRAY_CONTAINER<char16_t, STATIC_UNICODE_BUFFER_LENGTH> StaticUnicodeBuffer;
|
||||
|
||||
std::uint64_t* DeallocationStack;
|
||||
std::uint64_t DeallocationStack;
|
||||
|
||||
ARRAY_CONTAINER<std::uint64_t*, TLS_MINIMUM_AVAILABLE> TlsSlots;
|
||||
ARRAY_CONTAINER<std::uint64_t, TLS_MINIMUM_AVAILABLE> TlsSlots;
|
||||
LIST_ENTRY64 TlsLinks;
|
||||
|
||||
std::uint64_t* Vdm;
|
||||
std::uint64_t* ReservedForNtRpc;
|
||||
ARRAY_CONTAINER<void*, 2> DbgSsReserved;
|
||||
std::uint64_t Vdm;
|
||||
std::uint64_t ReservedForNtRpc;
|
||||
ARRAY_CONTAINER<std::uint64_t, 2> DbgSsReserved;
|
||||
|
||||
ULONG HardErrorMode;
|
||||
ARRAY_CONTAINER<void*, 11> Instrumentation;
|
||||
ARRAY_CONTAINER<std::uint64_t, 11> 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<Emu64>::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<ULONG, 2> Rcu;
|
||||
} TEB64, *PTEB64;
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
static_assert(sizeof(TEB64) == 0x1878);
|
||||
|
||||
#if defined(OS_WINDOWS) && defined(_WIN64)
|
||||
inline TEB64* NtCurrentTeb64()
|
||||
{
|
||||
return reinterpret_cast<TEB64*>(__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 <typename Traits>
|
||||
@@ -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<Emu64>::PVOID* TlsVector;
|
||||
EmulatorTraits<Emu64>::PVOID TlsVector;
|
||||
EmulatorTraits<Emu64>::PVOID TlsModulePointer;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -378,7 +378,7 @@ namespace utils
|
||||
{
|
||||
const auto size = this->read<uint64_t>();
|
||||
result.clear();
|
||||
result.reserve(size);
|
||||
result.reserve(static_cast<size_t>(size));
|
||||
|
||||
for (uint64_t i = 0; i < size; ++i)
|
||||
{
|
||||
@@ -447,7 +447,7 @@ namespace utils
|
||||
const auto size = this->read<uint64_t>();
|
||||
|
||||
result.clear();
|
||||
result.reserve(size);
|
||||
result.reserve(static_cast<size_t>(size));
|
||||
|
||||
for (uint64_t i = 0; i < size; ++i)
|
||||
{
|
||||
|
||||
@@ -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<size_t>(1))),
|
||||
memory_permission::read_write);
|
||||
const auto memory = emu.memory.allocate_memory(
|
||||
static_cast<size_t>(page_align_up(std::max(data.size(), static_cast<size_t>(1)))),
|
||||
memory_permission::read_write);
|
||||
emu.emu().write_memory(memory, data.data(), data.size());
|
||||
|
||||
emu.emu().reg(x64_register::rcx, memory);
|
||||
|
||||
@@ -22,7 +22,7 @@ int main()
|
||||
printf("------------\n\n");
|
||||
|
||||
const auto peb = static_cast<PPEB64>(GetCurrentProcessPeb());
|
||||
const auto api_set_map = peb->ApiSetMap;
|
||||
const auto api_set_map = reinterpret_cast<API_SET_NAMESPACE*>(peb->ApiSetMap);
|
||||
|
||||
printf("APISET: 0x%p\n", api_set_map);
|
||||
printf("Version: %d\n", api_set_map->Version);
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace test
|
||||
constexpr auto offset = 1;
|
||||
const auto instructionsToExecute = executedInstructions - offset;
|
||||
|
||||
new_emu.start(instructionsToExecute);
|
||||
new_emu.start(static_cast<size_t>(instructionsToExecute));
|
||||
|
||||
ASSERT_EQ(new_emu.get_executed_instructions(), instructionsToExecute);
|
||||
ASSERT_NOT_TERMINATED(new_emu);
|
||||
|
||||
@@ -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<size_t>(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<size_t>(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<size_t>(lower_bound));
|
||||
|
||||
const auto rip = emu.emu().read_instruction_pointer();
|
||||
|
||||
|
||||
@@ -57,12 +57,13 @@ namespace apiset
|
||||
{
|
||||
switch (location)
|
||||
{
|
||||
#ifdef OS_WINDOWS
|
||||
#ifdef OS_WINDOWS_64
|
||||
case location::host: {
|
||||
const auto apiSetMap =
|
||||
reinterpret_cast<const API_SET_NAMESPACE*>(NtCurrentTeb64()->ProcessEnvironmentBlock->ApiSetMap);
|
||||
const auto* dataPtr = reinterpret_cast<const std::byte*>(apiSetMap);
|
||||
return {dataPtr, dataPtr + apiSetMap->Size};
|
||||
const auto* teb = NtCurrentTeb64();
|
||||
const auto* peb = reinterpret_cast<PEB64*>(teb->ProcessEnvironmentBlock);
|
||||
const auto* api_set_map = reinterpret_cast<const API_SET_NAMESPACE*>(peb->ApiSetMap);
|
||||
const auto* data_ptr = reinterpret_cast<const std::byte*>(api_set_map);
|
||||
return {data_ptr, data_ptr + api_set_map->Size};
|
||||
}
|
||||
#else
|
||||
case location::host:
|
||||
|
||||
@@ -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<size_t>(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<uint64_t>(this->id);
|
||||
teb_obj.NtTib.StackLimit = reinterpret_cast<std::uint64_t*>(this->stack_base);
|
||||
teb_obj.NtTib.StackBase = reinterpret_cast<std::uint64_t*>(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<size_t>(this->stack_size));
|
||||
emu.set_segment_base(x64_register::gs, this->gs_segment->get_base());
|
||||
|
||||
CONTEXT64 ctx{};
|
||||
|
||||
@@ -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<size_t>(this->stack_size));
|
||||
this->stack_base = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,11 +95,6 @@ class emulator_object
|
||||
return this->value() + this->size();
|
||||
}
|
||||
|
||||
T* ptr() const
|
||||
{
|
||||
return reinterpret_cast<T*>(this->address_);
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return this->address_ != 0;
|
||||
@@ -221,11 +216,11 @@ class emulator_allocator
|
||||
return emulator_object<T>(*this->memory_, potential_start);
|
||||
}
|
||||
|
||||
char16_t* copy_string(const std::u16string_view str)
|
||||
uint64_t copy_string(const std::u16string_view str)
|
||||
{
|
||||
UNICODE_STRING<EmulatorTraits<Emu64>> uc_str{};
|
||||
this->make_unicode_string(uc_str, str);
|
||||
return reinterpret_cast<char16_t*>(uc_str.Buffer);
|
||||
return uc_str.Buffer;
|
||||
}
|
||||
|
||||
void make_unicode_string(UNICODE_STRING<EmulatorTraits<Emu64>>& 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<size_t>(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<EmulatorTraits<Emu64>>* uc_string)
|
||||
inline std::u16string read_unicode_string(emulator& emu, const uint64_t uc_string)
|
||||
{
|
||||
return read_unicode_string(emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{emu, uc_string});
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace
|
||||
}
|
||||
|
||||
record_obj.access([&](exception_record& r) {
|
||||
r.ExceptionRecord = reinterpret_cast<EmulatorTraits<Emu64>::PVOID>(nested_record_obj.ptr());
|
||||
r.ExceptionRecord = nested_record_obj.value(); //
|
||||
});
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace
|
||||
assert(total_size >= allocation_size);
|
||||
|
||||
std::vector<uint8_t> zero_memory{};
|
||||
zero_memory.resize(total_size, 0);
|
||||
zero_memory.resize(static_cast<size_t>(total_size), 0);
|
||||
|
||||
emu.write_memory(new_sp, zero_memory.data(), zero_memory.size());
|
||||
|
||||
|
||||
@@ -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<uint8_t*>(&this->kusd_);
|
||||
memcpy(data, kusd_buffer + addr, real_size);
|
||||
memcpy(data, kusd_buffer + addr, static_cast<size_t>(real_size));
|
||||
}
|
||||
|
||||
uint64_t kusd_mmio::address()
|
||||
|
||||
@@ -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<size_t>(first_length);
|
||||
|
||||
regions[split_point] = memory_manager::committed_region{second_length, i->second.permissions};
|
||||
regions[split_point] =
|
||||
memory_manager::committed_region{static_cast<size_t>(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<size_t>(map_length), permissions);
|
||||
committed_regions[map_start] = committed_region{static_cast<size_t>(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<size_t>(map_length), permissions);
|
||||
committed_regions[map_start] = committed_region{static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(lower_end - result.start);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace
|
||||
uint64_t get_first_section_offset(const PENTHeaders_t<std::uint64_t>& nt_headers, const uint64_t nt_headers_offset)
|
||||
{
|
||||
const auto* nt_headers_addr = reinterpret_cast<const uint8_t*>(&nt_headers);
|
||||
size_t optional_header_offset =
|
||||
const size_t optional_header_offset =
|
||||
reinterpret_cast<uintptr_t>(&(nt_headers.OptionalHeader)) - reinterpret_cast<uintptr_t>(&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<uint64_t>(first_section_addr);
|
||||
@@ -23,7 +23,7 @@ namespace
|
||||
std::vector<std::byte> read_mapped_memory(const memory_manager& memory, const mapped_module& binary)
|
||||
{
|
||||
std::vector<std::byte> mem{};
|
||||
mem.resize(binary.size_of_image);
|
||||
mem.resize(static_cast<size_t>(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<std::byte> buffer, const uint64_t offset,
|
||||
const uint64_t delta)
|
||||
{
|
||||
const auto obj = buffer.as<T>(offset);
|
||||
const auto obj = buffer.as<T>(static_cast<size_t>(offset));
|
||||
const auto value = obj.get();
|
||||
const auto new_value = value + static_cast<T>(delta);
|
||||
obj.set(new_value);
|
||||
@@ -146,7 +146,7 @@ namespace
|
||||
const PENTHeaders_t<std::uint64_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<IMAGE_SECTION_HEADER>(first_section_offset);
|
||||
const auto sections = buffer.as<IMAGE_SECTION_HEADER>(static_cast<size_t>(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_t>(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_t>(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<const
|
||||
binary.image_base = optional_header.ImageBase;
|
||||
binary.size_of_image = page_align_up(optional_header.SizeOfImage); // TODO: Sanitize
|
||||
|
||||
if (!memory.allocate_memory(binary.image_base, binary.size_of_image, memory_permission::all))
|
||||
if (!memory.allocate_memory(binary.image_base, static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(mod.size_of_image));
|
||||
}
|
||||
|
||||
@@ -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<std::uint64_t*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ inline std::optional<uint32_t> 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<size_t>(instruction_rva)] != instruction_opcode)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -62,8 +62,7 @@ namespace syscalls
|
||||
const auto attributes = object_attributes.read();
|
||||
if (attributes.ObjectName)
|
||||
{
|
||||
name = read_unicode_string(
|
||||
c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
name = read_unicode_string(c.emu, attributes.ObjectName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +98,7 @@ namespace syscalls
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
const auto name =
|
||||
read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace syscalls
|
||||
|
||||
auto& enum_state = *f->enumeration_state;
|
||||
|
||||
size_t current_offset{0};
|
||||
uint64_t current_offset{0};
|
||||
emulator_object<T> 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<std::streamsize>(temp_buffer.size()));
|
||||
const auto count = std::max(read_count, static_cast<std::streamsize>(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<size_t>(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<UNICODE_STRING<EmulatorTraits<Emu64>>*>(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<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
const auto object_name =
|
||||
read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(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<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
const auto object_name =
|
||||
read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace syscalls
|
||||
return STATUS_FILE_INVALID;
|
||||
}
|
||||
|
||||
const auto size = page_align_up(locale_file.size());
|
||||
const auto size = static_cast<size_t>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<void*>(region_info.start);
|
||||
image_info.AllocationBase = reinterpret_cast<void*>(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<int64_t>(region_info.length);
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace syscalls
|
||||
const emulator_object<MEMORY_IMAGE_INFORMATION64> info{c.emu, memory_information};
|
||||
|
||||
info.access([&](MEMORY_IMAGE_INFORMATION64& image_info) {
|
||||
image_info.ImageBase = reinterpret_cast<void*>(mod->image_base);
|
||||
image_info.ImageBase = mod->image_base;
|
||||
image_info.SizeOfImage = static_cast<int64_t>(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<void*>(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<int64_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<size_t>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace syscalls
|
||||
|
||||
const emulator_object<PROCESS_BASIC_INFORMATION64> 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<Emu64>::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<EmulatorTraits<Emu64>::PVOID>(tls_entry_ptr);
|
||||
c.emu.write_memory<EmulatorTraits<Emu64>::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<void*>(tls_vector + index);
|
||||
c.emu.write_memory<void*>(new_tls_vector + index, old_entry);
|
||||
const auto old_entry = c.emu.read_memory<uint64_t>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ namespace syscalls
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
auto key =
|
||||
read_unicode_string(c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
auto key = read_unicode_string(c.emu, attributes.ObjectName);
|
||||
|
||||
if (attributes.RootDirectory)
|
||||
{
|
||||
@@ -247,4 +246,4 @@ namespace syscalls
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ namespace syscalls
|
||||
const auto attributes = object_attributes.read();
|
||||
if (attributes.ObjectName)
|
||||
{
|
||||
auto name = read_unicode_string(
|
||||
c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(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<UNICODE_STRING<EmulatorTraits<Emu64>>*>(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_t>(size), protection, reserve_only);
|
||||
|
||||
if (!reserve_only && !file_data.empty())
|
||||
{
|
||||
@@ -289,4 +287,4 @@ namespace syscalls
|
||||
{
|
||||
return handle_NtUnmapViewOfSection(c, process_handle, base_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,8 +78,7 @@ namespace syscalls
|
||||
const auto attributes = object_attributes.read();
|
||||
if (attributes.ObjectName)
|
||||
{
|
||||
s.name = read_unicode_string(
|
||||
c.emu, reinterpret_cast<UNICODE_STRING<EmulatorTraits<Emu64>>*>(attributes.ObjectName));
|
||||
s.name = read_unicode_string(c.emu, attributes.ObjectName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,4 +100,4 @@ namespace syscalls
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<THREAD_BASIC_INFORMATION64> 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
|
||||
{
|
||||
|
||||
@@ -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<size_t>(ntdll->size_of_image));
|
||||
const auto win32u_data = emu.read_memory(win32u->image_base, static_cast<size_t>(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<size_t>(target_instructions - current_instructions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<breakpoint_key>
|
||||
{
|
||||
std::size_t operator()(const breakpoint_key& k) const noexcept
|
||||
{
|
||||
return ((std::hash<size_t>()(k.addr) ^ (std::hash<size_t>()(k.size) << 1)) >> 1) ^
|
||||
return ((std::hash<uint64_t>()(k.addr) ^ (std::hash<size_t>()(k.size) << 1)) >> 1) ^
|
||||
(std::hash<size_t>()(static_cast<size_t>(k.type)) << 1);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user