螢幕上的文字大都是由gdi32.dll的以下幾個函式顯示的:textouta、textoutw、exttextouta、 exttextoutw。實現螢幕抓詞的關鍵就是截獲對這些函式的呼叫,得到程式發給它們的引數。
我的方法有以下三個步驟:
一、得到滑鼠的當前位置
通過setwindowshookex實現。
二、向滑鼠下的視窗發重畫訊息,讓它呼叫系統函式重畫
通過windowfrompoint,screentoclient,invalidaterect 實現。
三、截獲對系統函式的呼叫,取得引數(以textouta為例)
1.仿照textouta作成自己的函式mytextouta,與textouta有相同引數和返回
值,放在系統鉤子所在
的dll裡。
sysfunc1=(dword)getprocaddress(getmodulehandle( /"gdi32.dll/"),/"texto
uta/");
bool winapi mytextouta(hdc hdc, int nxstart, int nystart, lpcstr l
pszstring,int cbstring)
2.由於系統滑鼠鉤子已經完成注入其它gui程序的工作,我們不需要為注入再
做工作。
如果你知道所有系統鉤子的函式必須要在動態庫里,就不會對「注入」感到
奇怪。當程序隱式或顯式
呼叫乙個動態庫里的函式時,系統都要把這個動態庫對映到這個程序的虛擬位址
空間裡(以下簡稱「位址空
間」)。這使得dll成為程序的一部分,以這個程序的身份執行,使用這個程序的
堆疊(見圖1)。
圖1 dll對映到虛擬位址空間中
對系統鉤子來說,系統自動將包含「鉤子**函式」的dll對映到受鉤子函式
影響的所有程序的位址
空間中,即將這個dll注入了那些程序。
3.當包含鉤子的dll注入其它程序後,尋找對映到這個程序虛擬記憶體裡的各個
模組(exe和dll)的
基位址。exe和dll被對映到虛擬記憶體空間的什麼地方是由它們的基位址決定的。
0x00400000。可以通
0處,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—
deor陣列,
看是否引入了gdi32.dll。如是,則窮舉image—thunk—data陣列,看是否引入了
textouta函式。
5.如果找到,將其替換為相應的自己的函式。
系統將exe和dll原封不動對映到虛擬記憶體空間中,它們在記憶體中的結構與磁
盤上的靜態檔案結構
是一樣的。即pe (portable executable) 檔案格式。
所有對給定api函式的呼叫總是通過可執行檔案的同乙個地方轉移。那就是一
個模組(可以是exe或
dll)的輸入位址表(import address table)。那裡有所有本模組呼叫的其它dll的
函式名及位址。對其它dll
的函式呼叫實際上只是跳轉到輸入位址表,由輸入位址表再跳轉到dll真正的函式
入口。例如:
圖2 對messagebox()的呼叫跳轉到輸入位址表,從輸入位址表再跳轉到mess
agebox函式
image—import—deor和image—thunk—data分別對應於dll和函式。
它們是pe
檔案的輸入位址表的格式(資料結構參見winnt.h)。
bool changefuncentry(hmodule hmodule)
else
pthunk++; } return 1;}}}
替換了輸入位址表中textouta的入口為mytextouta後,截獲系統函式呼叫的
主要部分已經完成,當
乙個被注入程序呼叫textouta時,其實呼叫的是mytextouta,只需在mytextouta
中顯示傳進來的字元
串,再交給textouta處理即可。
VC實現螢幕截詞功能的方法詳解
vc程式設計中螢幕上的文字大都是由gdi32.dll的以下幾個函式顯示的 textouta textoutw exttextouta exttextoutw。實現螢幕抓詞的關鍵就是截獲對這些函式的呼叫,得到程式發給它們的引數。實現的方法有以下三個步驟 一 得到滑鼠的當前位置 通過setwindows...
VC無閃爍刷屏技術的實現
1.顯示的圖形為什麼會閃爍 我們的繪圖過程大多放在ondraw或者onpaint函式中,ondraw在進行螢幕顯示時是由onpaint進行呼叫的。當視窗由於任何原因需要重繪時,總是先用背景色將顯示區清除,然後才呼叫onpaint,而背景色往往與繪圖內容反差很大,這樣在短時間內背景色與顯示圖形的交替出...
VC無閃爍刷屏技術的實現
我們的繪圖過程大多放在ondraw或者onpaint函式中,ondraw在進行螢幕顯示時是由onpaint進行呼叫的。當視窗由於任何原因需要重繪時,總是先用背景色將顯示區清除,然後才呼叫onpaint,而背景色往往與繪圖內容反差很大,這樣在短時間內背景色與顯示圖形的交替出現,使得顯示視窗看起來在閃。...