問:
在cmd.exe下運行rundll32.exe mydll.dll,MyFunc ,本想直接在當前cmd窗口輸出調試信息.
可因rundll32是Win32 GUI程序而非Win32 console,所以cmd.exe標準輸入輸出句柄無法被mydll.dll繼承用來向父進程cmd.exe輸出數(shù)據(jù).
這時, 如果用強行用GetStdHandle獲得句柄,然后用WriteConsole來進行輸出,則會發(fā)生無效句柄錯誤.
但是如果在這之前先AllocConsole,則可正常WriteConsole,但是會新建個控制臺窗口來輸出數(shù)據(jù),很不爽 :-P
有沒有什么辦法向當前cmd.exe窗口輸出數(shù)據(jù)呢?
我想通過給進程拍照和遍歷,
可以獲得rundll32的父進程cmd.exe的PID和Handle,但如何進一步下去(建立管道, 寫數(shù)據(jù))就沒轍了?
不知道有沒有描述清楚 還是太羅嗦了,麻煩大家看看,謝謝~
?
答:
如果只是要輸出數(shù)據(jù)的話 可以向父窗口 發(fā)送鍵盤消息 WM_CHAR 輸出你的數(shù)據(jù)
?
?
代碼
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
;
}
?