Android打包的一些分析

Android市場(chǎng)的渠道分散已不是什么新鮮事,但如何高效打包仍是令許多開發(fā)者頭疼的問題铣耘。本篇文章著重介紹了目前最新的三種打包方案票堵,并且從安全方面對(duì)這三種方案進(jìn)行點(diǎn)評(píng)慎璧,相信會(huì)給開發(fā)者帶來新的助力砍鸠。

一般需求的打包扩氢,一條行命令就出來了。復(fù)雜一些的話爷辱,也就是一個(gè)簡(jiǎn)單的開源工具,或是一段小配置代碼就搞定了朦肘。既然如此饭弓,為什么我還要來寫Android打包相關(guān)內(nèi)容?主要有以下兩個(gè)方面的原因:

Android市場(chǎng)開放媒抠,渠道越來越多弟断,幾千個(gè)渠道已經(jīng)是常態(tài)。所以趴生,需要一個(gè)高效且安全的打包方式阀趴,來支持成千上萬的渠道打包重任。

現(xiàn)在Android應(yīng)用程序都會(huì)使用ProGuard或者DexGuard來進(jìn)行代碼混淆苍匆,在引入代碼混淆的前提下刘急,需要針對(duì)某一個(gè)版本盡量只保留一份符號(hào)表(Android是mapping文件)。多份不同的符號(hào)表對(duì)應(yīng)到一個(gè)版本的程序浸踩,會(huì)給Crash修正等后期問題的追查造成很大困難叔汁。

所以,當(dāng)Android開發(fā)團(tuán)隊(duì)有一定規(guī)模時(shí)检碗,需要一種優(yōu)雅并且高效安全的打包方式來銜接從代碼到應(yīng)用程序包的這個(gè)過程据块。

歷史回顧

大概在3-4年前,國內(nèi)的移動(dòng)開發(fā)者都會(huì)使用友盟來做Crash收集和一些用戶的行為數(shù)據(jù)收集折剃。所以另假,友盟定義渠道的方式基本定義了數(shù)據(jù)收集工具的渠道定義方式。友盟默認(rèn)的渠道直接從AndroidManifest文件中的meta-data里面讀取怕犁。如以下代碼所示:

'' '' '' ''

在示例中边篮,UMENG_APPKEY是賬戶的唯一標(biāo)示己莺,UMENG_CHANNEL的內(nèi)容為wandoujia,即表示這時(shí)渠道是wandoujia苟耻。這里再多說一句渠道的概念夏醉,一般的渠道可能會(huì)表示具體是哪個(gè)應(yīng)用市場(chǎng)泡垃。比如上傳豌豆莢和上傳360手機(jī)助手的渠道標(biāo)示不一樣,當(dāng)然,如果有一些線下推廣的話一铅,也需要區(qū)分渠道。隨著數(shù)據(jù)統(tǒng)計(jì)越來越細(xì)票摇,渠道也會(huì)更加的層出不窮『ヒ荆現(xiàn)在一個(gè)日活在百萬的應(yīng)用,Android的渠道在幾千個(gè)是非常正常的現(xiàn)象杈湾。

在AndroidManifest定義渠道的年代解虱,多渠道打包無非以下兩種方案:

方案一:完全的重新編譯,即在代碼重新編譯打包之前漆撞,在AndroidManifest中修改渠道標(biāo)示殴泰;

方案二:通過ApkTool進(jìn)行解包,然后修改AndroidManifest中修改渠道標(biāo)示浮驳,最后再通過ApkTool進(jìn)行打包悍汛、簽名。

現(xiàn)在看來至会,這兩種方式效率都不高离咐。方案一基本上毫無效率可言,只能支持20個(gè)以內(nèi)的渠道規(guī)模奉件。方案二效率高一些宵蛀,如果再引入多線程驅(qū)動(dòng)來進(jìn)行打包,支持200以內(nèi)的渠道打包毫無壓力县貌。但是隨著Android的版本升級(jí)术陶,代碼混淆和加固工具的引入,這種方案已經(jīng)不能正常運(yùn)行了窃这。所以瞳别,需要一種兼容性好并且高效的多渠道打包方式。

三種高效的多渠道打包方式

Android項(xiàng)目本身是開源的杭攻,大家都可以去研究任何實(shí)現(xiàn)祟敛,基于這個(gè)特性,一種叫做“Android黑科技”的學(xué)科迅速誕生兆解。以下介紹的多渠道打包方式都應(yīng)該屬于其范疇馆铁。

添加comments多渠道打包

首先解釋什么是comments(注釋或評(píng)論)的打包方式?

Android應(yīng)用使用的APK文件就是一個(gè)帶簽名信息的zip文件锅睛,根據(jù)zip文件格式規(guī)范(請(qǐng)參見:https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)埠巨,每個(gè)文件的最后都必須有一個(gè)叫Central Directory Record(https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html)的部分历谍,這個(gè)CDR的最后部分叫“End of Central Directory Record”,這一部分包含一些元數(shù)據(jù)辣垒,它的末尾是zip文件的注釋望侈。注釋包含Comment Length和File Comment兩個(gè)字段。前者表示注釋的長(zhǎng)度勋桶,后者是注釋的內(nèi)容脱衙,正確修改這一部分不會(huì)對(duì)zip文件造成破壞,利用這個(gè)字段例驹,我們可以添加一些自定義數(shù)據(jù)捐韩。

簡(jiǎn)單來說就是:我們利用的是zip文件“可以添加comment(摘要)”的數(shù)據(jù)結(jié)構(gòu)特點(diǎn),在文件的末尾寫入任意數(shù)據(jù)鹃锈,而不用重新解壓zip文件(apk文件就是zip文件格式)荤胁;所以該工具不需要對(duì)APK文件解壓縮和重新簽名即可完成多渠道自動(dòng)打包,可謂是高效屎债、速度快仅政,無兼容問題。

這種高效的方式是奇虎360的一位工程師公布的盆驹,他已經(jīng)把相關(guān)工具的代碼開放在GitHub上面了已旧,地址為https://github.com/seven456/MultiChannelPackageTool。工具本身為命令行形式召娜,一條命令即可生成一個(gè)多渠道包,并且非常高效惊楼。作者本人公布的性能數(shù)據(jù)是:5M的APK玖瘸,1秒種能打300個(gè)。

就是因?yàn)樗俣确浅檀咙?煅诺梗F(xiàn)在一些廠商用這種方案來做安裝包的動(dòng)態(tài)生成。在用戶下載之前渠道是沒有添加進(jìn)去的弧可,用戶選擇下載以后通過渠道來源判斷渠道標(biāo)示蔑匣,并且寫入。過程瞬間完成棕诵,用戶下載時(shí)毫無感知裁良。

當(dāng)然,利用工具把渠道寫入應(yīng)用程序包內(nèi)校套,還應(yīng)該提供一種在APK內(nèi)部讀取渠道的方式价脾。讀取時(shí)方法也非常簡(jiǎn)單,首先通過反射方法找到APK在手機(jī)中的位置笛匙,然后通過讀zip comment的方式獲取渠道內(nèi)容侨把。讀取comment和找APK位置的代碼都能在這個(gè)急速添加渠道的工具中找到犀变,在這里不再詳細(xì)介紹。需要注意的是秋柄,在Android中使用Java反射的性能非常差获枝,需要做一些優(yōu)化處理。

如果你覺得這種方式的安全比較差骇笔,也可以自己重新實(shí)現(xiàn)一個(gè)小工具省店,并且對(duì)comment的內(nèi)容加密。當(dāng)然蜘拉,加密使用的密鑰需要在APK代碼中體現(xiàn)萨西,這種加密方案也只是提高了一點(diǎn)破譯的門檻而已。

美團(tuán)的Android多渠道打包

美團(tuán)點(diǎn)評(píng)技術(shù)團(tuán)隊(duì)(原美團(tuán)技術(shù)團(tuán)隊(duì))有一個(gè)公開的博客旭旭,每篇文章都在領(lǐng)域內(nèi)有一定的影響谎脯。其中有一篇就是討論“如何高效地進(jìn)行Android多渠道打包?”持寄,可參見:http://tech.meituan.com/mt-apk-packaging.html源梭。

文章中首先提到了ApkTool的多渠道打包方式,然后講到美團(tuán)的業(yè)務(wù)發(fā)展已經(jīng)有900多個(gè)渠道稍味,ApkTool的方式已經(jīng)不能支持這種規(guī)模的多渠道打包废麻。所以,美團(tuán)點(diǎn)評(píng)技術(shù)團(tuán)隊(duì)開始探索一種更加高效的多渠道打包方式模庐。

美團(tuán)的做法是把一個(gè)Android應(yīng)用包當(dāng)作zip文件包進(jìn)行解壓烛愧,然后發(fā)現(xiàn)在簽名生成的目錄下添加一個(gè)空文件不需要重新簽名。利用這個(gè)機(jī)制掂碱,該文件的文件名就是渠道名怜姿。這種方式不需要重新簽名等步驟,非常高效疼燥。

下面我們來詳細(xì)講解一下這個(gè)過程沧卢。首先把一個(gè)已經(jīng)簽名好的Android應(yīng)用程序包解壓縮,簽名文件的目錄為:META-INF醉者,如圖1所示但狭。

圖1 美團(tuán)Android多渠道打包壓縮文件目錄

圖中有兩個(gè)框選的部分,分別為:assets目錄和META-INF目錄撬即。assets等下文介紹豌豆莢高效打包方式的時(shí)候再說立磁。我們這里先來看看META-INF目錄。在META-INF目錄下的三個(gè)文件搞莺,就是一個(gè)Android應(yīng)用程序包被正確簽名之后的生成文件息罗,當(dāng)這個(gè)程序包中的文件被修改以后,驗(yàn)證信息就需要重新生成才沧,否則驗(yàn)證的簽名信息就不正確迈喉。這套簽名機(jī)制也是從Java的jar包方式繼承過來的绍刮。

美團(tuán)多渠道打包方式,正是利用簽名的驗(yàn)證方式挨摸,巧妙地放入了一個(gè)空文件孩革,利用文件名來表示渠道方式的完成。如果放入了一個(gè)非空的文件得运,這時(shí)簽名驗(yàn)證的機(jī)制就會(huì)被破壞膝蜈。美團(tuán)的具體做法是通過一段簡(jiǎn)單的Python腳本來完成。代碼如下:

'' import zipfile

'' zipped = zipfile.ZipFile(your_apk, 'a', zipfile.ZIP_DEFLATED)

'' empty_channel_file = "META-INF/mtchannel_{channel}".format(channel=your_channel)

'' zipped.write(your_empty_file, empty_channel_file)

通過運(yùn)行Python腳本熔掺,Android應(yīng)用程序包中便會(huì)多出一個(gè)文件饱搏,如圖2所示。

圖2 通過運(yùn)行Python腳本置逻,Android應(yīng)用程序包中多出來的一個(gè)文件

渠道添加成功后推沸,可以參照美團(tuán)點(diǎn)評(píng)技術(shù)團(tuán)隊(duì)的博客,在Android程序中添加讀取渠道的代碼券坞,即可擁有高效的多渠道打包方式鬓催。

當(dāng)然,這個(gè)技術(shù)實(shí)現(xiàn)本身可以有更加優(yōu)雅和高效的方式——添加渠道恨锚。原理不變宇驾,添加方式可以進(jìn)行改變。添加文件可以使用AAPT這個(gè)工具猴伶。AAPT本身是Android平臺(tái)自帶的一個(gè)命令行工具课舍,可以實(shí)現(xiàn)從Android程序包中刪除和添加任意文件。當(dāng)然他挎,如果添加文件破壞了簽名驗(yàn)證信息布卡,則是另外一回事了。關(guān)于AAPT的使用和其在多渠道簽名打包時(shí)的用法雇盖,會(huì)在下文進(jìn)行講解。

如果現(xiàn)在想把美團(tuán)的渠道刪除栖忠,使用AAPT輸入一條簡(jiǎn)單的命令行即可(能刪除就能添加崔挖,添加部分還是在豌豆莢多渠道打包方案中介紹吧):

'' aapt remove? meituan.apk META-INF/mtchannel_meituan

豌豆莢Android多渠道打包

豌豆莢的多渠道打包方案和美團(tuán)的所用的方式一樣,都是添加一個(gè)文件庵寞,文件本身會(huì)帶入渠道消息狸相。但不同點(diǎn)在于它添加的是一個(gè)不為空的文件。之前已經(jīng)提到過了捐川,如果添加一個(gè)非空文件脓鹃,就會(huì)破壞簽名校驗(yàn),需要重新簽名古沥。

從這個(gè)方案可以看出瘸右,豌豆莢多渠道打包和美團(tuán)多渠道打包正好是利用了一個(gè)特性的兩個(gè)方面娇跟。當(dāng)然,如果需要重新簽名太颤,效率會(huì)差一些苞俘。在失去效率的同時(shí),擁有了更加安全的渠道管理龄章。下面具體講解吃谣,豌豆莢多渠道打包管理方案。

首先做裙,如果把渠道文件還放在META-INF目錄下的話岗憋,重新簽名時(shí)渠道文件會(huì)被刪掉。所以锚贱,渠道文件需要重新找一個(gè)合理的地方存放仔戈。之前的文章也提到過,還有一個(gè)assets目錄惋鸥。assets目錄和META-INF目錄一樣杂穷,可以隨便放入小文件。如果是空文件不需要重新簽名

加入渠道時(shí)主要有以下步驟卦绣。

首先需要準(zhǔn)備好渠道文件耐量。在Android應(yīng)用程序包的同級(jí)目錄,新建一個(gè)assets目錄滤港,并且在該目錄下放入一個(gè)channel.txt文件廊蜒,文件內(nèi)容是渠道信息,可以是wandoujia或360等溅漾。

使用AAPT加入渠道文件:

'' aapt add wandoujia.apk asserts/channel.txt

在渠道加入后山叮,重新簽名APK文件并且進(jìn)行對(duì)齊。

重新簽名相關(guān)的步驟就不再介紹了添履,如果感興趣的話屁倔,推薦看一下calabash-android這個(gè)開源項(xiàng)目的resign相關(guān)部分實(shí)現(xiàn),calabash的重新簽名實(shí)現(xiàn)是我見過最嚴(yán)謹(jǐn)?shù)摹?/p>

圖3 豌豆莢打包方案處理一個(gè)包需要大約4秒

說完了豌豆莢多渠道打包的實(shí)現(xiàn)部分以后暮胧,需要來談一下效率锐借。之前的兩種多渠道打包方案效率都很高,處理一個(gè)包都能在1秒之內(nèi)完成往衷。但豌豆莢的多渠道打包方案由于必須重新簽名钞翔,會(huì)慢一些(但也沒有慢多少)。在屏蔽了一些關(guān)鍵信息之后席舍,從圖3中可以看到布轿,一次處理大概需要4秒的時(shí)間。現(xiàn)在一臺(tái)一般配置的計(jì)算機(jī),開8個(gè)線程處理汰扭,速度完全可以接受稠肘。

從安全的角度看多渠道打包方案

三種打包方案都是高效的實(shí)現(xiàn),當(dāng)然也有各自的側(cè)重點(diǎn)东且。以下启具,從安全的角度來分析。

對(duì)于Android應(yīng)用包的安全問題來說珊泳,主要需要考慮渠道被惡意篡改的可能性和成本鲁冯。如果一個(gè)渠道商,通過網(wǎng)絡(luò)劫持和篡改渠道的組合方式來獲取暴利色查,對(duì)于程序開發(fā)者來說可能會(huì)存在著巨大的經(jīng)濟(jì)損失薯演。

在介紹篡改渠道之前,還是先簡(jiǎn)單介紹AAPT這個(gè)工具的一般使用方法秧了。AAPT是在AndroidSDK內(nèi)的一個(gè)命令行工具跨扮,具體位置在AndroidSDK目錄下的build-tools/19.0.0或者其他版本下,AAPT并不存在于每個(gè)發(fā)行版本中验毡,所以一般使用的AAPT是19.0.0或19.0.1版本衡创。

使用AAPT主要有以下4種場(chǎng)景:

查看Android開發(fā)包的基本信息,例如:包名晶通、版本等璃氢。以微信的Android版本為例:

'' INPUT? apt dump badging weixin.apk

'' OUTPUT package: name='com.tencent.mm' versionCode='740' versionName='6.3.13.49_r4080b63'

'' uses-permission:'com.tencent.mm.plugin.permission.READ'

'' uses-permission:'com.tencent.mm.plugin.permission.WRITE'

'' uses-permission:'com.tencent.mm.permission.MM_MESSAGE'

''? uses-permission:'com.huawei.authentication.HW_ACCESS_AUTH_SERVICE'

'' sdkVersion:'15'

'' targetSdkVersion:'23'

'' uses-feature-not-required:'android.hardware.camera'

'' uses-feature-not-required:'android.hardware.camera.autofocus'

'' uses-feature-not-required:'android.hardware.bluetooth'

'' uses-feature-not-required:'android.hardware.location'

'' uses-feature-not-required:'android.hardware.location.gps'

'' uses-feature-not-required:'android.hardware.location.network'

'' uses-feature-not-required:'android.hardware.microphone'

'' uses-feature-not-required:'android.hardware.telephony'

'' uses-feature-not-required:'android.hardware.touchscreen'

'' uses-feature-not-required:'android.hardware.wifi'

'' uses-permission:'android.permission.ACCESS_NETWORK_STATE'

'' uses-permission:'android.permission.ACCESS_COARSE_LOCATION'

'' uses-permission:'android.permission.ACCESS_FINE_LOCATION'

'' uses-permission:'android.permission.CAMERA'

'' .....

從以上代碼可以看到這個(gè)微信的版本信息,并且知道了微信的包名是:com.tencent.mm狮辽,還能看到微信這個(gè)應(yīng)用使用到了哪些權(quán)限等信息(更多的信息還是交給讀者自己仔細(xì)研究吧)一也。

使用AAPT查看Android開發(fā)包的目錄結(jié)構(gòu)如下:

'' INPUT? aapt list? weixin.apk

'' OUTPUT META-INF/MANIFEST.MF

''? META-INF/COM_TENC.SF

''? META-INF/COM_TENC.RSA

''? assets/jsapi/wxjs.js

''? assets/avatar/default_nor_avatar.png

''? assets/avatar/default_meishiapp.png

''? assets/avatar/default_hd_avatar.png

''? assets/ipcall_country_code.txt

''? assets/merged_features.xml

''? assets/address

''? .....

又看到了META-INF目錄和assets目錄。一般在Android的應(yīng)用中assets都會(huì)放一些靜態(tài)的資源喉脖。

使用AAPT添加一個(gè)文件:

'' INPUT aapt add wandoujia.apk? assets/channel.txt

使用AAPT刪除一個(gè)文件

'' INPUT aapt remove wandoujia.apk assets/channel.txt

在掌握了以上簡(jiǎn)單的四個(gè)命令行后椰苟,修改美團(tuán)的渠道就已經(jīng)非常簡(jiǎn)單了。先通過list命令找到渠道文件树叽,然后直接刪除文件舆蝴,最后再加入自己的惡意渠道。但豌豆莢的渠道也可以通過相同的方式來進(jìn)行篡改题诵,但篡改之后需要重新簽名须误。在沒有官方的簽名文件時(shí),是沒有辦法完全偽造一個(gè)相同的簽名的仇轻。

添加comments多渠道打包方式中雖然渠道信息不是明文顯示,但也存在著被篡改的可能性奶甘。如果自己進(jìn)行一些簡(jiǎn)單的加密可以杜絕大多數(shù)的惡意篡改篷店,但由于不需要重新簽名,這種方法還是存在著被篡改的機(jī)率的。

具體選擇哪一種多渠道打包方式疲陕,還是由業(yè)務(wù)決定的方淤。豌豆莢作為一個(gè)應(yīng)用商店,需要有自己的渠道蹄殃,渠道的安全性會(huì)很不好携茂。如果是一個(gè)普通的App,一般都是在一些應(yīng)用商店上發(fā)布新版本诅岩,應(yīng)用商店本身會(huì)給開發(fā)者提供相對(duì)安全的環(huán)境讳苦。所以這也就是美團(tuán)方案依然能夠使用的關(guān)鍵。

結(jié)束語

本文重點(diǎn)介紹了3種高效的多渠道打包方式吩谦。這三種方式都不會(huì)產(chǎn)生二次編譯鸳谜,二次編譯會(huì)對(duì)一個(gè)版本的程序產(chǎn)生多個(gè)版本的符號(hào)表,在后期的問題追查中會(huì)有很多障礙式廷。利用結(jié)束語簡(jiǎn)單說說符號(hào)表的重要性吧咐扭。

當(dāng)程序正確打包發(fā)布以后,可以通過各種免費(fèi)滑废、收費(fèi)或自己開發(fā)的工具來收集Crash等堆棧信息蝗肪,查看錯(cuò)誤并進(jìn)行改正。你可能會(huì)得到一段這樣的異常堆棧:

'' ava.lang.RuntimeException: There is no view set with ViewPackage found in the log tree.

'' at o.λ.?(:64)

'' at o.λ.ˊ(:25)

'' at o.к$ˋ.run(:233)

'' at android.os.Handler.handleCallback(Handler.java:733)

'' at android.os.Handler.dispatchMessage(Handler.java:95)

'' at android.os.Looper.loop(Looper.java:136)

'' at android.os.HandlerThread.run(HandlerThread.java:61)

然后如果沒有一個(gè)符號(hào)表幫忙蠕趁,你會(huì)陷入深深的沉思:這到底是什么問題薛闪?我的代碼在哪里?如果有了正確的符號(hào)表妻导,一條命令行就可以就可以把相關(guān)的異常堆棧信息翻譯正確逛绵。符號(hào)表和編譯過程有著緊密的耦合,所以在選擇打包工具時(shí)倔韭,都應(yīng)該選擇不產(chǎn)生二次編譯的工具术浪。在以上提到的三款工具中,添加多渠道都是基于已有APK進(jìn)行添加的寿酌,并不是基于源碼來添加渠道胰苏。所以都完全滿足條件。

考慮到文章的篇幅醇疼,有一些內(nèi)容沒有展開說硕并,開發(fā)者如果遇到這方面的問題,歡迎與我交流秧荆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末倔毙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子乙濒,更是在濱河造成了極大的恐慌陕赃,老刑警劉巖卵蛉,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異么库,居然都是意外死亡傻丝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門诉儒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來葡缰,“玉大人,你說我怎么就攤上這事忱反》菏停” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵缭受,是天一觀的道長(zhǎng)胁澳。 經(jīng)常有香客問我,道長(zhǎng)米者,這世上最難降的妖魔是什么韭畸? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蔓搞,結(jié)果婚禮上胰丁,老公的妹妹穿的比我還像新娘。我一直安慰自己喂分,他們只是感情好锦庸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蒲祈,像睡著了一般甘萧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梆掸,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天扬卷,我揣著相機(jī)與錄音,去河邊找鬼酸钦。 笑死怪得,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的卑硫。 我是一名探鬼主播徒恋,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼欢伏!你這毒婦竟也來了入挣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤硝拧,失蹤者是張志新(化名)和其女友劉穎径筏,沒想到半個(gè)月后风皿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匠璧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咸这。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夷恍。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖媳维,靈堂內(nèi)的尸體忽然破棺而出酿雪,到底是詐尸還是另有隱情,我是刑警寧澤侄刽,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布指黎,位于F島的核電站,受9級(jí)特大地震影響州丹,放射性物質(zhì)發(fā)生泄漏醋安。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一墓毒、第九天 我趴在偏房一處隱蔽的房頂上張望吓揪。 院中可真熱鬧,春花似錦所计、人聲如沸柠辞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叭首。三九已至,卻和暖如春踪栋,著一層夾襖步出監(jiān)牢的瞬間焙格,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工己英, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留间螟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓损肛,卻偏偏與公主長(zhǎng)得像厢破,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子治拿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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