mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Support more syscalls
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user