前言
远程线程注入是指一个进程在另一个进程中创建线程的技术,在病毒、木马以及外挂中经常使用到该技术,本篇博客是以安全防御为目的。
使用场景
调试器中也使用了该技术;可以通过宿主来执行一些隐藏操作如一些木马病毒;可以实现HOOK API来修改目标进程的行为如实现隐藏进程、隐藏文件、隐藏注册表项等;修改目标进程的数据如外挂;等我想到了再补充...
实现流程
其流程大致如下:
代码实现
测试函数代码如下,可根据实际情况再做更改
BOOL CreateRemoteThreadInjectDll(
DWORD dwProcessId, //进程的ID
const char *pszDllFileName //要注入的DLL路径
)
//线程注入函数
BOOL CreateRemoteThreadInjectDll(DWORD dwProcessId,const char *pszDllFileName)
{
HANDLE hProcess = NULL;
DWORD dwSize = 0;
LPVOID pDllAddr = NULL;
FARPROC pFuncProcAddr = NULL;
//打开注入进程,获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
if(NULL == hProcess)
{
printf("OpenProcess Error!\n");
return FALSE;
}
//在注入进程中申请内存
dwSize = _tcslen(pszDllFileName) + 1;
pDllAddr = VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);
if(NULL == pDllAddr)
{
printf("VirtualAllocEx Error!\n");
return FALSE;
}
//向申请的内存中写入数据_tcslen(pszDllFileName)*sizeof(WCHAR)
if(FALSE == WriteProcessMemory(hProcess,pDllAddr,pszDllFileName,dwSize,NULL))
{
printf("WriteProcessMemory Error!\n");
return FALSE;
}
//获取LOADLibrary函数地址
pFuncProcAddr = GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA");
if(NULL == pFuncProcAddr)
{
printf("GetProcAddress Error!\n");
return FALSE;
}
//使用CreateRemoteThread创建远程线程,实现DLL注入
HANDLE hRemoteThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pFuncProcAddr,pDllAddr,0,NULL);
if(NULL == hRemoteThread)
{
printf("CreateRemoteThread Error!\n");
return FALSE;
}
CloseHandle(hProcess);
return TRUE;
}
这个注入程序是使用的是多字节字符集,所有远程线程入口函数是用的LoadLibraryA,否则用LoadLibraryW
如果你阅读了代码,可能会发出疑问,为什么创建的远程线程的入口地址是测试进程的LoadLibrary函数地址?这是因为系统可以保证kernel32.dll的加载基地址在任何进程中都是相同的,因此导出的函数地址也完全相同,所以可以这样用,这点是实现远程注入的一个关键,但除了kernel32.dll和ntdll.dll外,其他的DLL的基地址在进程中是否相同是不能保证的,所以不要误用!
注意事项
当然,测试这个函数还需要自己编写一个DLL,可以写一些弹窗或者通过Process Explore(最好是这样,因为有些不会弹窗)来查看是否注入成功,要注意的如果要注入64位的程序,那么需要编写64位的DLL。
下一篇远程线程注入将讲述更底层的注入方法