最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

VC實現(xiàn)屏幕截詞功能的方法詳解

 更新時間:2014年07月16日 17:44:03   投稿:shichen2014  
這篇文章主要介紹了VC實現(xiàn)屏幕截詞功能的方法詳解,對于深入的理解windows程序運行原理很有幫助,需要的朋友可以參考下

VC程序設計中屏幕上的文字大都是由gdi32.dll的以下幾個函數顯示的:TextOutA、TextOutW、ExtTextOutA、ExtTextOutW。實現(xiàn)屏幕抓詞的關鍵就是截獲對這些函數的調用,得到程序發(fā)給它們的參數。

實現(xiàn)的方法有以下三個步驟:

一、得到鼠標的當前位置
通過SetWindowsHookEx實現(xiàn)。

二、向鼠標下的窗口發(fā)重畫消息,讓它調用系統(tǒng)函數重畫
通過WindowFromPoint,ScreenToClient,InvalidateRect 實現(xiàn)。

三、截獲對系統(tǒng)函數的調用,取得參數(以TextOutA為例)

1.仿照TextOutA作成自己的函數MyTextOutA,與TextOutA有相同參數和返回值,放在系統(tǒng)鉤子所在的DLL里。

SysFunc1=(DWORD)GetProcAddress(GetModuleHandle("gdi32.dll"),"TextOutA");
BOOL WINAPI MyTextOutA(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString,int cbString)
{ //輸出lpszString的處理
return ((FARPROC)SysFunc1)(hdc,nXStart,nYStart,lpszString,cbString);
}

2.由于系統(tǒng)鼠標鉤子已經完成注入其它GUI進程的工作,我們不需要為注入再做工作。
如果你知道所有系統(tǒng)鉤子的函數必須要在動態(tài)庫里,就不會對"注入"感到奇怪。當進程隱式或顯式調用一個動態(tài)庫里的函數時,系統(tǒng)都要把這個動態(tài)庫映射到這個進程的虛擬地址空間里(以下簡稱"地址空間")。這使得DLL成為進程的一部分,以這個進程的身份執(zhí)行,使用這個進程的堆棧。

DLL映射到虛擬地址空間中

對系統(tǒng)鉤子來說,系統(tǒng)自動將包含"鉤子回調函數"的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,我們可以通過如下方式得以實現(xiàn):

while(VirtualQuery (base, &mbi, sizeof (mbi))>0)
{
if(mbi.Type==MEM-IMAGE)
ChangeFuncEntry((DWORD)mbi.BaseAddress,1);
base=(DWORD)mbi.BaseAddress+mbi.RegionSize;
}

4.得到模塊的基地址后,根據PE文件的格式窮舉這個模塊的IMAGE-IMPORT-DESCRIPTOR數組,看是否引入了gdi32.dll。如是,則窮舉IMAGE-THUNK-DATA數組,看是否引入了TextOutA函數。

5.如果找到,將其替換為相應的自己的函數。
系統(tǒng)將EXE和DLL原封不動映射到虛擬內存空間中,它們在內存中的結構與磁盤上的靜態(tài)文件結構是一樣的。即PE (Portable Executable) 文件格式。
所有對給定API函數的調用總是通過可執(zhí)行文件的同一個地方轉移。那就是一個模塊(可以是EXE或DLL)的輸入地址表(import address table)。那里有所有本模塊調用的其它DLL的函數名及地址。對其它DLL的函數調用實際上只是跳轉到輸入地址表,由輸入地址表再跳轉到DLL真正的函數入口。例如:

對MessageBox()的調用跳轉到輸入地址表,從輸入地址表再跳轉到MessageBox函數

IMAGE-IMPORT-DESCRIPTOR和IMAGE-THUNK-DATA分別對應于DLL和函數。它們是PE文件的輸入地址表的格式(數據結構參見winnt.h)。

BOOL ChangeFuncEntry(HMODULE hmodule)
{
PIMAGE-DOS-HEADER pDOSHeader;
PIMAGE-NT-HEADERS pNTHeader;
PIMAGE-IMPORT-DESCRIPTOR pImportDesc;
/ get system functions and my functions′entry /
pSysFunc1=(DWORD)GetProcAddress(GetModuleHandle("gdi32.dll"),"TextOutA");
pMyFunc1= (DWORD)GetProcAddress(GetModuleHandle("hookdll.dll"),"MyTextOutA");
pDOSHeader=(PIMAGE-DOS-HEADER)hmodule;
if (IsBadReadPtr(hmodule, sizeof(PIMAGE-NT-HEADERS)))
return FALSE;
if (pDOSHeader->e-magic != IMAGE-DOS-SIGNATURE)
return FALSE;
pNTHeader=(PIMAGE-NT-HEADERS)((DWORD)pDOSHeader+(DWORD)pDOSHeader->e-lfanew);
if (pNTHeader->Signature != IMAGE-NT-SIGNATURE)
return FALSE;
pImportDesc = (PIMAGE-IMPORT-DESCRIPTOR)((DWORD)hmodule+(DWORD)pNTHeader->OptionalHeader.DataDirectory[IMAGE-DIRECTORY-ENTRY-IMPORT].VirtualAddress);
if (pImportDesc == (PIMAGE-IMPORT-DESCRIPTOR)pNTHeader)
return FALSE;
while (pImportDesc->Name)
{
PIMAGE-THUNK-DATA pThunk;
strcpy(buffer,(char )((DWORD)hmodule+(DWORD)pImportDesc->Name));
CharLower(buffer);
if(strcmp(buffer,"gdi32.dll"))
{
pImportDesc++;
continue;
}else{
pThunk=(PIMAGE-THUNK-DATA)((DWORD)hmodule+(DWORD)pImportDesc->FirstThunk);
while (pThunk->u1.Function)
{ 
if ((pThunk->u1.Function) == pSysFunc1)
{ 
VirtualProtect((LPVOID)(&pThunk->u1.Function),
sizeof(DWORD),PAGE-EXECUTE-READWRITE,&dwProtect);
(pThunk->u1.Function)=pMyFunc1;
VirtualProtect((LPVOID)(&pThunk->u1.Function), sizeof(DWORD),dwProtect,&temp);
}
pThunk++; 
} 
return 1;
}
}
}

替換了輸入地址表中TextOutA的入口為MyTextOutA后,截獲系統(tǒng)函數調用的主要部分已經完成,當一個被注入進程調用TextOutA時,其實調用的是MyTextOutA,只需在MyTextOutA中顯示傳進來的字符串,再交給TextOutA處理即可。

相關文章

  • C語言課程設計之停車場管理問題

    C語言課程設計之停車場管理問題

    這篇文章主要為大家詳細介紹了C語言課程設計之停車場管理問題,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • StretchBlt函數和BitBlt函數用法案例詳解

    StretchBlt函數和BitBlt函數用法案例詳解

    這篇文章主要介紹了StretchBlt函數和BitBlt函數用法案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • C++ std::function的用法詳解

    C++ std::function的用法詳解

    這篇文章主要介紹了C++ std::function使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-10-10
  • C++實現(xiàn)添加桌面右鍵新建菜單

    C++實現(xiàn)添加桌面右鍵新建菜單

    本文給大家匯總了3個版本的C++實現(xiàn)添加桌面右鍵新建菜單的代碼,陸陸續(xù)續(xù)寫的,有需要的小伙伴可以根據自己的需求來選擇
    2016-01-01
  • 用C語言實現(xiàn)一個掃雷小游戲

    用C語言實現(xiàn)一個掃雷小游戲

    這篇文章主要為大家詳細介紹了用C語言實現(xiàn)一個掃雷小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C 語言基礎教程(我的C之旅開始了)[二]

    C 語言基礎教程(我的C之旅開始了)[二]

    C 語言基礎教程(我的C之旅開始了)[二]...
    2007-02-02
  • C語言循環(huán)隊列的表示與實現(xiàn)實例詳解

    C語言循環(huán)隊列的表示與實現(xiàn)實例詳解

    這篇文章主要介紹了C語言循環(huán)隊列的表示與實現(xiàn),對于數據結構與算法的研究很有幫助,需要的朋友可以參考下
    2014-07-07
  • C++三色球問題描述與算法分析

    C++三色球問題描述與算法分析

    這篇文章主要介紹了C++三色球問題描述與算法分析,結合注釋形式詳細講述了三色球問題的描述與相應的算法設計思路,并給出了相關的實現(xiàn)方法,需要的朋友可以參考下
    2016-05-05
  • C語言分支和循環(huán)詳解

    C語言分支和循環(huán)詳解

    C語言是一門結構化的程序設計語言,當C語言用來描述生活中的事物時,會用到三種結構:順序結構(不去贅述),選擇結構(對應分支語句),循環(huán)結構(對應循環(huán)語句),分支語句:分支語句分為兩種,一種是if語句,一種是switch語句
    2021-10-10
  • C基礎 尋找隨機函數的G點詳解

    C基礎 尋找隨機函數的G點詳解

    下面小編就為大家?guī)硪黄狢基礎 尋找隨機函數的G點詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06

最新評論

旬邑县| 榆社县| 揭西县| 福建省| 鹤峰县| 房产| 黑水县| 潞城市| 黄冈市| 泸州市| 凉山| 阿克| 敦煌市| 唐山市| 千阳县| 同德县| 甘泉县| 达州市| 高要市| 阳山县| 铜陵市| 东乌| 长治县| 廉江市| 方城县| 安丘市| 临夏市| 澄迈县| 会昌县| 兰州市| 永善县| 武隆县| 孟连| 老河口市| 泽州县| 岑溪市| 长泰县| 万宁市| 申扎县| 酒泉市| 新和县|