Support initial memory protection

This commit is contained in:
momo5502
2025-04-13 17:59:47 +02:00
committed by Maurice Heumann
parent c4ba1e992f
commit 4f8c374b01
4 changed files with 13 additions and 4 deletions

View File

@@ -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())
{

View File

@@ -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};
};

View File

@@ -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);

View File

@@ -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;
});