我用WM_GETMESSAGE的钩子成功注入到一个目标程序当中!现在我想把它的窗口标题给改了.
我在SetWindowsHookEx里的消息处理函数里,用::SetWindowText(TargetWnd,"标题改变了!");
为什么不好使呢??
要怎么样才能把目标进程的窗口文字改变了呢>?
谢谢!
我在SetWindowsHookEx里的消息处理函数里,用::SetWindowText(TargetWnd,"标题改变了!");
为什么不好使呢??
要怎么样才能把目标进程的窗口文字改变了呢>?
谢谢!
以下代码我没有经过编译,应该没有问题至于目标窗口句柄的获得,方法很多。
例如,你可以枚举目标进程中的顶级窗口;或者就在钩子里判断HWND g_hTargetWnd = xxx; // 目标窗口句柄(通过上面说的方法得到)// 钩子函数中
{
MSG* pMsg = (MSG*)lParam; if(pMsg->hwnd == g_hTargetWnd && pMsg->message == WM_SETTEXT)
{
LPCTSTR szTitle = (LPCTSTR)lParam;
if(_tcscmp(szTitle, "你想改成的标题") != 0)
SetWindowText(pMsg->hwnd, "你想改成的标题");
}
}
楼上的正确。我补充一下:楼主的方法之所以不行,是因为不能跨进程直接传递指针(直接的字面字符串实际
上是一个地址,也可以说是一个指针),指针地址在进程内有效的,传递到其他进程(被注入的目标程序)后,是
无效的。需要一种跨进程的数据共享机制来将数据(要设置的窗口标题)传递到目标进程。下面是我模仿《Windows核心编程》中介绍的,使用共享数据节的实现:============= DLL ===========================
#include <windows.h>
#include <tchar.h>#define UM_CHANGE_TITLE (WM_USER + 0x1000)#pragma data_seg("Shared")
HHOOK g_hhook=NULL;
extern "C" __declspec(dllexport) TCHAR g_szTitle[500]={0};
#pragma data_seg()#pragma comment(linker,"/section:Shared,rws")static HINSTANCE g_hDll;BOOL WINAPI DllMain(HINSTANCE hInst,DWORD fdwReason,PVOID fImpLoad)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hDll = hInst;
break;
}
return TRUE;
}static LRESULT WINAPI GetMsgProc(int ncode,WPARAM wParam,LPARAM lParam)
{
MSG* pMsg;
pMsg = (MSG*)lParam;
if (UM_CHANGE_TITLE == pMsg->message)
{
HANDLE hEvent;
HWND hwnd; hwnd = (HWND)(pMsg->wParam);
SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)g_szTitle); hEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,_T("MsgProcessed"));
SetEvent(hEvent);
CloseHandle(hEvent);
}
return CallNextHookEx(g_hhook,ncode,wParam,lParam);
}extern "C" __declspec(dllexport) BOOL WINAPI SetMyHook(DWORD dwThreadId)
{
if (0 != dwThreadId)
g_hhook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,g_hDll,dwThreadId);
else
UnhookWindowsHookEx(g_hhook);
return TRUE;
}=================== 主进程 ===========================
#pragma comment(lib,"MsgHookDll.lib")
extern "C" __declspec(dllimport) BOOL WINAPI SetMyHook(DWORD);
extern "C" __declspec(dllimport) TCHAR g_szTitle[500];
#define UM_CHANGE_TITLE (WM_USER + 0x1000)void CExportSMSDlg::CopyDataFromList()
{
if(NULL == m_hDestWnd) return; DWORD dwThreadId;
HANDLE hEvent; ZeroMemory(g_szTitle,sizeof(g_szTitle));
lstrcpy(g_szTitle,TEXT("通过挂钩设置的窗口标题")); hEvent = CreateEvent(NULL,FALSE,FALSE,"MsgProcessed"); dwThreadId = GetWindowThreadProcessId(m_hDestWnd,NULL);
SetMyHook(dwThreadId);
PostThreadMessage(dwThreadId,UM_CHANGE_TITLE,(WPARAM)m_hDestWnd,0);
WaitForSingleObject(hEvent,INFINITE);
SetMyHook(0);
CloseHandle(hEvent);
}
WM_SETTEXT这个消息应该是最有趣的,它的参数字符串是可以跨过进程的
HWND hWnd = ::FindWindow(NULL, "计算器");
::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)"器算计");以下是MSDN的SetWindowText部分的说明:To set the text of a control in another process, send the WM_SETTEXT message directly instead of calling SetWindowText
刚看了下MSDN,的确是这样的。第一次了解到还有这么有趣的问题呢。