DLL远程注入与卸载
以下提供两个函数,分别用于向其它进程注入和卸载指定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远程注入与卸载的更多相关文章
- DLL远程注入及卸载实现
实现win7 64位系统下dll的远程注入及卸载,尚未再其他系统测试 源码地址:https://github.com/ndhisrfzs/InjectDll
- [转]C++ DLL远程注入与卸载函数
代码是别处的 第一个函数是成功的,第二个函数运行发现会将目标程序挂死,也许是目标程序有保护机制 支持Unicode编码. //------------------------------------- ...
- 一个完整的DLL远程注入函数
函数名称: CreateRemoteDll() 返加类型:BOOL 接受参数: DLL路径,注入进程ID 其完整代码如下: BOOL CreateRemoteDll(const char *DllFu ...
- DLL远程注入实例
一般情况下,每个进程都有自己的私有空间,理论上,别的进程是不允许对这个私人空间进行操作的,但是,我们可以利用一些方法进入这个空间并进行操作,将自己的代码写入正在运行的进程中,于是就有了远程注入了. 对 ...
- 无DLL远程注入
界面如下: 主要代码如下: #define STRLEN 20 typedef struct _DATA { DWORD dwLoadLibrary; DWORD dwGetProcAddress; ...
- HOOK -- DLL的远程注入技术详解(1)
DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...
- DLL的远程注入技术
DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...
- 将DLL挂接到远程进程之中(远程注入)
线程的远程注入 要实现线程的远程注入必须使用Windows提供的CreateRemoteThread函数来创建一个远程线程该函数的原型如下:HANDLE CreateRemoteThread( ...
- [转]远程注入DLL : 取得句柄的令牌 OpenProcessToken()
http://hi.baidu.com/43755979/blog/item/3ac19711ea01bdc4a6ef3f6a.html 要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关 ...
随机推荐
- svn 分支整个项目合并主干
1.首先主干要更新最新版本. 2.找到主干(trunk)点击右键--合并--合并类型选择(合并一个版本范围)点击下一步--合并源选择整个分支项目--将要合并的修改版本范围(选择指定(a)范围)点击下一 ...
- boost库区间range基本原理及使用实例
由 www.169it.com 搜集整理 区间的概念类似于STL中的容器概念.一个区间提供了可以访问半开放区间[first,one_past_last)中元素的迭代器,还提供了区间中的元素数量的信息. ...
- 断开SVN连接操作方法
SVN是日常项目管理中经常使用到的工具,然而拷贝备份需要与SVN服务器断开连接,具体操作步骤: 1.在桌面建立一个文本文件,取名为kill-svn-folders.reg(扩展名由txt改为reg), ...
- win7下将主分区转换成逻辑分区
在了解怎么转换之前,先搞清楚主分区,扩展分区,逻辑分区的基本概念. 主分区,也称为主磁盘分区,和扩展分区.逻辑分区一样,是一种分区类型.主分区中不能再划分其他类型的分区,因此每个主分区都相当于一个逻辑 ...
- Unity 5.4大赞:HTC Vive经典The lab渲染器开源
HTC Vive提供了一个不错的免费VR demo,最近1周仔细体验了一番. 仔细看了其安装文件,竟然是Unity 5.4beta版本(通过查log,知道Valve公司用的是最新的5.4.0b11版本 ...
- 免费的HTML5连载来了《HTML5网页开发实例详解》连载(六)媒体查询
响应式设计的另一个重要技术手段是媒体查询.如果只是简单的设计一个流式布局系统,那么可以保证每个网格按比例的放大和缩小,但有可能会使得在小屏幕下(如手机设备)网格太小而严重影响阅读,这样的设计称不上响应 ...
- Js 赋值传值和引用传址
赋值传值和引用传址 在JavaScript中基本数据类型都是赋值传值,复合数据类型都是引用传址(传地址) 基本数据类型的变量名和数据是直接存在"快速内存"(栈内存)中,而复合数据类 ...
- Go 接口转换的一个例子
今天将Go 的websocket集成到已有的http中时也遇到以下一个问题:其中主要是接口类型转换 转载自[http://www.cnblogs.com/ghj1976/archive/2013/04 ...
- 算法 replace,replace_copy,back_inserter
replace (list.begin(), list.end(), , ); // replace any elements with value of 0 by 42 replace算法对输入序列 ...
- opencv 手写选择题阅卷 (一)表格设计与识别
(一)答题表格设计与识别 实际设计好的表格如下图 为了图像精确,表格和四角的标记都是由程序生成的,文字和数据是后期排版软件添加上去的. 图中四角的四个黑方块主要用来定位表格,然后就可以切割出每个单元格 ...