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