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:
@@ -2,6 +2,10 @@
|
||||
|
||||
// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
#ifndef OS_WINDOWS
|
||||
#define CREATE_SUSPENDED 0x00000004
|
||||
#endif
|
||||
|
||||
#define CONTEXT_X86_MAIN 0x00010000
|
||||
#define CONTEXT_AMD64_MAIN 0x100000
|
||||
#define CONTEXT_CONTROL_32 (CONTEXT_X86_MAIN | 0x1L)
|
||||
|
||||
@@ -43,6 +43,7 @@ using NTSTATUS = std::uint32_t;
|
||||
#define STATUS_INVALID_ADDRESS ((NTSTATUS)0xC0000141L)
|
||||
#define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L)
|
||||
#define STATUS_CONNECTION_REFUSED ((NTSTATUS)0xC0000236L)
|
||||
#define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS)0xC0000245L)
|
||||
#define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS)0xC0000328L)
|
||||
|
||||
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
|
||||
|
||||
@@ -96,12 +96,14 @@ namespace
|
||||
}
|
||||
|
||||
emulator_thread::emulator_thread(memory_manager& memory, const process_context& context, const uint64_t start_address,
|
||||
const uint64_t argument, const uint64_t stack_size, const uint32_t id)
|
||||
const uint64_t argument, const uint64_t stack_size, const bool suspended,
|
||||
const uint32_t id)
|
||||
: memory_ptr(&memory),
|
||||
stack_size(page_align_up(std::max(stack_size, static_cast<uint64_t>(STACK_SIZE)))),
|
||||
start_address(start_address),
|
||||
argument(argument),
|
||||
id(id),
|
||||
suspended(suspended),
|
||||
last_registers(context.default_register_set)
|
||||
{
|
||||
this->stack_base = memory.allocate_memory(this->stack_size, memory_permission::read_write);
|
||||
@@ -151,7 +153,7 @@ bool emulator_thread::is_terminated() const
|
||||
|
||||
bool emulator_thread::is_thread_ready(process_context& process, utils::clock& clock)
|
||||
{
|
||||
if (this->is_terminated())
|
||||
if (this->is_terminated() || this->suspended > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class emulator_thread : public ref_counted_object
|
||||
}
|
||||
|
||||
emulator_thread(memory_manager& memory, const process_context& context, uint64_t start_address, uint64_t argument,
|
||||
uint64_t stack_size, uint32_t id);
|
||||
uint64_t stack_size, bool suspended, uint32_t id);
|
||||
|
||||
emulator_thread(const emulator_thread&) = delete;
|
||||
emulator_thread& operator=(const emulator_thread&) = delete;
|
||||
@@ -54,6 +54,7 @@ class emulator_thread : public ref_counted_object
|
||||
bool await_any{false};
|
||||
bool waiting_for_alert{false};
|
||||
bool alerted{false};
|
||||
uint32_t suspended{0};
|
||||
std::optional<std::chrono::steady_clock::time_point> await_time{};
|
||||
|
||||
std::optional<NTSTATUS> pending_status{};
|
||||
@@ -123,6 +124,8 @@ class emulator_thread : public ref_counted_object
|
||||
buffer.write(this->waiting_for_alert);
|
||||
buffer.write(this->alerted);
|
||||
|
||||
buffer.write(this->suspended);
|
||||
|
||||
buffer.write_optional(this->await_time);
|
||||
buffer.write_optional(this->pending_status);
|
||||
buffer.write_optional(this->gs_segment);
|
||||
@@ -156,6 +159,8 @@ class emulator_thread : public ref_counted_object
|
||||
buffer.read(this->waiting_for_alert);
|
||||
buffer.read(this->alerted);
|
||||
|
||||
buffer.read(this->suspended);
|
||||
|
||||
buffer.read_optional(this->await_time);
|
||||
buffer.read_optional(this->pending_status);
|
||||
buffer.read_optional(this->gs_segment, [this] { return emulator_allocator(*this->memory_ptr); });
|
||||
|
||||
@@ -198,9 +198,9 @@ void process_context::deserialize(utils::buffer_deserializer& buffer)
|
||||
}
|
||||
|
||||
handle process_context::create_thread(memory_manager& memory, const uint64_t start_address, const uint64_t argument,
|
||||
const uint64_t stack_size)
|
||||
const uint64_t stack_size, const bool suspended)
|
||||
{
|
||||
emulator_thread t{memory, *this, start_address, argument, stack_size, ++this->spawned_thread_count};
|
||||
emulator_thread t{memory, *this, start_address, argument, stack_size, suspended, ++this->spawned_thread_count};
|
||||
auto [h, thr] = this->threads.store_and_get(std::move(t));
|
||||
this->callbacks_->on_create_thread(h, *thr);
|
||||
return h;
|
||||
|
||||
@@ -50,7 +50,8 @@ struct process_context
|
||||
void setup(x64_emulator& emu, memory_manager& memory, const application_settings& app_settings,
|
||||
const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container);
|
||||
|
||||
handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size);
|
||||
handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size,
|
||||
bool suspended);
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const;
|
||||
void deserialize(utils::buffer_deserializer& buffer);
|
||||
|
||||
@@ -299,7 +299,7 @@ namespace
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (info_class == ThreadSchedulerSharedDataSlot)
|
||||
if (info_class == ThreadSchedulerSharedDataSlot || info_class == ThreadBasePriority)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1169,7 +1169,8 @@ namespace
|
||||
{
|
||||
if (info_class == SystemFlushInformation || info_class == SystemFeatureConfigurationInformation ||
|
||||
info_class == SystemSupportedProcessorArchitectures2 ||
|
||||
info_class == SystemFeatureConfigurationSectionInformation)
|
||||
info_class == SystemFeatureConfigurationSectionInformation ||
|
||||
info_class == SystemLogicalProcessorInformation)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -1453,7 +1454,8 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (info_class == ProcessEnclaveInformation || info_class == ProcessMitigationPolicy)
|
||||
if (info_class == ProcessEnclaveInformation || info_class == ProcessMitigationPolicy ||
|
||||
info_class == ProcessGroupInformation)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -2523,6 +2525,11 @@ namespace
|
||||
0xD4, 0x04, 0x4B, 0x68, 0x42, 0x34, 0x23, 0xBE, 0x69, 0x4E, 0xE9, 0x03, 0x00, 0x00,
|
||||
};
|
||||
|
||||
if (token_information_class == TokenAppContainerSid)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (token_information_class == TokenUser)
|
||||
{
|
||||
constexpr auto required_size = sizeof(sid) + 0x10;
|
||||
@@ -3507,7 +3514,7 @@ namespace
|
||||
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>>
|
||||
/*object_attributes*/,
|
||||
const handle process_handle, const uint64_t start_routine, const uint64_t argument,
|
||||
const ULONG /*create_flags*/, const EmulatorTraits<Emu64>::SIZE_T /*zero_bits*/,
|
||||
const ULONG create_flags, const EmulatorTraits<Emu64>::SIZE_T /*zero_bits*/,
|
||||
const EmulatorTraits<Emu64>::SIZE_T stack_size,
|
||||
const EmulatorTraits<Emu64>::SIZE_T /*maximum_stack_size*/,
|
||||
const emulator_object<PS_ATTRIBUTE_LIST<EmulatorTraits<Emu64>>> attribute_list)
|
||||
@@ -3517,7 +3524,8 @@ namespace
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const auto h = c.proc.create_thread(c.win_emu.memory, start_routine, argument, stack_size);
|
||||
const auto h = c.proc.create_thread(c.win_emu.memory, start_routine, argument, stack_size,
|
||||
create_flags & CREATE_SUSPENDED);
|
||||
thread_handle.write(h);
|
||||
|
||||
if (!attribute_list)
|
||||
@@ -3878,6 +3886,22 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetTimerResolution(const syscall_context&, const ULONG /*desired_resolution*/,
|
||||
const BOOLEAN set_resolution, const emulator_object<ULONG> current_resolution)
|
||||
{
|
||||
if (current_resolution)
|
||||
{
|
||||
current_resolution.write(0x0002625a);
|
||||
}
|
||||
|
||||
if (set_resolution)
|
||||
{
|
||||
return STATUS_TIMER_RESOLUTION_NOT_SET;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtSetContextThread(const syscall_context& c, const handle thread_handle,
|
||||
const emulator_object<CONTEXT64> thread_context)
|
||||
{
|
||||
@@ -3919,6 +3943,29 @@ namespace
|
||||
c.win_emu.yield_thread();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtResumeThread(const syscall_context& c, const handle thread_handle,
|
||||
const emulator_object<ULONG> previous_suspend_count)
|
||||
{
|
||||
auto* thread = c.proc.threads.get(thread_handle);
|
||||
if (!thread)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
const auto old_count = thread->suspended;
|
||||
if (previous_suspend_count)
|
||||
{
|
||||
previous_suspend_count.write(old_count);
|
||||
}
|
||||
|
||||
if (old_count > 0)
|
||||
{
|
||||
thread->suspended -= 1;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& handler_mapping)
|
||||
@@ -4051,6 +4098,8 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtSystemDebugControl);
|
||||
add_handler(NtRequestWaitReplyPort);
|
||||
add_handler(NtQueryDefaultLocale);
|
||||
add_handler(NtSetTimerResolution);
|
||||
add_handler(NtResumeThread);
|
||||
|
||||
#undef add_handler
|
||||
}
|
||||
|
||||
@@ -281,7 +281,8 @@ void windows_emulator::setup_process(const application_settings& app_settings)
|
||||
|
||||
this->dispatcher.setup(ntdll->exports, ntdll_data, win32u->exports, win32u_data);
|
||||
|
||||
const auto main_thread_id = context.create_thread(this->memory, this->mod_manager.executable->entry_point, 0, 0);
|
||||
const auto main_thread_id =
|
||||
context.create_thread(this->memory, this->mod_manager.executable->entry_point, 0, 0, false);
|
||||
switch_to_thread(*this, main_thread_id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user