以下提供两个函数,分别用于向其它进程注入和卸载指定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;
}

DLL远程注入与卸载的更多相关文章

  1. DLL远程注入及卸载实现

    实现win7 64位系统下dll的远程注入及卸载,尚未再其他系统测试 源码地址:https://github.com/ndhisrfzs/InjectDll

  2. [转]C++ DLL远程注入与卸载函数

    代码是别处的 第一个函数是成功的,第二个函数运行发现会将目标程序挂死,也许是目标程序有保护机制 支持Unicode编码. //------------------------------------- ...

  3. 一个完整的DLL远程注入函数

    函数名称: CreateRemoteDll() 返加类型:BOOL 接受参数: DLL路径,注入进程ID 其完整代码如下: BOOL CreateRemoteDll(const char *DllFu ...

  4. DLL远程注入实例

    一般情况下,每个进程都有自己的私有空间,理论上,别的进程是不允许对这个私人空间进行操作的,但是,我们可以利用一些方法进入这个空间并进行操作,将自己的代码写入正在运行的进程中,于是就有了远程注入了. 对 ...

  5. 无DLL远程注入

    界面如下: 主要代码如下: #define STRLEN 20 typedef struct _DATA { DWORD dwLoadLibrary; DWORD dwGetProcAddress; ...

  6. HOOK -- DLL的远程注入技术详解(1)

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  7. DLL的远程注入技术

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  8. 将DLL挂接到远程进程之中(远程注入)

    线程的远程注入 要实现线程的远程注入必须使用Windows提供的CreateRemoteThread函数来创建一个远程线程该函数的原型如下:HANDLE CreateRemoteThread(    ...

  9. [转]远程注入DLL : 取得句柄的令牌 OpenProcessToken()

    http://hi.baidu.com/43755979/blog/item/3ac19711ea01bdc4a6ef3f6a.html 要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关 ...

随机推荐

  1. fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    为完成老师的任务,用c++写个计算器,又去学点c++,结果就有各种问题,如题 http://www.cnblogs.com/newpanderking/articles/3372969.html 感谢 ...

  2. sql常识-IN 操作符

    IN 操作符 IN 操作符允许我们在 WHERE 子句中规定多个值. SQL IN 语法 SELECT column_name(s) FROM table_name WHERE column_name ...

  3. Android之进度条2

    我之前有写过一篇“Android之进度条1”,那个是条形的进度条(显示数字进度),这次实现圆形进度条. 点击查看Android之进度条1:http://www.cnblogs.com/caidupin ...

  4. JavaScript之可运行按钮

    看到好多大神都写了像这种在页面"可运行"的Javascript脚本,感觉很好奇,所以我今天也试着写了一个. 自从有了这个"可运行"按钮,好多代码就再也不以图片的 ...

  5. asp.net MVC中使用Html.Checkbox提示该字符串未被识别为有效的布尔值错误的解决方法

    在asp.net MVC中使用Html.CheckBox提交后出现该字符串未被识别为有效的布尔值错误,或从类型“System.String”到类型“System.Boolean”的参数转换失败. 错误 ...

  6. Cocos2d-x中创建SQLite数据库

    我们下边介绍如何通过SQLite3提供的API实现MyNotes数据库创建.创建数据库一般需要经过如下三个步骤.(1) 使用sqlite3_open函数打开数据库.(2) 使用sqlite3_exec ...

  7. UIDynamic 基础认识

    UIDynamic 是从iOS 7开始引入的一种新技术,属于UIKit框架,可以模拟现实生活中的物理现象,如:碰撞.抖动.摆动等 动力效果:有一个效果器,叫做“动力效果器”里面面可以添加“动力效果” ...

  8. css Hack 以及css的一些兼容问题小结

    坚持每天做总结.今天下班还算早.写个跟css兼容有关的知识点.便于后期查看与学习.一.先说说各种主流浏览器的内核 浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引 ...

  9. 引用类型之Function类型

    Function类型 ECMAScript中最有意思的就是函数了,有意思的根源,在于函数实际上是对象.每个函数都是Function的实例,具有属性和方法.而重要的一点是,函数名,不过是指向函数的指针, ...

  10. 分布式之高性能IO组件

    因为毕业设计(实时分析大型数据流),开始对分布式并行计算做研究,第一个问题就是通讯.高性能的通讯是整个系统性能的基本保障. 方案 就目前的经验来讲,最好的通信选择是:异步非阻塞IO + 资源池. 异步 ...