mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Support initial memory protection
This commit is contained in:
committed by
Maurice Heumann
parent
c4ba1e992f
commit
4f8c374b01
@@ -78,6 +78,7 @@ namespace utils
|
||||
static void serialize(buffer_serializer& buffer, const memory_manager::reserved_region& region)
|
||||
{
|
||||
buffer.write(region.is_mmio);
|
||||
buffer.write(region.initial_permission);
|
||||
buffer.write<uint64_t>(region.length);
|
||||
buffer.write_map(region.committed_regions);
|
||||
}
|
||||
@@ -85,6 +86,7 @@ namespace utils
|
||||
static void deserialize(buffer_deserializer& buffer, memory_manager::reserved_region& region)
|
||||
{
|
||||
buffer.read(region.is_mmio);
|
||||
buffer.read(region.initial_permission);
|
||||
region.length = static_cast<size_t>(buffer.read<uint64_t>());
|
||||
buffer.read_map(region.committed_regions);
|
||||
}
|
||||
@@ -258,6 +260,7 @@ bool memory_manager::allocate_memory(const uint64_t address, const size_t size,
|
||||
.try_emplace(address,
|
||||
reserved_region{
|
||||
.length = size,
|
||||
.initial_permission = permissions,
|
||||
})
|
||||
.first;
|
||||
|
||||
@@ -497,6 +500,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
|
||||
result.start = MIN_ALLOCATION_ADDRESS;
|
||||
result.length = MAX_ALLOCATION_ADDRESS - result.start;
|
||||
result.permissions = memory_permission::none;
|
||||
result.initial_permissions = memory_permission::none;
|
||||
result.allocation_base = {};
|
||||
result.allocation_length = result.length;
|
||||
result.is_committed = false;
|
||||
@@ -532,6 +536,7 @@ region_info memory_manager::get_region_info(const uint64_t address)
|
||||
result.allocation_length = reserved_region.length;
|
||||
result.start = result.allocation_base;
|
||||
result.length = result.allocation_length;
|
||||
result.initial_permissions = entry->second.initial_permission;
|
||||
|
||||
if (committed_regions.empty())
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ struct region_info : basic_memory_region
|
||||
size_t allocation_length{};
|
||||
bool is_reserved{};
|
||||
bool is_committed{};
|
||||
memory_permission initial_permissions{};
|
||||
};
|
||||
|
||||
using mmio_read_callback = std::function<void(uint64_t addr, void* data, size_t size)>;
|
||||
@@ -42,6 +43,7 @@ class memory_manager : public memory_interface
|
||||
struct reserved_region
|
||||
{
|
||||
size_t length{};
|
||||
memory_permission initial_permission{};
|
||||
committed_region_map committed_regions{};
|
||||
bool is_mmio{false};
|
||||
};
|
||||
|
||||
@@ -219,20 +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::read))
|
||||
if (!memory.allocate_memory(binary.image_base, binary.size_of_image, memory_permission::all))
|
||||
{
|
||||
binary.image_base = memory.find_free_allocation_base(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::read))
|
||||
if (!is_relocatable || !memory.allocate_memory(binary.image_base, 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);
|
||||
|
||||
binary.entry_point = binary.image_base + optional_header.AddressOfEntryPoint;
|
||||
|
||||
const auto* header_buffer = buffer.get_pointer_for_range(0, optional_header.SizeOfHeaders);
|
||||
|
||||
@@ -43,11 +43,11 @@ namespace syscalls
|
||||
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.AllocationProtect = 0;
|
||||
image_info.PartitionId = 0;
|
||||
image_info.RegionSize = static_cast<int64_t>(region_info.length);
|
||||
|
||||
image_info.Protect = map_emulator_to_nt_protection(region_info.permissions);
|
||||
image_info.AllocationProtect = map_emulator_to_nt_protection(region_info.initial_permissions);
|
||||
image_info.Type = MEM_PRIVATE;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user