什么是纤程(Fibers)?
用一个类比:线程是进程内部的实体,那么纤程则又是纤程内部的实体。
在《Windows Internals(第六版)》一书中提到:
因为将 CPU 的执行从一个线程切换到另一个线程,将不可避免地涉及内核调度器,所以,这可能是一个开销昂贵的操作,如果两个线程经常频繁地来回切换则尤其如此。 Windows 实现了两种机制来降低这一开销:纤程(fiber)和用户模式调度( UMS , user-mode scheduling )。
纤程使得一个应用程序可以调度它自己的“线程”的执行过程,而不必依赖于 Windows 内置的基于优先级的调度机制。纤程也常被称为“轻量”线程:从调度的角度来看,它们对于内核是不可见的,因为它们是在用户模式下在 Kemel32.dll 中实现的。为了使用纤程,首先要调用 Windows 的 ConvertThreadToFiber 函数。该函数将当前线程转变成一个正在运行的纤程。之后,在转变得到的纤程中,通过调用 CreateFiber 函数,又可以创建额外的纤程(每个纤程可以有它自己的一组纤程)。然而,与线程不同的是,纤程不会自动执行,它必须由 SwitchToFiber 函数手工选中,然后才能执行。新的纤程会一直运行,直到退出,或者调用SwitchToFiber再次选择运行另一个纤程。
总结一下,纤程是执行单元,其必须由应用程序进行手动调度。纤程在对其进行调度的线程的上下文中运行。
本文中,企图通过利用和纤程相关的 Win32 API,来在本地进程中执行 shellcode。绕过一些防御设备对常见进程注入 API 的拦截。
为了使用纤程执行 Shellcode,调用链为:
- 将主线程转换为纤程1(这是必需的,因为只有一个纤程才可以创建另一个纤程)。使用
ConvertThreadToFiber
函数。 - 将shellcode写入某个内存位置并使其可执行,获取指向此位置的指针。可使用
VirtualAlloc
+memcpy
函数。 - 创建一个指向 Shellcode 位置的新纤程2——我们将使用在第一步中通过主线程转的纤程1来创建此纤程2。使用
CreateFiber
函数,传参的时候注意第二个参数指向第二步中获取的位置指针。 - 手工选中纤程2,执行纤程。至此 Shellcode 得以执行。使用
SwitchToFiber
函数。
说的够清楚了,于是不放具体代码示例......