屏幕取词核心内幕

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

屏幕取词核心内幕

本文只对与几个关键性技术的实现细节进行讨论,其它的编程细节,请参考源程序。

32位到16位的形式替换

32位代码与16位代码的数据交换

  动态修改Windows内核

 1.  32bit16bit的形式替换(Thunk

形式替换是指那些允许从16位代码调用32位代码或从32位代码调用16位代码的技术。形式替换用于解决试图在同一操作系统或同一可执行程序上使16位代码与32位代码同时并存的问题,即16位代码与32位代码的混合编程技术。早期的DOS程序及Window3.x上的应用程序均为16位程序,Windows95Windows NT虽然也可运行旧的16位程序,但它们的主流发展方向是32位应用程序。与Windows NT不同的是,Windows95不是一个“纯”32位操作系统,为了兼有令人满意的速度和与旧的16位程序的良好兼容性,其内核本身就是一个16位与32位的混合体,因此也为编程者使用形式替换提供了便利。Microsoft为编写形式替换程序提供了通用的接口及工具,但因LTW32中的形式替换并不复杂,所以使用了一些编程技巧,而避免了使用Microsoft复杂的开发工具。

形式替换中最主要的问题有两点:①16位与32位数据类型尺寸的变化,如16位代码到32位代码的一个重要变化是整型数int的长度加倍了 ;②是堆栈操作时,16位模式使用SS:SP堆栈指针控制栈顶,而在32位模式中使用ESP寄存器作堆栈指针控制栈顶。

LTW32中,屏幕抓词功能由16DLL实现,因而只需实现32位到16位的形式替换,为32位代码提供16DLL的调用接口。CALL FWORD PTR32位汇编代码的一种调用方法,它可让32位代码调用到16位代码。作为实现的关键,控制16位侧与32位侧各自的堆栈是编程的要点。

32位侧的调用代码:

_asm{

        pusha

        call fword ptr [func16bit] /* func16bit16位被调用者的48位地址 */

        popa

}

16位侧的调用代码:

int dummy;

static char stack[8192];              /* 16位代码的临时堆栈 */

static WORD stack_seg;

static WORD prev_seg;

static DWORD prev_ofs;

static WORD prev_ds;

_asm{

        push ax;

        push bx;

        mov ax, ds;

        mov bx, seg dummy;

        mov ds, bx;

        mov stack_seg, bx;

        mov prev_ds, ax;

        pop bx;

        pop ax;

        mov prev_seg, ss;

        mov dword ptr prev_ofs, esp; /* 保存32位堆栈指针 */

        mov ss, stack_seg;

        mov sp, offset stack;      /* 设置16位堆栈指针 */

        add sp, 8192;

}

/* 此处加入16位代码要实现的功能 */

_asm{

        mov ss, prev_seg;

        mov esp, dword ptr prev_ofs; /* 恢复32位堆栈指针 */

        mov ds, prev_ds;

       lea sp, word ptr [bp-2];

       pop ds;

        pop bp;

    dec bp;

        db 66h;

        retf;

}

由于调用中传递的参数有限,所以涉及的代码并不多,唯一比较复杂之处在16位侧,它临时转向一个16位堆栈,服务于来自32位的调用者的请求。在16位侧入口处,必须存放好32位调用者的32位堆栈的指针,并且在16位侧返回时恢复它。由代码可见,这个过程是不可重入的,即一次只支持一个调用者,由于调用者只有LTW3232位侧代码,所以此限制可以满足。另外,在16位代码返回时,必须恢复32位调用者的48位堆栈指针(SS:ESP)而不是32位的CS:SP,而且必须用一个48位地址(16:32)远返回(66h RETF)到它的32位调用者。

处理好这些细节,实现32位到16位的形式替换实际上是很简单的。

2.  32位代码与16位代码的数据交换

32位代码使用16位段地址加32位线性地址(16:32)的地址形式,16位代码使用16位段选择符(selector)加16位偏移(16:16)的地址形式。在Windows 9532位侧,段址28h是系统段,即通过CS=28hDS=28h可以访问系统的4G空间,其它应用程序的地址空间都是映射到28h段的4G空间中。Windows95中所有32位进程的地址空间(共4G)的高2G80000000H~FFFFFFFFH)全部映射到28:80000000~28:FFFFFFFFH。即这块区域是所有32位程序共享的。这里一般存放系统DLL、虚拟设备驱动程序(VxD)、内存映射文件、16位应用程序和16位全局堆等。最后一项很重要,这为32位代码与16位代码交换数据提供了一个简便的方法。因为16位程序的段选择符的基址即是其所映射的系统段中的线性地址,这样,只要能够得到这个线性地址,32位代码就可以轻易地访问到16位程序的数据(LTW32 32位侧使用此方法从16位侧获得屏幕截获的信息)。而16位段选择符的线性基址可以通过使用系统调用GetSelectorBase()得到,具体实现可参考源程序。线性地址计算的例子如下:

16位地址:07F2:1234H

段选择符         07F2H的线性基址为:82F41300H

段选择符         07F2H的尺寸为:4000H

82F41300H + 1234H = 82F42534

对应的32位线性地址为28:82F42534H

3.  动态修改Windows内核

如前所述,Windows95不是一个“纯”32位操作系统,其内核模块中的USERGDI均是用16位代码实现的。USER32.DLLGDI32.DLL只是16位的USER.EXEGDI.EXE32位调用接口。因此,如果屏幕截获程序用32位代码实现,则只能截获32位应用程序对USER32.DLLGDI32.DLL的调用,无法截获16位应用程序对USER.EXEGDI.EXE的调用,所以如果想截获所有应用程序(包括Windows95的桌面程序Explorer)中有关屏幕输出的系统调用,则应该用16位代码实现屏幕截获功能。这就是LTW32为什么不是“纯”32位应用程序的原因。LTW32主要截获两个系统调用TextOut()ExtTextOut(),方法很简单,把这两个函数的头五个字节修改为一个JMP FAR 指令,使得对这两个函数的调用均转向屏幕截获程序。这就涉及到一个关键问题:动态修改Windows的代码。

在传统的DOS程序中,动态修改程序代码无任何困难,但在Windows中则不然,因为在Windows中,代码可被同一程序的多个实例(进程)共享,所以系统不允许应用程序动态的修改代码。在16位侧,内存的可读、写属性是与段选择符联系在一起的。段选择符基本上可分为两类:数据段选择符和代码段选择符。前者可读、可写、不可执行;后者可读、可执行、不可写。Windows提供了这两类段选择符相转换的系统调用。未公开的16位系统调用AllocCStoDSAlias()为给定的代码段选择符分配一个具有相同线性基址和尺寸的数据段别名(DS Alias)。通过DS别名可以对给定的代码段进行修改。AllocCStoDSAlias()的使用方法如下:

WORD (FAR PASCAL *AllocCStoDSAlias)(WORD);

AllocCStoDSAlias = GetProcAddress(

GetModuleHandle(“KERNEL”), ”ALLOCCSTODSALIAS”);

调用参数为给定的代码选择符,调用成功时返回一个线性基址和尺寸均与原代码选择符相同的DS别名。当不再使用此DS别名时,要用系统调用FreeSelector()DS别名释放掉。

使用上述技术,就可实现动态修改Windows代码,从而改变GDI的系统调用TextOut()ExtTextOut()的执行动作,实时地截获屏幕输出,为实现鼠标随动翻译提供可能。

把上述的32位到16位的形式替换、32位代码与16位代码的数据交换、动态修改Windows内核等技术综合应用在一起,配合单词查找算法和词组分析算法就可以实现鼠标随动翻译功能。

Unbuntu20.04环境下一款开源翻译软件:goldendict的安装与配置(图文) Unbuntu20.04环境下一款开源翻译软件:goldendict的安装与配置(图文)一、goldendict的安装二、goldendict的配置2.1. 屏幕取词设置2.2. 在线字典配置 不论是在科研、项目开发,大量查看阅读英语资料、文献是必不可少的,很多东西只有从英文原文才能领会它们的精髓。因此,一款好用的Linux环境下的翻译软件是我们工作学习中必备的工具。 一、goldendict的安装 这款软件就是golddict,可以在github上查看源码https://github.com/golden 阅读详情

相关推荐

屏幕取词编程学习总结

屏幕取词的研究 现在词典市场金山词霸占了绝对优势,所以再做字典也没什么前途了。我就是这么认为的,所以我虽然 掌握了这项技术,却没去做字典软件。只做了一个和词霸相似的软件自己用,本来想拿出来做共享软件 ,但我的词库是“偷”来的,而且词汇不多,所以也就算了,词库太小,只能取词有什么用呢?而且词 霸有共享版的。但既然很多人想了解这项技术,我也不会保留。我准备分多次

bcbobo21cn的专栏 5815

关于金山词霸的屏幕取词1

“金山词霸”屏幕取词技术揭密(讨论稿) (17千字)发信人:5,555时 间:2001-11-1 9:30:12 详细信息:“金山词霸”屏幕取词技术揭密(讨论稿) 主题  屏幕取词技术系列讲座(一) 作者   亦东 很多人对这个问题感兴趣。 原因是这项技术让人感觉很神奇,也很有商业价值。 现在词典市场金山词霸占了绝对优势,所以再做字典也没什么前途了。我就是这么认为的,所以我虽然掌握了这项技术,

deadcat的专栏 5529

VC++屏幕取词源代码.zip

VC++屏幕取词源代码.zip visual c++仿金山词霸等 屏幕取词功能

Linux 下屏幕取词(goldendict)

安装 goldendict sudo apt-get install goldendict 打开屏幕选词功能 配置自己的在线查询脚本 chmod +x youdao_get.py 设置权限 youdao_get.py #!/home/wjq/anaconda3/bin/python # -*- coding: utf-8 -*- header={ 'Accept':'text...

junqing_wu的博客 2411

屏幕取词核心内幕 (转)

屏幕取词核心内幕 (转)[@more@]屏幕取词核心内幕 本文只对与几个关键性技术的实现细节进行讨论,其它的编程细节,请参考源程序。 32位到16位的形式替换 32位代码与16位代码的数据交换 动态修改windows...

circularr9834的博客 81

OpenScreen 界面语言设置完整指南:3 步切换到中文,还能自己加一种语言

OpenScreen 是一款免费开源的屏幕录制与视频编辑工具(可看作 Screen Studio 的免费替代)。它的**界面语言切换**做得相当顺手:内置 13 种语言,默认英语,中文用户可以在启动窗口或编辑器顶栏一键切换到简体中文,设置还会自动记住。这篇指南带你从零完成 OpenScreen 中文界面设置,顺带看懂它底层的国际化(i18n,即"国际化",指软件根据用户地区显示对应语言的能力)架构

gitblog_00376的博客 396

IT文档 12

屏幕取词核心内幕屏幕抓图程序DIY工具条的停靠控制巧妙实现BROWSE语句左右翻屏的方法巧用ASP技术保护DHTML源代码巧用ASP生成PDF文件巧用CLIPBOARD建立图像数据库巧用VB编程使XMPLAYER自动播放VCD巧用Visual C++编程来实现全屏幕显示功能巧用文件保存对象来提高JSP的性能巧用缓存提高ASP应用程序的性能常用文件目录操作平台+插件软件设计思想及基于COM的原型实现

iamhere1956的专栏 464

•alpha 闪烁效果-(2013/09/18)

alpha 闪烁效果-(2013/09/18) button color picker-(2013/09/18) 使用odbcapi编写数据库应用程序-(2013/09/18) stl之父访谈录-(2013/09/18) sysutil 1.0: a window-(2013/09/18) 利用activex控件自制mp3播放器 microsoft windows ce 编程的十点忠告

q1q2q3q4ln的专栏-随我一起研究程序 998

屏幕取词实现

要建个DLL实现钩子unit GetWord;interfaceuses  SysUtils,  windows,  messages;const NHD_GETWORD_TIMER = 2;const NHD_MAX_TEXTLEN = 1024;const NHD_WIN_INITPOSX = -1;const NHD_WIN_INITPOSY = -1;const NHD_FLYWIN_WI

RENYUAN 4830

goldendict 屏幕取词

goldendict使用

qq_27137935的博客 704

goldendict 屏幕取词_GoldenDict词典工具使用方法

简介GoldenDict是一种非常实用和方便的词典软件,支持多种的词典格式,方便平时经常查询词典使用。但需要注意的是:它并不是词典本身,而是词典的使用工具,类似系统一样,使用的软件要在系统里单独安装,系统提供了软件可以运行的环境。GoldenDict提供了词典可以使用的环境,里面的词典文件需要单独下载。这在以后会说明。GoldenDict的优势:开源,免费。启动快捷、便利,不占用系统资源...

weixin_39618275的博客 7698

安装使用 GoldenDict 查词神器 (Windows/Mac/Linux)

安装使用 GoldenDict 查词神器 (Windows/Mac/Linux) 人一生离不开词典。无论是生活、学习还是工作,当我们遇到不懂的词语时,大部分人的解决方法是使用搜索引擎或者查词软件。作为学习者,我认为查词软件更好用,而且一本或几本好词典能让我们学习事半功倍。而免费查词软件我推荐GoldenDict。 GoldenDict 的优点: 免费 纯净无广告 == 专注 跨平台:Windows / Mac / Linux 支持多种词典格式 支持查维基百科 / 支持在线查词 / 支持在.

networkhunter的博客 1万+

[每天一个Linux小技巧] Goldendict 快速取词

Goldendict 屏幕取词比较麻烦,没有快捷键,需要点击Goldendict的界面选择屏幕取词. 所以推荐用如下的方式来取词: Ctrl + C + C 需要翻译的词选上后, 使用如上按键即可.

闲云孤鹤 1万+

关于屏幕取词的问题(转)

金山词霸”屏幕取词技术揭密(讨论稿) 这篇文章最早是发在北极星论坛的一系列帖子,那时候闻怡洋(好像他也是MVP)也在那里混原始的帖子我已经没有了,但不知道是谁帮我收集整理了下来(非常感谢),我用google找到了?这是我进金山之前写的,应该不算泄露公司技术秘密吧 而且这些现在看来似乎已经有些过时了?那时讨论的只是Win31和Win9x下的取词实现?我到了金山之后

RaoX的专栏 3212

GoldenDict设置

切换到Dictionaries,通过改变“词典位置”调整“查词优先级”顺序。选择自定义词典位置打开,此处以D:\GoldenDict为例,点击。图标右键点击,可开启实时屏幕取词。完成后 Apply 应用。扫描前,注意勾选递归搜索。

issta的博客 1792
下一篇: 将你的Visual Basic 6.0移植到Visual Basic.NET
OUYAN
博客等级 码龄26年 0粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值