首页 > 代码库 > 远程创建线程注入DLL
远程创建线程注入DLL
HANDLE WINAPI 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
);
hProcess [in] 线程所属进程的进程句柄.
该句柄必须具有 PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE,和PROCESS_VM_READ 访问权限.
lpThreadAttributes [in] 一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结指定了线程的安全属性 一般用NULL即可
dwStackSize [in] 线程初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
lpStartAddress [in] 在远程进程的地址空间中,该线程的线程函数的起始地址.
lpParameter [in] 传给线程函数的参数.
dwCreationFlags [in] 线程的创建标志.
值
含义
0 线程创建后立即运行
CREATE_SUSPENDED 0x00000004 线程创建后先将线程挂起,直到 ResumeThread 被调用.
lpThreadId [out] 指向所创建线程句柄的指针,如果创建失败,该参数为NULL.
原理:在目标进程中开启一个线程以执行LoadLibrary(Ex)操作。
步骤:
(1) 提升加载进程的权限
(1) 用VirtualAllocEx函数在远程进程的地址空间中分配一块内存存放参数
(2) 用WriteProcessMemory函数把DLL的路径名复制到(1)步骤分配的内存中
(3) 用GetProcAddress获取LoadLibrary(Ex)函数的实际地址
(4) 用CreateRemoteThread函数在远程进程中创建一个线程,让新线程调用正确的LoadLibrary(Ex)函数并在参数中传入(1)步骤分配的内存地址
(5) 用GetProcAddress获取FreeLibrary函数的实际地址
(6) 用CreateRemoteThread函数在远程进程中创建一个线程,让新线程调用正确的FreeLibrary函数并在参数中传入远程DLL的HMODULE
(7) 用VirtualFreeEx来释放(1)步骤分配的内存
**********************************************************************************
EXE部分
**********************************************************************************
// 远程线程注入DLL
#include <windows.h>
#include <stdio.h>
#define INJECTDLLNAME "RemoteThreadDllInjectDLL.dll"
//提升当前进程权限
void AdjustProcessTokenPrivilege()
{
LUID luidTmp;
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
OutputDebugString("AdjustProcessTokenPrivilege OpenProcessToken Failed ! \n");
return;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidTmp))
{
OutputDebugString("AdjustProcessTokenPrivilege LookupPrivilegeValue Failed ! \n");
CloseHandle(hToken);
return;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = luidTmp;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
OutputDebugString("AdjustProcessTokenPrivilege AdjustTokenPrivileges Failed ! \n");
CloseHandle(hToken);
return;
}
return;
}
void GetExePath(char* pExePath)
{
int pathlen = GetModuleFileName(NULL, pExePath, MAX_PATH);
while(1)
{
if(pExePath[pathlen--]==‘\\‘)
break;
}
pExePath[++pathlen] = 0;
}
int main(int argc,char **argv)
{
CHAR* pDllName = NULL;
HANDLE hProcess = NULL;
DWORD dwProcessId = 0;
LPVOID lpStartAddress = NULL;
LPVOID lpParaAddress = NULL;
HANDLE hRemoteThread = NULL;
DWORD dwExitHandle = 0;
// 获取一下DLL的路径
CHAR tmpPath[MAX_PATH] = {0};
GetExePath(tmpPath);
strcat(tmpPath,"\\");
strcat(tmpPath,INJECTDLLNAME);
pDllName = tmpPath;
printf("注入的DLL路径:%s \r\n", pDllName);
printf("输入要注入的进程ID:");
scanf("%d", &dwProcessId);
// 提升当前进程的权限
AdjustProcessTokenPrivilege();
// 打开目标进程
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
// 为目标进程分配内存
lpParaAddress = VirtualAllocEx(hProcess, NULL, strlen(pDllName), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
// 将要注入的DLL路径写入到目标进程
WriteProcessMemory(hProcess, lpParaAddress, pDllName, strlen(pDllName), 0);
// 获取LoadLibrary的地址
lpStartAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"),"LoadLibraryA");
// 创建远程线程执行注入DLL操作
hRemoteThread = CreateRemoteThread(hProcess,NULL,0,lpStartAddress,lpParaAddress,0,NULL);
// 等待其加载完毕
WaitForSingleObject(hRemoteThread,INFINITE);
CloseHandle(hRemoteThread);
system("pause");
// 获取GetModuleHandleA的地址
lpStartAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"),"GetModuleHandleA");
// 创建远程线程执行GetModuleHandleA操作
hRemoteThread = CreateRemoteThread(hProcess,NULL,0,lpStartAddress,lpParaAddress,0,NULL);
WaitForSingleObject(hRemoteThread,INFINITE);
GetExitCodeThread(hRemoteThread,&dwExitHandle);//线程的结束码即为Dll模块儿的句柄
CloseHandle(hRemoteThread);
// 获取FreeLibrary的地址
lpStartAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"),"FreeLibrary");
// 创建远程线程执行卸载DLL操作
hRemoteThread = CreateRemoteThread(hProcess,NULL,0,lpStartAddress,(LPVOID)dwExitHandle,0,NULL);
// 等待其卸载完毕
WaitForSingleObject(hRemoteThread,INFINITE);
CloseHandle(hRemoteThread);
// 释放资源
VirtualFreeEx(hProcess,lpParaAddress,0,MEM_RELEASE);
CloseHandle(hProcess);
system("pause");
return 0;
}