0x0 废话
dll注入的方式和程序正常加载dll模块的本质上是相同的,无非是通过导入表加载,利用LoadLibrary加载和一些系统机制强制加载。要使程序动态加载一个dll文件,也就是执行程序原本没有的代码,势必要改变程序的控制流,创建一个新的线程可以做到这件事。最简单的远线程注入就是利用CreateRemoteThread和LoadLibrary两个API来完成了。
关于注入的介绍及两种经典注入方式:https://blog.csdn.net/qq_35713009/article/details/86721445。
一些安全相关软件对LoadLibrary这样的API十分敏感,且dll文件本身也容易被检测并删除,而所谓的反射型dll注入,可以解决这两个问题。
0x1 反射型dll注入
0x00 介绍
反射型dll注入其实就是自己实现了LoadLibrary的主要功能,它能够顺利将内存中的dll模块加载到目标进程中,并正常运行。因此,我们的dll文件会先被映射到内存中,然后加载到目标进程中,这两个过程都由我们来控制,比较灵活。如果我们使用LoadLibrary,那么dll文件一定会在某一时刻出现在磁盘中,这就有可能被安全软件秒删。而用反射型dll注入,dll文件可以从不出现在磁盘中,而直接从内存中加载。
0x01 实现思路
首先,我们需要一个注射器,它将一个dll文件映射到内存中,然后写入到目标进程空间中。其次,我们的dll文件需要一个导出函数ReflectiveLoader,它完成LoadLibrary的主要工作,将dll文件自身注入到目标进程中,注射器利用创建远线程的方式启动目标进程中的ReflectiveLoader,dll就会注入成功。
0x02 注射器
注射器的功能很简单,流程大概如下:
- 将dll文件读取到内存中
- 找到ReflectiveLoader的偏移位置
- 开辟目标进程内存空间
- 将dll模块写入到目标进程
- 使用CreateRemoteThread函数启动ReflectiveLoader
主要代码大致如下:
void Injector(const char* filepath, HANDLE hProcess)
{
LPVOID lpBuffer;
HANDLE hFile;
DWORD dwLength;
DWORD dwBytesRead;
DWORD dwThreadId;
ULONG_PTR lpReflectiveLoader;
LPVOID lpRemoteDllBuffer;
hFile = CreateFileA(filepath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
dwLength = GetFileSize(hFile, NULL);
lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
Re