mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Support ProcessInstrumentationCallback
This commit is contained in:
@@ -1124,4 +1124,10 @@ struct PROCESS_PRIORITY_CLASS
|
||||
UCHAR PriorityClass;
|
||||
};
|
||||
|
||||
struct PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION
|
||||
{
|
||||
ULONG Version;
|
||||
ULONG Reserved;
|
||||
PVOID Callback;
|
||||
};
|
||||
// NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
|
||||
@@ -388,6 +388,7 @@ void process_context::setup(x86_64_emulator& emu, memory_manager& memory, regist
|
||||
this->rtl_user_thread_start = ntdll.find_export("RtlUserThreadStart");
|
||||
this->ki_user_apc_dispatcher = ntdll.find_export("KiUserApcDispatcher");
|
||||
this->ki_user_exception_dispatcher = ntdll.find_export("KiUserExceptionDispatcher");
|
||||
this->instrumentation_callback = 0;
|
||||
|
||||
this->default_register_set = emu.save_registers();
|
||||
}
|
||||
@@ -413,6 +414,7 @@ void process_context::serialize(utils::buffer_serializer& buffer) const
|
||||
buffer.write_optional(this->rtl_user_thread_start32);
|
||||
buffer.write(this->ki_user_apc_dispatcher);
|
||||
buffer.write(this->ki_user_exception_dispatcher);
|
||||
buffer.write(this->instrumentation_callback);
|
||||
|
||||
buffer.write(this->events);
|
||||
buffer.write(this->files);
|
||||
@@ -467,6 +469,7 @@ void process_context::deserialize(utils::buffer_deserializer& buffer)
|
||||
buffer.read_optional(this->rtl_user_thread_start32);
|
||||
buffer.read(this->ki_user_apc_dispatcher);
|
||||
buffer.read(this->ki_user_exception_dispatcher);
|
||||
buffer.read(this->instrumentation_callback);
|
||||
|
||||
buffer.read(this->events);
|
||||
buffer.read(this->files);
|
||||
|
||||
@@ -110,6 +110,7 @@ struct process_context
|
||||
uint64_t rtl_user_thread_start{};
|
||||
uint64_t ki_user_apc_dispatcher{};
|
||||
uint64_t ki_user_exception_dispatcher{};
|
||||
uint64_t instrumentation_callback{};
|
||||
|
||||
// For WOW64 processes
|
||||
std::optional<emulator_object<PEB32>> peb32;
|
||||
|
||||
@@ -101,6 +101,19 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
|
||||
}
|
||||
|
||||
entry->second.handler(c);
|
||||
|
||||
if (context.instrumentation_callback != 0 && entry->second.name != "NtContinue")
|
||||
{
|
||||
uint64_t rip_old = emu.reg<uint64_t>(x86_register::rip);
|
||||
|
||||
// The increase in RIP caused by executing the syscall here has not yet occurred.
|
||||
// If RIP is set directly, it will lead to an incorrect address, so the length of
|
||||
// the syscall instruction needs to be subtracted.
|
||||
emu.reg<uint64_t>(x86_register::rip, context.instrumentation_callback - 2);
|
||||
|
||||
emu.reg<uint64_t>(x86_register::r10, rip_old);
|
||||
}
|
||||
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
||||
@@ -281,6 +281,23 @@ namespace syscalls
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (info_class == ProcessInstrumentationCallback)
|
||||
{
|
||||
|
||||
if (process_information_length != sizeof(PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION))
|
||||
{
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION info;
|
||||
|
||||
c.emu.read_memory(process_information, &info, sizeof(PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION));
|
||||
|
||||
c.proc.instrumentation_callback = (uint64_t)info.Callback;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Unsupported info process class: %X\n", info_class);
|
||||
c.emu.stop();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user