問:

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

?