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

小默

(zz)逆向RING0程序從這里開始

標(biāo) 題: 逆向RING0程序從這里開始
作 者: 笨笨雄
時(shí) 間: 2006-12-06 21:41
鏈 接: http://bbs.pediy.com/showthread.php?threadid=35999
詳細(xì)信息:

【文章標(biāo)題】: 逆向RING0程序從這里開始
【文章作者】: 笨笨雄
【作者郵箱】: nemo314@gmail.com
【使用工具】: IDA

接觸RING 0之前,以為得學(xué)很多東西,一大堆驅(qū)動(dòng)開發(fā)的知識(shí)。不過后來想了想,驅(qū)動(dòng)殼等其他不直接訪問硬件的程序?yàn)榱思嫒菪裕豢赡苷娴闹苯釉L問硬件,也就是那些是基于硬件抽象層之上的,而且大部分使用的還是系統(tǒng)提供的API(RING0下使用的API稱為NATIVE API)。事情一下子變簡單了,除非你想通過逆向硬件廠商驅(qū)動(dòng),自己編寫優(yōu)化硬件或者超頻程序。

雖然這是純靜態(tài)分析,但是我希望通過分析整個(gè)驅(qū)動(dòng),你會(huì)理解一些RING0下的機(jī)制,并且懂得在動(dòng)態(tài)調(diào)試中應(yīng)該如何下斷點(diǎn)定位代碼。

在開始之前,感謝rockhard的源代碼和已編譯好的驅(qū)動(dòng),這樣我就可以不必學(xué)習(xí)WINDDK的使用了。你可以在下面鏈接的附件中得到:

http://bbs.pediy.com/showthread.php?s=&threadid=35626
初步實(shí)現(xiàn)系統(tǒng)級(jí)攔截應(yīng)用程序取硬盤物理序列號(hào)

Rockhard發(fā)表上述文章時(shí)的目標(biāo)是通過簡單修改REGMON驅(qū)動(dòng)部分的源代碼完成攔截應(yīng)用程序取硬盤物理序列號(hào)的功能,難免有不足之處。個(gè)人對(duì)源代碼的不成熟評(píng)論并不針對(duì)Rockhard。

學(xué)習(xí)逆向時(shí),我的方法是先看看高級(jí)語言代碼編譯后究竟是怎么樣的。或許最后我還是得學(xué)習(xí)WINDDK的使用,編寫代碼,編譯,反匯編,它會(huì)解答一些疑問。下面讓我來以源碼和反匯編代碼對(duì)照的形式來說明RING0下的一些機(jī)制。

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )

DriverEntry,驅(qū)動(dòng)程序的入口函數(shù),驅(qū)動(dòng)的一些初始化操作,將在這里進(jìn)行。象RING3那樣,程序通過堆棧訪問DriverObject和RegistryPath。而在IDA,反匯編后是這樣子:“; int __stdcall start(PDRIVER_OBJECT DriverObject,HANDLE Handle)”第二個(gè)參數(shù)的名字有點(diǎn)不同,不過不重要,我們知道,其實(shí)它是一樣的。

.text:000105A0                 push    7
.text:000105A2                 pop     ecx
.text:000105A3                 mov     esi, offset s_DeviceHdhook ; "\\Device\\HDHOOK"
.text:000105A8                 lea     edi, [ebp+regnameNt]
.text:000105AE                 push    9
.text:000105B0                 rep movsd
.text:000105B2                 movsw
.text:000105B4                 pop     ecx
.text:000105B5                 mov     esi, offset s_DosdevicesHdh ; "\\DosDevices\\HDHOOK"
.text:000105BA                 lea     edi, [ebp+regnameDos]
.text:000105C0                 push    206B6444h       ; Tag
.text:000105C5                 rep movsd
.text:000105C7                 movsw
.text:000105C9                 mov     esi, offset s_Start ; "Start"
.text:000105CE                 lea     edi, [ebp+SourceString]
.text:000105D1                 movsd
.text:000105D2                 movsd
.text:000105D3                 movsd
.text:000105D4                 mov     esi, [ebp+Handle]
.text:000105D7                 movzx   eax, word ptr [esi]
.text:000105DA                 inc     eax
.text:000105DB                 inc     eax
.text:000105DC                 push    eax             ; NumberOfBytes
.text:000105DD                 push    1               ; PoolType
.text:000105DF                 call    ds:ExAllocatePoolWithTag

前面一大堆代碼,都是因?yàn)橄旅?個(gè)局部變量的定義,編譯器會(huì)生成一段代碼,先將這些字符移進(jìn)堆棧,然后再使用。

WCHAR                   deviceNameBuffer[]  = L"\\Device\\"DRIVER_NAME;
WCHAR                   deviceLinkBuffer[]  = L"\\DosDevices\\"DRIVER_NAME;
WCHAR                   startValueBuffer[] = L"Start";

從逆向的角度來看,象這種靜態(tài)字符變量,如果換成全局變量,或者可以獲得更高的運(yùn)行效率和更小的程序。值得注意的是NATIVE API的調(diào)用,第一個(gè)參數(shù)入棧后的幾行代碼,仍然是局部變量的初始化,這編譯器讓我想起扭曲變形的介紹。000105D4的代碼是從堆棧中取得DriverEntry的第二參數(shù),它是一個(gè)UNICODE_STRING結(jié)構(gòu),從MSDN中搜索到的說明(如無特別說明,一切資料都是從MSDN中搜索得到):

typedef struct _UNICODE_STRING {
  USHORT  Length;
  USHORT  MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING *PUNICODE_STRING;

從000105D7處的代碼來看,該結(jié)構(gòu)在反匯編是:

  WORD  Length
  WORD  MaximumLength
  DWORD  Buffer(指向字符的指針)

通過逆向RtlInitUnicodeString,可知上述結(jié)構(gòu)中的 MaximumLength成員,其實(shí)就相當(dāng)于Length + sizeof(UNICODE_NULL)。關(guān)于調(diào)用ExAllocatePoolWithTag的第三參數(shù)PoolType:

typedef enum _POOL_TYPE {
  NonPagedPool,
  PagedPool,
  NonPagedPoolMustSucceed,
  DontUseThisType,
  NonPagedPoolCacheAligned,
  PagedPoolCacheAligned,
  NonPagedPoolCacheAlignedMustS
} POOL_TYPE;

這里看起來跟PUSH 1好象沒有什么關(guān)系,現(xiàn)在看看源代碼:

    registryPath.Buffer = ExAllocatePool( PagedPool,
                                          RegistryPath->Length + sizeof(UNICODE_NULL));

這里使用的參數(shù)是PagedPool,對(duì)于enum類型的定義,每個(gè)成員代表的數(shù)字是從0開始遞增。PagedPool剛好在第二個(gè)位置,所以它是1。源代碼使用的ExAllocatePool,反匯編后的代碼使用的是ExAllocatePoolWithTag。MSDN的說法是ExAllocatePool已經(jīng)被舍棄了,取代的是ExAllocatePoolWithTag(以標(biāo)識(shí)申請(qǐng)內(nèi)存)。調(diào)用API之后是對(duì)返回結(jié)果的判斷:

    if (!registryPath.Buffer) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

它對(duì)應(yīng)的匯編代碼是

.text:000105E5                 mov     edi, eax
.text:000105E7                 xor     ebx, ebx
.text:000105E9                 cmp     edi, ebx
.text:000105EB                 mov     [ebp+Path], edi
.text:000105EE                 jnz     short loc_105FA
.text:000105EE
.text:000105F0                 mov     eax, 0C000009Ah
.text:000105F5                 jmp     loc_1075A

注意到000105F0,STATUS_INSUFFICIENT_RESOURCES=0C000009Ah,仍然使用EAX作為返回參數(shù)。接下來的源代碼,終于看到編譯優(yōu)化了:

    registryPath.Length = RegistryPath->Length + sizeof(UNICODE_NULL);
    registryPath.MaximumLength = registryPath.Length;

    RtlZeroMemory( registryPath.Buffer, registryPath.Length );

    RtlMoveMemory( registryPath.Buffer,  RegistryPath->Buffer,
                   RegistryPath->Length  );

    RtlZeroMemory( &paramTable[0], sizeof(paramTable));

這里本來要調(diào)用2個(gè)API的。對(duì)于前一個(gè)RtlZeroMemory調(diào)用,編譯器使用自己的代碼來代替它:

.text:000105FA                 mov     ax, [esi]
.text:000105FD                 add     ax, 2
.text:00010601                 movzx   ecx, ax
.text:00010604                 mov     edx, ecx
.text:00010606                 xor     eax, eax
.text:00010608                 shr     ecx, 2
.text:0001060B                 rep stosd
.text:0001060D                 mov     ecx, edx
.text:0001060F                 and     ecx, 3
.text:00010612                 rep stosb

先是4字節(jié)對(duì)齊的填0,然后使用AND取得除以4后的余數(shù),繼續(xù)填0。第二次調(diào)用,編譯器同樣使用自己的代碼來實(shí)現(xiàn)這個(gè)功能:

.text:00010624                 add     esp, 0Ch
.text:00010627                 xor     eax, eax
.text:00010629                 lea     edi, [ebp+QueryTable]
.text:0001062F                 push    0Eh
.text:00010631                 pop     ecx
.text:00010632                 rep stosd

現(xiàn)在讓我們?cè)賮砜纯聪到y(tǒng)中RtlZeroMemory的代碼:

00402520: 57                       PUSH EDI
00402521: 8B7C2408                 MOV EDI, [ESP+08]
00402525: 8B4C240C                 MOV ECX, [ESP+0C]
00402529: 33C0                     XOR EAX, EAX
0040252B: FC                       CLD ;這一句用來保證DF=0
0040252C: 8BD1                     MOV EDX, ECX
0040252E: 83E203                   AND EDX, 00000003
00402531: C1E902                   SHR ECX, 02
00402534: F3AB                     REP STOSD 
00402536: 0BCA                     OR ECX, EDX
00402538: 7504                     JNZ 40253E;非4字節(jié)對(duì)齊,繼續(xù)填0
0040253A: 5F                       POP EDI
0040253B: C20800                   RETN 0008
0040253E: F3AA                     REP STOSB 
00402540: 5F                       POP EDI
00402541: C20800                   RETN 0008

高級(jí)語言似乎不提供修改標(biāo)志寄存器的功能,CLD可以省掉。在編譯過程中比較需要填0的內(nèi)存是否4字節(jié)對(duì)齊,把比較語句也省了。這里的代碼沒有以函數(shù)的形式出現(xiàn),當(dāng)然連傳遞參數(shù)和保存環(huán)境的代碼也省了。至于RtlMoveMemory,編譯器用下面代碼代替:

.text:00010614                 movzx   eax, word ptr [esi]
.text:00010617                 push    eax             ; size_t
.text:00010618                 push    dword ptr [esi+4] ; void *
.text:0001061B                 push    [ebp+Path]      ; void *
.text:0001061E                 call    ds:memmove

選擇使用MEMMOVE而不是RtlMoveMemory。簡單分析了一下,前者為每種情況都準(zhǔn)備了一個(gè)獨(dú)立的處理例程,通過跳轉(zhuǎn)表的形式來實(shí)現(xiàn),后者則是使用了不少比較命令。由于代碼量較多,有興趣的可以自己看看。
編譯出來的程序,至少在代碼段,看起來跟RING 3沒有什么區(qū)別,同樣可以通過程序?qū)崿F(xiàn)的功能和驅(qū)動(dòng)導(dǎo)入表,估計(jì)程序用了什么API,下斷,并最終定位目標(biāo)功能代碼。我們需要做的事,只是熟悉這些API和一些常用的RING0機(jī)制,然后就可以象分析RING 3程序一樣分析RING 0了。下面我將把重點(diǎn)放在API的解釋。程序下一個(gè)調(diào)用的API是RtlQueryRegistryValues,MSDN可以查得該函數(shù)的功能是訪問注冊(cè)表。其中一個(gè)參數(shù)的結(jié)構(gòu)如下:

typedef struct _RTL_QUERY_REGISTRY_TABLE {
    PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
    ULONG Flags;
    PWSTR Name;
    PVOID EntryContext;
    ULONG DefaultType;
    PVOID DefaultData;
    ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;

關(guān)于Flags標(biāo)記,可用的常量如下:

RTL_QUERY_REGISTRY_SUBKEY 
RTL_QUERY_REGISTRY_TOPKEY 
RTL_QUERY_REGISTRY_REQUIRED 
RTL_QUERY_REGISTRY_NOVALUE 
RTL_QUERY_REGISTRY_NOEXPAND 
RTL_QUERY_REGISTRY_DIRECT 
RTL_QUERY_REGISTRY_DELETE

對(duì)于這類型常量定義,從1(二進(jìn)制)開始,第二個(gè)是10(二進(jìn)制),第三個(gè)是100(二進(jìn)制),如此類推。源代碼中使用的是RTL_QUERY_REGISTRY_DIRECT,所以有如下代碼:

.text:0001064F                 mov     [ebp+QueryTable.Flags], 20h

這里有點(diǎn)想不明白,在此API調(diào)用之前的大段代碼和幾個(gè)API的調(diào)用,都是為了初始化此API的Path參數(shù)。為什么不能直接使用入口參數(shù)RegistryPath的BUFFER,而要另外分配內(nèi)存,轉(zhuǎn)移數(shù)據(jù)在作為傳入?yún)?shù)?另外在此API的注釋中看到這一句話“The table must be allocated from nonpaged pool.”。程序沒有申請(qǐng)一塊nonpaged內(nèi)存存放QueryTable結(jié)構(gòu),而是直接使用堆棧。難道RING 0下的堆棧都是nonpaged的?此外程序此后并沒有對(duì)該API的返回值或者返回?cái)?shù)據(jù)作任何處理。這里大膽假設(shè)一下到目前為止的代碼都是垃圾代碼。另外我注意到編譯器的對(duì)于每行代碼幾乎都是很機(jī)械的編譯,下面源代碼:

    paramTable[0].EntryContext = &startType;
    paramTable[0].DefaultType = REG_DWORD;
    paramTable[0].DefaultData = &startType;

對(duì)應(yīng)的反匯編代碼:

.text:00010634                 lea     eax, [ebp+var_4]
.text:00010637                 push    4
.text:00010639                 mov     [ebp+QueryTable.EntryContext], eax
.text:0001063C                 lea     eax, [ebp+var_4]
.text:0001063F                 pop     edi
.text:00010640                 mov     [ebp+QueryTable.DefaultData], eax

編譯器將相同的賦值語句歸類了,但是卻對(duì)EAX重復(fù)賦值,顯然0001063C處的代碼可以省略。接下來是ZwOpenKey。根據(jù)NTSTATUS的定義(詳見WINDDK中的ntstatus.h),最高位有如下定義:

//          00 – Success      ;對(duì)應(yīng)的16進(jìn)制最高位0
//          01 – Informational    ;4
//          10 – Warning      ;8
//          11 – Error        ;c

比較是否成功調(diào)用的代碼是:

.text:0001069D                 test    eax, eax
.text:0001069F                 jl      short loc_106CF;最高位為1(調(diào)用失敗),跳

在RING 3下API調(diào)用失敗返回的是-1,NATIVE API則是以返回值的最高位來判斷調(diào)用是否成功。

.text:00010675                 lea     eax, [ebp+Handle]
.text:00010678                 push    20006h          ; DesiredAccess
.text:0001067D                 push    eax             ; KeyHandle
.text:0001067E                 mov     [ebp+ObjectAttributes.RootDirectory], ebx
.text:00010681                 mov     [ebp+ObjectAttributes.Attributes], 40h
.text:00010688                 mov     [ebp+ObjectAttributes.ObjectName], esi
.text:0001068B                 mov     [ebp+ObjectAttributes.SecurityDescriptor], ebx
.text:0001068E                 mov     [ebp+ObjectAttributes.SecurityQualityOfService], ebx
.text:00010691                 call    ds:ZwOpenKey

由上面代碼可知,該API的KeyHandle參數(shù),使用的就是DriverEntry的第二個(gè)參數(shù)。也就是說KeyHandle其實(shí)就是一個(gè)UNICODE_STRING結(jié)構(gòu)。搞不懂micro$oft,一樣的東西搞這么多概念干什么。另外想不明白的是,假如該API調(diào)用成功,將會(huì)在注冊(cè)表寫入一些數(shù)據(jù)。但是對(duì)程序的運(yùn)行沒有影響。ZwOpenKey調(diào)用失敗了反而省了幾行代碼。隨后是IoCreateDevice和IoCreateSymbolicLink建立驅(qū)動(dòng)對(duì)象和符號(hào)連接,API調(diào)用失敗則把建立的對(duì)象和符號(hào)連接刪除。為IRP_MJ_SHUTDOWN,IRP_MJ_CREATE,IRP_MJ_CLOSE和IRP_MJ_DEVICE_CONTROL分派處理例程。分別有下面對(duì)應(yīng)關(guān)系:

       名稱                                    描述                            調(diào)用的API
IRP_MJ_CREATE                       請(qǐng)求一個(gè)句柄                           CreateFile 
IRP_MJ_CLOSE                       關(guān)閉句柄                             CloseHandle 
IRP_MJ_DEVICE_CONTROL        控制操作(利用IOCTL宏)        DeviceIoControl 
IRP_MJ_SHUTDOWN                   系統(tǒng)關(guān)閉                                InitiateSystemShutdown

當(dāng)RING 3程序調(diào)用上述API對(duì)驅(qū)動(dòng)進(jìn)行操作時(shí),系統(tǒng)會(huì)查找該IRP對(duì)應(yīng)的處理例程地址,并調(diào)用該例程。

.text:0001071B                 mov     eax, offset sub_104B4
.text:00010720                 cmp     edi, ebx
.text:00010722                 mov     [esi+70h], eax
.text:00010725                 mov     [esi+40h], eax
.text:00010728                 mov     [esi+38h], eax
.text:0001072B                 mov     [esi+78h], eax

此處ESI指向的是DriverEntry的第一個(gè)參數(shù)DriverObject。+38h是IRP_MJ_CREATE,+40h是IRP_MJ_CLOSE。具體請(qǐng)查閱WINDDK中的wdm.h。

.text:0001074E                 mov     eax, ds:KeServiceDescriptorTable
.text:00010753                 mov     dword_1080C, eax

執(zhí)行完這兩行代碼,把SSDT存到全局變量中便結(jié)束了DriverEntry例程,也就是說驅(qū)動(dòng)的初始化完畢了。實(shí)現(xiàn)驅(qū)動(dòng)功能的代碼在IRP例程中,這讓我想起RING 3下的消息環(huán)。下面來看看sub_104B4:

.text:000104B4 sub_104B4       proc near               ; DATA XREF: start+187 o
.text:000104B4                  ;按照IRPDispatch例程的定義
.text:000104B4 arg_0           = dword ptr  8      ;DeviceObject
.text:000104B4 arg_4           = dword ptr  0Ch    ;pIrp

關(guān)于pIrp結(jié)構(gòu),MSDN中的定義不完整。對(duì)照源代碼可知:

+0ch    DWORD    AssociatedIrp.SystemBuffer
+18h    DWORD    IoStatus.Status
+1Ch    DWORD    IoStatus.Information
+3ch    DWORD    UserBuffer
+60h    DWORD    irpStack

irpStack:

+00h    BYTE    MajorFunction ,查詢WINDDK中的WDM.h可知

#define IRP_MJ_CREATE                      0x00
#define IRP_MJ_CLOSE                      0x02
#define IRP_MJ_DEVICE_CONTROL           0x0e
#define IRP_MJ_SHUTDOWN                 0x10

+04h    DWORD    Parameters.DeviceIoControl.OutputBufferLength
+08h    DWORD    Parameters.DeviceIoControl.InputBufferLength
+0ch    DWORD    Parameters.DeviceIoControl.IoControlCode
+18h    DWORD    FileObject

該函數(shù)根據(jù)不同的IRP消息,進(jìn)入不同的流程。其中從IRP_MJ_DEVICE_CONTROL的處理流程可知,當(dāng)IoControlCode的低3位為111(二進(jìn)制,即METHOD_NEITHER)時(shí),驅(qū)動(dòng)程序使用UserBuffer返回?cái)?shù)據(jù),反之則使用SystemBuffer。現(xiàn)在來看看sub_103DA,即是源代碼中的HDHookDeviceControl函數(shù):

.text:000103EB                 cmp     ecx, 83050000h
.text:000103F1                 jz      loc_104A7
.text:000103F1
.text:000103F7                 cmp     ecx, 83050004h
.text:000103FD                 jz      loc_104A0
.text:000103FD
.text:00010403                 cmp     ecx, 83050008h
.text:00010409                 jz      short loc_1047E
.text:00010409
.text:0001040B                 cmp     ecx, 8305000Ch
.text:00010411                 jz      short loc_10452
.text:00010411
.text:00010413                 cmp     ecx, 83050010h
.text:00010419                 jz      short loc_10426

函數(shù)將IoControlCode保存在ECX中,經(jīng)過對(duì)比跳轉(zhuǎn)到相關(guān)代碼中。在用戶態(tài)程序中,通過下面API與驅(qū)動(dòng)進(jìn)行通信:

BOOL DeviceIoControl(

    HANDLE hDevice,  // handle to device of interest
    DWORD dwIoControlCode,  // control code of operation to perform
    LPVOID lpInBuffer,  // pointer to buffer to supply input data
    DWORD nInBufferSize,  // size of input buffer
    LPVOID lpOutBuffer,  // pointer to buffer to receive output data
    DWORD nOutBufferSize,  // size of output buffer
    LPDWORD lpBytesReturned,  // pointer to variable to receive output byte count
    LPOVERLAPPED lpOverlapped   // pointer to overlapped structure for asynchronous operation
   );

也就是說,攔截該API,取得dwIoControlCode,在IRP分派例程的入口下條件斷點(diǎn)。然后便可以定位驅(qū)動(dòng)中相關(guān)的功能代碼。我想看到這里,大家都大概了解RING 0的一些機(jī)制,并且能嘗試動(dòng)態(tài)調(diào)試一些程序了。該程序大部分代碼的功能Rockhard在他的貼里已經(jīng)講得很清楚了,除了如何取得系統(tǒng)調(diào)用號(hào)。我們知道系統(tǒng)調(diào)用號(hào)隨著系統(tǒng)版本,甚至SP之間也會(huì)有所不同,如何兼容各版本?我對(duì)此很感興趣,先看看源代碼:

VOID HookStart( void )
{
    if( !IsHooked ) {
        RealZwDeviceIoControlFile = SYSCALL( ZwDeviceIoControlFile );
        SYSCALL( ZwDeviceIoControlFile ) = (PVOID) HookZwDeviceIoControlFile;
        IsHooked = TRUE;
    }
}

你能想象這樣的代碼能取得ZwDeviceIoControlFile在SSDT中的位置嗎?現(xiàn)在再讓我們看看反匯編代碼:

.text:00010381                 mov     eax, ds:ZwDeviceIoControlFile
.text:00010386                 mov     ecx, ssdt
.text:0001038C                 push    esi
.text:0001038D                 mov     edx, [eax+1];這里有點(diǎn)奇怪,取函數(shù)的機(jī)械碼?
.text:00010390                 mov     esi, [ecx]
.text:00010392                 mov     edx, [esi+edx*4]
.text:00010395                 pop     esi
.text:00010396                 mov     dword_10814, edx
.text:0001039C                 mov     eax, [eax+1]
.text:0001039F                 mov     ecx, [ecx]
.text:000103A1                 mov     dword ptr [ecx+eax*4], offset sub_1030E

現(xiàn)在讓我們來看看ZwDeviceIoControlFile的代碼:

00400BC6: B838000000               MOV EAX, 00000038
00400BCB: 8D542404                 LEA EDX, [ESP+04]
00400BCF: CD2E                     INT 2E
00400BD1: C22800                   RETN 0028

入口點(diǎn)加1,便是系統(tǒng)調(diào)用號(hào)。最后感謝所有看到這里的人

posted on 2010-02-05 23:47 小默 閱讀(549) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Language

導(dǎo)航

統(tǒng)計(jì)

留言簿(13)

隨筆分類(287)

隨筆檔案(289)

漏洞

搜索

積分與排名

最新評(píng)論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            激情av一区| 亚洲精品日产精品乱码不卡| 国产一级精品aaaaa看| 国产精品jvid在线观看蜜臀 | 国产精品99久久久久久久vr| 亚洲精品在线免费| 一本久道久久综合婷婷鲸鱼| 亚洲成人中文| 久久精品女人的天堂av| 欧美亚洲综合网| 亚洲一线二线三线久久久| 中文在线不卡| 久久国产精品毛片| 久久婷婷亚洲| 欧美国产综合一区二区| 欧美极品欧美精品欧美视频| 欧美香蕉视频| 黑人极品videos精品欧美裸| 伊人久久大香线| 亚洲欧洲日产国产网站| 一级成人国产| 久久久久久久精| 亚洲区一区二| 欧美一级视频免费在线观看| 久久久久久久91| 欧美日本免费| 国产一区在线免费观看| 久久噜噜亚洲综合| 欧美黄色大片网站| 国产欧美 在线欧美| 亚洲国产你懂的| 欧美在线在线| 亚洲美女福利视频网站| 欧美一区二粉嫩精品国产一线天| 久久婷婷丁香| 国产精品网站在线观看| 亚洲国产欧美在线| 久久精品30| 一本大道久久a久久精二百| 蜜臀av在线播放一区二区三区| 欧美日韩精品| 黄色一区二区在线| 亚洲午夜电影| 亚洲国产精品成人一区二区 | 亚洲欧美国产视频| 欧美777四色影视在线| 亚洲天堂网在线观看| 欧美成人免费全部观看天天性色| 99热免费精品在线观看| 欧美一区二区在线看| 欧美理论视频| 91久久线看在观草草青青| 午夜精品久久久久久99热软件| 亚洲韩国青草视频| 久久深夜福利| 精品69视频一区二区三区| 欧美影院一区| 午夜精品www| 欧美日韩精品欧美日韩精品| 亚洲人午夜精品| 亚洲观看高清完整版在线观看| 久久久国产精品亚洲一区 | 久久亚洲美女| 黄色成人精品网站| 久久嫩草精品久久久精品| 亚洲女爱视频在线| 国产伦精品一区二区三区视频孕妇 | 亚洲成人资源网| 老司机aⅴ在线精品导航| 在线播放日韩欧美| 免费欧美日韩国产三级电影| 久久性色av| 亚洲精选大片| 日韩视频在线观看免费| 国产精品国产三级国产普通话三级| 亚洲视频一二区| 亚洲一区在线视频| 狠狠爱成人网| 欧美激情在线免费观看| 欧美日韩亚洲综合在线| 亚洲影音一区| 欧美一级在线视频| 亚洲人成网在线播放| 一本色道久久99精品综合| 国产美女精品一区二区三区| 美女黄网久久| 欧美区二区三区| 欧美一区在线直播| 久久免费视频在线观看| 日韩视频在线观看一区二区| 亚洲一区二区免费视频| 亚洲无线一线二线三线区别av| 国产精品久久久久久久久久免费 | 亚洲二区视频在线| 欧美日韩999| 久久精品免费| 欧美另类一区| 久久国产精品电影| 久久人人爽人人| 这里是久久伊人| 久久精品国产综合精品| 日韩午夜三级在线| 欧美一区二区视频在线观看2020| 亚洲精品一区二区在线| 亚洲欧美日韩天堂| 亚洲人成在线观看| 亚洲午夜精品| 亚洲精品资源| 久久久久久久999| 性欧美在线看片a免费观看| 美女啪啪无遮挡免费久久网站| 欧美极品一区二区三区| 久久激情综合| 欧美日韩国产另类不卡| 久久青草久久| 国产精品一页| 一区二区三区四区五区精品| 亚洲人成亚洲人成在线观看| 亚洲综合精品四区| 亚洲国产婷婷| 欧美资源在线观看| 国产三区精品| 日韩视频一区二区三区在线播放免费观看 | 老司机67194精品线观看| 欧美日韩精选| 亚洲风情在线资源站| 国产亚洲欧美一级| 亚洲天堂av电影| av成人免费观看| 免费精品视频| 亚洲精品老司机| 欧美一区二区高清在线观看| 亚洲精品日韩在线观看| 久久精品一区中文字幕| 午夜精品久久久久久| 欧美午夜不卡视频| 亚洲精品男同| 亚洲国产欧美一区二区三区久久| 久久九九精品| 欧美成人精品不卡视频在线观看 | 国产精品久久久久一区二区三区共 | 欧美高清视频一区二区三区在线观看| 国产日韩欧美高清免费| 午夜精品久久久久久久久久久久 | 激情一区二区三区| 欧美一区二区三区日韩视频| 久久久国产精品一区二区中文| 国产日产亚洲精品| 欧美专区在线播放| 国产性色一区二区| 欧美在线综合视频| 美国三级日本三级久久99| 在线观看精品视频| 欧美国产在线电影| 亚洲国产欧美在线人成| 最新高清无码专区| 欧美日韩精品免费看| 亚洲免费影视第一页| 久久亚洲高清| 日韩视频三区| 国产精品色午夜在线观看| 欧美一区二区免费观在线| 久久婷婷综合激情| 亚洲日本一区二区| 国产精品久久久久久久久搜平片 | 亚洲免费观看高清完整版在线观看熊| 欧美丰满高潮xxxx喷水动漫| 日韩视频一区二区| 欧美有码视频| 在线免费不卡视频| 欧美日韩亚洲一区二区| 午夜一级久久| 欧美激情一区在线| 午夜精品www| 1000部国产精品成人观看| 欧美日韩国产小视频在线观看| 在线亚洲一区观看| 免费亚洲电影在线观看| 99热精品在线| 黄色精品一二区| 欧美视频在线观看免费网址| 亚洲制服丝袜在线| 欧美福利精品| 欧美在线观看视频一区二区三区| 一区在线观看| 欧美日韩一区二区三区免费| 欧美在线免费| 正在播放亚洲一区| 亚洲高清在线| 久久一区亚洲| 欧美一区二区三区成人| 在线视频一区二区| 91久久精品国产91久久性色| 国产手机视频一区二区| 欧美亚洲成人网| 久久米奇亚洲| 亚洲欧美福利一区二区| 亚洲欧洲精品一区| 久久九九热免费视频| 正在播放欧美视频|