远程线程模块注入
首先明白自己进程加载dll,可以直接LoadLibrary就可以把模块加载进去。但是远程的进程该怎么让它加载我另外写的模块呢?
思路:
如果能够让远程进程自己执行这段代码:
HINSTANCE hModule = LoadLibrary("InjectDll.dll");
就达到注入DLL的目的了.
步骤:
-
创建远程线程时,需要指定进程句柄/线程函数/线程函数的参数
- 进程句柄的获取,这里用PID来获取 OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
- 线程函数地址:本进程的LoadLibrary地址 == 远程进程的LoadLibrary地址
- 线程函数的参数:需要用VirtualAllocEx、WriteProcessMemory在远程进程中申请内存并写下dll名称作为函数参数
-
创建远程线程
HANDLE WINAPI CreateRemoteThread(
HANDLE hProcess, //要创建线程的进程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes, //安全属性
SIZE_T dwStackSize, //堆栈大小
LPTHREAD_START_ROUTINE lpStartAddress, //线程函数
LPVOID lpParameter, //线程函数参数
DWORD dwCreationFlags,//0 创建完毕立即调度 CREATE_SUSPENDED创建后挂起
LPDWORD lpThreadId //线程ID
);
-
等待线程函数结束, 获取线程退出码,即LoadLibrary的返回值,即dll的首地址
- WaitForSingleObject
- GetExitCodeThread
-
卸载dll函数FreeLibrary(),同样在远程进程中加载FreeLibrary达到卸载dll目的
-
释放为DLL名字申请的空间:VirtualFreeEx
-
关闭句柄
源代码如下、需要用到 “模块注入Dll.dll” dll文件
// 模块注入器.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <windows.h>
#define PID 10064 //PID更改
using namespace std;
int main()
{
//获取远程进程句柄 根据进程PID获取,这里我是直接看的,没用快照
HANDLE hProcess = NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, PID);
if (hProcess == NULL)
{
return 0;
}
//加载写入函数 也可以不加
HMODULE hKernel32Mod = NULL;
hKernel32Mod = LoadLibrary(TEXT("Kernel32.dll"));
typedef void* (__stdcall* pfVirtual)(HANDLE, PVOID, DWORD, DWORD, DWORD);
pfVirtual VirtualAllocEx = NULL;
if (hKernel32Mod != NULL)
{
VirtualAllocEx = (pfVirtual)GetProcAddress(hKernel32Mod,"VirtualAllocEx");
if (VirtualAllocEx == NULL)
{
cout << "申请空间函数加载失败" << endl;
return 0;
}
}
else
{
cout << "Kernel32模块加载失败" << endl;
return 0;
}
//申请空间
LPVOID SrcSpace = NULL;
SrcSpace = VirtualAllocEx(hProcess, NULL, 50, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (SrcSpace == NULL)
{
cout << "申请空间失败:"<< endl;
}
//向空间内写函数名 注意字符集 因为LoadLibrary使用的是宽字符
WCHAR dllName[50] = TEXT("模块注入Dll.dll");
if (SrcSpace == NULL)
return 0;
BOOL Ret = WriteProcessMemory(hProcess, SrcSpace, dllName, 50 , NULL);
if (!Ret)
{
cout << "写入空间失败" << endl;
return 0;
}
//创建远程线程
HANDLE hRemoteThread = NULL;
hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary,(LPVOID)SrcSpace, 0, 0);
if (hRemoteThread == NULL)
{
cout << "远程线程创建失败" << endl;
return 0;
}
//因为返回的是我线程的句柄,但我得得到模块的句柄 就是线程函数的退出码
//得到dll句柄
WaitForSingleObject(hRemoteThread, -1);
DWORD Handle;
GetExitCodeThread(hRemoteThread,&Handle);
//卸载远程Dll,注意点:FreeLibrary参数为dll句柄
cout << "卸载Dll" << endl;
system("pause");
HANDLE hExitThread = NULL;
hExitThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, (LPVOID)Handle, 0, NULL);
if (hExitThread == NULL)
return 0;
//得到退出码
WaitForSingleObject(hExitThread, -1);
HMODULE ExitThreadHandle;
GetExitCodeThread(hExitThread, (PDWORD)&ExitThreadHandle);
//释放远程空间
if (SrcSpace == NULL)
return 0;
Ret = VirtualFreeEx(hProcess, SrcSpace, 0, MEM_RELEASE);
if (Ret)
{
cout << "目标空间以释放" << endl;
}
//关闭句柄
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
CloseHandle(hExitThread);
return 0;
}
可用ollydbg查看运行中的进程模块
注入前:
注入后: