C++封装远程注入类CreateRemoteThreadEx实例

所属分类: 软件编程 / C 语言 阅读数: 49
收藏 0 赞 0 分享

本文实例讲述了C++封装远程注入类CreateRemoteThreadEx的方法,分享给大家供大家参考。具体方法如下:

首先,类初始化时传入要注入的DLL文件名

只使用两个函数

复制代码 代码如下:
// 注入DLL到指定的地址空间
BOOL InjectModuleInto(DWORD dwProcessId);
// 从指定的地址空间卸载DLL
BOOL EjectModuleFrom(DWORD dwProcessId);

.h头文件如下:

复制代码 代码如下:
#pragma once 
#include <windows.h>  //在头文件中包含 
 
class CRemThreadInject 

public: 
    CRemThreadInject(LPSTR lpDllName); 
    ~CRemThreadInject(void); 
 
protected: 
    char m_szDllName[MAX_PATH]; 
    static BOOL EnableDebugPrivilege(BOOL bEnable); 
public: 
    // 注入DLL到指定的地址空间 
    BOOL InjectModuleInto(DWORD dwProcessId); 
    // 从指定的地址空间卸载DLL 
    BOOL EjectModuleFrom(DWORD dwProcessId); 
};

.cpp源文件如下:

复制代码 代码如下:
#include "RemThreadInject.h" 
#include <tlhelp32.h>  
 
CRemThreadInject::CRemThreadInject(LPSTR lpDllName) 

    memcpy(m_szDllName, lpDllName, MAX_PATH); 
    EnableDebugPrivilege(TRUE); 

 
CRemThreadInject::~CRemThreadInject(void) 

    EnableDebugPrivilege(FALSE); 

 
BOOL CRemThreadInject::EnableDebugPrivilege(BOOL bEnable) 

    HANDLE hToken = INVALID_HANDLE_VALUE; 
    //OpenProcessToken 
    if (0 == ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) 
    { 
        return FALSE; 
    } 
    LUID luid; 
     
    // 
    ::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); 
    TOKEN_PRIVILEGES tp; 
    tp.PrivilegeCount = 1; 
    tp.Privileges[0].Luid = luid; 
    if (bEnable) 
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    else 
        tp.Privileges[0].Attributes = 0; 
    if ( !AdjustTokenPrivileges( 
        hToken,  
        FALSE,  
        &tp,  
        sizeof(TOKEN_PRIVILEGES),  
        (PTOKEN_PRIVILEGES) NULL,  
        (PDWORD) NULL) ) 
    {  
        return FALSE;  
    }  
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 
    { 
        return FALSE; 
    }  
    ::CloseHandle(hToken); 
    return TRUE; 

 
// 注入DLL到指定的地址空间 
BOOL CRemThreadInject::InjectModuleInto(DWORD dwProcessId) 

    // 
    if (::GetCurrentProcessId() == dwProcessId) 
    { 
        return FALSE;  
    } 
    BOOL bFound; 
    /************************************************************************/ 
    /* 遍历模块                                                              */ 
    /************************************************************************/ 
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;  
    MODULEENTRY32 me32;  
 
    //  Take a snapshot of all modules in the specified process.  
    hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );  
    if( hModuleSnap == INVALID_HANDLE_VALUE )  
    {  
        return( FALSE );  
    }  
    me32.dwSize = sizeof( MODULEENTRY32 );  
    if( !Module32First( hModuleSnap, &me32 ) )  
    {  
        CloseHandle( hModuleSnap );     // Must clean up the snapshot object!  
        return( FALSE );  
    }  
    do  
    {  
        if (stricmp(me32.szModule, m_szDllName) == 0) 
        { 
            bFound = TRUE; 
            break; 
        } 
    } while( Module32Next( hModuleSnap, &me32 ) );  
 
    //  Do not forget to clean up the snapshot object.  
    CloseHandle( hModuleSnap );  
 
    if (bFound) //如果已经加载了模块,就不再加载 
    { 
        return FALSE; 
    } 
 
    //如果没加载,打开进程,远程注入 
     
    HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD |PROCESS_VM_OPERATION |PROCESS_VM_WRITE, FALSE, dwProcessId); 
    if (hProcess == NULL) 
    { 
        return FALSE; 
    } 
    HMODULE  hKernerl32 = GetModuleHandle("kernel32.dll"); 
    LPTHREAD_START_ROUTINE pfnLoadLibraryA = (LPTHREAD_START_ROUTINE)::GetProcAddress(hKernerl32, "LoadLibraryA");  
 
    int cbSize = strlen(m_szDllName)+1; 
    LPVOID lpRemoteDllName = ::VirtualAllocEx(hProcess, 0, cbSize, MEM_COMMIT, PAGE_READWRITE); 
    ::WriteProcessMemory(hProcess, lpRemoteDllName, m_szDllName, cbSize, NULL); 
    HANDLE hRemoteThread = ::CreateRemoteThreadEx(hProcess, NULL, 0, pfnLoadLibraryA, lpRemoteDllName, 0, NULL, NULL); 
    if (NULL == hRemoteThread) 
    { 
        ::CloseHandle(hProcess); 
        return FALSE; 
    } 
    //等待目标线程运行结束,即LoadLibraryA函数返回 
    ::WaitForSingleObject(hRemoteThread, INFINITE); 
    ::CloseHandle(hRemoteThread); 
    ::CloseHandle(hProcess); 
    return TRUE; 

 
// 从指定的地址空间卸载DLL 
BOOL CRemThreadInject::EjectModuleFrom(DWORD dwProcessId) 

    // 
    if (::GetCurrentProcessId() == dwProcessId) 
    { 
        return FALSE;  
    } 
    BOOL bFound; 
    /************************************************************************/ 
    /* 遍历模块                                                              */ 
    /************************************************************************/ 
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;  
    MODULEENTRY32 me32;  
 
    //  Take a snapshot of all modules in the specified process.  
    hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );  
    if( hModuleSnap == INVALID_HANDLE_VALUE )  
    {  
        return( FALSE );  
    }  
    me32.dwSize = sizeof( MODULEENTRY32 );  
    if( !Module32First( hModuleSnap, &me32 ) )  
    {  
        CloseHandle( hModuleSnap );     // Must clean up the snapshot object!  
        return( FALSE );  
    }  
    do  
    {  
        if (stricmp(me32.szModule, m_szDllName) == 0) 
        { 
            bFound = TRUE; 
            break; 
        } 
    } while( Module32Next( hModuleSnap, &me32 ) );  
 
    //  Do not forget to clean up the snapshot object.  
    CloseHandle( hModuleSnap );  
 
    if (!bFound) //如果没有加载模块,就不能卸载 
    { 
        return FALSE; 
    } 
 
    //如果加载了,打开进程,远程注入 
 
    HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD |PROCESS_VM_OPERATION |PROCESS_VM_WRITE, FALSE, dwProcessId); 
    if (hProcess == NULL) 
    { 
        return FALSE; 
    } 
    HMODULE  hKernerl32 = GetModuleHandle("kernel32.dll"); 
    LPTHREAD_START_ROUTINE pfnFreeLibrary = (LPTHREAD_START_ROUTINE)::GetProcAddress(hKernerl32, "FreeLibrary");
 
    int cbSize = strlen(m_szDllName)+1; 
    LPVOID lpRemoteDllName = ::VirtualAllocEx(hProcess, 0, cbSize, MEM_COMMIT, PAGE_READWRITE); 
    ::WriteProcessMemory(hProcess, lpRemoteDllName, m_szDllName, cbSize, NULL); 
    HANDLE hRemoteThread = ::CreateRemoteThreadEx(hProcess, NULL, 0, pfnFreeLibrary, lpRemoteDllName, 0, NULL, NULL); 
    if (NULL == hRemoteThread) 
    { 
        ::CloseHandle(hProcess); 
        return FALSE; 
    } 
    //等待目标线程运行结束,即LoadLibraryA函数返回 
    ::WaitForSingleObject(hRemoteThread, INFINITE); 
    ::CloseHandle(hRemoteThread); 
    ::CloseHandle(hProcess); 
    return TRUE; 
}

希望本文所述对大家的C++程序设计有所帮助。

更多精彩内容其他人还在看

C++广播通信实例

这篇文章主要介绍了C++实现广播通信的方法,实例讲述了C++ socket广播通信的原理与实现方法,需要的朋友可以参考下
收藏 0 赞 0 分享

C++计算ICMP头的校验和实例

这篇文章主要介绍了C++计算ICMP头的校验和的方法,代码简单实用,对于校验ICMP报文来说有不错的实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++设置超时时间的简单实现方法

这篇文章主要介绍了C++设置超时时间的简单实现方法,涉及系统函数setsockopt对套接口的操作,具有一定的实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++实现ping程序实例

这篇文章主要介绍了C++实现ping程序实例,涉及C++对于ICMP数据包的发送与回显处理,具有一定的实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++之boost::array的用法

这篇文章主要介绍了C++之boost::array的用法,以实例的形式简单讲述了静态数组的容器boost::array的使用技巧,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C++之Boost::array用法简介

这篇文章主要介绍了C++之Boost::array用法简介,较为详细的分析了Boost::array中的常见用法,并用实例的形式予以总结归纳,需要的朋友可以参考下
收藏 0 赞 0 分享

VC文件目录常见操作实例汇总

这篇文章主要介绍了VC文件目录常见操作实例汇总,总结了VC针对文件目录的各种常用操作,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享

VC打印word,excel文本文件的方法

这篇文章主要介绍了VC打印word,excel文本文件的方法,是VC操作文本文件中非常实用的技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

VC++获得当前进程运行目录的方法

这篇文章主要介绍了VC++获得当前进程运行目录的方法,可通过系统函数实现该功能,是非常实用的技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

VC中SendMessage和PostMessage的区别

这篇文章主要介绍了VC中SendMessage和PostMessage的区别,较为全面的分析了SendMessage和PostMessage运行原理及用法上的不同之处,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多