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

DLL注入,如果更改被注入进程的窗口标题呢?解决方案

2012-01-11 
DLL注入,如果更改被注入进程的窗口标题呢?我用WM_GETMESSAGE的钩子成功注入到一个目标程序当中!现在我想把

DLL注入,如果更改被注入进程的窗口标题呢?
我用WM_GETMESSAGE的钩子成功注入到一个目标程序当中!

现在我想把它的窗口标题给改了.
我在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这个消息应该是最有趣的,它的参数字符串是可以跨过进程的

C/C++ code

    HWND hWnd = ::FindWindow(NULL, "计算器");    ::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)"器算计");
[解决办法]

刚看了下MSDN,的确是这样的。第一次了解到还有这么有趣的问题呢。
[解决办法]
使用sendmessage发送消息即可

热点排行