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

歡迎訪問 生活随笔!

生活随笔

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

windows

[6]Windows内核情景分析 --APC

發布時間:2023/12/13 windows 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [6]Windows内核情景分析 --APC 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

APC:異步過程調用。這是一種常見的技術。前面進程啟動的初始過程就是:主線程在內核構造好運行環境后,從KiThreadStartup開始運行,然后調用PspUserThreadStartup,在該線程的apc隊列中插入一個APC:LdrInitializeThunk,這樣,當PspUserThreadStartup返回后,正式退回用戶空間的總入口BaseProcessStartThunk前,會執行中途插入的那個apc,完成進程的用戶空間初始化工作(鏈接dll的加載等)

可見:APC的執行時機之一就是從內核空間返回用戶空間的前夕。也即在返回用戶空間前,會“中斷”那么一下。因此,APC就是一種軟中斷。

除了這種APC用途外,應用程序中也經常使用APC。如Win32?API?ReadFileEx就可以使用APC機制來實現異步讀寫文件的功能。

BOOL???//源碼

ReadFileEx(IN?HANDLE?hFile,

???????????IN?LPVOID?lpBuffer,

???????????IN?DWORD?nNumberOfBytesToRead??OPTIONAL,

???????????IN?LPOVERLAPPED?lpOverlapped,//完成結果

???????????IN?LPOVERLAPPED_COMPLETION_ROUTINE?lpCompletionRoutine)//預置APC將調用的完成例程

{

???LARGE_INTEGER?Offset;

???NTSTATUS?Status;

???Offset.u.LowPart?=?lpOverlapped->Offset;

???Offset.u.HighPart?=?lpOverlapped->OffsetHigh;

???lpOverlapped->Internal?=?STATUS_PENDING;

???Status?=?NtReadFile(hFile,

???????????????????????NULL,?//Event=NULL

???????????????????????ApcRoutine,//這個是內部預置的APC例程

???????????????????????lpCompletionRoutine,//APC的Context

???????????????????????(PIO_STATUS_BLOCK)lpOverlapped,

???????????????????????lpBuffer,

???????????????????????nNumberOfBytesToRead,

???????????????????????&Offset,

???????????????????????NULL);//Key=NULL

???if?(!NT_SUCCESS(Status))

???{

?SetLastErrorByStatus(Status);//

?return?FALSE;

???}

???return?TRUE;

}

?

VOID??ApcRoutine(PVOID?ApcContext,//指向用戶提供的完成例程

_IO_STATUS_BLOCK*?IoStatusBlock,//完成結果

????????????ULONG?Reserved)

{

LPOVERLAPPED_COMPLETION_ROUTINE?lpCompletionRoutine?=?ApcContext;

DWORD?dwErrorCode?=?RtlNtStatusToDosError(IoStatusBlock->Status);

?????//調用用戶提供的完成例程

lpCompletionRoutine(dwErrorCode,

IoStatusBlock->Information,?

(LPOVERLAPPED)IoStatusBlock);

}

?

?

因此,應用層的用戶提供的完成例程實際上是作為APC函數進行的,它運行在APC_LEVEL?irql

?

NTSTATUS

NtReadFile(IN?HANDLE?FileHandle,

???????????IN?HANDLE?Event?OPTIONAL,

???????????IN?PIO_APC_ROUTINE?ApcRoutine?OPTIONAL,//內置的APC

???????????IN?PVOID?ApcContext?OPTIONAL,//應用程序中用戶提供的完成例程

???????????OUT?PIO_STATUS_BLOCK?IoStatusBlock,

???????????OUT?PVOID?Buffer,

???????????IN?ULONG?Length,

???????????IN?PLARGE_INTEGER?ByteOffset?OPTIONAL,

???????????IN?PULONG?Key?OPTIONAL)

{

???…

???Irp?=?IoAllocateIrp(DeviceObject->StackSize,?FALSE);//分配一個irp

???Irp->Overlay.AsynchronousParameters.UserApcRoutine?=?ApcRoutine;//記錄

???Irp->Overlay.AsynchronousParameters.UserApcContext?=?ApcContext;//記錄

???…

???Status?=?IoCallDriver(DeviceObject,?Irp);//把這個構造的irp發給底層驅動

???…

}

?

當底層驅動完成這個irp后,會調用IoCompleteRequest完成掉這個irp,這個IoCompleteRequest實際上內部最終調用IopCompleteRequest來做一些完成時的工作

VOID

IopCompleteRequest(IN?PKAPC?Apc,

???????????????????IN?PKNORMAL_ROUTINE*?NormalRoutine,

???????????????????IN?PVOID*?NormalContext,

???????????????????IN?PVOID*?SystemArgument1,

???????????????????IN?PVOID*?SystemArgument2)

{

???…

???if?(Irp->Overlay.AsynchronousParameters.UserApcRoutine)//上面傳入的APC

???{

??????//構造一個APC

??????KeInitializeApc(&Irp->Tail.Apc,KeGetCurrentThread(),CurrentApcEnvironment,

?????? IopFreeIrpKernelApc,

???????????????????IopAbortIrpKernelApc,

??????????????????(PKNORMAL_ROUTINE)Irp->Overlay.AsynchronousParameters.UserApcRoutine,

??????????????????Irp->RequestorMode,

??????????????????Irp->Overlay.AsynchronousParameters.UserApcContext);//應用層的完成例程

??????//插入到APC隊列

??????KeInsertQueueApc(&Irp->Tail.Apc,?Irp->UserIosb,?NULL,?2);

????}//end?if

???…

}

?

如上,ReadFileEx函數的異步APC機制是:在這個請求完成后,IO管理器會將一個APC插入隊列中,然后

在返回用戶空間前夕調用那個內置APC,最終調用應用層用戶提供的完成例程。

?

明白了APC大致原理后,現在詳細看一下APC的工作原理。

APC分兩種,用戶APC、內核APC。前者指在用戶空間執行的APC,后者指在內核空間執行的APC。

先看一下內核為支持APC機制提供的一些基礎結構設施。

Typedef?struct?_KTHREAD

{

???…

???KAPC_STATE??ApcState;//表示本線程當前使用的APC狀態(即apc隊列的狀態)

???KAPC_STATE??SavedApcState;//表示保存的原apc狀態,備份用

???KAPC_STATE*?ApcStatePointer[2];//狀態數組,包含兩個指向APC狀態的指針

???UCHAR?ApcStateIndex;//0或1,指當前的ApcState在ApcStatePointer數組中的索引位置

???UCHAR?ApcQueueable;//指本線程的APC隊列是否可插入apc

???ULONG?KernelApcDisable;//禁用標志

//專用于掛起操作的APC(這個函數在線程一得到調度就重新進入等待態,等待掛起計數減到0)

???KAPC?SuspendApc;

???…???

}KTHREAD;

?

Typedef?struct?_KAPC_STATE?//APC隊列的狀態描述符

{

???LIST_EBTRY??ApcListHead[2];//每個線程有兩個apc隊列

???PKPROCESS?Process;//當前線程所在的進程

???BOOL?KernelApcInProgress;//指示本線程是否當前正在?內核apc

???BOOL?KernelApcPending;//表示內核apc隊列中是否有apc

???BOOL?UserApcPending;//表示用戶apc隊列中是否apc

}

Typedef?enum?_KAPC_ENVIRONMENT

{

???OriginalApcEnvironment,//0,狀態數組索引

???AttachedApcEnvironment;//1,狀態數組索引

???CurrentApc?Environment;//2,表示使用當前apc狀態

???CurrentApc?Environment;//3,表示使用插入apc時那時的線程的apc狀態

}

?

一個線程可以掛靠到其他進程的地址空間中,因此,一個線程的狀態分兩種:常態、掛靠態。

常態下,狀態數組中0號元素指向ApcState(即當前apc狀態),1號元素指向SavedApcState(非當前apc狀態);掛靠態下,兩個元素的指向剛好相反。但無論如何,KTHREAD結構中的ApcStateIndex總是指當前狀態的位置,ApcState則總是表示線程當前使用的apc狀態。

于是有:

#define?PsGetCurrentProcess??IoGetCurrentProces

PEPROCESS??IoGetCurrentProces()

{

???Return?PsGetCurrentThread()->Tcb.ApcState.Process;//ApcState中的進程字段總是表示當前進程

}

不管當前線程是處于常態還是掛靠態下,它都有兩個apc隊列,一個內核,一個用戶。把apc插入對應的隊列后就可以在恰當的時機得到執行。注意:每當一個線程掛靠到其他進程時,掛靠初期,兩個apc隊列都會變空。下面看下每個apc本身的結構

typedef?struct?_KAPC

{

??UCHAR?Type;//結構體的類型

??UCHAR?Size;//結構體的大小

??struct?_KTHREAD?*Thread;//目標線程

??LIST_ENTRY?ApcListEntry;//用來掛入目標apc隊列

??PKKERNEL_ROUTINE?KernelRoutine;//該apc的內核總入口

??PKRUNDOWN_ROUTINE?RundownRoutine;

??PKNORMAL_ROUTINE?NormalRoutine;//該apc的用戶空間總入口或者用戶真正的內核apc函數

??PVOID?NormalContext;//真正用戶提供的用戶空間apc函數或者用戶真正的內核apc函數的context*

??PVOID?SystemArgument1;//掛入時的附加參數1。真正用戶apc的context*

??PVOID?SystemArgument2;//掛入時的附加參數2

??CCHAR?ApcStateIndex;//指要掛入目標線程的哪個狀態時的apc隊列

??KPROCESSOR_MODE?ApcMode;//指要掛入用戶apc隊列還是內核apc隊列

??BOOLEAN?Inserted;//表示本apc是否已掛入隊列

}?KAPC,?*PKAPC;

注意:

若這個apc是內核apc,那么NormalRoutine表示用戶自己提供的內核apc函數,NormalContext則是該apc函數的context*,SystemArgument1與SystemArgument2表示插入隊列時的附加參數

若這個apc是用戶apc,那么NormalRoutine表示該apc的用戶空間總apc函數,NormalContext才是真正用戶自己提供的用戶空間apc函數,SystemArgument1則表示該真正apc的context*。(一切錯位了)

?

?

//下面這個Win32?API可以用來手動插入一個apc到指定線程的用戶apc隊列中

DWORD?

QueueUserAPC(PAPCFUNC?pfnAPC,?HANDLE?hThread,?ULONG_PTR?dwData)

{

??NTSTATUS?Status;

??//調用對應的系統服務

??Status?=?NtQueueApcThread(hThread,//目標線程

?IntCallUserApc,//用戶空間中的總apc入口

?pfnAPC,//用戶自己真正提供的apc函數

(PVOID)dwData,//SysArg1=context*

?NULL);//SysArg2=NULL

??if?(!NT_SUCCESS(Status))

??{

????SetLastErrorByStatus(Status);

????return?0;

??}

??return?1;

}

?

NTSTATUS

NtQueueApcThread(IN?HANDLE?ThreadHandle,//目標線程

?????????????????IN?PKNORMAL_ROUTINE?ApcRoutine,//用戶空間中的總apc

?????????????????IN?PVOID?NormalContext,//用戶自己真正的apc函數

?????????????????IN?PVOID?SystemArgument1,//用戶自己apc的context*

?????????????????IN?PVOID?SystemArgument2)//其它

{

????PKAPC?Apc;

????PETHREAD?Thread;

????NTSTATUS?Status?=?STATUS_SUCCESS;

????Status?=?ObReferenceObjectByHandle(ThreadHandle,THREAD_SET_CONTEXT,PsThreadType,

???????????????????????????????????????ExGetPreviousMode(),?(PVOID)&Thread,NULL);

????//分配一個apc結構,這個結構最終在PspQueueApcSpecialApc中釋放

????Apc?=?ExAllocatePoolWithTag(NonPagedPool?|POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,

????????????????????????????????sizeof(KAPC),TAG_PS_APC);

????//構造一個apc

????KeInitializeApc(Apc,

????????????????????&Thread->Tcb,//目標線程

????????????????????OriginalApcEnvironment,//目標apc狀態(此服務固定為OriginalApcEnvironment)

????????????????????PspQueueApcSpecialApc,//內核apc總入口

????????????????????NULL,//Rundown?Rounine=NULL

????????????????????ApcRoutine,//用戶空間的總apc

????????????????????UserMode,//此系統服務固定插入到用戶apc隊列

????????????????????NormalContext);//用戶自己真正的apc函數

????//插入到目標線程的用戶apc隊列

????KeInsertQueueApc(Apc,

?????????????????????SystemArgument1,//插入時的附加參數1,此處為用戶自己apc的context*

?????????????????????SystemArgument2,?//插入時的附加參數2

?????????????????????IO_NO_INCREMENT)//表示不予調整目標線程的調度優先級

????return?Status;

}

?

//這個函數用來構造一個要插入指定目標隊列的apc對象

VOID

KeInitializeApc(IN?PKAPC?Apc,

????????????????IN?PKTHREAD?Thread,//目標線程

????????????????IN?KAPC_ENVIRONMENT?TargetEnvironment,//目標線程的目標apc狀態

????????????????IN?PKKERNEL_ROUTINE?KernelRoutine,//內核apc總入口

????????????????IN?PKRUNDOWN_ROUTINE?RundownRoutine?OPTIONAL,

????????????????IN?PKNORMAL_ROUTINE?NormalRoutine,//用戶空間的總apc

????????????????IN?KPROCESSOR_MODE?Mode,//要插入用戶apc隊列還是內核apc隊列

????????????????IN?PVOID?Context)?//用戶自己真正的apc函數

{

????Apc->Type?=?ApcObject;

????Apc->Size?=?sizeof(KAPC);

????if?(TargetEnvironment?==?CurrentApcEnvironment)//CurrentApcEnvironment表示使用當前apc狀態

????????Apc->ApcStateIndex?=?Thread->ApcStateIndex;

????else

????????Apc->ApcStateIndex?=?TargetEnvironment;

????Apc->Thread?=?Thread;

????Apc->KernelRoutine?=?KernelRoutine;

????Apc->RundownRoutine?=?RundownRoutine;

????Apc->NormalRoutine?=?NormalRoutine;

????if?(NormalRoutine)//if?提供了用戶空間總apc入口

????{

????????Apc->ApcMode?=?Mode;

????????Apc->NormalContext?=?Context;

????}

????Else//若沒提供,肯定是內核模式

????{

????????Apc->ApcMode?=?KernelMode;

????????Apc->NormalContext?=?NULL;

????}

????Apc->Inserted?=?FALSE;//表示初始構造后,尚未掛入apc隊列

}

?

BOOLEAN

KeInsertQueueApc(IN?PKAPC?Apc,IN?PVOID?SystemArgument1,IN?PVOID?SystemArgument2,

?????????????????IN?KPRIORITY?PriorityBoost)

{

????PKTHREAD?Thread?=?Apc->Thread;

????KLOCK_QUEUE_HANDLE?ApcLock;

????BOOLEAN?State?=?TRUE;

????KiAcquireApcLock(Thread,?&ApcLock);//插入過程需要獨占隊列

????if?(!(Thread->ApcQueueable)?||?(Apc->Inserted))//檢查隊列是否可以插入apc

????????State?=?FALSE;

????else

????{

????????Apc->SystemArgument1?=?SystemArgument1;//記錄該apc的附加插入時的參數

????????Apc->SystemArgument2?=?SystemArgument2;?//記錄該apc的附加插入時的參數

????????Apc->Inserted?=?TRUE;//標記為已插入隊列

???//插入目標線程的目標apc隊列(如果目標線程正處于睡眠狀態,可能會喚醒它)

????????KiInsertQueueApc(Apc,?PriorityBoost);?

????}

????KiReleaseApcLockFromDpcLevel(&ApcLock);

????KiExitDispatcher(ApcLock.OldIrql);//可能引發一次線程切換,以立即切換到目標線程執行apc

????return?State;

}

?

VOID?FASTCALL

KiInsertQueueApc(IN?PKAPC?Apc,IN?KPRIORITY?PriorityBoost)//喚醒目標線程后的優先級增量

{

????PKTHREAD?Thread?=?Apc->Thread;

????BOOLEAN?RequestInterrupt?=?FALSE;

????if?(Apc->ApcStateIndex?==?InsertApcEnvironment)?//if要動態插入到當前的apc狀態隊列

????????Apc->ApcStateIndex?=?Thread->ApcStateIndex;?

????ApcState?=?Thread->ApcStatePointer[(UCHAR)Apc->ApcStateIndex];//目標狀態

ApcMode?=?Apc->ApcMode;

//先插入apc到指定位置

????/*?插入位置的確定:分三種情形

?????*?1)?Kernel?APC?with?Normal?Routine?or?User?APC?:?Put?it?at?the?end?of?the?List

?????*?2)?User?APC?which?is?PsExitSpecialApc?:?Put?it?at?the?front?of?the?List

?????*?3)?Kernel?APC?without?Normal?Routine?:?Put?it?at?the?end?of?the?No-Normal?Routine?Kernel?APC?list

????*/

????if?(Apc->NormalRoutine)//有NormalRoutine的APC都插入尾部(用戶模式發來的線程終止APC除外)

????{

????????if?((ApcMode?==?UserMode)?&&?(Apc->KernelRoutine?==?PsExitSpecialApc))

????????{

????????????Thread->ApcState.UserApcPending?=?TRUE;

????????????InsertHeadList(&ApcState->ApcListHead[ApcMode],&Apc->ApcListEntry);

????????}

????????else

????????????InsertTailList(&ApcState->ApcListHead[ApcMode],&Apc->ApcListEntry);

????}

????Else?//無NormalRoutine的特殊類APC(內核APC),少見

????{

????????ListHead?=?&ApcState->ApcListHead[ApcMode];

????????NextEntry?=?ListHead->Blink;

????????while?(NextEntry?!=?ListHead)

????????{

????????????QueuedApc?=?CONTAINING_RECORD(NextEntry,?KAPC,?ApcListEntry);

????????????if?(!QueuedApc->NormalRoutine)?break;

????????????NextEntry?=?NextEntry->Blink;

????????}

????????InsertHeadList(NextEntry,?&Apc->ApcListEntry);//插在這兒

????}

?

????//插入到相應的位置后,下面檢查Apc狀態是否匹配

????if?(Thread->ApcStateIndex?==?Apc->ApcStateIndex)//if?插到了當前apc狀態的apc隊列中

????{

????????if?(Thread?==?KeGetCurrentThread())//if就是給當前線程發送的apc

????????{

????????????ASSERT(Thread->State?==?Running);//當前線程肯定沒有睡眠,這不廢話嗎?

????????????if?(ApcMode?==?KernelMode)

????????????{

????????????????Thread->ApcState.KernelApcPending?=?TRUE;

????????????????if?(!Thread->SpecialApcDisable)//發出一個apc中斷,待下次降低irql時將執行apc

????????????????????HalRequestSoftwareInterrupt(APC_LEVEL);?//關鍵

????????????}

????????}

????????Else?//給其他線程發送的內核apc

????????{

????????????KiAcquireDispatcherLock();

????????????if?(ApcMode?==?KernelMode)

????????????{

????????????????Thread->ApcState.KernelApcPending?=?TRUE;

????????????????if?(Thread->State?==?Running)

????????????????????RequestInterrupt?=?TRUE;//需要給它發出一個apc中斷

????????????????else?if?((Thread->State?==?Waiting)?&&?(Thread->WaitIrql?==?PASSIVE_LEVEL)?&&

?????????????????????????!(Thread->SpecialApcDisable)?&&?(!(Apc->NormalRoutine)?||

?????????????????????????(!(Thread->KernelApcDisable)?&&

?????????????????????????!(Thread->ApcState.KernelApcInProgress))))

????????????????{

????????????????????Status?=?STATUS_KERNEL_APC;

????????????????????KiUnwaitThread(Thread,?Status,?PriorityBoost);//臨時喚醒目標線程執行apc

????????????????}

????????????????else?if?(Thread->State?==?GateWait)?…

????????????}

????????????else?if?((Thread->State?==?Waiting)?&&?(Thread->WaitMode?==?UserMode)?&&

?????????????????????((Thread->Alertable)?||?(Thread->ApcState.UserApcPending)))

????????????{

????????????????Thread->ApcState.UserApcPending?=?TRUE;

????????????????Status?=?STATUS_USER_APC;

????????????????KiUnwaitThread(Thread,?Status,?PriorityBoost);//強制喚醒目標線程

????????????}

????????????KiReleaseDispatcherLockFromDpcLevel();

????????????KiRequestApcInterrupt(RequestInterrupt,?Thread->NextProcessor);

????????}

????}

}

如上,這個函數既可以給當前線程發送apc,也可以給目標線程發送apc。若給當前線程發送內核apc時,會立即請求發出一個apc中斷。若給其他線程發送apc時,可能會喚醒目標線程。

?

APC函數的執行時機:

回顧一下從內核返回用戶時的流程:

KiSystemService()//int?2e的isr,內核服務函數總入口,注意這個函數可以嵌套、遞歸!!!

{

?????SaveTrap();//保存trap現場

Sti??//開中斷

---------------上面保存完寄存器等現場后,開始查SST表調用系統服務------------------

FindTableCall();

---------------------------------調用完系統服務函數后------------------------------

Move??esp,kthread.TrapFrame;?//將棧頂回到trap幀結構體處

Cli??//關中斷

If(上次模式==UserMode)

{

Call??KiDeliverApc?//遍歷執行本線程的內核APC和用戶APC隊列中的所有APC函數

清理Trap幀,恢復寄存器現場

Iret???//返回用戶空間

}

Else

{

???返回到原call處后面的那條指令處

}

}

不光是從系統調用返回用戶空間要掃描執行apc,從異常和中斷返回用戶空間也同樣需要掃描執行。

現在我們只看從系統調用返回時apc的執行過程。

上面是偽代碼,實際的從Cli后面的代碼,是下面這樣的。

Test?dword?ptr[ebp+KTRAP_FRAME_EFLAGS],?EFLAGS_V86_MASK???//檢查eflags是否標志運行在V86模式

Jnz?1??//若運行在V86模式,那么上次模式肯定是從用戶空間進入內核的,跳過下面的檢查

Test?byte?ptr[ebp+KTRAP_FRAME_CS],1

Je?2?//若上次模式不是用戶模式,跳過下面的流程,不予掃描apc

1:

Mov?ebx,PCR[KPCR_CURRENT_THREAD]??//ebx=KTHREAD*(當前線程對象的地址)

Mov?byte?ptr[ebx+KTHREAD_ALERTED],0?//kthread.Alert修改為不可提醒

Cmp?byte?ptr[ebx+KTHREAD_PENDING_USER_APC],0

Je?2?//如果當前線程的用戶apc隊列為空,直接跳過

Mov?ebx,ebp?//ebx=TrapFrame幀的地址

Mov?[ebx,KTRAP_FRAME_EAX],eax?//保存

Mov?ecx,APC_LEVEL

Call?KfRaiseIrql??//call?KfRaiseIrql(APC_LEVEL)

Push?eax?//保存提升irql之前的irql

Sti

Push?ebx?//TrapFrame幀的地址

Push?NULL

Push?UserMode

Call?KiDeliverApc???//call?KiDeliverApc(UserMode,?NULL,?TrapFrame*)?

Pop?ecx?//?ecx=之前的irql

Call?KfLowerIrql??//call?KfLowerIrql(之前的irql)

Move?eax,?[ebx,KTRAP_FRAME_EAX]?//恢復eax

Cli

Jmp?1?//再次跳回1處循環,掃描apc隊列

?

關鍵的函數是KiDeliverApc,這個函數用來真正掃描apc隊列執行所有apc,我們看:

VOID

KiDeliverApc(IN?KPROCESSOR_MODE?DeliveryMode,//指要執行哪個apc隊列中的函數

?????????????IN?PKEXCEPTION_FRAME?ExceptionFrame,//傳入的是NULL

?????????????IN?PKTRAP_FRAME?TrapFrame)//即將返回用戶空間前的Trap現場幀

{

????PKTHREAD?Thread?=?KeGetCurrentThread();

????PKPROCESS?Process?=?Thread->ApcState.Process;

????OldTrapFrame?=?Thread->TrapFrame;

????Thread->TrapFrame?=?TrapFrame;

????Thread->ApcState.KernelApcPending?=?FALSE;

if?(Thread->SpecialApcDisable)?goto?Quickie;

//先固定執行掉內核apc隊列中的所有apc函數

????while?(!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))

????{

????????KiAcquireApcLockAtApcLevel(Thread,?&ApcLock);//鎖定apc隊列

????????ApcListEntry?=?Thread->ApcState.ApcListHead[KernelMode].Flink;//隊列頭部中的apc

????????Apc?=?CONTAINING_RECORD(ApcListEntry,?KAPC,?ApcListEntry);

????????KernelRoutine?=?Apc->KernelRoutine;//內核總apc函數

????????NormalRoutine?=?Apc->NormalRoutine;//用戶自己真正的內核apc函數

????????NormalContext?=?Apc->NormalContext;//真正內核apc函數的context*

????????SystemArgument1?=?Apc->SystemArgument1;

????????SystemArgument2?=?Apc->SystemArgument2;

????????if?(NormalRoutine==NULL)?//稱為Special?Apc,少見

????????{

????????????RemoveEntryList(ApcListEntry);//關鍵,移除隊列

????????????Apc->Inserted?=?FALSE;

????????????KiReleaseApcLock(&ApcLock);

????????????//執行內核中的總apc函數

????????????KernelRoutine(Apc,&NormalRoutine,&NormalContext,

??????????????????????????&SystemArgument1,&SystemArgument2);

????????}

????????Else?//典型,一般程序員都會提供一個自己的內核apc函數

????????{

????????????if?((Thread->ApcState.KernelApcInProgress)?||?(Thread->KernelApcDisable))

????????????{

????????????????KiReleaseApcLock(&ApcLock);

????????????????goto?Quickie;

????????????}

????????????RemoveEntryList(ApcListEntry);?//關鍵,移除隊列

????????????Apc->Inserted?=?FALSE;

????????????KiReleaseApcLock(&ApcLock);

//執行內核中的總apc函數

????????????KernelRoutine(Apc,

??????????????????????????&NormalRoutine,//注意,內核中的總apc可能會在內部修改NormalRoutine

??????????????????????????&NormalContext,

??????????????????????????&SystemArgument1,

??????????????????????????&SystemArgument2);

????????????if?(NormalRoutine)//如果內核總apc沒有修改NormalRoutine成NULL

????????????{

????????????????Thread->ApcState.KernelApcInProgress?=?TRUE;//標記當前線程正在執行內核apc

????????????????KeLowerIrql(PASSIVE_LEVEL);

????????????????//直接調用用戶提供的真正內核apc函數

????????????????NormalRoutine(NormalContext,?SystemArgument1,?SystemArgument2);

????????????????KeRaiseIrql(APC_LEVEL,?&ApcLock.OldIrql);

????????????}

????????????Thread->ApcState.KernelApcInProgress?=?FALSE;

????????}

????}

????//上面的循環,執行掉所有內核apc函數后,下面開始執行用戶apc隊列中的第一個apc

????if?((DeliveryMode?==?UserMode)?&&

?????????!(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))?&&

?????????(Thread->ApcState.UserApcPending))

????{

????????KiAcquireApcLockAtApcLevel(Thread,?&ApcLock);//鎖定apc隊列

????????Thread->ApcState.UserApcPending?=?FALSE;

?

????????ApcListEntry?=?Thread->ApcState.ApcListHead[UserMode].Flink;//隊列頭

????????Apc?=?CONTAINING_RECORD(ApcListEntry,?KAPC,?ApcListEntry);

????????KernelRoutine?=?Apc->KernelRoutine;?//內核總apc函數

????????NormalRoutine?=?Apc->NormalRoutine;?//用戶空間的總apc函數

????????NormalContext?=?Apc->NormalContext;//用戶真正的用戶空間apc函數

????????SystemArgument1?=?Apc->SystemArgument1;//真正apc的context*

????????SystemArgument2?=?Apc->SystemArgument2;

????????RemoveEntryList(ApcListEntry);//關鍵,移除隊列

????????Apc->Inserted?=?FALSE;

????????KiReleaseApcLock(&ApcLock);

????????KernelRoutine(Apc,

??????????????????????&NormalRoutine,//?注意,內核中的總apc可能會在內部修改NormalRoutine

??????????????????????&NormalContext,

??????????????????????&SystemArgument1,

??????????????????????&SystemArgument2);

????????if?(!NormalRoutine)

????????????KeTestAlertThread(UserMode);

????????Else?//典型,準備提前回到用戶空間調用用戶空間的總apc函數

????????{

????????????KiInitializeUserApc(ExceptionFrame,//NULL

????????????????????????????????TrapFrame,//Trap幀的地址

????????????????????????????????NormalRoutine,?//用戶空間的總apc函數

????????????????????????????????NormalContext,?//用戶真正的用戶空間apc函數

????????????????????????????????SystemArgument1,?//真正apc的context*

????????????????????????????????SystemArgument2);

????????}

????}

Quickie:

????Thread->TrapFrame?=?OldTrapFrame;

}

如上,這個函數既可以用來投遞處理內核apc函數,也可以用來投遞處理用戶apc隊列中的函數。

特別的,當要調用這個函數投遞處理用戶apc隊列中的函數時,它每次只處理一個用戶apc。

由于正式回到用戶空間前,會循環調用這個函數。因此,實際的處理順序是:

掃描執行內核apc隊列所有apc->執行用戶apc隊列中一個apc->再次掃描執行內核apc隊列所有apc->執行用戶apc隊列中下一個apc->再次掃描執行內核apc隊列所有apc->再次執行用戶apc隊列中下一個apc如此循環,直到將用戶apc隊列中的所有apc都執行掉。

執行用戶apc隊列中的apc函數與內核apc不同,因為用戶apc隊列中的apc函數自然是要在用戶空間中執行的,而KiDeliverApc這個函數本身位于內核空間,因此,不能直接調用用戶apc函數,需要‘提前’回到用戶空間去執行隊列中的每個用戶apc,然后重新返回內核,再次掃描整個內核apc隊列,再執行用戶apc隊列中遺留的下一個用戶apc。如此循環,直至執行完所有用戶apc后,才‘正式’返回用戶空間。

?

?

?

?

下面的函數就是用來為執行用戶apc做準備的。

VOID

KiInitializeUserApc(IN?PKEXCEPTION_FRAME?ExceptionFrame,

????????????????????IN?PKTRAP_FRAME?TrapFrame,//原真正的斷點現場幀

????????????????????IN?PKNORMAL_ROUTINE?NormalRoutine,

????????????????????IN?PVOID?NormalContext,

????????????????????IN?PVOID?SystemArgument1,

????????????????????IN?PVOID?SystemArgument2)

{

Context.ContextFlags?=?CONTEXT_FULL?|?CONTEXT_DEBUG_REGISTERS;

//將原真正的Trap幀打包保存在一個Context結構中

????KeTrapFrameToContext(TrapFrame,?ExceptionFrame,?&Context);

????_SEH2_TRY

????{

????????AlignedEsp?=?Context.Esp?&?~3;//對齊4B

//為用戶空間中KiUserApcDisatcher函數的參數騰出空間(4個參數+?CONTEXT?+?8B的seh節點)

????????ContextLength?=?CONTEXT_ALIGNED_SIZE?+?(4?*?sizeof(ULONG_PTR));

????????Stack?=?((AlignedEsp?-?8)?&?~3)?-?ContextLength;//8表示seh節點的大小

????????//模擬壓入KiUserApcDispatcher函數的4個參數

????????*(PULONG_PTR)(Stack?+?0?*?sizeof(ULONG_PTR))?=?(ULONG_PTR)NormalRoutine;

????????*(PULONG_PTR)(Stack?+?1?*?sizeof(ULONG_PTR))?=?(ULONG_PTR)NormalContext;

????????*(PULONG_PTR)(Stack?+?2?*?sizeof(ULONG_PTR))?=?(ULONG_PTR)SystemArgument1;

????????*(PULONG_PTR)(Stack?+?3?*?sizeof(ULONG_PTR))?=?(ULONG_PTR)SystemArgument2;

????????//將原真正trap幀保存在用戶棧的一個CONTEXT結構中,方便以后還原

????????RtlCopyMemory(?(Stack?+?(4?*?sizeof(ULONG_PTR))),&Context,sizeof(CONTEXT));

?

????????//強制修改當前Trap幀中的返回地址與用戶棧地址(偏離原來的返回路線)

????????TrapFrame->Eip?=?(ULONG)KeUserApcDispatcher;//關鍵,新的返回斷點地址

????????TrapFrame->HardwareEsp?=?Stack;//關鍵,新的用戶棧頂

????????TrapFrame->SegCs?=?Ke386SanitizeSeg(KGDT_R3_CODE,?UserMode);

????????TrapFrame->HardwareSegSs?=?Ke386SanitizeSeg(KGDT_R3_DATA,?UserMode);

????????TrapFrame->SegDs?=?Ke386SanitizeSeg(KGDT_R3_DATA,?UserMode);

????????TrapFrame->SegEs?=?Ke386SanitizeSeg(KGDT_R3_DATA,?UserMode);

????????TrapFrame->SegFs?=?Ke386SanitizeSeg(KGDT_R3_TEB,?UserMode);

????????TrapFrame->SegGs?=?0;

????????TrapFrame->ErrCode?=?0;

????????TrapFrame->EFlags?=?Ke386SanitizeFlags(Context.EFlags,?UserMode);

????????if?(KeGetCurrentThread()->Iopl)?TrapFrame->EFlags?|=?EFLAGS_IOPL;

????}

????_SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord,?_SEH2_GetExceptionInformation()->ExceptionRecord,?sizeof(EXCEPTION_RECORD)),????EXCEPTION_EXECUTE_HANDLER))

????{

????????SehExceptRecord.ExceptionAddress?=?(PVOID)TrapFrame->Eip;

????????KiDispatchException(&SehExceptRecord,ExceptionFrame,TrapFrame,UserMode,TRUE);

????}

????_SEH2_END;

}

至于為什么要放在一個try塊中保護,是因為用戶空間中的棧地址,誰也無法保證會不會出現崩潰。

如上,這個函數修改返回地址,回到用戶空間中的KiUserApcDisatcher函數處去。然后把原trap幀保存在用戶棧中。由于KiUserApcDisatcher這個函數有參數,所以需要模擬壓入這個函數的參數,這樣,當返回到用戶空間時,就仿佛是在調用這個函數。看下那個函數的代碼:

KiUserApcDisatcher(NormalRoutine,

???????????????????NormalContext,

???????????????????SysArg1,

???????????????????SysArg2

)

{

???Lea?eax,[esp+?CONTEXT_ALIGNED_SIZE+16]???//eax指向seh異常節點的地址

???Mov?ecx,fs:[TEB_EXCEPTION_LIST]

???Mov?edx,offset?KiUserApcExceptionHandler

???--------------------------------------------------------------------------------------

???Mov?[eax],ecx?//seh節點的next指針成員

???Mov?[eax+4],edx?//she節點的handler函數指針成員

???Mov?fs:[TEB_EXCEPTION_LIST],eax

???--------------------上面三條指令在棧中構造一個8B的標準seh節點-----------------------

???Pop?eax?//eax=NormalRoutine(即IntCallUserApc這個總apc函數)

???Lea?edi,[esp+12]?//edi=棧中保存的CONTEXT結構的地址

???Call?eax?//相當于call?IntCallUserApc(NormalContext,SysArg1,SysArg2)

???

???Mov?ecx,[edi+?CONTEXT_ALIGNED_SIZE]

???Mov?fs:[?TEB_EXCEPTION_LIST],ecx???//撤銷棧中的seh節點

?

???Push?TRUE??//表示回到內核后需要繼續檢測執行用戶apc隊列中的apc函數

???Push?edi??//傳入原棧幀的CONTEXT結構的地址給這個函數,以做恢復工作

???Call?NtContinue???//調用這個函數重新進入內核(注意這個函數正常情況下是不會返回到下面的)

???----------------------------------華麗的分割線-------------------------------------------

???Mov?esi,eax

???Push?esi

???Call?RtlRaiseStatus??//若ZwContinue返回了,那一定是內部出現了異常

???Jmp?StatusRaiseApc

???Ret?16

}

如上,每當要執行一個用戶空間apc時,都會‘提前’偏離原來的路線返回用戶空間的這個函數處去執行用戶的apc。在執行這個函數前,會先構造一個seh節點,也即相當于把這個函數的調用放在try塊中保護。這個函數內部會調用IntCallUserApc,執行完真正的用戶apc函數后,調用ZwContinue重返內核。?

?

?

Void?CALLBACK??//用戶空間的總apc函數

IntCallUserApc(void*?RealApcFunc,?void*?SysArg1,void*?SysArg2)

{

???(*RealApcFunc)(SysArg1);//也即調用RealApcFunc(void*?context)

}

NTSTATUS?NtContinue(CONTEXT*?Context,?//原真正的TraFrame?

????????????????????BOOL?TestAlert??//指示是否繼續執行用戶apc隊列中的apc函數

)

{

???Push?ebp??//此時ebp=本系統服務自身的TrapFrame地址

???Mov?ebx,PCR[KPCR_CURRENT_THREAD]?//ebx=當前線程的KTHREAD對象地址

???Mov?edx,[ebp+KTRAP_FRAME_EDX]?//注意TrapFrame中的這個edx字段不是用來保存edx的

???Mov?[ebx+KTHREAD_TRAP_FRAME],edx?//將當前的TrapFrame改為上一個TrapFrame的地址

???Mov?ebp,esp

???Mob?eax,[ebp]?//eax=本系統服務自身的TrapFrame地址

???Mov?ecx,[ebp+8]?/本函數的第一個參數,即Context

???Push?eax

???Push?NULL

???Push?ecx

???Call?KiContinue??//call?KiContinue(Context*,NULL,TrapFrame*)

???Or?eax,eax

???Jnz?error

???Cmp?dword?ptr[ebp+12],0?//檢查TestAlert參數的值

???Je?DontTest

???Mov?al,[ebx+KTHREAD_PREVIOUS_MODE]

???Push?eax

???Call?KeTestAlertThread??//檢測用戶apc隊列是否為空

???DontTest:

???Pop?ebp

???Mov?esp,ebp

???Jmp?KiServiceExit2?//返回用戶空間(返回前,又會去掃描執行apc隊列中的下一個用戶apc)

}

?

?

NTSTATUS

KiContinue(IN?PCONTEXT?Context,//原來的斷點現場

???????????IN?PKEXCEPTION_FRAME?ExceptionFrame,

???????????IN?PKTRAP_FRAME?TrapFrame)?//NtContinue自身的TrapFrame地址

{

????NTSTATUS?Status?=?STATUS_SUCCESS;

????KIRQL?OldIrql?=?APC_LEVEL;

????KPROCESSOR_MODE?PreviousMode?=?KeGetPreviousMode();

if?(KeGetCurrentIrql()?<?APC_LEVEL)?

KeRaiseIrql(APC_LEVEL,?&OldIrql);

????_SEH2_TRY

????{

????????if?(PreviousMode?!=?KernelMode)

????????????KiContinuePreviousModeUser(Context,ExceptionFrame,TrapFrame);//恢復成原TrapFrame

????????else

????????{

????????????KeContextToTrapFrame(Context,ExceptionFrame,TrapFrame,Context->ContextFlags,

?????????????????????????????????KernelMode);?//恢復成原TrapFrame

????????}

????}

????_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

????{

????????Status?=?_SEH2_GetExceptionCode();

????}

????_SEH2_END;

if?(OldIrql?<?APC_LEVEL)

?KeLowerIrql(OldIrql);

????return?Status;

}

?

VOID

KiContinuePreviousModeUser(IN?PCONTEXT?Context,//原來的斷點現場

???????????????????????????IN?PKEXCEPTION_FRAME?ExceptionFrame,

???????????????????????????IN?PKTRAP_FRAME?TrapFrame)//NtContinue自身的TrapFrame地址

{

????CONTEXT?LocalContext;

????ProbeForRead(Context,?sizeof(CONTEXT),?sizeof(ULONG));

????RtlCopyMemory(&LocalContext,?Context,?sizeof(CONTEXT));

Context?=?&LocalContext;

//看到沒,將原Context中的成員填寫到NtContinue系統服務的TrapFrame幀中(也即修改成原來的TrapFrame)

????KeContextToTrapFrame(&LocalContext,ExceptionFrame,TrapFrame,

?????????????????????????LocalContext.ContextFlags,UserMode);

}

?

如上,上面的函數,就把NtContinue的TrapFrame強制還原成原來的TrapFrame,以好‘正式’返回到用戶空間的真正斷點處(不過在返回用戶空間前,又要去掃描用戶apc隊列,若仍有用戶apc函數,就先執行掉內核apc隊列中的所有apc函數,然后又偏離原來的返回路線,‘提前’返回到用戶空間的KiUserApcDispatcher函數去執行用戶apc,這是一個不斷循環的過程。可見,NtContinue這個函數不僅含有繼續回到原真正用戶空間斷點處的意思,還含有繼續執行用戶apc隊列中下一個apc函數的意思)

?

BOOLEAN??KeTestAlertThread(IN?KPROCESSOR_MODE?AlertMode)

{

????PKTHREAD?Thread?=?KeGetCurrentThread();

????KiAcquireApcLock(Thread,?&ApcLock);

????OldState?=?Thread->Alerted[AlertMode];

????if?(OldState)

????????Thread->Alerted[AlertMode]?=?FALSE;

????else?if?((AlertMode?!=?KernelMode)?&&

?(!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))

????{

????????Thread->ApcState.UserApcPending?=?TRUE;//關鍵。又標記為不空,從而又去執行用戶apc

????}

????KiReleaseApcLock(&ApcLock);

????return?OldState;

}

上面這個函數的關鍵工作是檢測到用戶apc隊列不為空,就又將UserApcPending標志置于TRUE。

?

?

?

前面我們看到的是用戶apc隊列的執行機制與時機,那是用戶apc唯一的執行時機。內核apc隊列中的apc執行時機是不相同的,而且有很多執行時機。

內核apc的執行時機主要有:

1、?每次返回用戶空間前,每執行一個用戶apc前,就會掃描執行整個內核apc隊列

2、?每當調用KeLowerIrql,從APC_LEVEL以上(不包括APC_LEVEL)?降到?APC_LEVEL以下(不包括APC_LEVEL)前,中途會檢查是否有阻塞的apc中斷請求,若有就掃描執行內核apc隊列

3、?每當線程重新得到調度,開始運行前,會掃描執行內核apc隊列?或者?發出apc中斷請求

內核apc的執行時機:【調度、返、降】apc

?

?

KeLowerIrql實質上是下面的函數:

VOID?FASTCALL

KfLowerIrql(IN?KIRQL?OldIrql)

{

????ULONG?EFlags;

????ULONG?PendingIrql,?PendingIrqlMask;

????PKPCR?Pcr?=?KeGetPcr();

????PIC_MASK?Mask;

????EFlags?=?__readeflags();//保存原eflags

????_disable();//關中斷

Pcr->Irql?=?OldIrql;//降到目標irql

//檢測是否有高于目標irql的阻塞中的軟中斷

????PendingIrqlMask?=?Pcr->IRR?&?FindHigherIrqlMask[OldIrql];

????if?(PendingIrqlMask)//若有

????{

????????BitScanReverse(&PendingIrql,?PendingIrqlMask);//找到最高級別的軟中斷

????????if?(PendingIrql?>?DISPATCH_LEVEL)

????????{

????????????Mask.Both?=?Pcr->IDR;

????????????__outbyte(PIC1_DATA_PORT,?Mask.Master);

????????????__outbyte(PIC2_DATA_PORT,?Mask.Slave);

????????????Pcr->IRR?^=?(1?<<?PendingIrql);

????????}

????????SWInterruptHandlerTable[PendingIrql]();//處理阻塞的軟中斷(即掃描執行隊列中的函數)

????}

????__writeeflags(EFlags);//恢復原eflags

}

?

這個函數在從當前irql降到目標irql時,會按irql高低順序執行各個軟中斷的isr。

軟中斷是用來模擬硬件中斷的一種中斷。

#define?PASSIVE_LEVEL???????????0

#define?APC_LEVEL???????????????1

#define?DISPATCH_LEVEL??????????2

#define?CMCI_LEVEL??????????????5

比如,當調用KfLowerIrql要將cpu的irql從CMCI_LEVEL降低到PASSIVE_LEVEL時,這個函數中途會先看看當前cpu是否收到了CMCI_LEVEL級的軟中斷,若有,就調用那個軟中斷的isr處理之。然后,再檢查是否收到有DISPATCH_LEVEL級的軟中斷,若有,調用那個軟中斷的isr處理之,然后,檢查是否有APC中斷,若有,同樣處理之。最后,降到目標irql,即PASSIVE_LEVEL。

換句話說,在irql的降低過程中會一路檢查、處理中途的軟中斷。Cpu數據結構中有一個IRR字段,即表示當前cpu累積收到了哪些級別的軟中斷。

?

?

下面的函數可用于模擬硬件,向cpu發出任意irql級別的軟中斷,請求cpu處理執行那種中斷。

VOID?FASTCALL

HalRequestSoftwareInterrupt(IN?KIRQL?Irql)//Irql一般是APC_LEVEL/DPC_LEVEL

{

????ULONG?EFlags;

????PKPCR?Pcr?=?KeGetPcr();

????KIRQL?PendingIrql;

????EFlags?=?__readeflags();//保存老的eflags寄存器

????_disable();//關中斷

????Pcr->IRR?|=?(1?<<?Irql);//關鍵。標志向cpu發出了一個對應irql級的軟中斷

PendingIrql?=?SWInterruptLookUpTable[Pcr->IRR?&?3];//IRR后兩位表示是否有阻塞的apc中斷

//若有阻塞的apc中斷,并且當前irql是PASSIVE_LEVEL,立即執行apc。也即在PASSIVE_LEVEL級時發出任意軟中斷后,會立即檢查執行現有的apc中斷。

if?(PendingIrql?>?Pcr->Irql)

?SWInterruptHandlerTable[PendingIrql]();//調用執行apc中斷的isr,處理apc中斷

????__writeeflags(EFlags);//恢復原eflags寄存器

}

?

那么什么時候,系統會調用這個函數,向cpu發出apc中斷呢?

典型的情形1:

在切換線程時,若將線程的WaitIrql置為APC_LEVEL,將導致KiSwapContextInternal函數內部在重新切回來后,立即自動發出一個apc中斷,以在下次降低irql到PASSIVE_LEVEL時處理執行隊列中那些阻塞的apc。反之,若將線程的WaitIrql置為PASSIVE_LEVEL,將導致KiSwapContextInternal函數內部在重新切回來后,不會發出apc中斷,然后系統會自行顯式調用KiDeliverApc給予掃描執行

?

典型情形2:

在給自身線程發送一個內核apc時,在apc進隊的同時,會發出apc中斷,以請求cpu在下次降低irql時,掃描執行apc。

?

?

?

Apc是一種軟中斷,既然是中斷,他也有類似的isr。Apc中斷的isr最終進入?HalpApcInterruptHandler

VOID?FASTCALL

HalpApcInterruptHandler(IN?PKTRAP_FRAME?TrapFrame)

{

????//模擬硬件中斷壓入保存的寄存器

????TrapFrame->EFlags?=?__readeflags();

????TrapFrame->SegCs?=?KGDT_R0_CODE;

????TrapFrame->Eip?=?TrapFrame->Eax;

????KiEnterInterruptTrap(TrapFrame);//構造Trap現場幀

????掃描執行當前線程的內核apc隊列,略…

????KiEoiHelper(TrapFrame);?

}

轉載于:https://www.cnblogs.com/jadeshu/p/10663609.html

總結

以上是生活随笔為你收集整理的[6]Windows内核情景分析 --APC的全部內容,希望文章能夠幫你解決所遇到的問題。

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

日日夜操| 亚洲精品xxx| 黄色动态图xx | 91资源在线 | 国产精品久久在线 | 国产伦精品一区二区三区无广告 | 激情网五月天 | 人人爽人人爽人人片 | 久久综合九色综合久久久精品综合 | 国产精品毛片一区视频播不卡 | 九九九热精品免费视频观看网站 | 久久免费久久 | 天天色天天骑天天射 | 天天操天天插 | 国产精品 日韩 欧美 | 欧美日韩高清免费 | 国产精品久久99综合免费观看尤物 | 亚洲视频 一区 | 久久乐九色婷婷综合色狠狠182 | 一区二区三区久久 | 日韩中文久久 | 手机在线日韩视频 | 人人添人人澡人人澡人人人爽 | 玖玖视频精品 | 91一区二区在线 | 欧美国产日韩一区二区三区 | 91成版人在线观看入口 | 国产精久久久久久妇女av | 9色在线视频 | 鲁一鲁影院 | 日日射天天射 | 五月婷婷开心 | av成人免费观看 | 99久久精品免费看 | 欧美成人h版在线观看 | 国产一二区精品 | 欧美在线视频日韩 | 狠狠色丁香婷婷综合橹88 | 91在线看视频| 久久这里只有精品久久 | 五月婷婷视频在线 | 中文字幕乱码在线播放 | www最近高清中文国语在线观看 | 国产精品福利无圣光在线一区 | 91最新中文字幕 | 成人精品一区二区三区中文字幕 | 国产91粉嫩白浆在线观看 | 麻豆久久一区二区 | 天天操操操操操操 | 天堂av在线7| 91女子私密保健养生少妇 | 欧美永久视频 | 狠狠狠干| 又黄又色又爽 | 久久资源在线 | 亚洲精品在线播放视频 | 日韩久久精品一区二区 | 99re亚洲国产精品 | 在线观看免费视频 | 丰满少妇一级片 | 久久久久二区 | 国产香蕉视频在线观看 | 国产在线视频不卡 | 亚洲精品乱码久久久久久按摩 | 久久国内免费视频 | 99精品视频99 | 亚洲激精日韩激精欧美精品 | 91九色国产视频 | 国产成人中文字幕 | 九九九九免费视频 | 久久九九影视 | 日韩午夜大片 | 91理论片午午伦夜理片久久 | 在线免费观看视频一区二区三区 | 日韩激情片在线观看 | 国产在线a免费观看 | 深夜免费福利在线 | 永久免费观看视频 | 激情伊人五月天久久综合 | 丁香婷婷综合色啪 | 久久综合九色九九 | 在线观看自拍 | 成年人视频在线免费 | 国产在线a | 青青久草在线视频 | 午夜在线国产 | 日本久久电影网 | 国产精品视频永久免费播放 | av免费高清观看 | 在线观看视频你懂得 | 欧美日韩精品在线观看视频 | 成年人免费看片 | 日韩在线色 | 国产中文字幕网 | 麻豆视频一区 | 四虎永久视频 | 国产亚洲一区 | 久草视频免费播放 | 国产成人黄色网址 | 日韩三级视频在线观看 | 色婷婷天天干 | 免费看成人 | 亚洲成成品网站 | 国产v在线播放 | 国产一级大片免费看 | 91九色porny蝌蚪视频 | 国产一区二区在线影院 | 久久久综合九色合综国产精品 | 天天综合成人 | www.色午夜 | japanesexxxxfreehd乱熟 | 一级淫片在线观看 | 成人av视屏 | 日韩精品大片 | www,黄视频 | 国产在线色 | 国产精品成人自产拍在线观看 | www黄com| 久久综合色天天久久综合图片 | 欧美怡红院| 69视频永久免费观看 | 成人av在线网址 | 日韩精品免费一区二区在线观看 | 日韩精品免费一区二区三区 | 五月开心婷婷网 | 亚洲精品视频久久 | 国产成人av在线 | 91免费观看视频在线 | 99在线观看视频网站 | 青青草国产在线 | 美女天天操 | 最新av网址在线 | 国产精品国内免费一区二区三区 | 成 人 黄 色 免费播放 | 国产区av在线 | 激情深爱五月 | 亚洲精品xx | 婷婷福利影院 | 爱色婷婷 | 日韩成人黄色av | www.成人久久| 91在线蜜桃臀 | 国产97色 | 天天干天天射天天爽 | 亚洲精品人人 | 国产精品自产拍在线观看蜜 | 国产精品久久久久久久久大全 | 日本性高潮视频 | 精品爱爱 | 色狠狠综合 | 天天操夜夜看 | 91九色蝌蚪国产 | 天天夜夜亚洲 | 成人av资源网 | 久久精品日本啪啪涩涩 | 视频国产在线 | 亚洲丝袜中文 | 激情五月在线视频 | 狠狠88综合久久久久综合网 | 91免费的视频在线播放 | 一区二区伦理 | 国产成人一区二区三区在线观看 | 亚洲综合在线五月天 | 亚洲涩涩色 | 日韩字幕在线观看 | 久久久久高清毛片一级 | 国产精品一区二区果冻传媒 | 国产在线91在线电影 | 91精品久久久久久久99蜜桃 | 黄色在线免费观看网址 | 成人毛片在线观看 | 国产香蕉视频在线播放 | 国产黄色在线观看 | 日韩在线小视频 | 婷婷久久一区二区三区 | 97在线看片 | 成 人 黄 色 视频免费播放 | www.国产精品| 热99久久精品 | 亚洲精品自在在线观看 | 国产精品夜夜夜一区二区三区尤 | 成人97视频| 午夜精品久久久久久久99水蜜桃 | 亚洲欧美视频在线 | 国产黄色一级片在线 | 精品久久久网 | 日韩www在线 | 精品久久1 | 天天综合日日夜夜 | 亚洲精品综合欧美二区变态 | 91精品亚洲影视在线观看 | 爱色av.com | 国产成人三级三级三级97 | 久久与婷婷 | 久久久私人影院 | 日韩精品视频网站 | 亚洲欧美国产精品va在线观看 | 欧美国产日韩在线视频 | 国产精品麻豆一区二区三区 | 久久香蕉国产精品麻豆粉嫩av | 久久理论电影网 | 国产无遮挡又黄又爽在线观看 | 国产精品中文字幕在线播放 | 国产成人精品一区二区 | 中文字幕专区高清在线观看 | 日本不卡一区二区三区在线观看 | 久日精品| 黄色在线观看www | 91桃色在线观看视频 | 国产高清福利在线 | 国产精品爽爽久久久久久蜜臀 | 日韩乱码中文字幕 | 日韩av影视在线观看 | 又黄又爽又色无遮挡免费 | 日韩av区 | 久久精品视频中文字幕 | 国产精品专区h在线观看 | 国产中文欧美日韩在线 | 天天综合网 天天综合色 | 91大神电影| 亚洲五月六月 | 国色天香第二季 | 免费无遮挡动漫网站 | 日韩高清国产精品 | 亚洲资源在线 | 狠狠综合久久 | 午夜视频一区二区三区 | 99热最新在线 | 91亚洲在线 | 欧美一级免费在线 | 久久久黄色免费网站 | 香蕉在线视频播放网站 | 色婷婷精品大在线视频 | 国产亚洲成av人片在线观看桃 | 精品久久久久一区二区国产 | 中文字幕在线看片 | 一区二区三区国产欧美 | 色婷婷激情电影 | 免费在线观看亚洲视频 | 午夜美女福利直播 | 国产一区在线不卡 | av一级久久 | 999视频在线播放 | 丁香视频在线观看 | 成人精品在线 | 亚洲精色 | 热久久电影 | 欧美精品一区在线发布 | 在线小视频你懂的 | 免费av在| 最近免费中文字幕mv在线视频3 | 毛片在线网 | 综合网伊人| 免费日韩av电影 | 午夜成人免费电影 | 在线天堂日本 | 久久精品国产一区二区电影 | 一级黄毛片 | 超碰电影在线观看 | 日日干天天干 | 欧美日韩在线视频一区二区 | 久草在线视频在线观看 | 婷婷色在线观看 | 亚洲码国产日韩欧美高潮在线播放 | 最新在线你懂的 | 特级西西444www大精品视频免费看 | 伊人色综合久久天天 | 久久久网址 | 狠狠干夜夜操天天爽 | 在线v片 | 久久久久综合精品福利啪啪 | 日本精品二区 | 爱情影院aqdy鲁丝片二区 | 天天综合网在线 | www.97色.com | 在线观看黄网站 | 日韩字幕在线 | 天天摸日日操 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 久久久精品欧美一区二区免费 | а天堂中文最新一区二区三区 | 在线观看麻豆av | 国产在线免费av | 国产免费观看久久 | 国产午夜精品一区二区三区在线观看 | 国内少妇自拍视频一区 | 色吊丝在线永久观看最新版本 | 久久久免费精品 | 狠狠躁夜夜a产精品视频 | 精品视频在线免费 | 天天爽夜夜爽人人爽一区二区 | 999久久久国产精品 高清av免费观看 | 在线免费视频a | 97国产精品视频 | av福利电影 | 美女网站在线观看 | 亚洲精品在线国产 | 麻豆系列在线观看 | 天天夜操| 欧美日韩一区二区久久 | 丁香六月激情 | 色婷婷久久久 | 麻豆精品视频在线 | 国产麻豆精品95视频 | 在线高清| 日韩大片在线观看 | 国产日韩在线播放 | 国产高清免费观看 | 欧美一区免费在线观看 | 99r在线视频| 亚洲成aⅴ人片久久青草影院 | 97操操| 91超国产 | 一级黄色大片在线观看 | 久久久精品国产一区二区电影四季 | 久久免费视频6 | 人人澡人人模 | 91精品久久久久久综合乱菊 | 我爱av激情网 | 国产原创在线 | 欧洲一区二区三区精品 | 午夜美女视频 | 亚洲香蕉在线观看 | 免费亚洲一区二区 | 午夜精品视频免费在线观看 | www.天堂av| 日韩在线第一区 | 日韩av午夜在线观看 | 人人揉人人揉人人揉人人揉97 | 亚洲日韩中文字幕在线播放 | 日韩成人中文字幕 | 看v片| 91九色porny蝌蚪主页 | 欧美视频xxx | 91探花系列在线播放 | 区一区二区三在线观看 | 久久精品一二三区 | 国产精品99久久免费黑人 | 99re国产视频 | 人人搞人人干 | 亚洲区视频在线 | 永久免费的啪啪网站免费观看浪潮 | 一区二区不卡 | 在线观看视频一区二区三区 | 日韩在线观看一区二区 | 亚洲国产精品小视频 | 天天拍天天干 | 日韩高清一区 | 日韩欧美一二三 | 黄色国产在线观看 | 五月天六月婷婷 | 国内外成人在线视频 | 91最新网址 | 久久久久久久久久亚洲精品 | 久久综合色婷婷 | 97人人添人澡人人爽超碰动图 | 国产在线黄 | 国产三级香港三韩国三级 | 在线黄色国产 | 97超碰超碰| 成人a在线观看高清电影 | 久久亚洲美女 | 日韩大片在线免费观看 | 欧美激情视频一区二区三区免费 | 国内毛片毛片 | 亚洲欧美日韩国产一区二区三区 | 国产一区免费视频 | 久久理伦片 | 久久优 | 91毛片在线 | 91在线一区| 亚洲精品18日本一区app | 欧美在线视频二区 | 国内精品在线一区 | 黄网站免费大全入口 | 91九色网址 | 韩国精品在线观看 | av电影久久 | 91av看片 | 国产一区二区三区在线免费观看 | 日韩av在线不卡 | 免费精品在线 | 探花视频免费在线观看 | 99精品视频免费看 | 免费在线观看污网站 | 在线看黄色的网站 | 精品视频999| 成人a毛片 | 中文字幕精| 亚洲在线精品视频 | 免费av在 | 久久久久久久久久久久国产精品 | 亚洲国产精品成人女人久久 | 亚洲美女在线一区 | 国产成人一区二区三区久久精品 | 99久久久久免费精品国产 | 麻豆视频在线播放 | 狠狠干天天色 | 国产亚洲精品久久久久久网站 | 亚洲精品国产精品国产 | 国产精品综合av一区二区国产馆 | 午夜精品视频一区 | 成人免费毛片aaaaaa片 | 午夜视频免费在线观看 | 亚洲国产欧美一区二区三区丁香婷 | 在线天堂亚洲 | 国产一区二区中文字幕 | 免费看av在线 | 国产精品毛片网 | 精品自拍sae8—视频 | 亚洲国产精品视频在线观看 | 在线综合 亚洲 欧美在线视频 | 黄色成年网站 | 久久免费看av | 免费在线成人 | av不卡中文字幕 | 精品在线观 | 亚洲精品在线电影 | 国产日女人 | 国色天香第二季 | 免费在线一区二区 | 免费在线一区二区三区 | 亚洲精品99久久久久中文字幕 | 亚洲另类在线视频 | 色吊丝在线永久观看最新版本 | 午夜婷婷在线观看 | 中文字幕在线日亚洲9 | 亚洲成人午夜在线 | 亚洲理论影院 | 久久精品久久精品久久39 | 久久婷婷国产色一区二区三区 | 国产91电影在线观看 | 日p视频在线观看 | 啪啪免费观看网站 | 五月激情丁香婷婷 | 午夜久久影院 | 国产成人在线精品 | 色搞搞| 91亚洲激情 | 一区二区视频电影在线观看 | 久久精品二区 | 欧美福利视频一区 | 国产精品久久久久久久妇 | 蜜桃久久久 | 成在线播放 | 久久精品一二三 | 日韩精品一区不卡 | 国产精品一区二区三区久久久 | 9999在线观看 | 九九爱免费视频在线观看 | 久久er99热精品一区二区 | 日韩中文字幕免费 | 国产精品成人av在线 | 久久国产经典视频 | 最新国产精品拍自在线播放 | 亚洲永久精品在线观看 | 欧美大片大全 | 亚洲国产成人高清精品 | 日韩毛片在线一区二区毛片 | 开心激情网五月天 | 国产成人一区二区三区免费看 | 91精选在线观看 | 6699私人影院 | 69视频在线播放 | 久久久久国产精品免费免费搜索 | 在线视频观看你懂的 | 99热官网| 色综合天天综合在线视频 | 首页国产精品 | 日本精品一区二区在线观看 | 日韩视频在线一区 | 欧美成人性网 | 国产原创在线视频 | av在线播放亚洲 | 久久久精品在线观看 | 色国产在线 | 在线视频国产区 | 国产日韩视频在线 | 天堂av在线免费观看 | 美女精品久久久 | 色综合天天色综合 | av免费高清观看 | 91在线91| av网站免费线看精品 | 国产精品激情偷乱一区二区∴ | 久久久久久久久电影 | 天天射天天色天天干 | 91成人免费视频 | 国产精品久久久久久久久久妇女 | 日韩免费b | 精品久久久久久久久久久久 | 在线天堂中文在线资源网 | 人人爱天天操 | 国产日韩欧美在线免费观看 | 日韩在线观看第一页 | 久久精品视 | 久久久久 免费视频 | 2021国产在线视频 | 在线看av网址| 国产精品久99 | 天堂资源在线观看视频 | 99爱国产精品 | 久久精品一区二区三区国产主播 | 国产日韩欧美在线播放 | 午夜视频在线观看网站 | 懂色av一区二区在线播放 | 亚洲高清在线观看视频 | 91亚洲在线 | 最近免费在线观看 | 久久视频这里有久久精品视频11 | 久久久久久久精 | 日韩精品一区二区三区不卡 | 日本黄色黄网站 | 在线 精品 国产 | 久久中文视频 | 午夜精品久久一牛影视 | 婷婷九月激情 | 日韩毛片在线一区二区毛片 | 中文不卡视频在线 | 免费三级黄色片 | 国产91勾搭技师精品 | 国产 日韩 在线 亚洲 字幕 中文 | aaa日本高清在线播放免费观看 | 2019久久精品 | 日韩三级中文字幕 | 色婷婷亚洲精品 | 国产小视频91 | 欧美乱熟臀69xxxxxx | 精品一区二区在线免费观看 | 欧美性黄网官网 | 久久99国产精品免费 | 高清av中文字幕 | 久久字幕网 | 激情欧美xxxx| 高清不卡一区二区三区 | 热久久视久久精品18亚洲精品 | 中文字幕精品一区二区三区电影 | 国产成人久久精品亚洲 | 国产精品九九久久久久久久 | 中文字幕在线观看网址 | 91完整版在线观看 | 97超碰精品| 狠狠五月天 | 欧美日韩中文在线 | av色综合| 国产精品久久久网站 | 成人亚洲综合 | 国产免费一区二区三区网站免费 | 色视频网站在线 | 91最新地址永久入口 | 在线观看www91 | 国内精品久久久久久久影视简单 | 国产一区免费视频 | 精品国产伦一区二区三区免费 | 99精品免费在线观看 | 日日操网| 国产亚洲精品久久久久久无几年桃 | 啪啪精品 | 最近中文字幕第一页 | 色噜噜狠狠狠狠色综合 | 日韩在线免费视频观看 | 久久久精品影视 | av在线电影播放 | 亚洲精品网站 | 啪啪免费试看 | 国产亚洲精品美女 | 免费观看第二部31集 | 国内精品久久久久久久 | 91视频下载| 色婷婷97| 国产精品美女久久久久久久网站 | 日日操日日插 | 在线免费高清一区二区三区 | 欧美日韩天堂 | 婷婷综合久久 | 激情综合五月婷婷 | 最近中文字幕完整视频高清1 | 精品免费久久久久久 | 午夜国产福利在线 | 91av视频观看| 国产精品久久久久一区二区三区共 | 色橹橹欧美在线观看视频高清 | 精品国产中文字幕 | 日韩午夜精品 | 国产成人333kkk | 久久综合之合合综合久久 | 黄色福利视频网站 | 国内丰满少妇猛烈精品播放 | 91亚洲精品久久久蜜桃 | 成人av在线一区二区 | 亚洲一区免费在线 | 亚洲午夜精品久久久久久久久久久久 | 久久久噜噜噜久久久 | 亚洲精品视频一二三 | 国产高清免费在线观看 | 久久er99热精品一区二区 | 亚洲欧美在线综合 | 免费av免费观看 | 主播av在线 | h文在线观看免费 | 国产视频在线播放 | 97人人澡人人爽人人模亚洲 | 激情网第四色 | 在线日韩视频 | 91在线porny国产在线看 | 亚洲最大成人免费网站 | 人人插人人费 | 天天看天天操 | 国产小视频在线播放 | 黄色大片av | 久久久久在线 | 色婷婷a | 欧美日韩在线观看一区 | 天海翼一区二区三区免费 | 99在线视频免费观看 | 日本中文字幕系列 | 欧美精品久久久久久久免费 | 精品久久一区二区 | 久久超 | 久久精品一二区 | 2024国产精品视频 | 亚洲精品国内 | 亚洲春色奇米影视 | 在线免费av网 | 丁香色婷 | 国产精品免费在线播放 | 黄色亚洲大片免费在线观看 | www色婷婷com| 狠狠色噜噜狠狠 | 成人一区二区三区在线 | 国产精品wwwwww | 国产免费一区二区三区最新6 | 丁香视频 | 中文永久字幕 | 丰满少妇在线观看网站 | 成人免费观看a | 黄色小说免费在线观看 | 国产亚洲精品久久久久久电影 | 婷婷五月色综合 | 99视频在线免费看 | 麻豆国产精品永久免费视频 | 日韩在线色视频 | 六月丁香综合网 | 国产精品九九久久久久久久 | 国产第一福利网 | 中文在线字幕免费观看 | 欧美在线不卡一区 | 国产在线永久 | 999抗病毒口服液 | 中文字幕在线观看资源 | 亚洲一区二区三区miaa149 | 香蕉色综合 | 激情丁香 | 蜜臀av一区二区 | 欧美日本啪啪无遮挡网站 | 在线99 | 91免费在线视频 | 久久女同性恋中文字幕 | 日韩免费一级a毛片在线播放一级 | 在线观看视频亚洲 | 国产黄色片免费在线观看 | 久爱综合 | 久久久免费观看完整版 | 日韩精品在线免费播放 | 激情五月五月婷婷 | 五月天.com| 亚洲精品视频观看 | 国产精品毛片久久 | 97视频免费在线 | www狠狠| 久草视频免费看 | 午夜影视av| 日韩影片在线观看 | 国产精品成人久久久久久久 | 日韩av快播电影网 | 国产91影院 | 中文字幕久久精品一区 | 国产在线观看黄 | 国内99视频 | 日本中文乱码卡一卡二新区 | 美女搞黄国产视频网站 | 免费观看十分钟 | 亚洲精品视频在线看 | 热精品| 成年人毛片在线观看 | 午夜精品一二三区 | 成人免费一级 | 综合国产视频 | 一区二区亚洲精品 | 99热在线免费观看 | 中文字幕一区二区三区在线视频 | 免费麻豆视频 | 国产美女视频 | 精品夜夜嗨av一区二区三区 | 天天插一插 | 精品国产乱码一区二 | 一区二区欧美日韩 | 欧美激情精品久久久久久 | 日日爱av | 嫩草av影院 | 日本黄色特级片 | 又黄又刺激视频 | 手机成人av在线 | 亚洲成人软件 | 亚洲精品在线视频播放 | 操操操影院| 视频在线一区二区三区 | 国产一线天在线观看 | 美女网站视频免费都是黄 | 97国产在线 | 97超碰中文字幕 | 日韩av午夜 | 久久 地址 | 国产麻豆精品95视频 | 久操操 | 午夜精品一区二区三区在线播放 | 中文字幕第| 成人播放器 | 五月激情丁香婷婷 | 免费人成网 | 月丁香婷婷 | 美女黄久久 | 国产精品一区在线播放 | 精品在线播放 | 免费成人av网站 | 97超碰人人澡人人 | 国产在线污 | av一区二区三区在线观看 | 日韩伦理一区二区三区av在线 | 91大神精品视频 | 中文字幕综合在线 | 亚洲精品国产麻豆 | 中文字幕中文字幕 | 久久99深爱久久99精品 | 黄色影院在线免费观看 | 成人午夜黄色 | а天堂中文最新一区二区三区 | 黄色亚洲免费 | 天海冀一区二区三区 | 久久久久激情 | a一片一级 | 亚洲免费小视频 | 五月婷婷伊人网 | 久久午夜精品 | 久久综合色婷婷 | 国产精品免费在线视频 | 91人人人 | 国产另类xxxxhd高清 | 亚洲视频高清 | 成人久久电影 | 精品国内| 成人免费大片黄在线播放 | 综合色中色 | 国产在线高清 | 免费网站在线观看人 | 狠狠色伊人亚洲综合网站色 | 亚洲日本中文字幕在线观看 | 亚洲激情 欧美激情 | 国产免费嫩草影院 | 9999国产精品| 中文成人字幕 | 中文字幕一区二区三区四区 | 91麻豆精品国产91 | 亚洲国产视频在线 | 精品在线观看国产 | 国产伦理久久精品久久久久_ | 日韩一区二区三区在线看 | 丁香六月在线 | 日本乱码在线 | 中文字幕在线观看第一区 | 亚在线播放中文视频 | 国产做a爱一级久久 | 少妇视频在线播放 | av在线一 | 激情小说久久 | 国产精品女同一区二区三区久久夜 | 国产视频一区在线 | 午夜 免费| 精品视频在线免费 | 麻豆精品视频 | 午夜精品一区二区三区免费视频 | 日韩av进入 | 在线观看国产www | 亚洲无吗视频在线 | 操操综合网 | 四虎在线观看视频 | 十八岁以下禁止观看的1000个网站 | 中文字幕高清有码 | 中文字幕丰满人伦在线 | 美女禁18| 亚州精品天堂中文字幕 | 免费日韩 精品中文字幕视频在线 | 青春草免费在线视频 | 国产亚洲精品久久久久久电影 | av一级片在线观看 | 亚洲成人精品在线 | 国产精品美乳一区二区免费 | 国产精品淫 | 成年人免费在线观看网站 | 日本爱爱免费视频 | 国产一区二区三区在线 | 日日夜精品 | 国产午夜三级一区二区三 | 亚洲成人av免费 | 久久久久女教师免费一区 | 成人在线视频观看 | 国产精品久久麻豆 | 欧美黑人性猛交 | 亚洲精品影视在线观看 | 九九热在线精品视频 | 国产中文字幕视频在线观看 | 久久无码av一区二区三区电影网 | av网址在线播放 | 国产91精品一区二区麻豆亚洲 | 欧美日韩二三区 | 国产精品女主播一区二区三区 | 日韩久久久久久久久久 | 日韩欧美69| 国产 日韩 欧美 中文 在线播放 | 亚洲激情久久 | 国产精品免费在线观看视频 | 久久露脸国产精品 | 在线 国产 亚洲 欧美 | 国产探花| 精品亚洲一区二区三区 | 国产精品一区二区中文字幕 | 免费在线播放黄色 | 热久久免费视频 | 日韩中文字幕网站 | 久久国产精品久久w女人spa | 国产麻豆果冻传媒在线观看 | 欧美日韩亚洲一 | 2020天天干天天操 | 免费黄色特级片 | 欧美成人按摩 | 久久久国产精品视频 | 91在线看视频 | 日韩在线视频免费播放 | 国产精品毛片 | 五月婷婷在线视频观看 | 免费观看国产精品 | 亚洲一区日韩在线 | 色婷婷视频 | 在线观看免费av片 | 玖草在线观看 | 日韩专区一区二区 | 亚洲精品1234区 | 成人a视频在线观看 | 激情五月婷婷激情 | 精品免费观看视频 | 国产精品久久99精品毛片三a | 免费观看性生活大片 | 久久精品欧美一区 | 欧美精品亚洲二区 | av日韩av| 亚洲精品美女在线 | 美女精品在线观看 | 伊人永久 | 精品久久一区二区三区 | 91色亚洲| 久久视频这里有久久精品视频11 | 人人超在线公开视频 | 国产日韩视频在线观看 | 天天射天天拍 | 成人a级免费视频 | 西西www4444大胆在线 | 一级性生活片 | 国产精品久久久久aaaa | 久久久久久久影院 | 一区二区三区精品在线视频 | 91综合视频在线观看 | 久草视频免费观 | 国产视频资源在线观看 | 国产91av视频在线观看 | 欧美日韩中文字幕视频 | 久草视频免费在线观看 | 热久久国产精品 | 国产小视频免费在线观看 | 国产在线观看 | 韩国av一区二区三区在线观看 | 天天爱天天爽 | 免费观看一级一片 | 国产麻豆精品久久 | 96香蕉视频 | 久久久久久久久久久网 | 欧美成天堂网地址 | 国产高清不卡一区二区三区 | 欧美日韩免费一区 | 久久国产精品99精国产 | 在线黄av | 亚洲天堂网站 | 国产 视频 久久 | 日本精品一区二区三区在线播放视频 | 色综合色综合色综合 | 亚洲精品tv久久久久久久久久 | 国产区精品 | 欧美少妇的秘密 | 免费在线观看一区二区三区 | 综合精品在线 | 人人爽人人插 | 免费看v片 | 在线观看免费91 | 国产又黄又爽无遮挡 | 精品久久久久久久久久 | 色五月色开心色婷婷色丁香 | 99精品视频在线免费观看 | www.夜夜| 免费情缘 | 久久精品1区2区 | 韩国视频一区二区三区 | 久久精品免视看 | 99热这里只有精品1 av中文字幕日韩 | 国产 日韩 欧美 中文 在线播放 | 天天激情站 | 日韩最新在线视频 | 国产精品久久久电影 | 日韩午夜视频在线观看 | 欧美一区二区三区免费观看 | 天天射天天拍 | 国产精品97 | 在线不卡a | 激情在线网站 | 日韩精品久久中文字幕 | 日韩肉感妇bbwbbwbbw | 国产一级大片免费看 | 精品免费观看 | 深夜免费福利网站 | www激情久久 | 国产大片免费久久 | 久久久久综合网 | 黄色国产区 | 国产福利一区二区三区视频 | 国产成人久久av | 亚洲做受高潮欧美裸体 | 久久久久久免费网 | 91精品在线免费观看视频 | 婷婷5月激情5月 | 免费黄色在线网址 | 成人av影视在线 | 五月婷婷六月综合 | 成人在线网站观看 | 中日韩免费视频 | 91av在线看 | 在线视频一区二区 | 九九九热精品免费视频观看网站 | 免费在线国产 | 9999国产| 综合成人在线 | 亚洲精品成人av在线 | 国产午夜精品一区二区三区 | 综合国产在线观看 | 日韩av成人在线观看 | 亚洲精品白浆高清久久久久久 | 日韩高清不卡一区二区三区 | 色偷偷88888欧美精品久久 | 一区二区三区在线影院 | 黄色精品国产 | 97电影手机版 | 久久综合成人 | 欧美日韩中文在线观看 | 天天射天天做 | 丰满少妇在线 | 91九色在线观看视频 | 亚洲在线成人精品 | 在线黄网站| 国产高清专区 | 成年人在线免费视频观看 | 婷婷亚洲综合五月天小说 | 涩涩网站在线播放 | 91色蜜桃 | 日韩欧美在线观看一区二区 | 中文av免费 | 免费色视频网站 | 色资源二区在线视频 | 91麻豆精品国产91久久久久久 | 在线观看岛国av | 成人亚洲精品国产www | 在线观看日韩国产 | 麻豆国产电影 | 91香蕉国产在线观看软件 | 国产精品专区一 | 狠狠躁日日躁狂躁夜夜躁 | 日韩欧美电影网 | 麻豆精品视频在线观看免费 | 色av色av色av | 亚州免费视频 | 精品国产自在精品国产精野外直播 | 亚洲乱码精品久久久 | 天天色天天综合 | 九九九热精品免费视频观看网站 | www,黄视频 | 久久精品99久久久久久2456 | 69精品在线 | 99热9 | 亚洲涩涩色 | 片网站 | 国产精品孕妇 | 九九热久久免费视频 |