国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

一文讓你搞懂 Python 的 pyc 文件

安全 應(yīng)用安全
混淆之后多了兩條指令,其中偏移量為 8 的指令,參數(shù)為 255,表示加載常量池中索引為 255 的元素。如果常量池沒有這么多元素,那么顯然會發(fā)生索引越界,導致反編譯的時候報錯。

pyc 文件的觸發(fā)

上一篇文章我們介紹了字節(jié)碼,當時提到,py 文件在執(zhí)行的時候會先被編譯成 PyCodeObject 對象,并且該對象還會被保存到 pyc 文件中。

然而事實并不總是這樣,有時當我們運行一個簡單的程序時,并沒有產(chǎn)生 pyc 文件。因此我們猜測:有些 Python 程序只是臨時完成一些瑣碎的工作,這樣的程序僅僅只會運行一次,然后就不會再使用了,因此也就沒有保存至 pyc 文件的必要。

如果我們在代碼中加上了一個 import abc 這樣的語句,再執(zhí)行你就會發(fā)現(xiàn)解釋器為 abc.py 生成了 pyc 文件,這就說明 import 語句會觸發(fā) pyc 的生成。

實際上,在運行過程中,如果碰到 import abc 這樣的語句,那么 Python 會在設(shè)定好的 path 中尋找 abc.pyc 或者 abc.pyd 文件。但如果沒有這些文件,而是只發(fā)現(xiàn)了 abc.py,那么會先將 abc.py 編譯成 PyCodeObject,然后寫入到 pyc 文件中。

接下來,再對 abc.pyc 進行 import 動作。對的,并不是編譯成 PyCodeObject 對象之后就直接使用,而是先寫到 pyc 文件里,然后再將 pyc 文件里面的 PyCodeObject 對象重新在內(nèi)存中復制出來。

當然啦,觸發(fā) pyc 文件生成不僅可以通過 import,還可以通過 py_compile 模塊手動生成。比如當前有一個 tools.py,代碼如下。

a = 1
b = "你好啊"

如何將其編譯成 pyc 呢?

import py_compile

py_compile.compile("tools.py")

查看當前目錄的 __pycache__ 目錄,會發(fā)現(xiàn) pyc 已經(jīng)生成了。

圖片圖片

然后 py文件名.cpython-版本號.pyc 便是編譯之后的 pyc 文件名。

pyc 文件的導入

如果有一個現(xiàn)成的 pyc 文件,我們要如何導入它呢?

from importlib.machinery import SourcelessFileLoader

tools = SourcelessFileLoader(
    "tools", "__pycache__/tools.cpython-312.pyc"
).load_module()

print(tools.a)  # 1
print(tools.b)  # 你好啊

以上我們就成功手動導入了 pyc 文件。

pyc 文件都包含哪些內(nèi)容

pyc 文件在創(chuàng)建的時候都會往里面寫入哪些內(nèi)容呢?

1)magic number

這是 Python 定義的一個整數(shù)值,不同版本的 Python 會定義不同的 magic number,這個值是為了保證 Python 能夠加載正確的 pyc。

比如 Python3.12 不會加載 3.10 版本的 pyc,因為 Python 在加載 pyc 文件的時候會首先檢測該 pyc 的 magic number。如果和自身的 magic number 不一致,則拒絕加載。

from importlib.util import MAGIC_NUMBER
print(MAGIC_NUMBER)  # b'\xcb\r\r\n'

with open("__pycache__/tools.cpython-312.pyc", "rb") as f:
    magic_number = f.read(4)
print(magic_number)  # b'\xcb\r\r\n'

pyc 文件的前 4 個字節(jié)便是 magic number。

2)pyc 文件的寫入時間

這個很好理解,在加載 pyc 之前會先比較源代碼的最后修改時間和 pyc 文件的寫入時間。如果 pyc 文件的寫入時間比源代碼的修改時間要早,說明在生成 pyc 之后,源代碼被修改了,那么會重新編譯并寫入 pyc,而反之則會直接加載已存在的 pyc。

3)py 文件的大小

py 文件的大小也會被記錄在 pyc 文件中。

4)PyCodeObject 對象

編譯之后的 PyCodeObject 對象,這個不用說了,肯定是要存儲的,并且是序列化之后再存儲。

因此 pyc 文件的結(jié)構(gòu)如下:

圖片圖片

我們實際驗證一下:

import struct
from importlib.util import MAGIC_NUMBER
from datetime import datetime

with open("__pycache__/tools.cpython-312.pyc", "rb") as f:
    data = f.read()

# 0 ~ 4 字節(jié)是 MAGIC NUMBER
print(data[: 4])  # b'\xcb\r\r\n'
print(MAGIC_NUMBER)  # b'\xcb\r\r\n'

# 4 ~ 8 字節(jié)是 4 個 \x00
print(data[4: 8])  # b'\x00\x00\x00\x00'

# 8 ~ 12 字節(jié)是 pyc 的寫入時間(小端存儲),一個時間戳
ts = struct.unpack("<I", data[8: 12])[0]
print(ts)  # 1726742711
print(
    datetime.fromtimestamp(ts)
)  # 2024-09-19 10:45:11

# 12 ~ 16 字節(jié)是 py 文件的大小
print(
    struct.unpack("<I", data[12: 16])[0]
)  # 22

結(jié)果和我們分析的一樣,前 16 字節(jié)是固定的,而 16 個字節(jié)往后就是 PyCodeObject 對象,并且是序列化之后的,因為該對象顯然無法直接存在文件中。

import marshal

with open("__pycache__/tools.cpython-312.pyc", "rb") as f:
    data = f.read()

# 通過 marshal.loads 可以反序列化
# marshal.dumps 則表示序列化
code = marshal.loads(data[16:])
# 此時就拿到了 py 文件編譯之后的 PyCodeObject
print(code)
"""
<code object <module> at 0x..., file "tools.py", line 1>
"""
# 查看常量池
print(code.co_consts)  # (1, '你好啊', None)

# 符號表
print(code.co_names)  # ('a', 'b')

常量池和符號表都是正確的。

pyc 文件的寫入

下面通過源碼來查看 pyc 文件的寫入過程,既然要寫入,那么肯定要有文件句柄。

// Python/marshal.c

// FILE 是 C 自帶的文件句柄
// 可以把 WFILE 看成是 FILE 的包裝
typedef struct {
    FILE *fp;
    // 下面的字段在寫入數(shù)據(jù)的時候會看到
    int error; 
    int depth;
    PyObject *str;
    char *ptr;
    const char *end;
    char *buf;
    _Py_hashtable_t *hashtable;
    int version;
} WFILE;

首先是寫入 magic number、創(chuàng)建時間和文件大小,它們會調(diào)用 PyMarshal_WriteLongToFile 函數(shù)進行寫入:

// Python/marshal.c
void
PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
{
    // magic number、創(chuàng)建時間和文件大小,只是一個 4 字節(jié)整數(shù)
    // 因此使用 char[4] 來保存
    char buf[4];
    // 聲明一個 WFILE 類型的變量 wf
    WFILE wf;
    // 內(nèi)存初始化
    memset(&wf, 0, sizeof(wf));
    // 初始化內(nèi)部字段
    wf.fp = fp;  // 文件句柄
    wf.ptr = wf.buf = buf;  // buf 數(shù)組首元素的地址
    wf.end = wf.ptr + sizeof(buf);  // buf 數(shù)組尾元素的地址
    wf.error = WFERR_OK;
    wf.version = version;
    // 調(diào)用 w_long 將信息寫到 wf 里面
    // 寫入的信息可以是 magic number、時間和文件大小
    w_long(x, &wf);
    // 刷到磁盤上
    w_flush(&wf);
}

所以該函數(shù)只是初始化了一個 WFILE 對象,真正寫入則是調(diào)用的 w_long。

// Python/marshal.c
static void
w_long(long x, WFILE *p)
{   
    w_byte((char)( x      & 0xff), p);
    w_byte((char)((x>> 8) & 0xff), p);
    w_byte((char)((x>>16) & 0xff), p);
    w_byte((char)((x>>24) & 0xff), p);
}

w_long 則是調(diào)用 w_byte 將 x 逐個字節(jié)地寫到文件里面去。

當頭信息寫完之后,就該寫 PyCodeObject 對象了,這個過程由 PyMarshal_WriteObjectToFile 函數(shù)負責。

// Python/marshal.c
void
PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
{
    char buf[BUFSIZ];
    WFILE wf;
    if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) {
        return; /* caller must check PyErr_Occurred() */
    }
    memset(&wf, 0, sizeof(wf));
    wf.fp = fp;
    wf.ptr = wf.buf = buf;
    wf.end = wf.ptr + sizeof(buf);
    wf.error = WFERR_OK;
    wf.version = version;
    if (w_init_refs(&wf, version)) {
        return; /* caller must check PyErr_Occurred() */
    }
    // 寫入頭信息由 PyMarshal_WriteLongToFile 負責,它內(nèi)部會調(diào)用 w_long
    // 寫入 PyCodeObject 由當前函數(shù)負責,它內(nèi)部會調(diào)用 w_object
    w_object(x, &wf);
    w_clear_refs(&wf);
    w_flush(&wf);
}

然后我們看一下 w_object 函數(shù)。

// Python/marshal.c
static void
w_object(PyObject *v, WFILE *p)
{
    char flag = '\0';

    p->depth++;

    if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
        p->error = WFERR_NESTEDTOODEEP;
    }
    else if (v == NULL) {
        w_byte(TYPE_NULL, p);
    }
    else if (v == Py_None) {
        w_byte(TYPE_NONE, p);
    }
    else if (v == PyExc_StopIteration) {
        w_byte(TYPE_STOPITER, p);
    }
    else if (v == Py_Ellipsis) {
        w_byte(TYPE_ELLIPSIS, p);
    }
    else if (v == Py_False) {
        w_byte(TYPE_FALSE, p);
    }
    else if (v == Py_True) {
        w_byte(TYPE_TRUE, p);
    }
    else if (!w_ref(v, &flag, p))
        w_complex_object(v, flag, p);

    p->depth--;
}

可以看到 w_object 和 w_long 一樣,本質(zhì)上都是調(diào)用了 w_byte。當然 w_byte 只能寫入一些簡單數(shù)據(jù),如果是列表、字典之類的數(shù)據(jù),那么會調(diào)用 w_complex_object 函數(shù),也就是代碼中的最后一個 else if 分支。

w_complex_object 這個函數(shù)的源代碼很長,我們看一下整體結(jié)構(gòu),具體邏輯就不貼了,后面會單獨截取一部分進行分析。

// Python/marshal.c
static void
w_complex_object(PyObject *v, char flag, WFILE *p)
{
    Py_ssize_t i, n;
    // 如果是整數(shù)的話,執(zhí)行整數(shù)的寫入邏輯
    if (PyLong_CheckExact(v)) {
        // ......
    }
    // 如果是浮點數(shù)的話,執(zhí)行浮點數(shù)的寫入邏輯
    else if (PyFloat_CheckExact(v)) {
        // ......
    }
    // 如果是復數(shù)的話,執(zhí)行復數(shù)的寫入邏輯
    else if (PyComplex_CheckExact(v)) {
        // ......
    }
    // 如果是字節(jié)序列的話,執(zhí)行字節(jié)序列的寫入邏輯
    else if (PyBytes_CheckExact(v)) {
        // ......
    }
    // 如果是字符串的話,執(zhí)行字符串的寫入邏輯
    else if (PyUnicode_CheckExact(v)) {
        // ......
    }
    // 如果是元組的話,執(zhí)行元組的寫入邏輯
    else if (PyTuple_CheckExact(v)) {
       // ......
    }
    // 如果是列表的話,執(zhí)行列表的寫入邏輯
    else if (PyList_CheckExact(v)) {
        // ......
    }
    // 如果是字典的話,執(zhí)行字典的寫入邏輯
    else if (PyDict_CheckExact(v)) {
        // ......
    }
    // 如果是集合的話,執(zhí)行集合的寫入邏輯
    else if (PyAnySet_CheckExact(v)) {
        // ......
    }
    // 如果是 PyCodeObject 對象的話
    // 執(zhí)行 PyCodeObject 對象的寫入邏輯
    else if (PyCode_Check(v)) {
        //......
    }
    // 如果是 Buffer 的話,執(zhí)行 Buffer 的寫入邏輯
    else if (PyObject_CheckBuffer(v)) {
        //......
    }
    else {
        W_TYPE(TYPE_UNKNOWN, p);
        p->error = WFERR_UNMARSHALLABLE;
    }
}

源代碼雖然長,但是邏輯非常單純,就是對不同的對象、執(zhí)行不同的寫動作,然而其最終目的都是通過 w_byte 寫到 pyc 文件中。了解完函數(shù)的整體結(jié)構(gòu)之后,我們再看一下具體細節(jié),看看它在寫入對象的時候到底寫入了哪些內(nèi)容?

// Python/marshal.c
static void
w_complex_object(PyObject *v, char flag, WFILE *p)
{
    // ......
    else if (PyList_CheckExact(v)) {
        W_TYPE(TYPE_LIST, p);
        n = PyList_GET_SIZE(v);
        W_SIZE(n, p);
        for (i = 0; i < n; i++) {
            w_object(PyList_GET_ITEM(v, i), p);
        }
    }
    else if (PyDict_CheckExact(v)) {
        Py_ssize_t pos;
        PyObject *key, *value;
        W_TYPE(TYPE_DICT, p);
        /* This one is NULL object terminated! */
        pos = 0;
        while (PyDict_Next(v, &pos, &key, &value)) {
            w_object(key, p);
            w_object(value, p);
        }
        w_object((PyObject *)NULL, p);
    }  
    // ......
}

以列表和字典為例,它們在寫入的時候?qū)嶋H上寫的是內(nèi)部的元素,其它對象也是類似的。

def foo():
    lst = [1, 2, 3]

# 把列表內(nèi)的元素寫進去了
print(
    foo.__code__.co_consts
)  # (None, (1, 2, 3))

當然啦,對于 3.12 版本來說,內(nèi)部的元素會以元組的形式被收集起來。

但很明顯,如果只是將元素收集起來顯然是不夠的,否則 Python 在加載的時候怎么知道它是一個列表呢?所以在寫入的時候不能光寫數(shù)據(jù),還要將類型信息也寫進去。我們再看一下上面列表和字典的寫入邏輯,里面都調(diào)用了 W_TYPE,它負責寫入類型信息。

因此無論對于哪種對象,在寫入具體數(shù)據(jù)之前,都會先調(diào)用 W_TYPE 將類型信息寫進去。如果沒有類型信息,那么當解釋器加載 pyc 文件的時候,只會得到一坨字節(jié)流,而無法解析字節(jié)流中隱藏的結(jié)構(gòu)和蘊含的信息。

所以在往 pyc 文件里寫入數(shù)據(jù)之前,必須先寫入一個標識,諸如 TYPE_LIST, TYPE_TUPLE, TYPE_DICT 等等,這些標識正是對應(yīng)的類型信息。

如果解釋器在 pyc 文件中發(fā)現(xiàn)了這樣的標識,則預(yù)示著上一個對象結(jié)束,新的對象開始,并且也知道新對象是什么樣的對象,從而也知道該執(zhí)行什么樣的構(gòu)建動作。當然,這些標識也是可以看到的,在底層已經(jīng)定義好了。

圖片圖片

到了這里可以看到,Python 對 PyCodeObject 對象的導出實際上是不復雜的。因為不管什么對象,最后都會歸結(jié)為兩種簡單的形式,一種是數(shù)值寫入,一種是字符串寫入。

上面都是對數(shù)值的寫入,比較簡單,僅僅需要按照字節(jié)依次寫入 pyc 即可。然而在寫入字符串的時候,Python 設(shè)計了一種比較復雜的機制,有興趣可以自己閱讀源碼,這里不再介紹。

字節(jié)碼混淆

最后再來說一下字節(jié)碼混淆,我們知道 pyc 是可以反編譯的,而且目前也有現(xiàn)成的工具。但這些工具它會將每一個指令都解析出來,所以字節(jié)碼混淆的方式就是往里面插入一些惡意指令(比如加載超出范圍的數(shù)據(jù)),讓反編譯工具在解析的時候報錯,從而失去作用。

但插入的惡意指令還不能影響解釋器執(zhí)行,因此還要插入一些跳轉(zhuǎn)指令,從而讓解釋器跳過惡意指令。

圖片圖片

混淆之后多了兩條指令,其中偏移量為 8 的指令,參數(shù)為 255,表示加載常量池中索引為 255 的元素。如果常量池沒有這么多元素,那么顯然會發(fā)生索引越界,導致反編譯的時候報錯。

但對于解釋器來說,是可以正常執(zhí)行的,因為在執(zhí)行到偏移量為 6 的指令時出現(xiàn)了一個相對跳轉(zhuǎn),直接跳到偏移量為 10(6 + 4)的指令了。

因此對于解釋器執(zhí)行來說,混淆前后是沒有區(qū)別的。但對于反編譯工具而言則無法正常工作,因為它會把每一個指令都解析一遍。根據(jù)這個思路,我們可以插入很多很多的惡意指令,然后再利用跳轉(zhuǎn)指令來跳過這些不合法指令。當然混淆的手段并不止這些,我們還可以添加一下虛假的分支,然后在執(zhí)行時跳轉(zhuǎn)到真實的分支當中。

而這一切的目的,都是為了防止別人根據(jù) pyc 文件反推出源代碼。不過這種做法屬于治標不治本,如果真的想要保護源代碼的話,可以使用 Cython 將其編譯成 pyd ,這是最推薦的做法。

責任編輯:武曉燕 來源: 古明地覺的編程教室
相關(guān)推薦

2025-06-04 03:21:00

RAGRetrievalGeneratio

2021-10-20 08:49:30

Vuexvue.js狀態(tài)管理模式

2022-09-29 10:26:59

iOSScaffoldflutter

2024-04-12 12:19:08

語言模型AI

2025-05-22 06:23:48

2022-03-24 08:51:48

Redis互聯(lián)網(wǎng)NoSQL

2025-05-21 09:32:28

2021-03-22 10:05:59

netstat命令Linux

2023-09-15 12:00:01

API應(yīng)用程序接口

2023-09-08 08:20:46

ThreadLoca多線程工具

2021-12-01 11:40:14

Python 輸入輸出

2022-05-05 16:47:24

Docker網(wǎng)絡(luò)空間容器

2020-05-15 16:37:13

PowerBI數(shù)據(jù)分析

2023-07-04 08:56:07

指針類型Golang

2021-09-11 10:41:27

PythonPickle模塊

2023-04-03 15:04:00

RPCPHP語言

2023-08-24 16:50:45

2023-10-16 08:16:31

Bean接口類型

2019-11-19 08:00:00

神經(jīng)網(wǎng)絡(luò)AI人工智能

2024-06-05 11:43:10

點贊
收藏

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

午夜不卡一区| 免费在线一级视频| 精品国产一区一区二区三亚瑟| 精品国产亚洲在线| 在线宅男视频| 亚洲精品乱码久久久久| 日韩国产一级片| 国产一区二区网址| 亚洲精品一区二区三区樱花| 国语对白精品一区二区| 国产精品日日摸夜夜添夜夜av| 亚洲妇女av| 欧美亚洲日本网站| 噜噜噜天天躁狠狠躁夜夜精品| 欧美成在线视频| 8x国产一区二区三区精品推荐| 欧美大胆a视频| 亚洲一区二区三区在线免费| 久久精品亚洲热| 国产亚洲字幕| 97免费在线视频| 日韩伦理一区二区三区| 热99在线视频| 久久不见久久见免费视频7| 欧美日韩不卡合集视频| 天堂av一区| 97在线观看免费高清| 久久99视频| 亚洲最大的网站| 美女被久久久| 日韩精品一区二区三区电影| 成人黄页毛片网站| www.日日操| 亚洲永久精品国产| 97在线观看免费观看高清| 日韩免费看网站| 97精品国产99久久久久久免费| 欧美国产极速在线| 久久中文亚洲字幕| 欧美在线激情| 国产99久久久精品| wwwwww99| 欧美在线小视频| www.youjizz.com在线| 日韩在线观看免费| 精品freesex老太交| 快播亚洲色图| 91年精品国产| 日韩私人影院| 国产视频久久久久久久| 99热这里只有精品首页| 97视频中文字幕| 国产激情偷乱视频一区二区三区| 亚洲一区在线不卡| 欧美写真视频网站| 成人精品动漫| 亚洲japanese制服美女| 久久99国产精品麻豆| 亚洲最大成人在线观看| 91精品福利在线| 色婷婷综合久久久中字幕精品久久| 欧美交受高潮1| 激情另类综合| 鲁一鲁一鲁一鲁一澡| 精品久久久久久久久久ntr影视| 免费电影网站在线视频观看福利| 欧美精品成人在线| 亚洲欧美日韩在线观看a三区| 日本在线观看a| 欧美在线一二三四区| 亚洲18在线| 久久精品国产精品国产精品污| 久久久久久电影| 免费网站黄在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整| 一二三区不卡| 国产91在线视频观看| 欧美剧情片在线观看| 日韩精品三级| 欧美日韩亚洲在线| 亚洲乱码中文字幕| 少妇一区视频| 久久精品人人做人人爽电影| 国产精品美女www爽爽爽| sm性调教片在线观看| 成人精品视频99在线观看免费| 成人avav影音| 婷婷av在线| 91视频免费网站| 国产精品二区一区二区aⅴ污介绍| 亚洲淫性视频| 国产精品影院在线观看| 久久综合九色综合97婷婷| 青青青草视频在线| av一区二区三区四区电影| 国产精品乱码一区二区三区软件| 九色porny视频在线观看| 国产精品一区二区三区四区五区| 国产精品久久久久久久蜜臀| 三级在线看中文字幕完整版| 国产精品手机在线| 亚洲一区二区三区四区在线观看 | 国产精品美女久久久久av爽李琼| 超碰在线cao| 久99久在线| 日本国产一区二区| 精品美女视频| 日韩av卡一卡二| 中文字幕亚洲国产| 国产伦精品一区二区三区免费迷| 麻豆传媒免费在线观看| 国产欧美韩国高清| 亚洲欧美日韩综合aⅴ视频| 免费精品一区二区三区在线观看| 91国在线高清视频| 亚洲精品久久7777777| 欧美亚洲自偷自偷| 男人天堂久久久| 风间由美一区二区三区| 福利一区视频在线观看| 久久影院一区| 在线观看av中文| 亚洲一区二区三区四区在线播放| 亚洲成人免费看| 9999国产精品| 日本国产在线| 国产亚洲精品va在线观看| 国产人妻777人伦精品hd| 亚洲电影第三页| 欧美日韩免费在线| 99国精产品一二二线| 成人网免费视频| 尤物国产精品| 国产精品久久毛片| 国产视频在线观看一区| 美日韩精品免费观看视频| 欧美大片第1页| 正在播放亚洲一区| 亚洲综合一区二区| 国产午夜精品理论片a级大结局 | 日精品一区二区三区| 精品久久久免费| 久久久久九九精品影院| 不卡av影片| 2017亚洲天堂1024| 九九在线视频| 激情校园亚洲图片| 精品久久久久av| 国产精品theporn88| 欧美视频小说| 欧美一级淫片aaaaaaa视频| 亚洲色图在线观看| 欧美一级片在线播放| 国产精品v欧美精品v日韩| 2021国产视频| 欧美日韩国产一二| 日韩伦理一区二区三区av在线| 五月天亚洲综合| 国产视频手机在线播放| 区一区二区三区中文字幕| 91亚洲精华国产精华| 国产精品手机视频| 国产精品夜夜夜爽张柏芝| 亚洲小说欧美另类激情| 九九九九精品九九九九| 91免费看视频| 国产一区二区三区视频在线播放| 91成人短视频在线观看| 成人在线免费视频| 岛国视频一区免费观看| 久久五月天婷婷| 欧美三级午夜理伦三级中视频| 欧美激情偷拍| 国产在线88av| 国产一级做a爰片久久| 国产精品大陆在线观看| 欧美三级日韩在线| 中文字幕在线资源| 国产精品久久久久久久久借妻| 欧洲精品中文字幕| 国产宾馆实践打屁股91| 国产精品一区高清| 国产丝袜在线播放| 成人黄网大全在线观看| 黑人巨大精品欧美一区二区小视频| 国产偷国产偷亚洲清高网站| 欧美激情在线看| 在线成人亚洲| 国产精品日韩精品在线播放| 可以在线观看的av网站| 噜噜噜久久亚洲精品国产品麻豆| 亚洲综合视频1区| 日韩中文字幕不卡视频| 一本到三区不卡视频| 福利一区福利二区| 午夜视频一区| 久久在线观看| 精精国产xxxx视频在线中文版 | 澳门久久精品| 国产成人无吗|