问:

在cmd.exe下运行rundll32.exe mydll.dll,MyFunc ,本想直接在当前cmd窗口输出调试信息.
可因rundll32是Win32 GUI程序而非Win32 console,所以cmd.exe标准输入输出句柄无法被mydll.dll继承用来向父进程cmd.exe输出数据.
这时, 如果用强行用GetStdHandle获得句柄,然后用WriteConsole来进行输出,则会发生无效句柄错误.
但是如果在这之前先AllocConsole,则可正常WriteConsole,但是会新建个控制台窗口来输出数据,很不爽 :-P

有没有什么办法向当前cmd.exe窗口输出数据呢?

我想通过给进程拍照和遍历,
可以获得rundll32的父进程cmd.exe的PID和Handle,但如何进一步下去(建立管道, 写数据)就没辙了?

不知道有没有描述清楚 还是太罗嗦了,麻烦大家看看,谢谢~

 

答:

如果只是要输出数据的话 可以向父窗口 发送键盘消息 WM_CHAR 输出你的数据

 

 

代码

Code:


BOOL APIENTRY DllMain ( HANDLE hModule ,
                        DWORD  ul_reason_for_call ,
                        LPVOID lpReserved )
{
    switch ( ul_reason_for_call )
    {
        case DLL_PROCESS_ATTACH :
             ShowMe ();
            
        case DLL_THREAD_ATTACH :
        case DLL_THREAD_DETACH :
        case DLL_PROCESS_DETACH :
            break;

    }
    return TRUE ;
}


void ShowMe ()
{
     DWORD    dwProcID ;
     HWND    hWnd ;
     dwProcID = FindParentProcID ( GetCurrentProcessId ());
         sprintf ( buf , "dwProcID:%d\nProcessId:%d " ,   dwProcID , GetCurrentProcessId ());
         MessageBox ( NULL , buf , "提示" , MB_ICONERROR );
    if( dwProcID == - 1 )
        return;

     hWnd = GetProcessMainWnd ( dwProcID );
    if( hWnd == NULL )
        return;

     SendMessage ( hWnd , WM_CHAR , WPARAM ( 'Z' ), NULL );
}


Code:

DWORD FindParentProcID ( DWORD dwChildProcID )         //找到返回父进程PID, 找不到返回-1
{
     PROCESSENTRY32     pr32 = { 0 };
     pr32 . dwSize = sizeof ( PROCESSENTRY32 );    // 不要漏了这句

    // 提权先
     DebugPrivilege ( SE_DEBUG_NAME , TRUE );    
     // 给进程照相
     HANDLE hSnap = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS , 0 );
     // 拍照失败, 返回-1
     if ( hSnap == ( HANDLE )- 1 ) return ( DWORD )- 1 ;
    
     // 开始枚举...
     if ( Process32First ( hSnap ,& pr32 ) == FALSE )  
    {
         CloseHandle ( hSnap );
        return ( DWORD )- 1 ;
    }

    do
    {
        if( pr32 . th32ProcessID == dwChildProcID )  
        {             // 如果被枚举到的进程ID等于所给的ID, 则返回父进程ID
             CloseHandle ( hSnap );
            return pr32 . th32ParentProcessID ;
        }
    }
    while( Process32Next ( hSnap , & pr32 ));

     // 找不到父进程ID, 返回-1
     CloseHandle ( hSnap );
    return - 1 ;
}


Code:

typedef struct tagWNDINFO
{
     DWORD dwProcessId ;
     HWND hWnd ;
} WNDINFO , * LPWNDINFO ;

BOOL CALLBACK YourEnumProc ( HWND hWnd , LPARAM lParam )
{
     DWORD dwProcessId ;
     GetWindowThreadProcessId ( hWnd , & dwProcessId );
     LPWNDINFO pInfo = ( LPWNDINFO ) lParam ;
    if( dwProcessId == pInfo -> dwProcessId )
    {
         pInfo -> hWnd = hWnd ;
        return FALSE ;
    }
    return TRUE ;
}

HWND GetProcessMainWnd ( DWORD dwProcessId )         // 找到返回进程主窗口的hWnd, 如果没有,返回NULL
{
     WNDINFO wi ;
     wi . dwProcessId = dwProcessId ;
     wi . hWnd = NULL ;
     EnumWindows ( YourEnumProc ,( LPARAM )& wi );
    return wi . hWnd ;
}