mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-20 12:13:57 +00:00
Bugfixes - minidump load, memory tail boundary (#568)
Minor change to allow minidump load to work with pages with copy permission set. File was probing memory via VirtualQuery incrementally, previously this ran forever as Sogen doesn't replicate Windows behaviour. Added exclusive allocation end boundary so that allocation / info check on last page of user space VA works. Modified memory_manager::find_free_allocation_base and memory_manager::get_region_info to use exclusive boundary. Added check to NtQueryVirtualMemory - now correctly returns STATUS_INVALID_PARAMETER when run against memory outside of user space VA. Kernel modules should use ZwQueryVirtualMemory not the user land API.
This commit is contained in:
@@ -504,7 +504,7 @@ uint64_t memory_manager::find_free_allocation_base(const size_t size, const uint
|
||||
start_address = align_up(region_end, ALLOCATION_GRANULARITY);
|
||||
}
|
||||
|
||||
if (start_address + size <= MAX_ALLOCATION_ADDRESS)
|
||||
if (start_address + size <= MAX_ALLOCATION_END_EXCL)
|
||||
{
|
||||
return start_address;
|
||||
}
|
||||
@@ -516,7 +516,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
|
||||
{
|
||||
region_info result{};
|
||||
result.start = MIN_ALLOCATION_ADDRESS;
|
||||
result.length = static_cast<size_t>(MAX_ALLOCATION_ADDRESS - result.start);
|
||||
result.length = static_cast<size_t>(MAX_ALLOCATION_END_EXCL - result.start);
|
||||
result.permissions = nt_memory_permission();
|
||||
result.initial_permissions = nt_memory_permission();
|
||||
result.allocation_base = {};
|
||||
@@ -541,7 +541,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
|
||||
if (lower_end <= address)
|
||||
{
|
||||
result.start = lower_end;
|
||||
result.length = static_cast<size_t>(MAX_ALLOCATION_ADDRESS - result.start);
|
||||
result.length = static_cast<size_t>(MAX_ALLOCATION_END_EXCL - result.start);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
constexpr auto ALLOCATION_GRANULARITY = 0x0000000000010000ULL;
|
||||
constexpr auto MIN_ALLOCATION_ADDRESS = 0x0000000000010000ULL;
|
||||
constexpr auto MAX_ALLOCATION_ADDRESS = 0x00007ffffffeffffULL;
|
||||
constexpr auto MAX_ALLOCATION_END_EXCL = MAX_ALLOCATION_ADDRESS + 1ULL;
|
||||
|
||||
// This maps to the `basic_memory_region` struct defined in
|
||||
// emulator\memory_region.hpp
|
||||
|
||||
@@ -51,8 +51,10 @@ inline std::optional<nt_memory_permission> try_map_nt_to_emulator_protection(uin
|
||||
case PAGE_EXECUTE_READWRITE:
|
||||
common = memory_permission::all;
|
||||
break;
|
||||
case 0:
|
||||
case PAGE_EXECUTE_WRITECOPY:
|
||||
common = memory_permission::all;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,15 @@ namespace syscalls
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (base_address < MIN_ALLOCATION_ADDRESS || base_address >= MAX_ALLOCATION_END_EXCL)
|
||||
{
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(0);
|
||||
}
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (info_class == MemoryBasicInformation)
|
||||
{
|
||||
if (return_length)
|
||||
|
||||
@@ -443,8 +443,8 @@ void windows_emulator::setup_hooks()
|
||||
this->callbacks.on_rdtscp();
|
||||
|
||||
const auto ticks = this->clock_->timestamp_counter();
|
||||
this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF);
|
||||
this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF);
|
||||
this->emu().reg(x86_register::rax, static_cast<uint32_t>(ticks));
|
||||
this->emu().reg(x86_register::rdx, static_cast<uint32_t>(ticks >> 32));
|
||||
|
||||
// Return the IA32_TSC_AUX value in RCX (low 32 bits)
|
||||
auto tsc_aux = 0; // Need to replace this with proper CPUID later
|
||||
@@ -457,8 +457,8 @@ void windows_emulator::setup_hooks()
|
||||
this->callbacks.on_rdtsc();
|
||||
|
||||
const auto ticks = this->clock_->timestamp_counter();
|
||||
this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF);
|
||||
this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF);
|
||||
this->emu().reg(x86_register::rax, static_cast<uint32_t>(ticks));
|
||||
this->emu().reg(x86_register::rdx, static_cast<uint32_t>(ticks >> 32));
|
||||
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user