問:
在cmd.exe下運(yùn)行rundll32.exe mydll.dll,MyFunc ,本想直接在當(dāng)前cmd窗口輸出調(diào)試信息.
可因rundll32是Win32 GUI程序而非Win32 console,所以cmd.exe標(biāo)準(zhǔn)輸入輸出句柄無法被mydll.dll繼承用來向父進(jìn)程cmd.exe輸出數(shù)據(jù).
這時(shí), 如果用強(qiáng)行用GetStdHandle獲得句柄,然后用WriteConsole來進(jìn)行輸出,則會發(fā)生無效句柄錯(cuò)誤.
但是如果在這之前先AllocConsole,則可正常WriteConsole,但是會新建個(gè)控制臺窗口來輸出數(shù)據(jù),很不爽 :-P
有沒有什么辦法向當(dāng)前cmd.exe窗口輸出數(shù)據(jù)呢?
我想通過給進(jìn)程拍照和遍歷,
可以獲得rundll32的父進(jìn)程cmd.exe的PID和Handle,但如何進(jìn)一步下去(建立管道, 寫數(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
)????????
//找到返回父進(jìn)程PID, 找不到返回-1
{ ????
PROCESSENTRY32?????pr32
= {
0
}; ????
pr32
.
dwSize
=
sizeof
(
PROCESSENTRY32
);???
// 不要漏了這句
????// 提權(quán)先 ????
DebugPrivilege
(
SE_DEBUG_NAME
,
TRUE
);???? ????
// 給進(jìn)程照相 ????
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
)?? ????????{????????????
// 如果被枚舉到的進(jìn)程ID等于所給的ID, 則返回父進(jìn)程ID ????????????
CloseHandle
(
hSnap
); ????????????return
pr32
.
th32ParentProcessID
; ????????} ????} ????while(
Process32Next
(
hSnap
, &
pr32
));
????
// 找不到父進(jìn)程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
)????????
// 找到返回進(jìn)程主窗口的hWnd, 如果沒有,返回NULL
{ ????
WNDINFO wi
; ????
wi
.
dwProcessId
=
dwProcessId
; ????
wi
.
hWnd
=
NULL
; ????
EnumWindows
(
YourEnumProc
,(
LPARAM
)&
wi
); ????return
wi
.
hWnd
; }
|
?