一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - IOS - iOS逆向工程之Hopper中的ARM指令詳解

iOS逆向工程之Hopper中的ARM指令詳解

2021-01-29 15:56青玉伏案 IOS

這篇文章主要介紹了iOS逆向工程之Hopper中的ARM指令的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下

雖然前段時(shí)間arm被日本軟銀收購(gòu)了,但是科技是無(wú)國(guó)界的,所以呢arm相關(guān)知識(shí)該學(xué)的學(xué)。現(xiàn)在看arm指令集還是倍感親切的,畢竟大學(xué)里開了arm這門課,并且做了不少的實(shí)驗(yàn),當(dāng)時(shí)自我感覺arm這門課學(xué)的還是可以的。雖然當(dāng)時(shí)感覺學(xué)這門課以后似乎不怎么用的上,可曾想這不就用上了嗎,不過之前學(xué)的都差不多忘了,還得撿起來(lái)呢。arm指令集是精簡(jiǎn)指令集,從名字我們就能看出指令的個(gè)數(shù)比那些負(fù)責(zé)指令集要少一些。當(dāng)然本篇所涉及的arm指令集是冰山一角,不過也算是基礎(chǔ),可以閱讀hopper中的匯編了,實(shí)踐出真知,看多了自然而然的就會(huì)了。

一、hopper中的arm指令

arm處理器就不多說(shuō)了,arm處理器因?yàn)榈凸牡仍颍源蟛糠忠苿?dòng)設(shè)備上用的基本上都是arm架構(gòu)的處理器。當(dāng)然作為移動(dòng)設(shè)備的android手機(jī),iphone也是用的arm架構(gòu)的處理器。如果你想對(duì)ios系統(tǒng)以及你的應(yīng)用進(jìn)一步的了解,那么對(duì)arm指令集的了解是必不可少的,arm指令集應(yīng)該也算得上是ios逆向工程的基礎(chǔ)了。

當(dāng)你使用hopper進(jìn)行反編譯時(shí),里邊全是arm的指令,那是看的一個(gè)爽呢。下面就是使用hopper打開mobilenote.app的一個(gè)hopper的界面。從主窗口中可以看到全是arm的指令呢,如果你對(duì)arm指令不了解,那么如何進(jìn)行分析呢,對(duì)吧。所以對(duì)arm指令的了解,是ios逆向工程的基礎(chǔ)呢。今天這篇博客就總結(jié)一下arm指令集的基礎(chǔ)指令。

iOS逆向工程之Hopper中的ARM指令詳解

hopper的功能是非常強(qiáng)大的,在hopper中你可以對(duì)arm指令進(jìn)行修改,并且生成一個(gè)新的可執(zhí)行文件。當(dāng)然hopper強(qiáng)大的功能可以幫助你更好的理解arm匯編語(yǔ)言的業(yè)務(wù)邏輯,hopper會(huì)根據(jù)arm匯編生成相關(guān)的邏輯圖,如下所示。從下方的邏輯圖中你就能清楚的看到相關(guān)arm匯編的指令邏輯。紅線表明條件不成立時(shí)的跳轉(zhuǎn),藍(lán)線則表明條件成立時(shí)的跳轉(zhuǎn)。

iOS逆向工程之Hopper中的ARM指令詳解

hopper的功能強(qiáng)大到可以將arm匯編生成相應(yīng)的偽代碼,如果你看arm指令不直觀的話,那么偽代碼對(duì)你來(lái)說(shuō)會(huì)更好一些。下方就是hopper根據(jù)arm指令生成的偽代碼,如下所示。

iOS逆向工程之Hopper中的ARM指令詳解

貌似有點(diǎn)跑偏了,今天的主題是arm指令集,hopper的東西就不做過多贅述了。

二、arm指令集綜述

arm指令主要是對(duì)寄存器,棧、內(nèi)存的操作。寄存器位于cpu中,個(gè)數(shù)少速度快,arm指令集中大部分指令都是對(duì)寄存器操作,但有些指令是對(duì)棧和內(nèi)存的操作。下方會(huì)對(duì)操作棧、寄存器以及內(nèi)存的指令進(jìn)行介紹。

1.棧操作---- push 與pop

先簡(jiǎn)單的聊一下棧的概念,“棧”說(shuō)白了就是數(shù)據(jù)結(jié)構(gòu)的一種,棧的數(shù)據(jù)結(jié)構(gòu)具有l(wèi)ifo(last in first out) ---- 后進(jìn)先出的特點(diǎn)。棧在arm中所指的其實(shí)是一塊具有棧數(shù)據(jù)結(jié)構(gòu)特點(diǎn)內(nèi)存區(qū)。棧中主要用來(lái)暫存寄存器中的值得,比如r0寄存器正在使呢,可是現(xiàn)在有一個(gè)優(yōu)先級(jí)比較高的函數(shù)要使用r0, 那么就先把r0的值push到棧中暫存,然后等r0被優(yōu)先級(jí)更高的函數(shù)使用完畢后在從棧中pop出之前的值。在函數(shù)調(diào)用時(shí)一般會(huì)對(duì)棧進(jìn)行操作。

對(duì)棧操作的命令就是push和pop了,一般會(huì)成對(duì)出現(xiàn),在函數(shù)開始時(shí)將該函數(shù)執(zhí)行時(shí)要使用的寄存器中的值push入棧,然后在函數(shù)結(jié)束時(shí)將之前push到棧中的值在pop到相應(yīng)的寄存器中。

下方就是push和pop的用法的一個(gè)實(shí)例。在下方函數(shù)開始執(zhí)行前,將該函數(shù)要使用的寄存器r4, r5, r7, lr使用push進(jìn)行入棧操作,lr是該函數(shù)執(zhí)行后要返回的地址。在函數(shù)執(zhí)行完畢后,使用pop命令將函數(shù)執(zhí)行前入棧的值在pop到相應(yīng)的寄存器中。有一點(diǎn)需要注意的是將lr寄存器中的值在函數(shù)結(jié)束后pop到pc (program counter)寄存器中,pc寄存器中存儲(chǔ)的是將要執(zhí)行的命令的地址。這樣一來(lái),函數(shù)執(zhí)行后就會(huì)返回到之前執(zhí)行的地址上繼續(xù)執(zhí)行。

iOS逆向工程之Hopper中的ARM指令詳解

2. pc寄存器中的中的標(biāo)志位

此處我們以32位指令為例,pc寄存器中的后四位是標(biāo)志位,第28 - 31位分別對(duì)應(yīng)著v (overflow),c (carry),z (zero),n (negative)。下面分別來(lái)介紹一下這四種符號(hào)所表示的狀態(tài)。

•n (negative): 如果結(jié)果是負(fù)數(shù)則置位。

•z (zero): 如果結(jié)果是零則置位。

•c (carry): 如果有進(jìn)位則置位。

•v (overflow): 在發(fā)生溢出的時(shí)候置位。

3. 命令操作符

下方是arm指令集中常用的算術(shù)操作:

(1)加法操作

•add r0, r1, r2 ; r0 = r1 + r2 •上面的命令就比較簡(jiǎn)單,就是講兩個(gè)數(shù)值進(jìn)行相加。

•adc r0, r1, r2 ; r0 = r1 + r2 + c (carry) •帶進(jìn)位的加法,adc將把兩個(gè)操作數(shù)加起來(lái),并把結(jié)果放置到目的寄存器中。adc使用了c--進(jìn)位標(biāo)志,這樣就可以做比32位大的加法了。下方就是128位的數(shù)字進(jìn)行加法操作的匯編代碼。

•我們現(xiàn)在要對(duì)一個(gè)128位的數(shù)字進(jìn)行加法操作,因?yàn)槲覀兪褂玫氖?2位的寄存器,所以要存儲(chǔ)一個(gè)128位的數(shù)字,我們需要4個(gè)(128 / 32 = 4)寄存器。所以我們假設(shè)r0,r1,r2,r3寄存器中分別由低到高存儲(chǔ)著第一個(gè)數(shù)字,而r4, r5, r6, r7存儲(chǔ)著第二個(gè)數(shù)字。下方就是兩個(gè)128數(shù)字相加操作的arm匯編指令。我們將結(jié)果存儲(chǔ)在r8, r9, r10, r11這四個(gè)寄存器中。首先我們執(zhí)行的是將兩個(gè)數(shù)的最低位相加并設(shè)置c標(biāo)志位(adds r8, r0, r4),然后在進(jìn)行下一位的操作,對(duì)r1和r5中的值進(jìn)行相加,在相加后再加上上次操作的進(jìn)位,然后再設(shè)置標(biāo)志位,以此類推。這樣我們最終的值就存儲(chǔ)在了r8-r11這四個(gè)寄存器中。

iOS逆向工程之Hopper中的ARM指令詳解

(2)減法操作

•sub r0, r1, r2 ; r0 = r1 - r2 •這個(gè)命名比較簡(jiǎn)單,就是使用r1寄存器中的值減去r2寄存器中的值,然后存儲(chǔ)到r0中。

•sbc r0, r1, r2 ; r0 = r1 - r2 - !c •帶借位的減法,假如我們當(dāng)前的寄存器是32bit, 如果兩個(gè)64bit的數(shù)值進(jìn)行減法操作就要使用到sbc借位操作。因?yàn)楫?dāng)兩個(gè)數(shù)值在進(jìn)行減法操作時(shí),如果需要借位時(shí)就會(huì)把c標(biāo)志位進(jìn)行清零操作,所以在進(jìn)行sbc操作時(shí)需要將c標(biāo)志位進(jìn)行取反操作。下面我們一128位數(shù)值相減為例。該實(shí)例與上述的adc命令類似,在此就不做過多贅述了。

iOS逆向工程之Hopper中的ARM指令詳解  

•rsb r0, r1, r2 ; r0 = r2 - r1 •反向減法

•rsc r0, r1, r2 ; r0 = r2 - r1 - !c
•帶借位的反向減法,上面這兩個(gè)命令與sub和sbc命令差不多,都是進(jìn)行減法操作的,不過操作數(shù)的計(jì)算順序不同。

(3)、乘法指令

在arm指令集中,乘法指令有兩種第一個(gè)是mul, 第二個(gè)是帶累加的乘法mla。當(dāng)然,這兩個(gè)指令使用起來(lái)都不復(fù)雜。

•mul: 乘法指令 mul{條件}{s} r0, r1, r2 ;r0 = r1 * r2

•mla: 乘法累加指令 mla{條件}{s} r0, r1, r2, r3 ;r0 = r1 * r2 + r3

(4)、邏輯操作

邏輯操作比較好理解一些,與我們編程中使用的邏輯操作大同小異,無(wú)非是一些與、或、非、異或這些操作。

•and r0, r1, r2 ; r0 = r1 & r2

•與操作, 1 & 1 = 1, 1 & 0 = 1, 0 & 1 = 1,0 & 0 = 0;

•orr r0, r1, r2 ; r0 = r1 | r2

•或操作, 1 | 1 = 1, 1 | 0 = 1, 0 | 1 = 1, 0 | 0 = 0;

•eor r0, r1, r2 ; r0 = r1 ^ r2

•異或,1 ^ 1 = 1, 1 ^ 0 = 0, 0 ^ 1 = 0, 0 ^ 0 = 1;

•bic r0, r1, r2 ; r0 = r1 &~ r2

•位清除指令,現(xiàn)將r2進(jìn)行取反,然后再與r1進(jìn)行與操作。r1 & (~r2)

•將r0的后四位清零:bic r0, r0,#0x0f

•mov r0, r1 ;r0 = r1

•賦值操作,將r1的值賦給r0

•mvn r0, r1 ;r0 = ~r1

•按位取反操作,將r1的每一位進(jìn)行取反操作,然后賦值給r0

4、寄存器的裝載和存儲(chǔ)

有時(shí)我們需要將內(nèi)存中的數(shù)據(jù)裝載到寄存器中進(jìn)行操作,或者將寄存器中運(yùn)算后的數(shù)據(jù)存儲(chǔ)到內(nèi)存中,此時(shí)我們就會(huì)用到寄存器的裝載和存儲(chǔ)的相關(guān)命令。下方就一一的總結(jié)了這些命令。

(1)、傳送單一數(shù)據(jù)

ldr{條件} rd, <地址>   ;將地址中的數(shù)據(jù)加載到rd寄存器中

str{條件} rd, <地址>   ;將寄存器rd中的數(shù)值存儲(chǔ)到<地址>中的內(nèi)存中

ldr{條件}b rd, <地址> ;將內(nèi)存地址所對(duì)應(yīng)值得低8位加載到rd的寄存器中。

str{條件}b rd, <地址> ;將寄存器rd的后8為存的到內(nèi)存地址中。

•ldr (load register) : 將數(shù)據(jù)從內(nèi)存中取出,加載到寄存器。

•ldr rt, [rn], #offset ;rt = *rn; rn = rn + offset

•ldr rt, [rn, #offset]! ; rt = *(rn + offset); rn = rn + offset

•str (store register): 將寄存器中的數(shù)據(jù),存儲(chǔ)到內(nèi)存。

•str rt, [rn], #offset ;*rn = rt; rn = rn + offset

•str rt, [rn, #offset]! ;*(rn + offset) = rn; rn = rn + offset(地址回寫)

(2)、一次傳送兩個(gè)數(shù)據(jù)

•ldrd (load register double): 一次填充兩個(gè)寄存器

•ldrd r4, r5, [r6, #offset] ;r4 = *(r6 + offset); r5 = *(r6 + offset + 4)

•strd (store register double):一次存儲(chǔ)兩個(gè)值到內(nèi)存

•strd r4, r5, [r6, #offset] ;*(r6 + offset) = r4; *(r6 + offset + 4) = r5

(3)、塊數(shù)據(jù)存取

•ldm (load mutiple): 將一塊數(shù)據(jù)從寄存器中加載到內(nèi)存中(reg list)。

•stm (store multiple): 將塊數(shù)據(jù)從內(nèi)存中加載到寄存器。

•ldm與stm塊內(nèi)存操作都有一個(gè)后綴,下方就是這四種條件,我們假設(shè)下方r0寄存器中存儲(chǔ)的值是0(r0 = 6) •ia (increment after): 傳輸后再增加值, •如:ldmia r0, {r1 - r3} ;r1 = 6, r2 = 7, r3 = 8

•ib (increment befor): 傳輸前增加值 •如:ldmib r0, {r1 - r3} ;r1 = 7, r2 = 8, r3 = 9

•da (decrement after):傳輸后減少值 •如: ldmda r0, {r1 - r3} ;r1 = 6, r2 = 5, r3 = 4

•db (decrement before):傳輸前減少值 •如:ldmdb r0, {r1 - r3} ;r1 = 5, r2 = 4, r3 = 3

(4)、單一數(shù)據(jù)交換:swp

swp命令用來(lái)交換寄存器與內(nèi)存直接的值,下方是swp的指令格式:

swp{條件}{b} rd, rm, [rn]

上述命令表示將rn中內(nèi)存地址所指向內(nèi)存中的數(shù)據(jù)加載到rd中,然后將寄存器rm中的值存儲(chǔ)到該內(nèi)存地址指向的區(qū)域中。如果rd = rm, 那么rn指向的內(nèi)存中的值就會(huì)與rd進(jìn)行交換。如果加上條件后綴的話,就說(shuō)明在滿足該條件時(shí)進(jìn)行操作,后綴b則是操作低8位。

5、比較、分支與條件指令

分支與條件指令是編程中不可或缺的指令,在處理一些特定的業(yè)務(wù)邏輯時(shí)會(huì)經(jīng)常使用到分支與條件指令。分支說(shuō)白了就是跳轉(zhuǎn),而分支與條件結(jié)合使用就是當(dāng)滿足一定條件后進(jìn)行特定的跳轉(zhuǎn)。接下來(lái),將總結(jié)一下arm指令集中常用的分支指令與條件指令,更確切的說(shuō)是條件后綴。

(1)、比較指令

在arm指令集中使用到的比較指令有cmn、cmp、teq、tst。有一點(diǎn)需要注意的是cmn與cmp是算術(shù)指令,teq和tst屬于邏輯指令。比較指令在執(zhí)行后總是會(huì)設(shè)置標(biāo)志位(n、z、c、v), 因?yàn)闂l件后綴是根據(jù)被設(shè)置的標(biāo)志位來(lái)判斷比較結(jié)果是否滿足條件的。下方會(huì)給出詳細(xì)的條件后綴。比較命令后方也是可以添加條件后綴的。

•cmn (compare negative) ---- 比較負(fù)值, cmn相同于cmp, 但他允許你對(duì)負(fù)值進(jìn)行比較

•cmn r0, r1   ;status = r0 - r1

•cmp (compare) ---- 之所以說(shuō)cmp,cmn指令是算術(shù)指令,是因?yàn)樗麄冎v操作數(shù)進(jìn)行減法操作,并且設(shè)置相應(yīng)的標(biāo)志位,但是不記

錄計(jì)算結(jié)果。cmn與cmp進(jìn)行的是算術(shù)減法操作,所以會(huì)影響c -- carry標(biāo)志。 •cmp r0, r1   ;status = r0 - r1

•teq (test equivalence) ---- 測(cè)試等價(jià),teq對(duì)操作數(shù)進(jìn)行異或(eor)邏輯操作,來(lái)判斷兩個(gè)操作數(shù)是否相同。因?yàn)閠eq做的是異或運(yùn)算,所以不會(huì)影響carry標(biāo)志位。 •teq r0, r1 ;status = r0 eor r1

•tst (test bits) ---- 測(cè)試位,使用tst命令來(lái)檢查是否設(shè)置了特定的位。tst命中令其實(shí)是將兩個(gè)操作數(shù)進(jìn)行按位與(and)操作,將結(jié)果存儲(chǔ)在標(biāo)志位中。可以使用tst來(lái)測(cè)試寄存器中某些位的特定值。 •tst r0, r1   ;status = r0 and r1

(2)、分支指令

常用的分支指令是b、bl、bx這三個(gè)指令。

•b lable ;該指令表示將pc設(shè)置成lable, 而pc就是指向下一條將要執(zhí)行的指令,所以b lable執(zhí)行后,接下來(lái)就會(huì)跳轉(zhuǎn)到label出進(jìn)行下一條命令的執(zhí)行。

•bl label ; 執(zhí)行該指令說(shuō)明將lr設(shè)置成pc - 4, 然后再將pc設(shè)置成lable。在執(zhí)行bl lable這條命令時(shí),pc中存儲(chǔ)的就是當(dāng)前bl這條命令,而pc - 4就是上一條指令的地址,將pc - 4賦值給lr,也就是記錄下跳轉(zhuǎn)執(zhí)行完指令后要返回的地址。如果bl在添加上一些條件,那么bl{條件}就可以進(jìn)行循環(huán)了。

•bx rd ; 該指令說(shuō)明將rd賦值給pc, 然后切換指令集(如從arm指令集切換到thumb指令集)。

(3)、條件后綴

上述的分支指令與條件后綴結(jié)合才能發(fā)揮其強(qiáng)大的功能和作用,解析這部分介紹的是就是我們的條件后綴。條件后綴不能單獨(dú)的使用,要和其他命令一塊結(jié)合使用,然后根據(jù)條件的結(jié)果來(lái)做一些操作。下方是所有條件后綴,條件是否成立是根據(jù)nzcv這四個(gè)標(biāo)志位來(lái)判斷的,因?yàn)槲覀冊(cè)趯?duì)一些數(shù)值進(jìn)行比較時(shí),會(huì)設(shè)置相應(yīng)的標(biāo)志位。然后我們就可以使用這些標(biāo)志位來(lái)判斷條件是否成立。

nzcv就是我們之前所提到的幾個(gè)標(biāo)志位,z(是否為零), c(是否進(jìn)位), n(是否為負(fù)), v(是否溢出)四種標(biāo)準(zhǔn)位來(lái)判斷的。

•eq: equal 等于,(z = 1)

•ne: not equal 不等于 (z = 0)

•cs: carry set 有進(jìn)位 (c = 1)

•hs: (unsigned higher or same) 同cs (c = 1)

•cc: (carry clear) 沒有進(jìn)位 (c = 0)

•lo: (unsigned lower) 同cc (c = 0)

•mi: (minus) 結(jié)果小于0 (n = 1)

•pl: (plus) 結(jié)果大于等于0 (n = 0)

•vs: (overflow set) 溢出 (v = 1)

•vc: (overflow clear) 無(wú)溢出 (v = 0)

•hi : (unsigned higher) 無(wú)符號(hào)比較,大于 (c = 1 & z = 0)

•ls: (unsigned lower or same) 無(wú)符號(hào)比較,小于等于 (c = 0 & z = 1)

•ge: (signed greater than or equal) 有符號(hào)比較,大于等于 (n = v)

•lt: (signed less than) 有符號(hào)比較,小于 (n != v)

•gt: (signed greater than) 有符號(hào)比較,大于 (z = 0 & n = v)

•le: (signed less than or equal) 有符號(hào)比較,小于等于 (z = 1 | n != v)

•al: (always) 無(wú)條件,默認(rèn)值

•nv: (never) 從不執(zhí)行

6. 移位操作(lsl、asl、lsr、asr、ror、rrx)

移位操作在arm指令集中不作為單獨(dú)的命令使用,它在指令格式中是一個(gè)字段。接下來(lái)將會(huì)介紹一下各種移位操作。如果你之前學(xué)過“數(shù)字電路”這門課的話,那么你肯定對(duì)這些移位操作并不陌生。

(1)、lsl ---- 邏輯左移(logical shift left)與 asl ---- 算術(shù)左移 (arithmetic shift left)

邏輯左移與算術(shù)左移的操作是一樣的,都是將操作數(shù)向左移位,低位補(bǔ)零,移除的高位進(jìn)行丟棄。接下來(lái)我們來(lái)看一個(gè)示例,根據(jù)這個(gè)示例來(lái)看一下lsl或者asl的工作方式。

mov r0, #5
mov r1, r0, lsl #2

上述命令,就是將5存儲(chǔ)到r0寄存器上(r0 = 5), 然后將r0邏輯左移2位后傳送到r1寄存器中。十進(jìn)制5的二進(jìn)制數(shù)值是0101,進(jìn)行邏輯左移2位就是0001_0100, 也就是十進(jìn)制中的20。其實(shí)沒邏輯左移1位就相當(dāng)于原數(shù)值進(jìn)行乘2操作,5邏輯左移2位其實(shí)就是5 x 2^2 = 20。下方是該操作的原理圖

iOS逆向工程之Hopper中的ARM指令詳解

(2)、lsr ---- 邏輯右移(logical shift right)

邏輯右移與邏輯左移是相對(duì)的,邏輯右移其實(shí)就是往右移位,左邊補(bǔ)零。用法與lsl類似,在此就不做過多贅述了。

(3)、asr ---- 算術(shù)右移(arithmetic shift right)

asr與lsr類似,唯一不同的是,lsr的高位補(bǔ)零,而asr的高位補(bǔ)符號(hào)位。符號(hào)位為1,那么就補(bǔ)1,符號(hào)位為0那么就補(bǔ)零。

(4)、ror ---- 循環(huán)右移(rotate right)

循環(huán)右移,見名知意,就是循環(huán)著往右移動(dòng),右邊移除的位往高位進(jìn)行填補(bǔ)。

以上所述是小編給大家介紹的ios逆向工程之hopper中的arm指令詳解,希望對(duì)大家有所幫助

原文鏈接:http://www.cnblogs.com/ludashi/archive/2016/09/23/5740696.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 极品一区| 亚洲高清视频网站 | 911精品国产亚洲日本美国韩国 | 日本在线播放 | 射18p| 亚洲国产货青视觉盛宴 | 波多野结衣被绝伦强在线观看 | 国产91精品久久久久久久 | 探花 在线 | 日韩久久精品 | 玩乳h文奶水和尚 | 校花被强迫np肉高h 校服下的白嫩小乳尖h1v1 | 青视频在线| 国产第一页无线好源 | 欧美黑人成人免费全部 | 女人把扒开给男人爽 | 亚洲精品国产SUV | 草逼视频免费看 | jj免费视频| 鬼畜重口高h合集长短篇 | 97热在线 | 国产精品九九久久一区hh | 99欧美视频 | 国产图片综合区 | 国产福利兔女郎在线观看 | 亚洲 另类 欧美 变态屎尿 | 国产欧美精品一区二区三区–老狼 | 国产91第一页 | 日本在线观看免费高清 | 久久全国免费久久青青小草 | 东京道一本热大交乱 | 国产亚洲女在线线精品 | 538免费精品视频搬运工 | 青青草精品 | 成人免费观看在线视频 | 四虎影视884aa·com| 国产一区二区三区在线 | 免费视频精品一区二区三区 | 青青草国产精品久久碰 | 九九九九九热 | 色婷婷激婷婷深爱五月老司机 |