CreateRemoteThread小记

利用全局钩子可以注入DLL到当前的所有进程,若要注入到特定的进程中可用CreateRemoteThread函数.
#include  < Tlhelp32.h >

/*
*  向指定进程注入DLL
*  dwProcessID: 目标进程ID
*  lpszDll: 待注入的DLL完全路径
* 返回注入成功与否
*/
inline  BOOL  InjectDllIntoProcess( DWORD  dwProcessID, LPCTSTR lpszDll )
{
    BOOL      bRet         
=   FALSE;
    HANDLE  hProcess   
=   NULL;
    PSTR  pszRemoteDll   
=   NULL;

    
do  
    {
        
// 根据进程ID获取进程句柄
        hProcess   =   ::OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessID );
        
if ( hProcess  ==  NULL )
            
break ;

        
int  nAllocSize   =   ( _tcslen( lpszDll )  +   1  )  *   sizeof (TCHAR);
        
// 在远程进程中分配内存
        pszRemoteDll   =   (PSTR)::VirtualAllocEx( hProcess, NULL, nAllocSize, MEM_COMMIT, PAGE_READWRITE );
        
if ( pszRemoteDll  ==  NULL )
            
break ;
        
// 写内存
         if ! ::WriteProcessMemory( hProcess, pszRemoteDll, lpszDll, nAllocSize,  NULL ) )
            
break ;

        LPTHREAD_START_ROUTINE  pfnThread 
=   NULL;
        
// Kernel32模块在每个进程中都被映射到相同的地址,故在本进程获取到的LoadLibrary函数地址和远程进程中地址是一样的
#ifdef UNICODE
        pfnThread  
=  ( LPTHREAD_START_ROUTINE ) ::GetProcAddress( ::GetModuleHandle( _T( " Kernel32 " ) ),  " LoadLibraryW "  );
#else
        pfnThread  
=  ( LPTHREAD_START_ROUTINE ) ::GetProcAddress( ::GetModuleHandle( _T( " Kernel32 " ) ),  " LoadLibraryA "  );
#endif   //  !UNICODE

        
if ( pfnThread  ==  NULL )
            
break ;

        HANDLE  hThread  
=   ::CreateRemoteThread( hProcess, NULL,  0 , pfnThread, pszRemoteDll,  0 , NULL );
        
if ( hThread  ==  NULL )
            
break ;
        
// 等待远程线程结束
        ::WaitForSingleObject( hThread, INFINITE );
        ::CloseHandle( hThread );

        bRet   
=   TRUE;
    } 
while ( FALSE );

    
// 释放资源
     if ( pszRemoteDll  !=  NULL )
        ::VirtualFreeEx( hProcess, pszRemoteDll, 
0 , MEM_RELEASE );
    
if ( hProcess  !=  NULL )
        ::CloseHandle( hProcess );

    
return  bRet;
}

/*
*  从指定进程释放DLL
*  dwProcessID: 目标进程ID
*  lpszDll: 待释放的DLL名称
* 返回释放成功与否
*/
inline  BOOL  FreeDllFromProcess( DWORD  dwProcessID, LPCTSTR lpszDll )
{
    
// 首先搜索进程的所有模块,如果没找到lpszDll指定的模块则直接退出
    HANDLE  hthSnapShot   =   ::CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessID );
    
if ( hthSnapShot   ==  INVALID_HANDLE_VALUE )
        
return  FALSE;

    BOOL   bHasMod  
=   FALSE;
    MODULEENTRY32  hMod  
=   {  sizeof (MODULEENTRY32) };
    BOOL  bMoreMods  
=   ::Module32First( hthSnapShot,  & hMod );
    
while  ( bMoreMods )
    {
        
if ( ( lstrcmpi( hMod.szExePath, lpszDll )  ==   0  )  ||  ( lstrcmpi( hMod.szModule, lpszDll )  ==   0  ) )
        {
            bHasMod  
=   TRUE;
            
break ;
        }
        bMoreMods  
=   ::Module32Next( hthSnapShot,  & hMod );
    }
    ::CloseHandle( hthSnapShot );
    
    
if ! bHasMod )
        
return   FALSE;

    BOOL      bRet         
=   FALSE;
    HANDLE  hProcess   
=   NULL;

    
do  
    {
        hProcess  
=   ::OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessID );
        
if ( hProcess  ==  NULL )
            
break ;

        LPTHREAD_START_ROUTINE  pfnThread 
=   ( LPTHREAD_START_ROUTINE ) ::GetProcAddress( ::GetModuleHandle( _T( " Kernel32 " ) ),  " FreeLibrary "  );

        
if ( pfnThread  ==  NULL )
            
break ;

        HANDLE  hThread  
=   ::CreateRemoteThread( hProcess, NULL,  0 , pfnThread, hMod.modBaseAddr,  0 , NULL );
        
if ( hThread  ==  NULL )
            
break ;

        ::WaitForSingleObject( hThread, INFINITE );
        ::CloseHandle( hThread );

        bRet   
=   TRUE;

    } 
while ( FALSE );

    
if ( hProcess  !=  NULL )
        ::CloseHandle( hProcess );

    
return   bRet;
}


/ //CreateRemoteThread注入线程函数 /// /
/*
* 在Debug下编译须去除/GZ编译开关
*/
typedef 
struct  _SMsgBoxParam
{
    DWORD_PTR  m_pfnMsgBox;   
// MessageBox的函数地址
    TCHAR  m_szCaption[ 128 ];    // 标题
    TCHAR  m_szText[ 256 ];        // 文本
    UINT     m_uType;                     // MessageBox显示类型
}SMsgBoxParam,  * PSMsgBoxParam;

DWORD  WINAPI  _InjectThreadProc( PSMsgBoxParam pMsgParam )
{
    ATLASSERT( pMsgParam 
!=  NULL );

    typedef  
int   (WINAPI  * PMessageBox)( HWND hWnd,  LPCTSTR lpText,  LPCTSTR lpCaption,  UINT uType ); 

    PMessageBox  pfnMsgBox 
=  (PMessageBox)pMsgParam -> m_pfnMsgBox;

    
if ( pfnMsgBox  !=  NULL )
    {
        pfnMsgBox( NULL, pMsgParam
-> m_szText, pMsgParam -> m_szCaption, pMsgParam -> m_uType );
    }

    
return   0 ;
}

const   DWORD  THREADSIZE   =    4096 ;

inline  BOOL  InjectTaskIntoProcess(  DWORD  dwProcessID )
{
    BOOL  bRet  
=   FALSE;
    HANDLE  hProcess   
=   NULL;
    LPVOID    pRemoteProc  
=   NULL;   
    PSMsgBoxParam   pMsgParam   
=   NULL;

    
do  
    {
        
// 根据进程ID获取进程句柄
        hProcess   =   ::OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessID );
        
if ( hProcess  ==  NULL )
            
break ;

        
// 在远程进程中注入函数地址
        pRemoteProc   =   ::VirtualAllocEx( hProcess, NULL, THREADSIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
        
if ( pRemoteProc  ==  NULL )
            
break ;
        
// 写内存
         if ! ::WriteProcessMemory( hProcess, pRemoteProc,  & _InjectThreadProc, THREADSIZE,  NULL ) )
            
break ;

        
// 在远程进程中注入参数地址
        SMsgBoxParam msgboxParam;
        wsprintf( msgboxParam.m_szCaption, _T(
" 提示 " ) );
        wsprintf( msgboxParam.m_szText, _T(
" 来自注入进程的对话框 " ) );
        msgboxParam.m_uType   
=   MB_OK;

        #ifdef UNICODE
            msgboxParam.m_pfnMsgBox  
=  ( DWORD_PTR ) ::GetProcAddress( ::GetModuleHandle( _T( " User32 " ) ),  " MessageBoxW "  );
        
#else
            msgboxParam.m_pfnMsgBox  
=  ( DWORD_PTR ) ::GetProcAddress( ::GetModuleHandle( _T( " User32 " ) ),  " MessageBoxA "  );
        
#endif   //  !UNICODE

        pMsgParam  
=   (PSMsgBoxParam)::VirtualAllocEx( hProcess, NULL,  sizeof (msgboxParam), MEM_COMMIT, PAGE_READWRITE );
        
if ( pMsgParam  ==  NULL )
            
break ;
        
// 写内存
         if ! ::WriteProcessMemory( hProcess, pMsgParam,  & msgboxParam,  sizeof (msgboxParam),  NULL ) )
            
break ;

        
        HANDLE  hThread  
=   ::CreateRemoteThread( hProcess, NULL,  0 , (LPTHREAD_START_ROUTINE)pRemoteProc, pMsgParam,  0 , NULL );
        
if ( hThread  ==  NULL )
            
break ;
        
// 等待远程线程结束
        ::WaitForSingleObject( hThread, INFINITE );
        ::CloseHandle( hThread );

        bRet   
=   TRUE;
    } 
while ( FALSE );


    
// 释放资源
     if ( pMsgParam  !=  NULL )
        ::VirtualFreeEx( hProcess, pMsgParam, 
0 , MEM_RELEASE );
    
if ( pRemoteProc  !=  NULL )
        ::VirtualFreeEx( hProcess, pRemoteProc, 
0 , MEM_RELEASE );
    
if ( hProcess  !=  NULL )
        ::CloseHandle( hProcess );

    
return   bRet;
}

转载于:https://www.cnblogs.com/fangkm/archive/2009/08/19/1550053.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值