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

elva

玩轉(zhuǎn)ptrace(一)

by Pradeep Padala
Created 2002-11-01 02:00
翻譯: Magic.D E-mail: adamgic@163.com
譯者序:在開發(fā)Hust Online Judge的過(guò)程中,查閱了不少資料,關(guān)于調(diào)試器技術(shù)的資料在網(wǎng)上是很少,即便是UNIX編程巨著《UNIX環(huán)境高級(jí)編程》中,相關(guān)內(nèi)容也不多,直到我在http://www.linuxjournal.com上找到這篇文章,如獲至寶,特翻譯之,作為鄙人翻譯技術(shù)文檔的第一次嘗試,必定會(huì)有不少蹩腳之處,各位就將就一下吧,歡迎大力拍磚。

你想過(guò)怎么實(shí)現(xiàn)對(duì)系統(tǒng)調(diào)用的攔截嗎?你嘗試過(guò)通過(guò)改變系統(tǒng)調(diào)用的參數(shù)來(lái)愚弄你的系統(tǒng)kernel嗎?你想過(guò)調(diào)試器是如何使運(yùn)行中的進(jìn)程暫停并且控制它嗎?
你 可能會(huì)開始考慮怎么使用復(fù)雜的kernel編程來(lái)達(dá)到目的,那么,你錯(cuò)了。實(shí)際上Linux提供了一種優(yōu)雅的機(jī)制來(lái)完成這些:ptrace系統(tǒng)函數(shù)。 ptrace提供了一種使父進(jìn)程得以監(jiān)視和控制其它進(jìn)程的方式,它還能夠改變子進(jìn)程中的寄存器和內(nèi)核映像,因而可以實(shí)現(xiàn)斷點(diǎn)調(diào)試和系統(tǒng)調(diào)用的跟蹤。
使用ptrace,你可以在用戶層攔截和修改系統(tǒng)調(diào)用(sys call)
在這篇文章中,我們將學(xué)習(xí)如何攔截一個(gè)系統(tǒng)調(diào)用,然后修改它的參數(shù)。在本文的第二部分我們將學(xué)習(xí)更先進(jìn)的技術(shù):設(shè)置斷點(diǎn),插入代碼到一個(gè)正在運(yùn)行的程序中;我們將潛入到機(jī)器內(nèi)部,偷窺和纂改進(jìn)程的寄存器和數(shù)據(jù)段。
 
基本知識(shí)
操 作系統(tǒng)提供了一種標(biāo)準(zhǔn)的服務(wù)來(lái)讓程序員實(shí)現(xiàn)對(duì)底層硬件和服務(wù)的控制(比如文件系統(tǒng)),叫做系統(tǒng)調(diào)用(system calls)。當(dāng)一個(gè)程序需要作系統(tǒng)調(diào)用的時(shí)候,它將相關(guān)參數(shù)放進(jìn)系統(tǒng)調(diào)用相關(guān)的寄存器,然后調(diào)用軟中斷0x80,這個(gè)中斷就像一個(gè)讓程序得以接觸到內(nèi)核 模式的窗口,程序?qū)?shù)和系統(tǒng)調(diào)用號(hào)交給內(nèi)核,內(nèi)核來(lái)完成系統(tǒng)調(diào)用的執(zhí)行。
 
在i386體系中(本文中所有的代碼都是面向i386體系),系統(tǒng)調(diào)用號(hào)將放入%eax,它的參數(shù)則依次放入%ebx, %ecx, %edx, %esi 和 %edi。 比如,在以下的調(diào)用
 
       Write(2, “Hello”, 5)
 
的匯編形式大概是這樣的


    movl $4, %eax
    movl $2, %ebx
    movl $hello, %ecx
    movl $5, %edx
    int $0x80
 

這里的$hello指向的是標(biāo)準(zhǔn)字符串”Hello”。
 
那么,ptrace會(huì)在什么時(shí)候出現(xiàn)呢?在執(zhí)行系統(tǒng)調(diào)用之前,內(nèi)核會(huì)先檢查當(dāng)前進(jìn)程是否處于被“跟蹤”(traced)的狀態(tài)。如果是的話,內(nèi)核暫停當(dāng)前進(jìn)程并將控制權(quán)交給跟蹤進(jìn)程,使跟蹤進(jìn)程得以察看或者修改被跟蹤進(jìn)程的寄存器。
 
讓我們來(lái)看一個(gè)例子,演示這個(gè)跟蹤程序的過(guò)程

 

#include <sys/ptrace.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
  #include <linux/user.h> /* For constants
                                    ORIG_EAX etc */

 int main()
  {
    pid_t child;
     long orig_eax;
     child = fork();
      if(child == 0) {
         ptrace(PTRACE_TRACEME, 0, NULL, NULL);
         execl("/bin/ls", "ls", NULL);
     }
      else {
         wait(NULL);
         orig_eax = ptrace(PTRACE_PEEKUSER,
                           child, 4 * ORIG_EAX,
                           NULL);
         printf("The child made a "
                "system call %ld ", orig_eax);
         ptrace(PTRACE_CONT, child, NULL, NULL);
     }
     return 0;
 }

運(yùn)行這個(gè)程序,將會(huì)在輸出ls命令的結(jié)果的同時(shí),輸出:
 
The child made a system call 11
 
說(shuō)明:11是execve的系統(tǒng)調(diào)用號(hào),這是該程序調(diào)用的第一個(gè)系統(tǒng)調(diào)用。
想知道系統(tǒng)調(diào)用號(hào)的詳細(xì)內(nèi)容,察看 /usr/include/asm/unistd.h。
 
在 以上的示例中,父進(jìn)程fork出了一個(gè)子進(jìn)程,然后跟蹤它。在調(diào)用exec函數(shù)之前,子進(jìn)程用PTRACE_TRACEME作為第一個(gè)參數(shù)調(diào)用了 ptrace函數(shù),它告訴內(nèi)核:讓別人跟蹤我吧!然后,在子進(jìn)程調(diào)用了execve()之后,它將控制權(quán)交還給父進(jìn)程。當(dāng)時(shí)父進(jìn)程正使用wait()函數(shù) 來(lái)等待來(lái)自內(nèi)核的通知,現(xiàn)在它得到了通知,于是它可以開始察看子進(jìn)程都作了些什么,比如看看寄存器的值之類。
 
出現(xiàn)系統(tǒng)調(diào)用之后,內(nèi)核會(huì)將eax中的值(此時(shí)存的是系統(tǒng)調(diào)用號(hào))保存起來(lái),我們可以使用PTRACE_PEEKUSER作為ptrace的第一個(gè)參數(shù)來(lái)讀到這個(gè)值。
我們察看完系統(tǒng)調(diào)用的信息后,可以使用PTRACE_CONT作為ptrace的第一個(gè)參數(shù),調(diào)用ptrace使子進(jìn)程繼續(xù)系統(tǒng)調(diào)用的過(guò)程。
 
ptrace函數(shù)的參數(shù)
 
Ptrace有四個(gè)參數(shù)
long ptrace(enum __ptrace_request request,
            pid_t pid,
            void *addr,
            void *data);
 
第一個(gè)參數(shù)決定了ptrace的行為與其它參數(shù)的使用方法,可取的值有:
PTRACE_ME
PTRACE_PEEKTEXT
PTRACE_PEEKDATA
PTRACE_PEEKUSER
PTRACE_POKETEXT
PTRACE_POKEDATA
PTRACE_POKEUSER
PTRACE_GETREGS
PTRACE_GETFPREGS,
PTRACE_SETREGS
PTRACE_SETFPREGS
PTRACE_CONT
PTRACE_SYSCALL,
PTRACE_SINGLESTEP
PTRACE_DETACH
在下文中將對(duì)這些常量的用法進(jìn)行說(shuō)明。
 
讀取系統(tǒng)調(diào)用的參數(shù)
 
通過(guò)將PTRACE_PEEKUSER作為ptrace 的第一個(gè)參數(shù)進(jìn)行調(diào)用,可以取得與子進(jìn)程相關(guān)的寄存器值。
 
先看下面這個(gè)例子

#include <sys/ptrace.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <linux/user.h>
  #include <sys/syscall.h> /* For SYS_write etc */
 
 int main()
  {
     pid_t child;
     long orig_eax, eax;
     long params[3];
     int status;
     int insyscall = 0;
     child = fork();
      if(child == 0) {
         ptrace(PTRACE_TRACEME, 0, NULL, NULL);
         execl("/bin/ls", "ls", NULL);
     }
      else {
         while(1) {
           wait(&status);
           if(WIFEXITED(status))
               break;
           orig_eax = ptrace(PTRACE_PEEKUSER,
                      child, 4 * ORIG_EAX, NULL);
            if(orig_eax == SYS_write) {
               if(insyscall == 0) {
                  /* Syscall entry */
                 insyscall = 1;
                 params[0] = ptrace(PTRACE_PEEKUSER,
                                    child, 4 * EBX,
                                    NULL);
                 params[1] = ptrace(PTRACE_PEEKUSER,
                                    child, 4 * ECX,
                                    NULL);
                 params[2] = ptrace(PTRACE_PEEKUSER,
                                    child, 4 * EDX,
                                    NULL);
                 printf("Write called with "
                        "%ld, %ld, %ld ",
                        params[0], params[1],
                        params[2]);
                 }
            else { /* Syscall exit */
                 eax = ptrace(PTRACE_PEEKUSER,
                              child, 4 * EAX, NULL);
                     printf("Write returned "
                            "with %ld ", eax);
                     insyscall = 0;
                 }
             }
             ptrace(PTRACE_SYSCALL,
                    child, NULL, NULL);
         }
     }
     return 0;
 }

這個(gè)程序的輸出是這樣的
 
ppadala@linux:~/ptrace > ls
a.out dummy.s ptrace.txt
libgpm.html registers.c syscallparams.c
dummy ptrace.html simple.c
ppadala@linux:~/ptrace > ./a.out
Write called with 1, 1075154944, 48
a.out dummy.s ptrace.txt
Write returned with 48
Write called with 1, 1075154944, 59
libgpm.html registers.c syscallparams.c
Write returned with 59
Write called with 1, 1075154944, 30
dummy ptrace.html simple.c
Write returned with 30
 

以上的例子中我們跟蹤了write系統(tǒng)調(diào)用,而ls命令的執(zhí)行將產(chǎn)生三個(gè)write系統(tǒng)調(diào)用。使用PTRACE_SYSCALL作為ptrace的 第一個(gè)參數(shù),使內(nèi)核在子進(jìn)程做出系統(tǒng)調(diào)用或者準(zhǔn)備退出的時(shí)候暫停它。這種行為與使用PTRACE_CONT,然后在下一個(gè)系統(tǒng)調(diào)用/進(jìn)程退出時(shí)暫停它是等 價(jià)的。
 
在前一個(gè)例子中,我們用PTRACE_PEEKUSER來(lái)察看write系統(tǒng)調(diào)用的參數(shù)。系統(tǒng)調(diào)用的返回值會(huì)被放入%eax。
 
wait函數(shù)使用status變量來(lái)檢查子進(jìn)程是否已退出。它是用來(lái)判斷子進(jìn)程是被ptrace暫停掉還是已經(jīng)運(yùn)行結(jié)束并退出。有一組宏可以通過(guò)status的值來(lái)判斷進(jìn)程的狀態(tài),比如WIFEXITED等,詳情可以察看wait(2) man。
 
讀取寄存器的值
 
如果你想在系統(tǒng)調(diào)用或者進(jìn)程終止的時(shí)候讀取它的寄存器,使用前面那個(gè)例子的方法是可以的,但是這是笨拙的方法。使用PRACE_GETREGS作為ptrace的第一個(gè)參數(shù)來(lái)調(diào)用,可以只需一次函數(shù)調(diào)用就取得所有的相關(guān)寄存器值。
獲得寄存器值得例子如下:

 

#include <sys/ptrace.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <linux/user.h>
 #include <sys/syscall.h>
 
 int main()
  {
     pid_t child;
     long orig_eax, eax;
     long params[3];
     int status;
     int insyscall = 0;
     struct user_regs_struct regs;
     child = fork();
      if(child == 0) {
         ptrace(PTRACE_TRACEME, 0, NULL, NULL);
         execl("/bin/ls", "ls", NULL);
     }
      else {
         while(1) {
           wait(&status);
           if(WIFEXITED(status))
               break;
           orig_eax = ptrace(PTRACE_PEEKUSER,
                             child, 4 * ORIG_EAX,
                             NULL);
            if(orig_eax == SYS_write) {
                if(insyscall == 0) {
                   /* Syscall entry */
                  insyscall = 1;
                  ptrace(PTRACE_GETREGS, child,
                         NULL, &regs);
                  printf("Write called with "
                         "%ld, %ld, %ld ",
                         regs.ebx, regs.ecx,
                         regs.edx);
              }
               else { /* Syscall exit */
                  eax = ptrace(PTRACE_PEEKUSER,
                               child, 4 * EAX,
                               NULL);
                  printf("Write returned "
                         "with %ld ", eax);
                  insyscall = 0;
              }
           }
           ptrace(PTRACE_SYSCALL, child,
                  NULL, NULL);
        }
    }
    return 0;
 }

這段代碼與前面的例子是比較相似的,不同的是它使用了PTRACE_GETREGS。 其中的user_regs_struct結(jié)構(gòu)是在<linux/user.h>中定義的。
 
 
來(lái)點(diǎn)好玩的
 
現(xiàn)在該做點(diǎn)有意思的事情了,我們將要把傳給write系統(tǒng)調(diào)用的字符串給反轉(zhuǎn)。

 

#include <sys/ptrace.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <linux/user.h>
 #include <sys/syscall.h>
 
 const int long_size = sizeof(long);
 
 void reverse(char *str)
  {
     int i, j;
     char temp;
     for(i = 0, j = strlen(str) - 2;
          i <= j; ++i, --j) {
         temp = str[i];
         str[i] = str[j];
         str[j] = temp;
     }
 }
 
 void getdata(pid_t child, long addr,
              char *str, int len)
  {
     char *laddr;
     int i, j;
      union u {
             long val;
             char chars[long_size];
     }data;
 
     i = 0;
     j = len / long_size;
     laddr = str;
      while(i < j) {
         data.val = ptrace(PTRACE_PEEKDATA,
                           child, addr + i * 4,
                           NULL);
         memcpy(laddr, data.chars, long_size);
         ++i;
         laddr += long_size;
     }
     j = len % long_size;
      if(j != 0) {
         data.val = ptrace(PTRACE_PEEKDATA,
                           child, addr + i * 4,
                           NULL);
         memcpy(laddr, data.chars, j);
     }
     str[len] = '';
 }
 
 void putdata(pid_t child, long addr,
              char *str, int len)
  {
     char *laddr;
     int i, j;
      union u {
             long val;
             char chars[long_size];
     }data;
 
     i = 0;
     j = len / long_size;
     laddr = str;
      while(i < j) {
         memcpy(data.chars, laddr, long_size);
         ptrace(PTRACE_POKEDATA, child,
                addr + i * 4, data.val);
         ++i;
         laddr += long_size;
     }
     j = len % long_size;
      if(j != 0) {
         memcpy(data.chars, laddr, j);
         ptrace(PTRACE_POKEDATA, child,
                addr + i * 4, data.val);
     }
 }
 
 int main()
  {
    pid_t child;
    child = fork();
     if(child == 0) {
       ptrace(PTRACE_TRACEME, 0, NULL, NULL);
       execl("/bin/ls", "ls", NULL);
    }
     else {
       long orig_eax;
       long params[3];
       int status;
       char *str, *laddr;
       int toggle = 0;
        while(1) {
          wait(&status);
          if(WIFEXITED(status))
              break;
          orig_eax = ptrace(PTRACE_PEEKUSER,
                            child, 4 * ORIG_EAX,
                            NULL);
           if(orig_eax == SYS_write) {
              if(toggle == 0) {
                toggle = 1;
                params[0] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * EBX,
                                   NULL);
                params[1] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * ECX,
                                   NULL);
                params[2] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * EDX,
                                   NULL);
                str = (char *)calloc((params[2]+1)
                                  * sizeof(char));
                getdata(child, params[1], str,
                        params[2]);
                reverse(str);
                putdata(child, params[1], str,
                        params[2]);
             }
              else {
                toggle = 0;
             }
          }
       ptrace(PTRACE_SYSCALL, child, NULL, NULL);
       }
    }
    return 0;
 }
輸出是這樣的:
 
ppadala@linux:~/ptrace > ls
a.out dummy.s ptrace.txt
libgpm.html registers.c syscallparams.c
dummy ptrace.html simple.c
ppadala@linux:~/ptrace > ./a.out
txt.ecartp s.ymmud tuo.a
c.sretsiger lmth.mpgbil c.llacys_egnahc
c.elpmis lmth.ecartp ymmud

這個(gè)例子中涵蓋了前面討論過(guò)的所有知識(shí)點(diǎn),當(dāng)然還有些新的內(nèi)容。這里我們用PTRACE_POKEDATA作為第一個(gè)參數(shù),以此來(lái)改變子進(jìn)程中的變量值。它以與PTRACE_PEEKDATA相似的方式工作,當(dāng)然,它不只是偷窺變量的值了,它可以修改它們。
 
單步
 
ptrace 提供了對(duì)子進(jìn)程進(jìn)行單步的功能。 ptrace(PTRACE_SINGLESTEP, …) 會(huì)使內(nèi)核在子進(jìn)程的每一條指令執(zhí)行前先將其阻塞,然后將控制權(quán)交給父進(jìn)程。下面的例子可以查出子進(jìn)程當(dāng)前將要執(zhí)行的指令。為了便于理解,我用匯編寫了這個(gè) 受控程序,而不是讓你為c的庫(kù)函數(shù)到底會(huì)作那些系統(tǒng)調(diào)用而頭痛。
 
以下是被控程序的代碼 dummy1.s,使用gcc  –o dummy1 dummy1.s來(lái)編譯

 

.data
hello:
    .string "hello world\n"
.globl main
main:
    movl $4, %eax
    movl $2, %ebx
    movl $hello, %ecx
    movl $12, %edx
    int $0x80
    movl $1, %eax
    xorl %ebx, %ebx
    int $0x80
    ret

以下的程序則用來(lái)完成單步:

 

#include <sys/ptrace.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <linux/user.h>
 #include <sys/syscall.h>
 int main()
  {
     pid_t child;
     const int long_size = sizeof(long);
     child = fork();
      if(child == 0) {
         ptrace(PTRACE_TRACEME, 0, NULL, NULL);
         execl("./dummy1", "dummy1", NULL);
     }
      else {
         int status;
          union u {
             long val;
             char chars[long_size];
         }data;
         struct user_regs_struct regs;
         int start = 0;
         long ins;
          while(1) {
             wait(&status);
             if(WIFEXITED(status))
                 break;
             ptrace(PTRACE_GETREGS,
                    child, NULL, &regs);
              if(start == 1) {
                 ins = ptrace(PTRACE_PEEKTEXT,
                              child, regs.eip,
                              NULL);
                 printf("EIP: %lx Instruction "
                        "executed: %lx ",
                        regs.eip, ins);
             }
              if(regs.orig_eax == SYS_write) {
                 start = 1;
                 ptrace(PTRACE_SINGLESTEP, child,
                        NULL, NULL);
             }
             else
                 ptrace(PTRACE_SYSCALL, child,
                        NULL, NULL);
         }
     }
     return 0;
 }

程序的輸出是這樣的:
你可能需要察看Intel的用戶手冊(cè)來(lái)了解這些指令代碼的意思。
更復(fù)雜的單步,比如設(shè)置斷點(diǎn),則需要很仔細(xì)的設(shè)計(jì)和更復(fù)雜的代碼才可以實(shí)現(xiàn)。
 
 
在第二部分,我們將會(huì)看到如何在程序中加入斷點(diǎn),以及將代碼插入到已經(jīng)在運(yùn)行的程序中

posted on 2009-07-25 17:45 葉子 閱讀(1555) 評(píng)論(5)  編輯 收藏 引用 所屬分類: Unix

Feedback

# re: 玩轉(zhuǎn)ptrace(一)[未登錄](méi) 2012-05-07 17:27 along

good job, guys  回復(fù)  更多評(píng)論   

# re: 玩轉(zhuǎn)ptrace(一) 2012-06-27 17:41 KIMBERLEYCRAWFORD

Do you understand that this is correct time to receive the <a href="http://goodfinance-blog.com">loan</a>, which can help you.   回復(fù)  更多評(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| 亚洲在线视频观看| 性欧美暴力猛交69hd| 一区二区三区精品视频在线观看 | 亚洲自拍另类| 欧美一区二区福利在线| 亚洲性av在线| 久久久久www| 欧美剧在线观看| 国产精品av一区二区| 国产精品资源在线观看| 国产一区二区三区免费观看 | 老司机精品视频一区二区三区| 久久超碰97中文字幕| 美国十次成人| 国产精品色网| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲黄色精品| 久久久久久久久伊人| 亚洲国产毛片完整版| 一区二区三区精品国产| 久久aⅴ国产欧美74aaa| 欧美电影在线| 狠狠色2019综合网| 亚洲看片免费| 蜜桃av综合| 午夜国产一区| 欧美视频不卡中文| 亚洲日产国产精品| 亚洲第一中文字幕| 久久精品卡一| 激情一区二区三区| 久久夜色精品国产亚洲aⅴ| 亚洲欧美国产另类| 国产精品毛片在线看| 亚洲一区在线免费| 一二三区精品| 国产精品v日韩精品| 久久一本综合频道| 亚洲激情在线观看视频免费| 久久中文欧美| 欧美成人免费播放| 亚洲视频二区| 性欧美xxxx大乳国产app| 国产免费亚洲高清| 久久综合网络一区二区| 久久久久成人网| 亚洲精品久久久一区二区三区| 久久先锋影音| 欧美日韩精品在线| 久久久99久久精品女同性| 久久九九热re6这里有精品| 亚洲国产精品一区在线观看不卡 | 亚洲欧洲一区二区天堂久久| 欧美岛国在线观看| 国产精品久久久久久久久动漫| 先锋影音久久久| 久久精品一区二区国产| 99视频热这里只有精品免费| 亚洲网站在线播放| 99在线精品观看| 久久精品导航| 久久久久久久尹人综合网亚洲 | 欧美一区二视频| 最新成人av在线| 久久精品亚洲精品国产欧美kt∨| 亚洲人成网在线播放| 欧美一级播放| 性伦欧美刺激片在线观看| 欧美α欧美αv大片| 国产日韩精品在线| 亚洲在线观看视频| 亚洲欧美综合一区| 国产精品区一区二区三| 在线亚洲美日韩| 亚洲男女自偷自拍| 国产精品极品美女粉嫩高清在线| 欧美激情第10页| 亚洲美女视频网| 欧美日韩视频在线一区二区| 亚洲黄网站在线观看| 亚洲精品乱码久久久久久蜜桃麻豆 | 久久se精品一区精品二区| 国产精品大片| 午夜天堂精品久久久久| 久久视频在线看| 亚洲高清二区| 欧美日韩国产色站一区二区三区| 一本色道久久精品| 久久视频在线免费观看| 亚洲第一精品久久忘忧草社区| 久久精品视频在线| 999亚洲国产精| 免费久久精品视频| 亚洲一区二区三区视频| 在线免费不卡视频| 国产精品日韩在线播放| 欧美大片在线看| 久久综合色播五月| 亚洲天堂久久| 99综合电影在线视频| 欧美黄免费看| 老司机久久99久久精品播放免费| 亚洲午夜激情免费视频| 亚洲综合色视频| 亚洲精品乱码久久久久久蜜桃91| 久久9热精品视频| 一区二区三区四区国产| 亚洲三级视频| 亚洲国产欧美另类丝袜| 精品1区2区3区4区| 精品动漫3d一区二区三区| 国产精品免费看| 欧美性猛交99久久久久99按摩 | 欧美精品一区二区在线播放| 久久精品中文字幕一区| 亚洲欧美日韩一区二区三区在线观看 | 欧美亚洲综合网| 欧美一区二区三区免费看| 久久精品视频va| 欧美国产成人精品| 国产精品家庭影院| 国产一区二区三区四区三区四| 国产欧美日韩综合一区在线观看 | 亚洲国产一成人久久精品| 亚洲韩国精品一区| 亚洲精品免费电影| 亚洲欧美一区在线| 玖玖精品视频| 国产精品大片| 亚洲国产精品久久久久久女王| 亚洲国产欧美国产综合一区| 亚洲午夜久久久久久久久电影院| 中文亚洲欧美| 欧美不卡视频一区发布| 激情久久久久久久| 亚洲欧洲三级| 欧美在线视频a| 亚洲乱码视频| 久久精品理论片| 国产精品视频精品视频| 亚洲国产精品久久91精品| 午夜视频在线观看一区| 亚洲高清一二三区| 久久久久久久一区二区| 欧美日韩在线一区| 亚洲人成人77777线观看| 免费不卡欧美自拍视频| 亚洲欧美视频一区| 国产精品成人播放| 亚洲免费人成在线视频观看| 欧美成人dvd在线视频| 久久国产免费| 有坂深雪在线一区| 亚洲成人资源| 欧美巨乳在线| 欧美一区二区三区另类| 午夜精品在线观看| 国产一区二区三区在线免费观看| 久久电影一区| 久久躁日日躁aaaaxxxx| 亚洲精品欧美精品| 中文国产成人精品| 伊人久久综合| 99在线热播精品免费| 国产欧美日韩精品一区 | 狠狠入ady亚洲精品| 欧美成人综合网站| 欧美午夜精品久久久久久孕妇| 亚洲伊人伊色伊影伊综合网 | 洋洋av久久久久久久一区| 在线视频免费在线观看一区二区| 国产一区二区三区久久 | 亚洲最黄网站| 欧美怡红院视频| 中文成人激情娱乐网| 亚洲欧美日韩系列| 蜜桃av一区二区三区| 亚洲永久免费观看| 牛牛国产精品| 免费不卡中文字幕视频| 国产精品女人毛片| 亚洲国产精品电影| 在线观看成人一级片| 香蕉av福利精品导航| 亚洲性图久久| 欧美日韩日本网| 亚洲精品日韩久久| 亚洲精品视频一区| 欧美成人一区二免费视频软件| 久久色中文字幕| 激情成人av| 久色成人在线| 一区二区三区精密机械公司 | 亚洲男人的天堂在线aⅴ视频| 99热精品在线| 国产精品美女午夜av| 篠田优中文在线播放第一区|