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

 更新时间:2014年10月17日 14:48:12   投稿:shichen2014  
这篇文章主要介绍了C++封装远程注入类CreateRemoteThreadEx实例,详细讲述了注入DLL到指定的地址空间以及从指定的地址空间卸载DLL的方法,需要的朋友可以参考下

本文实例讲述了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++实现线性表顺序存储的相关知识,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2023-03-03
  • VC实现给窗体的一个按钮添加事件的方法

    VC实现给窗体的一个按钮添加事件的方法

    这篇文章主要介绍了VC实现给窗体的一个按钮添加事件的方法,通过三个简单步骤实现窗体按钮添加事件,需要的朋友可以参考下
    2015-05-05
  • C++的头文件和实现文件详解

    C++的头文件和实现文件详解

    这篇文章主要介绍了C++的头文件和实现文件详解的相关资料,需要的朋友可以参考下
    2015-01-01
  • C++音乐播放按钮的封装过程详解

    C++音乐播放按钮的封装过程详解

    此篇文章用于记录学习C++封装音乐播放按钮,封装将对象的属性和行为作为一个整体,表现生活中的事物、将属性和行为加以权限控制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • 浅谈C++的几种从键盘输入方式

    浅谈C++的几种从键盘输入方式

    今天小编就为大家分享一篇浅谈C++的几种从键盘输入方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • C++连接mysql数据库的两种方法小结

    C++连接mysql数据库的两种方法小结

    这篇文章主要介绍了C++连接mysql数据库的两种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • C语言编程C++动态内存分配示例讲解

    C语言编程C++动态内存分配示例讲解

    这篇文章主要介绍了C语言编程C++动态内存分配示例讲解,为什么存在动态内存分配?本文通过动态内存介绍及常见内存错误等示例来为大家讲解
    2021-09-09
  • C++ Boost Parameter超详细讲解

    C++ Boost Parameter超详细讲解

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • C++获取字符串长度的几个函数方式

    C++获取字符串长度的几个函数方式

    这篇文章主要介绍了C++获取字符串长度的几个函数方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • C语言动态分配二维字符串数组的方法

    C语言动态分配二维字符串数组的方法

    小编最近忙里偷闲,给大家整理一份教程关于C语言动态分配二维字符串数组的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-10-10

最新评论