Support more syscalls

This commit is contained in:
momo5502
2024-12-21 20:18:59 +01:00
parent 98d3077d35
commit ce6cb0116b
4 changed files with 87 additions and 8 deletions

View File

@@ -71,6 +71,12 @@ public:
this->write_memory(address, &value, sizeof(value));
}
template <typename T>
void write_memory(void* address, const T& value)
{
this->write_memory(reinterpret_cast<uint64_t>(address), &value, sizeof(value));
}
void write_memory(void* address, const void* data, const size_t size)
{
this->write_memory(reinterpret_cast<uint64_t>(address), data, size);

View File

@@ -253,7 +253,8 @@ public:
std::wstring name{};
std::optional<NTSTATUS> exit_status{};
std::optional<handle> await_object{};
std::vector<handle> await_objects{};
bool await_any{false};
bool waiting_for_alert{false};
bool alerted{false};
std::optional<std::chrono::steady_clock::time_point> await_time{};
@@ -317,7 +318,8 @@ public:
buffer.write_string(this->name);
buffer.write_optional(this->exit_status);
buffer.write_optional(this->await_object);
buffer.write_vector(this->await_objects);
buffer.write(this->await_any);
buffer.write(this->waiting_for_alert);
buffer.write(this->alerted);
@@ -349,7 +351,8 @@ public:
buffer.read_string(this->name);
buffer.read_optional(this->exit_status);
buffer.read_optional(this->await_object);
buffer.read_vector(this->await_objects);
buffer.read(this->await_any);
buffer.read(this->waiting_for_alert);
buffer.read(this->alerted);

View File

@@ -399,6 +399,11 @@ namespace
return STATUS_NO_TOKEN;
}
NTSTATUS handle_NtOpenThreadTokenEx()
{
return STATUS_NO_TOKEN;
}
NTSTATUS handle_NtCreateEvent(const syscall_context& c, const emulator_object<handle> event_handle,
const ACCESS_MASK /*desired_access*/,
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
@@ -1764,6 +1769,12 @@ namespace
return STATUS_NOT_SUPPORTED;
}
NTSTATUS handle_NtOpenProcessTokenEx()
{
//puts("NtOpenProcessToken not supported");
return STATUS_NOT_SUPPORTED;
}
NTSTATUS handle_NtQuerySecurityAttributesToken()
{
//puts("NtQuerySecurityAttributesToken not supported");
@@ -2554,6 +2565,46 @@ namespace
return FALSE;
}
NTSTATUS handle_NtWaitForMultipleObjects(const syscall_context& c, const ULONG count,
const emulator_object<handle> handles, const WAIT_TYPE wait_type,
const BOOLEAN alertable, const emulator_object<LARGE_INTEGER> timeout)
{
if (alertable)
{
c.win_emu.logger.print(color::gray, "Alertable NtWaitForMultipleObjects not supported yet!\n");
}
if (wait_type != WaitAny && wait_type != WaitAll)
{
puts("Wait type not supported!");
c.emu.stop();
return STATUS_NOT_SUPPORTED;
}
auto& t = c.win_emu.current_thread();
t.await_objects.clear();
t.await_any = wait_type == WaitAny;
for (ULONG i = 0; i < count; ++i)
{
const auto h = handles.read(i);
if (h.value.type != handle_types::thread && h.value.type != handle_types::event)
{
c.win_emu.logger.print(color::gray, "Unsupported handle type for NtWaitForMultipleObjects!\n");
return STATUS_NOT_SUPPORTED;
}
}
if (timeout.value() && !t.await_time.has_value())
{
t.await_time = convert_delay_interval_to_time_point(timeout.read());
}
c.win_emu.yield_thread();
return STATUS_SUCCESS;
}
NTSTATUS handle_NtWaitForSingleObject(const syscall_context& c, const handle h,
const BOOLEAN alertable,
const emulator_object<LARGE_INTEGER> timeout)
@@ -2570,7 +2621,8 @@ namespace
}
auto& t = c.win_emu.current_thread();
t.await_object = h;
t.await_objects = {h};
t.await_any = false;
if (timeout.value() && !t.await_time.has_value())
{
@@ -2690,6 +2742,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtFreeVirtualMemory);
add_handler(NtQueryVirtualMemory);
add_handler(NtOpenThreadToken);
add_handler(NtOpenThreadTokenEx);
add_handler(NtQueryPerformanceCounter);
add_handler(NtQuerySystemInformation);
add_handler(NtCreateEvent);
@@ -2715,6 +2768,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtDeviceIoControlFile);
add_handler(NtQueryWnfStateData);
add_handler(NtOpenProcessToken);
add_handler(NtOpenProcessTokenEx);
add_handler(NtQuerySecurityAttributesToken);
add_handler(NtQueryLicenseValue);
add_handler(NtTestAlert);
@@ -2766,6 +2820,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtGetCurrentProcessorNumberEx);
add_handler(NtQueryObject);
add_handler(NtQueryAttributesFile);
add_handler(NtWaitForMultipleObjects);
#undef add_handler
}

View File

@@ -591,7 +591,7 @@ void emulator_thread::mark_as_ready(const NTSTATUS status)
{
this->pending_status = status;
this->await_time = {};
this->await_object = {};
this->await_objects = {};
// TODO: Find out if this is correct
if (this->waiting_for_alert)
@@ -625,11 +625,26 @@ bool emulator_thread::is_thread_ready(windows_emulator& win_emu)
return false;
}
if (this->await_object.has_value())
if (!this->await_objects.empty())
{
if (is_object_signaled(win_emu.process(), *this->await_object))
bool all_signaled = true;
for (uint32_t i = 0; i < this->await_objects.size(); ++i)
{
this->mark_as_ready(STATUS_WAIT_0);
const auto& obj = this->await_objects[i];
const auto signaled = is_object_signaled(win_emu.process(), obj);
all_signaled &= signaled;
if (signaled && this->await_any)
{
this->mark_as_ready(STATUS_WAIT_0 + i);
return true;
}
}
if (!this->await_any && all_signaled)
{
this->mark_as_ready(STATUS_SUCCESS);
return true;
}