通过远程线程注入DLL!心得!

1.       通过GetModuleHandle定位LoadLiabraryKernel32.dll中的虚拟地址!!(根据jerry 牛人的说法,就是kernel32.dll在任何进程中加载的位置都是一样的)

2.       提升当前进程的权限,使其权限提升为debug的权限,这样才能在目标进程中分配虚拟空间和读写虚拟空间操作。

3.       在目标进程中分配存放LoadLibrary的参数的内存。因为必须将参数写到目标进程中,才能让创建的线程访问,要不然,就会发生进程访问数据冲突,(不能垮进程访问地址),通过函数VirtualAllocEx.

4.       在分配的地址空间中写入参数值,通过WriteProcessMemery.

5.       调用CreateRemoteThread创建远程线程!

6.       补充说明一下:提升权限用到的函数:
1)
通过OpenProcess一查询权限打开自己的进程.
2)
通过OpenProcessToken打开访问令牌。

3)
通过LookupPrivilegeValue查询debug权限的值
4)
通过AdjustPrivilegeValue来调整进程权限

7.       在写的过程中遇到了很多麻烦,其中一个问题就是,当我代码没有问题的时候,发现老师只能注入自己的线程,其他的都注入不进去,后来啄么了很久,才防线是依赖库的问题,没有吧依赖库放到一起,再者,需要注意的是,当远程线程在目标进程中运行的时候,如果你传的路径不是绝对路径,那么也会出问题,因为他要从目标进程的目录中搜索,搜索不到,在从环境变量中列出的路径搜索,所以,路径得必须谨慎。其次,是你的函数和传入的路径字符串要是同一字符集。要不让也会出问题!

8.       如果想要卸载注入的DLL,也很简单,通过注入FreeLiabray线程就OK了!!!方法同上!

代码:

//提升当前进程的权限 BOOL CMoveCursorDlg::AdjustProcessPrivilege(DWORD dwProcessId) { HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwProcessId); //以查询方式打开进程 if(hProcess == NULL) return FALSE; HANDLE hToken = NULL; BOOL bRet = FALSE; DWORD dwErr = 0; bRet = ::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY ,&hToken); dwErr = ::GetLastError(); if(!bRet) return FALSE; LUID luid; if(::LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid) == 0)//查询权限值(设置权限值) return FALSE; TOKEN_PRIVILEGES tkp; tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = luid; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bRet = ::AdjustTokenPrivileges(hToken,FALSE,&tkp,0,NULL,NULL); //调整权限 if(!bRet) return FALSE; ::CloseHandle(hToken); ::CloseHandle(hProcess); return TRUE; 9. } // //注入目标进程 BOOL CMoveCursorDlg::InjectDesProcess(DWORD dwProcessId) { BOOL bRet = FALSE; DWORD dwCurrProcessId = ::GetCurrentProcessId(); bRet = AdjustProcessPrivilege(dwCurrProcessId); //手动提升当前进程权限 //打开目标进程句柄 m_hDesProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE , dwProcessId); if(m_hDesProcess != NULL && bRet) { //定位LoadLibraryA在kernel32.dll中的位置 HMODULE hModule = ::GetModuleHandle(_T("Kernel32")); if(hModule == NULL) return FALSE; PTHREAD_START_ROUTINE pfnLoadLibraryW = (PTHREAD_START_ROUTINE)::GetProcAddress(hModule,LPCSTR("LoadLibraryW")); if(pfnLoadLibraryW == NULL) return FALSE; //在远程线程中分配地址空间来存放LoadLibraryA的参数 TCHAR szDllPath[MAX_PATH] ={0}; _tcscpy_s(szDllPath,MAX_PATH, _T("INJDLL.dll")); //DLL路径 DWORD dwSize = lstrlen(szDllPath) * sizeof(TCHAR) + 1; PCWSTR* lpAddr = (PCWSTR*)::VirtualAllocEx(m_hDesProcess , NULL, dwSize, MEM_COMMIT | MEM_RESERVE , PAGE_EXECUTE_READWRITE); if(lpAddr == NULL) return FALSE; //将数据写入到目标进程地址空间中去 DWORD dwNumBytesOfWritten = 0; bRet = ::WriteProcessMemory(m_hDesProcess, lpAddr, (LPVOID)szDllPath ,dwSize, &dwNumBytesOfWritten); if(dwSize != dwNumBytesOfWritten) { ::VirtualFreeEx(m_hDesProcess,lpAddr,sizeof(szDllPath), MEM_RELEASE); //释放地址空间 return FALSE; } if(!bRet) return FALSE; //将指定DLL注入目标进程 DWORD dwThreadId = 0; HANDLE hRemoteThread = ::CreateRemoteThread(m_hDesProcess, NULL, 0, (PTHREAD_START_ROUTINE)pfnLoadLibraryW, lpAddr, 0, &dwThreadId); if(hRemoteThread == NULL) return FALSE; ::WaitForSingleObject(hRemoteThread,INFINITE); ::VirtualFreeEx(m_hDesProcess,lpAddr,sizeof(szDllPath), MEM_RELEASE); //释放地址空间 ::CloseHandle(hRemoteThread); return TRUE; } else { return FALSE; } }

10.    

 

你可能感兴趣的:(通过远程线程注入DLL!心得!)