您的位置:首页 > 其它

CreateRemoteThread 失败错误码 5

2016-06-08 09:55 344 查看
最近在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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: