mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-29 07:51:01 +00:00
@@ -36,6 +36,7 @@ using NTSTATUS = std::uint32_t;
|
|||||||
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
|
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
|
||||||
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
|
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
|
||||||
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
|
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
|
||||||
|
#define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS)0xC0000045L)
|
||||||
#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xC0000046L)
|
#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xC0000046L)
|
||||||
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xC0000047L)
|
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xC0000047L)
|
||||||
#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
|
#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
|
||||||
|
|||||||
@@ -792,6 +792,11 @@ namespace
|
|||||||
|
|
||||||
bool test_apis()
|
bool test_apis()
|
||||||
{
|
{
|
||||||
|
if (VirtualProtect(nullptr, 0, 0, nullptr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
wchar_t buffer[0x100];
|
wchar_t buffer[0x100];
|
||||||
DWORD size = sizeof(buffer) / 2;
|
DWORD size = sizeof(buffer) / 2;
|
||||||
return GetComputerNameExW(ComputerNameNetBIOS, buffer, &size);
|
return GetComputerNameExW(ComputerNameNetBIOS, buffer, &size);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ inline std::string get_permission_string(const memory_permission permission)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline nt_memory_permission map_nt_to_emulator_protection(uint32_t nt_protection)
|
inline std::optional<nt_memory_permission> try_map_nt_to_emulator_protection(uint32_t nt_protection)
|
||||||
{
|
{
|
||||||
memory_permission_ext ext = memory_permission_ext::none;
|
memory_permission_ext ext = memory_permission_ext::none;
|
||||||
// TODO: Check for invalid combinations
|
// TODO: Check for invalid combinations
|
||||||
@@ -51,14 +51,26 @@ inline nt_memory_permission map_nt_to_emulator_protection(uint32_t nt_protection
|
|||||||
case PAGE_EXECUTE_READWRITE:
|
case PAGE_EXECUTE_READWRITE:
|
||||||
common = memory_permission::all;
|
common = memory_permission::all;
|
||||||
break;
|
break;
|
||||||
|
case 0:
|
||||||
case PAGE_EXECUTE_WRITECOPY:
|
case PAGE_EXECUTE_WRITECOPY:
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Failed to map protection");
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nt_memory_permission{common, ext};
|
return nt_memory_permission{common, ext};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline nt_memory_permission map_nt_to_emulator_protection(uint32_t nt_protection)
|
||||||
|
{
|
||||||
|
const auto protection = try_map_nt_to_emulator_protection(nt_protection);
|
||||||
|
if (protection.has_value())
|
||||||
|
{
|
||||||
|
return *protection;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Failed to map protection: " + std::to_string(nt_protection));
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32_t map_emulator_to_nt_protection(const memory_permission permission)
|
inline uint32_t map_emulator_to_nt_protection(const memory_permission permission)
|
||||||
{
|
{
|
||||||
const bool has_exec = (permission & memory_permission::exec) != memory_permission::none;
|
const bool has_exec = (permission & memory_permission::exec) != memory_permission::none;
|
||||||
|
|||||||
@@ -144,15 +144,19 @@ namespace syscalls
|
|||||||
base_address.write(aligned_start);
|
base_address.write(aligned_start);
|
||||||
bytes_to_protect.write(static_cast<uint32_t>(aligned_length));
|
bytes_to_protect.write(static_cast<uint32_t>(aligned_length));
|
||||||
|
|
||||||
const auto requested_protection = map_nt_to_emulator_protection(protection);
|
const auto requested_protection = try_map_nt_to_emulator_protection(protection);
|
||||||
|
if (!requested_protection.has_value())
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PAGE_PROTECTION;
|
||||||
|
}
|
||||||
|
|
||||||
c.win_emu.callbacks.on_memory_protect(aligned_start, aligned_length, requested_protection);
|
c.win_emu.callbacks.on_memory_protect(aligned_start, aligned_length, *requested_protection);
|
||||||
|
|
||||||
nt_memory_permission old_protection_value{};
|
nt_memory_permission old_protection_value{};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
c.win_emu.memory.protect_memory(aligned_start, static_cast<size_t>(aligned_length), requested_protection,
|
c.win_emu.memory.protect_memory(aligned_start, static_cast<size_t>(aligned_length), *requested_protection,
|
||||||
&old_protection_value);
|
&old_protection_value);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
@@ -180,7 +184,11 @@ namespace syscalls
|
|||||||
allocation_bytes = page_align_up(allocation_bytes);
|
allocation_bytes = page_align_up(allocation_bytes);
|
||||||
bytes_to_allocate.write(allocation_bytes);
|
bytes_to_allocate.write(allocation_bytes);
|
||||||
|
|
||||||
const auto protection = map_nt_to_emulator_protection(page_protection);
|
const auto protection = try_map_nt_to_emulator_protection(page_protection);
|
||||||
|
if (!protection.has_value())
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PAGE_PROTECTION;
|
||||||
|
}
|
||||||
|
|
||||||
auto potential_base = base_address.read();
|
auto potential_base = base_address.read();
|
||||||
if (!potential_base)
|
if (!potential_base)
|
||||||
@@ -204,15 +212,15 @@ namespace syscalls
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (commit && !reserve &&
|
if (commit && !reserve &&
|
||||||
c.win_emu.memory.commit_memory(potential_base, static_cast<size_t>(allocation_bytes), protection))
|
c.win_emu.memory.commit_memory(potential_base, static_cast<size_t>(allocation_bytes), *protection))
|
||||||
{
|
{
|
||||||
c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, protection, true);
|
c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, *protection, true);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, protection, false);
|
c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, *protection, false);
|
||||||
|
|
||||||
return c.win_emu.memory.allocate_memory(potential_base, static_cast<size_t>(allocation_bytes), protection,
|
return c.win_emu.memory.allocate_memory(potential_base, static_cast<size_t>(allocation_bytes), *protection,
|
||||||
!commit)
|
!commit)
|
||||||
? STATUS_SUCCESS
|
? STATUS_SUCCESS
|
||||||
: STATUS_MEMORY_NOT_ALLOCATED;
|
: STATUS_MEMORY_NOT_ALLOCATED;
|
||||||
|
|||||||
Reference in New Issue
Block a user