选择显示字体大小

给msn messager装个钩子

最近研究怎么样使用hook拦截其他应用程序的消息,于是就动手写了一个钩子程序来挂到最常用的通讯及时通讯工具msn,虽然没有什么实际意义,但作为学习研究却能够帮助我们理解利用hook是怎么样将自己编写的dll注入已经存在的程序空间中的。

我们需要做的是通过我们自己编写的应用程序去拦截别人写好的应用程序消息,实际上这是在两个进程之间进行的,难度就在这里,如果是同一个进程什么都好办,只要将系统响应windows消息的处理函数修改为我们自己编写的函数就可以,但现在不能这么做,因为两个进程有各自的进程地址空间,理论上你没有办法直接去访问别的进程的地址空间,那么怎么办来?办法还是很多的,这里仅仅介绍通过hook来达到目的。

需要拦截别的应用程序的消息,需要利用将自己编写的dll注入到别人的dll地址空间中才可以达到拦截别人消息的目的。只有将我们的dll插入到别的应用程序的地址空间中才能够对别的应用程序进行操作,hook帮助我们完成了这些工作,我们只需要使用hook来拦截指定的消息,并提供必要的处理函数就行了。我们这里介绍拦截在msn聊天对话框上的鼠标消息,对应的hook类型是wh_mouse。

首先我们要建立一个用来hook的dll。这个dll的建立和普通的dll建立没有什么具体的区别,不过我们这里提供的方法有写不同。这里使用隐式导入dll的方法。代码如下:

头文件

#pragma once
#ifndef msnhook_api
#define msnhook_api __declspec(dllimport)
#endif

msnhook_api bool winapi setmsnhook(dword dwthreadid);//安装msn钩子函数
msnhook_api void winapi gettext(int &x,int &y,char ** ptext);//安装msn钩子函数
msnhook_api hwnd winapi getmyhwnd();//安装msn钩子函数

==================================================

dll 的cpp文件

#include "stdafx.h"
#include "msnhook.h"
#include

// 下面几句的含义是告诉编译器将各变量放入它自己的数据共享节中

#pragma data_seg("shared")
hhook g_hhook = null;
dword g_dwthreadidmsn = 0;
point mouseloc={0,0};
char text[256]={0};
hwnd g_hwnd = null;
#pragma data_seg()

//告诉编译器设置共享节的访问方式为:读,写,共享

#pragma comment(linker,"/section:shared,rws")

hinstance g_hinstdll = null;

bool apientry dllmain( handle hmodule,
dword ul_reason_for_call,
lpvoid lpreserved
)
{
switch (ul_reason_for_call)
{
case dll_process_attach:
g_hinstdll = (hinstance)hmodule;
break;
case dll_thread_attach:
case dll_thread_detach:
case dll_process_detach:
break;
}
return true;
}

lresult winapi getmsgproc(int ncode,wparam wparam, lparam lparam);

bool winapi setmsnhook(dword dwthreadid)
{
outputdebugstring("setmsnhook");
bool fok = false;
if(dwthreadid != 0)
{
outputdebugstring("setmsnhook dwthreadid != 0");
g_dwthreadidmsn = getcurrentthreadid();

//安装wm_mouse钩子和处理函数getmsgproc
g_hhook = setwindowshookex(wh_mouse,getmsgproc,g_hinstdll,dwthreadid);
fok = (g_hhook != null);
if(fok)
{
fok = postthreadmessage(dwthreadid,wm_null,0,0);
}
else
{
fok = unhookwindowshookex(g_hhook);
g_hhook = null;
}
}
return(fok);
}

lresult winapi getmsgproc(int ncode,wparam wparam, lparam lparam)
{

char temp[20];
sprintf(temp,"%d\n",ncode);
outputdebugstring("temp");
if (ncode==hc_action)
{
mousehookstruct *l=(mousehookstruct *)lparam;
mouseloc=l->pt; //送鼠标位置

//char text[256] = "";
hwnd hwnd = windowfrompoint(l->pt);
if(hwnd)
{
//getwindowtext(hwnd,text,256);
sendmessage(hwnd,wm_gettext,256,(lparam)(lpctstr)text);
// strcpy(text,"123455555");
sendmessage(hwnd,wm_settext,256,(lparam)(lpctstr)text);
g_hwnd = hwnd;
}
//sendmessage(windowfrompoint(l->pt),wm_gettext,256,(lparam)(lpctstr)psw);
}

return(callnexthookex(g_hhook,ncode,wparam,lparam));
}

void winapi gettext(int &x,int &y,char ** ptext)
{
x = mouseloc.x;
y = mouseloc.y;
*ptext = text;
}

hwnd winapi getmyhwnd()
{
return g_hwnd;
}


上面是处理钩子的dll代码,下面我们要让这个dll起作用还需要一个启动部分,通过这个启动部分我们才能让我们的钩子函数真正的注入到系统其他函数中。我们这里使用个对话框的程序,程序非常简单:一个按钮用来启动钩子,一个用来停止,一个timer用来刷新显示,还有一个editbox用来接受信息。

程序如下:

//包含dll函数导出的头文件
#include "msnhook.h"

//隐式导入

#pragma comment(lib,"msnhook.lib")

//声明导入函数

__declspec(dllimport) bool winapi setmsnhook(dword dwthreadid);
__declspec(dllimport) void winapi gettext(int &x,int &y,char ** ptext);
__declspec(dllimport) hwnd winapi getmyhwnd();//安装msn钩子函数


void ctestmsnhookdlg::onbnclickedok()
{

//通过spy++可以看到msn聊天对话框窗口类是imwindowclass,通过这个得到该窗口句柄
cwnd *pmsnwin = findwindow(text("imwindowclass"),null);
if(pmsnwin == null) return ;

//通过窗口句柄得到对应的线程的id
setmsnhook(getwindowthreadprocessid(pmsnwin->getsafehwnd(),null));
msg msg;
getmessage(&msg,null,0,0);
settimer(101,100,null);

}

void ctestmsnhookdlg::ontimer(uint_ptr nidevent)
{

//刷新消息
char * ptext = null;
int x = 0,y = 0;
gettext(x,y,&ptext);
if(x ==0 && y ==0) return ;
m_edit.format("%d:%d:%s",x,y,ptext);
//m_edit = ptext;
updatedata(false);

hwnd hwnd = getmyhwnd();
cwnd * pwnd = cwnd::fromhandle(hwnd);
pwnd->getwindowtext(m_edit);
cdialog::ontimer(nidevent);
}

void ctestmsnhookdlg::onbnclickedbutton1()
{

//关闭
killtimer(101);
setmsnhook(0);
oncancel();
}


好了,基本上就这些了。这里有个问题,我本想得到msn用户聊天时输入的聊天信息,这里通过wm_gettext消息的不到,如果有知道的朋友告诉一声。

作者blog: http://blog.csdn.net/windcsn/


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons