求高人解决HOOK问题——使某个窗口的标题永远为为"XXX"
我一开始想用WH_CALLWNDPROC,试了下,不可以用这个,因为这个是在消息发到目标窗口之前的
最后决定用这个WH_CALLWNDPROCRET
MessageBox可以正常显示,SetWindowText就没效果了
dll.def:
LIBRARY HookDllEXPORTSSetHookuHook
#include <windows.h>#pragma data_seg("SetWindowTextHookEx")HWND g_hwnd = 0;char *g_title = 0;HHOOK hhgm = 0;#pragma data_seg()#pragma comment(linker,"/section:SetWindowTextHookEx,RWS")BOOL SetText();LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam){ CWPRETSTRUCT *cs = (CWPRETSTRUCT *)lParam; if(code==HC_ACTION) { if(cs->hwnd == g_hwnd) { if(cs->message == WM_SETTEXT) { //MessageBox(0,0,0,0); //SendMessage(g_hwnd,WM_SETTEXT,0,(LPARAM)g_title); SetText(); } } }else if(code<0) { return CallNextHookEx(hhgm,code,wParam,lParam); } return 0;}bool SetHook(HWND hwnd,char *title){ hhgm = SetWindowsHookEx(WH_CALLWNDPROCRET,CallWndProc,GetModuleHandle("HookDll"),NULL); if(hhgm) { g_hwnd = hwnd; g_title = title; return true; }else { return false; }}BOOL uHook(){ return UnhookWindowsHookEx(hhgm);}BOOL SetText(){ MessageBox(g_hwnd,"NOW",0,0); return SetWindowText(g_hwnd,g_title);}#include <Windows.h>#pragma comment(lib,"HookDll.lib")_declspec(dllimport) bool SetHook(HWND hwnd,char *title);_declspec(dllimport) BOOL uHook();LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);HWND hwnd,hb;int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrveInstance, LPSTR lpCmdLine, int nCmdShow){ WNDCLASSEX wcex; wcex.cbClsExtra=0; wcex.cbSize=sizeof(WNDCLASSEX); wcex.cbWndExtra=0; wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); wcex.hCursor=LoadCursor(NULL,IDC_ARROW); wcex.hIcon=LoadIcon(NULL,IDI_APPLICATION); wcex.hIconSm=LoadIcon(NULL,IDI_APPLICATION); wcex.hInstance=hInstance; wcex.lpfnWndProc=WndProc; wcex.lpszClassName="ClassName"; wcex.lpszMenuName=NULL; wcex.style=CS_HREDRAW|CS_VREDRAW; RegisterClassEx(&wcex); //hi = hInstance; hwnd=CreateWindow(wcex.lpszClassName,"Title",WS_OVERLAPPEDWINDOW+WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,350,250,NULL,NULL,hInstance,NULL); hb=CreateWindow("Button","Title",WS_CHILDWINDOW+WS_VISIBLE,0,0,100,50,hwnd,NULL,hInstance,NULL); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam;}LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){ switch(message) { case WM_CREATE: break; case WM_COMMAND: if((HWND)lParam==hb) { //SendMessage(hWnd,WM_SETTEXT,99,(LPARAM)"agsagas"); bool result = SetHook((HWND)3278740,"想修改?没门!"); if(result) { MessageBox(hWnd,"chenggong",0,0); }else { MessageBox(0,"shibai",0,0); } } break; case WM_DESTROY: uHook(); PostQuitMessage(0); break; default: return DefWindowProc(hWnd,message,wParam,lParam); break; } return 0;}
在WM_SETTEXT里SetWindowText岂不成死循环了吗?
应该修改WM_SETTEXT的lParam吧
[解决办法]
应该是用WH_CALLWNDPROC更合适, 劫持消息,并替换参数,后续的任然按正常的流程走
这个是用SPY++追踪的SetWindowText(hwnd, _T("TestAA"))的消息记录
<00711> 00190798 S WM_SETTEXT lpsz:0012FA28 ("Test")
<00712> 00190798 S message:0x00AE [未知] wParam:00000009 lParam:00000000
<00713> 00190798 R message:0x00AE [未知] lResult:00000000
<00714> 00190798 R WM_SETTEXT fSucceeded:True
它除了WM_SETTEXT外 还执行力一些未公开的消息操作,如果是返回后处理,可能有些内部的操作处理不了
[解决办法]
CallWndProc( int nCode, WPARAM wParam, LPARAM lParam);
lParam
[in] Pointer to a CWPSTRUCT structure that contains details about the message.
CWPRETSTRUCT *cs = (CWPRETSTRUCT *)lParam;
if(cs->message == WM_SETTEXT)
{
cs->lParam = (LPARAM)L"TESTaaa";
[解决办法]
LRESULT CALLBACK CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{
CWPRETSTRUCT *cs = (CWPRETSTRUCT *)lParam;
if(code==HC_ACTION)
{
if(cs->message == WM_SETTEXT)
{
cs->lParam = (LPARAM)L"Test";
}
}
return CallNextHookEx(hhgm,code,wParam,lParam);
}
只改参数,后续的让它继续
[解决办法]
应该用子类化方式
OldWndProc = GetWindowLong(g_hwnd, GWL_WNDPROC);
SetWindowLong(g_hwnd, GWL_WNDPROC, (LONG)NewWndProc);
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_SETTEXT)
{
lParam = g_title;
}
return CallWindowProc(OldWndProc, hwnd, uMsg, wParam, lParam);
}
[解决办法]
非要动态的改吗?直接改那个程序的字符串不行?
[解决办法]
在钩子函数里调用SetWindowLong来子类化是可以的,因为HOOK也是注入dll的一种方法
[解决办法]
你都注入dll了,直接干掉set的那几个api不就完事
[解决办法]
你可以改用线程钩子吧,线程ID可用GetWindowThreadProcessId得到
这里有一个例子:
http://www.codeproject.com/Articles/5264/Cross-Process-Subclassing