我想使用线程挂起的方法将一段代码注入(inject)到正在运行的模块中。
- 暂停线程
- 获取线程上下文
- 做点什么
- 恢复线程
我的问题是,如果我当前注入(inject)的线程处于可警报/可等待模式(WaitForSingleObject、GetMessage),会发生什么情况。一旦我点击 ResumeThread 命令会发生什么。
最佳答案
我想,否则会发生同样的事情。
假设目标线程当前处于用户模式。您保存所有寄存器供以后使用,将 RIP
设置为指向您的代码并调用 ResumeThread()
。在某个时刻,您的代码开始执行,执行它所做的一切,恢复注入(inject)代码保存的所有寄存器,并让程序恢复正常运行。
现在假设目标线程正在等待。等待意味着线程执行一个系统调用,该调用告诉调度程序在某些事情发生(事件已发出信号等)之前不要调度线程执行。您保存用户模式上下文的寄存器(调用 sysenter
时的方式),将 RIP 设置为指向您的代码并调用 ResumeThread()
。一切都很好,但是调度程序仍然不会安排它执行,直到满足等待条件为止。
当等待最终结束时,线程确实完成了它在内核模式下的业务,返回到用户模式,而不是在 sysenter
之后执行 ret
命令执行您的代码。最后,您的代码恢复所有寄存器并跳转到保存的 RIP
(来自 ntdll!ZwWaitForSingleObject
或其他),一切照常进行。
最后,假设您正在执行可警告等待。这个故事和前两段差不多(你真的不需要我重复第三次,是吗?:)),除了等待函数返回之前它执行所有排队等候的用户 APC thread - 完全没有你的干预会发生 - 然后继续执行你的代码等。
所以基本上发生的事情就是您应该预料到的事情:
- 如果您调用
SetThreadContext()
,则用户模式上下文会更改,计算机会相应地运行,而不管线程是否在等待。 - 如果线程正在等待某事,它会继续等待同一件事,无论您是否调用了“SetThreadContext()”。
- 如果线程处于可警告等待状态,在系统调用返回之前,它会确保用户 APC 队列为空(因为存在用户 APC 并且它调用了它们,或者因为队列为空且“常规”等待条件终于发生了)。同样,这与您是否调用了
SetThreadContext()
无关。
关于c++ - 更改可警告/可等待线程的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34401154/