Ψ星泪
最近评论
skxq1983:楼主
的代码很棒
rhzwan123:2) const char * p 是不是应该写作*const char p呢?
文章分类
    收藏
      相册
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 DLL远程注入与卸载收藏

      新一篇: VC中让CListBox带有复选框 | 旧一篇: 分享一个注册表搜索函数

      以下提供两个函数,分别用于向其它进程注入和卸载指定DLL模块。 支持Unicode编码。

      #include <windows.h>
      
      #include <tchar.h>
      
      #include <tlhelp32.h>
      
      
      
      //-----------------------------------------------------------------------------------------------------------
      
      // 函数:InjectDll
      
      // 功能:向目标进程中注入一个指定 Dll 模块文件。
      
      // 参数:[in] const TCHAR* pszDllFile - Dll 文件名及路径
      
      //       [in] DWORD dwProcessId - 目标进程 ID
      
      // 返回:bool - 注入成功返回 true,注入失败则返回 false
      
      // 说明:采用远程线程注入技术实现。
      
      //-----------------------------------------------------------------------------------------------------------
      
      bool InjectDll(const TCHAR* pszDllFile, DWORD dwProcessId)
      
      {
      
      	// 参数无效
      
      	if (NULL == pszDllFile || 0 == ::_tcslen(pszDllFile))
      
      	{
      
      		return false;
      
      	}
      
      
      
      	// 指定 Dll 文件不存在
      
      	if (-1 == _taccess(pszDllFile, 0))
      
      	{
      
      		return false;
      
      	}
      
      
      
      	HANDLE	hProcess		= NULL;
      
      	HANDLE	hThread			= NULL;
      
      	DWORD	dwSize			= 0;
      
      	TCHAR*	pszRemoteBuf	= NULL;
      
      	LPTHREAD_START_ROUTINE lpThreadFun = NULL;
      
      
      
      	// 获取目标进程句柄
      
      	hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId);
      
      	if (NULL == hProcess)
      
      	{
      
      		return false;
      
      	}
      
      
      
      	// 在目标进程中分配内存空间
      
      	dwSize = (DWORD)::_tcslen(pszDllFile) + 1;
      
      	pszRemoteBuf = (TCHAR*)::VirtualAllocEx(hProcess, NULL, dwSize * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
      
      	if (NULL == pszRemoteBuf)
      
      	{
      
      		::CloseHandle(hProcess);
      
      		return false;
      
      	}
      
      
      
      	// 在目标进程的内存空间中写入所需参数(模块名)
      
      	if (FALSE == ::WriteProcessMemory(hProcess, pszRemoteBuf, (LPVOID)pszDllFile, dwSize * sizeof(TCHAR), NULL))
      
      	{
      
      		::VirtualFreeEx(hProcess, pszRemoteBuf, dwSize, MEM_DECOMMIT);
      
      		::CloseHandle(hProcess);
      
      		return false;
      
      	}
      
      
      
      	// 从 Kernel32.dll 中获取 LoadLibrary 函数地址
      
      #ifdef _UNICODE
      
      	lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
      
      #else
      
      	lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
      
      #endif
      
      	if (NULL == lpThreadFun)
      
      	{
      
      		::VirtualFreeEx(hProcess, pszRemoteBuf, dwSize, MEM_DECOMMIT);
      
      		::CloseHandle(hProcess);
      
      		return false;
      
      	}
      
      
      
      	// 创建远程线程调用 LoadLibrary
      
      	hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, pszRemoteBuf, 0, NULL);
      
      	if (NULL == hThread)
      
      	{
      
      		::VirtualFreeEx(hProcess, pszRemoteBuf, dwSize, MEM_DECOMMIT);
      
      		::CloseHandle(hProcess);
      
      		return false;
      
      	}
      
      
      
      	// 等待远程线程结束
      
      	::WaitForSingleObject(hThread, INFINITE);
      
      
      
      	// 清理
      
      	::VirtualFreeEx(hProcess, pszRemoteBuf, dwSize, MEM_DECOMMIT);
      
      	::CloseHandle(hThread);
      
      	::CloseHandle(hProcess);
      
      
      
      	return true;
      
      }
      
      //-----------------------------------------------------------------------------------------------------------
      
      // 函数:UnInjectDll
      
      // 功能:从目标进程中卸载一个指定 Dll 模块文件。
      
      // 参数:[in] const TCHAR* pszDllFile - Dll 文件名及路径
      
      //       [in] DWORD dwProcessId - 目标进程 ID
      
      // 返回:bool - 卸载成功返回 true,卸载失败则返回 false
      
      // 说明:采用远程线程注入技术实现。
      
      //-----------------------------------------------------------------------------------------------------------
      
      bool UnInjectDll(const TCHAR* pszDllFile, DWORD dwProcessId)
      
      {
      
      	// 参数无效
      
      	if (NULL == pszDllFile || 0 == ::_tcslen(pszDllFile))
      
      	{
      
      		return false;
      
      	}
      
      
      
      	HANDLE	hModuleSnap	= INVALID_HANDLE_VALUE;
      
      	HANDLE	hProcess	= NULL;
      
      	HANDLE	hThread		= NULL;
      
      
      
      	// 获取模块快照
      
      	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, pszDllFile) || 0 == ::_tcsicmp(me32.szExePath, pszDllFile));
      
      		if (isFound) // 找到指定模块
      
      		{
      
      			break;
      
      		}
      
      	} while (TRUE == ::Module32Next(hModuleSnap, &me32));
      
      
      
      	::CloseHandle(hModuleSnap);
      
      
      
      	if (false == isFound)
      
      	{
      
      		return false;
      
      	}
      
      
      
      	// 获取目标进程句柄
      
      	hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, FALSE, dwProcessId);
      
      	if (NULL == hProcess)
      
      	{
      
      		return false;
      
      	}
      
      
      
      	// 从 Kernel32.dll 中获取 FreeLibrary 函数地址
      
      	LPTHREAD_START_ROUTINE lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "FreeLibrary");
      
      	if (NULL == lpThreadFun)
      
      	{
      
      		::CloseHandle(hProcess);
      
      		return false;
      
      	}
      
      
      
      	// 创建远程线程调用 FreeLibrary
      
      	hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, me32.modBaseAddr /* 模块地址 */, 0, NULL);
      
      	if (NULL == hThread)
      
      	{
      
      		::CloseHandle(hProcess);
      
      		return false;
      
      	}
      
      
      
      	// 等待远程线程结束
      
      	::WaitForSingleObject(hThread, INFINITE);
      
      
      
      	// 清理
      
      	::CloseHandle(hThread);
      
      	::CloseHandle(hProcess);
      
      
      
      	return true;
      
      }

      发表于 @ 2007年09月16日 01:17:00|评论(loading...)|收藏

      新一篇: VC中让CListBox带有复选框 | 旧一篇: 分享一个注册表搜索函数

      评论:没有评论。

      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © Ψ星泪