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

隨筆-60  評論-111  文章-0  trackbacks-0

異步過程調(diào)用(APCs) 是NT異步處理體系結(jié)構(gòu)中的一個基礎(chǔ)部分,理解了它,對于了解NT怎樣操作和執(zhí)行幾個核心的系統(tǒng)操作很有幫助。

1) APCs允許用戶程序和系統(tǒng)元件在一個進(jìn)程的地址空間內(nèi)某個線程的上下文中執(zhí)行代碼。
2) I/O管理器使用APCs來完成一個線程發(fā)起的異步的I/O操作。例如:當(dāng)一個設(shè)備驅(qū)動調(diào)用IoCompleteRequest來通知I/O管理器,它已經(jīng)結(jié)束處理一個異步I/O請求時,I/O管理器排隊一個apc到發(fā)起請求的線程。然后線程在一個較低IRQL級別,來執(zhí)行APC. APC的作用是從系統(tǒng)空間拷貝I/O操作結(jié)果和狀態(tài)信息到線程虛擬內(nèi)存空間的一個緩沖中。
3) 使用APC可以得到或者設(shè)置一個線程的上下文和掛起線程的執(zhí)行。

上面是網(wǎng)上找來的,下面是MSDN上的說明:


An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread. When an APC is queued to a thread, the system issues a software interrupt. The next time the thread is scheduled, it will run the APC function. An APC generated by the system is called a kernel-mode APC. An APC generated by an application is called a user-mode APC. A thread must be in an alertable state to run a user-mode APC.

Each thread has its own APC queue. An application queues an APC to a thread by calling the QueueUserAPC function. The calling thread specifies the address of an APC function in the call to QueueUserAPC. The queuing of an APC is a request for the thread to call the APC function.

還先看一下那些重要結(jié)構(gòu):

kd> dt KTHREAD
nt!KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY
+0x018 InitialStack : Ptr32 Void
+0x01c StackLimit : Ptr32 Void
+0x020 KernelStack : Ptr32 Void
+0x024 ThreadLock : Uint4B
+0x028 ApcState : _KAPC_STATE
+0x028 ApcStateFill : [23] UChar
+0x03f ApcQueueable : UChar
+0x040 NextProcessor : UChar
+0x041 DeferredProcessor : UChar
+0x042 AdjustReason : UChar
+0x043 AdjustIncrement : Char
+0x044 ApcQueueLock : Uint4B
+0x048 ContextSwitches : Uint4B
+0x04c State : UChar
+0x04d NpxState : UChar
+0x04e WaitIrql : UChar
+0x04f WaitMode : Char
+0x050 WaitStatus : Int4B
+0x054 WaitBlockList : Ptr32 _KWAIT_BLOCK
+0x054 GateObject : Ptr32 _KGATE
+0x058 Alertable : UChar
+0x059 WaitNext : UChar
+0x05a WaitReason : UChar
+0x05b Priority : Char
+0x05c EnableStackSwap : UChar
+0x05d SwapBusy : UChar
+0x05e Alerted : [2] UChar
+0x060 WaitListEntry : _LIST_ENTRY
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 Queue : Ptr32 _KQUEUE
+0x06c WaitTime : Uint4B
+0x070 KernelApcDisable : Int2B
+0x072 SpecialApcDisable : Int2B
+0x070 CombinedApcDisable : Uint4B
+0x074 Teb : Ptr32 Void
+0x078 Timer : _KTIMER
+0x078 TimerFill : [40] UChar
+0x0a0 AutoAlignment : Pos 0, 1 Bit
+0x0a0 DisableBoost : Pos 1, 1 Bit
+0x0a0 ReservedFlags : Pos 2, 30 Bits
+0x0a0 ThreadFlags : Int4B
+0x0a8 WaitBlock : [4] _KWAIT_BLOCK
+0x0a8 WaitBlockFill0 : [23] UChar
+0x0bf SystemAffinityActive : UChar
+0x0a8 WaitBlockFill1 : [47] UChar
+0x0d7 PreviousMode : Char
+0x0a8 WaitBlockFill2 : [71] UChar
+0x0ef ResourceIndex : UChar
+0x0a8 WaitBlockFill3 : [95] UChar
+0x107 LargeStack : UChar
+0x108 QueueListEntry : _LIST_ENTRY
+0x110 TrapFrame : Ptr32 _KTRAP_FRAME
+0x114 CallbackStack : Ptr32 Void
+0x118 ServiceTable : Ptr32 Void
+0x11c ApcStateIndex : UChar
+0x11d IdealProcessor : UChar
+0x11e Preempted : UChar
+0x11f ProcessReadyQueue : UChar
+0x120 KernelStackResident : UChar
+0x121 BasePriority : Char
+0x122 PriorityDecrement : Char
+0x123 Saturation : Char
+0x124 UserAffinity : Uint4B
+0x128 Process : Ptr32 _KPROCESS
+0x12c Affinity : Uint4B
+0x130 ApcStatePointer : [2] Ptr32 _KAPC_STATE
+0x138 SavedApcState : _KAPC_STATE
+0x138 SavedApcStateFill : [23] UChar
+0x14f FreezeCount : Char
+0x150 SuspendCount : Char
+0x151 UserIdealProcessor : UChar
+0x152 CalloutActive : UChar
+0x153 Iopl : UChar
+0x154 Win32Thread : Ptr32 Void
+0x158 StackBase : Ptr32 Void
+0x15c SuspendApc : _KAPC
+0x15c SuspendApcFill0 : [1] UChar
…………

…………

上面紅色部分是APC機制用到的幾個字段!!

kd> dt _KAPC_STATE
nt!_KAPC_STATE
+0x000 ApcListHead : [2] _LIST_ENTRY,每個指針指向_KAPC結(jié)構(gòu)
+0x010 Process : Ptr32 _KPROCESS
+0x014 KernelApcInProgress : UChar
+0x015 KernelApcPending : UChar
+0x016 UserApcPending : UChar

顯然,這里的 ApcListHead 就是 APC 隊列頭。不過這是個大小為 2 的數(shù)組,說明實際
上(每個線程)有兩個 APC 隊列。這是因為 APC 函數(shù)分為用戶 APC 和內(nèi)核 APC 兩種,各有
各的隊列。所謂用戶 APC,是指相應(yīng)的 APC 函數(shù)位于用戶空間、在用戶空間執(zhí)行;而內(nèi)核
APC,則相應(yīng)的 APC 函數(shù)為內(nèi)核函數(shù)。

SavedApcState也是個_KAPC_STATE結(jié)構(gòu),當(dāng)當(dāng)前程暫時“掛靠(Attach)”到另一個進(jìn)程的地址空間的時侯,ApcState就拷貝到SavedApcState暫時存放!

當(dāng)然,還要有狀態(tài)信息說明本線程當(dāng)前是處于“原始環(huán)境”還是“掛靠環(huán)境”,這就是 ApcStateIndex 的作用,代碼中為 ApcStateIndex的值定義了一種枚舉類型:

typedef enum _KAPC_ENVIRONMENT {
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
} KAPC_ENVIRONMENT;

實際可用于 ApcStateIndex 的只是 OriginalApcEnvironment和 AttachedApcEnvironment。

KAPC_STATE 指針數(shù)組 ApcStatePointer[2],就用ApcStateIndex 的當(dāng)前值作為下標(biāo),而數(shù)組中的指針則根據(jù)情況可以分別指向兩個APC_STATE 數(shù)據(jù)結(jié)構(gòu)中的一個。

kd> dt _KAPC ;APC對象
nt!_KAPC
+0x000 Type : UChar
+0x001 SpareByte0 : UChar
+0x002 Size : UChar
+0x003 SpareByte1 : UChar
+0x004 SpareLong0 : Uint4B
+0x008 Thread : Ptr32 _KTHREAD
+0x00c ApcListEntry : _LIST_ENTRY
+0x014 KernelRoutine : Ptr32 void
+0x018 RundownRoutine : Ptr32 void
+0x01c NormalRoutine : Ptr32 void
+0x020 NormalContext : Ptr32 Void
+0x024 SystemArgument1 : Ptr32 Void
+0x028 SystemArgument2 : Ptr32 Void
+0x02c ApcStateIndex : Char
+0x02d ApcMode : Char
+0x02e Inserted : UChar

KernelRoutine、RundownRoutine、NormalRoutine。其中只有 NormalRoutine才指向(執(zhí)行)APC 函數(shù)的請求者所提供的函數(shù),其余兩個都是輔助性的!

NTKERNELAPI
VOID
KeInitializeApc (
__out PRKAPC Apc,
__in PRKTHREAD Thread,
__in KAPC_ENVIRONMENT Environment,
__in PKKERNEL_ROUTINE KernelRoutine,
__in_opt PKRUNDOWN_ROUTINE RundownRoutine,
__in_opt PKNORMAL_ROUTINE NormalRoutine,
__in_opt KPROCESSOR_MODE ProcessorMode,
__in_opt PVOID NormalContext
);

這個函數(shù)主要用來初始化Apc(_KAPC)這個結(jié)構(gòu)的,如果Environment==CurrentApcEnvironment,Apc->ApcStateIndex就由KTHREAD中的ApcStateIndex決定,但Environment不能大于KTHREAD中的ApcStateIndex!

最后,APC 請求的模式ProcessorMode,但是有個例外,那就是:如果指針NormalRoutine 為 0,那么實際的模式變成了 KernelMode。這是因為在這種情況下沒有用戶空間APC函數(shù)可以執(zhí)行, 唯一將得到執(zhí)行的是KernelRoutine!

最后,KeInitializeApc 設(shè)置Inserted域為FALSE。然而初始化APC對象,并沒有把它存放到相應(yīng)的APC隊列中。


NTKERNELAPI
BOOLEAN
KeInsertQueueApc (
__inout PRKAPC Apc,
__in_opt PVOID SystemArgument1,
__in_opt PVOID SystemArgument2,
__in KPRIORITY Increment
);

據(jù)APC請求的具體情況,有時候要插在隊列的前頭,一般則掛在隊列的尾部。

_KiServiceExit:

cli ; disable interrupts
DISPATCH_USER_APC ebp, ReturnCurrentEax

;
; Exit from SystemService
;

EXIT_ALL NoRestoreSegs, NoRestoreVolatile ;這個宏以后再講

DISPATCH_USER_APC macro TFrame, ReturnCurrentEax
local a, b, c
c:
.errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)

test byte ptr [TFrame]+TsEflags+2, EFLAGS_V86_MASK/010000h ; is previous mode v86?
jnz short b ; if nz, yes, go check for APC
test byte ptr [TFrame]+TsSegCs,MODE_MASK ; is previous mode user mode?
jz a ; No, previousmode=Kernel, jump out
b: mov ebx, PCR[PcPrcbData+PbCurrentThread]; get addr of current thread
mov byte ptr [ebx]+ThAlerted, 0 ; clear kernel mode alerted
cmp byte ptr [ebx]+ThApcState.AsUserApcPending, 0
je a ; if eq, no user APC pending

mov ebx, TFrame
ifnb <ReturnCurrentEax>;條件宏匯編,如果ReturnCurrentEax參數(shù)不為空,則編譯!

;DISPATCH_USER_APC ebp, ReturnCurrentEax,顯然這里是編譯的!
mov [ebx].TsEax, eax ; Store return code in trap frame
mov dword ptr [ebx]+TsSegFs, KGDT_R3_TEB OR RPL_MASK
mov dword ptr [ebx]+TsSegDs, KGDT_R3_DATA OR RPL_MASK
mov dword ptr [ebx]+TsSegEs, KGDT_R3_DATA OR RPL_MASK
mov dword ptr [ebx]+TsSegGs, 0
endif

;
; Save previous IRQL and set new priority level
;
RaiseIrql APC_LEVEL
push eax ; Save OldIrql

sti ; Allow higher priority ints

;
; call the APC delivery routine.
;
; ebx - Trap frame
; 0 - Null exception frame
; 1 - Previous mode
;
; call APC deliver routine
;

stdCall _KiDeliverApc, <1, 0, ebx> ;1就是UserMode

pop ecx ; (ecx) = OldIrql
LowerIrql ecx

ifnb <ReturnCurrentEax> ;同上分析
mov eax, [ebx].TsEax ; Restore eax, just in case
endif

cli
jmp b ; 注意這個循環(huán)!!

ALIGN 4
a:
endm

這段代碼主要檢查:

即將返回的是否用戶空間。
是否有用戶APC請求正在等待執(zhí)行

條件符合才用KiDeliverApc真正投遞APC。注意代碼jmp b,好像在返回用戶空間前KiDeliverApc會被循環(huán)調(diào)用直到?jīng)]有user APC,其實不是的,KiDeliverApc每處理完一個User APC就把UserApcPending清零,所以User APCs在返回用戶空間時還是只能投遞一次!KiDeliverApc中用while處理完所有Kernel Mode APCs,但User Mode APC卻只處理一個!事實上User APC的投遞是很特殊的,以后會講到,而且每次只能投遞一次!


前面講過,KTHREAD 中有兩個 KAPC_STATE 數(shù)據(jù)結(jié)構(gòu),一個是 ApcState,另一個是SavedApcState,二者都有APC 隊列,但是要投遞的只是ApcState 中的隊列。

KiDeliverApc (
IN KPROCESSOR_MODE PreviousMode,//寫成DeliverMode不是更好
IN PKEXCEPTION_FRAME ExceptionFrame,//這個參數(shù)幾乎就是0
IN PKTRAP_FRAME TrapFrame
)

這個函數(shù)里面還比較復(fù)雜,代碼不帖了。

參數(shù)PreviousMode表示需要“投遞”哪一種 APC,可以是UserMode,也可以是KernelMode。不過,KernelMode 確實表示只要求執(zhí)行內(nèi)核 APC,而UserMode 卻表示在執(zhí)行內(nèi)核 APC 之外再執(zhí)行用戶APC。

The Windows operating system uses three kinds of APCs:


User APCs run strictly in user mode and only when the current thread is in an alertable wait state. The operating system uses user APCs to implement mechanisms such as overlapped I/O and the QueueUserApc Win32 routine. (run IRQL = PASSIVE_LEVEL)
Normal kernel APCs run in kernel mode at IRQL = PASSIVE_LEVEL. A normal kernel APC preempts all user-mode code, including user APCs. Normal kernel APCs are generally used by file systems and file-system filter drivers.
Special kernel APCs run in kernel mode at IRQL = APC_LEVEL. A special kernel APC preempts user-mode code and kernel-mode code that executes at IRQL = PASSIVE_LEVEL, including both user APCs and normal kernel APCs. The operating system uses special kernel APCs to handle operations such as I/O request completion.
從代碼的角度看是這樣的:

User APCs
_KAPC.ApcMode==UserMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine!=NULL

Normal kernel APCs

_KAPC.ApcMode==KernelMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine!=NULL

Special kernel APCs

_KAPC.ApcMode==KernelMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine==NULL

有一點它們的_KAPC.KernelRoutine肯定不為空。并且,如果NormolRoutine也不為空,那么KernelRoutine都在NormolRoutine被調(diào)用前被調(diào)用!!

上文中講到投遞User Mode APCs是很特殊的,道理很簡單,因為User Mode APC是ring3下的回調(diào)函數(shù),顯然ring0中的KiDeliverAPC()不能像Kernel Mode APC那樣直接call,必須要先回到ring3環(huán)境下。當(dāng)然不能像普通情況那樣返回(否則就回到ring3系統(tǒng)調(diào)用的地方了),只有一個辦法,那就是修改TrapFrame ,欺騙系統(tǒng)返回“APC回調(diào)函數(shù)”!KiInitializeUserApc就是這么做的!

該函數(shù)首先把TrapFrame轉(zhuǎn)化為ContextFrame,然后移動用戶態(tài)ESP指針,分配大約sizeof(CONTEXT)+sizeof(KAPC_RECORD)個字節(jié):

UserStack-> ……

KAPC_RECORD

……

……

CONTEXT

TopOfStack-> ……

KAPC_RECORD就是KiInitializeUserApc的最后四個參數(shù)

nt!_KAPC_RECORD

+0x000 NormalRoutine : Ptr32 void

+0x004 NormalContext : Ptr32 Void

+0x008 SystemArgument1 : Ptr32 Void

+0x00c SystemArgument2 : Ptr32 Void

CONTEXT結(jié)構(gòu)主要來存放被修改前的TrapFrame,之所以用CONTEXT結(jié)構(gòu)是跟APC函數(shù)返回有關(guān)!

TrapFrame->HardwareEsp = UserStack;

TrapFrame->Eip = (ULONG)KeUserApcDispatcher;

TrapFrame->ErrCode = 0;

從上面的代碼看到確實修改了TrapFrame,并且返回到的是ring3下的KeUserApcDispatcher,剛才說的_KAPC_RECORD其實也是它的參數(shù)!真正我們的User APC回調(diào)函數(shù)是由KeUserApcDispatcher調(diào)用的!

.func KiUserApcDispatcher@16

.globl _KiUserApcDispatcher@16

_KiUserApcDispatcher@16:

/* Setup SEH stack */

lea eax, [esp+CONTEXT_ALIGNED_SIZE+16]

mov ecx, fs:[TEB_EXCEPTION_LIST]

mov edx, offset _KiUserApcExceptionHandler

mov [eax], ecx

mov [eax+4], edx

/* Enable SEH */

mov fs:[TEB_EXCEPTION_LIST], eax

/* Put the Context in EDI */

pop eax

lea edi, [esp+12]

/* Call the APC Routine */

call eax

/* Restore exception list */

mov ecx, [edi+CONTEXT_ALIGNED_SIZE]

mov fs:[TEB_EXCEPTION_LIST], ecx

/* Switch back to the context */

push 1 ; TestAlert

push edi ;edi->CONTEXT結(jié)構(gòu)

call _ZwContinue@8

;;不會返回到這里的

上面的代碼并不難理解,我們的User APC回調(diào)函數(shù)返回后,立即調(diào)用了ZwContinue,這是個ntdll中的導(dǎo)出函數(shù),這個函數(shù)又通過系統(tǒng)調(diào)用進(jìn)入kernel中的NtContinue!

NTSTATUS

; NtContinue (

; IN PCONTEXT ContextRecord,

; IN BOOLEAN TestAlert

; )

;

; Routine Description:

;

; This routine is called as a system service to continue execution after

; an exception has occurred. Its function is to transfer information from

; the specified context record into the trap frame that was built when the

; system service was executed, and then exit the system as if an exception

; had occurred.

;

; WARNING - Do not call this routine directly, always call it as

; ZwContinue!!! This is required because it needs the

; trapframe built by KiSystemService.

;

; Arguments:

;

; KTrapFrame (ebp+0: after setup) -> base of KTrapFrame

;

; ContextRecord (ebp+8: after setup) = Supplies a pointer to a context rec.

;

; TestAlert (esp+12: after setup) = Supplies a boolean value that specifies

; whether alert should be tested for the previous processor mode.

;

; Return Value:

;

; Normally there is no return from this routine. However, if the specified

; context record is misaligned or is not accessible, then the appropriate

; status code is returned.

;

;--

NcTrapFrame equ [ebp + 0]

NcContextRecord equ [ebp + 8]

NcTestAlert equ [ebp + 12]

align dword

cPublicProc _NtContinue ,2

push ebp ;ebp->TrapFrame

;

; Restore old trap frame address since this service exits directly rather

; than returning.

;

mov ebx, PCR[PcPrcbData+PbCurrentThread] ; get current thread address

mov edx, [ebp].TsEdx ; restore old trap frame address

mov [ebx].ThTrapFrame, edx ;

;

; Call KiContinue to load ContextRecord into TrapFrame. On x86 TrapFrame

; is an atomic entity, so we don't need to allocate any other space here.

;

; KiContinue(NcContextRecord, 0, NcTrapFrame)

;

mov ebp,esp

mov eax, NcTrapFrame

mov ecx, NcContextRecord

stdCall _KiContinue, <ecx, 0, eax>

or eax,eax ; return value 0?

jnz short Nc20 ; KiContinue failed, go report error

;

; Check to determine if alert should be tested for the previous processor mode.

;

cmp byte ptr NcTestAlert,0 ; Check test alert flag

je short Nc10 ; if z, don't test alert, go Nc10

mov al,byte ptr [ebx]+ThPreviousMode ; No need to xor eax, eax.

stdCall _KeTestAlertThread, <eax> ; test alert for current thread

;如果User APCs不為空,它會設(shè)置UserApcPending,

;跟Alertable無關(guān)

Nc10: pop ebp ; (ebp) -> TrapFrame

mov esp,ebp ; (esp) = (ebp) -> trapframe

jmp _KiServiceExit2 ; common exit

Nc20: pop ebp ; (ebp) -> TrapFrame

mov esp,ebp ; (esp) = (ebp) -> trapframe

jmp _KiServiceExit ; common exit

stdENDP _NtContinue

NtContinue把CONTEXT結(jié)構(gòu)轉(zhuǎn)化成TrapFrame(回復(fù)原來的陷阱幀),然后就從KiServiceExit2處退出系統(tǒng)調(diào)用!

;++

;

; _KiServiceExit2 - same as _KiServiceExit BUT the full trap_frame

; context is restored

;

;--

public _KiServiceExit2

_KiServiceExit2:

cli ; disable interrupts

DISPATCH_USER_APC ebp

;

; Exit from SystemService

;

EXIT_ALL ; RestoreAll

KiServiceExit2跟KiServiceExit差不多,只是宏參數(shù)的不同!同樣如果還有User APC又會進(jìn)入上文描述的情形,直到?jīng)]有User APC,至此才會返回真正發(fā)起原始系統(tǒng)調(diào)用的地方!


本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/better0332/archive/2009/06/29/4306683.aspx

posted on 2011-05-05 12:09 shaker(太子) 閱讀(1316) 評論(0)  編輯 收藏 引用 所屬分類: C++Windows Kernel
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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一区| 亚洲免费电影在线| 国产区亚洲区欧美区| 久久综合久色欧美综合狠狠| 欧美黄色日本| 欧美在线3区| 免费成人高清在线视频| 亚洲欧美日韩直播| 久久九九精品99国产精品| 99在线精品观看| 欧美一区亚洲| 99精品视频免费在线观看| 午夜激情综合网| 91久久国产精品91久久性色| 在线一区二区三区四区| 午夜精品久久久久久久| 亚洲国产一区二区三区a毛片| 一区二区三区欧美在线观看| 伊人影院久久| 亚洲一区二区三区三| 91久久中文| 久久精品五月婷婷| 亚洲女女做受ⅹxx高潮| 免费看av成人| 久久久女女女女999久久| 欧美视频一区二区三区四区| 久久影院午夜片一区| 国产精品豆花视频| 亚洲人午夜精品| 国产综合久久| 亚洲自拍偷拍视频| 国产欧美一区二区三区在线老狼| 亚洲国产精品久久久久| 国产亚洲一区在线| 亚洲一区二区三区久久| 一区二区国产精品| 免费成人小视频| 另类国产ts人妖高潮视频| 国产精品香蕉在线观看| 一本到高清视频免费精品| 亚洲欧洲美洲综合色网| 久久嫩草精品久久久久| 久久三级福利| 国产综合色在线| 午夜精品www| 欧美一区二区三区另类| 国产精品成人一区二区三区吃奶 | 在线观看视频一区| 亚洲欧美资源在线| 欧美一进一出视频| 国产精品久久久久久福利一牛影视| 亚洲激情在线激情| 亚洲美女精品成人在线视频| 欧美成人精品在线视频| 欧美激情国产日韩精品一区18| 激情五月***国产精品| 久久成人羞羞网站| 蜜臀av性久久久久蜜臀aⅴ| 海角社区69精品视频| 久久精品一区中文字幕| 久久青青草原一区二区| 极品中文字幕一区| 久久尤物视频| 亚洲国产天堂久久综合| 夜久久久久久| 欧美视频在线免费| 亚洲欧美日韩综合aⅴ视频| 欧美在线观看www| 黄色成人91| 欧美高清视频在线| 999亚洲国产精| 香蕉久久a毛片| 韩日视频一区| 欧美激情在线狂野欧美精品| 一区二区三区不卡视频在线观看 | 精品99一区二区三区| 久久影音先锋| 亚洲理论在线| 欧美一区激情| 亚洲国产天堂久久国产91| 欧美电影免费观看高清| 亚洲婷婷综合色高清在线| 久久久久国产一区二区三区四区| 在线观看91精品国产入口| 欧美日韩福利视频| 欧美在线观看你懂的| 欧美激情亚洲精品| 午夜精品久久久久久久久久久久久| 国产亚洲精品成人av久久ww| 欧美插天视频在线播放| 亚洲尤物在线| 亚洲国产精品久久精品怡红院| 亚洲欧美成人综合| 影音先锋在线一区| 国产精品美女久久久久久久| 久久久青草婷婷精品综合日韩 | 午夜激情综合网| 亚洲高清二区| 久久免费视频网| 一本色道久久综合一区| 国内久久精品视频| 国产精品激情av在线播放| 卡一卡二国产精品| 亚洲一品av免费观看| 亚洲成在人线av| 在线精品视频一区二区三四| 国产精品yjizz| 免费观看日韩av| 欧美在线一二三| 中文国产成人精品| 亚洲精品久久久久久久久| 久久网站免费| 欧美在线观看视频| 亚洲永久视频| 亚洲桃色在线一区| 亚洲美女少妇无套啪啪呻吟| **欧美日韩vr在线| 国内精品久久久久久| 国产精品久久久久一区| 欧美日韩一区在线观看| 欧美高清hd18日本| 久久性天堂网| 久久嫩草精品久久久精品一| 欧美在线www| 欧美亚洲综合久久| 午夜精品久久久久久久久久久久| 99精品国产在热久久婷婷| 亚洲级视频在线观看免费1级| 男女激情视频一区| 老司机午夜精品| 老鸭窝亚洲一区二区三区| 久久久99免费视频| 久久蜜桃香蕉精品一区二区三区| 亚洲欧美在线磁力| 欧美一区二粉嫩精品国产一线天| 亚洲一区二区在线看| 亚洲一区二区日本| 亚洲一级一区| 午夜日韩在线| 久久男人av资源网站| 久久久久国产一区二区| 老司机成人网| 免费亚洲电影在线观看| 欧美成人一区二免费视频软件| 欧美大尺度在线观看| 欧美男人的天堂| 欧美三日本三级少妇三99| 国产精品对白刺激久久久| 国产精品日韩久久久| 国产婷婷一区二区| 在线日韩中文字幕| 亚洲巨乳在线| 亚洲欧美三级在线| 老鸭窝亚洲一区二区三区| 亚洲成人在线网| 在线亚洲美日韩| 香蕉久久一区二区不卡无毒影院 | 亚洲国产老妈| 亚洲一区二区三区在线播放| 欧美一区三区三区高中清蜜桃 | 亚洲欧美国产视频| 久久精品国产亚洲aⅴ| 欧美sm重口味系列视频在线观看| 亚洲国产一成人久久精品| 亚洲私拍自拍| 久久综合亚州| 国产精品看片资源| 亚洲国产精品视频| 亚洲欧美激情一区二区| 美女诱惑一区| 亚洲视频香蕉人妖| 另类综合日韩欧美亚洲| 欧美性视频网站| 在线免费观看成人网| 亚洲一区视频| 欧美激情精品久久久久久蜜臀| 一区二区三区日韩欧美| 美女999久久久精品视频| 麻豆91精品91久久久的内涵| 99国产一区| 欧美11—12娇小xxxx| 国产麻豆9l精品三级站| 亚洲国产精品欧美一二99| 欧美怡红院视频一区二区三区| 亚洲国产成人在线视频| 小黄鸭精品aⅴ导航网站入口| 欧美激情精品| 在线观看视频一区二区| 久久丁香综合五月国产三级网站| 亚洲日本欧美天堂| 美腿丝袜亚洲色图| 精品不卡视频| 久久嫩草精品久久久久|