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;
}
posted @ 2009-08-19 17:34  孤竹君  阅读(508)  评论(0编辑  收藏  举报