From 70400547ff2acc541fff246549122b8986aba461 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 12 Sep 2024 09:50:13 +0200 Subject: [PATCH] Properly map locale file --- src/common/utils/io.cpp | 124 ++++++++++++++++++ src/common/utils/io.hpp | 22 ++++ src/emulator/memory_manager.hpp | 11 ++ src/windows_emulator/main.cpp | 2 +- .../module/module_mapping.cpp | 9 +- src/windows_emulator/syscalls.cpp | 24 ++-- 6 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 src/common/utils/io.cpp create mode 100644 src/common/utils/io.hpp diff --git a/src/common/utils/io.cpp b/src/common/utils/io.cpp new file mode 100644 index 0000000..fb151bb --- /dev/null +++ b/src/common/utils/io.cpp @@ -0,0 +1,124 @@ +#include "io.hpp" +#include +#include + +namespace utils::io +{ + bool remove_file(const std::filesystem::path& file) + { + std::error_code ec{}; + return std::filesystem::remove(file, ec) && !ec; + } + + bool move_file(const std::filesystem::path& src, const std::filesystem::path& target) + { + copy_folder(src, target); + return remove_file(src); + } + + bool file_exists(const std::filesystem::path& file) + { + return std::ifstream(file).good(); + } + + bool write_file(const std::filesystem::path& file, const std::vector& data, const bool append) + { + if (file.has_parent_path()) + { + io::create_directory(file.parent_path()); + } + + std::basic_ofstream stream( + file, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : std::ofstream::out)); + + if (stream.is_open()) + { + stream.write(data.data(), static_cast(data.size())); + stream.close(); + return true; + } + + return false; + } + + std::vector read_file(const std::filesystem::path& file) + { + std::vector data; + read_file(file, &data); + return data; + } + + bool read_file(const std::filesystem::path& file, std::vector* data) + { + if (!data) return false; + data->clear(); + + std::ifstream stream(file, std::ios::binary); + if (!stream) return false; + + *data = std::vector{(std::istreambuf_iterator(stream)), std::istreambuf_iterator()}; + return true; + } + + std::size_t file_size(const std::filesystem::path& file) + { + std::ifstream stream(file, std::ios::binary); + + if (stream) + { + stream.seekg(0, std::ios::end); + return static_cast(stream.tellg()); + } + + return 0; + } + + bool create_directory(const std::filesystem::path& directory) + { + std::error_code ec{}; + return std::filesystem::create_directories(directory, ec) && !ec; + } + + bool directory_exists(const std::filesystem::path& directory) + { + std::error_code ec{}; + return std::filesystem::is_directory(directory, ec) && !ec; + } + + bool directory_is_empty(const std::filesystem::path& directory) + { + std::error_code ec{}; + return std::filesystem::is_empty(directory, ec) && !ec; + } + + void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target) + { + std::error_code ec{}; + std::filesystem::copy(src, target, + std::filesystem::copy_options::overwrite_existing | + std::filesystem::copy_options::recursive, ec); + } + + std::vector list_files(const std::filesystem::path& directory, const bool recursive) + { + std::error_code code{}; + std::vector files; + + if (recursive) + { + for (auto& file : std::filesystem::recursive_directory_iterator(directory, code)) + { + files.push_back(file.path()); + } + } + else + { + for (auto& file : std::filesystem::directory_iterator(directory, code)) + { + files.push_back(file.path()); + } + } + + return files; + } +} diff --git a/src/common/utils/io.hpp b/src/common/utils/io.hpp new file mode 100644 index 0000000..d61236b --- /dev/null +++ b/src/common/utils/io.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +namespace utils::io +{ + bool remove_file(const std::filesystem::path& file); + bool move_file(const std::filesystem::path& src, const std::filesystem::path& target); + bool file_exists(const std::filesystem::path& file); + bool write_file(const std::filesystem::path& file, const std::vector& data, bool append = false); + bool read_file(const std::filesystem::path& file, std::vector* data); + std::vector read_file(const std::filesystem::path& file); + size_t file_size(const std::filesystem::path& file); + bool create_directory(const std::filesystem::path& directory); + bool directory_exists(const std::filesystem::path& directory); + bool directory_is_empty(const std::filesystem::path& directory); + void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target); + + std::vector list_files(const std::filesystem::path& directory, bool recursive = false); +} diff --git a/src/emulator/memory_manager.hpp b/src/emulator/memory_manager.hpp index ca01cda..b7059ba 100644 --- a/src/emulator/memory_manager.hpp +++ b/src/emulator/memory_manager.hpp @@ -63,6 +63,17 @@ class memory_manager region_info get_region_info(uint64_t address); + uint64_t allocate_memory(const size_t size, const memory_permission permissions, const bool reserve_only = false) + { + const auto allocation_base = this->find_free_allocation_base(size); + if (!allocate_memory(allocation_base, size, permissions, reserve_only)) + { + return 0; + } + + return allocation_base; + } + private: using reserved_region_map = std::map; reserved_region_map reserved_regions_{}; diff --git a/src/windows_emulator/main.cpp b/src/windows_emulator/main.cpp index 9cd13b7..556899b 100644 --- a/src/windows_emulator/main.cpp +++ b/src/windows_emulator/main.cpp @@ -318,7 +318,7 @@ namespace context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS& proc_params) { proc_params.Length = sizeof(proc_params); - proc_params.Flags = 0x6001 | 0x80000000; // Prevent CsrClientConnectToServer + proc_params.Flags = 0x6001; //| 0x80000000; // Prevent CsrClientConnectToServer proc_params.ConsoleHandle = CONSOLE_HANDLE.h; proc_params.StandardOutput = STDOUT_HANDLE.h; diff --git a/src/windows_emulator/module/module_mapping.cpp b/src/windows_emulator/module/module_mapping.cpp index b37c0fb..5f7b3ba 100644 --- a/src/windows_emulator/module/module_mapping.cpp +++ b/src/windows_emulator/module/module_mapping.cpp @@ -2,6 +2,7 @@ #include "module_mapping.hpp" #include +#include #include namespace @@ -173,12 +174,6 @@ namespace } } - std::vector load_file(const std::filesystem::path& file) - { - std::ifstream stream(file, std::ios::in | std::ios::binary); - return {(std::istreambuf_iterator(stream)), std::istreambuf_iterator()}; - } - std::optional map_module(emulator& emu, const std::span data, std::filesystem::path file) { @@ -247,7 +242,7 @@ std::optional map_module_from_data(emulator& emu, const std::span std::optional map_module_from_file(emulator& emu, std::filesystem::path file) { - const auto data = load_file(file); + const auto data = utils::io::read_file(file); if (data.empty()) { return {}; diff --git a/src/windows_emulator/syscalls.cpp b/src/windows_emulator/syscalls.cpp index ccfa2ab..91b3422 100644 --- a/src/windows_emulator/syscalls.cpp +++ b/src/windows_emulator/syscalls.cpp @@ -2,6 +2,8 @@ #include "syscalls.hpp" #include "context_frame.hpp" +#include + struct syscall_context { x64_emulator& emu; @@ -631,8 +633,6 @@ namespace if (info_class == SystemProcessorInformation) { - puts("PROC INFO"); - c.proc.verbose = true; if (return_length) { return_length.write(sizeof(SYSTEM_PROCESSOR_INFORMATION)); @@ -1231,10 +1231,7 @@ namespace client_shared_memory.access([&](PORT_VIEW& view) { - const auto address = c.emu.find_free_allocation_base(view.ViewSize); - c.emu.allocate_memory(address, - view.ViewSize, memory_permission::read_write); - + const auto address = c.emu.allocate_memory(view.ViewSize, memory_permission::read_write); view.ViewBase = reinterpret_cast(address); }); @@ -1319,12 +1316,23 @@ namespace return STATUS_NOT_SUPPORTED; } - NTSTATUS handle_NtInitializeNlsFiles(const syscall_context& /*c*/, const emulator_object base_address, + NTSTATUS handle_NtInitializeNlsFiles(const syscall_context& c, const emulator_object base_address, const emulator_object default_locale_id, const emulator_object /*default_casing_table_size*/) { + const auto locale_file = utils::io::read_file(R"(C:\Windows\System32\locale.nls)"); + if (locale_file.empty()) + { + return STATUS_FILE_INVALID; + } + + const auto size = page_align_up(locale_file.size()); + const auto base = c.emu.allocate_memory(size, memory_permission::read); + c.emu.write_memory(base, locale_file.data(), locale_file.size()); + + base_address.write(base); default_locale_id.write(0x407); - base_address.write(0x1337); + return STATUS_SUCCESS; }