远程DLL注入
介绍
远程线程技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。在进程中,可以通过CreateThread函数创建线程,被创建的新线程与主线程共享地址空间以及其它的资源。通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程的地址空间。
创建方法
首选通过OpenProcess来打开我们试图注入的进程(如果远程进程不允许打开,那么注入就无法进行了,这往往是由于权限不足导致,解决方法是通过种种途径提升本地进程的权限)
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, //允许所有
TRUE,
remoteProcessId); //远程进程ID值
然后,我们可以建立LoadLibraryW函数来加载DLL,LoadLibraryW函数时在kernel32.dll中定义,用来加载DLL文件,它只有一个参数,就是DLL文件的绝对路径名psLibFileName,也就是我们要加载的DLL文件名,但是由于DLL是在远程进程内调用的,所以还需要将这个文件名复制到远程地址空间,否则远程线程是无法读到这个参数。
SIZE_T pathSize = (lstrlenW(dllPath) + 1) * sizeof(WCHAR); //计算DLL路径名需要的内存空间大小
LPVOID startAddress = ::VirtualAllocEx(hProcess, nullptr, pathSize, MEM_COMMIT, PAGE_READWRITE); //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区
if (!startAddress)
{
return 0;
}
//使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间
if (!::WriteProcessMemory(hProcess, startAddress, dllPath, pathSize, nullptr))
{
return FALSE;
}
计算LoadLibraryW的入口地址。
PTHREAD_START_ROUTINE pfnStartAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
if (!pfnStartAddress)
{
return FALSE;
}
启动远程线程LoadLibraryW,通过远程线程调用注入的DLL文件
HANDLE hThread = ::CreateRemoteThreadEx(hProcess, nullptr, NULL, pfnStartAddress, startAddress, NULL, NULL, NULL);
if (!hThread)
{
return FALSE;
}
::WaitForSingleObject(hThread, INFINITE);
最后收尾工作
::CloseHandle(hThread);
::CloseHandle(hProcess);
根据进程名找到进程ID
#include <iostream>
#include<Windows.h>
#include<TlHelp32.h>
#include<tchar.h>
using namespace std;
DWORD GetPID(LPCTSTR exeName)
{
HANDLE hProcSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); //获取进程快照句柄
if (!hProcSnap)
{
return 0;
}
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(PROCESSENTRY32);
BOOL flag = ::Process32First(hProcSnap, &pe32);
while (flag)
{
wcout << pe32.szExeFile << endl;
if (!_tcscmp(pe32.szExeFile, exeName))
{
::CloseHandle(hProcSnap);
return pe32.th32ProcessID; //返回pid
}
flag = ::Process32Next(hProcSnap, &pe32); //获取下一个进程
}
::CloseHandle(hProcSnap);
return 0;
}
int main()
{
DWORD pid = ::GetPID(L"win32calc.exe");
return TRUE;
}