diff --git a/src/windows_emulator/handles.hpp b/src/windows_emulator/handles.hpp index 35c208bc..c28661a8 100644 --- a/src/windows_emulator/handles.hpp +++ b/src/windows_emulator/handles.hpp @@ -10,6 +10,7 @@ struct handle_types symlink, directory, semaphore, + port, }; }; diff --git a/src/windows_emulator/main.cpp b/src/windows_emulator/main.cpp index 080ed938..b25fe9ac 100644 --- a/src/windows_emulator/main.cpp +++ b/src/windows_emulator/main.cpp @@ -79,12 +79,11 @@ namespace [i = std::move(info), object, &emu](const uint64_t address, size_t, uint64_t) { const auto rip = emu.emu().read_instruction_pointer(); - const auto* binary = emu.process().module_manager.find_by_address(rip); const auto offset = address - object.value(); printf("%s: %llX (%s) at %llX (%s)\n", i.get_type_name().c_str(), offset, i.get_member_name(offset).c_str(), rip, - binary ? binary->name.c_str() : ""); + emu.process().module_manager.find_name(rip)); }); } diff --git a/src/windows_emulator/module/module_manager.hpp b/src/windows_emulator/module/module_manager.hpp index cc3129ac..ea1854a1 100644 --- a/src/windows_emulator/module/module_manager.hpp +++ b/src/windows_emulator/module/module_manager.hpp @@ -12,7 +12,7 @@ public: mapped_module* find_by_address(const uint64_t address) { const auto entry = this->get_module(address); - if(entry != this->modules_.end()) + if (entry != this->modules_.end()) { return &entry->second; } @@ -20,6 +20,17 @@ public: return nullptr; } + const char* find_name(const uint64_t address) + { + const auto* mod = this->find_by_address(address); + if (!mod) + { + return ""; + } + + return mod->name.c_str(); + } + void serialize(utils::buffer_serializer& buffer) const; void deserialize(utils::buffer_deserializer& buffer); @@ -45,4 +56,4 @@ private: std::advance(upper_bound, -1); return upper_bound; } -}; \ No newline at end of file +}; diff --git a/src/windows_emulator/process_context.hpp b/src/windows_emulator/process_context.hpp index 4ac4423b..b2e590fa 100644 --- a/src/windows_emulator/process_context.hpp +++ b/src/windows_emulator/process_context.hpp @@ -76,6 +76,25 @@ struct semaphore } }; +struct port +{ + std::wstring name{}; + uint64_t view_base{}; + + void serialize(utils::buffer_serializer& buffer) const + { + buffer.write(this->name); + buffer.write(this->view_base); + } + + void deserialize(utils::buffer_deserializer& buffer) + { + buffer.read(this->name); + buffer.read(this->view_base); + } +}; + + struct process_context { process_context(x64_emulator& emu) @@ -107,6 +126,7 @@ struct process_context handle_store events{}; handle_store files{}; handle_store semaphores{}; + handle_store ports{}; std::map atoms{}; emulator_allocator gs_segment; @@ -129,6 +149,7 @@ struct process_context buffer.write(this->events); buffer.write(this->files); buffer.write(this->semaphores); + buffer.write(this->ports); buffer.write_map(this->atoms); buffer.write(this->gs_segment); } @@ -156,6 +177,7 @@ struct process_context buffer.read(this->events); buffer.read(this->files); buffer.read(this->semaphores); + buffer.read(this->ports); buffer.read_map(this->atoms); buffer.read(this->gs_segment); } diff --git a/src/windows_emulator/syscalls.cpp b/src/windows_emulator/syscalls.cpp index 27ae5479..c17d418a 100644 --- a/src/windows_emulator/syscalls.cpp +++ b/src/windows_emulator/syscalls.cpp @@ -1,5 +1,8 @@ #include "std_include.hpp" #include "syscalls.hpp" + +#include + #include "context_frame.hpp" #include "emulator_utils.hpp" @@ -287,7 +290,7 @@ namespace NTSTATUS handle_NtTraceEvent() { - return STATUS_NOT_SUPPORTED; + return STATUS_SUCCESS; } NTSTATUS handle_NtOpenThreadToken() @@ -1224,24 +1227,33 @@ namespace return STATUS_SUCCESS; } - NTSTATUS handle_NtConnectPort(const syscall_context& c, const emulator_object /*client_port_handle*/, + NTSTATUS handle_NtConnectPort(const syscall_context& c, const emulator_object client_port_handle, const emulator_object server_port_name, const emulator_object /*security_qos*/, const emulator_object client_shared_memory, - const emulator_object /*server_shared_memory*/, + const emulator_object server_shared_memory, const emulator_object /*maximum_message_length*/, uint64_t /*connection_info*/, const emulator_object /*connection_info_length*/) { - const auto port_name = read_unicode_string(c.emu, server_port_name); + auto port_name = read_unicode_string(c.emu, server_port_name); printf("NtConnectPort: %S\n", port_name.c_str()); + port p{}; + p.name = std::move(port_name); + + const auto xx = server_shared_memory.read(); + client_shared_memory.access([&](PORT_VIEW& view) { - const auto address = c.emu.allocate_memory(view.ViewSize, memory_permission::read_write); - view.ViewBase = reinterpret_cast(address); + p.view_base = c.emu.allocate_memory(view.ViewSize, memory_permission::read_write); + view.ViewBase = reinterpret_cast(p.view_base); + view.ViewRemoteBase = view.ViewBase; }); + const auto handle = c.proc.ports.store(std::move(p)); + client_port_handle.write(handle.bits); + return STATUS_SUCCESS; } @@ -1284,7 +1296,8 @@ namespace NTSTATUS handle_NtQueryWnfStateNameInformation() { puts("NtQueryWnfStateNameInformation not supported"); - return STATUS_NOT_SUPPORTED; + //return STATUS_NOT_SUPPORTED; + return STATUS_SUCCESS; } NTSTATUS handle_NtOpenProcessToken() @@ -1323,9 +1336,9 @@ namespace return STATUS_NOT_SUPPORTED; } - NTSTATUS handle_NtAlpcSendWaitReceivePort(const syscall_context& /*c*/, const uint64_t /*port_handle*/, - const ULONG /*flags*/, - const emulator_object /*send_message*/, + NTSTATUS handle_NtAlpcSendWaitReceivePort(const syscall_context& c, const uint64_t port_handle, + const ULONG flags, + const emulator_object send_message, const emulator_object /*send_message_attributes*/ , const emulator_object receive_message, @@ -1334,10 +1347,18 @@ namespace /*receive_message_attributes*/, const emulator_object /*timeout*/) { - receive_message.access([](PORT_MESSAGE& msg) + const auto* port = c.proc.ports.get(port_handle); + if (!port) { - msg.u1.Length = 0; - }); + return STATUS_INVALID_HANDLE; + } + + const emulator_object data{c.emu, receive_message.value() + 0x48}; + const auto dest = data.read(); + const auto base = reinterpret_cast(dest.Base); + + const auto value = base + 0x10; + c.emu.write_memory(base + 8, &value, sizeof(value)); return STATUS_SUCCESS; } @@ -1665,7 +1686,7 @@ void syscall_dispatcher::add_handlers() } #ifndef NDEBUG - if(!handler_mapping.empty()) + if (!handler_mapping.empty()) { throw std::runtime_error("Unmapped handlers!"); } diff --git a/src/windows_emulator/windows_emulator.cpp b/src/windows_emulator/windows_emulator.cpp index aaeda220..af4ca0fc 100644 --- a/src/windows_emulator/windows_emulator.cpp +++ b/src/windows_emulator/windows_emulator.cpp @@ -249,7 +249,7 @@ namespace context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS& 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; @@ -266,7 +266,7 @@ namespace } gs.make_unicode_string(proc_params.CommandLine, command_line); - gs.make_unicode_string(proc_params.CurrentDirectory.DosPath, file.parent_path().wstring()); + //gs.make_unicode_string(proc_params.CurrentDirectory.DosPath, file.parent_path().wstring()); gs.make_unicode_string(proc_params.ImagePathName, file.wstring()); const auto total_length = gs.get_next_address() - context.process_params.value(); @@ -549,15 +549,16 @@ void windows_emulator::setup_hooks() { const auto permission = get_permission_string(operation); const auto ip = this->emu().read_instruction_pointer(); + const char* name = this->process().module_manager.find_name(ip); if (type == memory_violation_type::protection) { - printf("Protection violation: %llX (%zX) - %s at %llX\n", address, size, permission.c_str(), ip); + printf("Protection violation: %llX (%zX) - %s at %llX (%s)\n", address, size, permission.c_str(), ip, name); } else if (type == memory_violation_type::unmapped) { - printf("Mapping violation: %llX (%zX) - %s at %llX\n", address, size, permission.c_str(), ip); + printf("Mapping violation: %llX (%zX) - %s at %llX (%s)\n", address, size, permission.c_str(), ip, name); } dispatch_access_violation(this->emu(), this->process().ki_user_exception_dispatcher, address, operation); @@ -577,8 +578,7 @@ void windows_emulator::setup_hooks() if (export_entry != binary->address_names.end()) { printf("Executing function: %s - %s (%llX)\n", binary->name.c_str(), - export_entry->second.c_str(), - address); + export_entry->second.c_str(), address); } else if (address == binary->entry_point) {