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