关于对《金山词霸》等软件鼠标取词的一点认识(50分)

  • 主题发起人 主题发起人 晨晨
  • 开始时间 开始时间

晨晨

Unregistered / Unconfirmed
GUEST, unregistred user!
前几天看到有人讨论鼠标取词技术,刚好我也对它有兴趣,并且研究(准确点是看别人的书)了近两个月。可惜的是最后因为技术不到失败了,我把这两个月的酸甜苦辣写在下面,虽然方法可能是不对的,但这个过程也许还是对大家有一点用的,也希望有用。
在今年4月初的一天,我突然对《金山词霸》的鼠标取词技术发生了兴趣,于是就开始自己研究了起来。开始的时候想当然的以为只要调用某个Windows Api函数就可以搞定,就去了学校的图书馆查Win32 SDK手册。找了大约一周的时间才发现原来这个函数并不存在!:( 不过我发现了另外一个东东鼠标Hook,于是我觉得好像又有希望了。可惜的是Win32 SDK手册上的例子是用SDK写的,而且不完整!我只会用Delphi,完全没有用SDK的经验,看了半天一点也看不懂!还好的是几天后我在图书馆找到了另外一本书讲鼠标Hook——《VC++开发人员指南》(书名不是太确定因为有1个多月了)而且讲的很好,例子也不复杂,虽说是VC++写的,但程序还是可以看懂一些。接下来就是用了2周的时间好好学习了一下鼠标Hook技术,并且简化和用Delphi改写了程序。到了4月底的时候我终于学会用鼠标Hook了!!!(如果谁不会的话可以去我的主页http://suncw.home.chinaren.com看我写的鼠标钩子函数的例程)但是学完了我才发现原来这种Message Hook是没有办法在屏幕上取到词的!哎!又白忙了:(其实还是有收获的,至少又学会了一种技巧^_^)
这样我只有又去图书馆碰运气。过了几天我偶然看到了张引大侠的大作《C++ 与 Windows高级编程》虽然这本书是针对Windows3.1平台写的,但是其中有一章——《彻底汉化Windows》正是我要的!!!(另外有讲C++ 中类实现的原理等,不可不看!!!)书上还说这是同类书中首次公布的商用技术!当时市场上的Win3.1外挂中文平台都是用的同样的技术!(张引大侠:我对你的景仰之情真是犹如滔滔江水,又如……)
张大侠在他的著作中对这个技术的描述非常详细,深入核心原理讲解!大家有机会一定要看,虽然是关于Win3.1的但有些原理现在也是适用的,在这里我就不抄书了。(抄了也没有用)只说说大意:在Win3.1中有两个没有公开的Api函数AllocCSToDSAlias()和AllocDSToCSAlias()。用它们就可以完成绕过Windows的保护,直接修改Windows的系统DLL所在内存,找到要改的函数的地址然后我们只要把函数的头几个字节(张大侠改了5个字节)改为跳转到自己的文字输出函数的代码就可以随便处理文字的输出了,也就是Hook Api技术。于是我就想可不可以在Win9X和Win2000中用这个技术进行鼠标取词呢?但是我找了很久也没有在我的Win2000下找到这两个函数,所以就算方法对了,但还是不能实用!我想了几天想到了CIH,报上说它只用了几条代码就跳入Win9X的ring0了!这样不就可以绕过Windows的保护修改系统DLL了吗?于是立刻又上网找来了CIH的代码,可是——它的反汇编代码我看了很久也没有看懂,再加上又不知道在Delphi中怎么用汇编(都怪我水平太次了),而且我知道在WindowsNT和Windows2000中这样跳到ring0是不行的!真让人气馁啊!
但是就在我要放弃的时候,就在我要抓狂的时候,图书馆新书惊现一本Jeffrey Richter大师的宝书——《Windows核心编程》真是众里寻她千百度啊!书上说像我这么改Windows内存中的核心DLL是不行的!是上个世纪的技术了!因为Windows是多线程的,如果正在修改的时候有程序访问那个DLL会引起灾难性的后果!!!55555~~~~~~~~亏我看了那么久的书。
不过Jeffrey Richter大师给了我们一个更好的方法Hook Api,就是修改每个进程的代码!大师以Hook MessageBox()函数为例子给我们讲了方法。
他说:我们知道Win32下的可执行文件都是PE格式的,在其首部有一个输入节,里面就有该文件要调用的输入函数的符号列表,只要把列表指向的函数地址改了就可以了,就这么简单!
大师说简单可是要实际做可是不那么简单的,尤其是像我这样不入流的菜鸟。看大师给的源程序,让我想起了一部动画片——《天书奇谈》^_^ 那些用VC++写的程序太复杂了!要让我这个菜鸟完全看懂并且改成Delphi的目前是绝对不可能的!并且我考虑了一下具体到Hook TextOutA()、TextOutW()和ExtTextOut() 等这些文字输出函数还有很多问题没有解决。例如:如何只是引发你的鼠标所在位置的文字调用TextOutA()或者ExtTextOut()函数呢?现在的我根本不可能解决这些问题,这下我是真的只好放弃了!哎!为什么受伤的总是我!
但是后来没有多久我在网上撞到了马飞涛大侠的网站(http://iflower.myrice.com/index.htm),原来马大侠早就搞定了鼠标取词:-0 看了马大侠写的手记我才知道鼠标取词的复杂程度远远比我以前想的更大!幸好我放弃了不然也许真的会抓狂的(BTW:马大侠,您收我当徒弟好不?)大家可以去看看,但是可惜的是马大侠他要找公司合作所以没有给出源程序,也没有给出Win9X和Windows2000下鼠标取词的方法;可是最绝的是上周日我在电脑报的四方软件专卖店看到了《着迷词王》上面写着——送鼠标取词源程序!啊!!!!我倒!55555~~~~~~~~~(但是我没有买,怕看不懂)
最后我把我构想的取词步骤写在下面但限于我的水平没有办法写出程序实践,所以想法可能很天真 :( 如果那位大侠知道有错请一定要指教(EMail:chen777@cmmail.com)还有如果那位大侠实现了能否让我看看呢?
1、把所有进程和线程的输入表中关于文字输出的函数都找出来,并且把其地址改为指向你自己的函数,并保存原来的地址,退出程序的时候再恢复;
2、为了防止程序用LoadLibrary()这一类函数动态挂上DLL,所以还要把它们挂上。
3、安装鼠标钩子(Mouse Hook);
4、监视鼠标活动,当鼠标移动后,就在鼠标所在的地方放下一个1×1大小的窗口,再Del它,这样Windows就会调用文字输出函数重画窗口上文字,这样我们的函数就可以得到文字了,处理完了记得还是要调用系统的相同的函数哦;
注意:在改进程和线程的输入表的时候不要把自己的程序都一同改了;Jeffrey Richter大师说Win9X在Debuger模式下内存有不同,要判断,原理我没有弄懂,大家还是找大师的书来看看吧。
哎呀,我刚来,就只有200分,上一个问题用了150就50分了,等下次再给回答了问题的大侠!
 
有控件实现了,我曾经用过,勉强可以取词,不太准确。
另外拜托你以后发贴子注意换行。
 
对不起啦,我是贴过来的,第一次来这里嘛!原谅我吧^_^
另外你可以告诉我源代码吗?
 
我有一份VB的源码,不过我没看过。
一位朋友送的。
你到这里去下:
http://www.yueliangwan.com.cn/yf/download.htm
下不了再给我发邮件:doxpix@yeah.net
 
我试了一下一般取词可以,不过IE里不行。
IE里有点麻烦。
 
很老的技术了
 
作者:病毒
  取词翻译没做过,不过写过类似程序,俺简单说一下。
  首先SetWindowsHookEx安装WH_MOUSE的全局HOOK。钩住鼠标消息,
需要在HOOK的CALLBACK函数中完成的功能有用WindowFromPoint获得鼠标所在点,
ScreenToClient获得窗口区域InvalidateRect使之失效。屏幕上文字显示是用GDI32.DLL
中的TextOut、ExtTextOut完成,此时需中截获系统函数并修改,然后仿照TextOut作成
自己的函数MyTextOut。(关于HOOK方面可以翻翻俺以前写的《HOOK技术在黑客软件中的
应用》)下面问题就在你如何知道哪个进程调用了GDI里的函数?这就还得返回来说一下
全局HOOK(参见《HOOK技术在黑客软件中的应用》)对系统钩子来说,系统自动将包含
“钩子CALLBACK函数”的DLL映射到受钩子函数影响的所有进程的地址空间中,即将这个
DLL注入了那些进程。理解了这些你便可以找到虚拟内存空间映射了哪些DLL,用
VirtualQuery找到DLL模块地址后根据PE文件的格式穷举这个模块的
IMAGE_IMPORT_DESCRIPTOR数组,看是否引入了gdi32.dll。如是,则穷举IMAGE_HUNK_DATA
数组,看是否引入了TextOut函数。如过是就可以先获取他然后使其地址表中TextOut的入口
为MyTextOut后,截获系统函数调用的主要部分已经完成,当一个被注入进程调用TextOut时
,其实调用的是MyTextOut,只需在MyTextOut中显示传进来的字符串,再交给TextOut处理
即可。
  这里还要注意WIN95/98和WIN NT/2000的区别,因WIN95/98不是纯32位系统,且GDI是
16位代码,这时就需要动态修改WIN内核,用THUNK技术进行16位32位之间 的通信把
TextOut函数前5个字节改为FAR *。总之类似这种程序要求对系统运行机制和底层有较深入
理解,就单拿HOOK来说本就是在WIN编程中不容易把握的东西,他是将自己的代码钩到其他
进程中执行,也就是说安装钩子后将遍例WIN下所有进程把自己的代码动态欠入这些进程,
并监视,修改其消息。所以控制不好很容易 出错,还有就是写THUNK机制代码,16位,
32位堆栈稍有闪失好就回彻底崩溃。再就是PE可执行文件格式文件比以前DOS下MZ格式复杂
100倍。但不是说就不能实现。这样的困难才有挑战性。如果你搞懂了这些机制,写出了
类似程序,那么你在WIN下编程会有冲刺性的进步。
  
  还有就是别相信那些跟你说截获,重载WIN的某个消息就能完成此类工作的话,
俺打赌他们没做过这方面工作。
 
热血大侠,你不要只是一句话就完了啊!讲一下您的见解好吗?
谢谢doxpix&simbasun大侠,我给分了。可惜我昨天才来分已经是0了:(555~~~
不然我就多给点。
 
屏幕取词的完整解决方案见我的《delphi深入windows核心编程》一书,
解决了IE、win98下的高技术难题,支持windows98/2000/xp,
我的主页http://wenjinshan.yeah.net
 
后退
顶部