mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
More syscalls
This commit is contained in:
@@ -132,7 +132,7 @@ namespace
|
||||
auto& export_directory_entry = optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
if (export_directory_entry.VirtualAddress == 0 || export_directory_entry.Size == 0)
|
||||
{
|
||||
return {};
|
||||
return binary;
|
||||
}
|
||||
|
||||
const auto* export_directory = reinterpret_cast<const IMAGE_EXPORT_DIRECTORY*>(ptr + export_directory_entry.
|
||||
|
||||
@@ -32,26 +32,51 @@ inline uint64_t page_align_up(const uint64_t value)
|
||||
return align_up(value, 0x1000);
|
||||
}
|
||||
|
||||
inline uint32_t get_memory_protection(const unicorn& uc, uint64_t address)
|
||||
template <typename T = void, typename F>
|
||||
T access_memory_regions(const unicorn& uc, const F& accessor)
|
||||
{
|
||||
uint32_t count{};
|
||||
uc_mem_region* regions{};
|
||||
|
||||
e(uc_mem_regions(uc, ®ions, &count));
|
||||
const auto _ = utils::finally([&]
|
||||
{
|
||||
uc_free(regions);
|
||||
});
|
||||
|
||||
for (const auto& region : std::span(regions, count))
|
||||
{
|
||||
if (is_within_start_and_end(address, region.begin, region.end))
|
||||
{
|
||||
return region.perms;
|
||||
}
|
||||
}
|
||||
uc_free(regions);
|
||||
});
|
||||
|
||||
return UC_PROT_NONE;
|
||||
return accessor(std::span(regions, count));
|
||||
}
|
||||
|
||||
inline uint32_t get_memory_protection(const unicorn& uc, const uint64_t address)
|
||||
{
|
||||
return access_memory_regions<uint32_t>(uc, [&](const std::span<uc_mem_region> regions) -> uint32_t
|
||||
{
|
||||
for (const auto& region : regions)
|
||||
{
|
||||
if (is_within_start_and_end(address, region.begin, region.end))
|
||||
{
|
||||
return region.perms;
|
||||
}
|
||||
}
|
||||
|
||||
return UC_PROT_NONE;
|
||||
});
|
||||
}
|
||||
|
||||
inline bool is_memory_allocated(const unicorn& uc, const uint64_t address)
|
||||
{
|
||||
return access_memory_regions<uint32_t>(uc, [&](const std::span<uc_mem_region> regions)
|
||||
{
|
||||
for (const auto& region : regions)
|
||||
{
|
||||
if (is_within_start_and_end(address, region.begin, region.end))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
inline uint32_t map_nt_to_unicorn_protection(const uint32_t nt_protection)
|
||||
@@ -102,4 +127,4 @@ inline uint32_t map_unicorn_to_nt_protection(const uint32_t unicorn_protection)
|
||||
}
|
||||
|
||||
return PAGE_READONLY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,61 @@ namespace
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
void handle_NtAllocateVirtualMemory(const unicorn& uc)
|
||||
{
|
||||
const auto process_handle = uc.reg(UC_X86_REG_R10);
|
||||
const unicorn_object<uint64_t> base_address{uc, uc.reg(UC_X86_REG_RDX)};
|
||||
const unicorn_object<uint64_t> bytes_to_allocate{uc, uc.reg(UC_X86_REG_R9)};
|
||||
//const auto allocation_type = uc.reg<uint32_t>(UC_X86_REG_R9D);
|
||||
const auto page_protection = static_cast<uint32_t>(uc.read_stack(6));
|
||||
|
||||
if (process_handle != ~0ULL)
|
||||
{
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, STATUS_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr auto allocation_granularity = 0x10000;
|
||||
const auto allocation_bytes = bytes_to_allocate.read();
|
||||
//allocation_bytes = align_up(allocation_bytes, allocation_granularity);
|
||||
//bytes_to_allocate.write(allocation_bytes);
|
||||
|
||||
const auto protection = map_nt_to_unicorn_protection(page_protection);
|
||||
|
||||
auto allocate_anywhere = false;
|
||||
auto allocation_base = base_address.read();
|
||||
if (!allocation_base)
|
||||
{
|
||||
allocate_anywhere = true;
|
||||
allocation_base = allocation_granularity;
|
||||
}
|
||||
else if (is_memory_allocated(uc, allocation_base))
|
||||
{
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, STATUS_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
bool succeeded = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
succeeded = uc_mem_map(uc, allocation_base, allocation_bytes, protection) == UC_ERR_OK;
|
||||
if (succeeded || !allocate_anywhere)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
allocation_base += allocation_granularity;
|
||||
}
|
||||
|
||||
base_address.write(allocation_base);
|
||||
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, succeeded
|
||||
? STATUS_SUCCESS
|
||||
: STATUS_NOT_SUPPORTED // No idea what the correct code is
|
||||
);
|
||||
}
|
||||
|
||||
void handle_NtAllocateVirtualMemoryEx(const unicorn& uc)
|
||||
{
|
||||
const auto process_handle = uc.reg(UC_X86_REG_R10);
|
||||
@@ -258,9 +313,9 @@ namespace
|
||||
}
|
||||
|
||||
constexpr auto allocation_granularity = 0x10000;
|
||||
auto allocation_bytes = bytes_to_allocate.read();
|
||||
allocation_bytes = align_up(allocation_bytes, allocation_granularity);
|
||||
bytes_to_allocate.write(allocation_bytes);
|
||||
const auto allocation_bytes = bytes_to_allocate.read();
|
||||
//allocation_bytes = align_up(allocation_bytes, allocation_granularity);
|
||||
//bytes_to_allocate.write(allocation_bytes);
|
||||
|
||||
const auto protection = map_nt_to_unicorn_protection(page_protection);
|
||||
|
||||
@@ -271,6 +326,11 @@ namespace
|
||||
allocate_anywhere = true;
|
||||
allocation_base = allocation_granularity;
|
||||
}
|
||||
else if (is_memory_allocated(uc, allocation_base))
|
||||
{
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, STATUS_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
bool succeeded = false;
|
||||
|
||||
@@ -285,6 +345,31 @@ namespace
|
||||
allocation_base += allocation_granularity;
|
||||
}
|
||||
|
||||
base_address.write(allocation_base);
|
||||
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, succeeded
|
||||
? STATUS_SUCCESS
|
||||
: STATUS_NOT_SUPPORTED // No idea what the correct code is
|
||||
);
|
||||
}
|
||||
|
||||
void handle_NtFreeVirtualMemory(const unicorn& uc)
|
||||
{
|
||||
const auto process_handle = uc.reg(UC_X86_REG_R10);
|
||||
const unicorn_object<uint64_t> base_address{uc, uc.reg(UC_X86_REG_RDX)};
|
||||
const unicorn_object<uint64_t> bytes_to_allocate{uc, uc.reg(UC_X86_REG_R8)};
|
||||
|
||||
if (process_handle != ~0ULL)
|
||||
{
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, STATUS_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto allocation_base = base_address.read();
|
||||
const auto allocation_size = bytes_to_allocate.read();
|
||||
|
||||
const auto succeeded = uc_mem_unmap(uc, allocation_base, allocation_size) == UC_ERR_OK;
|
||||
|
||||
uc.reg<uint64_t>(UC_X86_REG_RAX, succeeded
|
||||
? STATUS_SUCCESS
|
||||
: STATUS_NOT_SUPPORTED // No idea what the correct code is
|
||||
@@ -306,6 +391,12 @@ void handle_syscall(const unicorn& uc, process_context& context)
|
||||
case 0x12:
|
||||
handle_NtOpenKey(uc);
|
||||
break;
|
||||
case 0x18:
|
||||
handle_NtAllocateVirtualMemory(uc);
|
||||
break;
|
||||
case 0x1E:
|
||||
handle_NtFreeVirtualMemory(uc);
|
||||
break;
|
||||
case 0x19:
|
||||
handle_NtQueryProcessInformation(uc, context);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user