金山詞霸」螢幕取詞技術揭密 討論稿

2021-04-01 04:21:07 字數 4426 閱讀 2231

這篇文章最早是發在北極星論壇的一系列帖子,那時候聞怡洋(好像他也是mvp)也在那裡混

原始的帖子我已經沒有了,但不知道是誰幫我收集整理了下來(非常感謝),我用google找到了

?這是我進金山之前寫的,應該不算洩露公司技術秘密吧

而且這些現在看來似乎已經有些過時了

?那時討論的只是win31和win9x下的取詞實現

?我到了金山之後不是負責取詞模組,而是做ui,因為有個傢伙比我更擅長做這種東西

他用softice除錯彙編**非常熟練,做逆向工程方面有過人的天分。??

「亦東」 是我那時的筆名??

「金山詞霸」螢幕取詞技術揭密(討論稿)

?主題  螢幕取詞技術系列講座(一)

作者   亦東

很多人對這個問題感興趣。

原因是這項技術讓人感覺很神奇,也很有商業價值。

現在詞典市場金山詞霸佔了絕對優勢,所以再做字典也沒什麼前途了。我就是這麼認為的,所以我雖然掌握了這項技術,卻沒去做字典軟體。只做了乙個和詞霸相似的軟體自己用,本來想拿出來做共享軟體,但我的詞庫是「偷」來的,而且詞彙不多,所以也就算了,詞庫太小,只能取詞有什麼用呢?而且詞霸有共享版的。

大約每週一兩次。想知道的人就常常來看看吧!

一.基礎知識

首先想編這種程式需要一些基礎知識。

會用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.***

主題  螢幕取詞技術系列講座(二)

作者   亦東

很抱歉讓大家久等了!

我看了一些人的回帖,發現很多人對取詞的原理還是不太清楚。

首先我來解釋一下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 ***x:***x語句,跳轉到自己的**裡。

步驟如下:

1.取得windows api入口,用getprocaddress實現

2.儲存api入口的前五個位元組,因為jmp是0xea,位址是4個位元組

3.寫入跳轉語句

這步最複雜

windows的**段本來是不可以寫的,但是microsoft給自己留了個後門。

有乙個未公開函式是alloccstodsalias,

uint winapi alloccstodsalias(uint);

你可以取到這個函式的入口,把api的**段的選擇符(要是不知道什麼是選擇符,就先去學學保護模式程式設計吧)傳給他,他會返回乙個可寫的資料段選擇符。這個選擇符用完要釋放的。用新選擇符和api入口的偏移量合成乙個指標就可以寫windows的**段了。

這就是取詞技術的最核心的東東,不止取詞,連外掛程式中文平台全屏漢化都是使用的這種技術。現在知道為什麼這麼簡單的幾句話卻很少知道了吧?因為太多的產品使用他,太多的公司靠他賺錢了。

這些公司和產品有:中文之星,四通利方,南極星,金山詞霸,實達銘泰的東方快車,roboword,譯典通,即時漢化專家等等等等。。。。還有至少20多家小公司。他們的具體實現雖然不同,但大致原理是相同的。

?主題  關於螢幕取詞的討論(三)

作者   亦東

讓大家久等,很抱歉,前些時候工作忙硬碟又壞了,太不幸了。

這回來點真格的。

咱們以擷取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()

bool clearhook()

bool hookon()

bhookalready=true; }

}

bool hookoff()

bhookalready=false; }

}

//鉤子函式,一定要和api有相同的引數和宣告

bool winapi mytextout(hdc hdc,int nxstart,int nystart,lpcstr lpszstring,uint cbstring)

上面的**是乙個最簡單的掛api鉤子的例子,我要提醒大家的是,這段**是我憑記憶寫的,我以前的**丟了,我沒有編譯測試過

因為我沒有vc++1.52.所以**可能會有錯。

建議使用borland c++,按16位編譯。

如果用vc++1.52,則要改個選項

在vc++1.52的option裡,有個記憶體模式的設定,選大模式,和"ds!=ss ds load on function entry.",切記,否則會系統崩潰。

用金山詞霸的dll檔案實現螢幕取詞 vb

引用xdictgrb.dll,自己到詞霸目錄找。嚴重注意 要金山詞霸2005的版本中的dll,2003版的我未測試成功。新建專案,在新窗體中新增3個label,名稱預設。窗體中 如下 option explicit implements ixdictgrabsink private gp as gr...

API HOOK 金山詞霸取詞功能原理2

螢幕上的文字大都是由 gdi32.dll 的以下幾個函式顯示的 textouta textoutw exttextouta exttextoutw 實現螢幕抓詞的關鍵就是截獲對這些函式的呼叫,得到程式發給它們的引數。我的方法有以下三個步驟 一 得到滑鼠的當前位置 通過setwindowshookex...

運用金山詞霸元件開發屬於自己的螢幕取詞模組

本軟體是基於金山詞霸元件進行com開發,所以需要你的機子上要裝有金山詞霸軟體 使用金山詞霸的螢幕取詞功能 xdictgrb.dll 1 介面 1.1 grabproxy取詞 物件 function advisegrab xdictgrabsink as ixdictgrabsink as long ...