6.【干貨】火爆全網(wǎng)的《超全NDK精品教程》JNI so庫奔潰&第三方so庫奔潰hook解決方案

NDK異常信息一般有三個要素:


ndk--------->墓碑

第一步:?

cd /data/tombstones/??

第二步:?

/data/tombstones # ls -lht

第三步:?

more cdc_8295-221024-197-tombstone_048?

so庫是如何生成的 ????

cmake生成.so方案

以上方案都是通通不行的,最終找到是Cmake 3.10.2版本過高土全,與build版本不一致造成的

NDK異常信息一般有三個要素:

信號

調(diào)用棧信息(棧地址茅郎,內(nèi)存地址)

寄存器信息

錯誤信號:11是信號量sigNum委煤,SIGSEGV是信號的名字,SEGV_MAPERR是SIGSEGV下的一種類型。

寄存器快照:進(jìn)程收到錯誤信號時保存下來的寄存器快照衔肢,其中PC寄存器存儲的就是下個要運(yùn)行的指令(出錯的位置)。

調(diào)用棧:#00是棧頂豁翎,#02是棧底角骤,#02調(diào)用#01調(diào)用#00方法,#00的方法時libspirit.so中的Spirit類下的testCrash方法,出錯的地方是testCrash方法內(nèi)匯編偏移17(不是行號哦0钭稹)

通常的來源有三個:

1背桐、硬件發(fā)生異常,即硬件(通常是CPU)檢測到一個錯誤條件并通知Linux內(nèi)核蝉揍,內(nèi)核處理該異常链峭,給相應(yīng)的進(jìn)程發(fā)送信號。硬件異常的例子包括執(zhí)行一條異常的機(jī)器語言指令又沾,諸如弊仪,被0除,或者引用了無法訪問的內(nèi)存區(qū)域杖刷。大部分信號如果沒有被進(jìn)程處理励饵,默認(rèn)的操作就是殺死進(jìn)程。在本文中挺勿,SIGSEGV(段錯誤)曲横,SIGBUS(內(nèi)存訪問錯誤),SIGFPE(算數(shù)異常)屬于這種信號不瓶。

2禾嫉、進(jìn)程調(diào)用的庫發(fā)現(xiàn)錯誤,給自己發(fā)送中止信號蚊丐,默認(rèn)情況下熙参,該信號會終止進(jìn)程。在本文中麦备,SIGABRT(中止進(jìn)程)屬于這種信號孽椰。

3、用戶(手賤)或第三方App(惡意)通過kill-信號 pid的方式給錯誤進(jìn)程發(fā)送凛篙,這時signal中的si_code會小于0黍匾。

SO庫奔潰總結(jié)方案:

1.添加日志信息

2.找到c的源代碼生成帶符號的so庫。

3.安裝bugly呛梆,分析具體那一行出了問題

4.jni異常和c++異常的基本分析和解決辦法

5.從奔潰信息中可以反饋一個問題:c比較安全锐涯,比較難破解

=====================================================

need-to-insert-img

在介紹工具之前,先簡單講一下有調(diào)試與無調(diào)試信息的兩個版本 so 填物。 一個含有 native 代碼的 app 項目的典型結(jié)構(gòu)是這樣的:

一般的分析崩潰日志的工具都是利用含有調(diào)試信息的 so纹腌, 結(jié)合崩潰信息,分析崩潰點(diǎn)在源代碼中的行號滞磺。

通常一次編譯會先生成一個有含有調(diào)試信息的 so升薯, 路徑通常是在 obj/local/ 各 abi 目錄下,其中還有一些中間文件(比如.o文件)击困;再通過對這些含有調(diào)試信息的 so 進(jìn)行一次 strip 涎劈, 產(chǎn)生對應(yīng)的無調(diào)試信息 so, 放到 libs 目錄下各 abi 目錄中, 發(fā)布產(chǎn)品時责语,我們都是用這些 strip 后的 so炮障。

————————————————

1.android如何編譯出帶符號表的.so庫

如果是mk:可以直接生成2種so庫

如果是cmake:debug版本就是帶符號的。release就是不帶符號的坤候。

用默認(rèn)的so庫路徑

#生成的so文件目錄

#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../../../src/main/jniLibs/armebai-v7a)

把自己生成的注釋掉

bugly:分析有符號的so庫

https://bugly.qq.com/docs/user-guide/symbol-configuration-android/?v=1590754344571#_11

符號表:

need-to-insert-img

VS 編寫實(shí)現(xiàn)方法生成 dll 動態(tài)庫

使用VisualStudio高效開發(fā)調(diào)試AndroidNDK

cmake編譯so庫胁赢。然后同時生成apk。

會發(fā)現(xiàn):會先編譯然后生成的apk會把so打包進(jìn)去白筹。放心好了

===========================================================================

2.so庫奔潰具體行數(shù):定位so奔潰的行數(shù)

Android NDK墓碑/崩潰分析

閃退發(fā)生時在logcat中將日志過濾條件選為“No Filters”就可以看到完整的閃退日志智末,或者叫tombstone(墓碑)文件。

tombstone(墓碑)是當(dāng)系統(tǒng) crash 的時候徒河,會保存一個 tombstone 文件到/data/tombstones目錄下(Logcat中也會有相應(yīng)的信息)

https://blog.csdn.net/crash163/article/details/51605926

3.NDK安裝包中提供了三個調(diào)試工具:addr2line系馆、objdump和ndk-stack,

google官方提供的ndk-stack工具分析:

https://developer.android.google.cn/ndk/guides/ndk-stack?hl=zh-cn

4.bugly的定位原理:ndk-stack使用:

https://blog.csdn.net/xyang81/article/details/42319789

Android ndk-stack 定位so庫crash位置

如果你覺得上面的方法太麻煩的話顽照,ndk-stack可以幫你減輕操作步聚由蘑,直接定位到代碼出錯的位置。

使用adb獲取logcat的日志代兵,并通過管道輸出給ndk-stack分析尼酿,并指定包含符號表的so文件位置。如果程序包含多種CPU架構(gòu)植影,需要根據(jù)手機(jī)的CPU類型裳擎,來選擇不同的CPU架構(gòu)目錄。以armv7架構(gòu)為例思币,執(zhí)行如下命令:

1.運(yùn)行終端鹿响。?跳轉(zhuǎn)到你android sdk 目錄 因為你的adb 在里面。

如 cd /Users/name/Android/adt-bundle-mac-x86_64-20131030/sdk/platform-tools?

2谷饿、找了路徑正確繼續(xù)下一步惶我,./adb logcat | 你android ndk-stack所在的路徑 -sym /你安卓工程.so文件所在的目錄

如./adb logcat | /Users/name/Android/android-ndk-r8e/ndk-stack -sym /Users/name/test/proj.android/obj/local/armeabi

3、正確配置后會在終端出現(xiàn)

- waiting for device -

adb logcat | $NDK_HOME/ndk-stack -sym $PROJECT/libs/armeabi

其中博投,$PROJECT/libs/armeabi是so的路徑指孤。

adb logcat | $NDK_HOME/ndk-stack -sym /Users/mac/AiOpen/AiOpen/app/jni-libs/armeabi

adb logcat > /Users/mac/ndk/tongue.txt

$NDK_HOME/ndk-stack -sym /Users/mac/AiOpen/AiOpen/app/jni-libs/armeabi -dump /Users/mac/ndk/tongue.txt

可以看到具體的行數(shù)

need-to-insert-img

need-to-insert-img

總結(jié):

如果是so庫找不到,那么看不到詳情

null指針可以

5.so庫奔潰贬堵,日志種類分析:

http://www.reibang.com/p/d8ef41edb1bd(不錯)

結(jié)合signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0信息,配合崩潰信號列表:

信號描述

SIGSEGV內(nèi)存引用無效结洼。

SIGBUS訪問內(nèi)存對象的未定義部分黎做。

SIGFPE算術(shù)運(yùn)算錯誤,除以零松忍。

SIGILL非法指令蒸殿,如執(zhí)行垃圾或特權(quán)指令

SIGSYS糟糕的系統(tǒng)調(diào)用

SIGXCPU超過CPU時間限制。

SIGXFSZ文件大小限制。

1宏所、SIGSEGV 段錯誤

SEGV_MAPERR 要訪問的地址沒有映射到內(nèi)存空間酥艳。 比如上面對空指針的寫操作, 當(dāng)指針被意外復(fù)寫為一個較小的數(shù)值時爬骤。

SEGV_ACCERR 訪問的地址沒有權(quán)限充石。比如試圖對代碼段進(jìn)行寫操作。

2霞玄、SIGFPE 浮點(diǎn)錯誤骤铃,一般發(fā)生在算術(shù)運(yùn)行出錯時。

FPE_INTDIV 除以0

FPE_INTOVE 整數(shù)溢出

3坷剧、SIGBUS 總線錯誤

BUS_ADRALN 地址對齊出錯惰爬。arm cpu比x86 cpu 要求更嚴(yán)格的對齊機(jī)制,所以在 arm cpu 機(jī)器中比較常見惫企。

4撕瞧、SIGILL 發(fā)生這種錯誤一般是由于某處內(nèi)存被意外改寫了。

ILL_ILLOPC 非法的指令操作碼

ILL_ILLOPN 非法的指令操作數(shù)

5狞尔、當(dāng)調(diào)用堆棧中出現(xiàn) stack_chk_fail 函數(shù)時丛版,一般是由于比如 strcpy 之類的函數(shù)調(diào)用將棧上的內(nèi)容覆蓋,而引起棧檢查失敗沪么。

Testin崩潰分析如何幫開發(fā)者發(fā)現(xiàn)NDK錯誤

以上提到的方法硼婿,只適合在開發(fā)測試期間,如果你的應(yīng)用或游戲已經(jīng)上線禽车,而用戶經(jīng)常反饋說崩潰寇漫、閃退,指望用戶幫你收集信息定位問題幾乎是不可能的殉摔。這個時候州胳,我們就需要用其他的手段來捕獲崩潰信息。


目前業(yè)界已經(jīng)有一些公司推出了崩潰信息收集的服務(wù)逸月,通過嵌入SDK栓撞,在程序發(fā)生崩潰時收集堆棧信息,發(fā)送到云服務(wù)平臺碗硬,從而幫助開發(fā)者定位錯誤信息瓤湘。在這方面,國內(nèi)的Testin和國外的crittercism都可以提供類似服務(wù)恩尾。


Testin從1.4版本開始支持NDK的崩潰分析弛说,其最新版本已升級到1.7。當(dāng)程序發(fā)生NDK錯誤時翰意,其內(nèi)嵌的SDK會收集程序在用戶手機(jī)上發(fā)生崩潰時的堆棧信息(主要就是上面我們通過logcat日志獲取到的函數(shù)指針)木人、設(shè)備信息信柿、線程信息等,SDK將這些信息上報至Testin云服務(wù)平臺醒第,在平臺進(jìn)行唯一性的處理渔嚷、并可以自定義時段進(jìn)行詳盡的統(tǒng)計分析,從多維度展示程序崩潰的信息和嚴(yán)重程度稠曼;最新版本還支持用戶自定義場景形病,方便開發(fā)者定位問題所在。


從用戶手機(jī)上報的堆棧信息蒲列,Testin為NDK崩潰提供了符號化的功能窒朋,只要將我們編譯過程中產(chǎn)生的包含符號表的so文件上傳,就可以自動將函數(shù)指針地址定位到函數(shù)名稱和代碼行數(shù)蝗岖。符號化之后侥猩,看起來就和我們前面在本地測試的結(jié)果是一樣的了,一目了然抵赢。而且使用這個功能還有一個好處:這些包含符號表的so文件欺劳,在每次開發(fā)者編譯之后都會改變,很有可能我們發(fā)布之后就已經(jīng)變了铅鲤,因為開發(fā)者會修改程序划提。在這樣的情況下,即使我們拿到了崩潰時的堆棧信息邢享,那也無法再進(jìn)行符號化了鹏往。我們可以將這些文件上傳到Testin進(jìn)行符號化的工作,Testin會為我們保存和管理不同版本的so文件骇塘,確保信息不會丟失伊履。

NDK | 說說 so 庫從加載到卸載的全過程

https://juejin.cn/post/6892793299427491854

.so文件的區(qū)別

armeabi、armeabi-v7a和x86都表示CPU的類型款违。一般的手機(jī)或平板都是用arm的cpu唐瀑。

不同的cpu的特性不一樣,armeabi就是針對普通的或舊的

arm v5 cpu插爹,armeabi-v7a是針對有浮點(diǎn)運(yùn)算或高級擴(kuò)展功能的arm v7 cpu哄辣。

mips、armeabi赠尾、armeabi-v7a和x86到底是什么

armeabi:默認(rèn)選項力穗,將創(chuàng)建以基于

ARM* v5TE 的設(shè)備為目標(biāo)的庫。 具有這種目標(biāo)的浮點(diǎn)運(yùn)算使用軟件浮點(diǎn)運(yùn)算气嫁。 使用此 ABI (二進(jìn)制接口)

創(chuàng)建的二進(jìn)制代碼將可以在所有 ARM* 設(shè)備上運(yùn)行当窗。所以armeabi通用性很強(qiáng)。但是速度慢

armeabi-v7a:創(chuàng)建支持基于 ARM* v7 的設(shè)備的庫杉编,并將使用硬件 FPU 指令超全。armeabi-v7a是針對有浮點(diǎn)運(yùn)算或高級擴(kuò)展功能的arm v7 cpu。

x86:支持基于硬件的浮點(diǎn)運(yùn)算的?

總結(jié):

不同的CPU不用的芯片邓馒,armeabi是最基本的嘶朱,有不同的運(yùn)算指令,如浮點(diǎn)運(yùn)算光酣,所以需要生成不同的.so文件

如果項目只包含了?armeabi疏遏,那么在所有android設(shè)備都可以運(yùn)行; 如果項目只包含了 armeabi-v7a救军,除armeabi架構(gòu)的設(shè)備外都可以運(yùn)行财异;?

如果項目只包含了 x86,那么armeabi架構(gòu)和armeabi-v7a的Android設(shè)備是無法運(yùn)行的唱遭;

如果同時包含了 armeabi戳寸, armeabi-v7a和x86,

所有設(shè)備都可以運(yùn)行拷泽,程序在運(yùn)行的時候去加載不同平臺對應(yīng)的so疫鹊,這是較為完美的一種解決方案,同時也會導(dǎo)致包變大司致。

2. 接下來說明這么做的依據(jù):?

看上面圖分析拆吆,armeabi-v7主要不支持ARMv5(1998年誕生)和ARMv6(2001年誕生).目前這兩款處理器的手機(jī)設(shè)備基本不在我公司的適配范圍(市場占比太少)。?

而許多基于 x86 的設(shè)備也可運(yùn)行 armeabi-v7a 和 armeabi NDK 二進(jìn)制文件脂矫。對于這些設(shè)備枣耀,主要 ABI 將是 x86,輔助 ABI 是 armeabi-v7a庭再。?

最后總結(jié)一點(diǎn):如果適配版本高于4.1版本捞奕,可以直接像我上面這樣寫,當(dāng)然佩微,如果armeabi-v7a不是設(shè)備主要ABI缝彬,那么會在性能上造成一定的影響。?

---------------------?

早期的Android系統(tǒng)幾乎只支持ARMv5的CPU架構(gòu)哺眯。你知道現(xiàn)在它支持多少種嗎谷浅?7種!

Android系統(tǒng)目前支持以下七種不同的CPU架構(gòu):ARMv5奶卓,ARMv7 (從2010年起)一疯,x86 (從2011年起),MIPS (從2012年起)夺姑,ARMv8墩邀,MIPS64和x86_64 (從2014年起),每一種都關(guān)聯(lián)著一個相應(yīng)的ABI盏浙。

應(yīng)用程序二進(jìn)制接口(Application Binary Interface)定義了二進(jìn)制文件(尤其是.so文件)如何運(yùn)行在相應(yīng)的系統(tǒng)平臺上眉睹,從使用的指令集荔茬,內(nèi)存對齊到可用的系統(tǒng)函數(shù)庫。在Android系統(tǒng)上竹海,每一個CPU架構(gòu)對應(yīng)一個ABI:armeabi慕蔚,armeabi-v7a,x86斋配,mips孔飒,arm64-v8a,mips64艰争,x86_64坏瞄。

4. ABI 兼容性

目前搜索的資料總結(jié)如下:

armeabi-v7a :armeabi-v7a向下兼容armeabi

arm64-v8a : 能兼容 armeabi-v7a 和 armeabi

x86_64 : 兼容 x86

mips64 : 兼容 mips

目前主流 APP 所用的 ABI 各是哪些

數(shù)據(jù)是?2017/4/8看的市場最新版,采集的幾個代表性樣本如下:

僅有 armeabi :?微博甩卓,今日頭條鸠匀,淘寶,QQ猛频,微信狮崩。

armeabi 與 armeabi-v7a:?UC 瀏覽器。

armeabi鹿寻,armeabi-v7a睦柴,armeabi-x86:優(yōu)酷,嗶哩嗶哩動畫毡熏。

7種類型全有:知乎坦敌。

現(xiàn)在主要是armV7的架構(gòu)和x86

我也看了目前流行的游戲 王者榮耀(因為我只安裝了它。痢法。狱窘。哈哈),發(fā)現(xiàn)它僅有 armeabi-v7a财搁。

ABI和CPU的關(guān)系

很多設(shè)備都支持多于一種的ABI蘸炸。例如ARM64和x86設(shè)備也可以同時運(yùn)行armeabi-v7a和armeabi的二進(jìn)制包。但最好是針對特定平臺提供相應(yīng)平臺的二進(jìn)制包尖奔,這種情況下運(yùn)行時就少了一個模擬層(例如x86設(shè)備上模擬arm的虛擬層)

CPU/ABIarmeabiarmeabi-v7aarm64-v8ax86x86_64mipsmips64

ARMv5支持

ARMv7支持支持

ARMv8支持支持支持

x86支持支持 支持

x86_64支持      支持支持

mips      支持

mips_64      支持支持

need-to-insert-img

通過指令查看cpu的信息搭儒,包含cpu的架構(gòu)

如何查看so庫安裝在手機(jī)里面存放在了什么位置立美?和它到底加載哪個

你應(yīng)該盡可能的提供專為每個ABI優(yōu)化過的.so文件丹泉,但要么全部支持,要么都不支持:你不應(yīng)該混合著使用贡珊。你應(yīng)該為每個ABI目錄提供對應(yīng)的.so文件茴扁。

當(dāng)一個應(yīng)用安裝在設(shè)備上铃岔,只有該設(shè)備支持的CPU架構(gòu)對應(yīng)的.so文件會被安裝。在x86設(shè)備上峭火,libs/x86目錄中如果存在.so文件的話毁习,會被安裝智嚷,如果不存在,則會選擇armeabi-v7a中的.so文件纺且,如果也不存在纤勒,則選擇armeabi目錄中的.so文件(因為x86設(shè)備也支持armeabi-v7a和armeabi)。

正確的做法

當(dāng)前市面絕大多數(shù)是arm的CPU隆檀,而且都是V7架構(gòu)的了,所以可以保留armeabi或者armeabi-v7a即可粹湃。

如果僅保留armeabi-v7a恐仑,而有些第三方包未提供v7a的包,則可以將對應(yīng)armeabi包拷貝到armeabi-v7a为鳄。

如果同時保留armeabi和armeabi-v7a裳仆,則需要保證兩個目錄下的so庫文件數(shù)相同。

so庫:https://juejin.im/post/5eae6f86e51d454ddb0b3dc6

3.NDK問題 孤钦,so庫類型不對奔潰

ndk {

abiFilters"armeabi"

}

4.奔潰歧斟,因為找不到方法或者so庫奔潰,方法找不到原因:要包名一樣才行的

?java.lang.UnsatisfiedLinkError: No implementation found for double

6.NDK版本不對偏形,導(dǎo)致奔潰問題

完美解決 No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android

https://blog.csdn.net/qq_24118527/article/details/82867864

7..地址配置有問題:拼接

Unable to resolve host "open-api1.51yund.comauth": No address associated with hostname

==========================

https://blog.csdn.net/scruffybear/article/details/129459810

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末静袖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子俊扭,更是在濱河造成了極大的恐慌队橙,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萨惑,死亡現(xiàn)場離奇詭異捐康,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)庸蔼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門解总,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人姐仅,你說我怎么就攤上這事花枫。” “怎么了萍嬉?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵乌昔,是天一觀的道長。 經(jīng)常有香客問我壤追,道長磕道,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任行冰,我火速辦了婚禮溺蕉,結(jié)果婚禮上伶丐,老公的妹妹穿的比我還像新娘。我一直安慰自己疯特,他們只是感情好哗魂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著漓雅,像睡著了一般录别。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上邻吞,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天组题,我揣著相機(jī)與錄音,去河邊找鬼抱冷。 笑死崔列,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的旺遮。 我是一名探鬼主播赵讯,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼耿眉!你這毒婦竟也來了边翼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鸣剪,失蹤者是張志新(化名)和其女友劉穎讯私,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體西傀,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斤寇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了拥褂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娘锁。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饺鹃,靈堂內(nèi)的尸體忽然破棺而出莫秆,到底是詐尸還是另有隱情,我是刑警寧澤悔详,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布镊屎,位于F島的核電站,受9級特大地震影響茄螃,放射性物質(zhì)發(fā)生泄漏缝驳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望用狱。 院中可真熱鬧运怖,春花似錦、人聲如沸夏伊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溺忧。三九已至咏连,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鲁森,已是汗流浹背捻勉。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刀森,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓报账,卻偏偏與公主長得像研底,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子透罢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容