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