c++实现dll注入其它进程

DLL注入其他进程技术
阅读本篇文章,需要有《线程注入其他进程技术》基础。
DLL注入技术才具有强大的功能和使用性,同时简单易用,因为DLL中可以实现复杂的功能和很多的技术。
 
 
技术要点:
1、宿主进程调用LoadLibrary,就可以完成DLL的远程注入。可以通过CreateRemoteThread将LoadLibrary作为宿主进程的一个线程来启动,就可以完成“控制目标进程调用LoadLibrary”的工作。
2、标准DLL中DllMain,是DLL执行的入口;使用MFC的DLL中InitInstance,是DLL执行的入口,但是没有消息循环。
   注意:
   a、如果是需要多线程,只能使用有DLLMain的标准DLL。因为使用MFC的DLL,在InitInstance中启动新的线程,会在启动线程的地方阻塞不继续执行。即说,使用带MFC的DLL只能单线程作业。
   b、如果需要使用多线程和MFC。可以在标准DLL中先启动线程,再调用使用MFC的DLL。
 

实现步骤
1、将DLL的地址拷贝到宿主进程地址空间中
2、通过CreateRemoteThread将LoadLibrary作为宿主进程的一个线程来启动
 
 
可以正确运行的示例代码(拷贝后直接可以使用):
应用程序文件内容:
// #pragma once

#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <time.h>

// 提升进程访问权限
bool enableDebugPriv()
{
    HANDLE  hToken;
    LUID    sedebugnameValue;
    TOKEN_PRIVILEGES tkp;
    if  ( !OpenProcessToken(  GetCurrentProcess(),
                            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)
        )
    {
        return false;
    }
    if( !LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue) )
    {
        CloseHandle(hToken);
        return false;
    }
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if( !AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL) )
    {
        CloseHandle(hToken);
        return false;
    }
    return true;
}

// 根据进程名称得到进程ID,如果有多个运行实例的话,返回第一个枚举到的进程的ID
DWORD processNameToId(LPCTSTR lpszProcessName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    if( !Process32First(hSnapshot, &pe) )
    {
        MessageBox( NULL,
                    "The frist entry of the process list has not been copyied to the buffer",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }
    while( Process32Next(hSnapshot, &pe) )
    {
        if( !strcmp(lpszProcessName, pe.szExeFile) )
        {
            return pe.th32ProcessID;
        }
    }
    return 0;
}

int main(int argc, char* argv[])
{
    // 定义线程体的大小
    const DWORD dwThreadSize = 5 * 1024;
    DWORD dwWriteBytes;
    // 提升进程访问权限
    enableDebugPriv();
    // 等待输入进程名称,注意大小写匹配
    std::cout << "Please input the name of target process !" << std::endl;
    char szExeName[MAX_PATH] = { 0 };
    std::cin >> szExeName;
    DWORD dwProcessId = processNameToId(szExeName);
    if( dwProcessId == 0 )
    {
        MessageBox( NULL,
                    "The target process have not been found !",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return -1;
    }

    // 根据进程ID得到进程句柄
    HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if( !hTargetProcess )
    {
        MessageBox( NULL,
                    "Open target process failed !",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }

    // 在宿主进程中为线程体开辟一块存储区域
    // 在这里需要注意MEM_COMMIT内存非配类型以及PAGE_EXECUTE_READWRITE内存保护类型
    // 其具体含义请参考MSDN中关于VirtualAllocEx函数的说明。
    void* pRemoteThread = VirtualAllocEx(   hTargetProcess,
                                            0,
                                            dwThreadSize,
                                            MEM_COMMIT , PAGE_EXECUTE_READWRITE);
    if( !pRemoteThread )
    {
        MessageBox( NULL,
                    "Alloc memory in target process failed !",
                    "notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }
    // 设置需要注入的DLL名称
    char szDll[256];
    memset(szDll, 0, 256);
    strcpy(szDll, "E:\\mydll.dll");
    // 拷贝注入DLL内容到宿主空间
    if( !WriteProcessMemory(    hTargetProcess,
                                pRemoteThread,
                                (LPVOID)szDll,
                                dwThreadSize,
                                0) )
    {
        MessageBox( NULL,
                    "Write data to target process failed !",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }

    LPVOID pFunc = LoadLibraryA;
    //在宿主进程中创建线程
    HANDLE hRemoteThread = CreateRemoteThread(  hTargetProcess,
                                                NULL,
                                                0,
                                                (LPTHREAD_START_ROUTINE)pFunc,
                                                pRemoteThread,
                                                0,
                                                &dwWriteBytes);
     if( !hRemoteThread )
     {
         MessageBox(    NULL,
                        "Create remote thread failed !",
                        "Notice",
                        MB_ICONINFORMATION | MB_OK
                        );
         return 0;
     }
     // 等待LoadLibraryA加载完毕
     WaitForSingleObject(hRemoteThread, INFINITE );
     VirtualFreeEx(hTargetProcess, pRemoteThread, dwThreadSize, MEM_COMMIT);
     CloseHandle( hRemoteThread );
     CloseHandle( hTargetProcess );
     return 0;
}
 
 
实验的标准DLL文件:
// mydll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
DWORD WINAPI MyThreadProc1( LPVOID pParam );
DWORD WINAPI MyThreadProc2( LPVOID pParam );
 
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch ( ul_reason_for_call )
    {
        case DLL_PROCESS_ATTACH:
        {
            MessageBox( NULL, "DLL已进入目标进程。", "信息", MB_ICONINFORMATION );
            DWORD dwThreadId;
            HANDLE myThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc1, NULL, 0, &dwThreadId);
            HANDLE myThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc2, NULL, 0, &dwThreadId);
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            MessageBox( NULL, "DLL已从目标进程卸载。", "信息", MB_ICONINFORMATION );
            break;
        }
    }
    return TRUE;
}
 
DWORD WINAPI MyThreadProc1( LPVOID pParam )
{
    MessageBox( NULL, "DLL已进入线程1。", "信息", MB_ICONINFORMATION );
    return 0;
}

DWORD WINAPI MyThreadProc2( LPVOID pParam )
{
    MessageBox( NULL, "DLL已进入线程2。", "信息", MB_ICONINFORMATION );
 

c++实现dll注入其它进程,布布扣,bubuko.com

c++实现dll注入其它进程

上一篇:java 环境变量配置


下一篇:线程同步控制