CreateRemoteThread 失败错误码 5

最近在WIN7下调试DLL注入进程的时候,32位的注入总是返回失败,错误码5。64位没问题。经过反复的检查。发现是OpenProcess打开的方式不对。添加PROCESS_ALL_ACCESS,问题解决。查了一下微软的文档,发现这个参数在XP下可能是有问题的。所以建议XP和WIN7分别处理。代码如下:
//提权
VOID EnableDebugPriv(VOID)
{
	HANDLE hToken;
	TOKEN_PRIVILEGES tkp;
	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
	CloseHandle(hToken);
}
注入DLL
BOOL InjectDll(TCHAR* ptszDllFile, DWORD dwProcessId)
{
	// 参数无效    
	if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))
	{
		return FALSE;
	}
	// 指定 Dll 文件不存在    
	/**if (-1 == _access(ptszDllFile, 0))
	{
		return FALSE;
	}**/
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;
	DWORD dwSize = 0;
	LPVOID ptszRemoteBuf = NULL;
	LPTHREAD_START_ROUTINE lpThreadFun = NULL;
	SIZE_T dwWritten;
	HANDLE hModuleSnap = INVALID_HANDLE_VALUE;


	// 获取模块快照  
	hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
	if (INVALID_HANDLE_VALUE == hModuleSnap)
	{
		return FALSE;
	}
	MODULEENTRY32 me32;
	memset(&me32, 0, sizeof(MODULEENTRY32));
	me32.dwSize = sizeof(MODULEENTRY32);
	// 开始遍历  
	if (FALSE == ::Module32First(hModuleSnap, &me32))
	{
		::CloseHandle(hModuleSnap);
		return FALSE;
	}
	// 遍历查找指定模块  
	bool isFound = FALSE;
	do
	{
		isFound = (0 == ::_tcsicmp(me32.szModule, ptszDllFile) || 0 == ::_tcsicmp(me32.szExePath, ptszDllFile));
		if (isFound) // 找到指定模块  
		{
			break;
		}
	} while (TRUE == ::Module32Next(hModuleSnap, &me32));
	::CloseHandle(hModuleSnap);
	if (TRUE == isFound)
	{
		return FALSE;
	}
	hProcess = NULL;
	hThread = NULL;
	// 获取目标进程句柄    
	hProcess = <span style="color:#ff0000;">::OpenProcess(PROCESS_ALL_ACCESS|PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId);</span>
	if (NULL == hProcess)
	{
		return FALSE;
	}
	// 在目标进程中分配内存空间    
	dwSize = lstrlenA(ptszDllFile) + 1;
	ptszRemoteBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == ptszRemoteBuf)
	{
		::CloseHandle(hProcess);
		return FALSE;
	}
	// 在目标进程的内存空间中写入所需参数(模块名)    

	if (FALSE == WriteProcessMemory(hProcess, ptszRemoteBuf, (LPVOID)ptszDllFile, dwSize, &dwWritten))
	{
		::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
		::CloseHandle(hProcess);
		return FALSE;
	}
	else if (dwWritten != dwSize) {
		return FALSE;
	}

	// 从 Kernel32.dll 中获取 LoadLibrary 函数地址    
#ifdef _UNICODE    
	lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
#else
	HMODULE kernel = ::GetModuleHandle("Kernel32");
	lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(kernel, "LoadLibraryA");
#endif    
	if (NULL == lpThreadFun)
	{
		::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
		::CloseHandle(hProcess);
		return FALSE;
	}
	// 创建远程线程调用 LoadLibrary    
	hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, ptszRemoteBuf, 0, NULL);
	if (NULL == hThread)
	{
		::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
		::CloseHandle(hProcess);
		return FALSE;
	}
	// 等待远程线程结束    
	::WaitForSingleObject(hThread, INFINITE);
	// 清理    
	::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
	::CloseHandle(hThread);
	::CloseHandle(hProcess);

	return TRUE;
}



  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值