c++线程注入学习
原理:
远程线程注入,首先在当前所有运行的进程中找到目标进程,然后将我们的dll的内容写入目标进程的私有空间中,最后通过关键的API:CreateRemoteThread创建线程。该线程只执行一个任务:loadlibrary加载我们的dll。
具体实现:
1.找到目标
原理简单,我们首先获得目前时刻正在运行的进程的列表,然后通过遍历搜索,找到列表中我们想要的进程,然后记录下进程的ID号。
hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
这个函数用来获得当前进程的快照,就是获得当前进程的列表啊。
然后通过下面的代码按顺序遍历这个列表,通过字符串对比,找到我们的目标:notepad.exe。代码如下:
DWORD ProcessFind(LPCTSTR Exename) //进程名称,notepad.exe
{
HANDLE hProcess=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);
if (!hProcess)
{
return FALSE;
}
PROCESSENTRY32 info;
info.dwSize=sizeof(PROCESSENTRY32);
if (!Process32First(hProcess,&info))
{
return FALSE;
}
while(TRUE)
{
if (_tcscmp(info.szExeFile,Exename) == 0)
{
return info.th32ProcessID;//返回进程的ID
}
if (!Process32Next(hProcess,&info))
{
return FALSE;
}
}
return FALSE;
}
上面这个代码段中关键函数分别是Process32First,Process32Next两个可以沿着列表搜索的函数还有一个字符串对比函数strcmp核对当前搜索的进程对象的名称是不是notepad.exe。
2.打开进程,把我们的dll写进去!
(1) 获取目标进程的句柄
在上一步获得目标进程的id后我们就可以打开进程,然后对进程进行操作。打开进程如下:
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,TRUE,ProcessID);
参数中的第一个是表明我们在打开进程的时候想要获得的权限,第三个是目标进程的ID。成功打开后,我们用hProcess存放打开的句柄。句柄嘛,大家都懂的,windows里都是用句柄访问和操作对象的嘛~~
(2)在目标进程内存中分配szDllName大小的内存
既然要往目标进程的私有空间写入数据,我们就要先在目标进程中申请和我们的dll一样大,或者更大的空间。申请如下:
SIZE_T PathSize = (_tcslen(DllPath)+1)*sizeof(TCHAR);
LPVOID StartAddress=VirtualAllocEx(hProcess,NULL,PathSize,MEM_COMMIT,PAGE_READWRITE);
参数中的PathSize是我们想要申请的尺寸,最后一个参数是读写权限。
空间申请好了,空间的首地址用StarAddress存着,然后就可以写数据了:
WriteProcessMemory(hProcess,StartAddress,DllPath,PathSize,NULL)
这个没啥好解释的,就是一个写内存的API。
至此在目标进程中已经有了我们dll邪恶的身影,最后当然是让目标进程加载我们的dll。
(3)获取LoadLibraryW() API的地址
PTHREAD_START_ROUTINE pfnStartAddress =(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),"LoadLibraryW");<strong>
</strong>
(4)在notepad.exe进程中运行线程
HANDLE hThread=CreateRemoteThreadEx(hProcess,NULL,NULL,pfnStartAddress,StartAddress,NULL,NULL,NULL);
(5)关闭线程和进程
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
依次使用以下函数:
OpenProcess //获取已知进程的句柄
VirtuallAllocEx //在进程中申请空间
WriteProcessMemory //向进程中写入东西
GetProcessAddress //取得函数在DLL中的地址
CreateRemoteThreadEx //在其他进程中创建新进程
CloseHandle //关闭句柄
完成线程的注入