您的位置:首页 > 其它

DLL注入

2015-08-25 20:17 316 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: