一种获取无窗口RichEdit控件文本内容的方法及其设备的制作方法

文档序号:7747626阅读:1272来源:国知局
专利名称:一种获取无窗口RichEdit控件文本内容的方法及其设备的制作方法
技术领域
本发明涉及互联网技术,尤其涉及即时通信软件。
背景技术
近来,通过即时通信软件(如QQ、MSN、Skype)的聊天行为导致的泄密事件日益增 多,因此需要在某些场合对即时通信软件的聊天内容进行监控。但是主流的即时通信软件 都对通信内容进行了加密,若通过对网络层数据包解密的方式获取聊天内容则需要算法密 钥,而算法密钥的获取又非常困难,因此需要寻找新的技术方法。对于即时通信软件,用户在使用它们进行聊天过程中,都会将聊天信息显示在聊 天窗口上。同时如QQ2009、MSN、Skype等主流即时通信软件都使用“无窗口类型的RichEdit 控件”来显示聊天内容信息。RichEdit控件是一个可用于输入、编辑、格式化、打印和保存文本的窗体。这些文 本可以设置字符和段落格式,并且可以包含嵌入的COM对象。由于RichEdit能显示丰富多 样的文本、图片,所以大多数即时聊天软件,如QQ、MSN等都使用RichEdit控件来作为聊天 内容的显示窗口。无窗口类型的RichEdit控件使用RichEdit模块提供的COM接口来创建对象实 例,并通过这些COM接口来访问其属性和方法,此时RichEdit控件不是一个子窗口,也没有 句柄,所以无法直接通过Windows系统的消息机制进行访问。

发明内容
本发明提供了一种能解决以上问题的获取无窗口 RichEdit控件文本内容的方法 及其设备。在第一方面,本发明提供了一种获取无窗口 RichEdit控件文本内容的方法。该方 法包括步骤a,安装消息钩子,以便监控窗口事件。步骤b,在监控窗口事件过程中,修改该聊天软件中RichEdit模块的创建文本服 务对象函数的入口地址,使其跳转到用于获取文本服务对象接口指针的H00K函数中。步骤c,调用该H00K函数,以获取所述文本服务对象的接口指针。步骤d,根据所述文本服务对象的接口指针访问RichEdit控件,从而获得所述无 窗口 RichEdit控件文本内容。在第二方面,本发明提供了一种获取无窗口 RichEdit控件文本内容的设备。该设 备包括安装消息钩子,以便监控窗口事件的模块。在监控窗口事件过程中,修改聊天软件中RichEdit模块的创建文本服务对象函 数的入口地址,使其跳转到用于获取文本服务对象接口指针的H00K函数中的模块。调用该H00K函数,以获取所述文本服务对象接口指针的模块。
4
根据该文本服务对象接口访问RichEdit控件以获得该无窗口 RichEdit控件文本 内容的模块。在本发明的一个实施例中,该获取无窗口 RichEdit控件文本内容的方法包括步骤h,系统强制加载DLL模块。步骤e,检测目标进程中是否已经加载DLL模块。步骤f,如果尚未加载DLL模块则系统强制加载DLL模块,再执行步骤g,如果已经 加载了 DLL模块则直接执行步骤g。步骤g,检测目标进程是否属于感兴趣进程,如果不是感兴趣进程则将该加载的 DLL模块退出,如果是感兴趣进程则继续执行所述步骤b。
在本发明的另一个实施例中,所述Ri chEd i t控件处理的消息包括用于获取该 RichEdit控件文本行数的EM_GETLINECOUNT消息,用于得到行开头字符索引值的EM_ LINEINDEX消息,用于得到行长度的EM_LINELENGTH消息,用于获取指定范围文本内容的 EM_GETTEXTRANGE 消息。在本发明的又一个实施例中,所述安装消息钩子包括安装CBT消息钩子、安装鼠 标消息钩子和安装键盘消息钩子,从而实时监控窗口事件。本发明通过API HOOK技术获取“无窗口类型RichEdit控件”的访问接口,进而获 取即时聊天软件显示的聊天内容,从而实现了对即时聊天软件聊天信息的监控。本发明方 法解决了需要通过算法密钥对网络层数据包的协议解析来实现对聊天信息进行监控的技 术难题。


下面将参照附图对本发明的具体实施方案进行更详细的说明,在附图中图1是本发明一个实施例的基于API HOOK技术跨进程获取聊天内容的流程图。
具体实施例方式APKApplication Programming Interface,应用程序编程接口)是一预先定义的 函数,目的是提供给开发人员应用程序,使其无需访问源码或理解内部工作机制。Η00Κ是Windows中提供的一种用以替换DOS下“中断”的系统机制,中文译为“挂 钩”或“钩子”。在对特定的系统事件进行Η00Κ后,一旦发生已Η00Κ事件,则对该事件进行 Η00Κ的程序就会受到系统的通知,这时程序就能在第一时间对该事件做出响应。API Η00Κ 技术是一种用于改变API执行结果的技术。以下将详细阐述如何通过API Η00Κ技术获取 无窗口 RichEdit控件文本内容。图1是本发明一个实施例的基于API Η00Κ技术跨进程获取聊天内容的流程图。在步骤110,在本地计算机中安装消息钩子,以便监控该本地计算机的窗口事件, 如监控窗口的创建、移动、销毁、改变大小等。一个例子中,该消息钩子为CBT消息钩子。较 佳地,该消息钩子为鼠标钩子、键盘钩子和CBT消息钩子。在本发明的一个实施例中,安装CBT消息钩子的代码为H安装CBT钩子if (glhCbtHook = = NULL)
{glhCbtHook = SetffindowsHookEx(WH_CBT, CbtProc, glhlnstance,0);if (glhCbtHook){MyOutputDebugString(" Setup CBT Hook Success !〃 );}else{char szErr[64] = {0};iErrCode = GetLastError ();sprintf (szErr, “ Setup CBT Hook Failed ! -% d" , iErrCode);MyOutputDebugString (szErr);bHook = FALSE ;}}return bHook ;}在步骤120,系统(如windows操作系统)检测进程中是否已经加载了 DLL模块,
如果已经加载了 DLL模块,则执行步骤130 ;如果尚未加载DLL模块,则执行步骤121。在步骤121,系统强制加载DLL模块,而后执行步骤130。在步骤130,由于步骤110已经安装了消息钩子,因此在监控窗口事件过程中,检 测当前目标进程是否属于感兴趣的进程(举例如,打开word窗口不是感兴趣进程,打开MSN 聊天窗口是感兴趣进程),如果不是感兴趣进程则执行步骤131,如果是感兴趣进程则执行 步骤140。在步骤131,将注入的DLL模块退出。在步骤140,进行HOOK API操作,将即时通信软件中RichEdit模块的创建文本服 务对象函数的入口地址头几个字节的内容,修改为跳转到H00K函数地址的指令。在本发明的一个实施例中,步骤140为,将RichEd20.dll模块 的CreateTextServices函数入口地址头几个字节的内容,修改为跳转到 CreateTextServices_H00K 函数地址的指令。在本发明的一个实施例中,HOOP API处理过程代码为BYTE g_btNewBytes[8] = {0xB8,0x0,0x0,0x40,0x0,OxFF,0xE0,0x0};BOOL SetupAPIHookO{HMODULE hModule = NULL ;hModule = GetModuleHandle(" RICHED20.DLL");if (hModule){//获取API地址
IpCreateTxServProcAddr = (DWORD)GetProcAddress(hModule,〃 CreateTex tServices");if(IpCreateTxServProcAddr = = NULL){MyOutputDebugString (〃 获取 CreateTextServices 函数地址失败!‘‘);return FALSE ;}Il保存原始字节数据if (ReadProcessMemory (INVALID,HANDLE_VALUE, (VOID*) IpCreateTxServProcAddr,(void*)g_dw01dBytes
,sizeof (DWORD)*2,NULL) == FALSE){MyOutputDebugString(〃读取本地进程内存数据失败!“);return FALSE ;}//将00400000改写为Η00Κ函数的地址*(DWORD*)(g_btNewBytes+l) = (DWORD)CreateTextServices_Hook ;H改写API入口地址后面几个字节的内容if(WriteProcessMemory(INVALID_HANDLE_VALUE,(VOID*)IpCreateTxServProcAddr,(void*)g_btNewBytes,sizeof (DWORD) *2,NULL) = = FALSE){MyOutputDebugString(〃改写本地进程内存数据失败!“);return FALSE ;}}return TRUE ;}在步骤150,若即时通信软件中的目标进程调用创建文本服务对象函数,则跳转到 Η00Κ函数中,以便获取文本服务对象的接口指针。在本发明的一个实施例中,步骤150为,在目标进程调用CreateTextServices函 数时,跳转到CreateTextServices_H00K函数中,以便获取ITextServices接口指针。下面以创建文本服务对象函数为CreateTextServices函数,文本服务对象接口 指针为ITextServices接口指针,Η00Κ函数为CreateTextServices_H00K函数为例,阐述 该Η00Κ函数的功能。该的Η00Κ函数功能为,先恢复CreateTextServices函数入口地址的头几个字节 数据,以便调用CreateTextServices函数。然后根据该CreateTextServices函数的传入参 数 IUnknown*punk0uter、ITextHost*pITextHost 获取指向 IUnknown 对象指针的指针(该CreateTextServices 函数的传出参数 IUnknown氺氺ppUnk),并i亥 CreateTextSercices 的 返回值作为CreateTextServices_HOOK函数的返回值。再通过该指向IUnknown对象指针的 指针查询ITextServices接口指针,在获得该ITextServices接口指针后,将该接口指针保 存起来,以便用于将来访问RichEdit控件。然后再继续将CreateTextServices函数入口 地址的头几个字节内容改写成跳转到CreateTextServices_HOOK函数入口地址的指令,以 保证下一次CreateTextServices函数被调用时,先进入CreateTextServices_HOOK函数。 最后CreateTextServices_HOOK函数返回,返回值为内部调用CreateTextServices函数的 返回值。在本发明的一个实施例中,CreateTextServices_HOOK函数的代码为HRESULT WINAPI CreateTextServices_Hook (IUnknown*punkOuter, ITextHost^pITextHost, IUnknown氺氺ppUnk){int i = O ;char szInfo[64] = {0};ITextServices氺IpTxServ = NULL ;//进入临界区EnterCriticalSection(&csHookApi);//恢复API头8个字节if (WriteProcessMemory (INVALID_HANDLE_VALUE, (VOID*) IpCreateTxServProcAddr, (void*)g_dw01dBytes
, sizeof(DWORD)NULL)== FALSE){MyOutputDebugString (〃 恢复 API 头 8 个字节失败〃);}//执行真实的APIHRESULT hResult = CreateTextServices (punkOuter, pITextHost, ppUnk);if (hRe suit== S_0K){//获取 ITextServices 接 口指针((IUnknown*)(*ppUnk))- > QueryInterface(IID_ITextServices, (void**)(&IpTxServ));if (IpTxServ){//保存接口指针}else{MyOutputDebugString(〃 获取IID_ITextServices 接口失败!“);}[Ol24]}
//继续HOOK[Ol26]i f(Wr i t e P r o c e s s M e mo r Y(工NVA L工D HAND LE VA LUE,(V 0工D*)工pCreateTXSerVPr。CAddr, (void*)g_btNewBytes,sizeof(DWORD)*2,NULL) 一一FALSE)[Ol 27]{
My。utputDebugString(”改写本地进程内存数据失败!”);[Ol29]}
LeaveCriticalSection(&csHookApi)[Ol32]return hResult;[Ol33] 在步骤160,根据文本服务对象接口提供的方法来访问RichEdit控件,以获取RichEdit控件的文本内容,从而得到聊天内容。一个例子中,根据I/extServices接口提供的方法来访问RichEdit控件。[Ol 34] 在本发明的一个实施例中,在RichEdit控件接收并处理的消息中包括EM—GETLINECOUNT消息、EM—LINEINDEX消息、EM—LINELENGTH消息、EM—GETTEXTRANGE消息,其用于获取RichEdit控件文本内容。
EM—GETLINECOUNT消息用于获取RichEdit控件文本的行数,EM—LINEINDEX消息用于得到行开头字符的索引值,EM—LINELENGTH消息用于得到行长度,EM—GETTEXTRANGE消息用于获取指定范围的文本内容。
具体获取RichEdit控件文本内容的处理方法为先获取RichEdit控件当前的文本行数,再与原记录的行数进行比较,如果没有变化则不进行任何处理;如果当前行数大于原行数,则以原行数作为循环起点,新行数作为循环结束点,开始循环。在循环体中,以当前行数值作为索引,先获取当前行首字符的偏移值并将其作为区段起始值,然后获取当前行的长度,并将其作为区段结束值。然后获取当前行设定的区段文本内容,并进行处理。再继续获取下一行的内容,直到所有新增行的内容都获取完为止。[Ol37] 在本发明的一个实施例中,获取RichEdit控件文本内容的代码为[Ol38]VOID GetReC。dePr。C(IN/iTalkwind。W工ndeX)[Ol39] {
IN/iLine一0
] IN/iLineCount一0
IN/iCharNum一0[Ol43]IN/iLineLength一0[Ol44]LRESUL/IResult一0[Ol45]/EX/1L4NGE/extRange;[Ol46] CHARszMsg/emp[MAXL工NEBUFLENGTH*2+1]一{0};[Ol47]WCHARwszMsg/emp[MAXL工NEBUFLENGTH+1]一{0};[Ol48]//获取RichEdit控件当前行数
hResult 一 ((I/extServices*)Talkwind。W工nf。[iTalkwind。W工ndeX].pITeXtSerViCe)一>TXSendMeSSage(EM—GETLINECOUNT,0,0,&iLineCount);
if (hResult ! = S_0K)return ;
H判断是否大于已获取的行数if (iLineCount > TalkffindowInfo[iTalkffindowIndex]. iPos){// 初始化 TextRange 结构memset(&TextRange,0, sizeof(TEXTRANGE));TextRange. IpstrText = (char*)wszMsgTemp ;//保存新行数iLine = TalkWindowInfo[iTalkWindowIndex]. iPos ;TalkWindowInfo[iTalkWindowIndex]. iPos = iLineCount ;Il循环获取新增的行内容for ( ;iLine < = iLineCount ; iLine++){//初始化内容缓冲memset(szMsgTemp,0,sizeof (CHAR)*MAXLINEBUFLENGTH*2);memset(wszMsgTemp,O, sizeof (WCHAR)*MAXLINEBUFLENGTH);//获取行内容//取得行开头字符的索引,作为选择起始点。((ITextServices氺)TalkffindowInfo[iTalkWindowIndex]. pITextService)- > TxSendMessage (EM_LINEINDEX, iLine, O, &(TextRifflge· chrg. cpMin));//得到行的长度,作为选择结尾偏移量((ITextServices氺)TalkffindowInfo[iTalkWindowIndex]. pITextService)- > TxSendMessage(EM_LINELENGTH, TextRange. chrg. cpMin,O, &iLineLength);iLineLength = iLineLength > MAXLINEBUFLENGTH ? MAXLINEBUFLENGTH iLineLength ;TextRange. chrg. cpMax = TextRange. chrg. cpMin+iLineLength ;//获取选择的内容((ITextServices氺)TalkffindowInfo[iTalkWindowIndex]. pITextService)- > TxSendMessage(EM_GETTEXTRANGE, O, (LPARAM)&TextRange,&iCharNum);//有实际内容才进行处理if (iCharNum > 0){//处理消息内容ProcMsgContentBuf ();}} //for}//if}
需要说明的是,以上仅以windows系统为例,阐述如何通过HOOK API方式获取 无窗口 RichEdit控件文本内容,进而获得即时通信软件中的聊天内容。实际上,本发明 不限于以上所述windows环境,更不限于H00K以上所述函数,也就是说,不管系统环境如 何变化,无论函数名称如何改变,只要是通过安装消息钩子及HOOK API方式获取无窗口 RichEdit控件文本内容,就都在本发明保护范围之内。显而易见,在不偏离本发明的真实精神和范围的前提下,在此描述的本发明可以 有许多变化。因此,所有对于本领域技术人员来说显而易见的改变,都应包括在本权利要求 书所涵盖的范围之内。本发明所要求保护的范围仅由所述的权利要求书进行限定。
权利要求
一种获取无窗口RichEdit控件文本内容的方法,其特征在于,包括步骤a,安装消息钩子,以便监控窗口事件;步骤b,在监控窗口事件过程中,修改该聊天软件中RichEdit模块的创建文本服务对象函数的入口地址,使其跳转到用于获取文本服务对象接口指针的HOOK函数中;步骤c,调用该HOOK函数,以获取所述文本服务对象的接口指针;步骤d,根据所述文本服务对象的接口指针访问RichEdit控件,从而获得所述无窗口RichEdit控件文本内容。
2.如权利要求1所述的一种获取无窗口RichEdit控件文本内容的方法,其特征在于, 在所述步骤a之后,步骤b之前包括步骤h,系统强制加载DLL模块;步骤e,检测目标进程中是否已经加载DLL模块;步骤f,如果尚未加载DLL模块则系统强制加载DLL模块,再执行步骤g ;如果已经加载 了 DLL模块则直接执行步骤g;步骤g,检测目标进程是否属于感兴趣进程,如果不是感兴趣进程则将该加载的DLL模 块退出,如果是感兴趣进程则继续执行所述步骤b。
3.如权利要求1所述的一种获取无窗口RichEdit控件文本内容的方法,其特征在于, 所述创建文本服务对象的函数为CreateTextServices函数,所述文本服务对象的接口指 针为ITextServices接口指针。
4.如权利要求3所述的一种获取无窗口RichEdit控件文本内容的方法,其特征在于, 所述H00K函数功能为先恢复所述CreateTextServices函数入口地址,以便调用该CreateTextServices函数;然后通过调用该CreateTextServices函数得到所述ITextServices的接口指针; 再将CreateTextServices函数入口地址改写成跳转到该H00K函数入口地址的指令; 最后将该H00K函数返回,其返回值为内部调用CreateTextServices函数的返回值。
5.如权利要求4所述的一种获取无窗口RichEdit控件文本内容的方法,其特征在于, 所述H00K函数包括传入参数IUnknown*punkOuter、ITextHost*pITextHost,以及传出参数 IUnknown**ppUnk ;该H00K函数通过该输入参数得到该输出参数,并通过该传出参数得到所述 ITextServices 接口指针。
6.如权利要求1所述的一种获取无窗口RichEdit控件文本内容的方法,其特征在于, 所述RichEdit控件处理的消息包括以下消息中的一个或多个用于获取该RichEdit控件文本行数的EM_GETLINECOUNT消息; 用于得到行开头字符索引值的EM_LINEINDEX消息; 用于得到行长度的EM_LINELENGTH消息;以及 用于获取指定范围文本内容的EM_GETTEXTRANGE消息。
7.如权利要求6所述的一种获取无窗口RichEdit控件文本内容的方法,其特征在于, 所述步骤d包括获取所述RichEdit控件当前的文本行数,并与原记录的行数进行比较,如果没有变化则不进行任何处理;如果当前行数大于原行数,则以原行数作为循环起点,新行数作为循环结束点,开始循环;在该循环体中,以当前行数值作为索引,先获取当前行首字符的偏移值,并将其作为区 段起始值,然后获取当前行的长度,并将其作为区段结束值,再获取当前行设定的区段文本 内容,并进行处理;继续获取下一行内容,直到所有新增行的内容都获取完为止。
8.如权利要求1所述的一种获取无窗口RichEdit控件文本内容的方法,其特征在于, 所述安装消息钩子包括安装CBT消息钩子、安装鼠标消息钩子和安装键盘消息钩子,从而 实时监控窗口事件。
9.一种获取无窗口 RichEdit控件文本内容的设备,其特征在于,包括 安装消息钩子,以便监控窗口事件的模块;在监控窗口事件过程中,修改聊天软件中RichEdit模块的创建文本服务对象函数的 入口地址,使其跳转到用于获取文本服务对象接口指针的H00K函数中的模块; 调用该H00K函数,以获取所述文本服务对象接口指针的模块;以及 根据该文本服务对象的接口指针访问RichEdit控件获得所述无窗口 RichEdit控件文 本内容的模块。
10.如权利要求9所述的一种获取无窗口RichEdit控件文本内容的设备,其特征在于, 所述创建文本服务对象的函数为CreateTextServices函数,所述文本服务对象的接口指 针为ITextServices接口指针。
11.如权利要求10所述的一种获取无窗口RichEdit控件文本内容的设备,其特征在 于,所H00K函数功能为恢复所述CreateTextServices函数入口地址以调用CreateTextServices函数的模块;通过调用该CreateTextServices函数得到所述ITextServices接口指针的模块; 将CreateTextServices函数入口地址改写成跳转到该H00K函数入口地址指令的模 块;以及将该H00K函数返回,并将其返回值作为内部调用CreateTextServices函数返回值的 模块。
12.如权利要求9所述的一种获取无窗口RichEdit控件文本内容的设备,其特征在于, 所述RichEdit控件处理的消息包括以下消息中的一个或多个用于获取该RichEdit控件文本行数的EM_GETLINECOUNT消息; 用于得到行开头字符索引值的EM_LINEINDEX消息; 用于得到行长度的EM_LINELENGTH消息;以及 用于获取指定范围文本内容的EM_GETTEXTRANGE消息。
全文摘要
本发明涉及一种获取无窗口RichEdit控件文本内容的方法及其设备。本发明首先安装消息钩子,以便监控窗口事件。在监控窗口事件过程中,修改该聊天软件中RichEdit模块的创建文本服务对象函数的入口地址。然后调用该HOOK函数,以获取该文本服务对象的接口指针。最后根据该文本服务对象接口访问RichEdit控件。本发明解决了需要通过算法密钥对网络层协议解析,以实现对聊天信息进行监控而带来的技术难题。因此本发明方法能够应用于监控使用即时聊天软件的聊天内容。
文档编号H04L12/58GK101834807SQ20101016127
公开日2010年9月15日 申请日期2010年4月28日 优先权日2010年4月28日
发明者李继明 申请人:北京网康科技有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1