Implement ALPC port abstraction and implement DNS resolver port

This commit is contained in:
Igor Pissolati
2025-10-19 18:06:15 -03:00
parent 9453123db0
commit 248c09d554
15 changed files with 845 additions and 111 deletions

View File

@@ -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.log.print(color::dark_gray, "NtAlpcConnectPort: %s\n", u16_to_u8(port_name).c_str());
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;
}