~~~屏幕取词技术介绍~~~

空手道人
交通大学思源BBS -- 文章阅读
--------------------------------------------------------------------------------
发信人: ganzhi (阿甘), 信区: Delphi
标 题: 屏幕取词大家谈 (资料整理)
发信站: 交大兵马俑BBS站 (Fri Apr 28 22:51:51 2000), 转信
公开的秘密
我们已经看到不少有关民族软件产业发展现状的分析,其中不乏政策、风险基金、盗版
等方面的解释,但是人们想到没有,技术教育和技术培训的欠缺也是阻碍软件产业发展
不容忽视的因素之一。
拿中英词典软件来说,程序启动后,光标所到之处,即可完成中英互译。这既是辞典软
件广受欢迎之处,也是辞典软件产品开发的难点之一,它涉及到屏幕取词的问题。据说
有一家软件厂商花了三四个月的时间,采用反汇编的方式,终于在浩如烟海的Windows目
标代码中找到了屏幕取词的“诀窍”,这一“诀窍”也就成了“镇山之宝”,秘而不宣
。然而,在微软为开发者提供的MSDN资料中,屏幕取词是公开的秘密;而且,微软提供
的方法远不止一种。换句话说,如果有了MSDN,用不了一天的时间,问题便可迎刃而解
。在为这种大无畏的愚公移山精神所感动之后,我们不禁会问,单就该产品而言,这种
开发方式的代价是不是大了些?在一刻千金的IT市场上,产品研发上的延宕意味着什么

--<<中国计算机报>>,99.7.08,48期.
象汉神,金山词霸中的鼠标一点,就可自动翻译,是如何实现的,调用了那些windowsap
i或函数?中国计算机报上介绍过一个简单的实现方法,主要是接管TextOut,TextoutEx之
类的函数,使用了一个window(16bit)的未公开函数CStoDs(?).该方法在win95下还
可以使用。
最近又有一些人问我怎样截获window api函数,本来想保密的。但是为了大家的利益,
做的小牺牲吧。我告诉大家一个简单的方法吧。那就是进入进程空间,再改写进程函数
的入口地址。 一般windows 程序,都在一个虚拟的地址空间运行,各进程只能改变自己
本身的地址空间的内容。怎样才能进入另外一个进程空间呢。有很多办法,最简单的方
法是利用函数钩子。比如大家可以做一个鼠标回调函数钩子,这样鼠标移到另外进程窗
口时,就会触发你的钩子函数。而且此时此函数钩子已在另外进程空间了。这样你就可
以为所欲为的改变另外一个进程的特性了。具体做法:(只能在NT上,因为95/98没有实
现VirtualProtect等函数), 首先记好该进程的ID,或线程ID。
1、先做钩子函数。
2、当触发此函数钩子时,判断进程ID是否为自己的进程ID。
若是,则是自己的消息,不是,为另外进程空间了判断是否已经hook某api ,否,则hoo
k她。怎样hook呢? 一般windows 函数被映射到此进程的虚拟地址空间里,你可通过GetP
rocAddress得到该函数的入口地址□再通过VirtualProtect一下,这样就可以改写该内
存处的东西了.如果还要该回去,你就保存好此处的内容,对吗?,我很久以前的了,大
家去看看吧,想NJStar就是这么做的。例子放在ftp://10.25.25.225/incoming/pwc/ho
okapi/
截获WIN95的API调用
就是原文中提到的Windows95SystemProgrammingSecrets,中文名字好像是叫Win95系统编
程奥秘,还带一张配书软盘,程序还是不错的,向我们介绍了一种比较成熟的HOOK技术,我
想象Spy之类的程序就需要这种技术.
通用的方法是不存在的。根据要截获的函数和目的,有几种方法:
截获对某些系统API函数调用。Win32程序调用外部API都是通过一个间接函数指针,修改
该指针即可。《Windows95SystemProgrammingSecrets》中有个APISPY32然b序,有详细
介绍,象怎样访问参数,值得研究。这种方法适用于截获应用程序对系统API的调用,但
但需重启动,调试较困难)。
*非输出函数或16位函数。
找到函数地址,用JMP指令替换第一条指令。金山词霸、南极星都用这种方法。这种方法
只能截获已知函数,要保证指令替换不出错。另外,有一个强大的软件BoundsChecker,
NuMega公司出品,其一个功能就是截获API调用。最新版本好像有用户编程接口,截获后
让用户的程序接着处理。该软件已经把所有关于API截获的事情都作了。
电子词典中鼠标取词的原理
据我所知,解决方案一般有两种,都是针对如何知道当前屏幕任一坐标出的字符的.采用截
获对部份GDI的API调用来实现,如TextOut,DrawText,TextOutEx等,字典对每次写屏操作
进行跟踪.技术细节就不赘述乐这种方法也在一些中文系统如中文之星等中采用,另外,有
些第三方的字体,如ADobe等,也是这个方法(参阅<>(AndrewSchulman))
2.对每个设备上下文(DC)做一分Copy,并跟踪所有修改上下文(DC)的操作,这种方法更强
大,但兼容性不好实际上,无论那种方法,都有潜在的问题,如第一种方法,它在WIN95下时
仍是16位方式的(32位技术困难较大),这样就隐含了一个假定:所有文本输出的32位API都
要通过16位的DLL实现,在WIN95中的确如此,担高版本就难说了.而且即使是第一种方法也
容易带来兼容性的问题,比如博雅和中文之星2.0之间就有一定的兼容性问题(WIN95下).
今天做了一个实验,终于大致明白它是怎么实现的。实验很简单,自己写个程序,在On
Paint()里写一句MessageBeep(-1);让PC喇叭发声。然后运行这个程序和“金山词霸”(
“博雅”也一样下面以“词霸”为例),当鼠标在自己程序的窗口上停下一会儿(就是
取词的等待时间)之后,PC喇叭就会发声,同时鼠标也会闪一下。
这说明,鼠标停下之后窗口会重画,这必然是“金山词霸”引起的。其目的是好让这个
窗口产生API调用,以截取TextOut()、DrawText()等函数。这样“词霸”就可以获取该
窗口中输出的字符串了,然后再根据鼠标位置作判断,就可以得到鼠标所指的字符(单
词)了。另外,我还不明白的是该如何截取API调用呢?(这项技术很有用的。)
GetProcAddress()之后应该用自己的函数取代它,然后再调用原来的吧。可是怎么实现
呢?
偶认为象博雅这样的取词是通过截获系统DLL(可能是GDI)中的TextOut或其相关函数来实
现的.系统DLL内存地址>0X8000000(2G~4G),为所有应用程序共享,地址空间固定,不象0~
2G间的内存地址随不同的应用程序而切换.
1做一个DLL,在内部实现与被调用APAPI同名的函数,再把这个DLL放到系统DLL
前面
2修改AAAPI函数代码,设置断点或用JJJMMMPPP,CCCALLL指令。
3在其他的进程中注入DLL,有四种方法
1设置钩子函数
2在注册表中进行注册
在中用CCCC函数,不过不适合95,强行注入D,
通用的方法是不存在的。根据要截获的函数和目的,有几种方法:
*截获对某些系统API函数调用。Win32程序调用外部API都是通过一个间接函数指针,修
改该指针即可。《Windows95SystemProgrammingSecrets》中有个APISPY32程序,有详细
介绍,象怎样访问参数,值得研究。这种方法适用于截获应用程序对系统API的调用,但
但需重启动,调试较困难)。
*非输出函数或16位函数。
找到函数地址,用JMP指令替换第一条指令。金山词霸、南极星都用这种方法。这种方法
只能截获已知函数,要保证指令替换不出错。
另外,有一个强大的软件BoundsChecker,NuMega公司出品,其一个功能就是截获API
调用。最新版本好像有用户编程接口,截获后让用户的程序接着处理。该软件已经把
所有关于API截获的事情都作了。
:就是修改textout等与文本有关的函数,将textout的函数前几个字节放上:ea(jmp)yo
urfun.在fun后在jmp回原textout等函数。这中间由于要:修改代码段,就必需有一个函
数,这就是windows3.1的一个未公开函数,:好像是CstoDsAlias之类,这个函数在win95
下也存在。但在NT下如何实现,还没做过,是不是利用钩函数将自己的DLL注入其他进然
b的地址空间,还望高手指教。
95比NT实现起来容易,NT里好像要改TextOut的
修改textout等与文本有关的函数,将textout的函数前几个字节放上ea(jmp)yourfun.
在fun后在jmp回原textout等函数。这中间由于要修改代码段,就必需有一个函数,这就
是windows3.1的一个未公开函数,好像是CstoDsAlias之类,这个函数在win95下也存在,
这一点我曾做过,应该不会错。但在NT下如何实现,还没做过,是不是利用钩函数将自
己的DLL注入其他进程的地址空间,还望高手指教。
就是怎样用自己的函数替换系统的函数,例如TEXTOUT被我的TEXTOUT1替换。不是只在自
己应用程序,是拦截真个系统中所有的调用。
不要告诉我用AllocCStoDsAlia,在95里已经不能用了。你是想实现屏幕取词吗?要在W
IN32平台下实现沟挂所有线程的API调用,很困难,沟挂某一个还差不多,没说一定是自
己的应用程序。但是我想如果通过走遍所有进程的方法也太笨拙了点。不过说说话,我
没什么更好的方法。但是象金山词霸是怎么做到的呢?所幸的是在95下是用的16位内核
,因此,似乎用的不是独立的内存空间。具体实现方法在TSINGHUABBS上有。
在NT下很难,至少我不知道。似乎国内的其他产品也不行。
NT下也有人做了,还公布了源码,你到各个板找找,我忘了是哪个版了是吗,NT下每个
进程都是独立的地址空间啊,那他是怎么做的呢?能不能提供点线索,给点思路?我找
不到你说的source,sigh.....
屏幕取词的实现源码
碰巧看到了,当然要下回来^_^
ftp://202.114.35.1/flier/Download/Delphi/Component/system/GUIhook95.zip
ftp://202.114.35.1/flier/Download/Delphi/Component/system/GUIhookNT.zip
摘自大富翁
--
I saw you smiling at me
Was it real or just my fantansy?
※ 来源:·交大兵马俑BBS站 bbs.xjtu.edu.cn·[FROM: 27h113]
--------------------------------------------------------------------------------
分类讨论区 全部讨论区 上一篇 本讨论区 下一篇 回文章

来也匆匆,
去也匆匆,
人生仿佛是一场梦!
oooO
( ) Oooo
\ ( ( )
\_) ) /
(_/
oooO
( ) Oooo
\ ( ( )
\_) ) /
(_/
踏踏实实做人,认认真真学习