本项目实现了一种“等待线程劫持”的进程注入技术。它通过在目标进程中寻找处于等待状态的线程,并修改其函数返回地址来执行 Shellcode,从而避免了创建新线程或调用敏感 API。
- 定位目标线程:
- 程序接收一个目标进程 PID 作为参数。
- 使用
NtQuerySystemInformation遍历目标进程的所有线程。 - 寻找一个状态为
Waiting且等待原因为WrQueue(或指定原因) 的线程。这种线程通常在等待某个事件,其执行流暂时停滞。
- 寻找返回地址:
- 获取该等待线程的上下文(寄存器状态)。
- 通过线程的栈指针 (
RSP) 访问其调用栈,找到当前函数调用结束后将要返回的地址。程序会验证该地址是否位于ntdll.dll或kernel32.dll等核心模块中,以确保劫持的稳定性。
- 注入与劫持:
- 在目标进程中分配一小块内存,用于存放 Shellcode。
- Shellcode 被特殊包装过:头部是原始的返回地址,其后才是真正的载荷。
- 使用
WriteProcessMemory将位于栈上的原始返回地址,替换为指向 Shellcode 载荷部分的指针。
- 触发执行:
- 当线程等待的事件满足后(例如,一个 I/O 操作完成),线程被唤醒。
- 当被劫持的函数执行完毕,它会执行
ret指令,但此时不会返回到原始的调用者,而是跳转到我们的 Shellcode。 - Shellcode 执行完毕后,会再次跳转到我们预先保存在其头部的原始返回地址,使程序流程得以恢复,增加了隐蔽性。
- 使用 Visual Studio 打开
waiting_hijacking.sln并编译。 - 执行命令:
waiting_hijacking.exe <PID> [可选的shellcode文件路径]- 如果不提供 shellcode 文件,程序将使用内置的、弹计算器的 shellcode。 .