Skip to content

Commit

Permalink
Small fixes and adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
momo5502 committed Sep 9, 2024
1 parent 29ad787 commit e054702
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 64 deletions.
6 changes: 3 additions & 3 deletions src/emulator/memory_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

namespace
{
constexpr auto MIN_ALLOCATION_ADDRESS = 0x0000000000010000;
constexpr auto MAX_ALLOCATION_ADDRESS = 0x00007ffffffeffff;
constexpr auto MIN_ALLOCATION_ADDRESS = 0x0000000000010000ULL;
constexpr auto MAX_ALLOCATION_ADDRESS = 0x00007ffffffeffffULL;

void split_regions(memory_manager::committed_region_map& regions, const std::vector<uint64_t>& split_points)
{
Expand Down Expand Up @@ -287,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 = MIN_ALLOCATION_ADDRESS;
uint64_t start_address = std::max(MIN_ALLOCATION_ADDRESS, 0x1000000000ULL);

for (const auto& region : this->reserved_regions_)
{
Expand Down
22 changes: 13 additions & 9 deletions src/windows_emulator/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ namespace
emu.reg<uint16_t>(x64_register::ss, 0x2B);
}

process_context setup_context(x64_emulator& emu)
process_context setup_context(x64_emulator& emu, const std::filesystem::path& file)
{
process_context context{};

Expand Down Expand Up @@ -325,9 +325,9 @@ namespace
proc_params.StandardInput = STDIN_HANDLE.h;
proc_params.StandardError = proc_params.StandardOutput;

gs.make_unicode_string(proc_params.CurrentDirectory.DosPath, L"C:\\Users\\mauri\\Desktop");
gs.make_unicode_string(proc_params.ImagePathName, L"C:\\Users\\mauri\\Desktop\\ConsoleApplication6.exe");
gs.make_unicode_string(proc_params.CommandLine, L"C:\\Users\\mauri\\Desktop\\ConsoleApplication6.exe");
gs.make_unicode_string(proc_params.CurrentDirectory.DosPath, file.parent_path().wstring());
gs.make_unicode_string(proc_params.ImagePathName, file.wstring());
gs.make_unicode_string(proc_params.CommandLine, file.wstring());
});

context.peb.access([&](PEB& peb)
Expand Down Expand Up @@ -518,10 +518,13 @@ namespace
{
const auto emu = unicorn::create_x64_emulator();

auto context = setup_context(*emu);
const std::filesystem::path application =
R"(C:\Program Files (x86)\Steam\steamapps\common\Hogwarts Legacy\Phoenix\Binaries\Win64\HogwartsLegacy.exe)";

auto context = setup_context(*emu, application);
context.module_manager = module_manager(*emu);

context.executable = context.module_manager.map_module(R"(C:\Users\mauri\Desktop\ConsoleApplication6.exe)");
context.executable = context.module_manager.map_module(application);

context.peb.access([&](PEB& peb)
{
Expand Down Expand Up @@ -574,18 +577,19 @@ namespace
return memory_violation_continuation::resume;
});

/*
watch_object(*emu, context.teb);
watch_object(*emu, context.peb);
watch_object(*emu, context.process_params);
watch_object(*emu, context.kusd);

*/
context.verbose = false;

emu->hook_memory_execution(0, std::numeric_limits<size_t>::max(), [&](const uint64_t address, const size_t)
{
++context.executed_instructions;

const auto* binary = context.module_manager.find_by_address(address);
/*const auto* binary = context.module_manager.find_by_address(address);
if (binary)
{
Expand All @@ -595,7 +599,7 @@ namespace
printf("Executing function: %s - %s (%llX)\n", binary->name.c_str(), export_entry->second.c_str(),
address);
}
}
}*/

if (!context.verbose)
{
Expand Down
7 changes: 5 additions & 2 deletions src/windows_emulator/module/module_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ module_manager::module_manager(emulator& emu)
{
}

mapped_module* module_manager::map_module(std::filesystem::path file)
mapped_module* module_manager::map_module(const std::filesystem::path& file)
{
auto mod = map_module_from_file(*this->emu_, std::move(file));
auto mod = map_module_from_file(*this->emu_, file);
if (!mod)
{
printf("Failed to map %s\n", file.generic_string().c_str());
return nullptr;
}

printf("Mapped %s at %llX\n", mod->path.generic_string().c_str(), mod->image_base);

const auto image_base = mod->image_base;
const auto entry = this->modules_.try_emplace(image_base, std::move(*mod));
return &entry.first->second;
Expand Down
2 changes: 1 addition & 1 deletion src/windows_emulator/module/module_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class module_manager
module_manager() = default; // TODO: Get rid of that
module_manager(emulator& emu);

mapped_module* map_module(std::filesystem::path file);
mapped_module* map_module(const std::filesystem::path& file);

mapped_module* find_by_address(const uint64_t address)
{
Expand Down
82 changes: 46 additions & 36 deletions src/windows_emulator/module/module_mapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,58 +178,68 @@ namespace
std::ifstream stream(file, std::ios::in | std::ios::binary);
return {(std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>()};
}
}


std::optional<mapped_module> map_module_from_data(emulator& emu, const std::span<const uint8_t> data,
std::filesystem::path file)
{
mapped_module binary{};
binary.path = std::move(file);
binary.name = binary.path.filename().string();
std::optional<mapped_module> map_module(emulator& emu, const std::span<const uint8_t> data,
std::filesystem::path file)
{
mapped_module binary{};
binary.path = std::move(file);
binary.name = binary.path.filename().string();

utils::safe_buffer_accessor buffer{data};
utils::safe_buffer_accessor buffer{data};

const auto dos_header = buffer.as<IMAGE_DOS_HEADER>(0).get();
const auto nt_headers_offset = dos_header.e_lfanew;
const auto dos_header = buffer.as<IMAGE_DOS_HEADER>(0).get();
const auto nt_headers_offset = dos_header.e_lfanew;

const auto nt_headers = buffer.as<IMAGE_NT_HEADERS>(nt_headers_offset).get();
auto& optional_header = nt_headers.OptionalHeader;
const auto nt_headers = buffer.as<IMAGE_NT_HEADERS>(nt_headers_offset).get();
auto& optional_header = nt_headers.OptionalHeader;

binary.image_base = optional_header.ImageBase;
binary.size_of_image = optional_header.SizeOfImage; // TODO: Sanitize
binary.image_base = optional_header.ImageBase;
binary.size_of_image = optional_header.SizeOfImage; // TODO: Sanitize

if (!emu.allocate_memory(binary.image_base, binary.size_of_image, memory_permission::read))
{
binary.image_base = emu.find_free_allocation_base(binary.size_of_image);
if ((optional_header.DllCharacteristics &
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 || //
!emu.allocate_memory(
binary.image_base, binary.size_of_image, memory_permission::read))
if (!emu.allocate_memory(binary.image_base, binary.size_of_image, memory_permission::read))
{
return {};
binary.image_base = emu.find_free_allocation_base(binary.size_of_image);
if ((optional_header.DllCharacteristics &
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 || //
!emu.allocate_memory(
binary.image_base, binary.size_of_image, memory_permission::read))
{
return {};
}
}
}

binary.entry_point = binary.image_base + optional_header.AddressOfEntryPoint;
binary.entry_point = binary.image_base + optional_header.AddressOfEntryPoint;

printf("Mapping %s at %llX\n", binary.path.generic_string().c_str(), binary.image_base);
const auto* header_buffer = buffer.get_pointer_for_range(0, optional_header.SizeOfHeaders);
emu.write_memory(binary.image_base, header_buffer,
optional_header.SizeOfHeaders);

const auto* header_buffer = buffer.get_pointer_for_range(0, optional_header.SizeOfHeaders);
emu.write_memory(binary.image_base, header_buffer,
optional_header.SizeOfHeaders);
map_sections(emu, binary, buffer, nt_headers, nt_headers_offset);

map_sections(emu, binary, buffer, nt_headers, nt_headers_offset);
auto mapped_memory = read_mapped_memory(emu, binary);
utils::safe_buffer_accessor<uint8_t> mapped_buffer{mapped_memory};

auto mapped_memory = read_mapped_memory(emu, binary);
utils::safe_buffer_accessor<uint8_t> mapped_buffer{mapped_memory};
apply_relocations(binary, mapped_buffer, optional_header);
collect_exports(binary, mapped_buffer, optional_header);

apply_relocations(binary, mapped_buffer, optional_header);
collect_exports(binary, mapped_buffer, optional_header);
emu.write_memory(binary.image_base, mapped_memory.data(), mapped_memory.size());

emu.write_memory(binary.image_base, mapped_memory.data(), mapped_memory.size());
return binary;
}
}

return binary;
std::optional<mapped_module> map_module_from_data(emulator& emu, const std::span<const uint8_t> data,
std::filesystem::path file)
{
try
{
return map_module(emu, data, std::move(file));
}
catch (...)
{
return {};
}
}

std::optional<mapped_module> map_module_from_file(emulator& emu, std::filesystem::path file)
Expand Down
62 changes: 49 additions & 13 deletions src/windows_emulator/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,28 +719,46 @@ namespace
return STATUS_NOT_SUPPORTED;
}

if (info_class != ProcessCookie)
if (info_class == ProcessCookie)
{
printf("Unsupported process info class: %X\n", info_class);
c.emu.stop();
if (return_length)
{
return_length.write(sizeof(uint32_t));
}

return STATUS_NOT_SUPPORTED;
}
if (process_information_length != sizeof(uint32_t))
{
return STATUS_BUFFER_OVERFLOW;
}

if (return_length)
{
return_length.write(sizeof(uint32_t));
const emulator_object<uint32_t> info{c.emu, process_information};
info.write(0x01234567);

return STATUS_SUCCESS;
}

if (process_information_length != sizeof(uint32_t))
if (info_class == ProcessDebugPort)
{
return STATUS_BUFFER_OVERFLOW;
if (return_length)
{
return_length.write(sizeof(DWORD_PTR));
}

if (process_information_length != sizeof(DWORD_PTR))
{
return STATUS_BUFFER_OVERFLOW;
}

const emulator_object<DWORD_PTR> info{c.emu, process_information};
info.write(0);

return STATUS_SUCCESS;
}

const emulator_object<uint32_t> info{c.emu, process_information};
info.write(0x01234567);
printf("Unsupported process info class: %X\n", info_class);
c.emu.stop();

return STATUS_SUCCESS;
return STATUS_NOT_SUPPORTED;
}

NTSTATUS handle_NtSetInformationProcess(const syscall_context& c, const uint64_t process_handle,
Expand Down Expand Up @@ -1097,6 +1115,23 @@ namespace

throw std::runtime_error("Unsupported file");
}

NTSTATUS handle_NtRaiseHardError(const syscall_context& c, const NTSTATUS error_status,
const ULONG /*number_of_parameters*/,
const emulator_object<UNICODE_STRING> /*unicode_string_parameter_mask*/,
const emulator_object<DWORD> /*parameters*/,
const HARDERROR_RESPONSE_OPTION /*valid_response_option*/,
const emulator_object<HARDERROR_RESPONSE> response)
{
if (response)
{
response.write(ResponseAbort);
}

printf("Hard error: %X\n", error_status);
c.emu.stop();
return STATUS_SUCCESS;
}
}

syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports)
Expand Down Expand Up @@ -1154,6 +1189,7 @@ syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports)
add_handler(NtContinue);
add_handler(NtTerminateProcess);
add_handler(NtWriteFile);
add_handler(NtRaiseHardError);

#undef add_handler
}
Expand Down

0 comments on commit e054702

Please sign in to comment.