日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

浅谈Windows API编程 (这个经典)

發布時間:2023/12/20 windows 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈Windows API编程 (这个经典) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

WinSDK是編程中的傳統難點,個人寫的WinAPI程序也不少了,其實之所以難就難在每個調用的API都包含著Windows這個操作系統的潛規則或者是windows內部的運行機制……

WinSDK是編程中的傳統難點,曾經聽有一個技術不是很好的朋友亂說什么給你API誰都會用,其實并非那么簡單,個人寫的WinAPI程序也不少了,其實之所以難就難在每個調用的API都包含著Windows這個操作系統的潛規則或者是windows內部的運行機制。

首先來談談句柄,初學習WinSDK的朋友剛看到這個詞頭大了吧?其實我也是了,我們來看看programming windows里面是怎么說的,一個句柄僅僅是用來識別某些事情的數字。它唯一的標識這當前的一個實例。這樣說確實不容易懂。那么我們這么看,比如你打開 windows自帶的計算器。你多打開幾次是不是桌面上出現了很多個計算器呢?你使用其中一個計算器的時候當你按下等于按鈕的時候運算結果是否會出現在其他的計算機結果欄里?不會,那windows怎么知道讓結果出現在哪里呢?這就是句柄的作用了,句柄唯一的標識著一個程序,你打開的每一個窗口(計算器) 都有一個不同的句柄你你每一步操作都是指定了在某個句柄下的,所以,他不會出錯。而且你打開的每一個計算機都共享著同樣的代碼和內存。通過句柄系統會把所需的資源充分的調用到當前的某個程序自己的數據區。

不僅是窗口,各種菜單,GDI對象都有自己的句柄,獲取句柄的手段也是多重多樣,不過當然是通過調用API函數實現了,如:

MFC中的hHandle = GetSafeHandle();

API編程中的hBrush = GetStorkObject(BLACK_BRUSH);

很多操作都需要將句柄添加到參數列表中,當你沒有直接定義句柄變量的時候可能要記憶很多API的返回類型來間接獲取。如:

??????hPen = SelectObject(hdc,GetStockObject(&logicpen));
? ? ? // SelectObject()這個函數在設置本設備描述表下的GDI對象時會返回設置前的GDI對象句柄
? ? ?MoveToEx(hdc, pt1.x, pt1.y, &apt);
? ? ?LineTo(hdc, pt2.x,pt2.y);
? ? ?SelectObject(hdc,hPen);

完成選擇自定義的GDI對象的操作。句柄的種類很多,掌握一種的使用方法所有的不學自通,WinAPI編程永遠伴隨的元素中句柄是其中之一。非常重要。由于是淺談,所以就說到這里了.

接下來是windows下的消息映射機制了,呵呵,窗口過程,剛學的朋友難理解吧?WinSDK編程基于C,但是和C的理念有著完全的不同,這中間的不同,在我看來最多的也就是來自于這個消息映射,后面什么吹的很炫的Hook技術,木馬技術,鍵盤截獲,都是來自于特殊消息的捕捉,映射自定義的特殊消息來實現的(當然和我接下來談的稍微有點不同)。

首先我們應該先明白消息和事件的區別,Windows是消息驅動的操作系統,這里的消息的產生來自于某個實例化的對象上用戶的操作,來自控件,菜單,或者是系統本身產生的,而事件是靠消息觸發的,但這也不是絕對的。可以用一個簡單的例子去解釋,我這里越寫越覺得自己難表達清楚,就比如這么一個例子:“某男殺人這條消息導致被槍斃這個事件”不過最重要的區別是在消息產生后并不會被直接處理,而是先插入windows系統的消息隊列,然后系統判斷此消息產生于哪個程序,送入此程序的消息循環,由LRSULT CALLBACK winprc(hwnd , uint,wParam,lParam)處理。而事件是操作系統處理消息的過程中反饋的結果。

用戶操作-> 產生消息->發送系統->系統判斷來源->發給相應的窗口過程或者其他Callback函數->消息處理->等待下一條消息的產生

以上為消息循環整個過程。

?????

  • LRSULT CALLBACK winprc(hwnd , uint,wParam,lParam);
  • int WINAPI WinMain(…)
  • {
  • MSG msg;
  • RegisterClass(…); // 注冊窗口類
  • CreateWindow(…); // 創建窗口
  • ShowWindow(…); // 顯示窗口
  • UpdateWindow(…);
  • While(GetMessage(&msg,…)){ // 消息循環
  • TranslateMessage(…);
  • DispatchMessage(…);
  • }
  • }
  • LRSULT CALLBACK winprc(hwnd , uint,wParam,lParam);
  • //窗口過程函數,用于映射switch語句中各個需要被處理的消息
  • {
  • While((UINT)message)
  • {
  • Switch(message)
  • Case…
  • Case…
  • ………
  • Default……….
  • }
  • }


  • 以上是最基本的WinAPi編程的代碼結構。其實這里面最重要的結構莫過于while(GetMessage(&msg))和 Winproc這個函數,這也是傳統的C面向過程編程的區別,win編程總等著特定事件觸發對應的消息映射函數來完成代碼功能,并不是一條代碼從頭走到尾。關于特殊消息的映射,這里不談,這里僅是個入門指引。

    最后談一點就是重繪問題。其實在我看來這個東西更多是屬于GDI編程里面的東西,說起來其實難度不大,但是處理起來確實是個難點。先拿剛才的代碼來說吧。先添加一條關于WM_LBUTTONDOWN的消息映射:
    ?

  • Static int apt[2];
  • case WM_LBUTTONDOWN:
  • hdc = GetDC(hwnd);
  • apt[1].x = LOWORD (lParam);
  • apt[1].y = HIWORD (lParam);
  • hPen = CreatePen(BLACK_PEN,3,RGB(125,125,125));
  • SelectObject(hdc,hPen);
  • MoveToEx(hdc,apt[0].x,apt[0].y,NULL);
  • LineTo(hdc,apt[1].x,apt[1].y);
  • apt[0].x = apt[1].x;
  • apt[0].y = apt[1].y;
  • DeleteObject(hPen);
  • ReleaseDC(hwnd,hdc);
  • return 0;


  • 這段代碼實現一個簡單的畫線功能,當你在你的客戶區胡點一通鼠標后試著拖動一下窗口大小,或者將其最小化或者被其他窗口覆蓋一下你都會發現你原來畫的線沒了,可是其他窗口為什么被覆蓋了以后再彈出窗口還會有原來的東西呢?那就是重繪,要重新繪制整個客戶區(準確的說是失效的矩形),以上說的操作都會導致你的客戶區失效,這時會產生重繪消息WM_PAINT,我們要想保存這些線那么我們就必須保存這些你用鼠標左鍵點過的點。當然這是重繪技術中最簡單的,當你的客戶區上是一個復雜的畫面的話,就不僅僅需要保存點,還有各種形狀的圖形,顏色等等……這里給大家一段我自己寫的代碼來實現以上的 WM_LBUTTONDOWN消息映射來產生的點。通過單鏈表來動態添加點來實現重繪。

  • case WM_PAINT:
  • hdc = BeginPaint(hwnd,&ps);
  • TextOut(hdc,cxClient/6,cyClient/6,TEXT("圖形重繪"),strlen("圖形重繪"));
  • ReDrawLines(&MyList,hdc);
  • EndPaint(hwnd,&ps);
  • return 0;
  • case WM_LBUTTONDOWN:
  • hdc = GetDC(hwnd);
  • apt[1].x = LOWORD (lParam);
  • apt[1].y = HIWORD (lParam);
  • hPen = CreatePen(BLACK_PEN,2,RGB(125,0,0));
  • SelectObject(hdc,hPen);
  • MoveToEx(hdc,apt[0].x,apt[0].y,NULL);
  • LineTo(hdc,apt[1].x,apt[1].y);
  • MyList.pCurrent->x = apt[0].x;
  • MyList.pCurrent->y = apt[0].y;
  • MyList.pCurrent->pNext->x = apt[1].x;
  • MyList.pCurrent->pNext->y = apt[1].y;
  • MyList.m_iCounter = MyList.m_iCounter+2;
  • MyList.pCurrent = MyList.pCurrent->pNext->pNext;
  • apt[0].x = apt[1].x;
  • apt[0].y = apt[1].y;
  • DeleteObject(hPen);
  • ReleaseDC(hwnd,hdc);
  • return 0;


  • 其中的重繪函數代碼如下:

  • void ReDrawLines(LinkList* pLinkList,HDC hdc)
  • {
  • pMyPoint p = pLinkList->pHead;
  • int iSaver =pLinkList->m_iCounter;
  • while(iSaver!=0)
  • {
  • MoveToEx(hdc,p->x,p->y,NULL);
  • LineTo(hdc,p->pNext->x,p->pNext->y);
  • p=p->pNext->pNext;
  • iSaver=iSaver-2;
  • }
  • }


  • 添加了以上的代碼你會發現再次拖動窗口大小等等你原來畫的線就都能重現出來了。呵呵是不是覺得一個看似簡單的東西其實里面需要很多代碼實現呢?也許,這就是windows.

    好了,WinSDK入門的東西就談這么多,希望能給初學者一定的幫助,這么多的字,都是我一個一個打出來沒有任何借鑒和摘抄的。相信做為一個過來人能更多的理解大家學習中的困難。

    Win32環境下動態鏈接庫(DLL)編程原理

    比較大應用程序都由很多模塊組成,這些模塊分別完成相對獨立的功能,它們彼此協作來完成整個軟件系統的工作。其中可能存在一些模塊的功能較為通用,在構造其它軟件系統時仍會被使用。在構造軟件系統時,如果將所有模塊的源代碼都靜態編譯到整個應用程序EXE文件中,會產生一些問題:一個缺點是增加了應用程序的大小,它會占用更多的磁盤空間,程序運行時也會消耗較大的內存空間,造成系統資源的浪費;另一個缺點是,在編寫大的EXE程序時,在每次修改重建時都必須調整編譯所有源代碼,增加了編譯過程的復雜性,也不利于階段性的單元測試。

    Windows系統平臺上提供了一種完全不同的較有效的編程和運行環境,你可以將獨立的程序模塊創建為較小的DLL(Dynamic Linkable Library)文件,并可對它們單獨編譯和測試。在運行時,只有當EXE程序確實要調用這些DLL模塊的情況下,系統才會將它們裝載到內存空間中。這種方式不僅減少了EXE文件的大小和對內存空間的需求,而且使這些DLL模塊可以同時被多個應用程序使用。Microsoft Windows自己就將一些主要的系統功能以DLL模塊的形式實現。例如IE中的一些基本功能就是由DLL文件實現的,它可以被其它應用程序調用和集成。

    一般來說,DLL是一種磁盤文件(通常帶有DLL擴展名),它由全局數據、服務函數和資源組成,在運行時被系統加載到進程的虛擬空間中,成為調用進程的一部分。如果與其它DLL之間沒有沖突,該文件通常映射到進程虛擬空間的同一地址上。DLL模塊中包含各種導出函數,用于向外界提供服務。Windows 在加載DLL模塊時將進程函數調用與DLL文件的導出函數相匹配。

    在Win32環境中,每個進程都復制了自己的讀/寫全局變量。如果想要與其它進程共享內存,必須使用內存映射文件或者聲明一個共享數據段。DLL模塊需要的堆棧內存都是從運行進程的堆棧中分配出來的。

    DLL現在越來越容易編寫。Win32已經大大簡化了其編程模式,并有許多來自AppWizard和MFC類庫的支持。


    一、導出和導入函數的匹配

    DLL文件中包含一個導出函數表。這些導出函數由它們的符號名和稱為標識號的整數與外界聯系起來。函數表中還包含了DLL中函數的地址。當應用程序加載 DLL模塊時時,它并不知道調用函數的實際地址,但它知道函數的符號名和標識號。動態鏈接過程在加載的DLL模塊時動態建立一個函數調用與函數地址的對應表。如果重新編譯和重建DLL文件,并不需要修改應用程序,除非你改變了導出函數的符號名和參數序列。

    簡單的DLL文件只為應用程序提供導出函數,比較復雜的DLL文件除了提供導出函數以外,還調用其它DLL文件中的函數。這樣,一個特殊的DLL可以既有導入函數,又有導入函數。這并不是一個問題,因為動態鏈接過程可以處理交叉相關的情況。

    在DLL代碼中,必須像下面這樣明確聲明導出函數:

    __declspec(dllexport) int MyFunction(int n);

    但也可以在模塊定義(DEF)文件中列出導出函數,不過這樣做常常引起更多的麻煩。在應用程序方面,要求像下面這樣明確聲明相應的輸入函數:

    __declspec(dllimport) int MyFuncition(int n);

    僅有導入和導出聲明并不能使應用程序內部的函數調用鏈接到相應的DLL文件上。應用程序的項目必須為鏈接程序指定所需的輸入庫(LIB文件)。而且應用程序事實上必須至少包含一個對DLL函數的調用。


    二、與DLL模塊建立鏈接

    應用程序導入函數與DLL文件中的導出函數進行鏈接有兩種方式:隱式鏈接和顯式鏈接。所謂的隱式鏈接是指在應用程序中不需指明DLL文件的實際存儲路徑,程序員不需關心DLL文件的實際裝載。而顯式鏈接與此相反。

    采用隱式鏈接方式,程序員在建立一個DLL文件時,鏈接程序會自動生成一個與之對應的LIB導入文件。該文件包含了每一個DLL導出函數的符號名和可選的標識號,但是并不含有實際的代碼。LIB文件作為DLL的替代文件被編譯到應用程序項目中。當程序員通過靜態鏈接方式編譯生成應用程序時,應用程序中的調用函數與LIB文件中導出符號相匹配,這些符號或標識號進入到生成的EXE文件中。LIB文件中也包含了對應的DLL文件名(但不是完全的路徑名),鏈接程序將其存儲在EXE文件內部。當應用程序運行過程中需要加載DLL文件時,Windows根據這些信息發現并加載DLL,然后通過符號名或標識號實現對DLL函數的動態鏈接。

    顯式鏈接方式對于集成化的開發語言(例如VB)比較適合。有了顯式鏈接,程序員就不必再使用導入文件,而是直接調用Win32 的LoadLibary函數,并指定DLL的路徑作為參數。LoadLibary返回HINSTANCE參數,應用程序在調用 GetProcAddress函數時使用這一參數。GetProcAddress函數將符號名或標識號轉換為DLL內部的地址。假設有一個導出如下函數的 DLL文件:

    extern "C" __declspec(dllexport) double SquareRoot(double d);

    下面是應用程序對該導出函數的顯式鏈接的例子:
    ?

  • typedef double(SQRTPROC)(double);
  • HINSTANCE hInstance;
  • SQRTPROC* pFunction;
  • VERIFY(hInstance=::LoadLibrary("c:\\winnt\\system32\\mydll.dll"));
  • VERIFY(pFunction=(SQRTPROC*)::GetProcAddress(hInstance,"SquareRoot"));
  • double d=(*pFunction)(81.0);//調用該DLL函數


  • 在隱式鏈接方式中,所有被應用程序調用的DLL文件都會在應用程序EXE文件加載時被加載在到內存中;但如果采用顯式鏈接方式,程序員可以決定DLL文件何時加載或不加載。顯式鏈接在運行時決定加載哪個DLL文件。例如,可以將一個帶有字符串資源的DLL模塊以英語加載,而另一個以西班牙語加載。應用程序在用戶選擇了合適的語種后再加載與之對應的DLL文件。


    三、使用符號名鏈接與標識號鏈接

    在Win16環境中,符號名鏈接效率較低,所有那時標識號鏈接是主要的鏈接方式。在Win32環境中,符號名鏈接的效率得到了改善。Microsoft 現在推薦使用符號名鏈接。但在MFC庫中的DLL版本仍然采用的是標識號鏈接。一個典型的MFC程序可能會鏈接到數百個MFC DLL函數上。采用標識號鏈接的應用程序的EXE文件體相對較小,因為它不必包含導入函數的長字符串符號名。


    四、編寫DllMain函數

    DllMain函數是DLL模塊的默認入口點。當Windows加載DLL模塊時調用這一函數。系統首先調用全局對象的構造函數,然后調用全局函數 DLLMain。DLLMain函數不僅在將DLL鏈接加載到進程時被調用,在DLL模塊與進程分離時(以及其它時候)也被調用。下面是一個框架 DLLMain函數的例子。
    ?

  • HINSTANCE g_hInstance;
  • extern "C" int APIENTRY DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpReserved)
  • {
  • if(dwReason==DLL_PROCESS_ATTACH)
  • {
  • TRACE0("EX22A.DLL Initializing!\n");
  • //在這里進行初始化
  • }
  • else if(dwReason=DLL_PROCESS_DETACH)
  • {
  • TRACE0("EX22A.DLL Terminating!\n");
  • //在這里進行清除工作
  • }
  • return 1;//成功
  • }


  • 如果程序員沒有為DLL模塊編寫一個DLLMain函數,系統會從其它運行庫中引入一個不做任何操作的缺省DLLMain函數版本。在單個線程啟動和終止時,DLLMain函數也被調用。正如由dwReason參數所表明的那樣。


    五、模塊句柄

    進程中的每個DLL模塊被全局唯一的32字節的HINSTANCE句柄標識。進程自己還有一個HINSTANCE句柄。所有這些模塊句柄都只有在特定的進程內部有效,它們代表了DLL或EXE模塊在進程虛擬空間中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,這個兩種類型可以替換使用。進程模塊句柄幾乎總是等于0x400000,而DLL模塊的加載地址的缺省句柄是0x10000000。如果程序同時使用了幾個DLL模塊,每一個都會有不同的HINSTANCE值。這是因為在創建DLL文件時指定了不同的基地址,或者是因為加載程序對DLL代碼進行了重定位。
    模塊句柄對于加載資源特別重要。Win32 的FindResource函數中帶有一個HINSTANCE參數。EXE和DLL都有其自己的資源。如果應用程序需要來自于DLL的資源,就將此參數指定為DLL的模塊句柄。如果需要EXE文件中包含的資源,就指定EXE的模塊句柄。

    但是在使用這些句柄之前存在一個問題,你怎樣得到它們呢?如果需要得到EXE模塊句柄,調用帶有Null參數的Win32函數GetModuleHandle;如果需要DLL模塊句柄,就調用以DLL文件名為參數的Win32函數GetModuleHandle。


    六、應用程序怎樣找到DLL文件

    如果應用程序使用LoadLibrary顯式鏈接,那么在這個函數的參數中可以指定DLL文件的完整路徑。如果不指定路徑,或是進行隱式鏈接,Windows將遵循下面的搜索順序來定位DLL:

    1. 包含EXE文件的目錄,
    2. 進程的當前工作目錄,
    3. Windows系統目錄,
    4. Windows目錄,
    5. 列在Path環境變量中的一系列目錄。

    這里有一個很容易發生錯誤的陷阱。如果你使用VC++進行項目開發,并且為DLL模塊專門創建了一個項目,然后將生成的DLL文件拷貝到系統目錄下,從應用程序中調用DLL模塊。到目前為止,一切正常。接下來對DLL模塊做了一些修改后重新生成了新的DLL文件,但你忘記將新的DLL文件拷貝到系統目錄下。下一次當你運行應用程序時,它仍加載了老版本的DLL文件,這可要當心!
    ?

    七、調試DLL程序

    Microsoft 的VC++是開發和測試DLL的有效工具,只需從DLL項目中運行調試程序即可。當你第一次這樣操作時,調試程序會向你詢問EXE文件的路徑。此后每次在調試程序中運行DLL時,調試程序會自動加載該EXE文件。然后該EXE文件用上面的搜索序列發現DLL文件,這意味著你必須設置Path環境變量讓其包含DLL文件的磁盤路徑,或者也可以將DLL文件拷貝到搜索序列中的目錄路徑下。

    HOOK API是一個永恒的話題,如果沒有HOOK,許多技術將很難實現,也許根本不能實現。這里所說的API,是廣義上的API,它包括DOS下的中斷, WINDOWS里的API、中斷服務、IFS和NDIS過濾等。比如大家熟悉的即時翻譯軟件,就是靠HOOK TextOut()或ExtTextOut()這兩個函數實現的,在操作系統用這兩個函數輸出文本之前,就把相應的英文替換成中文而達到即時翻譯;IFS 和NDIS過濾也是如此,在讀寫磁盤和收發數據之前,系統會調用第三方提供的回調函數來判斷操作是否可以放行,它與普通HOOK不同,它是操作系統允許的,由操作系統提供接口來安裝回調函數。

    甚至如果沒有HOOK,就沒有病毒,因為不管是DOS下的病毒或WINDOWS里的病毒,都是靠HOOK系統服務來實現自己的功能的:DOS下的病毒靠HOOK INT 21來感染文件(文件型病毒),靠HOOK INT 13來感染引導扇區(引導型病毒);WINDOWS下的病毒靠HOOK系統API(包括RING0層的和RING3層的),或者安裝IFS(CIH病毒所用的方法)來感染文件。因此可以說“沒有HOOK,就沒有今天多姿多彩的軟件世界”。

    由于涉及到專利和知識產權,或者是商業機密,微軟一直不提倡大家HOOK它的系統API,提供IFS和NDIS等其他過濾接口,也是為了適應殺毒軟件和防火墻的需要才開放的。所以在大多數時候,HOOK API要靠自己的力量來完成。

    HOOK API有一個原則,這個原則就是:被HOOK的API的原有功能不能受到任何影響。就象醫生救人,如果把病人身體里的病毒殺死了,病人也死了,那么這個 “救人”就沒有任何意義了。如果你HOOK API之后,你的目的達到了,但API的原有功能失效了,這樣不是HOOK,而是REPLACE,操作系統的正常功能就會受到影響,甚至會崩潰。

    HOOK API的技術,說起來也不復雜,就是改變程序流程的技術。在CPU的指令里,有幾條指令可以改變程序的流程:JMP,CALL,INT,RET, RETF,IRET等指令。理論上只要改變API入口和出口的任何機器碼,都可以HOOK,但是實際實現起來要復雜很多,因為要處理好以下問題:

    1,CPU指令長度問題,在32位系統里,一條JMP/CALL指令的長度是5個字節,因此你只有替換API里超過5個字節長度的機器碼(或者替換幾條指令長度加起來是5字節的指令),否則會影響被更改的小于5個字節的機器碼后面的數條指令,甚至程序流程會被打亂,產生不可預料的后果;
    2,參數問題,為了訪問原API的參數,你要通過EBP或ESP來引用參數,因此你要非常清楚你的HOOK代碼里此時的EBP/ESP的值是多少;
    3,時機的問題,有些HOOK必須在API的開頭,有些必須在API的尾部,比如HOOK CreateFilaA(),如果你在API尾部HOOK API,那么此時你就不能寫文件,甚至不能訪問文件;HOOK RECV(),如果你在API頭HOOK,此時還沒有收到數據,你就去查看RECV()的接收緩沖區,里面當然沒有你想要的數據,必須等RECV()正常執行后,在RECV()的尾部HOOK,此時去查看RECV()的緩沖區,里面才有想要的數據;
    4,上下文的問題,有些HOOK代碼不能執行某些操作,否則會破壞原API的上下文,原API就失效了;
    5,同步問題,在HOOK代碼里盡量不使用全局變量,而使用局部變量,這樣也是模塊化程序的需要;
    6,最后要注意的是,被替換的CPU指令的原有功能一定要在HOOK代碼的某個地方模擬實現。

    下面以ws2_32.dll里的send()為例子來說明如何HOOK這個函數:?

  • Exported fn(): send - Ord:0013h
  • 地址?????????機器碼?????????????????匯編代碼
  • :71A21AF4 55??????????????????? push ebp //將被HOOK的機器碼(第1種方法)
  • :71A21AF5 8BEC????????????????? mov ebp, esp //將被HOOK的機器碼(第2種方法)
  • :71A21AF7 83EC10??????????????? sub esp, 00000010
  • :71A21AFA 56??????????????????? push esi
  • :71A21AFB 57??????????????????? push edi
  • :71A21AFC 33FF???????????????? xor edi, edi
  • :71A21AFE 813D1C20A371931CA271? cmp dword ptr [71A3201C], 71A21C93 //將被HOOK的機器碼(第4種方法)
  • :71A21B08 0F84853D0000??????????je 71A25893
  • :71A21B0E 8D45F8??????????????? lea eax, dword ptr [ebp-08]
  • :71A21B11 50?????????????????? push eax
  • :71A21B12 E869F7FFFF??????????? call 71A21280
  • :71A21B17 3BC7???????????????? cmp eax, edi
  • :71A21B19 8945FC??????????????? mov dword ptr [ebp-04], eax
  • :71A21B1C 0F85C4940000??????????jne 71A2AFE6
  • :71A21B22 FF7508??????????????? push [ebp+08]
  • :71A21B25 E826F7FFFF??????????? call 71A21250
  • :71A21B2A 8BF0???????????????? mov esi, eax
  • :71A21B2C 3BF7???????????????? cmp esi, edi
  • :71A21B2E 0F84AB940000??????????je 71A2AFDF
  • :71A21B34 8B4510??????????????? mov eax, dword ptr [ebp+10]
  • :71A21B37 53?????????????????? push ebx
  • :71A21B38 8D4DFC??????????????? lea ecx, dword ptr [ebp-04]
  • :71A21B3B 51?????????????????? push ecx
  • :71A21B3C FF75F8??????????????? push [ebp-08]
  • :71A21B3F 8D4D08??????????????? lea ecx, dword ptr [ebp+08]
  • :71A21B42 57?????????????????? push edi
  • :71A21B43 57?????????????????? push edi
  • :71A21B44 FF7514??????????????? push [ebp+14]
  • :71A21B47 8945F0??????????????? mov dword ptr [ebp-10], eax
  • :71A21B4A 8B450C??????????????? mov eax, dword ptr [ebp+0C]
  • :71A21B4D 51?????????????????? push ecx
  • :71A21B4E 6A01???????????????? push 00000001
  • :71A21B50 8D4DF0??????????????? lea ecx, dword ptr [ebp-10]
  • :71A21B53 51?????????????????? push ecx
  • :71A21B54 FF7508??????????????? push [ebp+08]
  • :71A21B57 8945F4??????????????? mov dword ptr [ebp-0C], eax
  • :71A21B5A 8B460C??????????????? mov eax, dword ptr [esi+0C]
  • :71A21B5D FF5064??????????????? call [eax+64]
  • :71A21B60 8BCE???????????????? mov ecx, esi
  • :71A21B62 8BD8???????????????? mov ebx, eax
  • :71A21B64 E8C7F6FFFF??????????? call 71A21230 //將被HOOK的機器碼(第3種方法)
  • :71A21B69 3BDF???????????????? cmp ebx, edi
  • :71A21B6B 5B?????????????????? pop ebx
  • :71A21B6C 0F855F940000??????????jne 71A2AFD1
  • :71A21B72 8B4508??????????????? mov eax, dword ptr [ebp+08]
  • :71A21B75 5F?????????????????? pop edi
  • :71A21B76 5E?????????????????? pop esi
  • :71A21B77 C9?????????????????? leave
  • :71A21B78 C21000??????????????? ret 0010


  • 下面用4種方法來HOOK這個API:

    1,把API入口的第一條指令是PUSH EBP指令(機器碼0x55)替換成INT 3(機器碼0xcc),然后用WINDOWS提供的調試函數來執行自己的代碼,這中方法被SOFT ICE等DEBUGER廣泛采用,它就是通過BPX在相應的地方設一條INT 3指令來下斷點的。但是不提倡用這種方法,因為它會與WINDOWS或調試工具產生沖突,而匯編代碼基本都要調試;

    2,把第二條mov ebp,esp指令(機器碼8BEC,2字節)替換為INT F0指令(機器碼CDF0),然后在IDT里設置一個中斷門,指向我們的代碼。我這里給出一個HOOK代碼:

    lea ebp,[esp+12] //模擬原指令mov ebp,esp的功能
    pushfd?????????????//保存現場
    pushad?????????????//保存現場

    //在這里做你想做的事情

    popad?????????????//恢復現場
    popfd?????????????//恢復現場
    iretd?????????????//返回原指令的下一條指令繼續執行原函數(71A21AF7地址處)

    這種方法很好,但缺點是要在IDT設置一個中斷門,也就是要進RING0。

    3,更改CALL指令的相對地址(CALL分別在71A21B12、71A21B25、71A21B64,但前面2條CALL之前有一個條件跳轉指令,有可能不被執行到,因此我們要HOOK 71A21B64處的CALL指令)。為什么要找CALL指令下手?因為它們都是5字節的指令,而且都是CALL指令,只要保持操作碼0xE8不變,改變后面的相對地址就可以轉到我們的HOOK代碼去執行了,在我們的HOOK代碼后面再轉到目標地址去執行。

    假設我們的HOOK代碼在71A20400處,那么我們把71A21B64處的CALL指令改為CALL 71A20400(原指令是這樣的:CALL 71A21230)
    而71A20400處的HOOK代碼是這樣的:

    71A20400:
    pushad

    //在這里做你想做的事情

    popad
    jmp 71A21230???????//跳轉到原CALL指令的目標地址,原指令是這樣的:call 71A21230

    這種方法隱蔽性很好,但是比較難找這條5字節的CALL指令,計算相對地址也復雜。

    4,替換71A21AFE地址上的cmp dword ptr [71A3201C], 71A21C93指令(機器碼:813D1C20A371931CA271,10字節)成為
    call 71A20400
    nop
    nop
    nop
    nop
    nop
    (機器碼:E8 XX XX XX XX 90 90 90 90 90,10字節)

    在71A20400的HOOK代碼是:
    pushad
    mov edx,71A3201Ch???????????????//模擬原指令cmp dword ptr [71A3201C], 71A21C93
    cmp dword ptr [edx],71A21C93h???????//模擬原指令cmp dword ptr [71A3201C], 71A21C93
    pushfd

    //在這里做你想做的事

    popfd
    popad
    ret
    這種方法隱蔽性最好,但不是每個API都有這樣的指令,要具體情況具體操作。

    以上幾種方法是常用的方法,值得一提的是很多人都是改API開頭的5個字節,但是現在很多殺毒軟件用這樣的方法檢查API是否被HOOK,或其他病毒木馬在你之后又改了前5個字節,這樣就會互相覆蓋,最

    APIHook一直是使大家感興趣的話題。屏幕取詞,內碼轉化,屏幕翻譯,中文平臺等等都涉及到了此項技術。有很多文章涉及到了這項技術,但都閃爍其詞不肯明明白白的公布。我僅在這里公布以下我用Delphi制作APIHook的一些心得。
    ?????????通常的APIHOOK有這樣幾種方法:
    ????????1、自己寫一個動態鏈接庫,里面定義自己寫的想取代系統的API。把這個動態鏈接庫映射到2G以上的系統動態鏈接庫所在空間,把系統動態鏈接庫中的該API的指向修改指向自己的函數。這種方法的好處就是可以取代系統中運行全部程序的該API。但他有個局限,就是只適用于Win9x。(原因是NT中動態鏈接庫不是共享的,每個進程都有自己的一份動態鏈接庫在內存中的映射)
    ????????2、自己寫一個動態鏈接庫,里面定義自己寫得象替代系統的API。把這個動態鏈接庫映射到進程的空間里。將該進程對API的調用指向自己寫的動態鏈接庫。這種方法的好處是可以選擇性的替代哪個進程的API。而且適用于所有的Windows操作系統。
    ????????這里我選用的是第二種方法。
    ????????第二種方法需要先了解一點PE文件格式的知識。
    ?????????首先是一個實模式的的DOS文件頭,是為了保持和DOS的兼容。
    ?????????接著是一個DOS的代理模塊。你在純DOS先運行Win32的可執行文件,看看是不是也執行了,只是顯示的的是一行信息大意是說該Windows程序不能在DOS實模式下運行。
    ?????????然后才是真正意義上的Windows可執行文件的文件頭。它的具體位置不是每次都固定的。是由文件偏移$3C決定的。我們要用到的就是它。
    ?????????如果我們在程序中調用了一個MessageBoxA函數那么它的實現過程是這樣的。他先調用在本進程中的MessageBoxA函數然后才跳到動態鏈接庫的MessageBoxA的入口點。即:
    ?????????call messageBoxA(0040106c)
    ?????????jmp dword ptr [_jmp_MessageBoxA@16(00425294)]
    其中00425294的內容存儲的就是就是MessageBoxA函數的入口地址。如果我們做一下手腳,那么......
    ????????那就開始吧!
    我們需要定義兩個結構
    type
    ?????PImage_Import_Entry = ^Image_Import_Entry;
    ?????Image_Import_Entry = record
    ????????Characteristics: DWORD;
    ????????TimeDateStamp: DWORD;
    ????????MajorVersion: Word;
    ????????MinorVersion: Word;
    ????????Name: DWORD;
    ????????LookupTable: DWORD;
    ?????end;
    type
    ?????TImportCode = packed record
    ????????JumpInstruction: Word; file: //定義跳轉指令jmp
    ????????AddressOfPointerToFunction: ^Pointer; file: //定義要跳轉到的函數
    ?????end;
    ?????PImportCode = ^TImportCode;
    然后是確定函數的地址。
    function LocateFunctionAddress(Code: Pointer): Pointer;
    var
    ?????func: PImportCode;
    begin
    ?????Result := Code;
    ?????if Code = nil then exit;
    ?????try
    ????????func := code;
    ????????if (func.JumpInstruction = $25FF) then
    ????????begin
    ???????????Result := func.AddressOfPointerToFunction^;
    ????????end;
    ?????except
    ????????Result := nil;
    ?????end;
    end;
    參數Code是函數在進程中的指針,即那條Jmp XXX的指令。$25FF就是跳轉指令的機器碼。

    在這里我將要實現轉跳。有人說修改內存內容要進入Ring 0 才可以??墒荳indows本身提供了一個寫內存的指令WriteProcessMemory。有了這把利器,我們幾乎無所不能。如游戲的修改等在這里我們只談APIHOOK。
    function RepointFunction(OldFunc, NewFunc: Pointer): Integer;
    var
    ????IsDone: TList;
    ????function RepointAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;
    ????var
    ???????Dos: PImageDosHeader;
    ???????NT: PImageNTHeaders;
    ???????ImportDesc: PImage_Import_Entry;
    ???????RVA: DWORD;
    ???????Func: ^Pointer;
    ???????DLL: string;
    ???????f: Pointer;
    ???????written: DWORD;
    ????begin
    ???????Result := 0;
    ???????Dos := Pointer(hModule);
    ???????if IsDone.IndexOf(Dos) >= 0 then exit;
    ???????IsDone.Add(Dos);

    ???????OldFunc := LocateFunctionAddress(OldFunc);

    ???????if IsBadReadPtr(Dos, SizeOf(TImageDosHeader)) then exit;
    ???????if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit;
    ???????NT := Pointer(Integer(Dos) + dos._lfanew);

    ???????RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
    ??????????.VirtualAddress;

    ???????if RVA = 0 then exit;
    ???????ImportDesc := pointer(integer(Dos) + RVA);
    ???????while (ImportDesc^.Name <> 0) do
    ???????begin
    ??????????DLL := PChar(Integer(Dos) + ImportDesc^.Name);
    ??????????RepointAddrInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);
    ??????????Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
    ??????????while Func^ <> nil do
    ??????????begin
    ?????????????f := LocateFunctionAddress(Func^);
    ?????????????if f = OldFunc then
    ?????????????begin
    ????????????????WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written);
    ????????????????if Written > 0 then Inc(Result);
    ?????????????end;
    ?????????????Inc(Func);
    ??????????end;
    ??????????Inc(ImportDesc);
    ???????end;
    ????end;

    begin
    ????IsDone := TList.Create;
    ????try
    ???????Result := RepointAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc);
    ????finally
    ???????IsDone.Free;
    ????end;
    end;
    有了這兩個函數我們幾乎可以更改任何API函數。
    我們可以先寫一個DLL文件。我這里以修改Text相關函數為例:
    先定義幾個函數:
    type
    ????TTextOutA = function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
    ????TTextOutW = function(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
    ????TTextOut = function(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
    ????TDrawTextA = function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    ????TDrawTextW = function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    ????TDrawText = function(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    var
    ????OldTextOutA: TTextOutA;
    ????OldTextOutW: TTextOutW;
    ????OldTextOut: TTextOut;
    ????OldDrawTextA: TDrawTextA;
    ????OldDrawTextW: TDrawTextW;
    ????OldDrawText: TDrawText;
    ......
    function MyTextOutA(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
    begin
    ????OldTextOutA(DC, X, Y, ''''ABC'''', length(''''ABC''''));
    end;

    function MyTextOutW(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
    begin
    ????OldTextOutW(DC, X, Y, ''''ABC'''', length(''''ABC''''));
    end;

    function MyTextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
    begin
    ????OldTextOut(DC, X, Y, ''''ABC'''', length(''''ABC''''));
    end;

    function MyDrawTextA(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    begin
    ????OldDrawTextA(hDC, ''''ABC'''', length(''''ABC''''), lpRect, uFormat);
    end;

    function MyDrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    begin
    ????OldDrawTextW(hDC, ''''ABC'''', length(''''ABC''''), lpRect, uFormat);
    end;

    function MyDrawText(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    begin
    ????OldDrawText(hDC, ''''ABC'''', length(''''ABC''''), lpRect, uFormat);
    end;

    調用時我們要把原來的函數地址保存下來:
    ????if @OldTextOutA = nil then
    ???????@OldTextOutA := LocateFunctionAddress(@TextOutA);
    ????if @OldTextOutW = nil then
    ???????@OldTextOutW := LocateFunctionAddress(@TextOutW);
    ????if @OldTextOut = nil then
    ???????@OldTextOut := LocateFunctionAddress(@TextOut);
    ????if @OldDrawTextA = nil then
    ???????@OldDrawTextA := LocateFunctionAddress(@DrawTextA);
    ????if @OldDrawTextW = nil then
    ???????@OldDrawTextW := LocateFunctionAddress(@DrawTextW);
    ????if @OldDrawText = nil then
    ???????@OldDrawText := LocateFunctionAddress(@DrawText);
    然后很順其自然的用自己的函數替換掉原來的函數
    ????RepointFunction(@OldTextOutA, @MyTextOutA);
    ????RepointFunction(@OldTextOutW, @MyTextOutW);
    ????RepointFunction(@OldTextOut, @MyTextOut);
    ????RepointFunction(@OldDrawTextA, @MyDrawTextA);
    ????RepointFunction(@OldDrawTextW, @MyDrawTextW);
    ????RepointFunction(@OldDrawText, @MyDrawText);
    ?????????在結束時不要忘記恢復原來函數的入口,要不然你會死得很難看喲!好了我們在寫一個Demo程序。你會說怎么文字沒有變成ABC呀?是呀,你要刷新一下才行。最小化然后在最大化??纯醋兞藳]有。???
    ?????????要不然你就寫代碼刷新一下好了。至于去攔截其他進程的API那就用SetWindowsHookEx寫一個其他的鉤子將DLL映射進去就行了,我就不再浪費口水了。
    掌握了該方法你幾乎無所不能。你可以修改其它程序。你可以攔截Createwindow等窗口函數改變其他程序的窗口形狀、你還可以入侵其它的程序,你還可以......嘿嘿。干了壞事別招出我來就行了。

    總結

    以上是生活随笔為你收集整理的浅谈Windows API编程 (这个经典)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    成人久久久久久久久久 | 在线观看自拍 | 开心激情网五月天 | 91av网址 | 日韩精品一区二区三区中文字幕 | 五月婷婷久久丁香 | 中文字幕在线观看视频一区 | 九九热99视频 | 欧美一级性生活视频 | 在线超碰av| 久久久久久久久影视 | 国产在线观看xxx | 国产中文字幕在线观看 | 欧美日韩精品综合 | 黄色片软件网站 | 在线观看视频你懂得 | 国产伦精品一区二区三区四区视频 | 国产精品久久久久一区二区三区共 | 国产精品久久久久毛片大屁完整版 | 国产一区影院 | 日韩在线视频一区二区三区 | 香蕉91视频 | 美女久久久久久 | 天天色天天操综合网 | 国产精选视频 | 久久久久久免费毛片精品 | 国产美女主播精品一区二区三区 | 成人在线观看av | 天天综合操 | www.久艹| 51久久成人国产精品麻豆 | 91亚洲在线观看 | 久久久久久久18 | 国产欧美精品xxxx另类 | 日韩电影一区二区三区 | 国产手机在线观看视频 | 久久网站免费 | 黄色国产在线 | 久久高视频| 色婷婷综合久久久久中文字幕1 | 中国精品一区二区 | 天天操综 | 99视频网址| 99爱视频在线观看 | 91免费高清视频 | 91视频在线 | 四虎小视频 | 看毛片网站| 国产精品福利无圣光在线一区 | 亚洲成av人片在线观看www | 日韩免费不卡av | 欧美日韩aa | 国产亚洲一区二区在线观看 | 亚洲精品永久免费视频 | 最新日韩中文字幕 | 黄网站色成年免费观看 | 免费看久久 | 中文资源在线官网 | 免费国产在线精品 | av片在线观看免费 | 日本久久久久久久久 | 91传媒在线 | 亚洲久久视频 | 国产一级免费在线观看 | 天天操导航| 亚洲精品五月 | 狠狠操狠狠操 | 久久精品国产一区二区三区 | 国产成人一区二区三区影院在线 | 四虎4hu永久免费 | 欧美一二三区在线播放 | 久久久黄色免费网站 | 日日日天天天 | 久久99精品国产99久久6尤 | 91在线看视频 | 国语精品免费视频 | 麻豆视频在线免费看 | av电影在线免费 | 99免在线观看免费视频高清 | 91精品国产成人观看 | 亚洲精品理论 | 国产二区视频在线观看 | 五月天久久婷婷 | 久艹视频在线观看 | 国产一区二区在线播放视频 | 三日本三级少妇三级99 | 麻豆国产视频 | 99国产精品 | 波多野结衣亚洲一区二区 | 99久久精品免费看国产免费软件 | 综合成人在线 | 亚洲精品在线观看免费 | www.狠狠操.com | 国产色久 | 国产日韩精品一区二区 | 日韩在线观看视频免费 | 国产午夜精品视频 | 婷婷午夜天 | 亚洲综合色播 | av成人动漫在线观看 | 亚洲毛片视频 | 免费在线观看中文字幕 | 美女视频黄是免费的 | 岛国一区在线 | 久久成人精品视频 | 五月开心网 | 激情综合网在线观看 | 中文国产字幕 | 国产精品99久久久久久武松影视 | 欧美美女视频在线观看 | 久久亚洲综合色 | 五月婷婷网站 | 99麻豆视频 | 成人全视频免费观看在线看 | 黄色一级动作片 | 人人看97| 成人 国产 在线 | 国产品久精国精产拍 | 久久精品视频免费播放 | 亚洲在线日韩 | 色五月激情五月 | 国产亚洲精品久久网站 | 高清av网站| www在线免费观看 | 玖玖玖在线观看 | 五月天综合婷婷 | 久久精品国产成人精品 | 色婷婷狠狠操 | 一区 二区 精品 | 久久久久久久久久久久影院 | 区一区二区三区中文字幕 | 欧美性精品 | 亚洲成av人影院 | 欧美久草网| 国产精品一区二区三区电影 | 最新国产在线 | 日日夜夜天天久久 | 国产亚洲精品久久久久秋 | 超碰成人免费电影 | 国产成人香蕉 | 国产高清久久久 | 婷婷六月色 | 天堂成人在线 | 国产免费av一区二区三区 | 亚洲精品小区久久久久久 | 91在线资源 | 91插插插免费视频 | 五月天久久久 | 成人精品久久 | 波多在线视频 | www天天干 | 天天干天天摸天天操 | 伊人天天综合 | 久久久精华网 | 成人av片在线观看 | 久久精品99久久久久久 | 黄色av成人在线观看 | 久久9999久久| 92国产精品久久久久首页 | 成人免费观看网站 | 99免费精品视频 | 久久这里只有精品久久 | 成人性生交视频 | av高清一区 | 欧美精品一区二区三区一线天视频 | 美女av免费看 | 丰满少妇对白在线偷拍 | 激情五月综合 | 天天爱天天操天天射 | 九色91视频| 亚洲黄色免费在线看 | 日韩在线观看一区二区 | 日韩精品一区二区电影 | av电影 一区二区 | 亚洲成人欧美 | 国产高清视频在线 | 日本99久久 | 91精品久久久久久综合五月天 | 97免费在线观看视频 | 国产精品国产三级国产aⅴ入口 | 97人人澡人人爽人人模亚洲 | 成人久久精品视频 | 成人免费影院 | h视频在线看 | 人人躁 | 天天射天天操天天色 | 狠狠激情中文字幕 | 日本久久综合网 | 国产精品一区二区麻豆 | 亚洲免费不卡 | 一区二区三区四区在线 | 欧美小视频在线观看 | 成人中文字幕在线 | 96视频免费在线观看 | 在线免费观看不卡av | 深夜免费福利 | 成人av一二三区 | 久久69av| 久久久国产影视 | 欧美成人亚洲成人 | 在线成人免费av | 一本一道久久a久久精品 | 亚洲欧美国产精品 | 91丨九色丨丝袜 | 欧洲精品久久久久毛片完整版 | 久久精品影片 | 亚洲一级黄色av | 九七视频在线观看 | 国产精品久久久久久av | 国模吧一区| 久久国产亚洲精品 | 欧美日韩18 | 日韩精品视频网站 | 国产精品黄色影片导航在线观看 | 在线韩国电影免费观影完整版 | 在线观看理论 | 天天曰天天爽 | av中文在线 | 在线免费观看一区二区三区 | 欧亚日韩精品一区二区在线 | 久久婷婷激情 | 国产免费一区二区三区最新 | 网站免费黄| 免费在线观看日韩 | 毛片3| 天天插天天狠天天透 | 日韩视频免费 | 九色视频网 | 一区二区三区高清不卡 | 99久久精品久久亚洲精品 | 97视频在线观看播放 | 欧美久久久久久久久久久久 | 日韩有码在线观看视频 | 久久国产精品区 | 97超碰人人澡 | 国产一区二区在线影院 | 九九热视频在线免费观看 | 欧美专区亚洲专区 | 丝袜美腿亚洲 | 香蕉视频18 | 91在线播放综合 | 一区二区三区四区五区六区 | 玖玖玖影院 | 玖玖精品视频 | 伊人精品影院 | 99精品国产99久久久久久福利 | 久久国产网站 | 久久精品欧美视频 | 日韩欧美电影在线观看 | 久久99久久99久久 | 丁香久久久 | 夜添久久精品亚洲国产精品 | 九九激情视频 | 五月婷婷国产 | 久久九精品 | 综合黄色网 | 色妞久久福利网 | 婷婷激情欧美 | 综合网天天色 | 日韩精品最新在线观看 | 国产精品久久久久久久久久久免费看 | 网站你懂的| 国产免费看 | 麻豆一区二区三区视频 | 国产精品亚洲片在线播放 | 黄色大片网 | 欧美天堂视频在线 | 久久草网 | 国产精品久久久久久久久久东京 | 日色在线视频 | 九九久久久久久久久激情 | 久久久香蕉视频 | 欧美91精品| 免费看一及片 | 亚洲欧美日韩精品久久奇米一区 | 天天操天天射天天操 | av看片网址 | 亚洲日本va在线观看 | 一区视频在线 | 91禁在线看 | 欧美人zozo | 黄色网www| 国产免费久久av | 99国产成+人+综合+亚洲 欧美 | 中文字幕精品三级久久久 | 国产一区二区午夜 | 在线观看免费成人av | 亚洲精品ww | 日日爽 | 在线观看一级片 | 国产91全国探花系列在线播放 | 中文字幕影片免费在线观看 | 中文字幕观看在线 | 亚洲激情 在线 | 久久久99精品免费观看 | 天堂成人在线 | 免费观看版 | 天天操夜夜操国产精品 | 国产精品99蜜臀久久不卡二区 | 欧美性另类| 久草青青在线观看 | 婷婷五月在线视频 | 国产在线观看免费 | 黄色免费av | 久久久影院一区二区三区 | 日韩欧美在线一区二区 | 亚洲欧美日韩在线看 | 99热这里| 99视频精品视频高清免费 | 中文在线资源 | 在线黄色免费 | 97超碰在线久草超碰在线观看 | 国产精成人品免费观看 | 免费a v在线| 高清国产午夜精品久久久久久 | 欧美日韩高清一区二区三区 | 精品国产一区二区三区在线观看 | 99久国产 | 激情视频网页 | 看黄色91| 免费看黄在线观看 | 免费美女久久99 | 人人爽人人舔 | 在线看一级片 | 一区二区日韩av | 一区二区 久久 | 亚洲日本va午夜在线影院 | 9999亚洲 | 在线国产福利 | 成人动图 | 一级精品视频在线观看宜春院 | 日韩性久久 | 在线看成人av | 精品成人a区在线观看 | 西西大胆免费视频 | 在线观看你懂的网站 | 国产精品一区二区在线免费观看 | 一区二区三区在线电影 | 成人在线观看av | 人人操日日干 | 伊人亚洲精品 | 国产精品一区二区久久 | 亚洲第一区在线播放 | 狠狠狠操 | 中文字幕资源网在线观看 | 午夜精品一区二区三区在线观看 | 91在线区 | 国产欧美精品在线观看 | 五月亚洲 | 午夜电影 电影 | 国产精品久久久久久久午夜片 | 激情视频区 | 国产99久久九九精品免费 | 色综合久久久网 | 精品福利在线观看 | 在线看欧美 | 久久久久 | 播五月综合 | 99热这里精品 | 久久99国产精品自在自在app | 国产日韩欧美在线 | 亚洲成人免费在线观看 | 久久人操 | 国产不卡网站 | 91av欧美| 97色综合| 婷婷色亚洲 | 成人久久久久久久久久 | 97成人免费视频 | 欧洲亚洲国产视频 | 国产精品一区免费看8c0m | 国产三级视频 | a v在线观看| 久久视频免费观看 | 四虎www. | 欧美乱淫视频 | 五月色丁香 | 天天射天天色天天干 | 久久观看免费视频 | 黄色在线网站噜噜噜 | 91精品视频在线免费观看 | 视频一区在线播放 | 精品一区在线看 | 在线观看电影av | 在线观看日本高清mv视频 | 午夜精品一区二区国产 | 日韩精品在线视频 | 日韩资源在线 | 国产精品九九久久99视频 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 免费在线观看一区 | 制服丝袜成人在线 | 99精品福利 | 国产精品黄色影片导航在线观看 | 亚洲欧美一区二区三区孕妇写真 | 国产永久免费观看 | 天天操天天舔天天干 | a黄色大片 | 特级西西人体444是什么意思 | 一二三区高清 | 日韩v欧美v日本v亚洲v国产v | 91成品人影院| 欧美一级久久 | 国产精品国产三级国产 | 九九欧美 | 奇米影音四色 | 在线电影播放 | 国产成人精品亚洲日本在线观看 | 国外成人在线视频网站 | 免费高清在线观看电视网站 | 精品一区二三区 | 色综合天天爱 | 国产原创在线观看 | 中文字幕资源网 国产 | 狠狠色狠狠色综合日日92 | 国产免费国产 | 亚洲精品久久久蜜桃直播 | 亚洲国产精品小视频 | 免费色婷婷 | 五月婷婷视频在线 | 天天狠狠干 | www.久久久.com | 91久久爱热色涩涩 | 日本不卡一区二区三区在线观看 | www.国产毛片 | 99精品视频一区 | 久久人人爽人人人人片 | 久久久精品二区 | 亚洲一级黄色片 | 久久av中文字幕片 | 日韩视频三区 | 五月婷婷综 | 麻豆影视在线观看 | 狠狠色丁香婷婷综合欧美 | 免费观看成人网 | av在线播放不卡 | 国产又粗又猛又黄 | 欧美激情亚洲综合 | 国产精久久 | 欧洲高潮三级做爰 | 一区二区三区www | 黄色午夜网站 | 婷婷色六月天 | 国产精品在线看 | 欧美日韩中文字幕在线视频 | 最近能播放的中文字幕 | 亚洲激情p | 色久综合 | 九九九九精品 | 69国产盗摄一区二区三区五区 | 日本激情视频中文字幕 | 国产欧美日韩视频 | 黄色精品久久久 | 黄色免费视频在线观看 | 亚洲一级黄色片 | 天天爱天天色 | 中日韩在线视频 | 色综合久久五月天 | 在线观看久久久久久 | 久久精品视频网站 | 五月天婷婷在线视频 | 操天天操 | 久久国产精品免费一区 | av综合站| 在线观看av不卡 | 五月天久久精品 | 高清av免费看 | 天天草天天干天天射 | 2023亚洲精品国偷拍自产在线 | 99精品欧美一区二区三区 | 夜夜操天天操 | 日韩av中文| 欧美精选一区二区三区 | 中文字幕免费观看全部电影 | 中文字幕成人 | 国产一区在线免费观看视频 | 999亚洲国产996395| av在线进入 | 日韩电影在线观看一区二区三区 | 婷婷中文在线 | 欧美在线观看视频一区二区 | 在线播放精品一区二区三区 | 久久精品伊人 | 日韩激情视频 | 精品国产成人在线 | 成人91在线 | 天堂网一区二区 | 波多野结衣动态图 | 久久久久久久久久久免费视频 | 国产高清在线免费观看 | 天天曰天天射 | 五月激情姐姐 | 97电影网手机版 | 日本中出在线观看 | 亚洲国产精品电影在线观看 | 奇米7777狠狠狠琪琪视频 | 亚洲一区二区精品 | 在线视频日韩 | 欧美日韩1区 | 黄色毛片视频免费观看中文 | 国产黑丝袜在线 | 偷拍精品一区二区三区 | 亚洲一区二区视频 | 国产一区在线视频 | 久久久国产精品久久久 | 69中文字幕 | 免费污片| 丁香久久久 | 午夜三级在线 | 亚洲免费av网站 | 深夜免费福利 | 九七视频在线 | 人人精品 | 欧美日韩综合在线观看 | 国产亚洲视频在线免费观看 | 国产丝袜| 97人人看| 视频一区二区精品 | 一区二区三区在线播放 | 综合色婷婷 | 91av中文字幕 | 色99之美女主播在线视频 | 久久草视频| 8x8x在线观看视频 | 中文字幕精品www乱入免费视频 | www.婷婷com| 亚洲狠狠丁香婷婷综合久久久 | 91看片在线看片 | 在线免费av网 | 99视频在线免费观看 | 久久99精品久久久久久清纯直播 | 午夜精品av | www.五月天 | 天天操福利视频 | 亚洲天天看| 国产高清在线不卡 | 久久国产精品视频 | 天天爱天天射 | 国产高清免费观看 | 亚洲综合视频在线 | 亚洲乱码久久 | 天天操天天干天天玩 | 亚洲视频综合在线 | 国产69熟 | 亚洲精品在线观看的 | 亚洲精品在线一区二区三区 | www日韩在线观看 | 亚洲免费av在线播放 | 国产流白浆高潮在线观看 | 免费观看福利视频 | 亚洲伊人成综合网 | 欧美成人xxxx | 激情久久久久久久久久久久久久久久 | 国产精品毛片一区二区在线看 | www.777奇米 | 精品字幕在线 | 国产一区欧美日韩 | 精品在线观看一区二区 | 精品国产自 | 成人午夜电影在线播放 | 国产成人精品av在线 | 天堂网中文在线 | 日韩伦理片hd | 日韩免费电影在线观看 | 国产一级片毛片 | 色综合久久88色综合天天 | 亚洲精品xx| 免费在线观看av电影 | 日韩最新中文字幕 | 狠狠色噜噜狠狠 | 香蕉成人在线视频 | 亚洲专区中文字幕 | 亚洲综合五月 | 天天玩天天操天天射 | 91在线蜜桃臀 | 日本久久成人中文字幕电影 | 日韩免费视频播放 | 国产精品涩涩屋www在线观看 | 亚洲女人天堂成人av在线 | 免费视频你懂得 | 超碰97人人在线 | 久久国产精品久久精品 | 国产精品久久久久久久久久免费 | 黄色视屏免费在线观看 | 国产资源在线视频 | 国产美女免费观看 | 91一区二区在线 | 久久精品看片 | 香蕉影院在线观看 | 丁香av在线 | 最近中文字幕在线 | 麻豆视频免费在线播放 | 国产高h视频| 国产中文在线视频 | 国产精品美女久久久久久久久久久 | 在线免费观看视频一区二区三区 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 成人黄色影片在线 | 2021久久 | 日本99久久| 国产亚洲精品久久久久5区 成人h电影在线观看 | 久久精品成人热国产成 | 国产美女搞久久 | 中文字幕中文字幕在线中文字幕三区 | 免费av视屏 | 久久av免费电影 | 亚洲国产大片 | a级片网站 | 国产精品久久久久一区 | 天天爱天天舔 | 三级黄色免费片 | 精品国产成人av在线免 | 中文字幕中文字幕在线中文字幕三区 | 国产精品女 | 亚洲精品在线网站 | 国产 字幕 制服 中文 在线 | 免费视频xnxx com | 人人看人人爱 | 天天爽天天爽 | 91手机视频在线 | 国产中文字幕网 | 国产美女视频一区 | 久久官网| 久久手机看片 | 婷婷久久五月 | 国产成人精品在线 | 在线观看你懂的网址 | 久久久久久97三级 | 在线观看mv的中文字幕网站 | 亚洲精品网站 | 日本不卡123 | 激情电影在线观看 | 精品久久久久久久久中文字幕 | 中文字幕网站视频在线 | 有码视频在线观看 | 欧美日韩高清一区 | 久久艹艹| 国产一区二区在线免费视频 | 91九色视频在线 | 久久久久这里只有精品 | 欧美999 | 亚洲成人第一区 | 欧美性大战 | 日韩欧美高清免费 | 欧美激情综合五月色丁香小说 | av手机在线播放 | 日本免费久久高清视频 | 制服丝袜成人在线 | 六月天综合网 | 99精品久久精品一区二区 | 精品一区91 | 3d黄动漫免费看 | 人人插人人玩 | 就要干b | 九九九在线观看视频 | 国产精品福利av | 麻豆视频在线免费 | 国产成人一区三区 | 黄色av高清| 怡红院av久久久久久久 | 亚洲欧洲国产精品 | 国产永久网站 | 97视频在线观看网址 | 四虎成人精品 | 国产精品久久久久久久久岛 | 欧美性色xo影院 | 日日日操操 | 精品国产成人av在线免 | 亚洲精品乱码久久久久久蜜桃动漫 | 久久精品小视频 | 久久1区 | 国产在线精品一区二区 | 久久综合99 | 五月婷综合网 | 正在播放日韩 | 中文字幕一区二区三区在线播放 | 成人黄色资源 | 在线播放 日韩专区 | 丁香六月中文字幕 | 岛国一区在线 | 欧美日韩精品在线免费观看 | 97国产精品久久 | 免费视频 你懂的 | 在线观看黄色小视频 | 草久久影院| 在线看片一区 | 午夜国产一区二区三区四区 | 日本夜夜草视频网站 | 最近最新中文字幕视频 | 久久成人18免费网站 | 国产v欧美| 久久久影片| 欧美日韩在线视频免费 | 91精品国自产在线偷拍蜜桃 | 91视频大全| 久久久精品成人 | 香蕉影视 | 欧美超碰在线 | 精品久久久国产 | 日韩欧美精品在线视频 | 欧美色精品天天在线观看视频 | 91久久精品一区 | 日韩欧美精品一区二区三区经典 | 999色视频| 看国产黄色大片 | 久色 网| 又黄又爽又湿又无遮挡的在线视频 | 亚洲国产资源 | 人人添人人澡人人澡人人人爽 | 国产精品成人av在线 | 国产精品99久久久久人中文网介绍 | 97免费在线观看视频 | 五月天com | 91成年人视频 | 99视频在线精品国自产拍免费观看 | 亚洲人成在线观看 | 黄色小视频在线观看免费 | 免费av网站在线看 | 国产成人久久 | 亚洲欧美国产精品 | 免费在线视频一区二区 | 99久久精 | 欧美一区二区三区免费看 | 日韩午夜电影网 | 美女黄频视频大全 | 久久久国产精品一区二区中文 | 日日爱夜夜爱 | 免费看黄在线观看 | 亚洲va欧美va国产va黑人 | 91视频高清 | 婷婷久久一区 | 中文字幕中文字幕 | 国产人成免费视频 | 国产韩国日本高清视频 | 日本女人b | 久久黄色免费 | 日韩高清一二三区 | 日本特黄特色aaa大片免费 | 婷婷性综合 | 日韩在线小视频 | 成人毛片在线观看视频 | 欧美精品国产综合久久 | 日韩中文字幕免费在线播放 | 亚洲黄色av网址 | 天天爽天天爽天天爽 | 激情喷水 | 日韩一区视频在线 | 很黄很污的视频网站 | 免费观看www小视频的软件 | 国产成人在线一区 | 天天爱天天射天天干天天 | 91久久精品日日躁夜夜躁国产 | 成人免费在线视频观看 | 六月婷婷色 | 国产96在线 | 亚洲区视频在线 | 在线高清| 欧美黄色成人 | 中文字幕免费久久 | 色婷婷一区 | 成人在线播放视频 | 欧美精品国产精品 | 国产精品乱看 | 在线导航福利 | 成人作爱视频 | 麻豆视频免费版 | 91爱看片| 国产91在线免费视频 | av三级在线免费观看 | 精品三级av | 人人舔人人插 | 欧美日韩二区在线 | 人人爽人人爽人人爽学生一级 | 日韩1级片 | 超碰成人免费电影 | 亚洲国产精品资源 | 国产精品免费久久久久久久久久中文 | 人人爽人人爽人人片av | 狠狠狠的干 | 日韩在线精品一区 | 99爱这里只有精品 | 九九久久久久久久久激情 | 久久久高清一区二区三区 | 欧美日韩中文国产一区发布 | 国产精品久久久久av | 天天干夜夜爱 | 99在线精品免费视频九九视 | 91精品国产三级a在线观看 | 国产精品一区二区三区视频免费 | 91亚洲精品久久久蜜桃 | 国产美女精品在线 | 欧美日韩一二三四区 | 欧美激情第八页 | www.天天操.com | 国产精品99久久久精品免费观看 | 99中文视频在线 | 99久久夜色精品国产亚洲 | 99这里只有精品99 | 亚洲aⅴ在线观看 | 免费看国产精品 | 91资源在线视频 | 免费日韩三级 | 蜜臀av免费一区二区三区 | 天天干天天操天天射 | 精品国内自产拍在线观看视频 | 蜜臀久久99精品久久久久久网站 | 国产九九精品视频 | 在线免费黄色av | 国产精品专区在线观看 | 九九99| 久久免费看片 | 国产手机在线观看 | 成人 亚洲 欧美 | 国产一区二区免费看 | 91日韩在线 | 日韩精品一区二区三区高清免费 | se视频网址 | 婷婷综合国产 | 久久综合五月婷婷 | 深爱激情综合 | 国产高清免费av | 午夜美女wwww | av一级免费 | 日韩美女高潮 | 欧美日韩性视频 | 国产五月| 国产无限资源在线观看 | 韩国av一区二区三区 | 国产精品嫩草影视久久久 | 国产成人av免费在线观看 | 91大神在线观看视频 | 国产免费高清 | 欧美日韩1区 | 在线观看av免费观看 | 国产91综合一区在线观看 | 成人影视免费 | 日韩久久久久久久久久久久 | 激情喷水 | 免费成人结看片 | 精品国产欧美一区二区三区不卡 | 97超碰福利久久精品 | 99久久99久国产黄毛片 | 最近免费中文字幕大全高清10 | 99草在线视频 | 亚洲精品影视在线观看 | 人人揉人人揉人人揉人人揉97 | 亚洲精品午夜久久久久久久久久久 | 五月天久久综合网 | aaa日本高清在线播放免费观看 | 深爱五月激情网 | 成人免费av电影 | 区一区二区三区中文字幕 | 色94色欧美 | 黄色免费网战 | 天天艹日日干 | 久久午夜精品影院一区 | 91精品无人成人www | 九九热在线精品视频 | 天天综合亚洲 | 国产精品久久久久久久99 | 国产精品女人久久久 | 精品色999 | 在线免费观看国产 | 99色网站 | 久久综合五月天 | 最近高清中文字幕在线国语5 | 亚洲高清91 | 在线小视频你懂得 | 国产亚洲字幕 | 91精品在线免费视频 | 国产精品18毛片一区二区 | 免费日韩 精品中文字幕视频在线 | 在线观看色网站 | 欧美 亚洲 另类 激情 另类 | 国内精自线一二区永久 | 日韩电影精品一区 | 国内久久看 | 在线免费中文字幕 | 日韩.com| 九九久久婷婷 | 欧美精品久久久久久久免费 | 亚洲一区二区三区miaa149 | 看片网站黄 | 国产手机免费视频 | 亚洲 在线 | 天天色天天上天天操 | 狠狠干电影 | 一区二区不卡高清 | 在线观看的av | 中文字幕丝袜美腿 | 亚洲欧美日韩精品久久久 | 爱干视频 | 91精品国产自产在线观看 | 国产精品嫩草影视久久久 | 亚洲一级片在线观看 | 精品久久久久久久久久岛国gif | 欧美精品中文 | 成人动漫精品一区二区 | 精品国产美女 | 国产日韩欧美精品在线观看 | 激情av一区二区 | 国产精品18久久久久vr手机版特色 | 最新国产中文字幕 | 久久伊人免费视频 | www黄色软件 | 亚洲男男gaygayxxxgv | 丁香综合| 免费a视频在线 | 午夜久久福利视频 | 精品国产一区二区三区久久久蜜月 | 色婷婷激情四射 | 久久综合影院 | 日日干狠狠操 | 亚洲伊人网在线观看 | 亚洲精品一区二区三区新线路 | 亚洲精品综合在线 | 男女激情片在线观看 | 色综合天天综合网国产成人网 | 69av在线视频 | 综合亚洲视频 | 免费av观看 | 亚洲综合视频在线 | 国产精品久久久久久久久久直播 | 免费视频你懂的 | 欧美乱淫视频 | 国产色综合天天综合网 | 9ⅰ精品久久久久久久久中文字幕 | 久久电影日韩 | 久久久亚洲国产精品麻豆综合天堂 | 999久久国产精品免费观看网站 | 成年人毛片在线观看 | 色丁香综合 | 日韩欧美综合视频 | 福利一区二区在线 | 91精品国产99久久久久久久 | 久久手机免费视频 | 国产亚洲亚洲 | 69av视频在线观看 | 中文字幕人成乱码在线观看 | 在线看av的网址 | 日批视频国产 | 亚洲精品av在线 | 国产亚洲精品久久久久久大师 | ,午夜性刺激免费看视频 | 日韩在线观看视频在线 | 国产91在线播放 | 久久久久久久久久久久电影 | 久久久精品久久日韩一区综合 | 亚洲最新毛片 | 久久久在线观看 | 亚洲视频在线观看免费 | 3d黄动漫免费看 | 国产精品丝袜在线 | 麻豆91精品91久久久 | 五月天高清欧美mv | 99热最新精品 | 久久久久免费精品视频 | 国模视频一区二区 | 五月婷婷婷婷婷 | 在线日韩亚洲 | 91精品久久久久久综合五月天 | 91成人天堂久久成人 | 久久精品91视频 | 91视频观看免费 | 日韩精品免费在线观看 | 韩国av免费 | 999视频网| 国产成人精品一区二区在线观看 | 91精品一区二区三区蜜桃 | 菠萝菠萝蜜在线播放 | 天天爽综合网 | 国产精品成人国产乱 | 色片网站在线观看 | 国产精品久久久久久一区二区三区 | 精品国产电影一区二区 | 婷婷激情综合 | 欧美激情综合色 | 中文字幕区 | 国产又粗又猛又黄又爽 | 国产亚洲一区二区在线观看 | 免费在线观看视频a | 日韩专区在线观看 | 精品久久一二三区 | 黄色大片中国 | 中文字幕在线观看免费高清完整版 | 一区视频在线 | 毛片激情永久免费 | 午夜视频在线网站 | 一区二区不卡视频在线观看 | 97看片 | 91久久国产露脸精品国产闺蜜 | 狠狠色丁婷婷日日 | 亚洲精品国产电影 | 免费在线观看不卡av | 免费看黄的 | 国产一级免费在线观看 | 操操综合 | www.国产精品 |