mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Fix creating suspended thread and parse create_flags
This commit is contained in:
@@ -971,6 +971,13 @@ union TEB_CROSS_TEB_FLAGS_UNION
|
||||
USHORT SpareCrossTebBits : 16;
|
||||
};
|
||||
|
||||
constexpr auto THREAD_CREATE_FLAGS_CREATE_SUSPENDED = 0x1;
|
||||
constexpr auto THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH = 0x2;
|
||||
constexpr auto THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER = 0x4;
|
||||
constexpr auto THREAD_CREATE_FLAGS_LOADER_WORKER = 0x10;
|
||||
constexpr auto THREAD_CREATE_FLAGS_SKIP_LOADER_INIT = 0x20;
|
||||
constexpr auto THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE = 0x40;
|
||||
|
||||
union TEB_SAME_TEB_FLAGS_UNION
|
||||
{
|
||||
USHORT SameTebFlags;
|
||||
|
||||
@@ -116,16 +116,18 @@ 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 bool suspended, const uint32_t id,
|
||||
const uint64_t argument, const uint64_t stack_size, const uint32_t create_flags, const uint32_t id,
|
||||
const bool initial_thread)
|
||||
: 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),
|
||||
create_flags(create_flags),
|
||||
last_registers(context.default_register_set)
|
||||
{
|
||||
this->suspended = create_flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED;
|
||||
|
||||
// native 64-bit
|
||||
if (!context.is_wow64_process)
|
||||
{
|
||||
@@ -154,6 +156,9 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context&
|
||||
teb_obj.CurrentLocale = 0x409;
|
||||
teb_obj.ProcessEnvironmentBlock = context.peb64.value();
|
||||
teb_obj.SameTebFlags.InitialThread = initial_thread;
|
||||
teb_obj.SameTebFlags.SkipThreadAttach = (create_flags & THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH) ? 1 : 0;
|
||||
teb_obj.SameTebFlags.LoaderWorker = (create_flags & THREAD_CREATE_FLAGS_LOADER_WORKER) ? 1 : 0;
|
||||
teb_obj.SameTebFlags.SkipLoaderInit = (create_flags & THREAD_CREATE_FLAGS_SKIP_LOADER_INIT) ? 1 : 0;
|
||||
});
|
||||
|
||||
return;
|
||||
@@ -212,6 +217,9 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context&
|
||||
|
||||
teb_obj.ProcessEnvironmentBlock = context.peb64.value();
|
||||
teb_obj.SameTebFlags.InitialThread = initial_thread;
|
||||
teb_obj.SameTebFlags.SkipThreadAttach = (create_flags & THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH) ? 1 : 0;
|
||||
teb_obj.SameTebFlags.LoaderWorker = (create_flags & THREAD_CREATE_FLAGS_LOADER_WORKER) ? 1 : 0;
|
||||
teb_obj.SameTebFlags.SkipLoaderInit = (create_flags & THREAD_CREATE_FLAGS_SKIP_LOADER_INIT) ? 1 : 0;
|
||||
teb_obj.StaticUnicodeString.MaximumLength = sizeof(teb_obj.StaticUnicodeBuffer);
|
||||
teb_obj.StaticUnicodeString.Buffer = this->teb64->value() + offsetof(TEB64, StaticUnicodeBuffer);
|
||||
|
||||
@@ -268,6 +276,9 @@ emulator_thread::emulator_thread(memory_manager& memory, const process_context&
|
||||
|
||||
teb32_obj.WowTebOffset = -0x2000;
|
||||
teb32_obj.InitialThread = initial_thread;
|
||||
teb32_obj.SkipThreadAttach = (create_flags & THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH) ? 1 : 0;
|
||||
teb32_obj.LoaderWorker = (create_flags & THREAD_CREATE_FLAGS_LOADER_WORKER) ? 1 : 0;
|
||||
teb32_obj.SkipLoaderInit = (create_flags & THREAD_CREATE_FLAGS_SKIP_LOADER_INIT) ? 1 : 0;
|
||||
|
||||
// Note: CurrentLocale and other fields will be initialized by WOW64 runtime
|
||||
});
|
||||
|
||||
@@ -49,7 +49,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,
|
||||
bool suspended, uint32_t id, bool initial_thread);
|
||||
uint32_t create_flags, uint32_t id, bool initial_thread);
|
||||
|
||||
emulator_thread(const emulator_thread&) = delete;
|
||||
emulator_thread& operator=(const emulator_thread&) = delete;
|
||||
@@ -86,6 +86,7 @@ class emulator_thread : public ref_counted_object
|
||||
bool await_any{false};
|
||||
bool waiting_for_alert{false};
|
||||
bool alerted{false};
|
||||
uint32_t create_flags{0};
|
||||
uint32_t suspended{0};
|
||||
std::optional<std::chrono::steady_clock::time_point> await_time{};
|
||||
|
||||
@@ -164,6 +165,7 @@ class emulator_thread : public ref_counted_object
|
||||
buffer.write(this->waiting_for_alert);
|
||||
buffer.write(this->alerted);
|
||||
|
||||
buffer.write(this->create_flags);
|
||||
buffer.write(this->suspended);
|
||||
buffer.write_optional(this->await_time);
|
||||
|
||||
@@ -209,6 +211,7 @@ class emulator_thread : public ref_counted_object
|
||||
buffer.read(this->waiting_for_alert);
|
||||
buffer.read(this->alerted);
|
||||
|
||||
buffer.read(this->create_flags);
|
||||
buffer.read(this->suspended);
|
||||
buffer.read_optional(this->await_time);
|
||||
|
||||
|
||||
@@ -525,9 +525,9 @@ generic_handle_store* process_context::get_handle_store(const handle handle)
|
||||
}
|
||||
|
||||
handle process_context::create_thread(memory_manager& memory, const uint64_t start_address, const uint64_t argument,
|
||||
const uint64_t stack_size, const bool suspended, const bool initial_thread)
|
||||
const uint64_t stack_size, const uint32_t create_flags, const bool initial_thread)
|
||||
{
|
||||
emulator_thread t{memory, *this, start_address, argument, stack_size, suspended, ++this->spawned_thread_count, initial_thread};
|
||||
emulator_thread t{memory, *this, start_address, argument, stack_size, create_flags, ++this->spawned_thread_count, initial_thread};
|
||||
auto [h, thr] = this->threads.store_and_get(std::move(t));
|
||||
this->callbacks_->on_thread_create(h, *thr);
|
||||
return h;
|
||||
|
||||
@@ -74,7 +74,7 @@ struct process_context
|
||||
const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container,
|
||||
const mapped_module* ntdll32 = nullptr);
|
||||
|
||||
handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size, bool suspended,
|
||||
handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size, uint32_t create_flags,
|
||||
bool initial_thread = false);
|
||||
|
||||
std::optional<uint16_t> find_atom(std::u16string_view name);
|
||||
|
||||
@@ -625,7 +625,7 @@ namespace syscalls
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const auto h = c.proc.create_thread(c.win_emu.memory, start_routine, argument, stack_size, create_flags & CREATE_SUSPENDED);
|
||||
const auto h = c.proc.create_thread(c.win_emu.memory, start_routine, argument, stack_size, create_flags);
|
||||
thread_handle.write(h);
|
||||
|
||||
if (!attribute_list)
|
||||
|
||||
@@ -371,7 +371,7 @@ 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,
|
||||
this->mod_manager.executable->size_of_stack_commit, false, true);
|
||||
this->mod_manager.executable->size_of_stack_commit, 0, true);
|
||||
|
||||
switch_to_thread(*this, main_thread_id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user