黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

Win32 結(jié)構(gòu)化異常處理(SEH)探秘

系統(tǒng) 1877 0

原著:Matt Pietrek

翻譯: VCKBASE


譯注:本文都翻譯了一大半了,才發(fā)現(xiàn)網(wǎng)上已經(jīng)有一篇董巖的譯本( http://www.diybl.com/course/3_program/c++/cppsl/200866/122881.html ),
看完他的譯文,感覺(jué)所有涉及關(guān)鍵技術(shù)的地方董巖翻譯得非常到位,所以自己就沒(méi)有再花時(shí)間往下譯,本文后面的部分基本上都是采用了董巖的譯文。此外,董巖在譯文后面附帶有一篇附錄,專門解釋“prolog 和 epilog”,后來(lái)我發(fā)現(xiàn) MSDN 庫(kù)中對(duì)此有專門的解釋,內(nèi)容也更豐富,所以就用微軟文檔中的內(nèi)容取而代之了。特此說(shuō)明。


原文出處: A Crash Course on the Depths of Win32? Structured Exception Handling

下載源代碼

本文假設(shè)你熟悉 C++,Win32

摘要

  Win32 結(jié)構(gòu)化異常處理其核心是操作系統(tǒng)提供的服務(wù),你能找到的關(guān)于 SEH 的所有文檔都是描述一個(gè)特定的編譯器運(yùn)行時(shí)庫(kù),這個(gè)運(yùn)行庫(kù)包裝著操作系統(tǒng)實(shí)現(xiàn)。在本文中,我將一層一層對(duì) SEH 進(jìn)行剝離,以便展現(xiàn)其最基本的概念。

  在 Win32 操作系統(tǒng)提供的所有功能中,使用最廣泛但最缺乏文檔描述的也許就是結(jié)構(gòu)化異常處理了(SEH),當(dāng)你考慮 Win32 結(jié)構(gòu)化異常處理時(shí),你也許會(huì)想到諸如 _try,_finally 以及 _except 這些術(shù)語(yǔ)。你能在任何有關(guān) Win32 的書中發(fā)現(xiàn)對(duì) SEH 很好的描述(即使是 remedial)。即便是 Win32 SDK 也具備有相當(dāng)完整的使用 _try,_finally 和 _except 進(jìn)行結(jié)構(gòu)化異常處理的概述。
  有了這些文檔,那為何還說(shuō) SEH 缺乏文檔呢?其實(shí),Win32 結(jié)構(gòu)化異常處理是操作系統(tǒng)提供的一個(gè)服務(wù)。你能找到的關(guān)于 SEH 的所有文檔都是描述特定編譯器的運(yùn)行時(shí)庫(kù),這個(gè)運(yùn)行庫(kù)對(duì)操作系統(tǒng)實(shí)現(xiàn)進(jìn)行包裝。_try,_finally 和 _except 這些關(guān)鍵字沒(méi)有任何神奇的地方。微軟的操作系統(tǒng)及其編譯器系列定義這些關(guān)鍵字和用法。其他的編譯器提供商則只是沿用這些語(yǔ)義。雖然借助編譯器層的 SEH 可以挽回一些原始操作系統(tǒng)級(jí) SEH 處理不良口碑,但在大眾眼里對(duì)原始操作系統(tǒng) SEH 細(xì)節(jié)的處理感覺(jué)依舊。
  我收到人們大量的e-mail,都是想要實(shí)現(xiàn)編譯器級(jí)的 SEH 處理,又無(wú)法找到操作系統(tǒng)功能提供的相關(guān)文檔。通常我都是建議參考 Visual C++ 或者 Borland C++ 運(yùn)行庫(kù)源代碼。唉,出于一些未知的原因,編譯器級(jí)的 SEH 似乎是一個(gè)大的秘密,微軟和 Borland 都不提供其對(duì) SEH 支持的核心層源代碼。
  在本文中,我將一層一層對(duì) SEH 進(jìn)行解剖,以便展現(xiàn)其最基本的概念。我打算通過(guò)代碼產(chǎn)生和運(yùn)行時(shí)庫(kù)支持將操作系統(tǒng)提供的功能和編譯器提供的功能分開(kāi)。當(dāng)我深入代碼考察關(guān)鍵的操作系統(tǒng)例程時(shí),我將使用 Intel 平臺(tái)上的 Windows NT4.0 作為基礎(chǔ)。但我將要描述的大多數(shù)內(nèi)容同樣適用于其它處理器上運(yùn)行的應(yīng)用。
  我打算避免涉及到真正的 C++ 異常處理,它們使用 catch(),而不是 _except。其實(shí),真正的 C++ 異常處理實(shí)現(xiàn)非常類似于本文中描述的內(nèi)容。但是 C++ 異常處理有一些額外的復(fù)雜性會(huì)影響我想要涉及的概念。
  通過(guò)深入研究晦澀的 .H 和 .INC 文件來(lái)歸納 Win32 SEH 構(gòu)成,我發(fā)現(xiàn)有一個(gè)信息源之一就是 IBM OS/2 頭文件(尤其是 BSEXCPT.H)。為此你不要覺(jué)得大驚小怪。。此處描述的 SEH 機(jī)制在其源頭被定義時(shí),微軟仍然開(kāi)發(fā) OS/2 平臺(tái)(譯注: OS/2 平臺(tái)起初是IBM 和 微軟共同研發(fā)的,后來(lái)由于種種原因兩個(gè)公司沒(méi)有再繼續(xù)下去)。所以你會(huì)發(fā)現(xiàn)Win32 下的 SEH 和 OS/2 下的 SEH 極其相似。

SEH 淺析

  從整體來(lái)看,SEH 的可謂不可一世,絕對(duì)壓倒一切,我將從細(xì)微之處開(kāi)始,用我自己的方式一層一層研究。如果你是一張白紙,以前從沒(méi)接觸過(guò)結(jié)構(gòu)化異常處理,那就最好不過(guò)了。如果你以前使用過(guò) SEH。那就嘗試清理你頭腦中的 _try,GetExceptionCode 和 EXCEPTION_EXECUTE_HANDLER 等諸如此類的詞,權(quán)當(dāng)自己是個(gè)新手。做一個(gè)深呼吸,準(zhǔn)備好了嗎?好,我們開(kāi)始。
  想象一下,我告訴你某個(gè)線程出錯(cuò)了,操作系統(tǒng)給你一個(gè)機(jī)會(huì)通知了這個(gè)線程錯(cuò)誤,或者再具體一點(diǎn),當(dāng)線程出錯(cuò)后,操作系統(tǒng)調(diào)用某個(gè)用戶定義的回調(diào)函數(shù)。這個(gè)回調(diào)函數(shù)可以所任何它想做的事情。例如,它可以修復(fù)任何原因?qū)е碌腻e(cuò)誤,或者播放一個(gè) .wav 文件。不管回調(diào)函數(shù)做什么,其最后總是返回一個(gè)值,這個(gè)值告訴系統(tǒng)下一步做什么。(這里描述的情況不一定完全一樣,但足夠接近。)
  假定當(dāng)你的代碼出現(xiàn)了混亂,你不得不回來(lái),想看看回調(diào)函數(shù)是什么樣子的?換句話說(shuō),你想知道什么樣的異常信息呢?其實(shí)這無(wú)關(guān)緊要,因?yàn)?Win32 已經(jīng)幫你決定了。一個(gè)異常回調(diào)函數(shù)就象下面這樣:

    EXCEPTION_DISPOSITION
__cdecl _except_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext
);
  

  該原型出自標(biāo)準(zhǔn)的 Win32 頭文件 EXCPT.H,初看就有那么一點(diǎn)不同凡響。如果你慢慢研究,其實(shí)并沒(méi)有那么糟。例如,忽略返回類型(EXCEPTION_DISPOSITION)。基本上你看到的就是一個(gè)叫做 _except_handler 的函數(shù),這個(gè)函數(shù)帶有四個(gè)參數(shù)。
  第一個(gè)參數(shù)是指向 EXCEPTION_RECORD 結(jié)構(gòu)指針,該結(jié)構(gòu)在 WINNT.H 中定義如下:

    typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
  

  ExceptionCode 參數(shù)是由操作系統(tǒng)賦值給異常的一個(gè)數(shù)。你可以在 WINNT.H 文件中搜一下“STATUS_”開(kāi)始的 #defines 內(nèi)容便可以得到一系列不同的異常編碼。例如 STATUS_ACCESS_VIOLATION 是大家再熟悉不過(guò)的異常編碼了,其值是 0xC0000005。更復(fù)雜的異常編碼可以從 Windows NT DDK 的 NTSTATUS.H 文件中找到。EXCEPTION_RECORD 結(jié)構(gòu)中的第四個(gè)元素是異常發(fā)生的地址。剩下的 EXCEPTION_RECORD 域現(xiàn)在可以忽略,不用管它。
  _except_handler 回調(diào)函數(shù)的第二個(gè)參數(shù)是指向建立者框架(establisher frame)結(jié)構(gòu)的指針,在 SEH 中它是一個(gè)至關(guān)重要的參數(shù),但現(xiàn)在可以不用關(guān)心它。
  _except_handler 回調(diào)函數(shù)的第三個(gè)參數(shù)是 CONTEXT 結(jié)構(gòu)的指針。CONTEXT 結(jié)構(gòu)在 WINNT.H 中定義,它表示特定線程異常發(fā)生時(shí)寄存器的值:

    typedef struct _CONTEXT
{
DWORD ContextFlags;
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;
FLOATING_SAVE_AREA FloatSave;
DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;
DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
DWORD Ebp;
DWORD Eip;
DWORD SegCs;
DWORD EFlags;
DWORD Esp;
DWORD SegSs;
} CONTEXT;
  

此外,這個(gè) CONTEXT 結(jié)構(gòu)與 GetThreadContext 和 SetThreadContext API 函數(shù)使用的結(jié)構(gòu)是相同的。
_except_handler 回調(diào)函數(shù)的第四個(gè)參數(shù)是 DispatcherContext。現(xiàn)在也可以忽略它。
  為了簡(jiǎn)化起見(jiàn),當(dāng)異常發(fā)生時(shí),你有一個(gè)回調(diào)函數(shù)被調(diào)用。此回調(diào)函數(shù)帶四個(gè)參數(shù),其中三個(gè)是結(jié)構(gòu)指針。在這些結(jié)構(gòu)中,某些域是很重要的,其余的不是那么重要。關(guān)鍵是 _except_handler 回調(diào)函數(shù)接收
很多信息,比如發(fā)生了什么類型的異常,在哪里發(fā)生的。利用這些信息,異常回調(diào)機(jī)制需要確定要做什么。
  雖然我迫不急但地想拋出例子程序示范 _except_handler 回調(diào)的運(yùn)行,但還有一些事情不能漏掉,需要說(shuō)明。特別是當(dāng)錯(cuò)誤發(fā)生時(shí),操作系統(tǒng)如何知道到哪里調(diào)用?答案仍然涉及另外一個(gè)結(jié)構(gòu) EXCEPTION_REGISTRATION。你將自始自終在本文中看到這個(gè)結(jié)構(gòu),所以不要掠過(guò)這部分內(nèi)容。我能找到正式定義 EXCEPTION_REGISTRATION 結(jié)構(gòu)的唯一地方是 EXSUP.INC 文件,該文件來(lái)自 Visual C++ 運(yùn)行庫(kù)的源:

    _EXCEPTION_REGISTRATION struc
prev dd ?
handler dd ?
_EXCEPTION_REGISTRATION ends
  

  你還將看到該結(jié)構(gòu)在 WINNT.H 文件中定義的 NT_TIB 結(jié)構(gòu)中被引用為 _EXCEPTION_REGISTRATION_RECORD。唉,除此之外,沒(méi)有什么地方能找到 _EXCEPTION_REGISTRATION_RECORD 的定義,所以我只能使用 EXSUP.INC 文件中定義的匯編語(yǔ)言結(jié)構(gòu)。這也是我為什么在本文前述內(nèi)容中說(shuō)過(guò)的 SEH 缺乏文檔的一個(gè)例證。
  不管怎樣,讓我們回到手頭的問(wèn)題,當(dāng)某個(gè)異常發(fā)生時(shí),OS 如何知道到哪里調(diào)用回調(diào)函數(shù)?EXCEPTION_REGISTRATION 由兩個(gè)域構(gòu)成,第一個(gè)你現(xiàn)在可以忽略。第二個(gè)域是句柄,它包含 _except_handler 回調(diào)函數(shù)的指針。這讓你更接近一點(diǎn)了,但目前問(wèn)題來(lái)了,OS 在哪里查找并發(fā)現(xiàn) EXCEPTION_REGISTRATION 結(jié)構(gòu)?
  為了回答這個(gè)問(wèn)題,回想一下結(jié)構(gòu)化異常處理是以線程為基礎(chǔ),并作用在每個(gè)線程上,明白這一點(diǎn)是有助于理解的。也就是說(shuō),每個(gè)線程具備其自己的異常處理回調(diào)函數(shù)。在我 1996年5月的專欄文章 中,我描述了一個(gè)關(guān)鍵的 Win32 數(shù)據(jù)結(jié)構(gòu)——線程信息塊(即 TEB 和 TIB)。該數(shù)據(jù)結(jié)構(gòu)的某些域在 Windows NT、Windows 95、Win32s 和 OS/2 平臺(tái)上是一樣的。TIB 中的第一個(gè) DWORD 是指向線程 EXCEPTION_REGISTRATION 結(jié)構(gòu)的指針。在 Intel Win32 平臺(tái)上,F(xiàn)S 寄存器總是指向當(dāng)前的 TIB。因此,在 FS:[0]位置,你能找到 EXCEPTION_REGISTRATION 結(jié)構(gòu)的指針。
  現(xiàn)在我們知道了,當(dāng)異常發(fā)生時(shí),系統(tǒng)檢查出錯(cuò)線程的 TIB 并獲取 EXCEPTION_REGISTRATION 結(jié)構(gòu)的指針。這個(gè)結(jié)構(gòu)中就有一個(gè) _except_handler 回調(diào)函數(shù)的指針。這些信息足以讓操作系統(tǒng)知道在哪里以及如何調(diào)用 _except_handler 函數(shù),如圖二所示:

Win32 結(jié)構(gòu)化異常處理(SEH)探秘
圖二 _except_handler 函數(shù)

  通過(guò)前面的描述,我寫了一個(gè)小程序來(lái)對(duì)操作系統(tǒng)層的結(jié)構(gòu)化異常進(jìn)行示范。程序代碼如下:

     //==================================================
 // MYSEH - Matt Pietrek 1997
 // Microsoft Systems Journal, January 1997
 // FILE: MYSEH.CPP
 // To compile: CL MYSEH.CPP
 //==================================================
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

DWORD  scratch;

EXCEPTION_DISPOSITION
__cdecl
_except_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT *ContextRecord,
    void * DispatcherContext )
{
    unsigned i;

    // Indicate that we made it to our exception handler
    printf( "Hello from an exception handler/n" );

    // Change EAX in the context record so that it points to someplace
    // where we can successfully write
    ContextRecord->Eax = (DWORD)&scratch;

    // Tell the OS to restart the faulting instruction
    return ExceptionContinueExecution;
}

int main()
{
    DWORD handler = (DWORD)_except_handler; 
    __asm
    { 
        // 創(chuàng)建 EXCEPTION_REGISTRATION 結(jié)構(gòu):
        push handler 	// handler函數(shù)的地址
        push FS:[0] 	// 前一個(gè)handler函數(shù)的地址
        mov FS:[0],ESP 	// 裝入新的EXECEPTION_REGISTRATION結(jié)構(gòu)
    } 
    __asm
    {
        mov eax,0     	// EAX清零
        mov [eax], 1 	// 寫EAX指向的內(nèi)存從而故意引發(fā)一個(gè)錯(cuò)誤
    } 
    printf( "After writing!/n" ); 
    __asm
    { 
        // 移去我們的 EXECEPTION_REGISTRATION 結(jié)構(gòu)記錄
        mov eax,[ESP]    	// 獲取前一個(gè)結(jié)構(gòu)
        mov FS:[0], EAX 	// 裝入前一個(gè)結(jié)構(gòu)
        add esp, 8       	// 將 EXECEPTION_REGISTRATION 彈出堆棧
    } 
    return 0; 
} 

  

  代碼中只有兩個(gè)函數(shù),main 函數(shù)使用了三部分內(nèi)聯(lián)匯編塊 ASM。第一個(gè) ASM 塊通過(guò)兩個(gè) PUSH 指令(即:“PUSH handler”和“PUSH FS:[0]”)在堆棧上建立一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)。PUSH FS:[0] 保存以前 FS:[0] 的值,它是結(jié)構(gòu)的一部分,但目前這個(gè)值對(duì)我們不重要。重要的是在堆棧上有一個(gè) 8-byte 的 EXCEPTION_REGISTRATION 結(jié)構(gòu)。緊接著的指令(MOV FS:[0],ESP)是讓線程信息塊中的第一個(gè) DWORD 指到新的 EXCEPTION_REGISTRATION 指令。
  如果你想知道為什么我要在堆棧上建立這個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu),而不是使用全局變量,有一個(gè)很好的理由。當(dāng)你使用編譯器的 _try/_except 時(shí),編譯器也會(huì)在堆棧上建立 EXCEPTION_REGISTRATION 結(jié)構(gòu)。我只是向你簡(jiǎn)要地揭示你使用 _try/_except 時(shí)編譯器所做的事情。讓我們回到 main 函數(shù),下一個(gè) __asm 塊是通過(guò)把 EAX 寄存器清零(MOV EAX,0),然后把此寄存器的值作為內(nèi)存地址讓下一條指令(MOV [EAX],1)向此地址寫入數(shù)據(jù)而故意引發(fā)一個(gè)錯(cuò)誤。最后一個(gè) __asm 塊是清除這個(gè)簡(jiǎn)單的異常處理例程:首先它恢復(fù)以前的 FS:[0] 內(nèi)容,然后它將 EXCEPTION_REGISTRATION 結(jié)構(gòu)記錄從堆棧中彈出(ADD ESP,8)。
現(xiàn)在,假設(shè)你正在運(yùn)行 MYSEH.EXE 并會(huì)看到所發(fā)生的事情。當(dāng) MOV [EAX],1 指令執(zhí)行時(shí),它導(dǎo)致一個(gè)數(shù)據(jù)訪問(wèn)違例。系統(tǒng)察看 TIB 中的 FS:[0] 并找到 EXCEPTION_REGISTRATION 結(jié)構(gòu)指針。此結(jié)構(gòu)中則有一個(gè)指向 MYSEH.CPP 中 _except_handler 函數(shù)的指針。系統(tǒng)則將四個(gè)必須的參數(shù)(我在前面描述過(guò)這四個(gè)參數(shù))壓入堆棧并調(diào)用 _except_handler 函數(shù)。
  一旦進(jìn)入 _except_handler,代碼首先通過(guò) printf 指示“哈!這里是我干的!”。接著,_except_handler 修復(fù)導(dǎo)致出錯(cuò)的問(wèn)題。即 EAX 寄存器指向某個(gè)不能寫入的內(nèi)存地址(地址 0)。修復(fù)方法是在改變 CONTEXT 結(jié)構(gòu)中的 EAX 的值,以便它指向某個(gè)允許進(jìn)行寫入操作的位置。在這個(gè)簡(jiǎn)單的程序中,DWORD 變量(scratch)是故意為此而設(shè)計(jì)的。_except_handler 函數(shù)最后一個(gè)動(dòng)作時(shí)返回 ExceptionContinueExecution 值,它在標(biāo)準(zhǔn)的 EXCPT.H 文件中定義。
  當(dāng)操作系統(tǒng)看到返回值為 ExceptionContinueExecution。它就認(rèn)為你已經(jīng)修復(fù)了問(wèn)題,并且引起錯(cuò)誤的指令應(yīng)該被重新執(zhí)行。因?yàn)槲业?_except_handler 函數(shù)強(qiáng)制 EAX 寄存器指向合法內(nèi)存,MOV EAX,1 指令再次執(zhí)行,函數(shù) main 一切正常。看,這并不復(fù)雜,不是嗎?


進(jìn)一步深入

  有了前面的最簡(jiǎn)單的例子,讓我們?cè)倩剡^(guò)頭去填補(bǔ)一些空白。雖然這個(gè)異常回調(diào)機(jī)制很棒,但它并不是一個(gè)完美的解決方案。對(duì)于稍微復(fù)雜一些的應(yīng)用程序來(lái)說(shuō),僅用一個(gè)函數(shù)就能處理程序中任何地方都可能發(fā)生的異常是相當(dāng)困難的。一個(gè)更實(shí)用的方案應(yīng)該是有多個(gè)異常處理例程,每個(gè)例程針對(duì)程序的特定部分。不知你是否知道,實(shí)際上,操作系統(tǒng)提供的正是這個(gè)功能。
  還記得系統(tǒng)用來(lái)查找異常回調(diào)函數(shù)的 EXCEPTION_REGISTRATION 結(jié)構(gòu)嗎?這個(gè)結(jié)構(gòu)的第一個(gè)成員,稱為 prev,前面我們?cè)阉雎缘袅恕K鼘?shí)際上是一個(gè)指向另外一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)的指針。這第二個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)可以有一個(gè)完全不同的處理函數(shù)。然后呢,它的 prev 域可以指向第三個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu),依次類推。簡(jiǎn)單地說(shuō),就是有一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表。線程信息塊的第一個(gè) DWORD(在基于 Intel CPU 的機(jī)器上是 FS:[0])總是指向這個(gè)鏈表的頭部。
  操作系統(tǒng)要這個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表做什么呢?原來(lái),當(dāng)異常發(fā)生時(shí),系統(tǒng)遍歷這個(gè)鏈表以便查找其中的一個(gè)EXCEPTION_REGISTRATION 結(jié)構(gòu),其例程回調(diào)(異常處理程序)同意處理該異常。在 MYSEH.CPP 的例子中,異常處理程序通過(guò)返回ExceptionContinueExecution 表示它同意處理這個(gè)異常。異常回調(diào)函數(shù)也可以拒絕處理這個(gè)異常。在這種情況下,系統(tǒng)移向鏈表的下一個(gè)EXCEPTION_REGISTRATION 結(jié)構(gòu)并詢問(wèn)它的異常回調(diào)函數(shù),看它是否愿意處理這個(gè)異常。圖四顯示了這個(gè)過(guò)程:

Win32 結(jié)構(gòu)化異常處理(SEH)探秘

圖四 查找處理異常的 EXCEPTION_REGISTRATION 結(jié)構(gòu)

一旦系統(tǒng)找到一個(gè)處理該異常的某個(gè)回調(diào)函數(shù),它就停止遍歷結(jié)構(gòu)鏈表。

  下面的代碼 MYSEH2.CPP 就是一個(gè)異常處理函數(shù)不處理某個(gè)異常的例子。為了使代碼盡量簡(jiǎn)單,我使用了編譯器層面的異常處理。main 函數(shù)只設(shè)置了一個(gè) __try/__except塊。在__try 塊內(nèi)部調(diào)用了 HomeGrownFrame 函數(shù)。這個(gè)函數(shù)與前面的 MYSEH 程序非常相似。它也是在堆棧上創(chuàng)建一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu),并且讓 FS:[0] 指向此結(jié)構(gòu)。在建立了新的異常處理程序之后,這個(gè)函數(shù)通過(guò)向一個(gè) NULL 指針?biāo)赶虻膬?nèi)存處寫入數(shù)據(jù)而故意引發(fā)一個(gè)錯(cuò)誤:

    *(PDWORD)0 = 0; 
  

  這個(gè)異常處理回調(diào)函數(shù),同樣被稱為_(kāi)except_handler,卻與前面的那個(gè)截然不同。它首先打印出 ExceptionRecord 結(jié)構(gòu)中的異常代碼和標(biāo)志,這個(gè)結(jié)構(gòu)的地址是作為一個(gè)指針參數(shù)被這個(gè)函數(shù)接收的。打印出異常標(biāo)志的原因稍后就會(huì)明白。因?yàn)開(kāi)except_handler 函數(shù)并沒(méi)有打算修復(fù)出錯(cuò)的代碼,因此它返回 ExceptionContinueSearch。這導(dǎo)致操作系統(tǒng)繼續(xù)在 EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表中搜索下一個(gè) EXCEPTION_REGISTRATION結(jié)構(gòu)。接下來(lái)安裝的異常回調(diào)函數(shù)是針對(duì) main 函數(shù)中的__try/__except塊的。__except 塊簡(jiǎn)單地打印出“Caught the exception in main()”。此時(shí)我們只是簡(jiǎn)單地忽略這個(gè)異常來(lái)表明我們已經(jīng)處理了它。 以下是 MYSEH2.CPP:

    //=================================================
// MYSEH2 - Matt Pietrek 1997
// Microsoft Systems Journal, January 1997
// FILE: MYSEH2.CPP
// 使用命令行CL MYSEH2.CPP編譯
//================================================= 
#define WIN32_LEAN_AND_MEAN 
#include <windows.h>
#include <stdio.h> 
EXCEPTION_DISPOSITION
__cdecl _except_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
	void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
	void * DispatcherContext )
{ 
	printf( "Home Grown handler: Exception Code: %08X Exception Flags %X",
		ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionFlags ); 
	if ( ExceptionRecord->ExceptionFlags & 1 )
		printf( " EH_NONCONTINUABLE" ); 
	if ( ExceptionRecord->ExceptionFlags & 2 )
		printf( " EH_UNWINDING" ); 
	if ( ExceptionRecord->ExceptionFlags & 4 )
		printf( " EH_EXIT_UNWIND" ); 
	if ( ExceptionRecord->ExceptionFlags & 8 ) 	// 注意這個(gè)標(biāo)志
		printf( " EH_STACK_INVALID" ); 
	if ( ExceptionRecord->ExceptionFlags & 0x10 )   // 注意這個(gè)標(biāo)志
		printf( " EH_NESTED_CALL" ); 
	printf( "/n" ); 
	// 我們不想處理這個(gè)異常,讓其它函數(shù)處理吧
	return ExceptionContinueSearch; 
} 
void HomeGrownFrame( void )
{ 
	DWORD handler = (DWORD)_except_handler; 
	__asm
	{
		// 創(chuàng)建EXCEPTION_REGISTRATION結(jié)構(gòu):
		push handler       	// handler函數(shù)的地址
			push FS:[0]        // 前一個(gè)handler函數(shù)的地址
		mov FS:[0],ESP     	// 安裝新的EXECEPTION_REGISTRATION結(jié)構(gòu)
	} 
	*(PDWORD)0 = 0; 			// 寫入地址0,從而引發(fā)一個(gè)錯(cuò)誤 
	printf( "I should never get here!/n" ); 
	__asm
	{
		// 移去我們的EXECEPTION_REGISTRATION結(jié)構(gòu)
		mov eax,[ESP]     		// 獲取前一個(gè)結(jié)構(gòu)
		mov FS:[0], EAX 		// 安裝前一個(gè)結(jié)構(gòu)
			add esp, 8        // 把我們EXECEPTION_REGISTRATION結(jié)構(gòu)彈出堆棧
	} 
} 
int main()
{ 
	__try
	{
		HomeGrownFrame();
	} 
	__except( EXCEPTION_EXECUTE_HANDLER )
	{
		printf( "Caught the exception in main()/n" );
	} 
	return 0; 
} 

  

  這里的關(guān)鍵是執(zhí)行流程。當(dāng)一個(gè)異常處理程序拒絕處理某個(gè)異常時(shí),它實(shí)際上也就拒絕決定流程最終將從何處恢復(fù)。只有接受某個(gè)異常的異常處理程序才能決定待所有異常處理代碼執(zhí)行完畢之后流程將從何處繼續(xù)執(zhí)行。這個(gè)規(guī)則暗含的意義非常重大,雖然現(xiàn)在還不是顯而易見(jiàn)。
  當(dāng)使用結(jié)構(gòu)化異常處理時(shí),如果一個(gè)函數(shù)有一個(gè)異常處理程序但它卻不處理某個(gè)異常,這個(gè)函數(shù)就有可能非正常退出。例如在 MYSEH2中 HomeGrownFrame 函數(shù)就不處理異常。由于在鏈表中后面的某個(gè)異常處理程序(這里是 main 函數(shù)中的)處理了這個(gè)異常,因此出錯(cuò)指令后面的 printf 就永遠(yuǎn)不會(huì)執(zhí)行。從某種程度上說(shuō),使用結(jié)構(gòu)化異常處理與使用 setjmp 和 longjmp 運(yùn)行時(shí)庫(kù)函數(shù)有些類似。
  如果你運(yùn)行 MYSEH2,會(huì)發(fā)現(xiàn)其輸出有些奇怪。看起來(lái)好像調(diào)用了兩次 _except_handler 函數(shù)。根據(jù)你現(xiàn)有的知識(shí),第一次調(diào)用當(dāng)然可以完全理解。但是為什么會(huì)有第二次呢?

    Home Grown handler: Exception Code: C0000005 Exception Flags 0
Home Grown handler: Exception Code: C0000027 Exception Flags 2 EH_UNWINDING
Caught the Exception in main() 
  

  比較一下以“Home Grown Handler”開(kāi)頭的兩行,就會(huì)看出它們之間有明顯的區(qū)別。第一次異常標(biāo)志是0,而第二次是2。這個(gè)問(wèn)題說(shuō)來(lái)話就長(zhǎng)了。實(shí)際上,當(dāng)一個(gè)異常處理回調(diào)函數(shù)拒絕處理某個(gè)異常時(shí),它會(huì)被再一次調(diào)用。但是這次回調(diào)并不是立即發(fā)生的。這有點(diǎn)復(fù)雜。我需要把異常發(fā)生時(shí)的情形好好梳理一下。
  當(dāng)異常發(fā)生時(shí),系統(tǒng)遍歷 EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表,直到它找到一個(gè)處理這個(gè)異常的處理程序。一旦找到,系統(tǒng)就再次遍歷這個(gè)鏈表,直到處理這個(gè)異常的結(jié)點(diǎn)為止。在這第二次遍歷中,系統(tǒng)將再次調(diào)用每個(gè)異常處理函數(shù)。關(guān)鍵的區(qū)別是,在第二次調(diào)用中,異常標(biāo)志被設(shè)置為2。這個(gè)值被定義為 EH_UNWINDING。(EH_UNWINDING 的定義在 Visual C++ 運(yùn)行時(shí)庫(kù)源代碼文件 EXCEPT.INC 中,但 Win32 SDK 中并沒(méi)有與之等價(jià)的定義。)
  EH_UNWINDING 表示什么意思呢?原來(lái),當(dāng)一個(gè)異常處理回調(diào)函數(shù)被第二次調(diào)用時(shí)(帶 EH_UNWINDING 標(biāo)志),操作系統(tǒng)給這個(gè)函數(shù)一個(gè)最后清理的機(jī)會(huì)。什么樣的清理呢?一個(gè)絕好的例子是 C++ 類的析構(gòu)函數(shù)。當(dāng)一個(gè)函數(shù)的異常處理程序拒絕處理某個(gè)異常時(shí),通常執(zhí)行流程并不會(huì)正常地從那個(gè)函數(shù)退出。現(xiàn)在,想像一下定義了一個(gè)C++類的實(shí)例作為局部變量的函數(shù)。C++規(guī)范規(guī)定析構(gòu)函數(shù)必須被調(diào)用。這帶 EH_UNWINDING 標(biāo)志的第二次回調(diào)就給這個(gè)函數(shù)一個(gè)機(jī)會(huì)去做一些類似于調(diào)用析構(gòu)函數(shù)和__finally 塊之類的清理工作。
  在異常已經(jīng)被處理完畢,并且所有前面的異常幀都已經(jīng)被展開(kāi)之后,流程從處理異常的那個(gè)回調(diào)函數(shù)決定的地方開(kāi)始繼續(xù)執(zhí)行。一定要記住,僅僅把指令指針設(shè)置到所需的代碼處就開(kāi)始執(zhí)行是不行的。流程恢復(fù)執(zhí)行處的代碼的堆棧指針和棧幀指針(在Intel CPU上是 ESP 和EBP)也必須被恢復(fù)成它們?cè)谔幚磉@個(gè)異常的函數(shù)的棧幀上的值。因此,這個(gè)處理異常的回調(diào)函數(shù)必須負(fù)責(zé)把堆棧指針和棧幀指針恢復(fù)成它們?cè)诎幚磉@個(gè)異常的 SEH 代碼的函數(shù)的堆棧上的值。
  通常,展開(kāi)操作導(dǎo)致堆棧上處理異常的幀以下的堆棧區(qū)域上的所有內(nèi)容都被移除了,就好像我們從來(lái)沒(méi)有調(diào)用過(guò)這些函數(shù)一樣。展開(kāi)的另外一個(gè)效果就是 EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表上處理異常的那個(gè)結(jié)構(gòu)之前的所有 EXCEPTION_REGISTRATION 結(jié)構(gòu)都被移除了。這很好理解,因?yàn)檫@些 EXCEPTION_REGISTRATION 結(jié)構(gòu)通常都被創(chuàng)建在堆棧上。在異常被處理后,堆棧指針和棧幀指針在內(nèi)存中比那些從 EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表上移除的 EXCEPTION_REGISTRATION 結(jié)構(gòu)高。圖六顯示了我說(shuō)的情況。

Win32 結(jié)構(gòu)化異常處理(SEH)探秘
圖六 從異常展開(kāi)

幫幫我!沒(méi)有人處理它!

  迄今為止,我實(shí)際上一直在假設(shè)操作系統(tǒng)總是能在 EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表中 的某個(gè)地方找到一個(gè)異常處理程序。如果找不到怎么辦呢?實(shí)際上,這幾乎不可能發(fā)生。因?yàn)椴僮飨到y(tǒng)暗中已經(jīng)為每個(gè)線程都提供了一個(gè)默認(rèn)的異常處理程序。這個(gè)默認(rèn)的異常處理程序總是鏈表的最后一個(gè)結(jié)點(diǎn),并且它總是選擇處理異常。它進(jìn)行的操作與其它正常的異常處理回調(diào)函數(shù)有些不同,下面我會(huì)說(shuō)明。
  讓我們來(lái)看一下系統(tǒng)是在什么時(shí)候插入了這個(gè)默認(rèn)的、最后一個(gè)異常處理程序。很明顯它需要在線程執(zhí)行的早期,在任何用戶代碼開(kāi)始執(zhí)行之前。
  下面是我為 BaseProcessStart 函數(shù)寫的偽代碼。它是 Windows NT KERNEL32.DLL 的一個(gè)內(nèi)部例程。這個(gè)函數(shù)帶一個(gè)參數(shù)——線程入口點(diǎn)函數(shù)的地址。BaseProcessStart 運(yùn)行在新進(jìn)程的上下文環(huán)境中,并且從該進(jìn)程的第一個(gè)線程的入口點(diǎn)函數(shù)開(kāi)始執(zhí)行。

     BaseProcessStart 偽碼 
 BaseProcessStart( PVOID lpfnEntryPoint )
 {
     DWORD retValue
     DWORD currentESP;
     DWORD exceptionCode;
 
     currentESP = ESP;
 
     _try
     {
         NtSetInformationThread( GetCurrentThread(),
                                 ThreadQuerySetWin32StartAddress,
                                 &lpfnEntryPoint, sizeof(lpfnEntryPoint) );
 
         retValue = lpfnEntryPoint();
 
         ExitThread( retValue );
     }
     _except(// 過(guò)濾器-表達(dá)式代碼
             exceptionCode = GetExceptionInformation(),
             UnhandledExceptionFilter( GetExceptionInformation() ) )
     {
         ESP = currentESP;
 
         if ( !_BaseRunningInServerProcess )         // 常規(guī)進(jìn)程
             ExitProcess( exceptionCode );
         else                                        // 服務(wù)
             ExitThread( exceptionCode );
     }
 }
  

  在這段偽碼中,注意對(duì) lpfnEntryPoint 的調(diào)用被封裝在一個(gè)__try 和 __except 塊中。正是此__try 塊安裝了默認(rèn)的、異常處理程序鏈表上的最后一個(gè)異常處理程序。所有后來(lái)注冊(cè)的異常處理程序都被安裝在此鏈表中這個(gè)結(jié)點(diǎn)的前面。如果 lpfnEntryPoint 函數(shù)返回,那么表明線程一直運(yùn)行到完成并且沒(méi)有引發(fā)異常。這時(shí) BaseProcessStart 調(diào)用 ExitThread 使線程退出。
  另一方面,如果線程引發(fā)了一個(gè)異常但是沒(méi)有異常處理程序來(lái)處理它時(shí),該怎么辦呢?這時(shí),執(zhí)行流程轉(zhuǎn)到 __except 關(guān)鍵字后面的括號(hào)中。在 BaseProcessStart 中,這段代碼調(diào)用 UnhandledExceptionFilter 這個(gè) API,稍后我會(huì)講到它。現(xiàn)在對(duì)于我們來(lái)說(shuō),重要的是 UnhandledExceptionFilter 這個(gè)API包含了默認(rèn)的異常處理程序。
  如果 UnhandledExceptionFilter 返回 EXCEPTION_EXECUTE_HANDLER,這時(shí) BaseProcessStart 中的__except 塊開(kāi)始執(zhí)行。而__except塊所做的只是調(diào)用 ExitProcess 函數(shù)去終止當(dāng)前進(jìn)程。稍微想一下你就會(huì)理解了。常識(shí)告訴我們,如果一個(gè)進(jìn)程引發(fā)了一個(gè)錯(cuò)誤而沒(méi)有異常處理程序去處理它,這個(gè)進(jìn)程就會(huì)被系統(tǒng)終止。你在偽代碼中看到的正是這些。
  對(duì)于上述內(nèi)容我還有一點(diǎn)要補(bǔ)充。如果引發(fā)錯(cuò)誤的線程是作為服務(wù)來(lái)運(yùn)行的,并且是基于線程的服務(wù),那么__except 塊并不調(diào)用 ExitProcess,而是調(diào)用 ExitThread。不能僅僅因?yàn)橐粋€(gè)服務(wù)出錯(cuò)就終止整個(gè)服務(wù)進(jìn)程。
  UnhandledExceptionFilter 中的默認(rèn)異常處理程序都做了什么呢?當(dāng)我在一個(gè)技術(shù)講座上問(wèn)起這個(gè)問(wèn)題時(shí),響應(yīng)者寥寥無(wú)幾。幾乎沒(méi)有人知道當(dāng)未處理異常發(fā)生時(shí),到底操作系統(tǒng)的默認(rèn)行為是什么。簡(jiǎn)單地演示一下這個(gè)默認(rèn)的行為也許會(huì)讓很多人豁然開(kāi)朗。我運(yùn)行一個(gè)故意引發(fā)錯(cuò)誤的程序,其結(jié)果如下(如圖八)。

Win32 結(jié)構(gòu)化異常處理(SEH)探秘
圖八 未處理異常對(duì)話框

  表面上看,UnhandledExceptionFilter 顯示了一個(gè)對(duì)話框告訴你發(fā)生了一個(gè)錯(cuò)誤。這時(shí),你被給予了一個(gè)機(jī)會(huì)要么終止出錯(cuò)進(jìn)程,要么調(diào)試它。但是幕后發(fā)生了許多事情,我會(huì)在文章最后詳細(xì)講述它。
  正如我讓你看到的那樣,當(dāng)異常發(fā)生時(shí),用戶寫的代碼可以(并且通常是這樣)獲得機(jī)會(huì)執(zhí)行。同樣,在操作過(guò)程中,用戶寫的代碼可以執(zhí)行。此用戶編寫的代碼也可能有缺陷并可能引發(fā)另一個(gè)異常。由于這個(gè)原因,異常處理回調(diào)函數(shù)也可以返回另外兩個(gè)值: ExceptionNestedException 和 ExceptionCollidedUnwind。很明顯,它們很重要。但這是非常復(fù)雜的問(wèn)題,我并不打算在這里詳細(xì)講述它們。要想理解其基本概念真的太困難了。

編譯器級(jí)的SEH

  雖然我在前面偶爾也使用了__try 和__except,但迄今為止幾乎我寫的所有內(nèi)容都是關(guān)于操作系統(tǒng)方面對(duì) SEH 的實(shí)現(xiàn)。然而看一下我那兩個(gè)使用操作系統(tǒng)的原始 SEH 的小程序別扭的樣子,編譯器對(duì)這個(gè)功能進(jìn)行封裝實(shí)在是非常有必要的。現(xiàn)在讓我們來(lái)看一下 Visual C++ 是如何在操作系統(tǒng)對(duì) SEH 功能實(shí)現(xiàn)的基礎(chǔ)上來(lái)創(chuàng)建它自己的結(jié)構(gòu)化異常處理支持的。
  在繼續(xù)往下討論之前,記住其它編譯器可以使用原始的系統(tǒng) SEH 來(lái)做一些完全不同的事情這一點(diǎn)是非常重要的。沒(méi)有誰(shuí)規(guī)定編譯器必須實(shí)現(xiàn) Win32 SDK 文檔中描述的__try/__except 模型。例如 Visual Basic 5.0 在它的運(yùn)行時(shí)代碼中使用了結(jié)構(gòu)化異常處理,但是那里的數(shù)據(jù)結(jié)構(gòu)和算法與我這里要講的完全不同。
  如果你把 Win32 SDK 文檔中關(guān)于結(jié)構(gòu)化異常處理方面的內(nèi)容從頭到尾讀一遍,一定會(huì)遇到下面所謂的“基于幀”的異常處理程序模型:

    __try {
// 這里是被保護(hù)的代碼
}
__except (過(guò)濾器表達(dá)式) { 
// 這里是異常處理程序代碼
} 
  

  簡(jiǎn)單地說(shuō),某個(gè)函數(shù)__try 塊中的所有代碼是由 EXCEPTION_REGISTRATION 結(jié)構(gòu)來(lái)保護(hù)的,該結(jié)構(gòu)建立在此函數(shù)的堆棧幀上。在函數(shù)的入口處,這個(gè)新的 EXCEPTION_REGISTRATION 結(jié)構(gòu)被放在異常處理程序鏈表的頭部。在__try 塊結(jié)束后,相應(yīng)的 EXCEPTION_REGISTRATION 結(jié)構(gòu)從這個(gè)鏈表的頭部被移除。正如我前面所說(shuō),異常處理程序鏈表的頭部被保存在 FS:[0] 處。因此,如果你在調(diào)試器中單步跟蹤時(shí)能看到類似下面的指令

    MOV DWORD PTR FS:[00000000],ESP
或者
MOV DWORD PTR FS:[00000000],ECX 
  

就能非常確定這段代碼正在進(jìn)入或退出一個(gè)__try/__except塊。

  既然一個(gè)__try 塊對(duì)應(yīng)著堆棧上的一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu),那么 EXCEPTION_REGISTRATION 結(jié)構(gòu)中的回調(diào)函數(shù)又如何呢?使用 Win32 的術(shù)語(yǔ)來(lái)說(shuō),異常處理回調(diào)函數(shù)對(duì)應(yīng)的是過(guò)濾器表達(dá)式(filter-expression)代碼。事實(shí)上,過(guò)濾器表達(dá)式就是__except 關(guān)鍵字后面的小括號(hào)中的代碼。就是這個(gè)過(guò)濾器表達(dá)式代碼決定了后面的大括號(hào)中的代碼是否執(zhí)行。
  由于過(guò)濾器表達(dá)式代碼是你自己寫的,你當(dāng)然可以決定在你的代碼中的某個(gè)地方是否處理某個(gè)特定的異常。它可以簡(jiǎn)單的只是一句 “EXCEPTION_EXECUTE_HANDLER”,也可以先調(diào)用一個(gè)把p計(jì)算到20,000,000位的函數(shù),然后再返回一個(gè)值來(lái)告訴操作系統(tǒng)下一步做什么。隨你的便。關(guān)鍵是你的過(guò)濾器表達(dá)式代碼必須是我前面講的有效的異常處理回調(diào)函數(shù)。
  我剛才講的雖然相當(dāng)簡(jiǎn)單,但那只不過(guò)是隔著有色玻璃看世界罷了。現(xiàn)實(shí)是非常復(fù)雜的。首先,你的過(guò)濾器表達(dá)式代碼并不是被操作系統(tǒng)直接調(diào)用的。事實(shí)上,各個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)的 handler 域都指向了同一個(gè)函數(shù)。這個(gè)函數(shù)在 Visual C++ 的運(yùn)行時(shí)庫(kù)中,它被稱為_(kāi)_except_handler3。正是這個(gè)__except_handler3 調(diào)用了你的過(guò)濾器表達(dá)式代碼,我一會(huì)兒再接著說(shuō)它。
  對(duì)我前面的簡(jiǎn)單描述需要修正的另一個(gè)地方是,并不是每次進(jìn)入或退出一個(gè)__try 塊時(shí)就創(chuàng)建或撤銷一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)。相反,在使用 SEH 的任何函數(shù)中只創(chuàng)建一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)。換句話說(shuō),你可以在一個(gè)函數(shù)中使用多個(gè) __try/__except 塊,但是在堆棧上只創(chuàng)建一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)。同樣,你可以在一個(gè)函數(shù)中嵌套使用 __try 塊,但 Visual C++ 仍舊只是創(chuàng)建一個(gè) EXCEPTION_REGISTRATION 結(jié)構(gòu)。
  如果整個(gè) EXE 或 DLL 只需要單個(gè)的異常處理程序(__except_handler3),同時(shí),如果單個(gè)的 EXCEPTION_REGISTRATION 結(jié)構(gòu)就能處理多個(gè)__try 塊的話,很明顯,這里面還有很多東西我們不知道。這個(gè)技巧是通過(guò)一個(gè)通常情況下看不到的表中的數(shù)據(jù)來(lái)完成的。由于本文的目的就是要深入探索結(jié)構(gòu)化異常處理,那就讓我們來(lái)看一看這些數(shù)據(jù)結(jié)構(gòu)吧。

擴(kuò)展的異常處理幀

  Visual C++ 的 SEH 實(shí)現(xiàn)并沒(méi)有使用原始的 EXCEPTION_REGISTRATION 結(jié)構(gòu)。它在這個(gè)結(jié)構(gòu)的末尾添加了一些附加數(shù)據(jù)。這些附加數(shù)據(jù)正是允許單個(gè)函數(shù)(__except_handler3)處理所有異常并將執(zhí)行流程傳遞到相應(yīng)的過(guò)濾器表達(dá)式和__except 塊的關(guān)鍵。我在 Visual C++ 運(yùn)行時(shí)庫(kù)源代碼中的 EXSUP.INC 文件中找到了有關(guān) Visual C++ 擴(kuò)展的 EXCEPTION_REGISTRATION 結(jié)構(gòu)格式的線索。在這個(gè)文件中,你會(huì)看到以下定義(已經(jīng)被注釋掉了):

    ;struct _EXCEPTION_REGISTRATION{
; struct _EXCEPTION_REGISTRATION *prev;
; void (*handler)( PEXCEPTION_RECORD,
; PEXCEPTION_REGISTRATION,
; PCONTEXT,
; PEXCEPTION_RECORD);
; struct scopetable_entry *scopetable;
; int trylevel;
; int _ebp;
; PEXCEPTION_POINTERS xpointers;
;}; 
  

  在前面你已經(jīng)見(jiàn)過(guò)前兩個(gè)域:prev 和 handler。它們組成了基本的 EXCEPTION_REGISTRATION 結(jié)構(gòu)。后面三個(gè)域:scopetable(作用域表)、trylevel 和_ebp 是新增加的。scopetable 域指向一個(gè) scopetable_entry 結(jié)構(gòu)數(shù)組,而 trylevel 域?qū)嶋H上是這個(gè)數(shù)組的索引。最后一個(gè)域_ebp,是 EXCEPTION_REGISTRATION 結(jié)構(gòu)創(chuàng)建之前棧幀指針(EBP)的值。
  _ebp 域成為擴(kuò)展的 EXCEPTION_REGISTRATION 結(jié)構(gòu)的一部分并非偶然。它是通過(guò) PUSH EBP 這條指令被包含進(jìn)這個(gè)結(jié)構(gòu)中的,而大多數(shù)函數(shù)開(kāi)頭都是這條指令(通常編譯器并不為使用FPO優(yōu)化的函數(shù)生成標(biāo)準(zhǔn)的堆棧幀,這樣其第一條指令可能不是 PUSH EBP。但是如果使用了SEH的話,那么無(wú)論你是否使用了FPO優(yōu)化,編譯器一定生成標(biāo)準(zhǔn)的堆棧幀)。這條指令可以使 EXCEPTION_REGISTRATION 結(jié)構(gòu)中所有其它的域都可以用一個(gè)相對(duì)于棧幀指針(EBP)的負(fù)偏移來(lái)訪問(wèn)。例如 trylevel 域在 [EBP-04]處,scopetable 指針在[EBP-08]處,等等。(也就是說(shuō),這個(gè)結(jié)構(gòu)是從[EBP-10H]處開(kāi)始的。)
  緊跟著擴(kuò)展的 EXCEPTION_REGISTRATION 結(jié)構(gòu)下面,Visual C++ 壓入了另外兩個(gè)值。緊跟著(即[EBP-14H]處)的一個(gè)DWORD,是為一個(gè)指向 EXCEPTION_POINTERS 結(jié)構(gòu)(一個(gè)標(biāo)準(zhǔn)的Win32 結(jié)構(gòu))的指針?biāo)A舻目臻g。這個(gè)指針就是你調(diào)用 GetExceptionInformation 這個(gè)API時(shí)返回的指針。盡管SDK文檔暗示 GetExceptionInformation 是一個(gè)標(biāo)準(zhǔn)的 Win32 API,但事實(shí)上它是一個(gè)編譯器內(nèi)聯(lián)函數(shù)。當(dāng)你調(diào)用這個(gè)函數(shù)時(shí),Visual C++ 生成以下代碼:

    MOV EAX,DWORD PTR [EBP-14] 
  

  GetExceptionInformation 是一個(gè)編譯器內(nèi)聯(lián)函數(shù),與它相關(guān)的 GetExceptionCode 函數(shù)也是如此。此函數(shù)實(shí)際上只是返回 GetExceptionInformation 返回的數(shù)據(jù)結(jié)構(gòu)(EXCEPTION_POINTERS)中的一個(gè)結(jié)構(gòu)(EXCEPTION_RECORD)中的一個(gè)域(ExceptionCode)的值。當(dāng) Visual C++ 為 GetExceptionCode 函數(shù)生成下面的指令時(shí),它到底是想干什么?我把這個(gè)問(wèn)題留給讀者。(現(xiàn)在就能理解為什么SDK文檔提醒我們要注意這兩個(gè)函數(shù)的使用范圍了。)

    MOV EAX,DWORD PTR [EBP-14] ; 執(zhí)行完畢,EAX指向EXCEPTION_POINTERS結(jié)構(gòu)
MOV EAX,DWORD PTR [EAX] ; 執(zhí)行完畢,EAX指向EXCEPTION_RECORD結(jié)構(gòu)
MOV EAX,DWORD PTR [EAX] ; 執(zhí)行完畢,EAX中是ExceptionCode的值 
  

  現(xiàn)在回到擴(kuò)展的 EXCEPTION_REGISTRATION 結(jié)構(gòu)上來(lái)。在這個(gè)結(jié)構(gòu)開(kāi)始前的8個(gè)字節(jié)處(即[EBP-18H]處),Visual C++ 保留了一個(gè)DWORD來(lái)保存所有prolog代碼執(zhí)行完畢之后的堆棧指針(ESP)的值(實(shí)際生成的指令為MOV DWORD PTR [EBP-18H],ESP)。這個(gè)DWORD中保存的值是函數(shù)執(zhí)行時(shí)ESP寄存器的正常值(除了在準(zhǔn)備調(diào)用其它函數(shù)時(shí)把參數(shù)壓入堆棧這個(gè)過(guò)程會(huì)改變 ESP寄存器的值并在函數(shù)返回時(shí)恢復(fù)它的值外,函數(shù)在執(zhí)行過(guò)程中一般不改變ESP寄存器的值)。
  看起來(lái)好像我一下子給你灌輸了太多的信息,我承認(rèn)。在繼續(xù)下去之前,讓我們先暫停,來(lái)回顧一下 Visual C++ 為使用結(jié)構(gòu)化異常處理的函數(shù)生成的標(biāo)準(zhǔn)異常堆棧幀,它看起來(lái)像下面這個(gè)樣子:

    EBP-00 _ebp
EBP-04 trylevel
EBP-08 scopetable數(shù)組指針
EBP-0C handler函數(shù)地址
EBP-10指向前一個(gè)EXCEPTION_REGISTRATION結(jié)構(gòu)
EBP-14 GetExceptionInformation
EBP-18 棧幀中的標(biāo)準(zhǔn)ESP 
  

  在操作系統(tǒng)看來(lái),只存在組成原始 EXCEPTION_REGISTRATION 結(jié)構(gòu)的兩個(gè)域:即[EBP-10h]處的prev指針和[EBP-0Ch]處的handler函數(shù)指針。棧幀中的其它所有內(nèi)容是針對(duì)于Visual C++的。把這個(gè)Visual C++生成的標(biāo)準(zhǔn)異常堆棧幀記到腦子里之后,讓我們來(lái)看一下真正實(shí)現(xiàn)編譯器層面SEH的這個(gè)Visual C++運(yùn)行時(shí)庫(kù)例程——__except_handler3。

__except_handler3 和 scopetable

  我真的很希望讓你看一看Visual C++運(yùn)行時(shí)庫(kù)源代碼,讓你自己好好研究一下__except_handler3函數(shù),但是我辦不到。因?yàn)?Microsoft并沒(méi)有提供。在這里你就將就著看一下我為_(kāi)_except_handler3函數(shù)寫的偽代碼吧:。

圖九 __except_handler3函數(shù)的偽代碼:

    int __except_handler3(
struct _EXCEPTION_RECORD * pExceptionRecord,
struct EXCEPTION_REGISTRATION * pRegistrationFrame,
struct _CONTEXT *pContextRecord,
void * pDispatcherContext ) 
{ 
	LONG filterFuncRet;
	LONG trylevel;
	EXCEPTION_POINTERS exceptPtrs;
	PSCOPETABLE pScopeTable; 
	CLD // 將方向標(biāo)志復(fù)位(不測(cè)試任何條件!) 
		// 如果沒(méi)有設(shè)置EXCEPTION_UNWINDING標(biāo)志或EXCEPTION_EXIT_UNWIND標(biāo)志
		// 表明這是第一次調(diào)用這個(gè)處理程序(也就是說(shuō),并非處于異常展開(kāi)階段)
		if ( ! (pExceptionRecord->ExceptionFlags
			& (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)) )
		{
			// 在堆棧上創(chuàng)建一個(gè)EXCEPTION_POINTERS結(jié)構(gòu)
			exceptPtrs.ExceptionRecord = pExceptionRecord;
			exceptPtrs.ContextRecord = pContextRecord; 
			// 把前面定義的EXCEPTION_POINTERS結(jié)構(gòu)的地址放在比
			// establisher棧幀低4個(gè)字節(jié)的位置上。參考前面我講
			// 的編譯器為GetExceptionInformation生成的匯編代
			// 碼*(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs; 
			// 獲取初始的“trylevel”值
			trylevel = pRegistrationFrame->trylevel; 
			// 獲取指向scopetable數(shù)組的指針 
			scopeTable = pRegistrationFrame->scopetable; 

	search_for_handler:
			if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
			{
				if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
				{
					PUSH EBP // 保存這個(gè)棧幀指針 
						// !!!非常重要!!!切換回原來(lái)的EBP。正是這個(gè)操作才使得
						// 棧幀上的所有局部變量能夠在異常發(fā)生后仍然保持它的值不變。
						EBP = &pRegistrationFrame->_ebp; 
					// 調(diào)用過(guò)濾器函數(shù)
					filterFuncRet = scopetable[trylevel].lpfnFilter(); 
					POP EBP // 恢復(fù)異常處理程序的棧幀指針 
						if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
						{
							if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
								return ExceptionContinueExecution; 
							// 如果能夠執(zhí)行到這里,說(shuō)明返回值為EXCEPTION_EXECUTE_HANDLER
							scopetable = pRegistrationFrame->scopetable; 
							// 讓操作系統(tǒng)清理已經(jīng)注冊(cè)的棧幀,這會(huì)使本函數(shù)被遞歸調(diào)用
							__global_unwind2( pRegistrationFrame ); 
							// 一旦執(zhí)行到這里,除最后一個(gè)棧幀外,所有的棧幀已經(jīng)
							// 被清理完畢,流程要從最后一個(gè)棧幀繼續(xù)執(zhí)行
							EBP = &pRegistrationFrame->_ebp; 
							__local_unwind2( pRegistrationFrame, trylevel ); 
							// NLG = "non-local-goto" (setjmp/longjmp stuff)
							__NLG_Notify( 1 ); // EAX = scopetable->lpfnHandler 
							// 把當(dāng)前的trylevel設(shè)置成當(dāng)找到一個(gè)異常處理程序時(shí)
							// SCOPETABLE中當(dāng)前正在被使用的那一個(gè)元素的內(nèi)容
							pRegistrationFrame->trylevel = scopetable->previousTryLevel; 
							// 調(diào)用__except {}塊,這個(gè)調(diào)用并不會(huì)返回
							pRegistrationFrame->scopetable[trylevel].lpfnHandler();
						} 
				} 
				scopeTable = pRegistrationFrame->scopetable;
				trylevel = scopeTable->previousTryLevel;
				goto search_for_handler; 
			}
			else // trylevel == TRYLEVEL_NONE
			{
				return ExceptionContinueSearch;
			} 
		}
		else // 設(shè)置了EXCEPTION_UNWINDING標(biāo)志或EXCEPTION_EXIT_UNWIND標(biāo)志
		{
			PUSH EBP // 保存EBP
				EBP = &pRegistrationFrame->_ebp; // 為調(diào)用__local_unwind2設(shè)置EBP
			__local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
				POP EBP // 恢復(fù)EBP
				return ExceptionContinueSearch;
		} 
}	

  

  雖然__except_handler3的代碼看起來(lái)很多,但是記住一點(diǎn):它只是一個(gè)我在文章開(kāi)頭講過(guò)的異常處理回調(diào)函數(shù)。它同MYSEH.EXE和 MYSEH2.EXE中的異常回調(diào)函數(shù)都帶有同樣的四個(gè)參數(shù)。__except_handler3大體上可以由第一個(gè)if語(yǔ)句分為兩部分。這是由于這個(gè)函數(shù)可以在兩種情況下被調(diào)用,一次是正常調(diào)用,另一次是在展開(kāi)階段。其中大部分是在非展開(kāi)階段的回調(diào)。
  __except_handler3一開(kāi)始就在堆棧上創(chuàng)建了一個(gè)EXCEPTION_POINTERS結(jié)構(gòu),并用它的兩個(gè)參數(shù)來(lái)對(duì)這個(gè)結(jié)構(gòu)進(jìn)行初始化。我在偽代碼中把這個(gè)結(jié)構(gòu)稱為 exceptPrts,它的地址被放在[EBP-14h]處。你回憶一下前面我講的編譯器為 GetExceptionInformation和 GetExceptionCode 函數(shù)生成的匯編代碼就會(huì)意識(shí)到,這實(shí)際上初始化了這兩個(gè)函數(shù)使用的指針。
  接著,__except_handler3從EXCEPTION_REGISTRATION幀中獲取當(dāng)前的trylevel(在[EBP-04h]處)。 trylevel變量實(shí)際是scopetable數(shù)組的索引,而正是這個(gè)數(shù)組才使得一個(gè)函數(shù)中的多個(gè)__try塊和嵌套的__try塊能夠僅使用一個(gè) EXCEPTION_REGISTRATION結(jié)構(gòu)。每個(gè)scopetable元素結(jié)構(gòu)如下:

    typedef struct _SCOPETABLE
{
DWORD previousTryLevel;
DWORD lpfnFilter;
DWORD lpfnHandler;
} SCOPETABLE, *PSCOPETABLE; 
  

  SCOPETABLE結(jié)構(gòu)中的第二個(gè)成員和第三個(gè)成員比較容易理解。它們分別是過(guò)濾器表達(dá)式代碼的地址和相應(yīng)的__except塊的地址。但是prviousTryLevel成員有點(diǎn)復(fù)雜。總之一句話,它用于嵌套的__try塊。這里的關(guān)鍵是函數(shù)中的每個(gè)__try塊都有一個(gè)相應(yīng)的SCOPETABLE結(jié)構(gòu)。
  正如我前面所說(shuō),當(dāng)前的 trylevel 指定了要使用的scopetable數(shù)組的哪一個(gè)元素,最終也就是指定了過(guò)濾器表達(dá)式和__except塊的地址。現(xiàn)在想像一下兩個(gè)__try塊嵌套的情形。如果內(nèi)層__try塊的過(guò)濾器表達(dá)式不處理某個(gè)異常,那外層__try塊的過(guò)濾器表達(dá)式就必須處理它。那現(xiàn)在要問(wèn),__except_handler3是如何知道SCOPETABLE數(shù)組的哪個(gè)元素相應(yīng)于外層的__try塊的呢?答案是:外層__try塊的索引由 SCOPETABLE結(jié)構(gòu)的previousTryLevel域給出。利用這種機(jī)制,你可以嵌套任意層的__try塊。previousTryLevel 域就好像是一個(gè)函數(shù)中所有可能的異常處理程序構(gòu)成的線性鏈表中的結(jié)點(diǎn)一樣。如果trylevel的值為0xFFFFFFFF(實(shí)際上就是-1,這個(gè)值在 EXSUP.INC中被定義為TRYLEVEL_NONE),標(biāo)志著這個(gè)鏈表結(jié)束。
  回到__except_handler3的代碼中。在獲取了當(dāng)前的trylevel之后,它就調(diào)用相應(yīng)的SCOPETABLE結(jié)構(gòu)中的過(guò)濾器表達(dá)式代碼。如果過(guò)濾器表達(dá)式返回EXCEPTION_CONTINUE_SEARCH,__exception_handler3 移向SCOPETABLE數(shù)組中的下一個(gè)元素,這個(gè)元素的索引由previousTryLevel域給出。如果遍歷完整個(gè)線性鏈表(還記得嗎?這個(gè)鏈表是由于在一個(gè)函數(shù)內(nèi)部嵌套使用__try塊而形成的)都沒(méi)有找到處理這個(gè)異常的代碼,__except_handler3返回DISPOSITION_CONTINUE_SEARCH(原文如此,但根據(jù)_except_handler函數(shù)的定義,這個(gè)返回值應(yīng)該為ExceptionContinueSearch。實(shí)際上這兩個(gè)常量的值是一樣的。我在偽代碼中已經(jīng)將其改正過(guò)來(lái)了),這導(dǎo)致系統(tǒng)移向下一個(gè)EXCEPTION_REGISTRATION幀(這個(gè)鏈表是由于函數(shù)嵌套調(diào)用而形成的)。
  如果過(guò)濾器表達(dá)式返回EXCEPTION_EXECUTE_HANDLER,這意味著異常應(yīng)該由相應(yīng)的__except塊處理。它同時(shí)也意味著所有前面的EXCEPTION_REGISTRATION幀都應(yīng)該從鏈表中移除,并且相應(yīng)的__except塊都應(yīng)該被執(zhí)行。第一個(gè)任務(wù)通過(guò)調(diào)用__global_unwind2來(lái)完成的,后面我會(huì)講到這個(gè)函數(shù)。跳過(guò)這中間的一些清理代碼,流程離開(kāi)__except_handler3轉(zhuǎn)向__except塊。令人奇怪的是,流程并不從__except塊中返回,雖然是 __except_handler3使用CALL指令調(diào)用了它。
  當(dāng)前的trylevel值是如何被設(shè)置的呢?它實(shí)際上是由編譯器隱含處理的。編譯器非常機(jī)靈地修改這個(gè)擴(kuò)展的EXCEPTION_REGISTRATION 結(jié)構(gòu)中的trylevel域的值(實(shí)際上是生成修改這個(gè)域的值的代碼)。如果你檢查編譯器為使用SEH的函數(shù)生成的匯編代碼,就會(huì)在不同的地方都看到修改這個(gè)位于[EBP-04h]處的trylevel域的值的代碼。
  __except_handler3是如何做到既通過(guò)CALL指令調(diào)用__except塊而又不讓執(zhí)行流程返回呢?由于CALL指令要向堆棧中壓入了一個(gè)返回地址,你可以想象這有可能破壞堆棧。如果你檢查一下編譯器為_(kāi)_except塊生成的代碼,你會(huì)發(fā)現(xiàn)它做的第一件事就是將EXCEPTION_REGISTRATION結(jié)構(gòu)下面8個(gè)字節(jié)處(即[EBP-18H]處)的一個(gè)DWORD值加載到ESP寄存器中(實(shí)際代碼為MOV ESP,DWORD PTR [EBP-18H]),這個(gè)值是在函數(shù)的 prolog 代碼中被保存在這個(gè)位置的(實(shí)際代碼為MOV DWORD PTR [EBP-18H],ESP)。

ShowSEHFrames 程序

  如果你現(xiàn)在覺(jué)得已經(jīng)被EXCEPTION_REGISTRATION、scopetable、trylevel、過(guò)濾器表達(dá)式以及展開(kāi)等等之類的詞搞得暈頭轉(zhuǎn)向的話,那和我最初的感覺(jué)一樣。但是編譯器層面的結(jié)構(gòu)化異常處理方面的知識(shí)并不適合一點(diǎn)一點(diǎn)的學(xué)。除非你從整體上理解它,否則有很多內(nèi)容單獨(dú)看并沒(méi)有什么意義。當(dāng)面對(duì)大堆的理論時(shí),我最自然的做法就是寫一些應(yīng)用我學(xué)到的理論方面的程序。如果它能夠按照預(yù)料的那樣工作,我就知道我的理解(通常)是正確的。
  下面是ShowSEHFrame.EXE的源代碼。它使用__try/__except塊設(shè)置了好幾個(gè) Visual C++ SEH 幀。然后它顯示每一個(gè)幀以及Visual C++為每個(gè)幀創(chuàng)建的scopetable的相關(guān)信息。這個(gè)程序本身并不生成也不依賴任何異常。相反,我使用了多個(gè)__try塊以強(qiáng)制Visual C++生成多個(gè) EXCEPTION_REGISTRATION 幀以及相應(yīng)的 scopetable。

    //ShowSEHFrames.CPP 
//=========================================================
// ShowSEHFrames - Matt Pietrek 1997
// Microsoft Systems Journal, February 1997
// FILE: ShowSEHFrames.CPP
// 使用命令行CL ShowSehFrames.CPP進(jìn)行編譯
//========================================================= 
#define WIN32_LEAN_AND_MEAN 
#include <windows.h>
#include <stdio.h> 
#pragma hdrstop 
//-------------------------------------------------------------------
// 本程序僅適用于Visual C++,它使用的數(shù)據(jù)結(jié)構(gòu)是特定于Visual C++的
//------------------------------------------------------------------- 
#ifndef _MSC_VER
#error Visual C++ Required (Visual C++ specific information is displayed)
#endif 
//-------------------------------------------------------------------
// 結(jié)構(gòu)定義
//------------------------------------------------------------------- 

// 操作系統(tǒng)定義的基本異常幀
struct EXCEPTION_REGISTRATION
{
	EXCEPTION_REGISTRATION* prev;
	FARPROC handler;
}; 
// Visual C++擴(kuò)展異常幀指向的數(shù)據(jù)結(jié)構(gòu)
struct scopetable_entry
{
	DWORD previousTryLevel;
	FARPROC lpfnFilter;
	FARPROC lpfnHandler;
}; 
// Visual C++使用的擴(kuò)展異常幀
struct VC_EXCEPTION_REGISTRATION : EXCEPTION_REGISTRATION
{
	scopetable_entry * scopetable;
	int trylevel;
	int _ebp;
}; 
//----------------------------------------------------------------
// 原型聲明
//---------------------------------------------------------------- 
// __except_handler3是Visual C++運(yùn)行時(shí)庫(kù)函數(shù),我們想打印出它的地址
// 但是它的原型并沒(méi)有出現(xiàn)在任何頭文件中,所以我們需要自己聲明它。
extern "C" int _except_handler3(PEXCEPTION_RECORD,
			EXCEPTION_REGISTRATION *,
			PCONTEXT,
			PEXCEPTION_RECORD); 
//-------------------------------------------------------------
// 代碼
//------------------------------------------------------------- 
//
// 顯示一個(gè)異常幀及其相應(yīng)的scopetable的信息
//
void ShowSEHFrame( VC_EXCEPTION_REGISTRATION * pVCExcRec )
{
	printf( "Frame: %08X Handler: %08X Prev: %08X Scopetable: %08X/n",
		pVCExcRec, pVCExcRec->handler, pVCExcRec->prev,
		pVCExcRec->scopetable ); 
	scopetable_entry * pScopeTableEntry = pVCExcRec->scopetable; 
	for ( unsigned i = 0; i <= pVCExcRec->trylevel; i++ )
	{
		printf( " scopetable[%u] PrevTryLevel: %08X "
			"filter: %08X __except: %08X/n", i,
			pScopeTableEntry->previousTryLevel,
			pScopeTableEntry->lpfnFilter,
			pScopeTableEntry->lpfnHandler ); 
		pScopeTableEntry++;
	} 
	printf( "/n" ); 
} 

//
// 遍歷異常幀的鏈表,按順序顯示它們的信息
//
void WalkSEHFrames( void )
{
	VC_EXCEPTION_REGISTRATION * pVCExcRec; 
	// 打印出__except_handler3函數(shù)的位置
	printf( "_except_handler3 is at address: %08X/n", _except_handler3 );
	printf( "/n" ); 
	// 從FS:[0]處獲取指向鏈表頭的指針
	__asm mov eax, FS:[0]
	__asm mov [pVCExcRec], EAX 
		// 遍歷異常幀的鏈表。0xFFFFFFFF標(biāo)志著鏈表的結(jié)尾
		while ( 0xFFFFFFFF != (unsigned)pVCExcRec )
		{
			ShowSEHFrame( pVCExcRec );
			pVCExcRec = (VC_EXCEPTION_REGISTRATION *)(pVCExcRec->prev);
		} 
} 

void Function1( void )
{
	// 嵌套3層__try塊以便強(qiáng)制為scopetable數(shù)組產(chǎn)生3個(gè)元素
	__try
	{
		__try
		{
			__try
			{
				WalkSEHFrames(); // 現(xiàn)在顯示所有的異常幀的信息
			} __except( EXCEPTION_CONTINUE_SEARCH )
			{}
		} __except( EXCEPTION_CONTINUE_SEARCH )
		{}
	} __except( EXCEPTION_CONTINUE_SEARCH )
	{} 
} 

int main() 
{
	int i; 
	// 使用兩個(gè)__try塊(并不嵌套),這導(dǎo)致為scopetable數(shù)組生成兩個(gè)元素
	__try
	{
		i = 0x1234;
	} __except( EXCEPTION_CONTINUE_SEARCH )
	{
		i = 0x4321;
	} 
	__try
	{
		Function1(); // 調(diào)用一個(gè)設(shè)置更多異常幀的函數(shù)
	} __except( EXCEPTION_EXECUTE_HANDLER )
	{
		// 應(yīng)該永遠(yuǎn)不會(huì)執(zhí)行到這里,因?yàn)槲覀儾](méi)有打算產(chǎn)生任何異常
		printf( "Caught Exception in main/n" );
	} 
	return 0; 
} 	
  

  ShowSEHFrames程序中比較重要的函數(shù)是WalkSEHFrames和ShowSEHFrame。WalkSEHFrames函數(shù)首選打印出 __except_handler3的地址,打印它的原因很快就清楚了。接著,它從FS:[0]處獲取異常鏈表的頭指針,然后遍歷該鏈表。此鏈表中每個(gè)結(jié)點(diǎn)都是一個(gè)VC_EXCEPTION_REGISTRATION類型的結(jié)構(gòu),它是我自己定義的,用于描述Visual C++的異常處理幀。對(duì)于這個(gè)鏈表中的每個(gè)結(jié)點(diǎn),WalkSEHFrames都把指向這個(gè)結(jié)點(diǎn)的指針傳遞給ShowSEHFrame函數(shù)。
  ShowSEHFrame函數(shù)一開(kāi)始就打印出異常處理幀的地址、異常處理回調(diào)函數(shù)的地址、前一個(gè)異常處理幀的地址以及scopetable的地址。接著,對(duì)于每個(gè) scopetable數(shù)組中的元素,它都打印出其priviousTryLevel、過(guò)濾器表達(dá)式的地址以及相應(yīng)的__except塊的地址。我是如何知道scopetable數(shù)組中有多少個(gè)元素的呢?其實(shí)我并不知道。但是我假定VC_EXCEPTION_REGISTRATION結(jié)構(gòu)中的當(dāng)前trylevel域的值比scopetable數(shù)組中的元素總數(shù)少1。
  圖十一是 ShowSEHFrames 的運(yùn)行結(jié)果。首先檢查以“Frame:”開(kāi)頭的每一行,你會(huì)發(fā)現(xiàn)它們顯示的異常處理幀在堆棧上的地址呈遞增趨勢(shì),并且在前三個(gè)幀中,它們的異常處理程序的地址是一樣的(都是004012A8)。再看輸出的開(kāi)始部分,你會(huì)發(fā)現(xiàn)這個(gè)004012A8不是別的,它正是 Visual C++運(yùn)行時(shí)庫(kù)函數(shù)__except_handler3的地址。這證明了我前面所說(shuō)的單個(gè)回調(diào)函數(shù)處理所有異常這一點(diǎn)。

Win32 結(jié)構(gòu)化異常處理(SEH)探秘
圖十一 ShowSEHFrames運(yùn)行結(jié)果

  你可能想知道為什么明明 ShowSEHFrames 程序只有兩個(gè)函數(shù)使用SEH,但是卻有三個(gè)異常處理幀使用__except_handler3作為它們的異常回調(diào)函數(shù)。實(shí)際上第三個(gè)幀來(lái)自 Visual C++ 運(yùn)行時(shí)庫(kù)。Visual C++ 運(yùn)行時(shí)庫(kù)源代碼中的 CRT0.C 文件清楚地表明了對(duì) main 或 WinMain 的調(diào)用也被一個(gè)__try/__except 塊封裝著。這個(gè)__try 塊的過(guò)濾器表達(dá)式代碼可以在 WINXFLTR.C文 件中找到。
  回到 ShowSEHFrames 程序,注意到最后一個(gè)幀的異常處理程序的地址是 77F3AB6C,這與其它三個(gè)不同。仔細(xì)觀察一下,你會(huì)發(fā)現(xiàn)這個(gè)地址在 KERNEL32.DLL 中。這個(gè)特別的幀就是由 KERNEL32.DLL 中的 BaseProcessStart 函數(shù)安裝的,這在前面我已經(jīng)說(shuō)過(guò)。

展開(kāi)

  在挖掘展開(kāi)(Unwinding)的實(shí)現(xiàn)代碼之前讓我們先來(lái)搞清楚它的意思。我在前面已經(jīng)講過(guò)所有可能的異常處理程序是如何被組織在一個(gè)由線程信息塊的第一個(gè)DWORD(FS:[0])所指向的鏈表中的。由于針對(duì)某個(gè)特定異常的處理程序可能不在這個(gè)鏈表的開(kāi)頭,因此就需要從鏈表中依次移除實(shí)際處理異常的那個(gè)異常處理程序之前的所有異常處理程序。
  正如你在Visual C++的__except_handler3函數(shù)中看到的那樣,展開(kāi)是由__global_unwind2這個(gè)運(yùn)行時(shí)庫(kù)(RTL)函數(shù)來(lái)完成的。這個(gè)函數(shù)只是對(duì)RtlUnwind這個(gè)未公開(kāi)的API進(jìn)行了非常簡(jiǎn)單的封裝。(現(xiàn)在這個(gè)API已經(jīng)被公開(kāi)了,但給出的信息極其簡(jiǎn)單,詳細(xì)信息可以參考最新的Platform SDK文檔。)

    __global_unwind2(void * pRegistFrame)
{
	_RtlUnwind( pRegistFrame, &__ret_label, 0, 0 );
__ret_label:
} 	
  

  雖然從技術(shù)上講RtlUnwind是一個(gè)KERNEL32函數(shù),但它只是轉(zhuǎn)發(fā)到了NTDLL.DLL中的同名函數(shù)上。下面是我為此函數(shù)寫的偽代碼。

RtlUnwind 函數(shù)的偽代碼:

      void _RtlUnwind( PEXCEPTION_REGISTRATION pRegistrationFrame,
		  PVOID returnAddr, // 并未使用!(至少是在i386機(jī)器上)
		  PEXCEPTION_RECORD pExcptRec,
		  DWORD _eax_value) 
  { 
	  DWORD stackUserBase;
	  DWORD stackUserTop;
	  PEXCEPTION_RECORD pExcptRec;
	  EXCEPTION_RECORD exceptRec;
	  CONTEXT context; 
	  // 從FS:[4]和FS:[8]處獲取堆棧的界限
	  RtlpGetStackLimits( &stackUserBase, &stackUserTop ); 
	  if ( 0 == pExcptRec ) // 正常情況
	  {
		  pExcptRec = &excptRec;
		  pExcptRec->ExceptionFlags = 0;
		  pExcptRec->ExceptionCode = STATUS_UNWIND;
		  pExcptRec->ExceptionRecord = 0;
		  pExcptRec->ExceptionAddress = [ebp+4]; // RtlpGetReturnAddress()—獲取返回地址
		  pExcptRec->ExceptionInformation[0] = 0;
	  } 
	  if ( pRegistrationFrame )
		  pExcptRec->ExceptionFlags |= EXCEPTION_UNWINDING;
	  else             // 這兩個(gè)標(biāo)志合起來(lái)被定義為EXCEPTION_UNWIND_CONTEXT
		  pExcptRec->ExceptionFlags|=(EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND); 
	  context.ContextFlags =( CONTEXT_i486 | CONTEXT_CONTROL |
		  CONTEXT_INTEGER | CONTEXT_SEGMENTS); 
	  RtlpCaptureContext( &context ); 
	  context.Esp += 0x10;
	  context.Eax = _eax_value; 
	  PEXCEPTION_REGISTRATION pExcptRegHead;
	  pExcptRegHead = RtlpGetRegistrationHead(); // 返回FS:[0]的值 
	  // 開(kāi)始遍歷EXCEPTION_REGISTRATION結(jié)構(gòu)鏈表
	  while ( -1 != pExcptRegHead )
	  {
		  EXCEPTION_RECORD excptRec2; 
		  if ( pExcptRegHead == pRegistrationFrame )
		  {
			  NtContinue( &context, 0 );
		  }
		  else
		  {
			  // 如果存在某個(gè)異常幀在堆棧上的位置比異常鏈表的頭部還低
			  // 說(shuō)明一定出現(xiàn)了錯(cuò)誤
			  if ( pRegistrationFrame && (pRegistrationFrame <= pExcptRegHead) )
			  {
				  // 生成一個(gè)異常
				  excptRec2.ExceptionRecord = pExcptRec;
				  excptRec2.NumberParameters = 0;
				  excptRec2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
				  excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
				  RtlRaiseException( &exceptRec2 );
			  }
		  } 
		  PVOID pStack = pExcptRegHead + 8; // 8 = sizeof(EXCEPTION_REGISTRATION) 
		  // 確保pExcptRegHead在堆棧范圍內(nèi),并且是4的倍數(shù)
		  if ( (stackUserBase <= pExcptRegHead )
			  && (stackUserTop >= pStack )
			  && (0 == (pExcptRegHead & 3)) )
		  {
			  DWORD pNewRegistHead;
			  DWORD retValue; 
			  retValue = RtlpExecutehandlerForUnwind(pExcptRec, pExcptRegHead, &context,
				  &pNewRegistHead, pExceptRegHead->handler ); 
			  if ( retValue != DISPOSITION_CONTINUE_SEARCH )
			  {
				  if ( retValue != DISPOSITION_COLLIDED_UNWIND )
				  {
					  excptRec2.ExceptionRecord = pExcptRec;
					  excptRec2.NumberParameters = 0;
					  excptRec2.ExceptionCode = STATUS_INVALID_DISPOSITION;
					  excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
					  RtlRaiseException( &excptRec2 );
				  }
				  else
					  pExcptRegHead = pNewRegistHead;
			  } 
			  PEXCEPTION_REGISTRATION pCurrExcptReg = pExcptRegHead;
			  pExcptRegHead = pExcptRegHead->prev;
			  RtlpUnlinkHandler( pCurrExcptReg ); 
		  }
		  else // 堆棧已經(jīng)被破壞!生成一個(gè)異常
		  {
			  excptRec2.ExceptionRecord = pExcptRec;
			  excptRec2.NumberParameters = 0;
			  excptRec2.ExceptionCode = STATUS_BAD_STACK;
			  excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
			  RtlRaiseException( &excptRec2 );
		  } 
	  } 
	  // 如果執(zhí)行到這里,說(shuō)明已經(jīng)到了EXCEPTION_REGISTRATION
	  // 結(jié)構(gòu)鏈表的末尾,正常情況下不應(yīng)該發(fā)生這種情況。
	  //(因?yàn)檎G闆r下異常應(yīng)該被處理,這樣就不會(huì)到鏈表末尾)
	  if ( -1 == pRegistrationFrame )
		  NtContinue( &context, 0 );
	  else
		  NtRaiseException( pExcptRec, &context, 0 ); 
  } 

  RtlUnwind函數(shù)的偽代碼到這里就結(jié)束了,以下是它調(diào)用的幾個(gè)函數(shù)的偽代碼: 
	  PEXCEPTION_REGISTRATION RtlpGetRegistrationHead( void )
  {
	  return FS:[0];
  } 
  RtlpUnlinkHandler( PEXCEPTION_REGISTRATION pRegistrationFrame )
  {
	FS:[0] = pRegistrationFrame->prev;
  } 
  void RtlpCaptureContext( CONTEXT * pContext )
  {
	  pContext->Eax = 0;
	  pContext->Ecx = 0;
	  pContext->Edx = 0;
	  pContext->Ebx = 0;
	  pContext->Esi = 0;
	  pContext->Edi = 0;
	  pContext->SegCs = CS;
	  pContext->SegDs = DS;
	  pContext->SegEs = ES;
	  pContext->SegFs = FS;
	  pContext->SegGs = GS;
	  pContext->SegSs = SS;
	  pContext->EFlags = flags; // 它對(duì)應(yīng)的匯編代碼為_(kāi)_asm{ PUSHFD / pop [xxxxxxxx] }
	  pContext->Eip = 此函數(shù)的調(diào)用者的調(diào)用者的返回地址    // 讀者看一下這個(gè)函數(shù)的
		  pContext->Ebp = 此函數(shù)的調(diào)用者的調(diào)用者的EBP        // 匯編代碼就會(huì)清楚這一點(diǎn)
		  pContext->Esp = pContext->Ebp + 8;
  } 		
  

  雖然 RtlUnwind 函數(shù)的規(guī)模看起來(lái)很大,但是如果你按一定方法把它分開(kāi),其實(shí)并不難理解。它首先從FS:[4]和FS:[8]處獲取當(dāng)前線程堆棧的界限。它們對(duì)于后面要進(jìn)行的合法性檢查非常重要,以確保所有將要被展開(kāi)的異常幀都在堆棧范圍內(nèi)。
  RtlUnwind 接著在堆棧上創(chuàng)建了一個(gè)空的EXCEPTION_RECORD結(jié)構(gòu)并把STATUS_UNWIND賦給它的ExceptionCode域,同時(shí)把 EXCEPTION_UNWINDING標(biāo)志賦給它的 ExceptionFlags 域。指向這個(gè)結(jié)構(gòu)的指針作為其中一個(gè)參數(shù)被傳遞給每個(gè)異常回調(diào)函數(shù)。然后,這個(gè)函數(shù)調(diào)用RtlCaptureContext函數(shù)來(lái)創(chuàng)建一個(gè)空的CONTEXT結(jié)構(gòu),這個(gè)結(jié)構(gòu)也變成了在展開(kāi)階段調(diào)用每個(gè)異常回調(diào)函數(shù)時(shí)傳遞給它們的一個(gè)參數(shù)。
  RtlUnwind函數(shù)的其余部分遍歷EXCEPTION_REGISTRATION結(jié)構(gòu)鏈表。對(duì)于其中的每個(gè)幀,它都調(diào)用 RtlpExecuteHandlerForUnwind 函數(shù),后面我會(huì)講到這個(gè)函數(shù)。正是這個(gè)函數(shù)帶 EXCEPTION_UNWINDING 標(biāo)志調(diào)用了異常處理回調(diào)函數(shù)。每次回調(diào)之后,它調(diào)用RtlpUnlinkHandler 移除相應(yīng)的異常幀。
  RtlUnwind 函數(shù)的第一個(gè)參數(shù)是一個(gè)幀的地址,當(dāng)它遍歷到這個(gè)幀時(shí)就停止展開(kāi)異常幀。上面所說(shuō)的這些代碼之間還有一些安全性檢查代碼,它們用來(lái)確保不出問(wèn)題。如果出現(xiàn)任何問(wèn)題,RtlUnwind 就引發(fā)一個(gè)異常,指示出了什么問(wèn)題,并且這個(gè)異常帶有EXCEPTION_NONCONTINUABLE 標(biāo)志。當(dāng)一個(gè)進(jìn)程被設(shè)置了這個(gè)標(biāo)志時(shí),它就不允許再運(yùn)行,必須終止。

未處理異常

  在文章的前面,我并沒(méi)有全面描述 UnhandledExceptionFilter 這個(gè) API。通常情況下你并不直接調(diào)用它(盡管你可以這么做)。大多數(shù)情況下它都是由 KERNEL32 中進(jìn)行默認(rèn)異常處理的過(guò)濾器表達(dá)式代碼調(diào)用。前面 BaseProcessStart 函數(shù)的偽代碼已經(jīng)表明了這一點(diǎn)。
  圖十三是我為 UnhandledExceptionFilter 函數(shù)寫的偽代碼。這個(gè)API有點(diǎn)奇怪(至少在我看來(lái)是這樣)。如果異常的類型是 EXCEPTION_ACCESS_VIOLATION,它就調(diào)用_BasepCheckForReadOnlyResource。雖然我沒(méi)有提供這個(gè)函數(shù)的偽代碼,但可以簡(jiǎn)要描述一下。如果是因?yàn)橐獙?duì) EXE 或 DLL 的資源節(jié)(.rsrc)進(jìn)行寫操作而導(dǎo)致的異常,_BasepCurrentTopLevelFilter 就改變出錯(cuò)頁(yè)面正常的只讀屬性,以便允許進(jìn)行寫操作。如果是這種特殊的情況,UnhandledExceptionFilter 返回 EXCEPTION_CONTINUE_EXECUTION,使系統(tǒng)重新執(zhí)行出錯(cuò)指令。

圖十三 UnHandledExceptionFilter 函數(shù)的偽代碼

    UnhandledExceptionFilter( STRUCT _EXCEPTION_POINTERS *pExceptionPtrs )
{ 
	PEXCEPTION_RECORD pExcptRec;
	DWORD currentESP;
	DWORD retValue;
	DWORD DEBUGPORT;
	DWORD dwTemp2;
	DWORD dwUseJustInTimeDebugger;
	CHAR szDbgCmdFmt[256]; // 從AeDebug這個(gè)注冊(cè)表鍵值返回的字符串
	CHAR szDbgCmdLine[256]; // 實(shí)際的調(diào)試器命令行參數(shù)(已填入進(jìn)程ID和事件ID)
	STARTUPINFO startupinfo;
	PROCESS_INFORMATION pi;
	HARDERR_STRUCT harderr; // ???
	BOOL fAeDebugAuto;
	TIB * pTib; // 線程信息塊


	pExcptRec = pExceptionPtrs->ExceptionRecord; 
	if ( (pExcptRec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
		&& (pExcptRec->ExceptionInformation[0]) )
	{
		retValue=BasepCheckForReadOnlyResource(pExcptRec->ExceptionInformation[1]); 
		if ( EXCEPTION_CONTINUE_EXECUTION == retValue )
			return EXCEPTION_CONTINUE_EXECUTION; 
	} 
	// 查看這個(gè)進(jìn)程是否運(yùn)行于調(diào)試器下
	retValue = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
		&debugPort, sizeof(debugPort), 0 ); 
	if ( (retValue >= 0) && debugPort ) // 通知調(diào)試器
		return EXCEPTION_CONTINUE_SEARCH; 
	// 用戶調(diào)用SetUnhandledExceptionFilter了嗎?
	// 如果調(diào)用了,那現(xiàn)在就調(diào)用他安裝的異常處理程序
	if ( _BasepCurrentTopLevelFilter )
	{
		retValue = _BasepCurrentTopLevelFilter( pExceptionPtrs );
		if ( EXCEPTION_EXECUTE_HANDLER == retValue )
			return EXCEPTION_EXECUTE_HANDLER;
		if ( EXCEPTION_CONTINUE_EXECUTION == retValue )
			return EXCEPTION_CONTINUE_EXECUTION; 
		// 只有返回值為EXCEPTION_CONTINUE_SEARCH時(shí)才會(huì)繼續(xù)執(zhí)行下去
	} 
	// 調(diào)用過(guò)SetErrorMode(SEM_NOGPFAULTERRORBOX)嗎?
	{
		harderr.elem0 = pExcptRec->ExceptionCode;
		harderr.elem1 = pExcptRec->ExceptionAddress; 
		if ( EXCEPTION_IN_PAGE_ERROR == pExcptRec->ExceptionCode )
			harderr.elem2 = pExcptRec->ExceptionInformation[2]; 
		else
			harderr.elem2 = pExcptRec->ExceptionInformation[0]; 
		dwTemp2 = 1;
		fAeDebugAuto = FALSE;
		harderr.elem3 = pExcptRec->ExceptionInformation[1];
		pTib = FS:[18h];
		DWORD someVal = pTib->pProcess->0xC; 
		if ( pTib->threadID != someVal )
		{
			__try
			{
				char szDbgCmdFmt[256];
				retValue = GetProfileStringA( "AeDebug", "Debugger", 0,
					szDbgCmdFmt, sizeof(szDbgCmdFmt)-1 ); 
				if ( retValue )
					dwTemp2 = 2; 
				char szAuto[8];
				retValue = GetProfileStringA( "AeDebug", "Auto", "0",
					szAuto, sizeof(szAuto)-1 ); 
				if ( retValue )
					if ( 0 == strcmp( szAuto, "1" ) )
						if ( 2 == dwTemp2 )
							fAeDebugAuto = TRUE; 
			}
			__except( EXCEPTION_EXECUTE_HANDLER )
			{
				ESP = currentESP;
				dwTemp2 = 1;
				fAeDebugAuto = FALSE;
			} 
		} 
		if ( FALSE == fAeDebugAuto )
		{
			retValue=NtRaiseHardError(STATUS_UNHANDLED_EXCEPTION | 0x10000000,
				4, 0, &harderr,_BasepAlreadyHadHardError ? 1 : dwTemp2,
				&dwUseJustInTimeDebugger ); 
		}
		else
		{
			dwUseJustInTimeDebugger = 3;
			retValue = 0;
		} 
		if (retValue >= 0 && (dwUseJustInTimeDebugger == 3)
			&& (!_BasepAlreadyHadHardError)&&(!_BaseRunningInServerProcess)) 
		{
			_BasepAlreadyHadHardError = 1;
			SECURITY_ATTRIBUTES secAttr = { sizeof(secAttr), 0, TRUE };
			HANDLE hEvent = CreateEventA( &secAttr, TRUE, 0, 0 );
			memset( &startupinfo, 0, sizeof(startupinfo) );
			sprintf(szDbgCmdLine, szDbgCmdFmt, GetCurrentProcessId(), hEvent);
			startupinfo.cb = sizeof(startupinfo);
			startupinfo.lpDesktop = "Winsta0/Default" 
				CsrIdentifyAlertableThread(); // ??? 
			retValue = CreateProcessA( 0,           // 應(yīng)用程序名稱
				szDbgCmdLine, // 命令行
				0, 0,          // 進(jìn)程和線程安全屬性
				1,             // bInheritHandles
				0, 0,          // 創(chuàng)建標(biāo)志、環(huán)境
				0,             // 當(dāng)前目錄
				&statupinfo, // STARTUPINFO
				&pi);          // PROCESS_INFORMATION 
			if ( retValue && hEvent )
			{
				NtWaitForSingleObject( hEvent, 1, 0 );
				return EXCEPTION_CONTINUE_SEARCH;
			} 
		} 
		if ( _BasepAlreadyHadHardError )
			NtTerminateProcess(GetCurrentProcess(), pExcptRec->ExceptionCode); 
	} 
	return EXCEPTION_EXECUTE_HANDLER; 
} 

LPTOP_LEVEL_EXCEPTION_FILTER
SetUnhandledExceptionFilter(
		LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter )
{
	// _BasepCurrentTopLevelFilter是KERNEL32.DLL中的一個(gè)全局變量
	LPTOP_LEVEL_EXCEPTION_FILTER previous= _BasepCurrentTopLevelFilter; 
	// 設(shè)置為新值
	_BasepCurrentTopLevelFilter = lpTopLevelExceptionFilter; 
	return previous; // 返回以前的值 
} 	
  

  UnhandledExceptionFilter接下來(lái)的任務(wù)是確定進(jìn)程是否運(yùn)行于Win32調(diào)試器下。也就是進(jìn)程的創(chuàng)建標(biāo)志中是否帶有標(biāo)志DEBUG_PROCESS或DEBUG_ONLY_THIS_PROCESS。它使用NtQueryInformationProcess函數(shù)來(lái)確定進(jìn)程是否正在被調(diào)試,我在本月的Under the Hood專欄中講解了這個(gè)函數(shù)。如果正在被調(diào)試,UnhandledExceptionFilter就返回 EXCEPTION_CONTINUE_SEARCH,這告訴系統(tǒng)去喚醒調(diào)試器并告訴它在被調(diào)試程序(debuggee)中產(chǎn)生了一個(gè)異常。
  UnhandledExceptionFilter接下來(lái)調(diào)用用戶安裝的未處理異常過(guò)濾器(如果存在的話)。通常情況下,用戶并沒(méi)有安裝回調(diào)函數(shù),但是用戶可以調(diào)用 SetUnhandledExceptionFilter這個(gè)API來(lái)安裝。上面我也提供了這個(gè)API的偽代碼。這個(gè)函數(shù)只是簡(jiǎn)單地用用戶安裝的回調(diào)函數(shù)的地址來(lái)替換一個(gè)全局變量,并返回替換前的值。
  有了初步的準(zhǔn)備之后,UnhandledExceptionFilter就開(kāi)始做它的主要工作:用一個(gè)時(shí)髦的應(yīng)用程序錯(cuò)誤對(duì)話框來(lái)通知你犯了低級(jí)的編程錯(cuò)誤。有兩種方法可以避免出現(xiàn)這個(gè)對(duì)話框。第一種方法是調(diào)用SetErrorMode函數(shù)并指定SEM_NOGPFAULTERRORBOX標(biāo)志。另一種方法是將AeDebug子鍵下的Auto的值設(shè)為1。此時(shí)UnhandledExceptionFilter跳過(guò)應(yīng)用程序錯(cuò)誤對(duì)話框直接啟動(dòng)AeDebug 子鍵下的Debugger的值所指定的調(diào)試器。如果你熟悉“即時(shí)調(diào)試(Just In Time Debugging,JIT)”的話,這就是操作系統(tǒng)支持它的地方。接下來(lái)我會(huì)詳細(xì)講。
大多數(shù)情況下,上面的兩個(gè)條件都為假。這樣UnhandledExceptionFilter就調(diào)用NTDLL.DLL中的 NtRaiseHardError函數(shù)。正是這個(gè)函數(shù)產(chǎn)生了應(yīng)用程序錯(cuò)誤對(duì)話框。這個(gè)對(duì)話框等待你單擊“確定”按鈕來(lái)終止進(jìn)程,或者單擊“取消”按鈕來(lái)調(diào)試它。(單擊“取消”按鈕而不是“確定”按鈕來(lái)加載調(diào)試器好像有點(diǎn)顛倒了,可能這只是我個(gè)人的感覺(jué)吧。)
  如果你單擊“確定”,UnhandledExceptionFilter就返回EXCEPTION_EXECUTE_HANDLER。調(diào)用UnhandledExceptionFilter 的進(jìn)程通常通過(guò)終止自身來(lái)作為響應(yīng)(正像你在BaseProcessStart的偽代碼中看到的那樣)。這就產(chǎn)生了一個(gè)有趣的問(wèn)題——大多數(shù)人都認(rèn)為是系統(tǒng)終止了產(chǎn)生未處理異常的進(jìn)程,而實(shí)際上更準(zhǔn)確的說(shuō)法應(yīng)該是,系統(tǒng)進(jìn)行了一些設(shè)置使得產(chǎn)生未處理異常的進(jìn)程將自身終止掉了。
  UnhandledExceptionFilter執(zhí)行時(shí)真正有意思的部分是當(dāng)你單擊應(yīng)用程序錯(cuò)誤對(duì)話框中的“取消”按鈕,此時(shí)系統(tǒng)將調(diào)試器附加(attach)到出錯(cuò)進(jìn)程上。這段代碼首先調(diào)用 CreateEvent來(lái)創(chuàng)建一個(gè)事件內(nèi)核對(duì)象,調(diào)試器成功附加到出錯(cuò)進(jìn)程之后會(huì)將此事件對(duì)象變成有信號(hào)狀態(tài)。這個(gè)事件句柄以及出錯(cuò)進(jìn)程的ID都被傳到 sprintf函數(shù),由它將其格式化成一個(gè)命令行,用來(lái)啟動(dòng)調(diào)試器。一切就緒之后,UnhandledExceptionFilter就調(diào)用 CreateProcess來(lái)啟動(dòng)調(diào)試器。如果CreateProcess成功,它就調(diào)用NtWaitForSingleObject來(lái)等待前面創(chuàng)建的那個(gè)事件對(duì)象。此時(shí)這個(gè)調(diào)用被阻塞,直到調(diào)試器進(jìn)程將此事件變成有信號(hào)狀態(tài),以表明它已經(jīng)成功附加到出錯(cuò)進(jìn)程上。UnhandledExceptionFilter函數(shù)中還有一些其它的代碼,我在這里只講重要的。

進(jìn)入地獄

  如果你已經(jīng)走了這么遠(yuǎn),不把整個(gè)過(guò)程講完對(duì)你有點(diǎn)不公平。我已經(jīng)講了當(dāng)異常發(fā)生時(shí)操作系統(tǒng)是如何調(diào)用用戶定義的回調(diào)函數(shù)的。我也講了這些回調(diào)的內(nèi)部情況,以及編譯器是如何使用它們來(lái)實(shí)現(xiàn)__try和__except的。我甚至還講了當(dāng)某個(gè)異常沒(méi)有被處理時(shí)所發(fā)生的情況以及系統(tǒng)所做的掃尾工作。剩下的就只有異常回調(diào)過(guò)程最初是從哪里開(kāi)始的這個(gè)問(wèn)題了。好吧,讓我們深入系統(tǒng)內(nèi)部來(lái)看一下結(jié)構(gòu)化異常處理的開(kāi)始階段吧。
  圖十四是我為 KiUserExceptionDispatcher 函數(shù)和一些相關(guān)函數(shù)寫的偽代碼。這個(gè)函數(shù)在NTDLL.DLL中,它是異常處理執(zhí)行的起點(diǎn)。為了絕對(duì)準(zhǔn)確起見(jiàn),我必須指出:剛才說(shuō)的并不是絕對(duì)準(zhǔn)確。例如在Intel平臺(tái)上,一個(gè)異常導(dǎo)致CPU將控制權(quán)轉(zhuǎn)到ring 0(0特權(quán)級(jí),即內(nèi)核模式)的一個(gè)處理程序上。這個(gè)處理程序由中斷描述符表(Interrupt Descriptor Table,IDT)中的一個(gè)元素定義,它是專門用來(lái)處理相應(yīng)異常的。我跳過(guò)所有的內(nèi)核模式代碼,假設(shè)當(dāng)異常發(fā)生時(shí)CPU直接將控制權(quán)轉(zhuǎn)到了 KiUserExceptionDispatcher 函數(shù)。

圖十四 KiUserExceptionDispatcher 的偽代碼:

    KiUserExceptionDispatcher( PEXCEPTION_RECORD pExcptRec, CONTEXT * pContext )
{
	DWORD retValue; 
	// 注意:如果異常被處理,那么 RtlDispatchException 函數(shù)就不會(huì)返回
	if ( RtlDispatchException( pExceptRec, pContext ) )
		retValue = NtContinue( pContext, 0 );
	else
		retValue = NtRaiseException( pExceptRec, pContext, 0 ); 
	EXCEPTION_RECORD excptRec2;
	excptRec2.ExceptionCode = retValue;
	excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
	excptRec2.ExceptionRecord = pExcptRec;
	excptRec2.NumberParameters = 0; 
	RtlRaiseException( &excptRec2 );
} 

int RtlDispatchException( PEXCEPTION_RECORD pExcptRec, CONTEXT * pContext )
{
	DWORD stackUserBase;
	DWORD stackUserTop;
	PEXCEPTION_REGISTRATION pRegistrationFrame;
	DWORD hLog; 
	// 從FS:[4]和FS:[8]處獲取堆棧的界限
	RtlpGetStackLimits( &stackUserBase, &stackUserTop ); 
	pRegistrationFrame = RtlpGetRegistrationHead();
	while ( -1 != pRegistrationFrame )
	{
		PVOID justPastRegistrationFrame = &pRegistrationFrame + 8;
		if ( stackUserBase > justPastRegistrationFrame )
		{
			pExcptRec->ExceptionFlags |= EH_STACK_INVALID;
			return DISPOSITION_DISMISS; // 0
		} 
		if ( stackUsertop < justPastRegistrationFrame )
		{
			pExcptRec->ExceptionFlags |= EH_STACK_INVALID;
			return DISPOSITION_DISMISS; // 0
		} 
		if ( pRegistrationFrame & 3 ) // 確保堆棧按DWORD對(duì)齊
		{
			pExcptRec->ExceptionFlags |= EH_STACK_INVALID;
			return DISPOSITION_DISMISS; // 0
		} 
		if ( someProcessFlag )
		{
			hLog = RtlpLogExceptionHandler( pExcptRec, pContext, 0,
				pRegistrationFrame, 0x10 );
		} 
		DWORD retValue, dispatcherContext; 
		retValue= RtlpExecuteHandlerForException(pExcptRec, pRegistrationFrame,
			pContext, &dispatcherContext,
			pRegistrationFrame->handler ); 
		if ( someProcessFlag )
			RtlpLogLastExceptionDisposition( hLog, retValue ); 
		if ( 0 == pRegistrationFrame )
		{
			pExcptRec->ExceptionFlags &= ~EH_NESTED_CALL; // 關(guān)閉標(biāo)志
		} 
		EXCEPTION_RECORD excptRec2;
		DWORD yetAnotherValue = 0; 
		if ( DISPOSITION_DISMISS == retValue )
		{
			if ( pExcptRec->ExceptionFlags & EH_NONCONTINUABLE )
			{
				excptRec2.ExceptionRecord = pExcptRec;
				excptRec2.ExceptionNumber = STATUS_NONCONTINUABLE_EXCEPTION;
				excptRec2.ExceptionFlags    = EH_NONCONTINUABLE;
				excptRec2.NumberParameters = 0;
				RtlRaiseException( &excptRec2 );
			}
			else
				return DISPOSITION_CONTINUE_SEARCH;
		}
		else if ( DISPOSITION_CONTINUE_SEARCH == retValue )
		{}
		else if ( DISPOSITION_NESTED_EXCEPTION == retValue )
		{
			pExcptRec->ExceptionFlags |= EH_EXIT_UNWIND;
			if ( dispatcherContext > yetAnotherValue )
				yetAnotherValue = dispatcherContext;
		}
		else // DISPOSITION_COLLIDED_UNWIND
		{
			excptRec2.ExceptionRecord = pExcptRec;
			excptRec2.ExceptionNumber = STATUS_INVALID_DISPOSITION;
			excptRec2.ExceptionFlags    = EH_NONCONTINUABLE;
			excptRec2.NumberParameters = 0;
			RtlRaiseException( &excptRec2 );
		} 
		pRegistrationFrame = pRegistrationFrame->prev; // 轉(zhuǎn)到前一個(gè)幀
	} 
	return DISPOSITION_DISMISS;
} 
_RtlpExecuteHandlerForException: // 處理異常(第一次) 
MOV EDX,XXXXXXXX
JMP ExecuteHandler 
RtlpExecutehandlerForUnwind: // 處理展開(kāi)(第二次) 
MOV EDX,XXXXXXXX 

int ExecuteHandler( PEXCEPTION_RECORD pExcptRec,
		   PEXCEPTION_REGISTRATION pExcptReg,
		   CONTEXT * pContext,
		   PVOID pDispatcherContext,
		   FARPROC handler ) // 實(shí)際上是指向_except_handler()的指針
{
	// 安裝一個(gè)EXCEPTION_REGISTRATION幀,EDX指向相應(yīng)的handler代碼
	PUSH EDX
		PUSH FS:[0]
	MOV FS:[0],ESP 
		// 調(diào)用異常處理回調(diào)函數(shù)
		EAX = handler( pExcptRec, pExcptReg, pContext, pDispatcherContext ); 
	// 移除EXCEPTION_REGISTRATION幀
	MOV ESP,DWORD PTR FS:[00000000]
	POP DWORD PTR FS:[00000000] 
	return EAX;
} 
_RtlpExecuteHandlerForException使用的異常處理程序:
{
	// 如果設(shè)置了展開(kāi)標(biāo)志,返回DISPOSITION_CONTINUE_SEARCH
	// 否則,給pDispatcherContext賦值并返回DISPOSITION_NESTED_EXCEPTION 
	return pExcptRec->ExceptionFlags & EXCEPTION_UNWIND_CONTEXT ?
DISPOSITION_CONTINUE_SEARC : ( *pDispatcherContext = 
			 pRegistrationFrame->scopetable,
			 DISPOSITION_NESTED_EXCEPTION );
} 

_RtlpExecuteHandlerForUnwind使用的異常處理程序:
{
	// 如果設(shè)置了展開(kāi)標(biāo)志,返回DISPOSITION_CONTINUE_SEARCH
	// 否則,給pDispatcherContext賦值并返回DISPOSITION_COLLIDED_UNWIND 
	return pExcptRec->ExceptionFlags & EXCEPTION_UNWIND_CONTEXT ?
DISPOSITION_CONTINUE_SEARCH : ( *pDispatcherContext = 
			  pRegistrationFrame->scopetable,
			  DISPOSITION_COLLIDED_UNWIND );
} 

  

  KiUserExceptionDispatcher 的核心是對(duì) RtlDispatchException 的調(diào)用。這拉開(kāi)了搜索已注冊(cè)的異常處理程序的序幕。如果某個(gè)處理程序處理這個(gè)異常并繼續(xù)執(zhí)行,那么對(duì) RtlDispatchException 的調(diào)用就不會(huì)返回。如果它返回了,只有兩種可能:或者調(diào)用了NtContinue以便讓進(jìn)程繼續(xù)執(zhí)行,或者產(chǎn)生了新的異常。如果是這樣,那異常就不能再繼續(xù)處理了,必須終止進(jìn)程。
  現(xiàn)在把目光對(duì)準(zhǔn) RtlDispatchException 函數(shù)的代碼,這就是我通篇提到的遍歷異常幀的代碼。這個(gè)函數(shù)獲取一個(gè)指向EXCEPTION_REGISTRATION 結(jié)構(gòu)鏈表的指針,然后遍歷此鏈表以尋找一個(gè)異常處理程序。由于堆棧可能已經(jīng)被破壞了,所以這個(gè)例程非常謹(jǐn)慎。在調(diào)用每個(gè)EXCEPTION_REGISTRATION結(jié)構(gòu)中指定的異常處理程序之前,它確保這個(gè)結(jié)構(gòu)是按DWORD對(duì)齊的,并且是在線程的堆棧之中,同時(shí)在堆棧中比前一個(gè)EXCEPTION_REGISTRATION結(jié)構(gòu)高。
  RtlDispatchException并不直接調(diào)用EXCEPTION_REGISTRATION結(jié)構(gòu)中指定的異常處理程序。相反,它調(diào)用 RtlpExecuteHandlerForException來(lái)完成這個(gè)工作。根據(jù)RtlpExecuteHandlerForException的執(zhí)行情況,RtlDispatchException或者繼續(xù)遍歷異常幀,或者引發(fā)另一個(gè)異常。這第二次的異常表明異常處理程序內(nèi)部出現(xiàn)了錯(cuò)誤,這樣就不能繼續(xù)執(zhí)行下去了。
  RtlpExecuteHandlerForException的代碼與RtlpExecuteHandlerForUnwind的代碼極其相似。你可能會(huì)回憶起來(lái)在前面討論展開(kāi)時(shí)我提到過(guò)它。這兩個(gè)“函數(shù)”都只是簡(jiǎn)單地給EDX寄存器加載一個(gè)不同的值然后就調(diào)用ExecuteHandler函數(shù)。也就是說(shuō),RtlpExecuteHandlerForException和RtlpExecuteHandlerForUnwind都是 ExecuteHanlder這個(gè)公共函數(shù)的前端。
  ExecuteHandler查找EXCEPTION_REGISTRATION結(jié)構(gòu)的handler域的值并調(diào)用它。令人奇怪的是,對(duì)異常處理回調(diào)函數(shù)的調(diào)用本身也被一個(gè)結(jié)構(gòu)化異常處理程序封裝著。在SEH自身中使用SEH看起來(lái)有點(diǎn)奇怪,但你思索一會(huì)兒就會(huì)理解其中的含義。如果在異常回調(diào)過(guò)程中引發(fā)了另外一個(gè)異常,操作系統(tǒng)需要知道這個(gè)情況。根據(jù)異常發(fā)生在最初的回調(diào)階段還是展開(kāi)回調(diào)階段,ExecuteHandler或者返回DISPOSITION_NESTED_EXCEPTION,或者返回DISPOSITION_COLLIDED_UNWIND。這兩者都是“紅色警報(bào)!現(xiàn)在把一切都關(guān)掉!”類型的代碼。
  如果你像我一樣,那不僅理解所有與SEH有關(guān)的函數(shù)非常困難,而且記住它們之間的調(diào)用關(guān)系也非常困難。為了幫助我自己記憶,我畫了一個(gè)調(diào)用關(guān)系圖(圖十五)。

圖十五 在SEH中是誰(shuí)調(diào)用了誰(shuí)

    KiUserExceptionDispatcher()
	RtlDispatchException()
		RtlpExecuteHandlerForException()
			ExecuteHandler() // 通常到 __except_handler3

__except_handler3()
	scopetable filter-expression()
	__global_unwind2()
		RtlUnwind()
			RtlpExecuteHandlerForUnwind()
	scopetable __except block()
  

  現(xiàn)在要問(wèn):在調(diào)用ExecuteHandler之前設(shè)置EDX寄存器的值有什么用呢?這非常簡(jiǎn)單。如果ExecuteHandler在調(diào)用用戶安裝的異常處理程序的過(guò)程中出現(xiàn)了什么錯(cuò)誤,它就把EDX指向的代碼作為原始的異常處理程序。它把EDX寄存器的值壓入堆棧作為原始的 EXCEPTION_REGISTRATION結(jié)構(gòu)的handler域。這基本上與我在MYSEH和MYSEH2中對(duì)原始的結(jié)構(gòu)化異常處理的使用情況一樣。

結(jié)論

  結(jié)構(gòu)化異常處理是Win32一個(gè)非常好的特性。多虧有了像Visual C++之類的編譯器的支持層對(duì)它的封裝,一般的程序員才能付出比較小的學(xué)習(xí)代價(jià)就能利用SEH所提供的便利。但是在操作系統(tǒng)層面上,事情遠(yuǎn)比Win32文檔說(shuō)的復(fù)雜。
  不幸的是,由于人人都認(rèn)為系統(tǒng)層面的SEH是一個(gè)非常困難的問(wèn)題,因此至今這方面的資料都不多。在本文中,我已經(jīng)向你指出了系統(tǒng)層面的SEH就是圍繞著簡(jiǎn)單的回調(diào)在打轉(zhuǎn)。如果你理解了回調(diào)的本質(zhì),在此基礎(chǔ)上分層理解,系統(tǒng)層面的結(jié)構(gòu)化異常處理也不是那么難掌握。


附錄:關(guān)于 “prolog 和 epilog ”

在 Visual C++ 文檔中,微軟對(duì) prolog 和 epilog 的解釋是:“保護(hù)現(xiàn)場(chǎng)和恢復(fù)現(xiàn)場(chǎng)” 此附錄摘自微軟 MSDN 庫(kù),詳細(xì)信息參見(jiàn):

    
      http://msdn.microsoft.com/en-us/library/tawsa7cb(VS.80).aspx
    
    (英文)
  
    
      http://msdn.microsoft.com/zh-cn/library/tawsa7cb(VS.80).aspx
    
    (中文)
  

  每個(gè)分配堆棧空間、調(diào)用其他函數(shù)、保存非易失寄存器或使用異常處理的函數(shù)必須具有 Prolog,Prolog 的地址限制在與各自的函數(shù)表項(xiàng)關(guān)聯(lián)的展開(kāi)數(shù)據(jù)中予以說(shuō)明(請(qǐng)參見(jiàn)異常處理 (x64))。Prolog 將執(zhí)行以下操作:必要時(shí)將參數(shù)寄存器保存在其內(nèi)部地址中;將非易失寄存器推入堆棧;為局部變量和臨時(shí)變量分配堆棧的固定部分;(可選)建立幀指針。關(guān)聯(lián)的展開(kāi)數(shù)據(jù)必須描述 Prolog 的操作,必須提供撤消 Prolog 代碼的影響所需的信息。
  如果堆棧中的固定分配超過(guò)一頁(yè)(即大于 4096 字節(jié)),則該堆棧分配的范圍可能超過(guò)一個(gè)虛擬內(nèi)存頁(yè),因此在實(shí)際分配之前必須檢查分配情況。為此,提供了一個(gè)特殊的例程,該例程可從 Prolog 調(diào)用,并且不會(huì)損壞任何參數(shù)寄存器。
  保存非易失寄存器的首選方法是:在進(jìn)行固定堆棧分配之前將這些寄存器移入堆棧。如果在保存非易失寄存器之前執(zhí)行了固定堆棧分配,則很可能需要 32 位位移以便對(duì)保存的寄存器區(qū)域進(jìn)行尋址(據(jù)說(shuō)寄存器的壓棧操作與移動(dòng)操作一樣快,并且在可預(yù)見(jiàn)的未來(lái)一段時(shí)間內(nèi)都應(yīng)該是這樣,盡管壓棧操作之間存在隱含的相關(guān)性)。可按任何順序保存非易失寄存器。但是,在 Prolog 中第一次使用非易失寄存器時(shí)必須對(duì)其進(jìn)行保存。

典型的 Prolog 代碼可以為:

    mov [RSP + 8], RCX
push R15
push R14
push R13
sub RSP, fixed-allocation-size
lea R13, 128[RSP]
...
  

  此 Prolog 執(zhí)行以下操作:將參數(shù)寄存器 RCX 存儲(chǔ)在其標(biāo)識(shí)位置;保存非易失寄存器 R13、R14、R15;分配堆棧幀的固定部分;建立幀指針,該指針將 128 字節(jié)地址指向固定分配區(qū)域。使用偏移量以后,便可以通過(guò)單字節(jié)偏移量對(duì)多個(gè)固定分配區(qū)域進(jìn)行尋址。
  如果固定分配大小大于或等于一頁(yè)內(nèi)存,則在修改 RSP 之前必須調(diào)用 helper 函數(shù)。此 __chkstk helper 函數(shù)負(fù)責(zé)探測(cè)待分配的堆棧范圍,以確保對(duì)堆棧進(jìn)行正確的擴(kuò)展。在這種情況下,前面的 Prolog 示例應(yīng)變?yōu)椋?

    mov [RSP + 8], RCX
push R15
push R14
push R13
mov RAX, fixed-allocation-size
call __chkstk
sub RSP, RAX
lea R13, 128[RSP]
..
  

  .除了 R10、R11 和條件代碼以外,此 __chkstk helper 函數(shù)不會(huì)修改任何寄存器。特別是,此函數(shù)將返回未更改的 RAX,并且不會(huì)修改所有非易失寄存器和參數(shù)傳遞寄存器。
  Epilog 代碼位于函數(shù)的每個(gè)出口。通常只有一個(gè) Prolog,但可以有多個(gè) Epilog。Epilog 代碼執(zhí)行以下操作:必要時(shí)將堆棧修整為其固定分配大小;釋放固定堆棧分配;從堆棧中彈出非易失寄存器的保存值以還原這些寄存器;返回。
  對(duì)于展開(kāi)代碼,Epilog 代碼必須遵守一組嚴(yán)格的規(guī)則,以便通過(guò)異常和中斷進(jìn)行可靠的展開(kāi)。這樣可以減少所需的展開(kāi)數(shù)據(jù)量,因?yàn)槊枋雒總€(gè) Epilog 不需要額外數(shù)據(jù)。通過(guò)向前掃描整個(gè)代碼流以標(biāo)識(shí) Epilog,展開(kāi)代碼可以確定 Epilog 正在執(zhí)行。
如果函數(shù)中沒(méi)有使用任何幀指針,則 Epilog 必須首先釋放堆棧的固定部分,彈出非易失寄存器,然后將控制返回調(diào)用函數(shù)。例如,

    add RSP, fixed-allocation-size
pop R13
pop R14
pop R15
ret
  

  如果函數(shù)中使用了幀指針,則在執(zhí)行 Epilog 之前必須將堆棧修整為其固定分配。這在技術(shù)上不屬于 Epilog。例如,下面的 Epilog 可用于撤消前面使用的 Prolog:

    lea RSP, -128[R13]
; epilogue proper starts here
add RSP, fixed-allocation-size
pop R13
pop R14
pop R15
ret
  

在實(shí)際應(yīng)用中,使用幀指針時(shí),沒(méi)有必要分兩個(gè)步驟調(diào)整 RSP,因此應(yīng)改用以下 Epilog:

    lea RSP, fixed-allocation-size – 128[R13]
pop R13
pop R14
pop R15
ret
  

  以上是 Epilog 的唯一合法形式。它必須由 add RSP,constant 或 lea RSP,constant[FPReg] 組成,后跟一系列零或多個(gè) 8 字節(jié)寄存器 pop、一個(gè) return 或一個(gè) jmp。(Epilog 中只允許 jmp 語(yǔ)句的子集。僅限于具有 ModRM 內(nèi)存引用的 jmp 類,其中 ModRM mod 字段值為 00。在 ModRM mod 字段值為 01 或 10 的 Epilog 中禁止使用 jmp。有關(guān)允許使用的 ModRM 引用的更多信息,請(qǐng)參見(jiàn)“AMD x86-64 Architecture Programmer’s Manual Volume 3: General Purpose and System Instructions”(AMD x86-64 結(jié)構(gòu)程序員手冊(cè)第 3 卷:通用指令和系統(tǒng)指令)中的表 A-15。)不能出現(xiàn)其他代碼。特別是,不能在 Epilog 內(nèi)進(jìn)行調(diào)度,包括加載返回值。
  請(qǐng)注意,未使用幀指針時(shí),Epilog 必須使用 add RSP,constant 釋放堆棧的固定部分,而不能使用 lea RSP,constant[RSP]。由于此限制,在搜索 Epilog 時(shí)展開(kāi)代碼具有較少的識(shí)別模式。
  通過(guò)遵守這些規(guī)則,展開(kāi)代碼便可以確定某個(gè) Epilog 當(dāng)前正在執(zhí)行,并可以模擬該 Epilog 其余部分的執(zhí)行,從而允許重新創(chuàng)建調(diào)用函數(shù)的上下文。

Win32 結(jié)構(gòu)化異常處理(SEH)探秘


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 久草免费在线观看 | 日韩精品在线视频 | 亚洲精品成人无码影院 | 亚洲国产精品无码久久九九大片 | 91麻豆精品91aⅴ久久久久久 | 精品深夜av无码一区二区 | 久久丫精品国产 | 久久综合九九 | 亚洲美女激情视频 | 日韩一区二区视频在线播放 | 色橹橹欧美在线观看视频高清 | 女同久久另类69精品国产 | 爱情岛论坛一区二区 | 91久久免费视频 | 最新777第四色米奇影视 | 婷婷干 | 久久99精品久久久久蜜芽 | 产无套精品一线二线三线 | 久久久精品无码中文天美 | 免费看又黄又爽又猛的视频 | 国产目拍亚洲精品99久久精品 | 亚洲中文字幕一二三四区苍井空 | 亚洲中文字幕久久精品无码喷水 | 国产成人精品午夜片在线观看 | 天天天天色综合 | 在线a亚洲老鸭窝天堂av高清 | 人妻综合专区第一页 | 欧美精品做受xxx性少妇 | 国产又色又爽又黄的网站免费 | 国产精品久久久久久久久动漫 | 伊人成伊人成综合网222 | 色免费看 | 色撸撸在线| 一区=区三区乱码 | 久久97精品久久久久久久不卡 | 精品国偷自产在线视频 | 亚洲九九九九 | 色站综合 | 日本在线视频观看 | 国产mv欧美mv日产mv免费 | 成人一区二区三区视频 | 少妇肉麻粗话对白视频 | 亚洲国产丝袜精品一区 | av网站免费线看精品 | 国产午夜精品免费一区二区三区 | 国产精品苏妲己野外勾搭 | 韩日精品在线观看 | 午夜成人影院网站18进 | 亚洲国产精品无码久久久 | 欧美一区二区三区另类 | 无码视频一区二区三区 | 男人的天堂色 | 国产另类ts人妖一区二区 | 免费看av毛片 | 国产91亚洲精品 | 国产成人av综合色 | 无码中文人妻在线一区 | 91网在线 | 亚洲最大在线观看 | 日本视频免费播放 | 亚洲人成电影免费观看在线看 | 久久久久香蕉 | 亚洲欧美日本另类 | 九色丨porny丨自拍入口 | 欧美日韩人妻精品一区二区三区 | 91精品久久久久久久久久久 | 亚洲另类中文字幕 | 中文字幕三级人妻无码视频 | 午夜理论片在线观看免费 | 中国人妻被两个老外三p | 2020精品国产视 | 免费看黄片毛片 | 超清无码一区二区三区 | av片免费在线 | 国产成人精品成人a在线观看 | 国产精品人妖 | 久久噜 | 日韩视频在线一区 | 97福利影院 | 国产一区日韩 | 美日韩中文字幕 | 79年熟女大胆露脸啪啪对白p | 日本又紧又色又嫩又爽的视频 | 干日本少妇 | 国产免费人成网站x8x8 | 99视频在线精品 | 精品影片在线观看的网站 | 131美女爱做视频免费 | 国产裸体无遮挡免费精品视频 | 欧美激情亚洲一区 | aⅴ网站在线观看 | 欧美视频a | 免费无码一区无码东京热 | 在线超碰av | 亚洲欧美成人另类激情 | 国产一区二区三区四区在线观看 | 欧美特级婬片毛多的少妇 | 国产熟妇勾子乱视频 | 在线中文字幕乱码英文字幕正常 | 亚洲人成网站在线播放影院在线 | 久久妇女高潮喷水多 | 久久久男人的天堂 | 四虎影视永久无码精品 | 欧美亚洲三级 | 波多中文字幕 | 亚洲欧美国产一区二区三区 | 久久人妻av无码中文专区 | 懂色av噜噜一区二区三区av | 丰满少妇大乳高潮高清 | 国产又黄又爽又猛免费视频播放 | 国产精品一区二区av在线观看 | 91在线欧美| 玩弄放荡人妇系列av在线网站 | 快射视频在线观看 | 国产成人av在线免播放观看新 | 成人亚洲一区二区三区在线 | 四虎在线视频免费观看 | 国产精品美女久久久久av福利 | 高清视频一区二区 | 欧美视频在线一区 | 97福利 | 午夜男女无遮掩免费视频 | 成人在线免费播放 | 宅男撸66国产精品 | 中文成人无码精品久久久 | 亚洲第一aaaaa片 | 色综合狠狠操 | 国产一区二区av在线 | www.91色.com| 高h喷水荡肉爽文np肉色学校 | 草草影院欧美 | 欧美色图一区二区 | 国产精品美女久久久浪潮软件 | 国产传媒专区 | 综合亚洲另类欧美久久成人精品 | 欧美日韩精品一区二区 | 美女bbbb| 青青草婷婷 | 精品无码成人网站久久久久久 | 中文字幕69页 | 日韩精品久久无码中文字幕 | 嫩草av久久伊人妇女超级a | 亚洲性色av一区二区三区 | 扶她强h文巨肉高h | 欧美极品少妇xxxxⅹ免费视频 | 夜夜爽妓女8888888视频 | 色片网站在线观看 | 久久精品中文字幕有码 | 久久人人添人人爽添人人88v | 国产日韩欧美视频在线 | 2020最新无码国产在线观看 | 成人在线视频一区 | 国产66av| 这里只有精品视频在线 | 丰满少妇中文字幕 | 亚洲无线观看国产精品 | 春色校园综合人妻av | 被窝的午夜无码福利专区 | 黄色一级片在线看 | 亚洲伊人色欲综合网 | 在线播放免费人成视频在线观看 | 老司机精品成人无码av | 国产乱老熟视频网88av | 日本 精品 高清不卡 | 中文字幕精 | 亚洲卡一卡二新区 | 人妻美妇疯狂迎合系列视频 | 阿v天堂2018| 性做爰片免费视频毛片中文 | 手机在线观看中文字幕 | 亚洲精品视频一区二区 | 国产精品一区二区久久久久 | 色九九视频 | 成人无码无遮挡很h在线播放 | 国产午夜福利片1000无码 | www.色五月.com| 国产无套白浆一区二区 | 欧美黄色激情视频 | 亚洲卡一卡二卡三乱草莓 | 亚洲码无人客一区二区三区 | 欧美一级爽 | 亚洲国产精品99久久久久久久久 | 日韩欧美一区二区在线视频 | 无码天堂亚洲国产av麻豆 | 成人天堂婷婷青青视频在线观看 | 国产又色又爽 | 亚洲爆乳少妇无码激情 | 欧美一级免费在线 | 香蕉久久精品日日躁夜夜躁夏 | 国产精品麻豆免费版 | 艳妇臀荡乳欲伦交换在线看 | 亚洲精品午夜无码专区 | 老子午夜精品无码不卡 | 色偷偷久久一区二区三区 | 色欲av蜜桃一区二区三 | 一区二区免费在线视频 | 中国少妇做爰全过程毛片 | 日韩天天 | 被窝的午夜无码福利专区 | 成 人 网 站国产免费观看 | 手机在线看片1024 | 98色花堂永久在线网站 | 叶子楣三级大全 | 中文字幕乱码中文乱码777 | 国产第一草草影院 | 午夜轮理| 久久精品成人免费国产片 | 日韩国产一区二区 | 91在线91拍拍在线91 | 极品美女在线观看免费直播 | 1024手机在线看 | 久久亚洲精品无码网站 | 日本在线第一页 | www伊人网 | 嫩草影院网站 | 少妇挑战三个黑人惨叫4p国语 | 秋霞影院午夜伦a片欧美 | 放荡闺蜜高h苏桃情事h | 日韩制服丝袜av | 星空大象mv在线观看 | 国产精品农村妇女bbw | 国产一区自拍视频 | 国产稀缺真实呦乱在线 | 午夜蜜桃视频 | 久久精品成人 | 亚洲国产成人无码影片在线播放 | 99大香伊乱码一区二区 | 精品国产一区二区三区日日嗨 | 欧洲一卡2卡3卡4卡国产 | 久草在线影 | 羞羞视频在线播放 | 日韩精品999 | 九九九九九精品 | 精精国产xxxx视频在线播放 | 成人无码av片在线观看蜜桃 | 色婷婷婷丁香亚洲综合 | 五月天黄色小说 | 亚洲一二三四区 | 天堂在线www资源在线 | 亚洲女同成av人片在线观看 | 久久久精品欧美一区二区 | 区久久aaa片69亚洲 | 亚洲欧洲偷自拍图片区 | 午夜福利伦伦电影理论片在线观看 | 亚洲制服丝袜av一区二区三区 | 伊人一区| 欧美成人一区二区三区在线视频 | 五月天一区二区三区 | 亚洲一区二区三区视频在线 | 国产精品卡1卡2卡3网站 | 7777av| 国产精品久久久久久久福利竹菊 | 日韩欧美国产视频 | 久久九九热视频 | 日韩精品黄 | 一区二区三区在线免费观看 | 亚洲精品国偷拍自产在线观看蜜臀 | 亚洲欧美日韩国产精品一区 | 亚洲精品55夜色66夜色 | 国产69精品久久久久观看软件 | 欧美日韩在线视频一区 | 欧美v国产v亚洲v日韩九九 | 成人激情在线视频 | 伦理一区二区三区 | 波多野结衣视频一区二区 | 亚洲综合激情五月丁香六月 | 无码av中文一区二区三区桃花岛 | 欧美精品一线 | 高潮又爽又无遮挡又免费 | 国产99久久九九精品无码 | 精品国产情侣高潮露脸在线 | 亚洲人成无码网www电影麻豆 | 欧美亚洲日韩在线在线影院 | 涩涩视频网 | 亚洲高清揄拍自拍 | 成人性视频免费看 | 国产成人精品a视频一区www | 男人av的天堂| 激情欧美一区二区三区免费看 | 亚洲国产中文在线 | 伊人久久大香 | 男人的天堂va在线无码 | 国产偷国产偷亚州清高app | 色欲av永久无码精品无码 | 日本一卡2卡3卡4卡5卡精品视频 | 国产一区二区精品免费 | 成人亚洲精品777777ww | 亚洲最大综合久久网成人 | eeuss影院一区二区三区 | k频道国产在线观看 | 奇米精品视频一区二区三区 | 手机无码人妻一区二区三区免费 | 中国做爰国产精品视频 | 丰满少妇又爽又紧又丰满在线观看 | 欧美性大战久久久久久 | 91精品国产综合久久久久久蜜臀 | 久久综合九色欧美婷婷 | 亚洲黄色三级视频 | 色佬视频| 秋霞久久久久久一区二区 | av中文在线资源 | 永久免费av在线 | 亚洲日本中文字幕一区二区三区 | 国产三级成人 | 欧美在线播放一区二区 | 免费观看美女裸体网站 | 欧美精品久久久久久久久久丰满 | 日本少妇高潮xxxxx另类 | 亚洲乱亚洲乱 | 视频一区二区三区在线观看 | 亚洲自拍网站 | 亚洲乱码国产乱码精品精小说 | 色爽爽爽 | 91插插插影库永久免费 | 69av片| 欧美np | 国产精品亚洲综合一区在线观看 | 91亚洲精 | 日韩激情一区二区 | 人妖天堂狠狠ts人妖天堂狠狠 | 亚洲男人的天堂在线aⅴ视频 | 人妻少妇无码精品专区 | 久草成人在线视频 | a天堂视频在线观看 | 99热在线免费 | 中文字幕乱码亚洲无线码小说 | 国产真实夫妇4p交换视频 | 九九九免费视频 | 欧美天堂视频 | 久久久免费精品 | 天天揉久久久久亚洲精品 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 日韩一卡二卡三卡四卡免费观在线 | 亚洲天堂网一区二区 | 天天躁日日躁xxxxaaaa | 人妻在厨房被色诱 中文字幕 | 日本在线看片免费人成视频 | 国产在线日本 | 色哟哟网站在线观看 | 免费国产黄色网址 | 少妇被又大又粗下爽a片 | 国产成人自拍小视频 | 国内成人自拍 | 日韩欧美一区二区三区在线观看 | 精品久久久久久久无码人妻热 | 久久99精品久久久久久秒播九色 | 宅男噜噜噜66网站高清 | 亚洲爆乳无码一区二区三区 | 国产精品综合色区在线观看 | 四虎成人精品国产永久免费无码 | 午夜精品久久久久久久99 | 性无码专区无码 | www插插插无码免费视频网站 | 欧美粗大猛烈 | 欧亚激情偷乱人伦小说专区 | 中文字幕精品亚洲无线码一区 | 天天干夜夜玩 | 免费放黄网站在线播放 | 免费无码一区二区三区a片18 | 成人午夜三级 | 午夜极品视频 | 亚洲国产一二 | 国产亚洲精品久久久久秋霞 | 日韩福利视频在线观看 | 男人添女荫道口图片 | 自拍日韩亚洲一区在线 | 成人羞羞视频播放网站 | 欧美一二三区视频 | 丰满圆润自拍少妇啪啪xxx | jizzjizz中国精品麻豆 | 日韩欧美一区二区三区, | 激情爆乳一区二区三区 | 日韩av爽爽爽久久久久久 | 国产人妻精品无码av在线 | 五月天婷婷网站 | 最新极品jizzhd欧美 | 日日摸日日碰夜夜爽av | 色爽黄1000部免费软件下载 | 欧美两根一起进3p在线观看 | 国产91我把她日出白浆 | 久久精品国产99久久无毒不卡 | 伊人久久综合精品无码av专区 | 久久人人爽人人爽人人av | 国产a v高清一区二区三区 | 激情av免费 | 天堂av片 | 久久一码二码三码区别 | 国产对白叫床清晰在线播放 | 国产影片中文字幕 | 欧美精品v国产精品v日韩精品 | 欧美人与动交视频在线观看 | 成人黄色片免费看 | 日韩一级在线观看视频 | 91在线观看. | 欧美四虎| 国产精品丝袜视频 | 国内精品第一页 | 亚洲熟妇av综合网 | 国产自产v一区二区三区c | 日本a级黄绝片a一级啪啪 | 国产91久久婷婷一区二区 | 亚洲 丝袜 制服 欧美 另类 | 国产成人一二三 | 国产福利萌白酱精品tv一区 | 国模少妇一区二区三区 | 亚洲gv天堂gv无码男同 | 日本不卡中文 | 国产一卡2卡3卡四卡精品免费 | 我家有个日本女人 | 欧美va日韩 | 日韩久久毛片 | 福利小视频在线观看 | 高清日韩 | 国产激情自拍 | 涩涩屋av | 日日天日日夜日日摸天天 | 黑人又粗又大xxx精品 | 狠狠色婷婷久久综合频道日韩 | 成人三级k8经典网 | 亚洲色图18p | 国产精品综合久久久精品综合蜜臀 | 极品魔鬼身材女神啪啪96 | 无套内谢少妇毛片免费看 | 欧美另类在线视频 | 国产精品呻吟av久久高潮 | 中文字幕日本免费毛片全过程 | 中文字幕在线视频一区二区三区 | 极品色av| 国产日韩精品一区 | 亚洲a∨无码一区二区 | 日韩精品视频一区二区三区 | 亚洲图片小说综合 | 麻花传媒mv在线观看 | 国产盗摄精品一区二区酒店 | 美女网站在线看 | 免费无码av片在线观看中文 | 五月天综合视频 | 4hu亚洲人成人无码网www电影首页 | 国产精品人成视频免费播放 | 七妺福利精品导航大全 | 中文字幕片 | 欧美日韩成人在线观看 | 亚洲精品18 | 亚洲日韩乱码中文字幕 | 奇米影视奇奇米色狠狠色777 | 一级做受大片免费视频 | 色99色| 久久精品国产亚洲欧美成人 | 精品国产一区二区三区性色av | 亚洲成av人在线观看成年美女 | 91少妇丨porny丨 | 人妻丰满熟妇ⅴ无码区a片 黄色片观看 | 中国男女全黄大片 | 被c到高潮疯狂喷水国产 | 亚洲人成电影在线观看影院 | 91色乱码一区二区三区 | 91超碰中文字幕久久精品 | 初音未来爆乳下裸羞羞无码 | 欧美做爰性生交视频 | 免费精品一区二区三区视频日产 | 亚洲欧美日韩精品久久亚洲区 | 国产乱人伦av在线a麻豆 | 日韩欧美猛交xxxxx无码 | 国内免费精品视频 | 色欲综合视频天天天综合网站 | 丁香婷婷激情俺也去俺来也 | 又粗又黄又猛又爽大片免费 | 亚洲婷婷五月综合狠狠 | 麻豆 美女 丝袜 人妻 中文 | 天天爽夜夜爽人人爽qc | 黑人操少妇 | 伊人国产在线视频 | 亚洲 欧洲 综合 另类小说 | 国产在线观看www污污污 | 色悠久久久久综合网香蕉 | 老司机午夜福利视频 | 一边捏奶一边高潮视频 | 夜夜夜噜噜噜 | 亚洲日韩电影久久 | 中文字幕在线观看一区二区 | 狠狠cao日日穞夜夜穞av | 人人妻人人做人人爽夜欢视频 | 91网在线播放 | 国产亚洲精品久久一区二区三区 | 久久四虎影院 | 久久中文字幕伊人小说小说 | 美女视频福利 | av网页在线观看 | 经典国产乱子伦精品视频 | 久久婷婷丁香七月色综合 | 日韩一区二区三区射精 | 国产免费人成在线视频网站 | 近伦中文字幕 | 2021最新精品国自产拍视频 | 日韩欧群交p片内射中文 | 国产绳艺sm调教室论坛 | 天天色播| 久久久久无码精品国产 | 超碰欧美 | 中文字幕第十二页 | 亚洲亚洲人成网站77777 | 天天干夜夜骑 | 久草视频手机在线 | 国产精品三级国产电影 | 岛国精品在线观看 | 国产香蕉97碰碰视频碰碰看 | 911看片 | 久久久久久久久免费 | 粉嫩av亚洲一区二区图片 | 国产色妇 | 大番蕉尹人一线久久 | 2021国产精品香蕉在线观看 | 99久久综合国产精品二区国产 | 亚洲欧洲免费三级网站 | 依人九九| 夜色成人网 | 国产一区二区无码专区 | 午夜伦4480yy私人影院久久 | 亚洲国产品综合人成综合网站 | 我把护士日出水了视频90分钟 | 天干天干天啪啪夜爽爽av软件 | 国产在线精品无码不卡手机免费 | 麻豆精品久久久久久久99蜜桃 | 日韩精品一卡二卡 | 三级全黄的视频在线观看 | 吃奶呻吟打开双腿做受视频 | 国产欧洲亚洲 | 新天堂av| 日韩精品免费在线视频 | 欧美日韩国产综合新一区 | 国产色爽女 | 日韩久久网| 激情五月深爱五月 | 97涩涩图| 色综合久久88色综合天天提莫 | 国产线播放免费人成视频播放 | 国产女人40精品一区毛片视频 | 国产成人精品女人久久久 | 无码精品人妻一区二区三区老牛 | 韩国乱码片免费看 | 国产精品久久久久77777按摩 | 亚洲国产超清无码专区 | 欧美视频xxx | 大狠狠大臿蕉香蕉大视频 | 色窝窝免费一区二区三区 | 亚洲欧洲日产韩国2020 | 试看120分钟做受小视频 | 国产日韩欧美不卡在线二区 | 婷婷综合五月 | 99热这里只有精品4 欧美色成人 | 99国产精品欧美一区二区三区 | 秋霞网一区二区 | 亚洲国产熟妇无码一区二区69 | 欧美亚洲日本国产综合在线 | 久久久精品人妻一区二区三区gv | 超级大爆乳奶牛被调教出奶水 | 中文字幕超清在线免费 | 欧美另类一区二区 | 欧美日批片 | 日本中文字幕在线观看视频 | 456欧美成人免费视频 | 亚洲国产精品午夜久久久 | 国产人妻xxxx精品hd | 曰批全过程免费视频在线观看无码 | 欧美黑人性猛交xxxx免费动漫 | 北条麻妃一区二区三区中文字幕 | 天堂v在线视频 | 91最新在线视频 | 18禁裸乳无遮挡啪啪无码免费 | 日韩视频中文字幕 | 91九色丨porny最新地址 | 国产aⅴ爽av久久久久电影渣男 | 日韩免费播放 | 中文字幕va一区二区三区 | 国产精品高潮呻吟久久av免费动漫 | 国产极品久久久久极品 | 久草免费福利在线 | 欧美1区2区3区视频 亚洲av禁18成人毛片一级在线 | 免费成人欧美 | 黄瓜视频在线播放 | 午夜热门福利 | 嫩草影院91 | 东京热久久综合伊人av | 91网站永久免费看 | 黄色成人毛片 | 欧洲精品无码一区二区三区在线播放 | 人成午夜免费视频无码 | 午夜看片网| 欧美精品videos另类 | 夜色资源站www国产在线视频 | 日韩字幕在线观看 | 国产精品久久网 | 国产97色在线| 四虎在线观看网站 | 狠狠爱综合 | 丰满人妻被黑人连续中出 | 国产精品欧美一区二区三区不卡 | 大桥未久亚洲无av码在线 | 精品在线播放 | 夏同学福利网 | 色欲色欲天天天www亚洲伊 | 国产精品性视频一区二区 | 醉酒后少妇被疯狂内射视频 | 凹凸日日摸日日碰夜夜爽1 亚洲免费最大黄页网站 | 视色网| 色欲狠狠躁天天躁无码中文字幕 | 黑人50厘米交亚洲女人 | 好吊色综合 | 国产99久久亚洲综合精品 | 日本久久精品视频 | 日韩激情无码免费毛片 | 国产奶水涨喷在线播放 | 久久91网| 好吊操这里有精品 | 亚洲欧美丝袜精品久久 | 欧美日韩伊人 | 亚洲a∨无码一区二区 | 人妻少妇乱子伦精品无码专区电影 | 东京热加勒比视频一区 | 欧美在线播放一区 | 久热在线这里只有精品国产 | 少妇太爽了太深了太硬了 | 真人做人60分钟啪啪免费看 | 白嫩白嫩国产精品 | 日本在线高清不卡免费播放 | 新91视频在线观看 | jizz在线观看| 久久精品中文字幕免费 | 欧美日本高清在线不卡区 | 国产成人久久av免费 | 国产成人精品亚洲日本语言 | 国产无套内射普通话对白 | 久久福利视频导航 | 少妇午夜三级伦理影院播放器 | 伊人福利| 日本一区二区免费在线 | 五月丁香六月激情综合在线视频 | 色噜噜狠狠色综合成人网 | 国产欧美日韩在线播放 | 麻豆精品一卡二卡三卡 | 亚洲成人手机在线 | 午夜少妇性色淫片特黄 | 中文人妻av大区中文不卡 | 亚洲аv电影天堂网 | 日本高清中文字幕免费一区二区 | 婷婷一区二区三区 | 91精品日韩 | 97色伦97色伦国产 | 99在线观看视频 | 美日韩一二三区 | 夜夜欢好(高 h) | www.五月婷婷.com | 午夜免费福利小视频 | 中文字幕永久有效 | 全球av集中精品导航福利 | 国产拍拍拍无码视频免费 | 国模无码视频一区 | 97一区二区国产好的精华液 | 99热免费在线 | 日韩精品一卡2卡3卡4卡新区 | 成人免费毛片网站 | 午夜在线播放 | 成 人 黄 色 视频免费播放 | 国产成人在线视频观看 | 就去干成人网 | 国产精品久久久久久久久av大片 | 偷拍区清纯另类丝袜美腿 | 色老头在线一区二区三区 | 欧美白人最猛性xxxxx | 亚洲激情国产 | av手机网站| 青青草免费在线观看视频 | 国产又黄又大又粗视频 | 国产精品美女被遭强扒开双腿 | 色天天天天| 日本亚洲精品一区二区三区 | 成人在线手机版视频 | 蜜桃成人无码区免费视频网站 | 欧美揉bbbbb揉bbbbb | 国产亚洲午夜高清国产拍精品 | 亚洲图片综合图区20p | 亚洲视频二| 日韩a视频| 久久人人爽人人爽人人av | 国产在线精品免费 | 中文字幕婷婷日韩欧美亚洲 | 久久久婷婷五月亚洲97色 | 亚洲一区二区二区久久成人婷婷 | 亚洲成aⅴ人片在线观 | 成人五月网 | 今日宜喜欢短剧免费观看 | 综合网伊人 | 久久久精品一区二区三区四季av | 午夜免费啪视频在线无码 | 中日韩在线视频 | 另类捆绑调教少妇 | 国产91玉足脚交在线播放 | 免费观看日韩毛片 | 欧美日本视频在线观看 | 波多野吉衣一二三区乱码 | 99久久精品久久久久久清纯 | 少妇高潮流白浆在线观看 | 无码国产精品一区二区色情男同 | 婷婷丁香激情五月 | 最近更新中文字幕免费大全 | 姑娘第5集在线观看免费好剧 | 国产乱子乱人伦电影在线观看 | 日韩va亚洲va欧美va久久 | 国产乱码人妻一区二区三区四区 | 精品日产卡一卡二卡三入口 | 国产色无码专区在线观看 | 欧美自拍嘿咻内射在线观看 | 蜜月va乱码一区二区三区 | 久操视频在线免费观看 | 你懂的亚洲 | 国产色xx群视频射精 | 青春草在线视频 | 人妻互换免费中文字幕 | 日韩欧美在线看 | 国产视频69 | 激情综合婷婷 | 日韩1024 | 人与禽交videos欧美 | 亚洲欧洲日产国码在线 | 久久婷婷人人澡人人爽人人爱 | 欧美高清一区二区三区四区 | 中文字幕无码日韩专区免费 | 熟妇人妻引诱中文字幕 | 香草乱码一二三四区别 | 久久久久久久久久久久久久国产 | 亚洲欧美一区二区三区国产精品 | 亚洲性xxxx | 久久黄色免费网站 | 乱人伦人妻中文字幕在线入口 | 国产av永久无码天堂影院 | 综合狠狠 | 毛片网站在线观看 | 成人男女做爰免费视频网老司机 | 99re6热在线精品视频观看 | 欧美爱爱视频免费 | 91久久久久久亚洲精品蜜桃 | 欧美怡红院免费全部视频 | 国产免费看又黄又粗又硬 | 老司机久久99久久精品播放免费 | 97欧美一乱一性一交一视频 | 国产精品国产免费无码专区不卡 | 国产又粗又大又长又深又刺激 | 精品国产乱码久久久久久鸭王1 | 欧美熟妇另类久久久久久不卡 | 日韩精品无码免费一区二区三区 | 日本sm/羞辱/调教/捆绑视频 | 真实国产乱子伦精品一区二区三区 | 久久99国产精品尤物 | 亚洲精品一区二区三区99 | 尤物网av| 国产人人干 | 国产超碰人人模人人爽人人添 | 国产精品视频一区二区三区不卡 | 人妻中文无码就熟专区 | 五月婷婷六月婷婷 | 中国xxx农村性视频 国产98在线 | 欧美 | 国产成人精品男人的天堂 | 操丝袜少妇 | 日日摸日日干 | 双乳奶水饱满少妇视频 | 成人国产亚洲精品a区天堂 国产偷窥女洗浴在线观看 老妇激情毛片视频 | 欧美不卡一二三区 | 精品亚洲免费 | 夜夜夜夜bbbbbb欧美 | 性视频久久 | 女女同性女同一区二区三区九色 | 欧美日韩一区二区三 | 桃色视频网址 | 国产又爽又黄视频 | 日韩av无码中文无码电影 | 精品在线视频一区二区三区 | 无码人妻一区二区三区免费 | 老太婆av| 国产精品成人观看视频国产奇米 | 国产又大又黄视频 | 不卡av免费观看 | 精品无码国产一区二区三区麻豆 | 天天人人| 亚洲精品久久久久久久久av无码 | 亚洲最大成人网 色香蕉 | 草1024榴社区入口 | 亚洲第一天堂影院 | 国产粗大 | 亚洲高清国产拍精品熟女 | 少妇高潮久久久久久潘金莲 | 91情侣在线 | 久久精品网站视频 | 狍与女人做爰毛片 | 久久免费精品国产72精品 | 亚洲天堂中文在线 | 无码熟妇人妻av在线影片 | 亚洲日本va中文字幕 | 久久91精品 | 精品亚洲欧美视频在线观看 | 偷偷av | 欧美三级视频在线播放 | 亚洲国产97在线精品一区 | 欧美精品一区二区三区蜜臀 | 欧美深夜视频 | 最新日本一道免费一区二区 | www.国产在线 | 国产sm重味一区二区三区 | 四虎网站在线观看 | 久久午夜无码鲁丝片午夜精品 | 91精品国产综合久久久久久软件 | 国产乱码1卡二卡3卡四卡5 | 99久久免费精品国产72精品九九 | 欧美色图片区 | 中国少妇乱子伦视频播放 | 欧美人与动牲交xxxxbbbb | 欧美在线精彩视频免费播放 | 夜操操| 中国少妇的呻吟xvideos | 九九视频久久 | 波多野结衣欲乱 | 亚洲综合国产在不卡在线 | 国产精品亚洲а∨天堂免 | 成人激情在线 | www.av在线 | 伊人久久大香线蕉av不变影院 | 美国av一区二区 | 毛片视频观看 | 国产在线拍偷自揄拍无码 | 久青草视频在线观看 | 国产福利二区 | 春色激情站 | 特黄特色免费视频 | 四虎成人精品永久免费av九九 | 中国av一区 | 久久tv中文字幕首页 | 久久精品国产99久久6动漫亮点 | 精品国产乱码久久久久久久软件 | 亚洲精品网站日本xxxxxxx | 骚虎视频在线观看 | 日本熟妇色高清播放 | 日韩精品视频久久 | 亚洲精品久久一区二区三区777 | 青青草91久久久久久久久 | 波多野结衣黄色片 | 国产精品热久久高潮av袁孑怡 | 国产精品美女久久久浪潮av | 思思久久96热在精品国产 | 久一在线视频 | 亚洲国产精品无码专区在线观看 | 亚洲另类国产综合小说 | 国内精品久久久久久久星辰影视 | 天天躁日日躁狠狠躁a∨麻豆 | 宅男666在线永久免费观看 | 337p粉嫩日本欧洲噜噜 | 玩弄人妻少妇500系列网址 | 久久久久国产综合av天堂 | 久久久福利视频 | 人人插人人澡 | 欧美一区二区三区久久综 | 色偷偷男人天堂 | 日本美妇 | 欧美精品一区二区久久 | 久久国产精品久久久久久电车 | 黄瓜污视频在线观看 | 午夜两性视频 | 欧美综合自拍 | 全球av在线 | 国产卡一卡二卡三无线乱码新区 | 亚洲a区在线观看 | 久久久性色精品国产免费观看 | 成人午夜福利院在线观看 | 男人进女人下部全黄大色视频 | 国产黄色在线观看 | 手机午夜电影神马久久 | 一级黄色片在线 | 久久夫妻视频 | 色国产一区 | 亚洲一区无码中文字幕乱码 | 999午夜 | 91av毛片| 在线看片免费人成视频无毒 | 韩国乱码伦视频免费 | 日本公妇乱偷中文字幕 | 色欲久久久天天天综合网精品 | 国产日韩一区二区三免费高清 | 日本淫少妇 | 欧美性猛交xxx乱久交 | 欧美日韩中文字幕视频 | 久草视频网站 | 影音先锋中文字幕在线播放 | 日韩一级片在线看 | 亚洲一区二区三区在线观看精品中文 | 中文国产一区 | 男人a天堂手机在线版 | 亲近乱子伦免费视频无码 | 超碰av男人的天堂 | 欧美精品激情 | 国产男女无遮挡猛进猛出免费 | www中文在线 | 久久99精品久久久久婷婷暖 | 色先锋av资源中文字幕 | 亚洲国产成人av在线电影播放 | 国产又粗又黄又猛 | 成人国产午夜在线观看 | 影音先锋成人资源网站 | 国产强被迫伦姧在线观看无码 | 成人涩涩网站 | 蜜桃av久| 玖玖爱视频在线观看 | 18禁无码永久免费无限制网站 | 久久不见久久见www电影 | 国产jk精品白丝av在线观看 | av中文字幕第一页 | 又大又长粗又爽又黄少妇视频 | 舌头伸进去搅动好爽视频 | 国内少妇毛片视频 | 黄色免费网页 | 日韩在线高清 | 提莫影院av毛片入口 | 综合无码成人aⅴ视频免费 人人澡人人爽人人 | 国产日韩一区二区在线观看 | 久久综合网av | 国产99在线 | 免费 | 野花国产精品入口 | 日产中文字幕在线观看 | 国产午夜亚洲精品羞羞网站 | 中国黄色毛片 大片 | 日韩夜夜高潮夜夜爽无码 | 少妇的丰满2蘑菇影院 | 福利所第一导航福利 | 国产高清在线精品 | 国产成人无码av片在线观看不卡 | 小泽玛莉亚一区二区视频在线 | 欧美成人aaaa免费全部观看 | 成年人免费在线观看网站 | 未满十八18禁止免费无码网站 | 欧美肥婆性猛交xxxx中国1 | 内射夜晚在线观看 | 亚洲精品久久久久avwww潮水 | 日韩 欧美 亚洲 | 亚洲狠狠丁香综合一区 | 永久免费黄色 | 日本妇乱大交xxxxx | 东京热人妻无码人av | 亚洲最新版av无码中文字幕一区 | 亚洲一本大道av久在线播放 | 亚洲第一色 | 国产美女福利在线 | 亚洲www啪成人一区二区 | 国产精品制服丝袜无码 | av资源中文在线 | 欧美精品系列 | 小泽玛利亚一区二区三区视频 | 日韩成人专区 | 亚洲国产精品综合久久2007 | 欧美不卡视频一区发布 | 性一交一性一交肉体 | 久久月本道色综合久久 | 国产白丝护士av在线网站 | 天堂网中文在线 | 亚洲国产精品人人做人人爱 | 午夜精品久久18免费观看 | www.九色.com | 巨大乳女人做爰视频在线看 | 丰满人妻一区二区三区视频53 | 天堂中文在线资 | 一二区在线观看 | 国产又大又粗又猛又爽的视频 | 亚洲色爱免费观看视频 | 热久久国产 | 国产传媒一本之道 | 亚洲女同在线 | 天天爽夜夜爽人人爽从早干到睌 | 欧美高清视频在线观看 | 中文字幕av无码人妻 | 国产特级毛片aaaaaa毛片 | 在线天堂中文最新版www | 成人毛片观看 | 午夜激情小视频 | 成人99一区二区激情免费看 | 成人重囗味sm | 久久精品人妻无码专区 | 亚洲另类在线制服丝袜国产 | 一区二区三区回区在观看免费视频 | 国产精品免费久久久久电影 | 成人做爰视频www网站小优视频 | 加勒比无码一区二区三区 | 久久久www | 国产成人精品电影在线观看 | 国产精品午夜片在线观看 | 91精品一本久道久久丁香狠狠躁 | 日本少妇bbwbbw精品 | 黄色二级毛片 | 国产亚洲精品久久久久妲己 | 婷婷在线播放 | 日日噜噜夜夜狠狠久久蜜桃 | 国产精品亚洲视频在线观看 | 96亚洲精品久久 | 手机国产乱子伦精品视频 | 老少配性视频免费xxx | 久久久国产99久久国产久 | 国产对白农村老女人性视频对话 | 日韩精品视频国产 | 激情小说区 | 久久久久久久久久久韩国男女 | 久久久久久精品成人鲁丝电影 | 国产香蕉97碰碰视频va碰碰看 | 性猛交ⅹxxx富婆视频 | 天天干天天操天天玩 | 久久久久久综合网天天 | 成人国产三级在线观看 | 中国熟女仑乱hd | 超碰97人人草 | 国产视频一区二区三区在线观看 | www.久久久久久久久 | 成人免费黄色av | 成年女性特黄午夜视频免费看 | 亚洲欧美一区中文字幕蜜臀 | 亚洲精品久久久久午夜aⅴ 色妞精品av一区二区三区 | 国自产偷精品不卡在线 | 亚洲精品动漫免费二区 | 国产丝袜一区二区三区免费视频 | 91精品国产综合久久四虎久久 | 精品一区二区三人妻视频 | 国内外成人激情视频 | 久久九九99 | 日韩成人一级 | 狠狠狠狼鲁亚洲综合网 | 欧美激情精品久久久久久大尺度 | 婷婷色中文字幕综合在线 | 国产av电影区二区三区曰曰骚网 | 五月天精品在线 | 精品午夜久久福利大片 | 国产成人精品怡红院在线观看 | 一级看片免费视频 | 午夜免费网址 | 偷拍激情视频一区二区三区 | 日日干狠狠操 | 国产网红主播精品一区 | 91啦丨国产 | 高潮精品一区videoshd | 日本特黄特色大片免费视频网站 | 欧美肥妇毛多水多bbxx水蜜桃 | 少妇人妻在线无码天堂视频网 | 女人被狂躁到高潮视频免费软件 | 欧美 日产 国产在线观看 | 亚洲精品图片区小说区 | 97久久久亚洲综合久久 | 又爽又黄无遮挡高潮视频网站 | 粗大的内捧猛烈进出少妇视频 | 免费黄色日本 | 强行18分钟处破痛哭av | 人人妻人人妻人人片色av | 国产精品性 | 日韩视频 中文字幕 视频一区 | 亚洲中文字幕无码中文字在线 | 日韩一区二区高清 | 欧美肥婆猛交 | 日本无遮挡吸乳视频 | 婷婷午夜影院 | 国产精品成人av片免费看 | 久久久久国产精品人妻电影 | ady狠狠躁免费视频 日日日干干干 | 不卡欧美| 国产高清露脸孕妇系列 | 国产精品久久久久久久久久妇女 | 美女18免费视频 | 中日韩文字幕无线网站2013 | 永久免费看mv网站入口亚洲 | 玩弄人妻少妇老师美妇厨房 | 久草视频在线免费 | 国产69精品久久久久乱码韩国 | 久青草无码视频在线观看 | 国产夫妇肉麻对白 | 9l视频自拍九色9l视频九色 | 欧美综合成人 | 免费看成人毛片 | 91丨九色丨蝌蚪丨老版 | 伊人热久久婷婷 | 欧美 日韩精品 | 色啪综合 | 亚洲国产精品13p | 久久人人视频 | 欧美com | 国产成人亚洲综合色影视 | 在线中文字幕网站 | 欧美又黄又粗 | 天堂俺去俺来也www 国产麻豆精品传媒 | 久草资源福利 | 18禁h免费动漫无码网站 | 日韩精品无码免费毛片 | 激情视频综合网 | 丁香激情综合久久伊人久久 | 日韩 欧美 亚洲 | 天天干天天干天天 | 国偷自产一区二区三区在线视频 | 亚洲国产精品福利 | 性色a∨精品高清在线观看 岛国激情片 | 亚洲欧美另类小说 | 无码内射中文字幕岛国片 | 青草青在线视频 | 婷婷一二三区 | 亚洲精品国产第一区第二 | 亚洲欧洲日产国码中文字幕 | 99这里只有精品视频 | 91看片黄色 | 精品国产一区二区三区色欲 | 国产乱人对白 | 91精品亚洲| 亚洲网站色 | 四虎影院精品在线观看 | 国产乱肥老妇女精品视频网站 | 美日韩在线观看 | 亚洲一区二区三区高清在线看 | 亚洲一区二区三区视频 | 国产老头和老头xxxx× | 精品国产乱 | 草久久久久久 | 国产精品久久久久久久av | 97视频观看| 九色.com| 中文字幕一区二区三区人妻少妇 | 高清自拍亚洲精品二区 | 无遮挡的又色又污又黄的网站 | 伊人春色在线 | 精品视频一区二区 | 特级毛片在线 | 国产精品海角社区在线观看 | 韩国的无码av看免费大片在线 | 免费看欧美黄色片 | 91国内自产精华天堂 | 国产二区精品 | 中文字幕久久波多野结衣av不卡 | 7777欧美日激情日韩精品 | 亚洲av激情毛片九色一区 | 精品视频九九 | 亚洲三级一区 | 美日韩av在线播放 | 亚洲精品国产精品色诱一区 | 国产小视频在线 | 久久综合精品国产丝袜长腿 | 91成人精品 | 69天堂网| 国产免费久久精品99reswag | 日韩欧美黄色大片 | 欧美黑人做爰爽爽爽 | 亚洲偷自拍另类图片二区 | 久久久精品小视频 | 开心五月激情综合婷婷 | 波多野结衣一区二区三区av高清 | 久草久 | 欧美成人在线免费观看 | 亚洲色图40p| 久久久久二区 | 久久波多野结衣 | 中文字幕国产在线视频 | 欧美激情在线一区二区三区 | xxx久久久| 99久久精品国产综合一区 | 一区二区高清国产在线视频 | 日日夜夜操操操 | 久久久网址 | 狠狠色丁香久久综合婷婷 | 9|在线观看免费 | 中字无码av在线电影 | 成 人 黄 色视频免费播放 | 邻居少妇张开腿让我爽了在线观看 | 欧美日本在线视频 | 天堂√在线| 亚洲美女屁股眼交3 | 欧美激情一区在线观看 | 欧美一区二区三区激情啪啪 | 国产精品女同一区二区 | 亚洲一区日韩在线 | 最新国产av无码专区亚洲 | 91免费毛片 | 大地资源网第二页免费观看 | 爱情岛论坛亚洲永久入口口 | www成人啪啪感受 | 欧美三级久久 | 天堂√在线中文官网在线 | 国产精品第二页 | 少妇性生交xxxⅹxxx | 爱福利视频 | 91极品国产 | av黄色在线观看 | 国产成人综合网 | 久久久噜噜噜www成人网 | 中文字幕无码精品亚洲资源网 | 草草影院欧美 | 久久午夜夜伦鲁鲁片不卡 | 姝姝窝人体色www精品 | 伊人久久大香线蕉亚洲五月天 | 日韩精品在线免费看 | 成人av网页| 国产亚洲精品久久久久久小说 | 国产精品福利网红主播 | 小雪好紧好滑好湿好爽视频 | 亚洲爱婷婷色婷婷五月 | 亚洲精品久久久久中文字幕一区 | www亚洲www | 97超级碰碰碰碰久久久久 | 黄色网页免费在线观看 | 插插操| 中国农村妇女hdxxxx | 狠狠色丁香九九婷婷综合五月 | 九九热精品在线 | 精品熟女少妇a∨免费久久 爆乳熟妇一区二区三区 | 久久激情综合网 | 久久久久久久中文字幕 | 国产精品一区在线播放 | 天堂网在线最新版www资源网 | 欧美人妻一区二区三区 | 四虎最新地址 | 最新国产av最新国产在钱 | 欧美日韩大片在线观看 | aⅴ网站在线观看 | 国内熟妇人妻色在线视频 | 女人黄色特级大片 | 99久久久无码国产麻豆 | 亚洲精品免费在线观看 | 日本中文字幕一区二区 | 国产日产欧产精品精乱子 | 国产美女福利视频 | 草草影院国产 | 奇米二区 | 无码三级国产三级在线电影 | 美女中文字幕 | 国内国外精品影片无人区 | 午夜爽爽久久久毛片 | 欧美操操网 | 91在线免费观看网站 | 国产欧美一区二区三区在线 | 青青青国产精品一区二区 | 国产成人无码av一区二区 | 天堂中文网| www.这里只有精品 | 国产美女被遭高潮免费 | 国产成人精品无码a区在线观看 | 免费国精产品—品二品 | 国产精品国产三级国产普通话99 | 强制中出し~大桥未久在线播放 | 97香蕉超级碰碰碰久久兔费 | 久久精品av一区二区免费 | 91男人影院| 动漫人妻h无码中文字幕 | 少妇夜夜春夜夜爽试看视频 | 激情综合站 | 超碰caopeng| 下面一进一出好爽视频 | 免费又黄又爽又猛的毛片 | 一本到在线 | 亚洲乱码尤物193yw最新网站 | 北条麻妃一二三区 | 欧美 日韩 国产 在线 | 国产在线高清精品二区 | 狠狠干导航 | 成人国内精品久久久久影院vr | 欧美三日本三级三级在线播放 | 日韩经典在线 | 久久精品国产99精品国产亚洲性色 | 欧美一区免费看 | 国产精品久久久久久久久免费丝袜 | 日本在线一区二区 | q2002日韩午夜伦高清 | 99久久国产露脸精品 | 亚洲第99页 | 天天摸天天爽日韩欧美大片 | 久久亚洲精品中文字幕无码 | 99视频国产精品免费观看 | 免费av不卡 | 无码人妻丝袜在线视频 | 国产精品电影久久久久电影网 | 欧美日韩在线免费观看视频 | 亚洲日本va一区二区三区 | 丁香六月色| 欧美三级网站在线观看 | 一级免费观看 | 国产成人精品午夜福利在线播放 | 欧美一级淫片aaaaaaa喷水 | 天天躁日日躁狠狠躁免费麻豆 | 久久午夜无码鲁丝片直播午夜精品 | 自拍偷自拍亚洲精品被多人伦好爽 | 中文字幕v亚洲ⅴv天堂 | 亚洲国产精品久久一线不卡 | 国产精华av午夜在线 | 色噜噜狠狠色综合成人网 | 天堂久久久久va久久久久 | www.色天使| 久操网在线| 四虎国产精品免费久久久 | 日韩欧美一区二区三区免费观看 | 国产乱色精品成人免费视频 | 日本卡2卡3卡4卡5卡精品视频 | 国产尤物在线视精品在亚洲 | 狠狠色丁香久久综合频道日韩 | 国产做受69高潮视频 | 伊人66 | 一区视频免费观看 | 欧美日韩在线视频 | 国产精品自在在线午夜免费 | 亚洲欧洲精品久久 | 国产精品99久久久精品无码 | 国产免费内射又粗又爽密桃视频 | 午夜精品久久久久久99热 | 玖玖玖香蕉精品视频在线观看 | 久久亚洲一区二区三区舞蹈 | 四虎在线免费 | 欧美黑人在线视频 | 久综合在线 | 久久久在线视频 | 少妇被黑人4p到惨叫欧美人 | 囯精品人妻无码一区二区三区99 | 日本毛片在线 | 在线观看日韩精品视频 | 最新毛片网站 | 亚洲国产超清无码专区 | 亚洲国产一区二 | 午夜理伦三级理论三级 | 国产真实精品久久二三区 | 成人无码精品免费视频在线观看 | 亚洲精品国产摄像头 | 成人免费观看视频网站 | 摸少妇的奶她呻吟不断爽视频 | 国产黄色片一级 | 91在线精品视频 | 在线视频日本 | 亚洲欧洲日韩 | 99久re热视频这只有精品6 | 天天爱天天插 | 曰本丰满熟妇xxxx性 | 国产一级免费不卡 | 亚洲三级网站 | av在线激情 | 真实国产乱子伦对白在线播放 | 欧美三级视频 | 337p人体粉嫩胞高清视频 | 亚洲国产成人久久综合人 | 丰满少妇高潮无套内谢 | 婷婷色站 | 免费观看成人毛片a片 | 国产精品综合一区二区三区 | 男人的天堂视频网站 | www.青青操 | 国产熟妇精品高潮一区二区三区 | 久久久国产精品黄毛片 | 国产另类一区 | 中文字幕丰满人伦在线 | 日韩精品一区国产偷窥在线 | 亚洲中文无码av永久不收费 | 国产精品6区 | 天天干夜夜弄 | 免费无码又爽又刺激软件下载直播 | 97se狠狠狠综合亚洲狠狠 | 中文字幕天使萌在线va | 特级一级黄色片 | 99无码精品二区在线视频 | 影音先锋新男人av资源站 | 国产破处在线视频 | 日本护士毛茸茸xx | 免费午夜福利不卡片在线播放 | 欧美一级视频免费观看 | 亚洲第一页在线观看 | 天堂中文а√在线 | 国精产品69永久中国有限 | 99亚洲乱人伦aⅴ精品 | 日本香港三级亚洲三级 | 亚洲 欧美 日韩 国产 丝袜 | 天堂中文av在线 | 国产一区二区欧美 | 国产精品多p对白交换绿帽 99久久99久久精品 | 亚洲经典视频在线观看 | 国产乱色 | 三上悠亚久久 | 日本亲子乱子伦xxxx30路 | 中文在线日本 | 可以直接看av的网址 | 久久一级黄色片 | 好男人在在线社区www在线影院 | www.日日日| 天堂在线www天堂 | 日日狠狠久久8888偷偷色 | 久久不卡视频 | 无码一区二区三区av免费蜜桃 | 色羞羞视频在线观看免费 | 日日夜夜超碰 | 国产又黄又猛又粗又爽的小说网站 | 人妻丰满av无码久久不卡 | 精品国产自在久久现线拍 | 特大巨黑吊xxxx高潮 | 国产视频在线观看一区二区 | 激情五月婷婷 | 韩国精品一区二区三区无码视频 | 亚洲精品无码你懂的网站 | 亚洲熟女乱色综合一区小说 | 尤物在线免费视频 | 女警高潮潮一夜一区二区三区毛片 | 97中文字幕在线 | 国产在线视频91 | 久久综合九色综合97婷婷 | www亚洲精品久久久无码 | 久久精品人人做人人爽播放器 | 亚洲一卡2卡3卡4卡国产 | 热热热久久久 | 国产又粗又猛又爽又黄老大爷 | 欧美久草视频 | 在线成人毛片 | 久久精品无码一区二区www | 在线精品亚洲一区二区动态图 | 四虎毛片 | 国产对白国语对白 | 日韩大片在线观看 | 亚洲制服无码一区二区三区 | 国产口语对白老妇 | 国产色宗合 | 亚洲综合欧美色五月俺也去 | 亚洲妇熟xx妇色黄蜜桃 | 亚洲欧美卡通动漫专区 | 色成人亚洲www78ixcom | 综合色吧 | 精品999视频 | 亚洲女久久久噜噜噜熟女 | 91免费版黄| 日韩视频一区二区三区 | 粉嫩精品国产色综合久久不8 | 亚洲影视大全 | 精品无码久久久久久国产 | jizzz日本| 国产精品xxxxxx | 亚洲 高清 成人 动漫 | 天堂资源官网在线资源 | 性视频网 | 女人天堂影院 | 夜夜草网站 | 在哪里可以看黄色片 | 日日摸天天摸爽爽狠狠97 | 亚洲欧美性受久久久999 | 五月天狠狠干 | 国内少妇偷人精品免费 | 国产欧美亚洲精品a第一页 久久香蕉综合色一综合色88 | 亚洲少妇第一页 | 一级做a爱片性色毛片高清 欧美精品videosex极品 | a级毛片蜜桃成熟时2免费观看 | 欧美精品一二区 | 久久久久久久久毛片精品 | 日本成人福利视频 | 91在线高清视频 | 亚州久久久久区1区2少妇 | 美女视频91| 国产人成高清在线视频99最全资源 | 人妻av乱片av出轨av | 日韩av一中美av一中文字慕 | 手机真实国产乱子伦对白视频 | 国产乱码精品一区二三区蜜臂 | 色婷婷av一区二区 | 日本怡红院免费全部的视频 | 亚洲综合免费 | 欧美三级免费网站 | 奇米影视色777四色在线首页 | 日韩免费无码一区二区三区 | 日韩精品无码综合福利网 | 99re6在线视频精品免费 | 免费人成在线观看网站品善网 | 国产精品二三区 | 在线播放免费人成视频在线观看 | 亚洲熟妇成人精品一区 | 大黑牛凹凸国产视觉盛宴 | 欧美精品欧美极品欧美激情 | 国产 欧美 在线 | 成人免费看黄 | 红桃17c视频永久免费入口 | 国产婷婷色一区二区三区在线 | 久草网视频 | 女人被狂躁的高潮免费视频 | 少妇做爰α片免费视频网站 | 国产精品国产av国产三级 | 久久九九爱 | a极黄色片 | 青青草在线视频网站 | 狠狠躁夜夜躁人人爽视频 | 国产区图片区一区二区三区 | 狠狠色综合激情丁香五月 | 1000部精品久久久久久久久 | 日韩国精品一区二区a片 | 午夜噜噜噜 | 亚洲色欲天天天堂色欲网 | av无码av无码专区 | 国产丝袜视频在线 | 久久夫妻视频 | 日韩一区精品视频一区二区 | 国产又粗又长又大又黄 | 天堂网www在线资源中文 | 色播五月激情五月 | 精品麻豆国产色欲色欲色欲www | 真实国产乱子伦精品一区二区三区 | 久久综合偷偷噜噜噜色 | 中文字幕日产av | 亚洲黄色精品 | 亚洲精品网站在线观看 | 亚洲码欧美码一区二区三区 | 国产精品 欧美日韩 | 国产亚洲精品美女久久久m 欧美高清视频在线观看 | 丰满少妇高潮惨叫久久久 | 一本到中文无码av在线精品 | 日韩一区二区三区毛片 | 美女又爽又黄大尺度 | 涩涩视频软件 | 99自拍偷拍视频 | 精品成人免费自拍视频 | 一级片免费观看 | 久久久久人妻精品区一三寸 | 亚洲无人区一卡2卡三卡 | 免费99精品国产人妻自在现线 | аⅴ天堂中文在线网官网 | 亚洲国产精品97久久无色 | 18成人在线 | 95av视频| 国产精品欧美综合亚洲 | 黑人上司粗大拔不出来电影 | 国产一区精选播放022 | 国产精品乱码 | 国内揄拍国产精品人妻门事件 | 亚洲性线免费观看视频成熟 | 春色导航 | 日韩欧美黄 | 精品一区二区三区影院在线午夜 | 久久久久久久久久久久中文字幕 | 女女百合av大片一区二区三区九县 | 国产精品久久久久久久久潘金莲 | 青青艹在线视频 | 操性感美女 | 欧美孕妇变态孕交粗暴 | 亚洲欧洲自拍 | 久色99| 久亚洲一线产区二线产区三线产区 | 国产妇女性爽视频 | 久久婷婷五月综合97色一本一本 | 又色又爽又黄无遮挡的免费视频 | 精品国产精品网麻豆系列 | 噼里啪啦高清在线观看 | 国产精品一区二区久久精品爱微奶 | 国产无遮挡又黄又爽不要vip网站 | 久久久噜噜噜久噜久久 | 国产鲁鲁视频在线观看免费 | 一二三四社区在线中文视频 | 西西人体大胆瓣开下部自慰 | 午夜福利午夜福利1000 | 激情综合五月 | 无遮无挡三级动态图 | 免费无遮挡禁18污污网站 | 国产精品亚洲一区二区三区 | 人妻av无码中文专区久久 | 久久精品无码一区二区三区免费 | 亚洲aⅴ无码专区在线观看 国产美女三级无套内谢 | 麻豆 美女 丝袜 人妻 中文 | 成年人黄色在线观看 | 大尺度无遮挡激烈床震网站 | 欧美成人一卡二卡三卡四卡 | 无码少妇一区二区三区 | 欧美乱妇高清无乱码免费 | 一区二区三区四区在线播放 | 777米奇色狠狠俺去啦 | 欧美韩日在线 | 木下凛凛子中文字幕亚洲 | 国产精品妇女一二三区 | 手机在线看片你懂的 | 国产人妻无码一区无 | 噜噜噜视频 | 免费萌白酱国产一区二区三区 | 国产黄在线免费观看 | 亚洲成av人片在 | 韩国美女换衣服 | 9999精品成人免费毛片在线看 | 五月激情日韩欧美啪啪婷婷 | 欧美日韩精品成人网视频 | a三级三级成人网站在线视频 | 国产不卡在线视频 | 男女无遮挡激情视频 | 免费看小12萝裸体视频国产 | 无码中文人妻在线一区二区三区 | 欧美爱爱视频免费 | 女人色极品影院 | 日韩欧美tⅴ一中文字暮 | 婷婷黄色网 | 色就操 | 尤物网址在线观看 | 久久精品99视频 | 精品一区二区三区视频 | 99久久久久国产精品免费人果冻 | 国产色综合视频 | 亚洲天堂视频在线观看 | 久久久久久a亚洲欧洲av | 国产亚洲精品一区二区在线观看 | 少妇人妻偷人激情视频 | 无码人妻斩一区二区三区 | 亚洲大乳高潮日本专区 | 野花视频免费版高清在线观看 | 亚洲精品视频免费 | 少妇高潮惨叫久久久久久电影 | 国产在线视频不卡 | 日韩免费网址 | 天天操天天射天天爱 | 日本最新免费二区三区 | 日本精品高清一区二区 | 北条麻妃99精品青青久久主播 | 在线观看老湿视频福利 | 无码一卡二卡三卡四卡 | 美女内射毛片在线看 | 国产成人福利在线 | 精品成人免费一区二区在线播放 | 香蕉久久一区二区三区 | 47pao国产成永久免费视频 | 国产人妻人伦精品久久久 | 亚洲大色堂人在线视频 | 日本成人在线网站 | 久草精品网 | 人妻丰满熟妇av无码片 | 一二三四观看视频社区在线 | 黄在线看片免费人成视频 | 开心春色激情网 | 99精品日本二区留学生 | 国产成人情侣激情视频 | 色综合久久久无码中文字幕 | 一色屋精品视频在线观看免费 | 波多野结衣一区二区三区av免费 | 国产精品久久网站 | 国产精久久一区二区三区 | 毛片视频免费100部 国内精品综合久久久40p | chinatube国语对白 | 全亚洲最大的免费影院 | 国产成人精品免高潮费视频 | 国产精品美女久久久久久久 | 粗壮挺进人妻水蜜桃成熟漫画 | 天天碰天天操 | 女性爽爽影院免费观看 | 曰批视频在线观看 | 狠狠做深爱婷婷综合一区 | 91精品久久久久久久久中文字幕 | 粉嫩av一区二区老牛影视 | 午夜在线不卡精品国产 | 人妻巨大乳挤奶水hd免费看 | 欧美日韩大片在线观看 | 5858s亚洲色大成网站www | 97人人在线 | 久久99精品久久久久久噜噜 | 男女真人国产牲交a做片野外 | 女人19水真多免费毛片 | 国产精品sm调教圈论坛 | 欧美人妖一区 | 午夜寂寞影视 | 丁香花开心四播房麻豆 | 欧美极品色午夜在线视频 | www.99av.com | 无码人妻一区二区三区免费手机 | 亚洲综合网站精品一区二区 | 久久综合五月天 | 日韩精品久久久久影视的特点 | 亚洲精品自产拍在线观看动漫 | 国产日产亚洲系列最新美使用方法 | 黄色一级生活片 | 久久av高潮av无码av | 黄网久久 | 成人无码视频在线观看网站 | 久久香蕉国产线熟妇人妻 | 极度另类bbwbbwbbw日本 | 国产偷国产偷亚洲高清人 | 亚洲午夜无码毛片av久久 | 中文字幕aⅴ人妻一区二区 99热最新精品 | 欧美中字 | 亚洲精品欧洲 | 中文字幕av免费观看 | 91porny首页入口 | 九九热精品在线视频 | 中文字幕乱码无码人妻系列蜜桃 | 亚洲一区二区国产 | 天天干干天天 | 欧美人禽杂交狂配免费看 | 黑人干日本少妇 | 国产乱码免费卡1卡二卡3 | 小婕子伦流澡到高潮h | 男女羞羞羞视频午夜视频 | 制服丨自拍丨欧美丨动漫丨 | 欧插网| 日韩精品动漫一区二区三区 | 免费做爰猛烈吃奶摸视频 | 精品精品国产高清a毛片 | 日韩国产图片区视频一区 | a级性视频| 国产精品爆乳在线播放第一人称 | 蜜臀av无码国产精品色午夜麻豆 | 国产精品久久毛片av大全日韩 | 欧美无乱码久久久免费午夜一区 | 午夜羞羞影院 | 婷婷五月日韩av永久免费 | 欧美成人综合 | 天天干天天射天天操 | 免费欧美一级视频 | 国产精品一区二区久久不卡 | 人人狠狠综合久久亚洲爱咲 | 台湾av在线| 欧美波霸在线 | 91看片在线播放 | 老熟女老太婆爽 | 国产精品视频你懂的 | 人人爽久久涩噜噜噜蜜桃 | 欧美牲交a欧美在线 | 五月婷六月婷婷俺也去 | 欧美黄色高清 | 人人搞人人爽 | 亚洲22p| 伴郎粗大的内捧猛烈进出视频观看 | 亚洲成av 人片在线观看无码 | 激情av在线播放 | 色五月激情五月亚洲综合考虑 | 69av一区 | 日日夜夜撸啊撸 | 亚洲网av | 久久久亚洲精品一区二区三区 | 麻花传媒在线观看免费 | 啪啪tv网站免费入口 | 亚洲欧美成人片在线观看 | 一区二区和激情视频 | 男人的天堂色 | 91网站在线免费观看 | 国产免费爽爽视频 | 日韩av影院在线观看 | 中文精品在线观看 | 久久精品一 | 91美女图片黄在线观看 | 91国偷自产中文字幕久久 | 狠狠综合亚洲综合亚洲色 | 欧美va亚洲 | 久久夜久久 | www.狠狠插| 麻花传媒在线mv免费观看视频 | 又粗又猛又大爽又黄老大爷5 | 性视频免费的视频大全2015年 | 婷婷色婷婷开心五月四房播播 | www.av在线| www,操 | av在线免费播放网站 | 欧美日一区二区三区 | 亚洲色欲久久久综合网东京热 | 特级西西女人444wwww人体 | 最新的中文字幕 | 999精品视频在线 | 国产v亚洲v天堂无码网站 | 久久草av | 狠狠撸在线 | 91porny在线 | 中文字幕亚韩 | 97在线观看永久免费视频 | 四虎永久免费地址入口 | 人人艹人人 | 天堂中文网在线 | 日韩欧美自拍偷拍 | 久热精品免费视频 | 韩国无码无遮挡在线观看 | mm31美女爽爽爽爱做视频vr | 国产特黄特色大片免费视频 | 亚洲激情在线视频 | 秋霞在线观看片无码免费不卡 | 色 亚洲 日韩 国产 综合 | 夜夜操综合 | 一区二区三区不卡在线观看 | 久久京东热 | 日本三级欧美三级人妇视频黑白配 | 成年免费视频黄网站zxgk | 伊人55影院 | 久久成人a | 国产一二区精品 | 天天影视色 | 欧美顶级metart裸体全部自慰 | 色av永久无码影院av | 男人女人做爽爽18禁网站 | 日本在线一区二区三区欧美 | 超碰人人爱人人 | 久久美女av | 尤物yw193无码点击进入 | av手机在线看片 | 久久99精品久久久久婷婷暖 | hs在线观看| 玖玖在线 | www成人在线 | 中文字幕一区三区 | 国产沙发午睡系列999 | 国产九九久久 | 国产精品九九 | 精品一区二区三区国产在线观看 | 中文字幕无码人妻波多野结衣 | 男女无套免费视频网站 | 性色av一区二区三区无码 | 色拍拍国产精品视频免费观看 | 亚洲国产精品成人久久 | 亚洲女人网 | 亚洲综合色区无码专区 | 欧美精品久久96人妻无码 | 9久久精品| 久久精品国产一区二区三 | 岛国毛片 | 无码人妻一区二区三区av | 国产av亚洲精品久久久久久 | 美女福利影院 | a极黄色片 | 影音先锋在线看片资源 | 精品亚洲aⅴ无码一区二区三区 | 色777狠狠狠综合 | 色臀av| 日本黄色美女视频 | 天堂国产永久综合人亚洲欧美 | 亚洲国产精品无码久久久 | 免费网禁国产you女网站下载 | 亚洲性无码av在线dvd | 日本久久丰满的少妇三区 | 精品人妻中文av一区二区三区 | 久久夜av| 天天操操操操操操 | 日韩国产第一页 | 九九99久久精品国产 | 国产熟女内射oooo | 国产一二| 97超碰国产精品无码 | 久涩涩福利视频在线观看 | 国产精品夜色一区二区三区 | 欧美乱强伦xxxxx高潮 | 亚洲另类天堂 | 亚洲色大成网站www久久九 | 99热免费在线 | 天天av天天操 | 丰满的亚洲女人毛茸茸 | 岛国精品在线 | 黄91视频| 天堂av2014| 国产日韩av网站 | 夜夜躁狠狠躁日日躁2002讲述 | 性强烈的欧美三级视频 | 午夜影院啊啊啊 | 欧美一区二区三区色 | 久久久精品视频免费看 | 99ee6这里只有精品热 | 2020国产精品香蕉在线观看 | 欧美老熟妇喷水 | 99国产超薄肉色丝袜交足的后果 | 777国产盗摄视频000 | 丰满少妇理论片 | 中国精品偷拍区偷拍无码 | 国产又爽又黄无码无遮挡在线观看 | 中国毛片网站 | 精品人人妻人人澡人人爽人人 | 亚洲一区二区三区日本久久九 | 免费精品视频在线观看 | 中国少妇内射xxxhd免费 | 国产精品女教师久久二区二区 | 国产99在线| 亚洲第一无码专区天堂 | 亚洲另类一二三区 | 亚洲中文字幕琪琪在线 | 97精品国产手机 | 亚洲国产精品久久久久婷蜜芽 | 久久久久久久久久久综合日本 | 小草国产精品情侣 | 人妻无码一区二区三区av | 99在线精品免费视频 | 久久伊人热热精品中文字幕 | 无码国内精品人妻少妇蜜桃视频 | 少妇又紧又色又爽又刺激视频 | 成人国产精品日本在线观看 | np高h肉辣灌浆调教肉奴 | 男人的午夜天堂 | 亚洲中文字幕乱码一区 | 黄色aa毛片| 亚洲a麻豆乱潮 | 国产成年人免费视频 | www国产 | 风韵犹存丰满大屁股熟妇 | 草草在线免费视频 | 性开放永久免费视频 | 亚洲精品久久久久久偷窥 | 偷偷操不一样的99 | 青青青爽视频在线观看 | 国产午夜无码精品免费看 | 大胆顶级欧美aaa级 亚洲精品亚洲人成在线观看 | www.日本在线视频 | 思思久热思| 国产乱妇乱子在线视频 | 亚洲成人一二三 | 91看黄网站 | av在线播放不卡 | 国产精品成人免费一区二区视频 | 国产亚洲精品a在线无码 | 又色又爽又高潮免费视频观看 | 99久久国产综合精品五月天 | 色多多福利网站免费破解 | 一曲二曲三曲在线观看中文字幕动漫 | 精品久久久久久无码专区不卡 | 免费亚洲婷婷 | 五月天av网站| 国产涩涩视频在线观看 | 毛片网在线 | 欧美性一区 | 日韩在线不卡免费视频一区 | 亚洲人成色77777在线观看 | 中文在线免费视频 | 亚洲日韩av无码美腿丝袜 | 免费啪视频 | 98国产精品视频 | 四虎永久免费 | 大学生被内谢粉嫩无套 | 美女18禁永久免费观看网站 | 亚洲人成网站在线无码 | 色综合久久88色综合天天 | 精品国产露脸久久av | 一区二区三区免费在线 | 亚洲人成网77777香蕉 | 欧美日韩免费高清 | 国产自产高清不卡 | 日本少妇bbb | 亚洲人成网www男同 亚洲最新无码中文字幕久久 | 中文字幕av久久爽一区 | 久久艹精品 | 91热爆在线| 老色鬼在线播放精品视频 | 日韩人妻无码精品专区综合网 | 天堂俺去俺来也www 国产麻豆精品传媒 | 麻花传媒在线观看免费 | 人妻激情偷乱一区二区三区 | xoxo国产三区精品欧美 | 久久久国产精华液 | 精品国产91久久久 | 婷婷综合五月 | 99视频在线视频 | 亚洲 变态 欧美 另类 捆绑 | 99久久er热在这里只有精品15 | 丰满人妻熟妇乱又伦精品app | a欧美亚洲日韩在线观看 | 韩国三级无码hd中文字幕 | 国产麻豆精品一区二区三区v视界 | 日韩在线一区二区三区四区 | 欧美成网站 | 饥渴少妇高潮视频大全 | 在线天堂www在线资源下载 | 亚洲一区二区三区自拍天堂 | 蜜臀av性久久久久蜜臀av | 国产高清成人免费视频在线观看 | 国产精品午夜片在线观看 | 九九热精品在线播放 | 成人免费crm一区二区 | 国产99久久久国产精品~~牛 | 伊人综合影院 | 国产玖玖玖玖精品电影 | 亚洲天堂中文字幕在线 | 日韩午夜在线播放 | 天堂网2021天堂手机版 | 四虎在线免费播放 | 91久久香蕉国产日韩欧美9色 | 欧美成人www免费全部网站 | 欧美久久久久久久久中文字幕 | 国产成本人片无码免费 | 91免费在线观看网站 | 绯色av蜜臀vs少妇 | 国产精品久久久久一区二区三区 | 999国产视频| 好色综合 | 中文字幕无码日韩专区免费 | av高清网站 | 婷婷色香合缴缴情av第三区 | 国产成人精品视频ⅴa片软件竹菊 | 欧美精品一二三四 | 国产精品边做奶水狂喷无码 | 男人的天堂色偷偷 | 免费日韩一区 | 少妇高潮喷水久久久久久久久久 | 天天躁夜夜躁天干天干2020 | 六月丁香婷婷在线 | 夜色福利站www国产在线视频 | 97天天操 | 超碰公开在线 | 久久人人玩人妻潮喷内射人人 | 日韩国产亚洲欧美中国v | 国产精品宾馆在线精品酒店 | 久久久久亚洲国产av麻豆 | 欧美黄色特级视频 | 国产精品女同一区二区久久夜 | 国产日韩欧美日韩 | 久久乐国产精品 | 九九色 | 久久久精品2019中文字幕之3 | 蜜臀久久久久 | 欧美区国产区 | 国产91在线高潮白浆在线观看 | 尤物网址在线观看 | 天天干干夜夜 | 久久综合中文网 | 亚洲欧美综合网 | 91一区二区三区久久久久国产乱 | 理论片中文字幕在线观看 | 区二区三区在线 | 欧洲 | 亚洲www久久久 | 国产亚洲欧美精品永久 | 粉嫩av一区二区在线播 | 亚洲人成电影在线观看青青 | 国产欧美国产综合每日更新 | 五十路熟妇强烈无码 | 精品国产免费观看久久久 | 韩国精品一区二区无码视频 | 亚洲a∨精品永久无码 | 综合激情av | 成人精品毛片va一区二区三区 | 国产又黄又潮娇喘视频 | 精品国产a∨无码一区二区三区 | 亚洲操你| 日本亲近相奷中文字幕 | 精品国产日韩亚洲一区 | 九色porny丨国产首页注册 | 欧美亚洲综合另类色妞网 | 亚洲中文字幕在线第六区 | 欧美在线影院 | 免费成人在线视频观看 | 亚洲熟妇av一区二区三区漫画 | 成人午夜又粗又硬又长 | 夜夜高潮夜夜爽夜夜爱爱一区 | 国产成人午夜精华液 | 国产香蕉一区二区三区在线视频 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 久久精品成人亚洲另类欧美 | 中文字幕乱偷无码av先锋 | 日韩av免费一区二区 | 嫩草嫩草嫩草影院 | 亚洲伦理在线 | 3d成人h动漫网站入口 | 国产日产高清欧美一区 | 国产成人精品2021 | 新影音先锋男人色资源网 | 又爽又黄又无遮挡的激情视频 | 精品视频国产 | 91精品国产高清一区二区三密臀 | 欧美大片免费看 | 最新在线中文字幕 | 五月天亚洲激情 | 四虎娱乐| 新版天堂资源中文8在线 | 日本a一级 | 国色精品卡一卡2卡3卡4卡在线 | 黑人巨茎大战白人美女 | 成年在线网站免费观看无广告 | 欧美一级日韩一级 | 一级aaa毛片 | 美日韩成人 | 国产亚洲人成网站观看 | 国内爆初菊对白视频 | 亚洲日产精品一二三四区 | 亚洲国产另类久久久精品网站 | 免费福利小视频 | 久久九精品 | 日本精品啪啪一区二区三区 | 99精品热6080yy久久 | 国产又黄又猛又粗又爽 | 日韩a片无码一区二区三区电影 | 吸咬奶头狂揉60分钟视频 | 婷婷开心激情综合五月天 | 欧美激情精品久久久久久免费印度 | 日韩亚洲欧美精品综合 | 亚洲精品少妇30p | 国产成人麻豆精品午夜在线 | 伊人久久大香线蕉av一区二区 | 久久久嫩草| 国产精品亚洲专区无码破解版 | 国产精品久久久久影院色老大 | 免费看美女毛片 | 国产成人啪精品视频免费网站软件 | 日韩人妻无码一区二区三区综合 | 久久久www免费人成黑人精品 | 性欧美视频在线 | 国产精品久久久福利 | 欧美成人精品二区三区99精品 | 欧美亚洲精品真实在线 | 在线欧美中文字幕农村电影 | 亚洲v成人天堂影视 | 老湿机69福利区18禁网站 | 亚洲乱码中文字幕在线 | 伊人免费视频 | 九九视频这里只有精品 | 国产亚洲欧美看国产 | 狠狠色噜噜狠狠狠狠色综合久 | 日本成人 | 免费精品国产人妻国语色戒 | 欧美精品国产制服第一页 | 黄色毛片一级视频 | 丰满少妇大叫太大太粗 | 亚洲天天做日日做天天欢 | 日本最黄网站 | 竹菊影视欧美日韩一区二区三区四区五区 | 91黄色视屏 | 少妇裸体淫交免费视频网站 | 97中文字幕在线观看 | 亚洲精品久久无码av片软件 | 亚洲四区在线 | 中出在线视频 | 午夜av亚洲女人剧场se | 国产亚洲产品影视在线产品 | 国产人妻无码一区二区三区免费 | 在线天堂中文www视软件 | 美女视频黄a是视频大全国产 | 国产特级乱淫免费看 | 在线看片免费人成视频大全 | 国产-第1页-浮力影院 | 天堂中文在线免费观看 | 91看片淫黄大片一级在线观看 | 亚洲欧美在线一区中文字幕 | 亚洲在av极品无码天堂 | 国产综合久久99久久 | 婷婷丁香五月缴情视频 | 久久婷婷色综合一区二区 | 国产v亚洲v天堂a无码99 | 中文字幕在线观看视频地址二 | 人妻无码不卡中文字幕在线视频 | 日本特黄特色大片免费视频老年人 | 自拍偷自拍亚洲精品牛影院 | 极品少妇被弄得高潮不断 | 99re6这里只有精品视频在线观看 | 亚洲人成色77777 | 成人网站www污污污网站 | 久章草国语自产拍在线观看 | 欧美日韩在线播放一区 | 自拍偷区亚洲网友综合图片 | 高清欧美精品xxxxx | 国产精品久久久久久久久费观看 | 黄色片国产| 亚洲乱码一区二区三区三上悠亚 | 久久久久无码精品国产人妻无码 | 日韩欧美在线观看视频 | 一本一本久久aa综合精品 | 欧美精品一区二区三 | 国产喷水1区2区3区咪咪爱av | 亚洲国产精品无卡做爰天天 | 热99re久久精品国产首页免费 | 国产日韩av免费无码一区二区三区 | 婷婷丁香五月中文字幕 | 国产三级韩国三级日产三级 | 久久天天躁夜夜躁狠狠2018 | 亚洲精品综合五月久久小说 | 日韩在线高清 | 欧美精品在线观看一区二区 | 风韵丰满熟妇啪啪区老熟熟女 | 影音先锋中文无码一区 | 亚洲国产成人久久综合三区 | 精品国产免费观看久久久 | 中国少妇裸体aaa | 韩国视频高清在线观看 | 91a级片| 国产成人综合久久久久久 | 国产在线视欧美亚综合 | 日本久久久久久久 | 国产区日韩区欧美区 | 青青草国产成人久久 | 密臀av| 亚洲第一无码精品立川理惠 | 狠狠爱天天综合色欲网 | 亚洲乱码中文字幕综合 | 亚洲精品无码高潮喷水在线 | 动漫av一区二区三区 | 日韩欧美国产网站 | av网址在线看 | 国产青草视频 | 国产精品一区二区熟女不卡 | 国产日本欧美在线 | 久久理论片午夜琪琪电影院 | 国产成人av区一区二区三泡芙 | 日本丰满少妇黄大片在线观看 | 国产亚洲精品第一综合麻豆 | 永久免费看视频 | 99精品人妻无码专区在线视频区 | 99精品电影一区二区免费看 | 无码精油按摩潮喷在播放 | 精品国产乱码久久久久久果冻传媒 | 人人人插人人费 | 国产偷国产偷亚州清高app | 日日夜夜免费视频 | 欧美啊v| 国产激情精品视频 | 中文字幕制服丝袜一区二区三区 | 久久精品国产9久久综合 | 人人爽久久涩噜噜噜红粉 | 免费ā片在线观看 | 黑人ⅴvideo暴力亚洲娇小 | 欧美 日本 国产 在线a∨观看 | 人人玩人人添人人澡欧美 | 日韩一二三 | 在线视频观看一区二区 | 色成人精品免费视频 | 国产三级网 | 国产农村黄aaaaa特黄av毛片 | 欧美s码亚洲码精品m码 | 日韩综合在线观看 | 国产成人综合久久精品免费 | 成人国内精品久久久久影院vr | 国产成人无码免费视频麻豆 | 黄色小视频在线免费看 | 美国十次成人欧美色导视频 | 91精品国产爱久久丝袜脚 | 亚洲大色堂人在线无码 | 日韩特级片 | 久热这里只精品99国产6 | 日本丰满的少妇 | 亚洲日本中文 | 日韩在线一二三区 | 在线观看免费人成视频色 | 一本之道之高码清乱码加勒比 | 国产毛1卡2卡3卡4卡免费观看 | 99欧美精品| 亚洲精品国产av成拍色拍婷婷 | 性色av一区二区三区无码 | 国产精品美脚玉足脚交欧美 | 日韩免费无码一区二区三区 | 精品国产一区二区三区色欲 | 一级α片免费看刺激高潮视频 | 日本日本乱码伦视频在线观看 | 欧美性受xxxx黑人猛交88 | 狠狠色综合7777久夜色撩人 | 欧美黄色一级网站 | 国产av亚洲精品久久久久李知恩 | 97人妻碰碰碰久久久久 | 伊人久久99 | 亚洲伊人色欲综合网无码中文 | 欧美va免费高清在线观看 | аⅴ资源中文在线天堂 | 毛茸茸熟妇丰满张开腿呻吟性视频 | 久久婷婷六月综合色液啪 | 欧美一区二区三区小说 | 日本人妖aⅴ系列 | 色综合伊人色综合网站 | 亚洲情网站 | 欧美精品一区二区蜜臀亚洲 | 成人在线免费 | 久久精品欧美日韩 | 日本久操 | 国产熟妇另类久久久久婷婷 | 亚洲乱亚洲乱妇小说网 | 久久九九久精品国产综合 | 主播大秀一区二区三区 | 中文字幕久久久人伦 | 成人自拍视频在线观看 | 日韩欧美视频在线播放 | 精品国产亚洲一区二区三区 | 中国一级片黄色一级片黄 | 国产精品青青 | 草草夜色精品国产噜噜竹菊 | 国产精品第157页 | 成人午夜淫片免费观看 | 亚洲 日韩 另类 制服 无码 | 玖玖在线资源 | 天堂av无码av一区二区三区 | 久久精品一本 | 国产一级免费片 | 99久久婷婷国产综合精品 | 国产免费人成视频尤勿视频 | 国产毛片毛片毛片毛片毛片毛片 | 少妇仑乱a毛片无码 | 久久久久久国产精品免费免费男同 | 亚洲卡一卡二新区入口将开 | 精品国产亚洲福利一区二区 | 国产黄在线观看 | 韩国午夜理论在线观看 | 91性高湖久久久久久久久_久久99 | 基地毛片 | 蜜臀av综合网 | 日本成人在线网站 | 国产精品美女www爽爽爽动态图 | 欧美老熟妇乱大交xxxxx | 色av网址 | 中文字幕123 | 日本肉体做爰猛烈高潮全免费 | 欧美色图亚洲自拍 | 91挑色| 我要看免费的毛片 | 777一区二区 | 久久久久琪琪去精品色一到本 | 一级精品毛片 | 黄色精品视频网站 | 日本欧美一区二区免费视频 | 亚洲人成电影网站色 | 精品无码久久久久国产电影 | 亚欧美日韩香蕉在线播放视频 | 日韩亚洲国产欧美 | 国产成人亚洲日韩欧美 | 欧美伊人网| av色影院| 亚洲片在线| 激情六月丁香婷婷 | 老熟女一区二区免费 | 激情高潮到大叫狂喷水 | 亚洲成色在线综合网站免费 | 国产精品综合av一区二区 | 亚洲熟妇中文字幕五十中出 | 国产99一区 | 成人性生活大片免费看ⅰ软件 | 老司机精品视频一区二区 | 蜜桃免费一区二区三区 | 欧美双人家庭影院 | 男同又粗又大又好爽 小说 女人裸体夜夜爽快 | 亚洲天堂视频在线观看免费 | 成人男女做爰免费视频网老司机 | 国产亚州av| 午夜福利试看120秒体验区 | 九九热视频这里只有精品 | 亚洲欧美精品 | 看h片网站 | 波多野结衣视频在线播放 | 欧美乱人免费视频观看 | 蜜臀久久99精品久久久久野外 | 久久国产精品娇妻素人 | 国产免费片 | 精品无人区一区二区三区 | 免费视频精品一区二区 | 无码中出人妻中文字幕av | 狠狠干精品 | 中日韩精品视频在线观看 | 久草视频中文 | 你懂的福利视频 | 亚欧免费无码aⅴ在线观看蜜桃 | 欧洲一卡2卡3卡4卡国产 | 黄色欧美在线 | 91视频在线网站 | 国产黑色丝袜高跟在线视频 | 狠狠综合久久综合88亚洲爱文 | 日韩av在线免费播放 | 国产精品无套 | 影音先锋久久 | 91av九色 | 国产午夜在线观看 | 国产92成人精品视频免费 | 黄色一级片免费看 | 日韩在线不卡免费视频一区 | 椎名空在线播放 | 精品国产百合女同互慰 | 亚洲狼人精品一区二区三区 | 99re这里只有 | 午夜精品无人区乱码1区2区 | 天天躁日日躁狠狠久久 | 少妇性xxxxxxxxx色武功 | 亚洲男人在线天堂 | 狠狠操一区二区 | 久碰久摸久看视频在线观看 | 黑人ⅴvideo暴力亚洲娇小 | 三级网址在线观看 | 伊人久久伊人 | 无遮挡又色又刺激的女人视频 | 国产va免费精品高清在线 | 77777亚洲午夜久久多喷 | 日本乱偷人妻中文字幕 | 久久久久国色av免费看图片 | 91蜜臀精品国产自偷在线 | 中文字幕线观看 | 能看av的网站 | 狼人久草 | 久久精品极品盛宴观看 | 国内外成人免费激情视频 | 亚洲日韩欧美一区二区三区 | 又硬又水多又坚少妇18p | 久久久精品久久久久 | 老师露双奶头无遮挡挤奶视频 | 无码中文字幕日韩专区 | 国产精品碰碰现在自在拍 | 亚洲字幕av | 日本免费视频 | 呦系列视频一区二区三区 | 色播在线精品一区二区三区四区 | 91久久北条麻妃一区二区三区 | 激情综合色综合啪啪五月丁香 | 天天狠天天透天干天天怕∴ | 国产色黄 | 午夜无码伦费影视在线观看 | 都市激情 小说 | 亚洲视频高清 | 精品毛片一区二区 | 国产在线视频网站 | 媚药一区二区三区四区 | 亚洲一级黄色 | 中文资源在线观看 | 一级片手机在线观看 | 亚洲网站在线 | 在线一区二区欧美 | 最近免费中文字幕大全免费版视频 | 天堂视频vs高清视频 | 精品日本一区二区三区在线观看 | 男人插女人b视频 | 欧美亚洲色aⅴ大片 | 国内精品久久久久影院薰衣草 | 亚洲国产欧美在线人成人 | 久久综合狠狠综合久久 | 久久成年视频 | 黄色毛片一级片 | 日韩精品hd | 欧美中文视频 | 色视频在线播放 | 欧美亚洲免费 | 伊人久久大香线蕉av五月天 | 男人的天堂国产在线视频 | 人妻少妇不满足中文字幕 | 亚洲gv永久无码天堂网 | 性欧美日本 | 美女黄的全免费 | 女同av在线播放 | 国产亚洲在线 | 日本黄色播放器 | 亚洲在线免费观看 | 国产色91| 国产精品一区视频 | 熟妇人妻午夜寂寞影院 | 天堂av在线官网 | 麻豆激情网 | 欧美日韩久久精品 | 日本黄色美女网站 | 天堂8中文在线最新版在线 天天操夜夜摸 | 十八岁污网站在线观看 | 91狠狠狠狠狠狠狠狠 | 人妻耻辱中文字幕在线bd | 张柏芝亚洲一区二区三区 | 午夜好爽好舒服免费视频 | 正在播放老肥熟妇露脸 | 男人天堂视频在线 | 久草日b视频一二三区 | 亚洲精品偷拍无码不卡av | 99热视屏| 九一在线观看免费高清视频 | 色性网| 真人做人60分钟啪啪免费看 | 国产视频黄 | 中国videosex高潮喷水 | 日韩精品在线播放 | 国产人妻aⅴ色偷 | 男人的天堂影院 | 怡红院精品久久久久久久高清 | 欧美一区二区最爽乱淫视频免费看 | 国产欧美在线一区二区三区 | 久久午夜羞羞影院免费观看 | 亚洲精品午夜久久久伊人 | 亚洲欧美一区中文字幕蜜臀 | 国产精品久久国产三级国不卡顿 | 日本高清www视频在线观看 | 精品日韩欧美一区二区在线播放 | 天堂а√在线中文在线鲁大师 | 人妻精品久久无码专区精东影业 | 国产手机在线精品 | 五月激激 | 亚洲人人精品 | 色欲天天婬色婬香综合网完整 | 成 人 色综合 综合网站 | 91九色网站 | 最新国产亚洲人成无码网站 | 亚洲aaaaaa特级| 亚洲视频第一页 | 亚洲一区二区无码偷拍 | 亚洲精品乱码久久久久久按摩观 | 人妻少妇精品久久久久久 | 中文字幕免费高 | 2020国产亚洲美女精品久久久 | 日韩高清成人 | 亚洲欧美丝袜精品久久中文字幕 | 久久久无码精品一区二区三区 | 日本又紧又色又嫩又爽的视频 | 黑人50厘米交亚洲女人 | 梦乃爱华在线播放 | 久久精品这里只有精品 | 日韩av人人夜夜澡人人爽 | 国产玖玖玖九九精品视频靠爱 | 成人午夜高潮刺激免费视频 | 免费欧美一级 | 久久理伦 | 久久精品人妻无码专区 | 人妻丰满熟妇岳av无码区hd | 亚洲最新一卡二卡三卡 | 欧美国产中文在线字幕视频 | 在线看片免费不卡人成视频 | 怡红院av亚洲一区二区三区h | 少妇被又大又粗下爽a片 | 日韩久久视频 | 成人h动漫精品一区二区原神 | 强制高潮18xxxxhd日韩 | 国产成人无码专区 | 四虎新网址 | 日本女人hd | 国产精品永久视频免费 | 亚洲午夜无码久久久久小说 | 精品国产欧美一区二区 | 在线天堂新版最新版在线8 亚洲www啪成人一区二区 | a级片中文字幕 | 国产无遮挡色视频免费观看性色 | 校园春色~综合网 | 97av麻豆蜜桃一区二区 | 无码av无码天堂资源网影音先锋 | 亚洲伊人久久成人综合网 | 国产精品久久国产精麻豆99网站 | 亚洲精品自偷自拍无码忘忧 | 成人国产一区二区三区 | 国产日韩在线视看第一页 | 国产tv| 91精品啪在线观看国产 | 91国内在线视频 | 男女后式激烈动态图片 | 国产成人片一区在线观看 | 亚洲欧美人成网站在线观看看 | 欧美在线激情 | 中文字幕丰满孑伦无码精品 | 亚洲a片v一区二区三区有声 | 国产精品刺激 | 日本不卡视频一区二区 | 97国产真实伦对白精彩视频8 | 国产成人小说视频在线观看 | 婷婷久久久久 | 最近最好的中文字幕2019免费 | 国产精品不卡无码av在线播放 | 国产成人精选视频在线观看 | 日本不卡在线视频 | 人人射人人插 | 密乳av | 亚洲v天堂v手机在线 | 日韩国产综合精选 | av一区二| 国产一区二区在线播放视频 | 色综合激情 | 久久久精品国产一区 | 久草97| 黄色快播视频 | 色婷婷噜噜久久国产精品12p | 欧美天堂网站 | 在线 | 国产精品99传媒a | 中文字幕第22页 | 一区二区三区毛片 | 狠狠操中文字幕 | 成人无高清96免费 | 狠狠色狠狠色综合网 | 色撸撸在线| 99re热视频这里只精品 | 亚洲成熟丰满熟妇高潮xxxxx | 天天操天天艹 | 国产极品粉嫩馒头一线天av | 日本a级在线播放 | 亚洲欧美精品无码一区二区三区 | 四虎成人精品永久免费av | 国产视频一区在线 | 在线a| 五月婷婷网 | 久久午夜夜伦鲁鲁片免费无码 | 九色最新 | 精品免费国产一区二区三区四区 | 午夜高清国产拍精品 | 国产精品亚洲二区在线观看 | 精品香蕉在线观看视频 | 92国产视频 | 免费永久看黄在线观看 | 成在人线av无码免费高潮水 | 美女日日日 | 97人人模人人爽人人少妇 | 高清欧美性猛交xxxx | 国产日韩黄色 | 亚洲国产欧美国产第一区 | 熟女少妇精品一区二区 | 无码一卡二卡三卡四卡 | 1区2区在线观看 | 国产无遮无挡120秒 91福利网站 | 宅男撸66国产精品 | 亚洲日本乱码在线观看 | 国产精品一区二区三区久久 | 秋霞av国产精品一区 | 无码国产精品免费看 | 国产亚洲美女精品久久久 | 国内精品伊人久久久久av影院 | 亚洲精品乱码久久久久久久久久 | 国产精品免费福利 | 精品国产乱码久久久久久郑州公司 | 久久老子午夜精品无码怎么打 | 国产成人久久精品77777的功能 | 亚洲丝袜一区二区 | 亚洲久久在线 | 亚洲国产欧美日韩另类 | 麻花传媒mv在线观看 | 欧美淫网站 | 中文字幕乱人伦视频在线 | 亚洲色婷婷一区二区三区 | 91av久久| 亚洲自拍偷拍网 | 国产成人无码av在线播放dvd | 国产一区二区三区在线看 | 久久精品伊人久久精品伊人 | 一本色道久久88综合亚洲精品ⅰ | 三级动漫在线观看 | 亚洲自拍色 | 国产极品美女高潮抽搐免费网站 | 久久中文字幕人妻av熟女 | 亚洲综合成人av一区在线观看 | 999久久a精品合区久久久 | 日本精品videossex 黑人 | 伊人成人激情 | 中文字幕高清在线免费播放 | 成人免费无码大片a毛片抽搐色欲 | 日本a级在线 | 丰满五十六十老熟女hd | 在线亚洲精品国产成人av剧情 | 好男人在线社区www资源 | 国产精品一区二区三区久久 | 丰满少妇好紧多水视频 | 男人天堂2021 | 2021亚洲国产精品无码 | 天天躁日日躁狠狠躁800凹凸 | 日韩欧美精品在线视频 | 久9re热视频这里只有精品 | 成人精品综合 | 欧美黄色高清视频 | 久久久激情视频 | av无码国产在线看免费网站 | 欧美又粗大人妖一进一出 | 精品亚洲卡一卡2卡三卡乱码 | 久久精品国产字幕高潮 | 免费做爰猛烈吃奶摸视频 | 亚洲高清乱码午夜电影网 | 国产亚洲日韩av在线播放不卡 | 久草视频新 | 亚洲国产成人av毛片大全 | 激情综合小说 | 国产精品高潮呻吟久久av免费动漫 | 夜夜春亚洲嫩草一区二区 | 欧美激情插插插 | 国产在线码观看超清无码视频 | 久草黄色| 国产亚洲欧美一区二区三区 | 婷婷国产 | 人妻丰满av无码中文字幕 | 人妻熟人中文字幕一区二区 | 国产欧美高清在线观看 | 天天舔天天爱 | 手机在线视频你懂的 | 热久久国产欧美一区二区精品 | 国产av福利第一精品 | 好男人在线社区www资源 | 亚洲欧美一区在线 | 男女下面一进一出好爽视频 | 午夜精品少妇 | 国产目拍亚洲精品一区二区 | 男人都懂的网址 | 国产卡一卡二卡三无线乱码新区 | 亚洲免费一区二区 | 九九热在线视频观看这里只有精品 | 91丁香婷婷综合久久欧美 | 精品国产一二 | 午夜免费精品视频 | 亚洲欧洲激情 | 亚洲超清无码制服丝袜无广告 | 少妇一级淫免费播放 | 午夜男女爽爽影院免费视频下载 | 亚洲熟妇色xxxxx亚洲 | 荫蒂添的好舒服视频囗交 | 中出av在线| 在线播放国产一区二区三区 | 人妖一区 | 国产片淫级awww | 亚洲精品中文字幕制 | 中字无码av在线电影 | tube少妇高潮 | 国产怡红院 | 色综合久久久久无码专区 | 少妇无码精油按摩专区 | 亚洲欧美综合精品另类天天更新 | 思思久久精品视频 | 欲色欲色天天天www 在线亚洲天堂 | 欧美国产精品久久 | 色综合天天综合狠狠爱_ | 成人亚洲欧美日韩在线观看 | 国内成人综合 | 内射白嫩少妇超碰 | aa级一级天堂片免费观看 | 国产亚洲产品影视在线产品 | 天摸夜夜添久久精品亚洲人成 | 日本大码a∨欧美在线 | 一区二区三区视频免费看 | 久久午夜夜伦鲁鲁片无码免费 | 日本免费啪视频在线看视频 | 超级碰碰色偷偷免费视频 | 看成年女人午夜毛片免费 | 久久青青草原精品国产app | 久久精品国产99精品国产2021 | 91av综合 | 国产精品免费观看久久 | 亚洲精品久久久久玩吗 | 91精品久久久久久久久久另类 | 日韩国产在线观看 | 成人片黄网站色大片免费毛片 | 2024男人天堂 | 日韩一级片在线看 | 日本免费三片在线观看 | 国产精品剧情对白无套在线观看 | 国产不卡一| 日日摸日日碰人妻无码老牲 | 日韩一二三 | 日韩欧美性视频 | 极品美女扒开粉嫩小泬 | 国产精品自产拍在线观看花钱看 | 欧美午夜精品久久久久久人妖 | 日韩精品三级 | 久久婷婷中文字幕 | 无码日韩av一区二区三区 | 日韩精品视频在线观看网站 | 免费的黄色一级片 | 亚洲综合在线视频自拍 | 忘忧草日本社区在线播放 | 国产黄大片在线观看画质优化 | 久久精品久久精品久久39 | 久久久久三级 | 超清制服丝袜无码av福利网 | 欧美一区二区三区成人久久片 | 91人人澡| 香蕉免费一区二区三区在 | 国产未成满18禁止免费看 | 欧美日批片| 日日摸夜夜添狠狠添欧美 | 成人免费午夜视频 | 久久青草国产免费频观 | 亚洲第一在线综合网站 | 成人tv888 | 精品国产av一二三四区 | 人妻丝袜av先锋影音先 | 中文字幕乱人伦视频在线 | 99视频| 国产日产人妻精品精品 | 亚洲人成网站在线播放影院在线 | 91视频高清 | 波多野结衣办公室33分钟 | 一本精品999爽爽久久久 | 日韩精品手机在线 | 午夜美女裸体福利视频 | 久久国内精品自在自线400部 | 欧美狂野乱码一二三四区 | 国产目拍亚洲精品二区 | 色综合天 | 成人av在线网 | 91精品国产高清一区二区三蜜臀 | 天堂资源最新在线 | 免费无码成人av在线播放不卡 | 天天操狠狠操夜夜操 | 鲁鲁网亚洲站内射污 | 黄色资源 | 亚洲精品国产偷自在线观看 | 久久精品亚洲精品国产欧美kt∨ | 国产一区二区三区导航 | 久久99在线 | 99久久99久久精品国产片果冻 | 国产精品爽爽久久久久久 | 亚洲中文av一区二区三区 | 四川少妇xxxx内谢欧美 | 成人午夜亚洲精品无码区毛片 | 婷婷伊人久久 | 北条麻妃在线一区二区 | 日韩人妻中文无码一区二区七区 | 一个人看的www日本动漫图片 | 亚洲福利在线观看 | 精品美女视频 | 日本少妇内射视频播放舔 | 精品人妻系列无码人妻不卡 | 久久人妻无码中文字幕 | 成av人片一区二区三区久久 | 2020最新无码国产在线观看 | 亚洲欧洲无码专区av | 国产精成人品日日拍夜夜 | 国产av亚洲精品久久久久久 | 色窝窝色蝌蚪在线视频 | 少妇又紧又大又色又爽视频 | 亚洲综合区小说区激情区 | 亚洲人成人影院在线观看 | 黑人强伦姧人妻日韩那庞大的 | 欧美男男作爱videos可播放 | 日韩成人免费 | 尤物精品视频在线观看 | 五月婷婷中文字幕 | 九九热伊人 | 天天久久综合网 | 成·人免费午夜无码视频在线观看 | 国产女人高潮叫床免费视频 | 伊人中文字幕 | 麻豆国产尤物av尤物在线观看 | 91看片淫黄大片一级在线观看 | 91精产国品一二三生产方式 | 波多野结衣视频网址 | 亚洲色婷婷婷婷五月基地 | 国产成人免费看一级大黄 | 就操网 | 男女无套免费视频网站动漫 | 辣+高h+浓+np+肉+黄在线 | 欧美成人a视频 | 日本成人动漫在线观看 | 播放日韩一级黄色片 | 久艹精品 | 国产露脸对白刺激2022 | 亚洲动漫精品无码av天堂 | 在线人人车操人人看视频 | 久久r | 欧美日韩国产在线观看 | 最新天堂中文在线 | 日韩国产欧美一区 | 亚洲一卡久久4卡5卡6卡7卡 | 一级免费看片 | 欧美另类精品xxxx | 天码欧美日本一道免费 | 国产α片免费观看在线人 | 国产福利一区二区麻豆 | 涩涩短视频网站 | 欧美日韩一区二区三区视频免费观看 | 麻豆国产丝袜白领秘书在线观看 | 国产正在播放 | 向日葵视频在线播放 | 手机在线欧美 | 亚洲国产成人欧美激情 | 免费无挡无摭十八禁视频 | 欧美中文在线视频 | 嫩草一二三| 福利不卡 | 欧美一二区视频 | 亚洲美女视频在线 | 免费黄色欧美视频 | 中文字幕免费高清 | 天天拍天天色 | 秋葵视频黄色 | 日本亚洲精品一区二区三区 | 日韩一区二区三区在线播放 | 人妻无码专区一区二区三区 | 国产欧美一区二区三区沐欲 | 一级特黄色| 无套内射蜜桃小视频 | 黑人又粗又大xxx精品 | 亚洲娇小与黑人巨大交 | 欧美三日本三级少妇三2023 | aa在线视频 | 午夜人妻久久久久久久久 | 日韩在线观看视频网站 | 亚洲欧美综合国产不卡 | 欧美黑人又粗又大xxx | 少妇人妻在线无码天堂视频网 | 亚洲中文无码av永久伊人 | 97精品久久天干天天天按摩 | 亚洲色偷偷偷网站色偷一区 | 激情av综合网 | 日本精品中文字幕 | 一区二区免费高清观看国产丝瓜 | 精品av国产一二三四区 | 欧美成人精品高清在线播放 | 亚洲a∨精品一区二区三区下载 | 国内露脸中年夫妇交换 | 中文字幕在线视频免费视频 | 一区二区三区欧美在线观看 | 九九99视频 | 特黄特黄欧美亚高清二区片 | 一本大道卡一卡二卡三乱码全集资源 | 亚洲少妇精品 | 亚洲女线av影视宅男宅女天堂 | 精品久久久久久久中文字幕 | 女色婷婷网 | 亚洲国产欧美在线人成人 | 99re6在线视频精品免费 | 国产日产久久高清欧美一区 | 日本美女动态图 | 国产精品自拍小视频 | 日韩免费三级 | 国产操片 | 久久国产精品77777 | 77米奇,狠狠| 亚洲欧美日韩综合一区二区 | 牲欲强的熟妇农村老妇女 | 偷偷要色偷偷中文无码 | 香蕉精品亚洲二区在线观看 | 推油少妇久久99久久99久久 | 一本色道久久综合狠狠躁篇的优点 | 无码国产伦一区二区三区视频 | 亚洲精品午夜无码电影网 | 在线三级网址 | 久久精品国产免费观看三人同眠 | 成人av首页| 精品人人妻人人澡人人爽牛牛 | 国产美女自卫慰视频福利 | 无翼乌18禁全肉肉无遮挡彩色 | 天堂网av2018 | 亚洲欧美在线综合色影视 | 欧美成人免费大片 | 好爽好紧好大的免费视频国产 | 欧洲美熟女乱又伦av影片 | 日本亚洲欧美高清专区vr专区 | 韩日综合成人中文字幕 | 97超碰中文字幕久久精品 | 四川性一交一乱一乱一视一频 | 天天爽夜夜爽夜夜爽 | 色就色综合 | 日本丰满大乳乳液 | 天堂8中文手机版 | 天天撸天天射 | www.黄色av| 国产成人亚洲精品无码mp4 | 成人无码专区免费播放三区 | 久久99精品久久久子伦 | 青娱乐极品视觉盛宴国产视频 | www.日本在线观看 | 97国产最新 | 国产成人涩涩涩视频在线观看 | 日本强伦姧熟睡人妻完整视频 | av无码不卡在线观看免费 | 久久五月丁香合缴情网 | 自拍偷拍你懂的 | 大乳丰满人妻中文字幕日本电影 | 欧美一区二区三区四区视频 | 亚洲精品成人网久久久久久 | 久久高清| 国产精品女同磨豆腐磨出水了 | 日本欧美一区二区免费视频 | 欧美成人高清视频在线观看 | 亚州国产精品视频 | 亚洲多毛妓女毛茸茸的 | 国产成人理论在线视频观看 | 欧美日韩精品免费 | 久草在线免费福利资源站 | 最近中文字幕在线 | 国产精品色无码av在线观看 | 国产丝袜一区视频在线观看 | 熟妇的奶头又大又粗视频 | 国产精品久久久精品 | 国产成人免费永久在线平台 | 蜜臀av在线无码国产 | 91日韩在线 | 熟熟熟熟熟熟熟熟妇50岁 | 天堂а√在线资源在线 | 国产成人视屏 | 亚洲福利一区二区 | 亚洲精品成人网久久久久久 | 亚洲不卡av一区二区无码不卡 | 国产91久久婷婷一区二区 | 正在播放国产对白孕妇作爱 | 国产好吊看视频在线观看 | 中文字幕在线观看视频免费 | 欧美视频影院 | 中国女人学生69xxx视频 | 国产美女自卫慰视频福利 | 奇米四色狠狠 | 日韩精品2 | 日本囗交全过程无遮挡 | 国产精品久久久久久影视不卡 | 色丁香av| 日日骑| youjizzhd| 久久18禁高潮出水呻吟娇喘 | 亚洲国产毛片 | 色男人av | 国产一区二区三区无码免费 | 美美女高清毛片视频免费观看 | 免费的国产成人av网站装睡的 | 18禁黄久久久aaa片广濑美月 | 婷婷六月综合 | 亚洲a∨精品永久无码 | 欧美性猛交xxxx乱大交少妇 | 国产专业剧情av在线 | 九九热爱视频精品视频16 | 亚洲精品动漫成人3d无尽在线 | 国产成人av大片在线观看 | 亚洲在av极品无码天堂手机版 | 特级黄色网 | 日韩精品一卡2卡3卡4卡新区乱码 | 日韩在线观看网址 | 狠狠狠色丁香婷婷综合激情 | 欧美日韩中文国产一区发布 | 怡春院久久国语视频免费 | 一本色综合 | 色又黄又爽网站www久久 | 国产人妻人伦精品1国产 | 精品久久久久久亚洲综合网站 | 91手机在线视频 | 999.av| 毛片毛片免费看 | 国产传媒麻豆剧精品av国产 | 日韩一卡2卡3卡4卡2021免费观看国色天香 | h色网站免费观看 | 午夜艹逼| 午夜精品久久久久久久久久久 | 亚洲欧美18岁网站 | 国产精品午夜福利在线观看地址 | 九九综合 | 欧美日韩在线视频一区二区 | 另类激情综合网 | 午夜体验区| 精品人妻av一区二区三区 | 国产免费不卡av在线播放 | 色八区人妻在线视频 | 亚洲精品第五页 | 欧美成人福利 | 色网站在线 | 91丨九色丨黑人外教 | 香蕉久草在线 | 国产特级毛片 | 国产成人自拍视频在线 | 中文字幕制服丝袜第57页 | 爽成人777777婷婷 | 少妇被粗大猛进进出出 | 亚洲精品屋v一区二区 | 麻豆国产av丝袜白领传媒 | 一本一道久久综合狠狠老精东影业 | 国产精品久久久久久久久久 | 男女同房做爰爽免费 | 7777少妇色视频免费播放 | 夜夜躁狠狠躁日日躁视频 | 很黄很色很污18禁免费 | 亚洲综合在线一区二区 | 色77久久综合网 | 成人97| 久久无码av一区二区三区 | 手机在线你懂的 | 国产寡妇精品久久久久久 | 黄色在线一区 | 色涩亚洲| 免费观看日韩钙片gv网站 | 精品久久久久久中文字幕2017 | 狠狠的干性视频 | 亚洲乱码中文字幕综合 | 亚洲欧美日韩在线观看一区二区三区 | 国产精品久久久一区二区三区 | 肉肉av福利一精品导航 | 中文字幕乱码熟妇五十中出 | 大乳美女a级三级三级 | 日本丰满毛茸茸熟妇 | 精品无码免费专区毛片 | 亚洲国产精品久久久天堂不卡 | aⅴ精品av导航| 国产精品成人va在线播放 | 爽爽爽av | 真实的国产乱xxxx | 欧美福利小视频 | 中文在线免费看视频 | 亚洲中文在线精品国产百度云 | 正在播放国产乱子伦最新视频 | 国产一区二区三区自产 | 亚洲国产日韩视频观看 | 欧美激性欧美激情在线 | 国产精品偷伦视频免费观看了 | 伊人男人天堂 | 国产成人在线网站 | 久久精品国产99精品国产亚洲性色 | 国产精品久线在线观看 | 国产精品久久久久久久久久久久午夜 | 国产精品卡一 | 天天干天天上 | 激情四月婷婷 | 欧美最黄视频 | 亚洲一区二区三区波多野结衣 | 久草热在线视频 | 国产日韩在线时看高清视频 | 亚洲国产成人精品福利 | 色大师在线观看 | 久久五十路丰满熟女中出 | 亚洲精品无码久久久久不卡 | 狠狠久久噜噜熟女 | 日韩一区二区三区精品视频 | 日韩人妻无码精品无码中文字幕 | 亲子乱对白乱都乱了视频 | 99国产精品国产精品九九 | 无码网站天天爽免费看视频 |