DLL注入

PS:以前的代码整理下发出来,希望能给你们一些帮助



/***************************************************************************************
* 文件名: RemoteThreadInjectDLL.h(注入核心模块)
* 功  能: DLL远程线程注入类
* 说  明: AttachByName(注入)、DetachByName(卸载)
*         第一个参数都是进程名
*         第二个参数都是要注入DLL的路径(如果DLL和被注入程序不在同一个目录,给绝对路径)
*         对外接口有两类: 根据进程名和根据进程ID
* 使  用: CRemoteThreadInjectDLL objInject;
*         objInject.AttachByName(_T("QQ.exe"), \
*         _T("D:\\VS2012工程\\深入动态链接库核心\\
*          DLL远程线程注入\\InjectDLL\\Debug\\DllOfInject.dll"));(卸载同理)
****************************************************************************************/
#pragma once
#include <windows.h>
//使用这个类时要注意定义成成员变量的类
//以便于使用时释放用到句柄
class CRemoteThreadInjectDLL
{
public:                                                   // 内部使用
    CRemoteThreadInjectDLL(void);
    ~CRemoteThreadInjectDLL(void);
    int   EnablePrivilege(bool isStart);                  // 提升权限
    DWORD GetProcessId(WCHAR* pszProcessName);            // 根据进程名获取进程ID 
    int   InjectDll(DWORD dwProcessId, WCHAR* szDllName); // 根据进程ID加载DLL 
    int   RelaseDll(DWORD dwProcessId, WCHAR* szDllName); // 根据进程ID卸载DLL
    
public:                                                   // 对外接口
    void  AttachById(DWORD dwProcessId, WCHAR* pDllName); // 加载DLL到指定ID进程
    void  DetachById(DWORD dwProcessId, WCHAR* pDllName); // 卸载指定ID进程的DLL
    void  AttachByName(WCHAR* pExeName, WCHAR* pDllName); // 加载DLL到指定名称进程
    void  DetachByName(WCHAR* pExeName, WCHAR* pDllName); // 卸载指定名称进程的DLL
    HMODULE m_hMod;                                       // 被注入的DLL模块句柄
    HANDLE  m_hInjecthread;
};





/***************************************************************************************
* 文件名: RemoteThreadInjectDLL.cpp (注入核心模块)
* 功  能: DLL远程线程注入类
* 说  明: AttachByName(注入)、DetachByName(卸载)
*         第一个参数都是进程名
*         第二个参数都是要注入DLL的路径(如果DLL和被注入程序不在同一个目录,给绝对路径)
* 使  用: CRemoteThreadInjectDLL objInject;
*         objInject.AttachByName(_T("QQ.exe"), \
*         _T("D:\\VS2012工程\\正式班-核心编程\\第六天 深入动态链接库核心\\
*          DLL远程线程注入\\InjectDLL\\Debug\\DllOfInject.dll"));(卸载同理)
****************************************************************************************/
#include "stdafx.h"
#include "RemoteThreadInjectDLL.h"
#include <Tlhelp32.h>
/***************************************************************************************
* 参  数: 无
* 功  能: 构造
* 返回值: 无
****************************************************************************************/
CRemoteThreadInjectDLL::CRemoteThreadInjectDLL(void)
{
}
/***************************************************************************************
* 参  数: 无
* 功  能: 析构
* 返回值: 无
****************************************************************************************/
CRemoteThreadInjectDLL::~CRemoteThreadInjectDLL(void)
{
}
/***************************************************************************************
* 参  数: 进程名
* 功  能: 遍历所有进程根据进程名获取进程ID
* 返回值: 进程ID
****************************************************************************************/
DWORD CRemoteThreadInjectDLL::GetProcessId(WCHAR* pszProcessName)
{
    HANDLE hProcess = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hProcess)
    {
        return 0;
    }
    DWORD dwProcessId = 0;
    PROCESSENTRY32 process32 = {0};
    process32.dwSize = sizeof(PROCESSENTRY32);
    BOOL bRetProcess = FALSE;
    bRetProcess = ::Process32First(hProcess, &process32);
    do
    {
        if (_tcscmp(pszProcessName, process32.szExeFile) == 0)
        {
            dwProcessId = process32.th32ProcessID;
            break;
        }
        bRetProcess = ::Process32Next(hProcess, &process32);
    }while (bRetProcess);
    ::CloseHandle(hProcess);
    return dwProcessId;
}
/***************************************************************************************
* 参数一: 进程ID
* 参数二: 被注入DLL的路径
* 功  能: 注入DLL到指定ID的进程
* 返回值: 失败-1, 成功0
****************************************************************************************/
int CRemoteThreadInjectDLL::InjectDll(DWORD dwProcessId, WCHAR* szDllName)
{
    if (szDllName[0] == NULL)
        return -1;
    EnablePrivilege(TRUE);                                  //获取权限
    //1. 打开进程
    HANDLE hProcess = ::OpenProcess(  PROCESS_ALL_ACCESS,   //打开进程权限
        FALSE,                                              //是否可继承 
        dwProcessId);                                       //进程ID
    if (hProcess == INVALID_HANDLE_VALUE)
        return -1;
    //2. 申请空间
    LPVOID pszDllName = ::VirtualAllocEx(hProcess,          //远程进程句柄               
        NULL,                                               //建议开始地址
        4096,                                               //分配空间大小
        MEM_COMMIT,                                         //空间初始化全0
        PAGE_EXECUTE_READWRITE);                            //空间权限
    if (NULL == pszDllName)
    {
        return -1;
    }
    //3. 写入数据
    BOOL bRet = ::WriteProcessMemory( hProcess, pszDllName, 
        szDllName, MAX_PATH, NULL);
    if (NULL == bRet)
    {
        return -1;
    }
    //4. 创建远程线程
    m_hInjecthread = ::CreateRemoteThread(hProcess,      //远程进程句柄
        NULL,                                            //安全属性
        0,                                               //栈大小
        (LPTHREAD_START_ROUTINE)LoadLibrary,             //进程处理函数    
        pszDllName,                                      //传入参数
        NULL,                                            //默认创建后的状态
        NULL);                                           //线程ID
    if (NULL == m_hInjecthread)
    {
        DWORD dwErr = GetLastError();
        return -1;
    }
    //5. 等待线程结束返回
    DWORD dw = WaitForSingleObject(m_hInjecthread, -1);
    //6. 获取线程退出码,即LoadLibrary的返回值,即dll的首地址
    DWORD dwExitCode;
    GetExitCodeThread(m_hInjecthread, &dwExitCode);
    m_hMod = (HMODULE)dwExitCode;
    //7. 释放空间
    BOOL bReturn = VirtualFreeEx(hProcess, pszDllName, 
        4096, MEM_DECOMMIT);
    if (NULL == bReturn)
    {
        return -1;
    }
    CloseHandle(hProcess);
    hProcess = NULL;
    EnablePrivilege(FALSE);
    return 0;
}
int CRemoteThreadInjectDLL::RelaseDll(DWORD dwProcessId, WCHAR* szDllName)
{
    if (szDllName[0] == NULL)
        return -1;
    if (m_hMod == NULL)
    {
        return -1;
    }
    EnablePrivilege(TRUE);                                   //获取权限
    HANDLE hProcess = ::OpenProcess(  PROCESS_ALL_ACCESS,    //打开进程权限
        FALSE,                                               //是否可继承 
        dwProcessId);                                        //进程ID
    if (hProcess == INVALID_HANDLE_VALUE)
        return -1;
    //4. 创建远程线程
    m_hInjecthread = ::CreateRemoteThread(hProcess,          //远程进程句柄
        NULL,                                                //安全属性
        0,                                                   //栈大小
        (LPTHREAD_START_ROUTINE)FreeLibrary,                 //进程处理函数    
        m_hMod,                                              //传入参数
        NULL,                                                //默认创建后的状态
        NULL);                                               //线程ID
    if (NULL == m_hInjecthread)
    {
        DWORD dwErr = GetLastError();
        return -1;
    }
    //5. 等待线程结束返回
    WaitForSingleObject(m_hInjecthread, -1);
    //6. 获取线程退出码,即LoadLibrary的返回值,即dll的首地址
    DWORD dwExitCode;
    GetExitCodeThread(m_hInjecthread, &dwExitCode);
    m_hMod = NULL;
    CloseHandle(hProcess);
    hProcess = NULL;
    return 0;
}
/***************************************************************************************
* 参  数: 布尔
* 功  能: 提升权限
* 返回值: 0
****************************************************************************************/
int CRemoteThreadInjectDLL::EnablePrivilege(bool isStart)
{    
    //1. 得到令牌句柄
    HANDLE  hToken = NULL;      //令牌句柄  
    if (!::OpenProcessToken( GetCurrentProcess(), 
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, 
        &hToken))
    {   
        return FALSE;
    }
    //2. 得到特权值
    LUID    luid = {0};         //特权值
    if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
        return FALSE;
    }
    //3. 提升令牌句柄权限
    TOKEN_PRIVILEGES tp = {0};  //令牌新权限
    tp.PrivilegeCount = 1;                                                      
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = isStart ? SE_PRIVILEGE_ENABLED : 0;
    if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
    {
        return FALSE;
    }
    //4. 关闭令牌句柄
    ::CloseHandle(hToken);
    return 0;
}
/***************************************************************************************
* 参数一: 进程ID
* 参数二: 欲加载的DLL路径
* 功  能: 加载DLL到指定ID进程
* 返回值: 无
****************************************************************************************/
void  CRemoteThreadInjectDLL::AttachById(DWORD dwProcessId, WCHAR* pDllName)
{
    if (InjectDll(dwProcessId,pDllName) == -1)
    {
        MessageBox(NULL,_T("注入失败"),_T("提示"),MB_OK);
    }
}
/***************************************************************************************
* 参数一: 进程ID
* 参数二: 欲卸载的DLL路径(该参数无用)
* 功  能: 卸载指定ID进程的DLL
* 返回值: 无
****************************************************************************************/
void  CRemoteThreadInjectDLL::DetachById(DWORD dwProcessId, WCHAR* pDllName) 
{
    if (RelaseDll(dwProcessId,pDllName) == -1)
    {
        MessageBox(NULL,_T("释放失败"),_T("提示"),MB_OK);
    }
}
/***************************************************************************************
* 参数一: 进程名
* 参数二: 欲加载的DLL路径
* 功  能: 加载DLL到指定名称进程
* 返回值: 无
****************************************************************************************/
void CRemoteThreadInjectDLL::AttachByName(WCHAR* pExeName,WCHAR* pDllName)
{
    DWORD dwProcessId = GetProcessId(pExeName);
    if (InjectDll(dwProcessId,pDllName) == -1)
    {
        MessageBox(NULL,_T("注入失败"),_T("提示"),MB_OK);
    }
}
/***************************************************************************************
* 参数一: 进程名称
* 参数二: 欲卸载的DLL路径(该参数无用)
* 功  能: 卸载指定名称进程的DLL
* 返回值: 无
****************************************************************************************/
void CRemoteThreadInjectDLL::DetachByName(WCHAR* pExeName,WCHAR* pDllName)
{
    DWORD dwProcessId = GetProcessId(pExeName);
    if (RelaseDll(dwProcessId,pDllName) == -1)
    {
        MessageBox(NULL,_T("释放失败"),_T("提示"),MB_OK);
    }
}





/***************************************************************************************
* 文件名: InjectDLL.cpp (注入使用模块)
* 功  能: DLL远程线程注入使用程序
* 说  明: AttachByName(注入)、DetachByName(卸载)
*         第一个参数都是进程名
*         第二个参数都是要注入DLL的路径(如果DLL和被注入程序不在同一个目录,给绝对路径)
****************************************************************************************/
#include "stdafx.h"
#include "RemoteThreadInjectDLL.h"
int _tmain(int argc, _TCHAR* argv[])
{
    char cChar;
    CRemoteThreadInjectDLL objInject;
    printf("请按数字1注入DLL、数字2卸载DLL、数字0退出程序:");
    
    while (true)
    {
        cChar = getchar();
        if ('1' == cChar)
        {
            objInject.AttachByName(_T("被注入程序.exe"), _T("DllOfInject.dll"));
        }
        else if ('2' == cChar)
        {
            objInject.DetachByName(_T("被注入程序.exe"), _T("DllOfInject.dll"));
        }
        else if ('0' == cChar)
        {
            break;
        }
    }
     
    return 0;
}





/***************************************************************************************
* 文件名: DllOfInject.h (被注入的DLL)
* 功  能: DLL远程线程注入过程中被注入的DLL
* 说  明: 无导出符号,只在DLL加载时做文章
****************************************************************************************/
#ifdef DLLOFINJECT_EXPORTS
#define DLLOFINJECT_API __declspec(dllexport)
#else
#define DLLOFINJECT_API __declspec(dllimport)
#endif





/***************************************************************************************
* 文件名: DllOfInject.cpp (被注入的DLL)
* 功  能: DLL远程线程注入过程中被注入的DLL
* 说  明: 无导出符号,只在DLL加载时做文章
****************************************************************************************/
#include "stdafx.h"
#include "DllOfInject.h"






/***************************************************************************************
* 文件名: dllmain.cpp 
* 功  能: DLL远程线程注入过程中被注入的DLL
* 说  明: 无导出符号,只在DLL加载时做文章
****************************************************************************************/
#include "stdafx.h"
#include "windows.h"
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        {
            ::MessageBox(0, L"DLL注入成功!", L"温馨提示", MB_OK);
        }
        break;
    case DLL_THREAD_ATTACH:
        {
        }
        break;
    case DLL_THREAD_DETACH:
        {
        }
        break;
    case DLL_PROCESS_DETACH:
        {
            ::MessageBox(0, L"DLL卸载成功!", L"温馨提示", MB_OK);
        }
        break;
    }
    return TRUE;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值