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

2021-04-16 01:38:17 字數 3040 閱讀 4997

螢幕上的文字大都是由

gdi32.dll

的以下幾個函式顯示的:

textouta

、textoutw

、exttextouta

、exttextoutw

。實現螢幕抓詞的關鍵就是截獲對這些函式的呼叫,得到程式發給它們的引數。

我的方法有以下三個步驟:

一、得到滑鼠的當前位置

通過setwindowshookex

實現。二、向滑鼠下的視窗發重畫訊息,讓它呼叫系統函式重畫

通過windowfrompoint

,screentoclient

,invalidaterect  

實現。三、截獲對系統函式的呼叫,取得引數(以

textouta

為例)  

1.仿照

textouta

作成自己的函式

mytextouta

,與textouta

有相同引數和返回值,放在系統鉤子所在的

dll裡。

sysfunc1=(dword)getprocaddress(getmodulehandle("gdi32.dll"),"textouta");  

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

2.由於系統滑鼠鉤子已經完成注入其它

gui程序的工作,我們不需要為注入再做工作。

如果你知道所有系統鉤子的函式必須要在動態庫里,就不會對"注入

"感到奇怪。當程序隱式或顯式呼叫乙個動態庫里的函式時,系統都要把這個動態庫對映到

這個程序的虛擬位址空間裡

(以下簡稱

"位址空間

")。這使得

dll成為程序的一部分,以這個程序的身份執行,使用這個程序的堆疊(見圖

1)。圖1   dll

對映到虛擬位址空間中

對系統鉤子來說,系統自動將包含

"鉤子**函式"的

dll對映到受鉤子函式影響的所有程序的位址空間中,即將這個

dll注入了那些程序。

3.當包含鉤子的

dll注入其它程序後,尋找對映到這個程序虛擬記憶體裡的各個模組(

exe和

dll)的基位址。

exe和

dll被對映到虛擬記憶體空間的

什麼地方是由它們的基位址決定的。它們的基位址是在鏈結時由鏈結器決定的。當你新建乙個

win32

工程時,

vc++鏈結器使用預設的基位址

0x00400000

。可以通過鏈結器的

base

選項改變模組的基位址。

exe通常被對映到虛擬記憶體的

0x00400000

處,dll

也隨之有不同的基地

址,通常被對映到不同程序的相同的虛擬位址空間處。

如何知道

exe和

dll被對映到**了呢?

在win32

中,hmodule

和hinstance

是相同的。它們就是相應模組被裝入程序的虛擬記憶體空間的基位址。比如:

hmodule   hmodule=getmodulehandle(

〃gdi32.dll

〃);  

返回的模組控制代碼強制轉換為指標後,就是

gdi32.dll

被裝入的基位址。

關於如何找到虛擬記憶體空間映**哪些

dll?我用如下方式實現:

while(virtualquery   (base,  

&mbi,   sizeof   (mbi))

〉0)  

4.得到模組的基位址後,根據

pe檔案的格式窮舉這個模組的

image-import-descriptor

陣列,看是否引入了

gdi32.dll

。如是,則窮舉

image-thunk-data

陣列,看是否引入了

textouta

函式。5.

如果找到,將其替換為相應的自己的函式。

系統將exe

和dll

原封不動對映到虛擬記憶體空間中,它們在記憶體中的結構與磁碟上的靜態檔案結構是一樣的。即

pe   (portable   executable)  

檔案格式。

所有對給定

api函式的呼叫總是通過可執行檔案的同乙個地方轉移。那就是乙個模組

(可以是

exe或

dll)

的輸入位址表

(import   address   table)

。那裡有所有本模組呼叫的其它

dll的函式名及位址。對其它

dll的函式呼叫實際上只是跳轉到輸入位址表,由輸入位址表再跳轉到

dll真正的

函式入口。例如:

圖2  

對messagebox()

的呼叫跳轉到輸入位址表,從輸入位址表再跳轉到

messagebox

函式image-import-descriptor

和image-thunk-data

分別對應於

dll和函式。它們是

pe檔案的輸入位址表的格式(資料結構參見

winnt.h

)。bool   changefuncentry(hmodule   hmodule)  

else  

pthunk++;   }   return   1;}}}  

替換了輸入位址表中

textouta

的入口為

mytextouta

後,截獲系統函式呼叫的主要部分已經完成,當乙個被注入程序呼叫

textouta

時,其實呼叫的是

mytextouta

,只需在

mytextouta

中顯示傳進來的字串,再交給

textouta

處理即可。

谷歌金山詞霸

早就聽說有 谷歌詞霸 了,一直想試用一下,可是網上給的鏈結都連不上。聽說要等到5月 8號發布,可昨天谷歌和金山官網上都沒有動靜。今天早上登入 csdn 才知道有正式發布的版本了。然後立刻到 google google 注意右側的詞典引導,可供選擇的詞典實在太少了。我們可以通過在詞典管理難介面新增詞典...

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

這篇文章最早是發在北極星論壇的一系列帖子,那時候聞怡洋 好像他也是mvp 也在那裡混 原始的帖子我已經沒有了,但不知道是誰幫我收集整理了下來 非常感謝 我用google找到了 這是我進金山之前寫的,應該不算洩露公司技術秘密吧 而且這些現在看來似乎已經有些過時了 那時討論的只是win31和win9x下...

如何用金山詞霸滑鼠取詞某些PDF文件

在安裝 金山詞霸 時,如果你的電腦中已經安裝acrobat reader的話,安裝程式會自動把外掛程式安裝好。如果是在安裝金山詞霸後安裝的acrobat reader或adobe acrobat 標準版及專業版,那麼需要根據版本分別採取措施,如下 1 acrobat reader 英文版取詞 版本相...