博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DLL远程注入与卸载
阅读量:4554 次
发布时间:2019-06-08

本文共 4335 字,大约阅读时间需要 14 分钟。

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

支持Unicode编码。

  

#include <windows.h>

#include <tchar.h>
#include <tlhelp32.h>

/************************************************************************************************************
 * 函 数 名:InjectDll

 * 参    数:[in] const TCHAR* pszDllFile // Dll 文件名及路径

    [in] DWORD dwProcessId   // 目标进程 ID

 * 返 回 值:bool - 注入成功返回 true,注入失败则返回 false

 * 实现功能:向目标进程中注入一个指定 Dll 模块文件。

************************************************************************************************************/
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

 * 参    数:[in] const TCHAR* pszDllFile // Dll 文件名及路径

    [in] DWORD dwProcessId   // 目标进程 ID

 * 返 回 值:bool - 卸载成功返回 true,卸载失败则返回 false

 * 实现功能:从目标进程中卸载一个指定 Dll 模块文件。

************************************************************************************************************/
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;

}

转载于:https://www.cnblogs.com/milantgh/p/3880663.html

你可能感兴趣的文章
【语言处理与Python】7.3开发和评估分块器
查看>>
[luogu1518]两只塔母沃斯牛
查看>>
JMX 监控 Hadoop
查看>>
C#,.net,VS,ACAD,office版本和对应关系
查看>>
linux系统命令学习系列-例行任务管理at命令
查看>>
unity3d对象池的使用
查看>>
IOS 前后台切换
查看>>
【css】多行文字图片混排容器内垂直居中解决方案
查看>>
Hibernate中session的get方法和load方法的区别
查看>>
第七周编程总结
查看>>
HashMap实现原理及源码分析
查看>>
session and cookie
查看>>
所谓独立环境
查看>>
当代GSM手机的硬件系统分析[zz]
查看>>
对我影响最深的三个老师
查看>>
128.C++文件操作小结
查看>>
开源项目托管GitHub
查看>>
WebStorm、Intellij IDEA、PhpStorm jar包破解
查看>>
Unity学习笔记—— 常用脚本函数
查看>>
.getCellType()的几种类型值
查看>>