概述
线程注入有很多种方法,有最简单也最方便安全的SetWindowsHookEx的钩子注入,也有代码简洁的远程线程创建注入。
这种方法构思巧妙,但是个人觉得直接硬写目标进程内存空间有一定风险,可谓差之毫厘,谬以千里。本菜鸟这个程序调试了很长时间才成功的,大牛请勿发笑。
CreatRemoteThread从字面意思上不难理解,创建一个远程线程,所以我们可以用他在目标进程中创建一个线程,立即执行。并且将线程的入口地址设置为LoadLibrary函数的入口地址,LoadLibrary只有一个参数,就是动态链接库的绝对地址,我们将这个参数传入就可以调用任意一个我们想要注入的动态链接库,在DllMain函数中放入我们的目标代码就可以实现寄生执行。
这里需要注意的是,我们都知道,进程是一个封闭的空间,里面的所有数据都是私有的,那么这个动态链接库的绝对地址要被这个进程的线程所使用就应该成为这个进程空间中的数据,这也就是关键所在,我们需要先使用VirtualAllocEx进程中的内存空间,然后用WriteProcessMemory将这个参数内容写进进程,这里需要注意任何细节,一点小小错误都会使得目标进程崩溃。
下面我们看看代码:
#include "windows.h"
#include "stdlib.h"
#include "stdio.h"
#include "tlhelp32.h"
DWORD ProcessNameToPID(char Name[20]);//将进程名转化成PID
int main()
{
DWORD pdwProcessId;
WCHAR pszLibFileName[MAX_PATH]={0};
char lpDllFullPathName[MAX_PATH],ProcessName[20];
HANDLE hRemoteThread,hRemoteProcess;
PWSTR pszLibFileRemote=NULL;
printf("请输入进程名称:n");
scanf("%s",ProcessName);
printf("请输入dll地址:n");
scanf("%s",lpDllFullPathName);
MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,lpDllFullPathName,strlen(lpDllFullPathName),pszLibFileName,MAX_PATH);
if((pdwProcessId=ProcessNameToPID(ProcessName))==-1)
return 0;
hRemoteProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pdwProcessId);//打开被注入进程
if (hRemoteProcess==NULL)
{
printf("OpenProcess Errorn");
return 0;
}
int cb=(1+lstrlenW(pszLibFileName))*sizeof(WCHAR);
pszLibFileRemote=(PWSTR)VirtualAllocEx(hRemoteProcess,NULL,cb,MEM_COMMIT,PAGE_EXECUTE_READWRITE);//开辟内存
if (pszLibFileRemote==NULL)
{
printf("VirtualAllocEx Errorn");
return 0;
}
if(!WriteProcessMemory(hRemoteProcess,(PVOID)pszLibFileRemote,(PVOID)pszLibFileName,cb,NULL))//将dll模块名称写入被注入进程作为私有变量可供目标进程使用
{
printf("WriteProcessMemory Error %dn",GetLastError());
return 0;
}
PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"LoadLibraryW");//获得LoadLibraryW地址
if(pfnStartAddr==NULL)
{
printf("pfnStartAddr Errorn");
}
//创建远程线程,线程回调函数就是LoadLibraryW,pszLibFileRemote中的dll路径作为LoadLibraryW的唯一参数传入
hRemoteThread=CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,pszLibFileRemote,0,NULL);
if (hRemoteThread==NULL)
{
printf("CreatRemoteThread Errorn");
return 0;
}
return 1;
}
DWORD ProcessNameToPID(char Name[20]) //进程遍历就不用多说了把,方法多的是
{
PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(pe32);
HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0) ;
if(hProcessSnap==INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot fuild!n");
return -1;
}
BOOL bMore=Process32First(hProcessSnap,&pe32);
while(bMore)
{
if (!strcmp(Name,pe32.szExeFile))
{
printf("find it %dn",pe32.th32ProcessID);
return pe32.th32ProcessID;
}
bMore=Process32Next(hProcessSnap,&pe32);
}
CloseHandle(hProcessSnap);
return -1;
}
下面是被注入进程的动态链接库代码,只输出一个MessageBox,“这是个测试程序!”:
#include "windows.h"
BOOL APIENTRY DllMain(HANDLE hMoudle,DWORD reason,LPVOID lpReserved)
{
switch(reason)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL,"this is a test!","Success",MB_OK);
break;
default:
return TRUE;
}
}
下面是运行效果,我写了个界面:
最后
以上就是风趣灯泡为你收集整理的CreatRemoteThread线程注入的全部内容,希望文章能够帮你解决CreatRemoteThread线程注入所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复