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

ITDeng 2012-03-12 08:36:19
我一开始想用WH_CALLWNDPROC,试了下,不可以用这个,因为这个是在消息发到目标窗口之前的
最后决定用这个WH_CALLWNDPROCRET
MessageBox可以正常显示,SetWindowText就没效果了
dll.def:
LIBRARY HookDll
EXPORTS
SetHook
uHook


dllcpp:
#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:
#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;
}
...全文
246 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
gfm688 2012-03-14
  • 打赏
  • 举报
回复
你可以改用线程钩子吧,线程ID可用GetWindowThreadProcessId得到

这里有一个例子:
http://www.codeproject.com/Articles/5264/Cross-Process-Subclassing
ITDeng 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 kevin_qing 的回复:]

你都注入dll了,直接干掉set的那几个api不就完事
[/Quote]
还木有注入。看了下注入的方法很麻烦,所以就没做。。
ITDeng 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 gfm688 的回复:]

在钩子函数里调用SetWindowLong来子类化是可以的,因为HOOK也是注入dll的一种方法
[/Quote]
全局钩子岂不是很浪费资源呐。。。。
Kevin_qing 2012-03-13
  • 打赏
  • 举报
回复
你都注入dll了,直接干掉set的那几个api不就完事



gfm688 2012-03-13
  • 打赏
  • 举报
回复
在钩子函数里调用SetWindowLong来子类化是可以的,因为HOOK也是注入dll的一种方法
ITDeng 2012-03-13
  • 打赏
  • 举报
回复
The SetWindowLong function fails if the window specified by the hWnd parameter does not belong to the same process as the calling thread.
ITDeng 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 stjay 的回复:]

应该用子类化方式

OldWndProc = GetWindowLong(g_hwnd, GWL_WNDPROC);

SetWindowLong(g_hwnd, GWL_WNDPROC, (LONG)NewWndProc);

LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam……
[/Quote]
OldWndProc = GetWindowLong(g_hwnd, GWL_WNDPROC);
OldWndProc 总是0,看了下MSDN,上面说,调用GetWindowLong(g_hwnd, GWL_WNDPROC)
的线程必须是目标窗口线程或子线程,
这样一来的话还得注入Dll吧?
ITDeng 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 robertbaker 的回复:]

非要动态的改吗?直接改那个程序的字符串不行?
[/Quote]
不单单是这一个程序
LiuYinChina 2012-03-13
  • 打赏
  • 举报
回复
非要动态的改吗?直接改那个程序的字符串不行?
ITDeng 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 stjay 的回复:]

应该用子类化方式

OldWndProc = GetWindowLong(g_hwnd, GWL_WNDPROC);

SetWindowLong(g_hwnd, GWL_WNDPROC, (LONG)NewWndProc);

LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam……
[/Quote]
好主意,我把这个忘记了
stjay 2012-03-12
  • 打赏
  • 举报
回复
应该用子类化方式

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);
}
zgl7903 2012-03-12
  • 打赏
  • 举报
回复
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);
}

只改参数,后续的让它继续
ITDeng 2012-03-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zgl7903 的回复:]

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……
[/Quote]
这样我试过了,不行的。
zgl7903 2012-03-12
  • 打赏
  • 举报
回复
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";
ITDeng 2012-03-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 itdeng 的回复:]

引用 3 楼 zgl7903 的回复:

应该是用WH_CALLWNDPROC更合适, 劫持消息,并替换参数,后续的任然按正常的流程走

这个是用SPY++追踪的SetWindowText(hwnd, _T("TestAA"))的消息记录
<00711> 00190798 S WM_SETTEXT lpsz:0012FA28 ("Test")
<00712> 00190798 S m……
[/Quote]
WH_CALLWNDPROC好像不能修改参数的
ITDeng 2012-03-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zgl7903 的回复:]

应该是用WH_CALLWNDPROC更合适, 劫持消息,并替换参数,后续的任然按正常的流程走

这个是用SPY++追踪的SetWindowText(hwnd, _T("TestAA"))的消息记录
<00711> 00190798 S WM_SETTEXT lpsz:0012FA28 ("Test")
<00712> 00190798 S message:0x00AE [未知] wPar……
[/Quote]
我试了很多遍,不行的额,麻烦你建个工程试试吧
zgl7903 2012-03-12
  • 打赏
  • 举报
回复
应该是用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外 还执行力一些未公开的消息操作,如果是返回后处理,可能有些内部的操作处理不了
ITDeng 2012-03-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gfm688 的回复:]

SetWindowText也会发WM_SETTEXT消息
在WM_SETTEXT里SetWindowText岂不成死循环了吗?
应该修改WM_SETTEXT的lParam吧
[/Quote]
这我也想到了。但是不知道如何解决- -
gfm688 2012-03-12
  • 打赏
  • 举报
回复
SetWindowText也会发WM_SETTEXT消息
在WM_SETTEXT里SetWindowText岂不成死循环了吗?
应该修改WM_SETTEXT的lParam吧

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧