首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

求高人解决HOOK有关问题——使某个窗口的标题永远为为"XXX"

2012-05-07 
求高人解决HOOK问题——使某个窗口的标题永远为为XXX我一开始想用WH_CALLWNDPROC,试了下,不可以用这个,因

求高人解决HOOK问题——使某个窗口的标题永远为为"XXX"
我一开始想用WH_CALLWNDPROC,试了下,不可以用这个,因为这个是在消息发到目标窗口之前的
最后决定用这个WH_CALLWNDPROCRET
MessageBox可以正常显示,SetWindowText就没效果了
dll.def:

C/C++ code
LIBRARY HookDllEXPORTSSetHookuHook


dllcpp:
C/C++ code
#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);}


execpp:
C/C++ code
#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;}


[解决办法]
SetWindowText也会发WM_SETTEXT消息


在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

热点排行