问:

在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
;
}