• 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;
    }
  • 相关阅读:
    2020-2021-1 20201314 《信息安全专业导论》第三周学习总结
    罗马数字转阿拉伯数字
    BASE64编码-20201314黄斯阳
    学期(2020-2021-1) 学号(20201314) 《信息安全专业导论》第2周学习总结
    师生关系
    快速浏览教材 。
    浏览教材的疑问
    2020-2021-1 20201314 《信息安全专业导论》第一周学习总结
    第四周作业补交
    第四周作业
  • 原文地址:https://www.cnblogs.com/fangkm/p/1550053.html
Copyright © 2020-2023  润新知