`
cuijiemin
  • 浏览: 265475 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

金山词霸”屏幕取词技术揭密(讨论稿)

阅读更多
主题  屏幕取词技术系列讲座(一)
作者   亦东
很多人对这个问题感兴趣。
原因是这项技术让人感觉很神奇,也很有商业价值。
现在词典市场金山词霸占了绝对优势,所以再做字典也没什么前途了。我就是这么认为的,所以我虽然掌握了这项技术,却没去做字典软件。只做了一个和词霸相似的软件自己用,本来想拿出来做共享软件,但我的词库是“偷”来的,而且词汇不多,所以也就算了,词库太小,只能取词有什么用呢?而且词霸有共享版的。
但既然很多人想了解这项技术,我也不会保留。我准备分多次讲述这项技术的所有细节。
大约每周一两次。想知道的人就常常来看看吧!
一.基础知识
首先想编这种程序需要一些基础知识。
会用Vc++,包括16/32位。
精通Windows API特别是GDI,KERNEL部分。
懂汇编语言,会用softice调试程序,因为这种程序最好用softice调试。
二.基本原理
在Window 3.x时代,windows系统提供的字符输出函数只有很少的几个。
TextOut
ExtTextOut
DrawText
......
其中DrawText最终是用ExtTextOut实现的。
所以Windows的所有字符输出都是由调用TextOut和ExtTextOut实现的。因此,如果你可以修改这两个函数的入口,让程序先调用你自己的一个函数再调用系统的字符输出,你就可以得到Windows所有输出的字符了。
到了Windows95时代,原理基本没变,但是95比3.x要复杂。开始的时候,一些在windows3.x下编写的取词软件仍然可以是使用。但是后来出了个IE4,结果很多词典软件就因为不支持IE4而被淘汰了,但同时也给一些软件创造了机会,如金山词霸。其实IE4的问题并不复杂,只不过它的输出的是unicode字符,是用TextOutW和ExtTextOutW输出的。知道了这一点,只要也截取就可以了。不过实现方法复杂一点,以后会有详细讲解。现在又出了个IE5,结果词霸也不好用了,微软真是#^@#$%$*&^&#@#@..........
我研究后找到了一种解决办法,但还有些问题,有时会取错,正在继续研究,希望大家共同探讨。
另外还有WindowsNT,原理也是一样,只是实现方法和95下完全不同。
三.技术要点
要实现取词,主要要解决以下技术问题。
1.截取API入口,获得API的参数。
2.安全地潜入Windows内部,良好地兼容Windows的各个版本
3.计算鼠标所在的单词和字母。
4.如果你在Window95下,做32位程序,还涉及Windows32/16混合编程的技术。
今天先到这里吧!最好准备一份softice for 95/98和金山词霸,让我们先来分析一下别人是怎么做的。
欢迎与我联系
E-Mail:yeedong@163.net
主题  屏幕取词技术系列讲座(二)
作者   亦东
很抱歉让大家久等了!
我看了一些人的回帖,发现很多人对取词的原理还是不太清楚。
首先我来解释一下hook问题。词霸中的确用到了hook,而且他用了两种hook其中一种是Windows标准hook,通过SetWindowHook安装一个回调函数,它安装了一个鼠标hook,是为了可以及时响应鼠标的消息用的和取词没太大关系。
另一种钩子是API钩子,这才是取词的核心技术所在。他在TextOut等函数的开头写了一个jmp语句,跳转到自己的代码里。
你用softice看不到这个跳转语句是因为它只在取词的一瞬间才存在,平时是没有的。
你可以在TextOut开头设一个读写断点
bpm textout
再取词,就会找到词霸用来写钩子的代码了。
/**********************************
所以我在次强调,想学这种技术一定要懂汇编语言和熟练使用softice.
**********************************/
至于从cjktl95中dump出来的未公开函数是和Windows32/16混合编程有关的,以后我会提到他们。
我先来讲述取词的过程,
0 判断鼠标是否在一个地方停留了一段时间
1 取得鼠标当前位置
2 以鼠标位置为中心生成一个矩形
3 挂上API钩子
4 让这个矩形产生重画消息
5 在钩子里等输出字符
6 计算鼠标在哪个单词上面,把这个单词保存下来
7 如果得到单词则摘掉API钩子,在一段时间后,无论是否得到单词都摘掉API钩子
8 用单词查词库,显示解释框。
很多步骤实现起来都有一些难度,所以在中国可以做一个完善的取词词典的人屈指可数。
其中0,1,2,7,8比较简单就不提了。
先说如何挂钩子:
所谓钩子其实就是在WindowsAPI入口写一个JMP XXXX:XXXX语句,跳转到自己的代码里。
步骤如下:
1.取得Windows API入口,用GetProcAddress实现
2.保存API入口的前五个字节,因为JMP是0xEA,地址是4个字节
3.写入跳转语句
这步最复杂
Windows的代码段本来是不可以写的,但是Microsoft给自己留了个后门。
有一个未公开函数是AllocCsToDsAlias,
UINT WINAPI ALLOCCSTODSALIAS(UINT);
你可以取到这个函数的入口,把API的代码段的选择符(要是不知道什么是选择符,就先去学学保护模式编程吧)传给他,他会返回一个可写的数据段选择符。这个选择符用完要释放的。用新选择符和API入口的偏移量合成一个指针就可以写windows的代码段了。
这就是取词技术的最核心的东东,不止取词,连外挂中文平台全屏汉化都是使用的这种技术。现在知道为什么这么简单的几句话却很少知道了吧?因为太多的产品使用他,太多的公司靠他赚钱了。
这些公司和产品有:中文之星,四通利方,南极星,金山词霸,实达铭泰的东方快车,roboword,译典通,即时汉化专家等等等等。。。。还有至少20多家小公司。他们的具体实现虽然不同,但大致原理是相同的。
我这些都是随手写的,也没有提纲之类的东西,以后如果有机会我会整理一下,大家先凑合着看吧!xixi...
主题  关于屏幕取词的讨论(三)
作者   亦东

让大家久等,很抱歉,前些时候工作忙硬盘又坏了,太不幸了。
这回来点真格的。
咱们以截取TextOut为例。
下面是代码:
//截取TextOut
typedef UINT (WINAPI* ALLOCCSTODSALIAS)(UINT);
ALLOCCSTODSALIAS AllocCsToDsAlias;
BYTE NewValue[5];//保存新的入口代码
BYTE OldValue[5];//API原来的入口代码
unsigned char * Address=NULL;//可写的API入口地址
UINT DsSelector=NULL;//指向API入口的可写的选择符
WORD OffSetEntry=NULL;//API的偏移量
BOOL bHookAlready = FALSE; //是否挂钩子的标志
BOOL InitHook()
{
HMODULE hKernel,hGdi;
hKernel = GetModuleHandle("Kernel");
if(hKernel==NULL)
return FALSE;
AllocCsToDsAlias = (ALLOCCSTODSALIAS)GetProcAddress(hKernel,"AllocCsToDsAlias");//这是未公开的API所以要这样取地址
if(AllocCsToDsAlias==NULL)
return FALSE;
hGdi = GetModuleHandle("Gdi");
if(hmGdi==NULL)
return FALSE;
FARPROC Entry = GetProcAddress(hGdi,"TextOut");
if(Entry==NULL)
return FALSE;
OffSetEntry = (WORD)(FP_OFF(Entry));//取得API代码段的选择符
DsSelector = AllocCsToDsAlias(FP_SEG(Entry));//分配一个等同的可写的选择符
Address = (unsigned char*)MK_FP(DsSelector,OffSetEntry);//合成地址
NewValue[0]=0xEA;
*((DWORD*)(NewValue+1)) = (DWORD)MyTextOut;
OldValue[0]=Address[0];
*((DWORD*)(OldValue+1)) = *((DWORD*)(Address+1));
}
BOOL ClearHook()
{
if(bHookAlready)
HookOff();
FreeSelector(DsSelector);
}
BOOL HookOn()
{
if(!bHookAlready){
for(int i=0;i<5;i++){
Address[i]=NewValue[i];
}
bHookAlready=TRUE;
}
}
BOOL HookOff()
{
if(bHookAlready){
for(int i=0;i<5;i++){
Address[i]=OldValue[i];
}
bHookAlready=FALSE;
}
}
//钩子函数,一定要和API有相同的参数和声明
BOOL WINAPI MyTextOut(HDC hdc,int nXStart,int nYStart,LPCSTR lpszString,UINT cbString)
{
BOOL ret;
HookOff();
ret = TextOut(hdc,nXStart,nYStart,lpszString,cbString);//调原来的TextOut
HookOn();
return ret;
}
上面的代码是一个最简单的挂API钩子的例子,我要提醒大家的是,这段代码是我凭记忆写的,我以前的代码丢了,我没有编译测试过
因为我没有VC++1.52.所以代码可能会有错。
建议使用Borland c++,按16位编译。
如果用VC++1.52,则要改个选项
在VC++1.52的Option里,有个内存模式的设置,选大模式,和"DS!=SS DS Load on Function entry.",切记,否则会系统崩溃。
有什么不明白的可以给我写信
分享到:
评论

相关推荐

    金山词霸屏幕取词功能源程序.zip

    该压缩包"金山词霸屏幕取词功能源程序.zip"包含了一些关键组件和文档,让我们深入了解这一技术。 1. **Nhw32.dll**:这是一个动态链接库(DLL)文件,通常用于实现特定的功能模块。在金山词霸的屏幕取词中,Nhw32....

    轻松解决金山词霸无法屏幕取词的故障

    金山词霸是一款在中国非常流行的词典软件,它提供屏幕取词功能,使得用户可以在不中断当前...对于无法通过常规方法解决的特殊情况,还需要依靠金山词霸的技术支持团队来协助处理,以保证用户能够顺利使用屏幕取词功能。

    仿金山词霸屏幕取词源代码

    理解并分析这个“仿金山词霸屏幕取词源代码”可以帮助开发者学习如何在自己的应用中实现类似的屏幕取词功能,同时也能深入理解Windows编程、OCR技术、钩子机制等多个IT领域的核心技术。这对于提升软件开发技能,特别...

    屏幕取词源码---金山词霸等屏幕取词技术

    屏幕取词源码。。。。屏幕取词源码。。。。屏幕取词源码。。。。金山词霸。。。。。。金山词霸。。

    屏幕取词金山研究,金山词霸手机屏幕取词,Delphi源码.zip

    本压缩包文件"屏幕取词金山研究,金山词霸手机屏幕取词,Delphi源码.zip"显然包含了关于这项技术的研究资料,特别是针对手机平台的实现,以及使用Delphi编程语言的源代码。 Delphi是一款强大的集成开发环境(IDE),...

    VC++ 仿金山词霸屏幕取词程序

    【VC++ 仿金山词霸屏幕取词程序】是一个基于C++编程语言开发的动态链接库(DLL)项目,旨在实现类似金山词霸的屏幕取词功能。在使用该程序时,用户只需按住Ctrl键,然后移动鼠标,就可以在屏幕上选取单词或短语,并...

    金山词霸屏幕取词原理

    “鼠标屏幕取词”技术是在电子字典中得到广泛地应用的,如四通利方和金山词霸等软件,这个技术看似简单,其实在WINDOWS系统中实现却是非常复杂的,总的来说有两种实现方式: 第一种:采用截获对部分GDI的API调用来...

    金山词霸屏幕取词组件的MFC例程

    金山词霸屏幕取词组件的MFC例程 网上只有VB调用例子,而没有VC++的,所编写了这个源码-Kingsoft Capture Characters from Screen Component MFC routines called VB online only examples and not VC. prepared by the...

    真正类似金山词霸屏幕取词的源代码

    这个“真正类似金山词霸屏幕取词的源代码”提供了实现这一功能的技术方案。金山词霸是一款知名的词典软件,其屏幕取词功能广受好评,它能够方便快捷地帮助用户理解屏幕上的英文内容。 屏幕取词的核心技术主要包括...

    金山词霸2006屏幕取词问题研究

    根据给定的信息,本文将深入探讨金山词霸2006屏幕取词功能的问题及其解决方案。金山词霸2006是一款由金山软件公司推出的词典翻译软件,它具有屏幕取词的功能,用户可以在计算机屏幕上选取任何位置的文字进行翻译。...

    C#开始金山词霸屏幕取词(有源码)

    本项目“C#实现金山词霸屏幕取词”提供了一种方法,利用C#编程语言来实现类似金山词霸的屏幕取词功能,并且附带了源代码,方便开发者学习和参考。 首先,我们要理解屏幕取词的基本原理。屏幕取词技术通常基于图像...

    类似金山词霸的屏幕取词示例代码.rar_取词_屏幕取词_屏幕取词 delphi_金山词霸

    屏幕取词技术是一种在计算机屏幕上选取任意单词或短语,并即时显示其翻译的功能,常见于各种翻译软件中,如金山词霸。这个压缩包“类似金山词霸的屏幕取词示例代码.rar”包含了实现这一功能的Delphi编程示例代码,...

    C# 屏幕取词源码(模拟金山词霸)

    在本案例中,我们讨论的是使用C#语言编写的屏幕取词源码,其功能是模拟金山词霸的应用。金山词霸是一款知名的词典软件,提供了丰富的词汇量和便捷的屏幕取词功能,使得用户在阅读英文文档或浏览网页时可以快速查找不...

    金山词霸64位WIN7取词补丁

    【金山词霸64位WIN7取词补丁】是一个专为64位Windows 7系统设计的软件补丁,其主要目的是解决在64位操作系统环境下金山词霸的屏幕取词功能无法正常工作的问题。在传统的32位系统中,金山词霸的屏幕取词功能通常能够...

    金山词霸的屏幕取词技术,利用了 DLL编程,非常值得学习.rar

    金山词霸作为一款知名的词典软件,其屏幕取词功能的实现就巧妙地运用了DLL(动态链接库)编程技术。DLL是一种可执行文件格式,它包含可被其他程序调用的函数和数据,从而实现了代码的共享和复用。 DLL编程的核心...

    c#鼠标屏幕取词(金山词霸dll)

    本项目涉及的是在C#环境下利用金山词霸的DLL(动态链接库)文件,实现一个鼠标屏幕取词的功能。这个功能允许用户在屏幕上悬浮鼠标时,自动识别并翻译选中的单词或短语,极大地提高了语言学习和工作的效率。 首先,...

    C#屏幕取词实例 利用 金山词霸 组件XdictGrb.dll

    本篇文章将深入探讨如何在C#编程环境中,利用金山词霸提供的组件XdictGrb.dll来实现屏幕取词。 首先,我们需要了解XdictGrb.dll是什么。这是一个由金山词霸提供的动态链接库(DLL),包含了用于与金山词霸软件进行...

    屏幕取词源代码可二次开发

    屏幕取词技术是一种在计算机屏幕上选取任意单词或短语,并进行即时翻译或查询的技术,它大大提升了用户在处理多语言信息时的效率。本压缩包包含的“屏幕取词源代码”提供了二次开发的可能性,意味着你可以根据自己的...

    金山词霸屏幕取词原理(源代码)

    自己写的 金山词霸类翻译软件的屏幕取词的原理性的源代码 分为三个部分 dll中是HOOK TextOutA的代码和安装钩子的代码 test是目标程序 此程序使用了TextOut函数 DLL_test是将DLL注入到目标程序的

    金山词霸如何屏幕取词.docx

    **金山词霸屏幕取词教程** 金山词霸是一款广受欢迎的英语学习软件,它提供了丰富的词汇资源和便捷的翻译功能。其中,屏幕取词是一项非常实用的功能,它允许用户在浏览网页、阅读文档或者使用其他应用程序时,只需将...

Global site tag (gtag.js) - Google Analytics