mirror of
https://github.com/momo5502/emulator.git
synced 2026-02-01 00:41:02 +00:00
Implement ALPC port abstraction and implement DNS resolver port (#558)
This PR introduces an abstraction for ALPC ports to make them easier to manage in the future, and implements the DNS resolver port, at least enough to get host address queries working. There's a lot of code in this PR that I'm not very confident about, so don't hesitate on the feedback 😄 <img width="1377" height="624" alt="image" src="https://github.com/user-attachments/assets/4d56b84d-4b87-42ed-9bfa-be04dbbf3735" />
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "../std_include.hpp"
|
||||
#include "../emulator_utils.hpp"
|
||||
#include "../syscall_utils.hpp"
|
||||
#include "../port.hpp"
|
||||
|
||||
namespace syscalls
|
||||
{
|
||||
@@ -15,8 +16,18 @@ namespace syscalls
|
||||
auto port_name = read_unicode_string(c.emu, server_port_name);
|
||||
c.win_emu.callbacks.on_generic_access("Connecting port", port_name);
|
||||
|
||||
port p{};
|
||||
p.name = std::move(port_name);
|
||||
port_creation_data data{};
|
||||
client_shared_memory.access([&](PORT_VIEW64& view) {
|
||||
data.view_size = view.ViewSize;
|
||||
data.view_base = c.win_emu.memory.allocate_memory(static_cast<size_t>(data.view_size), memory_permission::read_write);
|
||||
view.ViewBase = data.view_base;
|
||||
view.ViewRemoteBase = view.ViewBase;
|
||||
});
|
||||
|
||||
port_container container{std::u16string(port_name), c.win_emu, data};
|
||||
|
||||
const auto handle = c.proc.ports.store(std::move(container));
|
||||
client_port_handle.write(handle);
|
||||
|
||||
if (connection_info)
|
||||
{
|
||||
@@ -25,15 +36,6 @@ namespace syscalls
|
||||
c.emu.write_memory(connection_info, zero_mem.data(), zero_mem.size());
|
||||
}
|
||||
|
||||
client_shared_memory.access([&](PORT_VIEW64& view) {
|
||||
p.view_base = c.win_emu.memory.allocate_memory(static_cast<size_t>(view.ViewSize), memory_permission::read_write);
|
||||
view.ViewBase = p.view_base;
|
||||
view.ViewRemoteBase = view.ViewBase;
|
||||
});
|
||||
|
||||
const auto handle = c.proc.ports.store(std::move(p));
|
||||
client_port_handle.write(handle);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -49,8 +51,53 @@ namespace syscalls
|
||||
maximum_message_length, connection_info, connection_info_length);
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcConnectPort(const syscall_context& c, const emulator_object<handle> port_handle,
|
||||
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> server_port_name,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> /*object_attributes*/,
|
||||
const emulator_pointer /*port_attributes*/, const ULONG /*flags*/,
|
||||
const emulator_pointer /*required_server_sid*/, const emulator_pointer /*connection_message*/,
|
||||
const emulator_object<EmulatorTraits<Emu64>::SIZE_T> /*buffer_length*/,
|
||||
const emulator_pointer /*out_message_attributes*/, const emulator_pointer /*in_message_attributes*/,
|
||||
const emulator_object<LARGE_INTEGER> /*timeout*/)
|
||||
{
|
||||
auto port_name = read_unicode_string(c.emu, server_port_name);
|
||||
c.win_emu.callbacks.on_generic_access("Connecting port", port_name);
|
||||
|
||||
port_container container{std::u16string(port_name), c.win_emu, {}};
|
||||
|
||||
const auto handle = c.proc.ports.store(std::move(container));
|
||||
port_handle.write(handle);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcConnectPortEx(const syscall_context& c, const emulator_object<handle> port_handle,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> connection_port_object_attributes,
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> /*client_port_object_attributes*/,
|
||||
const emulator_pointer port_attributes, const ULONG flags,
|
||||
const emulator_pointer /*server_security_requirements*/, const emulator_pointer connection_message,
|
||||
const emulator_object<EmulatorTraits<Emu64>::SIZE_T> buffer_length,
|
||||
const emulator_pointer out_message_attributes, const emulator_pointer in_message_attributes,
|
||||
const emulator_object<LARGE_INTEGER> timeout)
|
||||
{
|
||||
if (!connection_port_object_attributes)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
const auto attributes = connection_port_object_attributes.read();
|
||||
if (!attributes.ObjectName)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> port_name{c.emu, attributes.ObjectName};
|
||||
return handle_NtAlpcConnectPort(c, port_handle, port_name, connection_port_object_attributes, port_attributes, flags, {},
|
||||
connection_message, buffer_length, out_message_attributes, in_message_attributes, timeout);
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcSendWaitReceivePort(const syscall_context& c, const handle port_handle, const ULONG /*flags*/,
|
||||
const emulator_object<PORT_MESSAGE64> /*send_message*/,
|
||||
const emulator_object<PORT_MESSAGE64> send_message,
|
||||
const emulator_object<ALPC_MESSAGE_ATTRIBUTES>
|
||||
/*send_message_attributes*/,
|
||||
const emulator_object<PORT_MESSAGE64> receive_message,
|
||||
@@ -59,38 +106,30 @@ namespace syscalls
|
||||
/*receive_message_attributes*/,
|
||||
const emulator_object<LARGE_INTEGER> /*timeout*/)
|
||||
{
|
||||
const auto* port = c.proc.ports.get(port_handle);
|
||||
auto* port = c.proc.ports.get(port_handle);
|
||||
if (!port)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (port->name != u"\\Windows\\ApiPort")
|
||||
{
|
||||
c.win_emu.log.error("!!! BAD PORT\n");
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
lpc_message_context context{c.emu};
|
||||
context.send_message = send_message;
|
||||
context.receive_message = receive_message;
|
||||
|
||||
// TODO: Fix this. This is broken and wrong.
|
||||
|
||||
try
|
||||
{
|
||||
const emulator_object<PORT_DATA_ENTRY<EmulatorTraits<Emu64>>> data{c.emu, receive_message.value() + 0x48};
|
||||
const auto dest = data.read();
|
||||
const auto base = dest.Base;
|
||||
|
||||
const auto value = base + 0x10;
|
||||
c.emu.write_memory(base + 8, &value, sizeof(value));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return port->handle_message(c.win_emu, context);
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcConnectPort()
|
||||
NTSTATUS handle_NtAlpcQueryInformation()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcCreateSecurityContext()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtAlpcDeleteSecurityContext()
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user