接着上一篇,说到qq屏蔽了wm_gettext消息,所以常规的sendmessage方法就失效了,那我们是不是束手无策呢了,答案是否定的,文章结尾我说了可以用dll进程注入加窗口子类化来实现输入框内容的获取,我自己试验了下,结果是肯定的,下面我来说下实现的步骤.
首先用窗口探测工具探测qq的消息输入窗口,我这里探测到窗口的句柄是198862,类名是RichEdit20A(这个很重要,类名错了,子类化时qq会崩溃),然后打开vc,新建一个dll工程,输入下面代码:
// qqinject.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "windows.h"
DWORD old;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call){
case DLL_PROCESS_ATTACH:
HWND hedit=::CreateWindow("RichEdit20A","",WS_VISIBLE|WS_CHILDWINDOW,10,30,40,50,::FindWindow("#32770","与 ###### 交谈中"),0,::GetModuleHandle(0),0);
DWORD win=::GetWindowLong(hedit,GWL_WNDPROC);
old=::SetWindowLong(HWND(198862),GWL_WNDPROC,(long)win);
char text[100]={0};
::SendMessage(HWND(198862),WM_GETTEXT,100,(long)text);
::MessageBox(0,text,"a",0);
::SetWindowLong(HWND(198862),GWL_WNDPROC,old);
}
return TRUE;
}
代码大致意思是当dll被加载时在qq聊天窗口上创建一个类名为RichEdit20A的窗口(放心,你看不见这个窗口的),然后对qq的消息输入框进行子类处理,然后发送wm_gettext消息,获取输入框文本内容,最后还原窗口处理函数地址.dll的进程注入部分我在这里就不多说,可以看下我前面的文章,都是老套路.然后开始写dll加载部分,打开vb(当然也能用vc),至于用vb,是因为在dll调用上感觉方便.输入下面代码(和前一篇类似):
Private Declare Sub inject Lib "D:/ject/sx1/Debug/sx1.dll" (ByVal name As String, ByVal process As String)
Private Sub Form_Load()
Dim a As String
a = "D:/ject/qqinject/Release/qqinject.dll"
inject a, "QQ.exe"
End Sub
意思我就不重复了,前面文章有,inject就是将a这个字符串里的dll注入到qq.exe中,inject是我自己写的包含在dll中的导出函数.
好了,往前面那qq聊天窗口(也就是"与 ##### 交谈中")的消息输入框里随便写点字,开始点vb启动吧(注意,前面那探测的窗qq口不能关).
好了,弹出一对话框,是不是就是qq消息输入框的内容啊,呵呵.
我只是做了个大概雏形,没有完善,而且本文讨论的只是纯技术,不做其他用途.切勿用于非法用途.本人才疏学浅,文章有错误遗漏之出还望高手见笑.
以上代码在vc++6.0,vb6.0,windows xp,qq2008beta2中测试通过.
如有疏忽与疑问,还请多指正与交流.