青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

君子性非異也,善假于物也。

如有恒,何須三更起,半夜眠;最怕莫,三天打魚兩天曬網,竹籃打水一場空!
posts - 31, comments - 23, trackbacks - 0, articles - 30
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

[轉]鼠標屏幕取詞技術的原理和實現

Posted on 2006-10-02 20:39 neter 閱讀(689) 評論(0)  編輯 收藏 引用 所屬分類: 程序設計
“鼠標屏幕取詞”技術是在電子字典中得到廣泛地應用的,如四通利方和金山詞霸等軟件,這個技術看似簡單,其實在WINDOWS系統中實現卻是非常復雜的,總的來說有兩種實現方式:
??? 第一種:采用截獲對部分GDI的API調用來實現,如TextOut,TextOutA等。
??? 第二種:對每個設備上下文(DC)做一分Copy,并跟蹤所有修改上下文(DC)的操作。?????
??? 第二種方法更強大,但兼容性不好,而第一種方法使用的截獲WindowsAPI的調用,這項技術的強大可能遠遠超出了您的想象,毫不夸張的說,利用WindowsAPI攔截技術,你可以改造整個操作系統,事實上很多外掛式Windows中文平臺就是這么實現的!而這項技術也正是這篇文章的主題。
??? 截WindowsAPI的調用,具體的說來也可以分為兩種方法:
??? 第一種方法通過直接改寫WinAPI 在內存中的映像,嵌入匯編代碼,使之被調用時跳轉到指定的地址運行來截獲;第二種方法則改寫IAT(Import Address Table 輸入地址表),重定向WinAPI函數的調用來實現對WinAPI的截獲。
??? 第一種方法的實現較為繁瑣,而且在Win95、98下面更有難度,這是因為雖然微軟說WIN16的API只是為了兼容性才保留下來,程序員應該盡可能地調用32位的API,實際上根本就不是這樣!WIN 9X內部的大部分32位API經過變換調用了同名的16位API,也就是說我們需要在攔截的函數中嵌入16位匯編代碼!
??? 我們將要介紹的是第二種攔截方法,這種方法在Win95、98和NT下面運行都比較穩定,兼容性較好。由于需要用到關于Windows虛擬內存的管理、打破進程邊界墻、向應用程序的進程空間中注入代碼、PE(Portable Executable)文件格式和IAT(輸入地址表)等較底層的知識,所以我們先對涉及到的這些知識大概地做一個介紹,最后會給出攔截部分的關鍵代碼。
????? 先說Windows虛擬內存的管理。Windows9X給每一個進程分配了4GB的地址空間,對于NT來說,這個數字是2GB,系統保留了2GB到 4GB之間的地址空間禁止進程訪問,而在Win9X中,2GB到4GB這部分虛擬地址空間實際上是由所有的WIN32進程所共享的,這部分地址空間加載了共享Win32 DLL、內存映射文件和VXD、內存管理器和文件系統碼,Win9X中這部分對于每一個進程都是可見的,這也是Win9X操作系統不夠健壯的原因。Win9X中為16位操作系統保留了0到4MB的地址空間,而在4MB到2GB之間也就是Win32進程私有的地址空間,由于 每個進程的地址空間都是相對獨立的,也就是說,如果程序想截獲其它進程中的API調用,就必須打破進程邊界墻,向其它的進程中注入截獲API調用的代碼,這項工作我們交給鉤子函數(SetWindowsHookEx)來完成,關于如何創建一個包含系統鉤子的動態鏈接庫,《電腦高手雜志》在第?期已經有過專題介紹了,這里就不贅述了。所有系統鉤子的函數必須要在動態庫里,這樣的話,當進程隱式或顯式調用一個動態庫里的函數時,系統會把這個動態庫映射到這個進程的虛擬地址空間里,這使得DLL成為進程的一部分,以這個進程的身份執行,使用這個進程的堆棧,也就是說動態鏈接庫中的代碼被鉤子函數注入了其它GUI進程的地址空間(非GUI進程,鉤子函數就無能為力了),
當包含鉤子的DLL注入其它進程后,就可以取得映射到這個進程虛擬內存里的各個模塊(EXE和DLL)的基地址,如:
HMODULE hmodule=GetModuleHandle(“Mypro.exe”);
在MFC程序中,我們可以用AfxGetInstanceHandle()函數來得到模塊的基地址。EXE和DLL被映射到虛擬內存空間的什么地方是由它們的基地址決定的。它們的基地址是在鏈接時由鏈接器決定的。當你新建一個Win32工程時,VC++鏈接器使用缺省的基地址0x00400000。可以通過鏈接器的BASE選項改變模塊的基地址。EXE通常被映射到虛擬內存的0x00400000處,DLL也隨之有不同的基地址,通常被映射到不同進程
的相同的虛擬地址空間處。
系統將EXE和DLL原封不動映射到虛擬內存空間中,它們在內存中的結構與磁盤上的靜態文件結構是一樣的。即PE (Portable Executable) 文件格式。我們得到了進程模塊的基地址以后,就可以根據PE文件的格式窮舉這個模塊的IMAGE_IMPORT_DESCRIPTOR數組,看看進程空間中是否引入了我們需要截獲的函數所在的動態鏈接庫,比如需要截獲“TextOutA”,就必須檢查“Gdi32.dll”是否被引入了。說到這里,我們有必要介紹一下PE文件的格式,如右圖,這是PE文件格式的大致框圖,最前面是文件頭,我們不必理會,從PE File Optional Header后面開始,就是文件中各個段的說明,說明后面才是真正的段數據,而實際上我們關心的只有一個段,那就是“.idata”段,這個段中包含了所有的引入函數信息,還有IAT(Import Address Table)的RVA(Relative Virtual Address)地址。
說到這里,截獲WindowsAPI的整個原理就要真相大白了。實際上所有進程對給定的API函數的調用總是通過PE文件的一個地方來轉移的,這就是一個該模塊(可以是EXE或DLL)的“.idata”段中的IAT輸入地址表(Import Address Table)。在那里有所有本模塊調用的其它DLL的函數名及地址。對其它DLL的函數調用實際上只是跳轉到輸入地址表,由輸入地址表再跳轉到DLL真正的函數入口。

具體來說,我們將通過IMAGE_IMPORT_DESCRIPTOR數組來訪問“.idata”段中引入的DLL的信息,然后通過IMAGE_THUNK_DATA數組來針對一個被引入的DLL訪問該DLL中被引入的每個函數的信息,找到我們需要截獲的函數的跳轉地址,然后改成我們自己的函數的地址……具體的做法在后面的關鍵代碼中會有詳細的講解。
?? 講了這么多原理,現在讓我們回到“鼠標屏幕取詞”的專題上來。除了API函數的截獲,要實現“鼠標屏幕取詞”,還需要做一些其它的工作,簡單的說來,可以把一個完整的取詞過程歸納成以下幾個步驟:
1. 安裝鼠標鉤子,通過鉤子函數獲得鼠標消息。
使用到的API函數:SetWindowsHookEx
2. 得到鼠標的當前位置,向鼠標下的窗口發重畫消息,讓它調用系統函數重畫窗口。
???? 使用到的API函數:WindowFromPoint,ScreenToClient,InvalidateRect
3. 截獲對系統函數的調用,取得參數,也就是我們要取的詞。
對于大多數的Windows應用程序來說,如果要取詞,我們需要截獲的是“Gdi32.dll”中的“TextOutA”函數。
我們先仿照TextOutA函數寫一個自己的MyTextOutA函數,如:
BOOL WINAPI MyTextOutA(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString,int cbString)
{
?????? // 這里進行輸出lpszString的處理
?????????? // 然后調用正版的TextOutA函數
}
把這個函數放在安裝了鉤子的動態連接庫中,然后調用我們最后給出的HookImportFunction函數來截獲進程
對TextOutA函數的調用,跳轉到我們的MyTextOutA函數,完成對輸出字符串的捕捉。HookImportFunction的
用法:
?HOOKFUNCDESC hd;
?PROC???????? pOrigFuns;
?hd.szFunc=TextOutA;
?hd.pProc=(PROC)MyTextOutA;
?HookImportFunction (AfxGetInstanceHandle(),gdi32.dll,&hd,pOrigFuns);
下面給出了HookImportFunction的源代碼,相信詳盡的注釋一定不會讓您覺得理解截獲到底是怎么實現的
很難,Ok,Let’s Go:

///////////////////////////////////////////// Begin ///////////////////////////////////////////////////////////////
#include <crtdbg.h>

// 這里定義了一個產生指針的宏
#define MakePtr(cast, ptr, AddValue) (cast)((DWORD)(ptr)+(DWORD)(AddValue))

// 定義了HOOKFUNCDESC結構,我們用這個結構作為參數傳給HookImportFunction函數
typedef struct tag_HOOKFUNCDESC
{
? LPCSTR szFunc; // The name of the function to hook.
? PROC pProc;??? // The procedure to blast in.
} HOOKFUNCDESC , * LPHOOKFUNCDESC;

// 這個函數監測當前系統是否是WindowNT
BOOL IsNT();

// 這個函數得到hModule -- 即我們需要截獲的函數所在的DLL模塊的引入描述符(import descriptor)
PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportModule);

// 我們的主函數
BOOL HookImportFunction(HMODULE hModule, LPCSTR szImportModule,
???????????????????????? LPHOOKFUNCDESC paHookFunc, PROC* paOrigFuncs)
{
/////////////////////// 下面的代碼檢測參數的有效性 ////////////////////////////
?_ASSERT(szImportModule);
?_ASSERT(!IsBadReadPtr(paHookFunc, sizeof(HOOKFUNCDESC)));
#ifdef _DEBUG
?if (paOrigFuncs) _ASSERT(!IsBadWritePtr(paOrigFuncs, sizeof(PROC)));
?_ASSERT(paHookFunc.szFunc);
?_ASSERT(*paHookFunc.szFunc != \0);
??????? _ASSERT(!IsBadCodePtr(paHookFunc.pProc));
#endif
?if ((szImportModule == NULL) || (IsBadReadPtr(paHookFunc, sizeof(HOOKFUNCDESC))))
?{
??_ASSERT(FALSE);
??SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
??return FALSE;
?}
//////////////////////////////////////////////////////////////////////////////

?// 監測當前模塊是否是在2GB虛擬內存空間之上
?// 這部分的地址內存是屬于Win32進程共享的
?if (!IsNT() && ((DWORD)hModule >= 0x80000000))
?{
??_ASSERT(FALSE);
??SetLastErrorEx(ERROR_INVALID_HANDLE, SLE_ERROR);
??return FALSE;
?}
??? ?// 清零
?if (paOrigFuncs) memset(paOrigFuncs, NULL, sizeof(PROC));

?// 調用GetNamedImportDescriptor()函數,來得到hModule -- 即我們需要
?// 截獲的函數所在的DLL模塊的引入描述符(import descriptor)
?PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetNamedImportDescriptor(hModule, szImportModule);
?if (pImportDesc == NULL)
?return FALSE; // 若為空,則模塊未被當前進程所引入

?//? 從DLL模塊中得到原始的THUNK信息,因為pImportDesc->FirstThunk數組中的原始信息已經
?//? 在應用程序引入該DLL時覆蓋上了所有的引入信息,所以我們需要通過取得pImportDesc->OriginalFirstThunk
?//? 指針來訪問引入函數名等信息
?PIMAGE_THUNK_DATA pOrigThunk = MakePtr(PIMAGE_THUNK_DATA, hModule,
?????????????????????????????????????????????? pImportDesc->OriginalFirstThunk);

?//? 從pImportDesc->FirstThunk得到IMAGE_THUNK_DATA數組的指針,由于這里在DLL被引入時已經填充了
?//? 所有的引入信息,所以真正的截獲實際上正是在這里進行的
?PIMAGE_THUNK_DATA pRealThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->FirstThunk);

?//? 窮舉IMAGE_THUNK_DATA數組,尋找我們需要截獲的函數,這是最關鍵的部分!
?while (pOrigThunk->u1.Function)
?{
??// 只尋找那些按函數名而不是序號引入的函數
??if (IMAGE_ORDINAL_FLAG != (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG))
??{
???// 得到引入函數的函數名
???PIMAGE_IMPORT_BY_NAME pByName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule,
?????????????? pOrigThunk->u1.AddressOfData);

???// 如果函數名以NULL開始,跳過,繼續下一個函數??
???if (\0 == pByName->Name[0])
????continue;

???// bDoHook用來檢查是否截獲成功
???BOOL bDoHook = FALSE;

???// 檢查是否當前函數是我們需要截獲的函數
???if ((paHookFunc.szFunc[0] == pByName->Name[0]) &&
????(strcmpi(paHookFunc.szFunc, (char*)pByName->Name) == 0))
???{
????// 找到了!
????if (paHookFunc.pProc)
????bDoHook = TRUE;
???}
???if (bDoHook)
???{
????// 我們已經找到了所要截獲的函數,那么就開始動手吧
????// 首先要做的是改變這一塊虛擬內存的內存保護狀態,讓我們可以自由存取
????MEMORY_BASIC_INFORMATION mbi_thunk;
????VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
????_ASSERT(VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,
??????????????????????? PAGE_READWRITE, &mbi_thunk.Protect));

????// 保存我們所要截獲的函數的正確跳轉地址
????if (paOrigFuncs)
????? paOrigFuncs = (PROC)pRealThunk->u1.Function;

????// 將IMAGE_THUNK_DATA數組中的函數跳轉地址改寫為我們自己的函數地址!
????// 以后所有進程對這個系統函數的所有調用都將成為對我們自己編寫的函數的調用
????pRealThunk->u1.Function = (PDWORD)paHookFunc.pProc;

????// 操作完畢!將這一塊虛擬內存改回原來的保護狀態
????DWORD dwOldProtect;
????_ASSERT(VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,
??????????????????????? mbi_thunk.Protect, &dwOldProtect));
????SetLastError(ERROR_SUCCESS);
????return TRUE;
???}
??}
??// 訪問IMAGE_THUNK_DATA數組中的下一個元素
??pOrigThunk++;
??pRealThunk++;
?}
?return TRUE;
}

// GetNamedImportDescriptor函數的實現
PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportModule)
{
?// 檢測參數
?_ASSERT(szImportModule);
?_ASSERT(hModule);
?if ((szImportModule == NULL) || (hModule == NULL))
?{
??_ASSERT(FALSE);
??SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
??return NULL;
?}

?// 得到Dos文件頭
?PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER) hModule;

?// 檢測是否MZ文件頭
?if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)) ||
??(pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE))
?{
??_ASSERT(FALSE);
??SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
??return NULL;
?}

?// 取得PE文件頭
?PIMAGE_NT_HEADERS pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);

?// 檢測是否PE映像文件
?if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) ||
?? (pNTHeader->Signature != IMAGE_NT_SIGNATURE))
?{
??_ASSERT(FALSE);
??SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
??return NULL;
?}

?// 檢查PE文件的引入段(即 .idata section)
?if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
??return NULL;

?// 得到引入段(即 .idata section)的指針
?PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDOSHeader,
??pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

?// 窮舉PIMAGE_IMPORT_DESCRIPTOR數組尋找我們需要截獲的函數所在的模塊
?while (pImportDesc->Name)
?{
??PSTR szCurrMod = MakePtr(PSTR, pDOSHeader, pImportDesc->Name);
??if (stricmp(szCurrMod, szImportModule) == 0)
????? break; // 找到!中斷循環
??// 下一個元素
??pImportDesc++;
?}

?// 如果沒有找到,說明我們尋找的模塊沒有被當前的進程所引入!
?if (pImportDesc->Name == NULL)
??return NULL;

?// 返回函數所找到的模塊描述符(import descriptor)
?return pImportDesc;
}

// IsNT()函數的實現
BOOL IsNT()
{
?OSVERSIONINFO stOSVI;
?memset(&stOSVI, NULL, sizeof(OSVERSIONINFO));
?stOSVI.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
?BOOL bRet = GetVersionEx(&stOSVI);
?_ASSERT(TRUE == bRet);
?if (FALSE == bRet) return FALSE;
?return (VER_PLATFORM_WIN32_NT == stOSVI.dwPlatformId);
}
/////////////////////////////////////////////// End //////////////////////////////////////////////////////////////////////

?? 不知道在這篇文章問世之前,有多少朋友嘗試過去實現“鼠標屏幕取詞”這項充滿了挑戰的技術,也只有嘗試過的朋友才能體會到其間的不易,尤其在探索API函數的截獲時,手頭的幾篇資料沒有一篇是涉及到關鍵代碼的,重要的地方都是一筆代過,MSDN更是顯得蒼白而無力,也不知道除了IMAGE_IMPORT_DESCRIPTOR和IMAGE_THUNK_DATA,微軟還隱藏了多少秘密,好在硬著頭皮還是把它給攻克了,希望這篇文章對大家能有所幫助。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久www| 亚洲第一久久影院| 亚洲欧美日韩中文播放| 亚洲一区二区在线免费观看视频| 最新国产成人av网站网址麻豆| 亚洲欧美文学| 欧美在线免费视频| 男同欧美伦乱| 亚洲高清视频的网址| 日韩视频不卡中文| 亚洲永久精品大片| 久热精品视频在线免费观看| 欧美区国产区| 国产日韩av高清| 亚洲第一精品福利| 亚洲午夜91| 久久夜色精品| 夜夜狂射影院欧美极品| 欧美在线免费视频| 欧美精品一卡| 黄色亚洲在线| 久久视频在线视频| 欧美成人精精品一区二区频| 国产精品嫩草久久久久| 欧美韩国一区| 午夜精品福利视频| 麻豆成人综合网| 国产精品久久久久久福利一牛影视| 国产伦理精品不卡| 亚洲激情网址| 久久精品国产亚洲一区二区三区| 亚洲第一在线| 欧美专区日韩视频| 欧美午夜电影在线| 亚洲成人在线观看视频| 午夜国产一区| aa日韩免费精品视频一| 久久精品中文字幕免费mv| 欧美天堂亚洲电影院在线观看| 一区视频在线看| 亚洲欧美一区二区三区极速播放 | 欧美亚洲一级| 亚洲欧洲一区| 久久综合国产精品台湾中文娱乐网| 欧美三区视频| 99视频一区二区| 欧美激情一区二区| 久久精品在线观看| 国产欧美一区二区三区在线老狼| 亚洲免费观看高清完整版在线观看熊| 久久久久久国产精品mv| 一区二区三区视频在线看| 欧美福利一区| 亚洲国产精品毛片| 蜜桃av综合| 欧美中文字幕在线视频| 国产偷久久久精品专区| 亚洲欧美日韩一区二区三区在线| 亚洲精品一区二区三区樱花| 免费不卡中文字幕视频| 亚洲国产另类久久精品| 另类图片国产| 老司机免费视频一区二区| 国产一区二区三区直播精品电影| 久久久久久久久久看片| 欧美一区二区私人影院日本 | 中日韩视频在线观看| 欧美日韩国产一区二区三区地区 | 亚洲毛片在线观看| 欧美激情亚洲| 欧美日本二区| 亚洲综合999| 亚洲深夜福利在线| 国产精品亚洲综合一区在线观看 | 香蕉亚洲视频| 国产一区二区三区最好精华液| 欧美在线视频观看免费网站| 午夜精品久久久| 亚洲一区二区在线免费观看| 午夜性色一区二区三区免费视频| 亚洲欧洲一区二区三区| 一区二区三区在线观看国产| 久久婷婷蜜乳一本欲蜜臀| 久久av资源网| 亚洲国产精品久久久久秋霞不卡| 欧美福利视频在线| 欧美激情一区二区三区| 亚洲视频欧美视频| 亚洲欧美卡通另类91av| 国产偷自视频区视频一区二区| 女人天堂亚洲aⅴ在线观看| 久久一本综合频道| 日韩视频精品| 小嫩嫩精品导航| 91久久亚洲| 亚洲尤物视频在线| 黄色资源网久久资源365| 亚洲国产欧洲综合997久久| 国产精品国产| 女同一区二区| 欧美性做爰猛烈叫床潮| 欧美成人免费播放| 国产精品vip| 可以免费看不卡的av网站| 欧美人与性动交a欧美精品| 久久精品免费电影| 欧美精品97| 麻豆精品视频在线| 欧美日韩综合网| 欧美r片在线| 国产毛片精品国产一区二区三区| 亚洲国产另类 国产精品国产免费| 国产精品色婷婷| 亚洲精品乱码久久久久久| 国内精品久久国产| 一区二区激情小说| 91久久久精品| 久久久久国产精品麻豆ai换脸| 一区二区日韩精品| 久久成人18免费观看| 亚洲一区二区在线看| 免费高清在线视频一区·| 性娇小13――14欧美| 欧美精品自拍偷拍动漫精品| 美女黄色成人网| 国产亚洲成精品久久| 亚洲在线黄色| 亚洲天堂av电影| 欧美好骚综合网| 亚洲高清久久| 亚洲高清一区二| 一区二区三区自拍| 欧美综合77777色婷婷| 99视频一区| 欧美日韩福利在线观看| 激情综合电影网| 亚洲一区二区三区在线| 亚洲天堂网在线观看| 欧美了一区在线观看| 亚洲国产高清高潮精品美女| 最新亚洲一区| 免费影视亚洲| 欧美成人免费一级人片100| 在线看欧美视频| 久久一二三四| 女同性一区二区三区人了人一| 尤物精品国产第一福利三区 | 国产一区二区三区久久悠悠色av| 亚洲性线免费观看视频成熟| 亚洲视频在线观看网站| 欧美日韩国产美女| 日韩一本二本av| 午夜在线一区二区| 国产精品女主播| 午夜精品久久久久久久蜜桃app| 欧美一区二区私人影院日本| 国产欧美一区二区三区视频| 欧美一区二区| 欧美xx视频| 亚洲精品在线观看视频| 欧美日韩欧美一区二区| 亚洲尤物视频在线| 久久人人97超碰人人澡爱香蕉| 韩国av一区二区三区四区| 久久乐国产精品| 亚洲精品在线观看免费| 亚洲欧美三级伦理| 伊人色综合久久天天| 欧美成人午夜影院| 在线视频精品| 麻豆精品精华液| 亚洲欧美日韩国产中文| 国产一区日韩一区| 欧美国产日韩一二三区| 亚洲午夜精品久久| 久久综合伊人77777| 洋洋av久久久久久久一区| 国产精品久久久久av免费| 久久精品123| 亚洲欧洲日产国码二区| 久久国产成人| 亚洲精品一区二区三区婷婷月| 国产精品美女黄网| 蜜桃久久av| 亚洲免费在线电影| 亚洲电影毛片| 久久久久久亚洲精品杨幂换脸| 亚洲精品1区2区| 国产精品久久一级| 鲁大师成人一区二区三区| 亚洲午夜在线观看| 亚洲大片免费看| 久久久免费精品| 亚洲女同精品视频| 亚洲日韩第九十九页| 国模精品一区二区三区| 国产精品福利在线观看| 欧美日韩成人综合在线一区二区| 久久视频在线视频| 欧美一区二区黄|