mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 19:23:56 +00:00
Query memory info
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto MIN_ALLOCATION_ADDRESS = 0x0000000000010000;
|
||||
constexpr auto MAX_ALLOCATION_ADDRESS = 0x00007ffffffeffff;
|
||||
|
||||
void split_regions(memory_manager::committed_region_map& regions, const std::vector<uint64_t>& split_points)
|
||||
{
|
||||
for (auto i = regions.begin(); i != regions.end(); ++i)
|
||||
@@ -284,7 +287,7 @@ bool memory_manager::release_memory(const uint64_t address, size_t size)
|
||||
|
||||
uint64_t memory_manager::find_free_allocation_base(const size_t size) const
|
||||
{
|
||||
uint64_t start_address = 0x0000000000010000;
|
||||
uint64_t start_address = MIN_ALLOCATION_ADDRESS;
|
||||
|
||||
for (const auto& region : this->reserved_regions_)
|
||||
{
|
||||
@@ -296,7 +299,7 @@ uint64_t memory_manager::find_free_allocation_base(const size_t size) const
|
||||
start_address = page_align_up(region.first + region.second.length);
|
||||
}
|
||||
|
||||
if (start_address + size <= 0x00007ffffffeffff)
|
||||
if (start_address + size <= MAX_ALLOCATION_ADDRESS)
|
||||
{
|
||||
return start_address;
|
||||
}
|
||||
@@ -304,6 +307,75 @@ uint64_t memory_manager::find_free_allocation_base(const size_t size) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
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.pemissions = memory_permission::none;
|
||||
result.allocation_base = {};
|
||||
result.is_committed = false;
|
||||
result.is_reserved = false;
|
||||
|
||||
if (this->reserved_regions_.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
auto upper_bound = this->reserved_regions_.upper_bound(address);
|
||||
if (upper_bound == this->reserved_regions_.begin())
|
||||
{
|
||||
result.length = upper_bound->first - result.start;
|
||||
return result;
|
||||
}
|
||||
|
||||
const auto entry = --upper_bound;
|
||||
const auto lower_end = entry->first + entry->second.length;
|
||||
if (lower_end <= address)
|
||||
{
|
||||
result.start = lower_end;
|
||||
result.length = MAX_ALLOCATION_ADDRESS - result.start;
|
||||
return result;
|
||||
}
|
||||
|
||||
// We have a reserved region
|
||||
const auto& reserved_region = entry->second;
|
||||
const auto& committed_regions = reserved_region.committed_regions;
|
||||
|
||||
result.is_reserved = true;
|
||||
result.allocation_base = entry->first;
|
||||
result.start = result.allocation_base;
|
||||
result.length = reserved_region.length;
|
||||
|
||||
if (committed_regions.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
auto committed_bound = committed_regions.upper_bound(address);
|
||||
if (committed_bound == committed_regions.begin())
|
||||
{
|
||||
result.length = committed_bound->first - result.start;
|
||||
return result;
|
||||
}
|
||||
|
||||
const auto committed_entry = --committed_bound;
|
||||
const auto committed_lower_end = committed_entry->first + committed_entry->second.length;
|
||||
if (committed_lower_end <= address)
|
||||
{
|
||||
result.start = committed_lower_end;
|
||||
result.length = lower_end - result.start;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.is_committed = true;
|
||||
result.start = committed_entry->first;
|
||||
result.length = committed_entry->second.length;
|
||||
result.pemissions = committed_entry->second.pemissions;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
memory_manager::reserved_region_map::iterator memory_manager::find_reserved_region(const uint64_t address)
|
||||
{
|
||||
if (this->reserved_regions_.empty())
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
#include "memory_region.hpp"
|
||||
#include "address_utils.hpp"
|
||||
|
||||
struct region_info : basic_memory_region
|
||||
{
|
||||
uint64_t allocation_base{};
|
||||
bool is_reserved{};
|
||||
bool is_committed{};
|
||||
};
|
||||
|
||||
class memory_manager
|
||||
{
|
||||
public:
|
||||
@@ -27,25 +34,27 @@ public:
|
||||
virtual bool try_read_memory(uint64_t address, void* data, size_t size) = 0;
|
||||
virtual void write_memory(uint64_t address, const void* data, size_t size) = 0;
|
||||
|
||||
bool protect_memory(const uint64_t address, const size_t size, const memory_permission permissions,
|
||||
memory_permission* old_permissions = nullptr);
|
||||
bool protect_memory(uint64_t address, size_t size, memory_permission permissions,
|
||||
memory_permission* old_permissions = nullptr);
|
||||
|
||||
bool allocate_memory(const uint64_t address, const size_t size, const memory_permission permissions,
|
||||
const bool reserve_only = false);
|
||||
bool allocate_memory(uint64_t address, size_t size, memory_permission permissions,
|
||||
bool reserve_only = false);
|
||||
|
||||
bool commit_memory(const uint64_t address, const size_t size, const memory_permission permissions);
|
||||
bool decommit_memory(const uint64_t address, const size_t size);
|
||||
bool commit_memory(uint64_t address, size_t size, memory_permission permissions);
|
||||
bool decommit_memory(uint64_t address, size_t size);
|
||||
|
||||
bool release_memory(const uint64_t address, size_t size);
|
||||
bool release_memory(uint64_t address, size_t size);
|
||||
|
||||
uint64_t find_free_allocation_base(const size_t size) const;
|
||||
uint64_t find_free_allocation_base(size_t size) const;
|
||||
|
||||
region_info get_region_info(uint64_t address);
|
||||
|
||||
private:
|
||||
using reserved_region_map = std::map<uint64_t, reserved_region>;
|
||||
reserved_region_map reserved_regions_{};
|
||||
|
||||
reserved_region_map::iterator find_reserved_region(const uint64_t address);
|
||||
bool overlaps_reserved_region(const uint64_t address, const size_t size) const;
|
||||
reserved_region_map::iterator find_reserved_region(uint64_t address);
|
||||
bool overlaps_reserved_region(uint64_t address, size_t size) const;
|
||||
|
||||
virtual void map_memory(uint64_t address, size_t size, memory_permission permissions) = 0;
|
||||
virtual void unmap_memory(uint64_t address, size_t size) = 0;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#define KUSD_ADDRESS 0x7ffe0000
|
||||
|
||||
bool use_gdb = true;
|
||||
bool use_gdb = false;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -199,7 +199,12 @@ namespace
|
||||
|
||||
map_sections(emu, binary, ptr, *nt_headers);
|
||||
apply_relocations(emu, binary, optional_header);
|
||||
collect_exports(binary, ptr, optional_header);
|
||||
|
||||
static int i = 0;
|
||||
if (++i < 3)
|
||||
{
|
||||
collect_exports(binary, ptr, optional_header);
|
||||
}
|
||||
|
||||
return binary;
|
||||
}
|
||||
|
||||
@@ -535,39 +535,76 @@ namespace
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (info_class != MemoryImageInformation)
|
||||
if (info_class == MemoryBasicInformation)
|
||||
{
|
||||
printf("Unsupported memory info class: %X\n", info_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(MEMORY_BASIC_INFORMATION));
|
||||
}
|
||||
|
||||
if (memory_information_length != sizeof(MEMORY_BASIC_INFORMATION))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
const emulator_object<MEMORY_BASIC_INFORMATION> info{c.emu, memory_information};
|
||||
|
||||
info.access([&](MEMORY_BASIC_INFORMATION& image_info)
|
||||
{
|
||||
const auto region_info = c.emu.get_region_info(base_address);
|
||||
|
||||
assert(!region_info.is_committed || region_info.is_reserved);
|
||||
|
||||
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 = region_info.length;
|
||||
image_info.State = region_info.is_committed
|
||||
? MEM_COMMIT
|
||||
: (region_info.is_reserved
|
||||
? MEM_RESERVE
|
||||
: MEM_FREE);
|
||||
image_info.Protect = map_emulator_to_nt_protection(region_info.pemissions);
|
||||
image_info.Type = MEM_PRIVATE;
|
||||
});
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (return_length)
|
||||
if (info_class == MemoryImageInformation)
|
||||
{
|
||||
return_length.write(sizeof(MEMORY_IMAGE_INFORMATION));
|
||||
if (return_length)
|
||||
{
|
||||
return_length.write(sizeof(MEMORY_IMAGE_INFORMATION));
|
||||
}
|
||||
|
||||
if (memory_information_length != sizeof(MEMORY_IMAGE_INFORMATION))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (!is_within_start_and_length(base_address, c.proc.ntdll.image_base, c.proc.ntdll.size_of_image))
|
||||
{
|
||||
puts("Bad image request");
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const emulator_object<MEMORY_IMAGE_INFORMATION> info{c.emu, memory_information};
|
||||
|
||||
info.access([&](MEMORY_IMAGE_INFORMATION& image_info)
|
||||
{
|
||||
image_info.ImageBase = reinterpret_cast<void*>(c.proc.ntdll.image_base);
|
||||
image_info.SizeOfImage = c.proc.ntdll.size_of_image;
|
||||
});
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (memory_information_length != sizeof(MEMORY_IMAGE_INFORMATION))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (!is_within_start_and_length(base_address, c.proc.ntdll.image_base, c.proc.ntdll.size_of_image))
|
||||
{
|
||||
puts("Bad image request");
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const emulator_object<MEMORY_IMAGE_INFORMATION> info{c.emu, memory_information};
|
||||
|
||||
info.access([&](MEMORY_IMAGE_INFORMATION& image_info)
|
||||
{
|
||||
image_info.ImageBase = reinterpret_cast<void*>(c.proc.ntdll.image_base);
|
||||
image_info.SizeOfImage = c.proc.ntdll.size_of_image;
|
||||
});
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
printf("Unsupported memory info class: %X\n", info_class);
|
||||
c.emu.stop();
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtQuerySystemInformation(const syscall_context& c, const uint32_t info_class,
|
||||
@@ -1084,6 +1121,7 @@ namespace
|
||||
const auto context = thread_context.read();
|
||||
apply_context(c.emu, context);
|
||||
|
||||
// TODO
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user