Dll注入

InjectUtils.h

#pragma once

#include <string>
#include <windows.h>
#include <tchar.h>

#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif

class InjectUtils
{
public:

    // 远程线程方式为指定进程加载 DLL 模块
    static bool LoadByRemoteThread(DWORD dwPID, const _tstring& strModulePath);

    // 远程线程方式为指定进程卸载 DLL 模块
    static bool UnloadByRemoteThread(DWORD dwPID, const _tstring& strModulePath);

private:

    static bool EnablePrivileges(HANDLE hProcess, LPCTSTR lpPrivilegesName);
    static FARPROC GetModuleProcAddress(LPCTSTR lpModulePath, LPCSTR lpProcName);
    static HMODULE GetProcessModuleHandle(HANDLE hProcess, const _tstring& strModulePath);
};

InjectUtils.cpp

#include "InjectUtils.h"
#include <psapi.h>

#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)

typedef NTSTATUS (WINAPI* PfnNtCreateThreadEx)(
    _Out_ PHANDLE ThreadHandle,
    _In_ ACCESS_MASK DesiredAccess,
    _In_opt_ LPVOID ObjectAttributes,
    _In_ HANDLE ProcessHandle,
    _In_ LPTHREAD_START_ROUTINE StartRoutine,
    _In_opt_ PVOID Argument,
    _In_ ULONG CreateFlags,
    _In_ SIZE_T ZeroBits,
    _In_ SIZE_T StackSize,
    _In_ SIZE_T MaximumStackSize,
    _In_opt_ LPVOID AttributeList
    );

bool InjectUtils::LoadByRemoteThread(DWORD dwPID, const _tstring& strModulePath)
{
    HANDLE hProcess = NULL;
    HANDLE hThread = NULL;
    PVOID pRemoteMem = NULL;
    SIZE_T path_length = 0;
    bool fResult = false;

    do
    {
        // 提权
        if (!EnablePrivileges(GetCurrentProcess(), SE_DEBUG_NAME))
        {
            break;
        }

        // 打开进程
        DWORD dwDesiredAccess = PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD;
        hProcess = ::OpenProcess(dwDesiredAccess, FALSE, dwPID);
        if (!hProcess)
        {
            break;
        }

        // 申请远程内存
        path_length = (strModulePath.size() + 1) * sizeof(TCHAR);
        pRemoteMem = ::VirtualAllocEx(hProcess, NULL, path_length, MEM_COMMIT, PAGE_READWRITE);
        if (!pRemoteMem)
        {
            break;
        }

        // 向远程内存写入模块路径
        if (!::WriteProcessMemory(hProcess, pRemoteMem, strModulePath.c_str(), path_length, NULL))
        {
            break;
        }

        // 获取 LoadLibraryW 函数
        FARPROC _LoadLibrary = GetModuleProcAddress(_T("kernel32.dll"), "LoadLibraryW");
        if (!_LoadLibrary)
        {
            break;
        }

        // 获取 NtCreateThreadEx 函数
        PfnNtCreateThreadEx _NtCreateThreadEx = (PfnNtCreateThreadEx)GetModuleProcAddress(_T("Ntdll.dll"), "NtCreateThreadEx");
        if (!_NtCreateThreadEx)
        {
            break;
        }

        // 创建远程线程
        if (!NT_SUCCESS(_NtCreateThreadEx(&hThread, PROCESS_ALL_ACCESS, NULL, hProcess, (LPTHREAD_START_ROUTINE)_LoadLibrary, pRemoteMem, 0, 0, 0, 0, NULL)))
        {
            break;
        }

        // 等待线程结束
        if (WAIT_OBJECT_0 != ::WaitForSingleObject(hThread, INFINITE))
        {
            break;
        }

        // 获取返回值
        DWORD dwExitCode = 0;
        ::GetExitCodeThread(hThread, &dwExitCode);
        if (!dwExitCode)
        {
            break;
        }

        fResult = true;

    } while (false);

    // 关闭线程句柄
    if (hThread)
    {
        ::CloseHandle(hThread);
    }

    // 释放远程内存
    if (pRemoteMem)
    {
        ::VirtualFreeEx(hProcess, pRemoteMem, 0, MEM_RELEASE);
    }

    // 关闭进程句柄
    if (hProcess)
    {
        ::CloseHandle(hProcess);
    }

    return fResult;
}

bool InjectUtils::UnloadByRemoteThread(DWORD dwPID, const _tstring& strModulePath)
{
    HANDLE hProcess = NULL;
    HANDLE hThread = NULL;
    bool fResult = false;

    do
    {
        // 提权
        if (!EnablePrivileges(GetCurrentProcess(), SE_DEBUG_NAME))
        {
            break;
        }

        // 打开进程
        DWORD dwDesiredAccess = PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
        hProcess = ::OpenProcess(dwDesiredAccess, FALSE, dwPID);
        if (!hProcess)
        {
            break;
        }

        // 获取指定模块句柄
        HANDLE hTargetModule = GetProcessModuleHandle(hProcess, strModulePath);
        if (!hTargetModule)
        {
            break;
        }

        // 获取 FreeLibrary 函数
        FARPROC _FreeLibrary = GetModuleProcAddress(_T("kernel32.dll"), "FreeLibrary");
        if (NULL == _FreeLibrary)
        {
            break;
        }

        // 获取 NtCreateThreadEx 函数
        PfnNtCreateThreadEx _NtCreateThreadEx = (PfnNtCreateThreadEx)GetModuleProcAddress(_T("Ntdll.dll"), "NtCreateThreadEx");
        if (!_NtCreateThreadEx)
        {
            break;
        }

        // 创建远程线程
        if (!NT_SUCCESS(_NtCreateThreadEx(&hThread, PROCESS_ALL_ACCESS, NULL, hProcess, (LPTHREAD_START_ROUTINE)_FreeLibrary, (LPVOID)hTargetModule, 0, 0, 0, 0, NULL)))
        {
            break;
        }

        // 等待线程结束
        if (WAIT_OBJECT_0 != ::WaitForSingleObject(hThread, INFINITE))
        {
            break;
        }

        // 获取返回值
        DWORD dwExitCode = 0;
        ::GetExitCodeThread(hThread, &dwExitCode);
        if (!dwExitCode)
        {
            break;
        }

        fResult = true;

    } while (false);

    // 关闭线程句柄
    if (hThread)
    {
        ::CloseHandle(hThread);
    }

    // 关闭进程句柄
    if (hProcess)
    {
        ::CloseHandle(hProcess);
    }

    return fResult;
}

bool InjectUtils::EnablePrivileges(
    HANDLE hProcess, 
    LPCTSTR lpPrivilegesName
)
{
    HANDLE hToken = NULL;
    LUID luidValue = { 0 };
    TOKEN_PRIVILEGES tokenPrivileges = { 0 };
    BOOL isSuccess = FALSE;

    do
    {
        if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken))
        {
            break;
        }

        if (!::LookupPrivilegeValue(NULL, lpPrivilegesName, &luidValue))
        {
            break;
        }

        tokenPrivileges.PrivilegeCount = 1;
        tokenPrivileges.Privileges[0].Luid = luidValue;
        tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        if (!::AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, NULL, NULL))
        {
            break;
        }

        isSuccess = true;

    } while (false);

    if (hToken)
    {
        ::CloseHandle(hToken);
    }

    return isSuccess;
}

FARPROC InjectUtils::GetModuleProcAddress(LPCTSTR lpModulePath, LPCSTR lpProcName)
{
    FARPROC ProcAddr = NULL;

    // 获取模块句柄
    HMODULE hModule = ::GetModuleHandle(lpModulePath);
    if (!hModule)
    {
        return NULL;
    }

    // 获取函数地址
    ProcAddr = ::GetProcAddress(hModule, lpProcName);

    return ProcAddr;
}

HMODULE InjectUtils::GetProcessModuleHandle(HANDLE hProcess, const _tstring& strModulePath)
{
    HMODULE* phMods = NULL;
    HMODULE hModule = NULL;
    DWORD cbNeeded = 0;
    DWORD dwModSize = 0;

    do
    {
        // 枚举进程模块
        if (!::EnumProcessModulesEx(hProcess, NULL, NULL, &cbNeeded, LIST_MODULES_ALL))
        {
            break;
        }

        // 分配枚举进程模块所需内存
        dwModSize = cbNeeded;
        phMods = (HMODULE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwModSize);
        if (NULL == phMods)
        {
            break;
        }

        // 枚举进程模块
        if (!::EnumProcessModulesEx(hProcess, phMods, dwModSize, &cbNeeded, LIST_MODULES_ALL))
        {
            break;
        }

        // 检索模块
        size_t nModuleCnt = cbNeeded / sizeof(HMODULE);
        for (size_t i = 0; i < nModuleCnt; i++)
        {
            TCHAR szModName[MAX_PATH] = { 0 };
            if (::GetModuleFileNameEx(hProcess, phMods[i], szModName, _countof(szModName)))
            {
                if (0 == _tcsicmp(szModName, strModulePath.c_str()))
                {
                    hModule = phMods[i];
                    break;
                }
            }
        }

    } while (false);

    // 释放模块句柄内存
    if (phMods)
    {
        ::HeapFree(::GetProcessHeap(), 0, phMods);
    }

    return hModule;
}

main.cpp

#include <iostream>
#include "InjectUtils.h"

int main()
{
    InjectUtils::LoadByRemoteThread(27036, _T(R"(D:\FC_Gitee\dll_inject\dll_inject\Bin\Dll_Demo.dll)"));
    InjectUtils::UnloadByRemoteThread(27036, _T(R"(D:\FC_Gitee\dll_inject\dll_inject\Bin\Dll_Demo.dll)"));

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值