InjectDLL.h

#pragma once

class CInjectDLL
{

public:
    CInjectDLL();
    ~CInjectDLL();

public:
    int Inject(LPCTSTR lpProcess, LPCTSTR lpDLLPath);
    void UnInject();

private:
    HMODULE m_hDLLModule;
    HANDLE m_hRemoteProcess;
    HMODULE m_hKernel32;

private:
    DWORD GetProcessID(LPCTSTR lpProcess);
    void EnableDebugPrivileges();
};

InjectDLL.cpp

#include "stdafx.h"
#include "InjectDLL.h"
#include <Tlhelp32.h>
#include <io.h>

CInjectDLL::CInjectDLL()
{
}

CInjectDLL::~CInjectDLL()
{
}

DWORD CInjectDLL::GetProcessID(LPCTSTR lpProcess)
{
    DWORD nProcessId = -1;
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        return -1;
    }

    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(pe);

    BOOL bRet = Process32First(hProcessSnap, &pe);
    while (bRet)
    {
        if (lstrcmpi(pe.szExeFile, lpProcess) == 0)
        {
            nProcessId = pe.th32ProcessID;
            break;
        }

        bRet = Process32Next(hProcessSnap, &pe);
    }
    CloseHandle(hProcessSnap);
    return nProcessId;
}

void CInjectDLL::EnableDebugPrivileges()
{
    LUID luid;
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);

    TOKEN_PRIVILEGES tkp;
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    HANDLE hToken;
    OpenProcessToken(GetCurrentProcess(), 
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
        &hToken);

    AdjustTokenPrivileges(hToken, 
        FALSE, 
        &tkp, 
        sizeof(tkp),
        NULL, 
        NULL);

    CloseHandle(hToken);
}

int CInjectDLL::Inject(LPCTSTR lpProcess,LPCTSTR lpDLLPath)
{
    TCHAR szDLLPath[MAX_PATH];
    strcpy_s(szDLLPath, lpDLLPath);
    if (_access(szDLLPath, 0) == -1)
    {
        return 1;
    }

    long pid = GetProcessID(lpProcess);
    if (pid == -1)
    {
        return 2;
    }
    
    m_hKernel32 = GetModuleHandle("Kernel32");
    if (m_hKernel32 == NULL)
    {
        return 3;
    }

    EnableDebugPrivileges();

    m_hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
    if (m_hRemoteProcess == NULL)
    {
        CloseHandle(m_hKernel32);
        return 4;
    }

    void *lpProcessBuff = VirtualAllocEx(
        m_hRemoteProcess, 
        NULL, 
        sizeof(szDLLPath),
        MEM_COMMIT, 
        PAGE_READWRITE);

    int ret = WriteProcessMemory(
        m_hRemoteProcess, 
        lpProcessBuff, 
        (void *)szDLLPath, 
        sizeof(szDLLPath), 
        NULL);
    if (ret == 0)
    {
        VirtualFreeEx(
            m_hRemoteProcess,
            lpProcessBuff,
            sizeof(szDLLPath),
            MEM_RELEASE);
        
        CloseHandle(m_hRemoteProcess);
        return 5;
    }

    HANDLE hRemoteThread = CreateRemoteThread(
        m_hRemoteProcess, 
        NULL, 
        0,
        (LPTHREAD_START_ROUTINE)GetProcAddress(m_hKernel32, "LoadLibraryA"),
        lpProcessBuff, 
        0, 
        NULL);

    WaitForSingleObject(hRemoteThread, INFINITE);

    // 取得 LoadLibraryA 返回的 HMODULE
    GetExitCodeThread(hRemoteThread, (LPDWORD)&m_hDLLModule);
    CloseHandle(hRemoteThread);

    VirtualFreeEx(
        m_hRemoteProcess, 
        lpProcessBuff, 
        sizeof(szDLLPath), 
        MEM_RELEASE);
    
    return 0;
}

void CInjectDLL::UnInject()
{
    HANDLE hThread = CreateRemoteThread(
        m_hRemoteProcess, 
        NULL, 
        0,
        (LPTHREAD_START_ROUTINE)::GetProcAddress(m_hKernel32, "FreeLibrary"),
        (LPVOID)m_hDLLModule, // thread argument
        0, 
        NULL);

    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    
    CloseHandle(m_hRemoteProcess);
}

使用方法:

#include "InjectDLL.h"

CInjectDLL obj;

int ret = obj.Inject("RTX.exe", "D:\\Test\\Hook.dll");
if (ret != 0)
{
    CString csErrMsg;
    csErrMsg.Format("error:%d", ret);
    AfxMessageBox(csErrMsg);
}

obj.UnInject();

 


本文链接地址: 通过远程线程注入DLL到指定进程
http://qingfengju.com/index.asp?id=370

分类:Win32/C++ 查看次数:2514 发布时间:2014-5-7 18:19:38