DLL注入
DLL注入:简而言之就是将一个不属于某进程的DLL文件加载到该进程当中。
Dll注入初衷是给第三方的应用程序进行一个功能的扩展。
API | 作用 |
---|
OpenProcess | 打开远程进程 |
VirtualAllocEx | 在远程进程中申请内存空间 |
WriteProcessMemory | 写入数据到远程进程 |
CreateRemoteThread | 创建远程线程 |
Loadlibrary | 加载模块 |
WaitForSingleObject | 等待信号 |
VirtualFreeEx | 释放远程进程内存空间 |
CloseHandle | 关闭句柄 |
常用API:
OpenProcess : 根据进程ID,打开进程句柄
| HANDLE OpenProcess( |
| [in] DWORD dwDesiredAccess, |
| [in] BOOL bInheritHandle, |
| [in] DWORD dwProcessId |
| ); |
VirtualAllocEx:在指定的进程中分配虚拟内存空间
| LPVOID VirtualAllocEx( |
| [in] HANDLE hProcess, |
| [in, optional] LPVOID lpAddress, |
| [in] SIZE_T dwSize, |
| [in] DWORD flAllocationType, |
| [in] DWORD flProtect |
| ); |
WriteProcessMemory: 往指定的进程写入内存
| BOOL WriteProcessMemory( |
| [in] HANDLE hProcess, |
| [in] LPVOID lpBaseAddress, |
| [in] LPCVOID lpBuffer, |
| [in] SIZE_T nSize, |
| [out] SIZE_T *lpNumberOfBytesWritten |
| ) |
CreateRemoteThread :创建进程的一个虚拟线程
| HANDLE CreateRemoteThread( |
| [in] HANDLE hProcess, |
| [in] LPSECURITY_ATTRIBUTES lpThreadAttributes, |
| [in] SIZE_T dwStackSize, |
| [in] LPTHREAD_START_ROUTINE lpStartAddress, |
| [in] LPVOID lpParameter, |
| [in] DWORD dwCreationFlags, |
| [out] LPDWORD lpThreadId |
| ); |
VirtualFreeEx : 释放开辟的虚拟内存
| BOOL VirtualFreeEx( |
| [in] HANDLE hProcess, |
| [in] LPVOID lpAddress, |
| [in] SIZE_T dwSize, |
| [in] DWORD dwFreeType |
| ); |
Main
- 打开指定的进程句柄。
| DWORD ProId = 4424; |
| |
| HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProId); |
- 为这个进程开辟虚拟内存
| |
| LPVOID Alloc=VirtualAllocEx(ProcessHandle, |
| NULL, |
| nlen, |
| MEM_RESERVE | MEM_COMMIT, |
| PAGE_READWRITE |
| ); |
| if (!Alloc) |
| { |
| printf("申请远程内存失败! %d\n", GetLastError()); |
| system("pause"); |
| return 0; |
| } |
- 往指定的进程中写入此虚拟内存的数据
| |
| SIZE_T realsize = 0; |
| WriteProcessMemory(ProcessHandle, |
| Alloc, |
| "MyDll.dll", |
| nlen, |
| &realsize); |
- 开辟进程的远程线程,并等待线程句柄处于有信号状态。
| |
| HANDLE MyHandle = CreateRemoteThread( |
| ProcessHandle, |
| NULL, |
| NULL, |
| (LPTHREAD_START_ROUTINE)LoadLibraryA, |
| Alloc, |
| NULL, |
| NULL |
| ); |
| WaitForSingleObject(MyHandle, -1); |
- 释放句柄及虚拟内存
| printf("LastError:%d\n", GetLastError()); |
| VirtualFreeEx(ProcessHandle, (char*)Alloc, NULL, MEM_RELEASE); |
| CloseHandle(ProcessHandle); |
| CloseHandle(MyHandle); |
完整代码:
| #include <iostream> |
| #include <Windows.h> |
| |
| int main() |
| { |
| DWORD nlen = strlen("MyDll.dll") + 1; |
| DWORD ProId = 4424; |
| |
| HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProId); |
| |
| |
| LPVOID Alloc=VirtualAllocEx(ProcessHandle, |
| NULL, |
| nlen, |
| MEM_RESERVE | MEM_COMMIT, |
| PAGE_READWRITE |
| ); |
| if (!Alloc) |
| { |
| printf("申请远程内存失败! %d\n", GetLastError()); |
| system("pause"); |
| return 0; |
| } |
| |
| SIZE_T realsize = 0; |
| WriteProcessMemory(ProcessHandle, |
| Alloc, |
| "MyDll.dll", |
| nlen, |
| &realsize); |
| |
| HANDLE MyHandle = CreateRemoteThread( |
| ProcessHandle, |
| NULL, |
| NULL, |
| (LPTHREAD_START_ROUTINE)LoadLibraryA, |
| Alloc, |
| NULL, |
| NULL |
| ); |
| WaitForSingleObject(MyHandle, -1); |
| printf("LastError:%d\n", GetLastError()); |
| VirtualFreeEx(ProcessHandle, (char*)Alloc, NULL, MEM_RELEASE); |
| CloseHandle(ProcessHandle); |
| CloseHandle(MyHandle); |
| system("pause"); |
| return 0; |
| } |
DLL
我们让它弹出一个框。
设置DLL文件项目的属性为 DLL动态库类型:

| #include <Windows.h> |
| #include<stdio.h> |
| |
| |
| BOOL WINAPI DllMain(DWORD Reason, LPVOID Param) |
| { |
| if (Reason == DLL_THREAD_ATTACH) |
| { |
| MessageBoxA(NULL, "DLL注入成功!", "提示", MB_OK); |
| } |
| return TRUE; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通