精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何用幾行代碼免重啟修復(fù)應(yīng)用程序BUG?(一)

企業(yè)動態(tài)
UCloud生而為云,一直專注在云計算的泥潭里摸爬滾打,踩過數(shù)不清的坑,寫過數(shù)不清的BUG。所幸,在不斷的試錯中,也錘煉出一些能在江湖傍身的大殺器。這些經(jīng)過千錘百煉的大殺器和寶貴的踩坑經(jīng)驗,一起成為今天UCloud的核心科技。

引言

千呼萬喚始出來,從今天起,《UCloud技術(shù)大觀園》系列正式開張,撒花╭(●`∀´●)╯!

UCloud生而為云,一直專注在云計算的泥潭里摸爬滾打,踩過數(shù)不清的坑,寫過數(shù)不清的BUG。所幸,在不斷的試錯中,也錘煉出一些能在江湖傍身的大殺器。這些經(jīng)過千錘百煉的大殺器和寶貴的踩坑經(jīng)驗,一起成為今天UCloud的核心科技。

現(xiàn)在,我們將在《UCloud技術(shù)大觀園》系列里,把這些核心科技全部開放出來,毫無保留,逐一為大家講解,哪些坑是我們已經(jīng)踩過的,引以為誡,哪些是優(yōu)質(zhì)的技術(shù)實踐經(jīng)驗,值得借鑒。

我們始終相信——開放,才是技術(shù)的本心。

本篇作為《UCloud技術(shù)大觀園》系列的開篇,聚焦UCloud應(yīng)用程序熱補丁技術(shù),將介紹一種簡單實用的應(yīng)用程序熱補丁技術(shù)。不少場景下,用該方法編寫幾行代碼即可免修復(fù)應(yīng)用程序BUG!

那,我們開始吧~

前言

應(yīng)用程序,作為核心業(yè)務(wù)組件,每天都面臨著嚴(yán)峻的高可用挑戰(zhàn),每次重啟,都會導(dǎo)致服務(wù)受損。尤其是單點的虛擬化組件和有狀態(tài)的應(yīng)用程序,一旦重啟,影響更甚。

熱補丁,一種在程序運行時動態(tài)修復(fù)內(nèi)存中代碼bug的技術(shù),能避免系統(tǒng)重啟導(dǎo)致的業(yè)務(wù)中斷、有效保證操作系統(tǒng)的可用性。

經(jīng)過大量的研究和實踐,UCloud從0到1,自研了一套應(yīng)用程序熱補丁技術(shù)。千錘百煉出真金,經(jīng)過內(nèi)部數(shù)十萬臺次修復(fù)驗證,UCloud應(yīng)用程序熱補丁技術(shù)已自成體系,成為UCloud核心黑科技之一。

原理

一般來說,應(yīng)用程序熱補丁的流程是,首先通過編譯器將熱補丁源碼制作成可加載的動態(tài)鏈接庫,然后通過加載程序?qū)嵫a丁加載到目標(biāo)進程的地址空間,***在進行一致性模型檢查確認(rèn)安全的情況下,把原始代碼替換成新的代碼,完成在線修復(fù)的過程。

下面我們分別介紹熱補丁本身和熱補丁加載程序,熱補丁本身是因patch而異的,加載程序是通用的。

假設(shè)我們有熱補丁加載程序Loader、目標(biāo)進程T、熱補丁patch.so,目標(biāo)程序的func函數(shù)替換為func_v2。

熱補丁

  1. 編寫熱補丁源碼,編譯成動態(tài)鏈接庫的格式的熱補丁patch.so,patch.so中包含func和func_v2的信息。
  2. 熱補丁patch.so在被加載程序Loader加載到目標(biāo)進程T地址空間的過程中,通過dlsym調(diào)用找到func的地址,并將func的入口指令改為可寫,同時改變?yōu)樘D(zhuǎn)到func_v2。
  3. 至此,所有對func的調(diào)用都會被重定向到func_v2,func_v2執(zhí)行完畢后返回,程序繼續(xù)運行。
  4. 如圖所示:

熱補丁加載程序

  1. 加載程序Loader找到目標(biāo)進程T的dlopen函數(shù)入口地址。
  2. Loader通過ptrace依附到目標(biāo)進程T,Loader將熱補丁的名字放入放入目標(biāo)進程T的堆棧,將IP寄存器設(shè)置為dlopen函數(shù)的地址。
  3. Loader使目標(biāo)進程T繼續(xù)運行。因為IP寄存器已經(jīng)設(shè)置為dlopen函數(shù)的入口,目標(biāo)進程T會調(diào)用dlopen把熱補丁加載到T的地址空間中。
  4. 如圖所示:

了解原理之后,我們一步步實現(xiàn)一種簡單的基于x86_64的熱補丁。

(對于需要制作熱補丁的同學(xué),只需自己編寫patch.so,而Loader是通用的。patch.so編寫可以參考下面的例子,往往只需幾行代碼做相應(yīng)替換。)

實現(xiàn)

熱補丁

1.目標(biāo)進程T執(zhí)行dlopen的過程中,通過預(yù)先在熱補丁(動態(tài)鏈接庫)中寫入的constructor函數(shù),在加載過程中函數(shù)func_v1替換函數(shù)func。

  1. static void __attribute__((constructor)) init(void) 
  2.  { 
  3.      int numpages; 
  4.      void *old_func_entry, *new_func_entry; 
  5.  
  6.      old_func_entry = dlsym(NULL"func"); 
  7.      new_func_entry = dlsym(NULL"func_v2"); 
  8.  
  9.      #define PAGE_SHIFT              12 
  10.      #define PAGE_SIZE               (1UL << PAGE_SHIFT) 
  11.      #define PAGE_MASK               (~(PAGE_SIZE-1)) 
  12.  
  13.      numpages = (PAGE_SIZE - (old_func_entry & ~PAGE_MASK) >= size) ? 1 : 2; 
  14.      mprotect((void *)(old_func_entry & PAGE_MASK), numpages * PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC); 
  15.  
  16.      /* 
  17.       * Translate the following instructions  
  18.       *  
  19.       * mov $new_func_entry, %rax  
  20.       * jmp %rax  
  21.       *  
  22.       * into machine code  
  23.       *  
  24.       * 48 b8 xx xx xx xx xx xx xx xx  
  25.       * ff e0  
  26.       */ 
  27.      memset(old_func_entry, 0x48, 1); 
  28.      memset(old_func_entry + 1, 0xb8, 1);  
  29.      memcpy(old_func_entry + 2, &new_func_entry, 8);  
  30.      memset(old_func_entry + 10, 0xff, 1); 
  31.      memset(old_func_entry + 11, 0xe0, 1); 
  32.  } 

熱補丁加載程序

1.Loader得到目標(biāo)進程T地址空間中dlopen入口地址

1.1. dlopen函數(shù)有l(wèi)ibdl提供,并不是所有的程序都加載libdl,幸運的是,libc中提供了同樣功能的函數(shù)libc_dlopen_mode,并且接受的參數(shù)和dlopen相同。除非特殊情況,所有程序都會加載libc。所以我們需要找到libc_dlopen_mode在目標(biāo)進程T地址空間中的函數(shù)入口地址。

1.2. 我們知道,不同進程中l(wèi)ibc會被加載到不同的基地址,但是libc中函數(shù)的地址相對基地址的偏移是不變的。

1.3. 通過Loader和目標(biāo)進程T的/proc/pid/maps,我們可以得到libc在Loader和目標(biāo)進程T中加載的基地址。通過Loader運行dlsym,我們可以得到Loader中的libc_dlopen_mode的地址。這樣我們可以得到目標(biāo)進程T中l(wèi)ibc_dlopen_mode的地址(Loader_dlopen - Loader_libc + T_libc)。

  1. / Take a hint and find start addr in /proc/pid/maps / 
  2.   static unsigned long find_lib_base(pid_t pid, char *so_hint) 
  3.   { 
  4.   FILE *fp; 
  5.   char maps[4096], mapbuf[4096], perms[32], libpath[4096]; 
  6.   char *libname; 
  7.   unsigned long start, end, file_offset, inode, dev_major, dev_minor; 
  8.  
  9.   sprintf(maps, "/proc/%d/maps", pid); 
  10.   fp = fopen(maps, "rb"); 
  11.   if (!fp) { 
  12.           fprintf(stderr, "Failed to open %s: %s\n", maps, strerror(errno)); 
  13.           return 0; 
  14.   } 
  15.  
  16.   while (fgets(mapbuf, sizeof(mapbuf), fp)) { 
  17.           sscanf(mapbuf, "%lx-%lx %s %lx %lx:%lx %lu %s", &start, 
  18.                   &end, perms, &file_offset, &dev_major, &dev_minor, &inode, libpath); 
  19.  
  20.           libname = strrchr(libpath, '/'); 
  21.           if (libname) 
  22.                   libname++; 
  23.           else 
  24.                   continue
  25.  
  26.           if (!strncmp(perms, "r-xp", 4) && strstr(libname, so_hint)) { 
  27.                   fclose(fp); 
  28.                   return start; 
  29.           } 
  30.   } 
  31.  
  32.   fclose(fp);   return 0;  
  33.   } 
  34.   loader_libc = find_lib_base(getpid(), “libc-c”); 
  35.   T_libc = find_lib_base(T_pid, “libc-“); 
  36.   Loader_dlopen = (unsigned long)dlsym(NULL, “__libc_dlopen_mode”); 
  37.   T_dlopen = T_libc + (Loader_dlopen - Loader_libc); 

2.Loader對目標(biāo)進程T使用ptrace attach,并保存T此時的寄存器信息。

  1. static int ptrace_attach(pid_t pid) 
  2.   { 
  3.   int status; 
  4.  
  5.   if (ptrace(PTRACE_ATTACH, pid, NULLNULL)) { 
  6.           fprintf(stderr, "Failed to ptrace_attach: %s\n", strerror(errno)); 
  7.           return 1; 
  8.   } 
  9.  
  10.   if (waitpid(pid, &status, __WALL) < 0) { 
  11.           fprintf(stderr, "Failed to wait for PID %d, %s\n", pid, strerror(errno)); 
  12.           return 1; 
  13.   } 
  14.   return 0; 
  15.   static int ptrace_call(pid_t pid, unsigned long func_addr, unsigned long arg1, unsigned long arg2, unsigned long *func_ret) 
  16.   { 
  17.   … 
  18.   memset(&saved_regs, 0, sizeof(struct user_regs_struct)); 
  19.   ptrace_getregs(pid, &saved_regs); 
  20.  
  21.   … 
  22.   } 

3.將目標(biāo)進程T的%RIP指向dlopen,熱補丁的名字的字符串放入堆棧,字符串的地址寫入%rdi,RTLD_NOW的值寫入%rsi作為dlopen的flag。同時把dlopen返回地址設(shè)置為非法地址0x0(把0x0壓入棧中),這樣Loader可以捕獲目標(biāo)進程T產(chǎn)生的SIGSEGV信號進而重新獲得T的控制權(quán)。

  1. unsigned long invalid = 0x0; 
  2.  regs.rsp -= sizeof(invalid); 
  3.  ptrace_poketext(pid, regs.rsp, ((void *)&invalid), sizeof(invalid)); 
  4.  ptrace_poketext(pid, regs.rsp + 512, filename, strlen(filename) + 1); 
  5.  regs.rip = dlopen_addr; 
  6.  regs.rdi = regs.rsp + 512; 
  7.  regs.rsi = RTLD_NOW; 
  8.  ptrace_setregs(pid, &regs); 

4.Loader使目標(biāo)進程T繼續(xù)運行。當(dāng)T執(zhí)行完dlopen之后,T產(chǎn)生的SIGSEGV信號被Loader捕獲,Loader重新獲得T進程的控制權(quán)。

  1. static int ptrace_cont(pid_t pid) 
  2.  
  3. {int status; 
  4.  
  5. if (ptrace(PTRACE_CONT, pid, NULL, 0)) { 
  6.  
  7. fprintf(stderr, "Failed to ptrace_cont: %s\n", strerror(errno));return 1; 
  8.  
  9.  
  10. if (waitpid(pid, &status, __WALL) < 0) {fprintf(stderr, "Failed to wait for PID %d, %s\n", pid, strerror(errno)); 
  11.  
  12. return 1;} 
  13. return 0;} 

5. Loader通過讀取目標(biāo)進程T此時的%rax寄存器得到dlopen的返回值,恢復(fù)T最開始的執(zhí)行狀態(tài),***釋放對T的控制

  1. ptrace_getregs(pid, &regs); 
  2.   dlopen_ret = regs.rax; 
  3.   ptrace_setregs(pid, &saved_regs); 
  4.   ptrace_detach(pid); 

至此對目標(biāo)進程T的熱補丁就完成了。下面我們看一個例子。

驗證

假設(shè)我們運行target程序,每隔一秒打印Hello一次:

  1. # ./target 
  2. Hello 
  3. Hello 
  4. … 
  5. target程序由tar 

target程序由target本身和libold.so組成,分別代碼如下:

  1. /* target.c */ 
  2. #include <unistd.h> 
  3. #include "old.h" 
  4.  
  5. int main() { 
  6.     for (;;) { 
  7.         print(); 
  8.         sleep(1); 
  9.     } 
  10.  
  11. /* old.c */ 
  12. #include <stdio.h> 
  13.  
  14. void print(void) 
  15.     printf("Hello\n"); 

編譯

  1. gcc -fPIC --shared old.c -o libold.so  
  2. gcc target.c ./libold.so -o target 

我們想要修改print函數(shù),變成打印“Goodbye”。我們需要編寫熱補丁new.c,并添加新函數(shù)和constructor:

  1. /* new.c */ 
  2. #include <stdio.h> 
  3.     #include <string.h>  
  4. #include <sys/mman.h>  
  5. #include <dlfcn.h>  
  6.  
  7. print_v2(void) 
  8.     printf("Goodbye\n"); 
  9.  
  10. static void __attribute__((constructor)) init(void) 
  11. {  
  12.     int numpages; 
  13.     void *old_func_entry, *new_func_entry; 
  14.  
  15.     old_func_entry = dlsym(NULL, print); 
  16.     new_func_entry = dlsym(NULL, print_v2); 
  17.  
  18.     #define PAGE_SHIFT              12  
  19.     #define PAGE_SIZE               (1UL << PAGE_SHIFT)  
  20.     #define PAGE_MASK               (~(PAGE_SIZE-1)) 
  21.  
  22.     numpages = (PAGE_SIZE - (old_func_entry & ~PAGE_MASK) >= size) ? 1 : 2; 
  23.     mprotect((void *)(old_func_entry & PAGE_MASK), numpages * PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC); 
  24.     memset(old_func_entry, 0x48, 1); 
  25.     memset(old_func_entry + 1, 0xb8, 1);  
  26.     memcpy(old_func_entry + 2, &new_func_entry, 8);  
  27.     memset(old_func_entry + 10, 0xff, 1); 
  28.     memset(old_func_entry + 11, 0xe0, 1); 
  29. }  

編譯:

  1. gcc -fPIC --shared new.c -ldl -o libnew.so 

然后通過加載程序?qū)arget進程打入熱補丁libnew.so,***我們對target程序打入這個熱補丁,觀察變化:

  1. # ./target 
  2. Hello 
  3. Hello 
  4. Goodbye 
  5. Goodbye 
  6. … 

我們發(fā)現(xiàn)熱補丁確實改變了print函數(shù),***通過gdb進一步確認(rèn),可以看出print函數(shù)的入口被修改成48 b8 dc b6 15 a9 c1 7f 00 00 ff e0,與我們的預(yù)期相符:

  1. (gdb) disas /r print 
  2. Dump of assembler code for function print: 
  3.    0x00007fc1a98f456c <+0>:     48 b8 dc b6 15 a9 c1 7f 00 00   movabs $0x7fc1a915b6dc,%rax 
  4.    0x00007fc1a98f4576 <+10>:    ff e0   jmpq   *%rax # 這里print在入口處跳轉(zhuǎn)到0x7fc1a915b6dc這個地址 
  5. … 
  6. (gdb) info symbol 0x7fc1a915b6dc 
  7. print_v2 in section .text of /root/process-hotupgrade/test/libnew.so # 0x7f2ea417971c這個地址就是print_v2函數(shù)的地址 

總結(jié)

我們介紹了應(yīng)用程序熱補丁的基本原理,實踐了一個應(yīng)用程序熱補丁demo。此類熱補丁適用于動態(tài)替換共享鏈接庫中的可見函數(shù),可以修復(fù)例如glibc “GHOST漏洞”(CVE-2015-0235)等等,在UCloud我們利用熱補丁修復(fù)了若干缺陷,在用戶沒有感知的情況下把bug快速及時的修復(fù)。這些熱補丁修復(fù)程序里,絕大多數(shù)代碼是通用的,只需少數(shù)幾行做特殊替換。

上文介紹的熱補丁技術(shù)對于適用的場景非常理想,簡單可靠,但存在幾個缺點:

  • 手寫熱補丁代碼門檻較高,特別是被修復(fù)函數(shù)的依賴函數(shù)鏈較長時手寫熱補丁很容易出錯
  • 無法修復(fù)局部函數(shù)和局部變量(只能修復(fù)全局可見的函數(shù)和變量)

【本文是51CTO專欄機構(gòu)作者“大U的技術(shù)課堂”的原創(chuàng)文章,轉(zhuǎn)載請通過微信公眾號(ucloud2012)聯(lián)系作者】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2017-06-07 23:15:30

應(yīng)用程序熱補丁代碼

2017-06-07 23:33:01

應(yīng)用程序熱補丁代碼

2013-02-22 09:28:45

MEAP軟件移動應(yīng)用開發(fā)HTML5

2024-10-16 08:23:15

大型語言模型LLM機器學(xué)習(xí)

2023-12-21 08:00:00

ChatGPT人工智能大型語言模型

2014-03-04 09:22:24

bug程序員

2011-12-03 20:25:53

2014-06-20 10:37:47

LAN帶寬

2011-07-21 16:19:30

iOS Twitter

2022-09-19 00:37:13

SaaS云計算開發(fā)

2011-06-07 09:36:41

BlackBerry 應(yīng)用程序

2015-11-05 10:16:33

2024-10-10 13:30:00

2013-02-21 14:14:40

開發(fā)Tizen

2025-08-27 08:12:21

2021-05-17 07:45:06

Linux系統(tǒng)程序

2013-11-19 15:35:01

2017-12-10 14:13:14

云服務(wù)云原生應(yīng)用程序

2010-02-05 18:21:24

Android應(yīng)用程序

2012-06-11 09:37:41

點贊
收藏

51CTO技術(shù)棧公眾號

日本丶国产丶欧美色综合| 综合久草视频| 久久久久国产精品一区二区| 亚洲天堂av电影| 成人日韩在线视频| 九色视频在线观看免费播放| 亚洲精品偷拍| 亚洲性无码av在线| 色18美女社区| 国模私拍一区二区国模曼安| 久久免费视频色| 欧美最猛黑人xxxx黑人猛叫黄| 亚洲码无人客一区二区三区| 亚洲精品555| 一区二区视频在线| 日本午夜一区二区三区| 中文字幕 日韩有码| 911精品美国片911久久久| 亚洲精品99久久久久| 免费人成自慰网站| 在线激情免费视频| 91丝袜国产在线播放| 91香蕉国产在线观看| 国产污视频在线观看| 免费成人av| 日韩欧美一区在线观看| 91蝌蚪视频在线观看| 青青青草视频在线| 国产精品福利在线播放| julia一区二区中文久久94| 中文字幕 国产精品| 亚洲特色特黄| 两个人的视频www国产精品| 亚洲国产果冻传媒av在线观看| 国产精一区二区| 91国偷自产一区二区三区成为亚洲经典| 香蕉久久免费影视| 国产中文字幕在线观看| 国产另类ts人妖一区二区| 色综合色综合久久综合频道88| 能直接看的av| 精品国产精品久久一区免费式| 亚洲黄色免费三级| 黄色三级视频在线播放| 欧美一级二级视频| 色综合视频在线观看| 缅甸午夜性猛交xxxx| 欧美videos另类精品| 国产精品区一区二区三区| 国产精品一区二区a| 中文字幕在线观看精品| 日韩激情一区二区| 欧美一二三视频| 久久久久久av无码免费网站| 久久久久久久久久久9不雅视频| 永久免费看mv网站入口亚洲| 人妻丰满熟妇av无码久久洗澡| 极品国产人妖chinesets亚洲人妖| 日韩欧美一区二区三区在线| 免费黄视频在线观看| 国产精品一区二区三区四区在线观看 | 一区二区在线观看不卡| 女女百合国产免费网站| 韩国av免费在线| 国产成人精品www牛牛影视| 2019国产精品视频| 国产福利第一页| 国产一区视频导航| 国产精品第一页在线| 久久久久精彩视频| 另类人妖一区二区av| 成人网在线观看| 久久这里只有精品9| 免费欧美在线视频| 国产这里只有精品| 精品人妻午夜一区二区三区四区 | 黄色国产在线观看| 精品色999| 久久精品成人动漫| 久久精品国产亚洲av香蕉| 精品动漫3d一区二区三区免费版| 97在线日本国产| www欧美在线| 日韩影院免费视频| 91精品视频一区| www.五月激情| www.欧美色图| 日韩在线三级| 日本色护士高潮视频在线观看| 精彩国产在线| 99热免费精品在线观看| 欧美最猛性xxxx| 91麻豆一区二区| 国产精品一区专区| 久久国产精品一区二区三区 | 欧美白人最猛性xxxxx69交| 亚洲欧美日韩偷拍| 成人在线免费观看网站| 欧美高清视频在线观看| 亚洲国产av一区二区三区| 久久www免费人成看片高清| 国产精品久久久久久久天堂第1集| 蜜桃视频在线观看网站| 亚洲精品成人a在线观看| 欧美 日韩 国产一区| 三级成人黄色影院| 日韩欧美亚洲另类制服综合在线| 免费看黄色aaaaaa 片| 99久久综合狠狠综合久久aⅴ| 国语自产在线不卡| 在线观看日批视频| 成人动漫精品一区二区| 一区二区不卡视频| 日本蜜桃在线观看视频| 欧美情侣在线播放| 亚洲精品乱码久久久久久久| 亚洲欧美综合久久久| 日本精品视频网站| 羞羞色院91蜜桃| 91亚洲午夜精品久久久久久| 日韩女优中文字幕| 欧美13videosex性极品| 欧美一级在线观看| 中国美女乱淫免费看视频| 欧美女激情福利| 成人a在线观看| 手机看片1024国产| 一区二区三区四区不卡视频 | 日韩精品久久久久久久| 国产一区二区三区精品欧美日韩一区二区三区| 国产精品三区四区| 国产在线观看网站| 欧美性猛交xxxx| 99re这里只有| 国产中文一区| 北条麻妃高清一区| a级影片在线| 欧美二区乱c少妇| 国产精品一二三区在线观看| 欧美日本精品| 成人av免费在线看| www.狠狠爱| 国产一二三在线观看| 亚洲一区在线观看免费| 午夜大片在线观看| 亚洲va久久| 日本高清+成人网在线观看| 肥臀熟女一区二区三区| 欧美激情一区二区三区| 波多野结衣天堂| 精品素人av| 69视频在线免费观看| 少妇人妻偷人精品一区二区| 亚洲综合一区二区三区| 久久久无码人妻精品无码| 欧美精品网站| 国产伦精品一区二区三区四区免费| 精品黄色免费中文电影在线播放 | 黄色网络在线观看| **欧美日韩在线| 欧美猛交免费看| 免费看黄色一级视频| 午夜成人免费视频| 97香蕉碰碰人妻国产欧美 | 三级在线观看网站| 午夜精品免费在线| 国产中年熟女高潮大集合| 久久一区国产| 一区二区日本| 北条麻妃一区二区三区在线观看 | 黄色片网站在线免费观看| 久久久午夜电影| 成年人免费大片| 99精品视频在线观看播放| 97人人做人人人难人人做| www久久日com| 亚洲国产美女久久久久| 无码人妻一区二区三区免费| 国产欧美日产一区| 佐山爱在线视频| 国产字幕视频一区二区| 欧美亚洲另类久久综合| www.成人| 91a在线视频| 欧美精品videos另类| 精品国偷自产国产一区| 欧美一区二区三区久久久| 中日韩免费视频中文字幕| 日本少妇一级片| 男女精品视频| 四虎永久在线精品免费一区二区| 日韩一区二区三免费高清在线观看| 欧美福利在线观看| 91社区在线| 欧美一区二区在线观看| 亚洲免费黄色网址| 亚洲精品亚洲人成人网在线播放| 能看毛片的网站| 国产欧美午夜| 亚洲成人一区二区三区| 国内精品麻豆美女在线播放视频 | 国产高清亚洲| **欧美日韩vr在线| 成人影院在线观看| 亚洲国产精品嫩草影院久久| 亚洲综合精品视频| 欧美视频在线免费看| 欧美人与禽zozzo禽性配| 久久品道一品道久久精品| 色哟哟精品视频| 日韩一级不卡| eeuss中文| 成人3d精品动漫精品一二三| 国产专区一区二区| 欧美a级大片在线| 国产免费亚洲高清| 欧美gay囗交囗交| 久久久久久久一| 国产黄在线看| 日韩精品视频在线观看免费| www.av网站| 在线播放中文字幕一区| 黄色片视频免费| 天天综合色天天| 九九免费精品视频| 国产精品乱码人人做人人爱| 成人区人妻精品一区二| 国产精品资源网| 奇米影音第四色| 国产视频一区三区| 国产在线播放观看| 亚洲国产精品一区制服丝袜| 超碰10000| 亚洲国产一成人久久精品| 五月天国产一区| 精品国产一区二区三区小蝌蚪| 久久本道综合色狠狠五月| 成人av综合网| 国产精品国产精品国产专区蜜臀ah| 久久久久久爱| 成人h片在线播放免费网站| 国产精品高清乱码在线观看| 国内精品小视频| 捆绑调教日本一区二区三区| 性欧美xxxx交| 少妇视频一区| 欧洲美女7788成人免费视频| 成人一区福利| 国产精品88a∨| 123成人网| 日本精品久久久久影院| 国产经典一区| 国产欧美日韩视频| 成人啊v在线| 国产精品亚发布| 99亚洲男女激情在线观看| 91麻豆国产语对白在线观看| 日韩一级特黄| 97超碰人人看人人 | 亚洲最大成人综合网| 日本一区二区成人在线| 无码人妻精品一区二区三应用大全| 国产成人亚洲综合a∨婷婷| 亚洲av无一区二区三区久久| 国产91精品露脸国语对白| 中文字幕人妻一区| 97精品电影院| 老牛影视av老牛影视av| 中文字幕精品一区二区精品绿巨人 | 国产精品网在线观看| 噜噜噜噜噜久久久久久91| 国产乱码精品一区二区亚洲 | zjzjzjzjzj亚洲女人| 99久久99久久精品免费看蜜桃| 久久久久久久久久久国产精品| 北岛玲一区二区三区四区| 久久久久9999| 亚洲欧美综合另类在线卡通| 日韩免费一二三区| 色呦呦网站一区| 在线观看毛片网站| 亚洲缚视频在线观看| 天堂8在线视频| 中文字幕一区二区三区电影| 欧美韩日亚洲| 日韩美女在线观看一区| 草民电影神马电影一区二区| 91原创国产| 婷婷五月色综合香五月| youjizz.com亚洲| 99精品国产99久久久久久福利| 成人一级片网站| 国产乱子轮精品视频| 国产欧美视频一区| 久久夜色精品国产噜噜av| 欧美肥妇bbwbbw| 欧美性猛交xxxx久久久| 久久久久久在线观看| 在线播放国产精品二区一二区四区| 五月婷婷六月丁香综合| 精品国产一区二区三区久久久| 羞羞电影在线观看www| 国产国语videosex另类| 一区二区三区免费在线看| 日韩精品久久一区二区三区| 91精品啪在线观看国产81旧版| www黄色av| 成人黄色av电影| 亚洲成人网在线播放| √…a在线天堂一区| 2025国产精品自拍| 日本韩国欧美一区| 国产哺乳奶水91在线播放| 伊人青青综合网站| 麻豆成全视频免费观看在线看| 91香蕉亚洲精品| 亚洲精品蜜桃乱晃| 亚洲精品无人区| 六月婷婷一区| av电影在线播放| 一区二区三区高清不卡| 亚洲欧美日韩一区二区三区四区| 亚洲精品在线网站| yellow91字幕网在线| 成人黄色网免费| 在线免费观看黄色av| 日本一区二区三区久久久久久久久不| 91视频免费看片| 91福利视频在线| 久久经典视频| 欧美在线视频免费| 午夜精品福利影院| 日韩免费一级视频| 国产成人三级在线观看| 黑人狂躁日本娇小| 欧美午夜电影在线播放| 少妇性bbb搡bbb爽爽爽欧美| 91国语精品自产拍在线观看性色 | 亚洲av无码一区二区二三区| 亚洲一区二区三区四区的| av男人天堂网| 欧美成人在线网站| 青草伊人久久| 污污污污污污www网站免费| 国产黄色成人av| 精品在线视频观看| 精品国产1区二区| 国产在线1区| 成人激情视频在线| 中文字幕一区二区av| 免费不卡av网站| 亚洲精品国产精品乱码不99| 国产高清免费观看| 色综合久久精品亚洲国产| 91成人噜噜噜在线播放| cao在线观看| 2欧美一区二区三区在线观看视频| 可以免费看的av毛片| 亚洲女人初尝黑人巨大| 1234区中文字幕在线观看| 免费99视频| 美女视频黄久久| 免费在线观看一级片| 精品国产一区久久| 国产在线精彩视频| 欧美三日本三级少妇三99| 麻豆精品在线视频| 69xx绿帽三人行| 日韩精品视频在线观看免费| 韩日精品一区| 亚洲av首页在线| 99精品视频免费在线观看| 精品99在线观看| 亚洲欧美日韩久久久久久| 日本黄色成人| 日本高清xxxx| 99在线热播精品免费| 日本久久综合网| 亚洲香蕉av在线一区二区三区| 日韩电影免费观看高清完整版在线观看| 青草全福视在线| 久久综合狠狠综合| 国产精品九九九九| 欧美成人免费网| 久久99久久人婷婷精品综合| 亚洲18在线看污www麻豆| 一区二区三区在线视频观看58 | 另类一区二区三区| 日韩欧美一区二区三区四区 | 国产乱码精品| xxxx黄色片| 欧美日韩免费一区二区三区| 男女羞羞视频在线观看| 日韩欧美亚洲日产国| 成人av影院在线| 中文字幕免费观看| 久久久久久久久久久人体| 欧美电影免费| 黄色国产在线观看| 日韩精品一区二区在线观看|