(九) 代碼簽名

1. 代碼簽名

代碼簽名并不是每一個iOS開發(fā)人員的首要任務(wù)坪郭,但是對代碼簽名工作原理的深入了解對于解決問題以及在開發(fā)團(tuán)隊(duì)中樹立自己的形象非常有用。沒有什么比一個可以重新簽署過時的Swift 2.2 iOS應(yīng)用程序的開發(fā)人員更“值得一提”了格二,而不是在時間不允許的情況下修復(fù)潛在的數(shù)千個Swift編譯器錯誤。

下面會講解代碼簽名工作原理的基本概述竣蹦。在下面的鏈接找到開源iOS Wordpress v10.9應(yīng)用程序:

在發(fā)送到iTunes Connect Store之前顶猜,我們會探索應(yīng)用程序代碼簽名的各個階段。此外痘括,我們會重新簽署Wordpress應(yīng)用程序长窄,以便它可以在我們自己的iOS設(shè)備上運(yùn)行!

1.1 準(zhǔn)備工作

我們需要一個合適的iOS蘋果開發(fā)人員帳戶來生成配置文件纲菌;需要一個真機(jī)來安裝Wordpress iOS應(yīng)用程序挠日;還需要獲取并安裝mobdevim命令,可在此處獲得:

這個小命令行工具可以做很多事情翰舌,包括在設(shè)備上安裝應(yīng)用程序嚣潜、查詢設(shè)備信息和連接到iOS設(shè)備時獲取控制臺日志。使用此工具可以更輕松地在設(shè)備上安裝iOS應(yīng)用程序椅贱,并在應(yīng)用程序簽名不正確時查找錯誤懂算。

按照mobdevsim上的說明安裝該工具。安裝mobdevim后夜涕,連上iOS設(shè)備并進(jìn)行測試運(yùn)行。

mobdevim -f

1.2 專業(yè)用語

要真正了解代碼簽名的工作原理属愤,我們需要了解三個關(guān)鍵組件:公鑰/私鑰女器、授權(quán)文件和配置文件。我們將從廣度優(yōu)先開始住诸,然后深入到深度優(yōu)先驾胆。

公鑰/私鑰用于簽署我們的應(yīng)用程序。這是我們的數(shù)字簽名贱呐,蘋果知道如何進(jìn)行驗(yàn)證丧诺。私鑰用于對應(yīng)用程序及其授權(quán)文件進(jìn)行密碼簽名。授權(quán)文件實(shí)際上只是嵌入在應(yīng)用程序中的一個XML字符串奄薇,它表示應(yīng)用程序可以做什么驳阎,不能做什么。

授權(quán)文件馁蒂、已批準(zhǔn)設(shè)備的列表和用于驗(yàn)證代碼簽名的公鑰都捆綁在應(yīng)用程序的配置文件中呵晚。所有信息都是通過私鑰創(chuàng)建的簽名強(qiáng)制執(zhí)行的,并且可以通過公鑰進(jìn)行驗(yàn)證沫屡。

1.3 公鑰/私鑰

在學(xué)習(xí)代碼簽名過程時饵隙,這可能是最難理解的事情。因?yàn)楣€/私鑰引入了密碼學(xué)沮脖,不斷深入將是個無底洞金矛。

簡單地說芯急,有兩種不同類型的密碼學(xué):對稱加密和非對稱加密。

  • 對稱加密驶俊,是一種只包含一個密鑰的密碼娶耍。如果A試圖向B發(fā)送一條秘密消息徘六,他們都必須知道共享的秘密才能對該消息進(jìn)行加密和解密胎撤。
  • 在非對稱加密中顺少,有兩個密鑰:公鑰和私鑰与殃。A和B都有自己獨(dú)特的私鑰和獨(dú)特的公鑰普碎。這樣作箍,他們就可以在任何人不知道對方私鑰的情況下共享信息浩销。

我們在設(shè)置Apple開發(fā)人員帳戶時账磺,已經(jīng)完成了從證書頒發(fā)機(jī)構(gòu)請求證書的過程购披。我們創(chuàng)建了一對公鑰/私鑰杖挣,將公鑰發(fā)送到Apple服務(wù)器(通過.csr文件)。最終的結(jié)果是創(chuàng)建了一個由蘋果簽署的簽名刚陡,這就是蘋果如何唯一地識別你惩妇。這意味著蘋果公司和我們都使用非對稱加密技術(shù)來分發(fā)應(yīng)用程序。

我們可以使用以下終端命令查看用于為應(yīng)用程序簽名的公鑰/私鑰對的名稱或標(biāo)識:

security find-identity -p codesigning -v

此命令查詢macOS系統(tǒng)的keychain筐乳,查找包含私鑰(-v)且其類型可以進(jìn)行代碼簽名(-p代碼簽名)的有效標(biāo)識歌殃。

此輸出將顯示有效的標(biāo)識,這些標(biāo)識可以生成代碼簽名的應(yīng)用程序蝙云。如果我們查找包含短語“iPhone Developer”的標(biāo)識氓皱,則該標(biāo)識可能用于在設(shè)備上簽名iOS應(yīng)用程序。

請注意勃刨,我們有一個公鑰或證書波材,以及下面的私鑰。證書可以重新創(chuàng)建身隐,但私鑰的價(jià)值超過黃金廷区。永遠(yuǎn)不要刪除私鑰!如果這樣做了贾铝,你就要拿出你是你的證據(jù)隙轻,就需要通過蘋果重新創(chuàng)造一個新的身份。

從這個意義上說垢揩,證書只是公鑰大脉。因此,如果要使用keychain訪問來導(dǎo)出標(biāo)識水孩,并且希望將其格式化為.cer格式镰矿,那么我們將只會導(dǎo)出公鑰。如果還要導(dǎo)出私鑰俘种,則必須使用PKCS12格式(.p12)正確導(dǎo)出完整標(biāo)識秤标、私鑰和其他信息绝淡。

這一點(diǎn)很重要,因?yàn)槲覀冃枰朗欠褚獙?dǎo)出標(biāo)識苍姜,以便另一個開發(fā)人員可以生成具有匹配分發(fā)標(biāo)識的構(gòu)建牢酵。但要小心:無論誰擁有私鑰,都可以為那家公司承擔(dān)全部身份衙猪,至少從蘋果的角度來看是這樣馍乙!

可以使用以下命令導(dǎo)出公共證書:

 security find-certificate -c ${name} -p

這將把名字叫${name}的公共證書輸出到stdout,并將其格式化為PEM格式垫释。顯示證書有兩種方法:DERPEM丝格。PEM可以被終端讀取(因?yàn)樗?code>base64編碼的棵譬;DER显蝌,用高度專業(yè)的編碼術(shù)語來說,會產(chǎn)生官話并使終端發(fā)出很多嗶嗶聲订咸。

重復(fù)上述命令并將輸出寫入/tmp/public_cert.cer曼尊。

 security find-certificate -c ${name} -p > /tmp/public_cert.cer

然后就可以在終端查看了。

cat /tmp/public_cert.cer
-----BEGIN CERTIFICATE-----
MIIFnDCCBISgAwIBAgIIFMKm2AG4HekwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
...

這就是我們怎么知道這個證書在PEM中脏嚷。我們可以使用openssl命令查詢公共的x509證書:

openssl x509 -in /tmp/public_cert.cer -inform PEM -text -noout
  • x509選項(xiàng)表示openssl命令應(yīng)該使用x509證書骆撇。
  • 提供公共證書路徑的-in,解碼格式為PEM(-inform PEM)父叙。
  • 希望證書采用可讀的文本格式-text選項(xiàng)神郊。
  • 指定不希望輸出證書中帶有-noout參數(shù)。

有關(guān)此公共證書的信息將顯示在終端中高每。

記住這個openssl命令屿岂。當(dāng)我們閱讀到將這些公共證書嵌入其中的配置文件時践宴,將重新接觸到x509證書的概念鲸匿。

1.4 授權(quán)文件

嵌入在幾乎每個編譯的應(yīng)用程序中的是一組授權(quán)文件。這是嵌入在應(yīng)用程序中的XML字符串阻肩,表示應(yīng)用程序可以做什么和不能做什么带欢。其他程序?qū)z查授權(quán)文件中的權(quán)限,并相應(yīng)地授予或拒絕請求烤惊。

其中許多權(quán)限檢查是由其他檢查程序權(quán)限的守護(hù)程序執(zhí)行的乔煞。例如,App Groups柒室、iCloud Services渡贾、Push NotificationsAssociated Domains都將修改應(yīng)用程序的授權(quán)信息雄右。Xcode中顯示的這些功能只是蘋果平臺上的一小部分權(quán)利空骚,因?yàn)榇蠖鄶?shù)功能都是蘋果私有的纺讲,并通過代碼簽名來實(shí)現(xiàn)。

可能最重要的授權(quán)囤屹,是get-task-allow授權(quán)熬甚,可以在使用開發(fā)人員證書編譯的所有軟件上找到。它允許相關(guān)程序附著到調(diào)試器上肋坚。

在macOS上乡括,可以通過為任何不具有get-task-allow: true的應(yīng)用程序禁用SIP來解決缺少此權(quán)限的問題。在iOS上智厌,我們將嘗試調(diào)試不具有此權(quán)限的應(yīng)用程序诲泌,除非通過越獄禁用了代碼驗(yàn)證。

可以通過codesign命令查看應(yīng)用程序的授權(quán)信息峦剔,比如Finder

codesign -d --entitlements :- /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder

-d選項(xiàng)表示在命令后面立即顯示--entitlements選項(xiàng)档礁。:-有兩種作用:

  • -打印到stdout
  • :表示省略有信息和長度。

就像在Mach-O中一樣吝沫,代碼簽名信息是用一個magic header和長度存儲的呻澜。:表示從輸出中刪除此頭信息,并且只顯示實(shí)際的XML授權(quán)字符串惨险。

1.5 配置文件

設(shè)置配置文件把公共x509證書羹幸、已批準(zhǔn)設(shè)備的列表以及授權(quán)文件嵌入到一個文件中。

配置文件的默認(rèn)位置可以在以下位置找到:

~/Library/MobileDevice/Provisioning Profiles/
// 通過ls命令查看文件夾下的所有證書
ls ~/Library/MobileDevice/Provisioning\ Profiles/

不幸的是辫愉,配置概要文件是由它們的UUID命名的栅受,而不是由我們(或Xcode)為它們?nèi)〉拿Q命名的。

幸運(yùn)的是恭朗,我們可以再次使用security命令來顯示原始信息屏镊。選擇任何一個.mobileprovision文件并執(zhí)行security命令,如下所示:

PP_FILE=$(ls ~/Library/MobileDevice/Provisioning\ Profiles/ *mobileprovision | head -1)
security cms -D -i "$PP_FILE"

第一個命令獲取一個配置文件并將其分配給PP_FILE變量痰腮。PP_FILE變量被傳遞到security命令中而芥。該命令對設(shè)置配置文件的加密消息語法cms格式進(jìn)行-D解碼,并通過-i選項(xiàng)指定輸入路徑膀值。

下面將討論某一個配置文件的輸出棍丐。輸出中有一些有意思的點(diǎn):

  • AppIDName是綁定到此設(shè)置配置文件的ID的名稱,可在https://developer.apple.com/account/ios/identifier/bundle上找到沧踏。
  • TeamIdentifier是Apple為團(tuán)隊(duì)標(biāo)識提供的唯一團(tuán)隊(duì)標(biāo)識歌逢。蘋果將為付款的每個賬戶生成一個特定的團(tuán)隊(duì)ID。例如翘狱,對于應(yīng)用商店版本秘案,會有一個唯一的團(tuán)隊(duì)ID;而對于企業(yè)版本,會有一個不同的團(tuán)隊(duì)ID阱高。
  • 授權(quán)包含應(yīng)用程序使用此簽名可以做什么和不能做什么师骗。這通常是Xcode生成的配置文件出現(xiàn)問題的原因。因?yàn)閄code需要更新App ID配置(本質(zhì)上是授權(quán))讨惩,然后生成具有正確值的新配置文件辟癌。
  • IsXcodeManaged是一個布爾值。表明Xcode是否管理這個配置文件荐捻。整個代碼簽名過程給開發(fā)者帶來了很多麻煩黍少,蘋果公司正試圖在IDE上做更多的工作,包括用我們的發(fā)行證書為應(yīng)用程序簽名处面。這是一把雙刃劍厂置,讓Xcode代為管理方便了我們,但是如果Xcode做了一些我們沒有預(yù)料到的事情魂角,那么潛在的錯誤可能更難追蹤昵济。
  • Name是在https://developer.Apple.com/account/ios/profile/limited上顯示的用于標(biāo)識配置文件的名稱。
  • ProvisionedDevices授權(quán)設(shè)備的列表野揪。
  • DeveloperCertificates是包含base64編碼的x509證書的數(shù)組访忿。這將包含先前通過security find certificate命令提取的相同公共證書。在對應(yīng)用程序進(jìn)行代碼簽名時斯稳,這些證書也被編碼到實(shí)際的可執(zhí)行文件中海铆。

1.6 探索WordPress app

與iOS設(shè)備上的典型調(diào)試工作流一樣,在將應(yīng)用程序發(fā)送到Apple iTunes Connect之前挣惰,必須編譯具有配置文件的應(yīng)用程序卧斟。每個上架前的App都有一個名為embedded.mobileprovision的配置文件。正是這個配置文件告訴iOS應(yīng)用程序是有效的憎茂,并且來自我們珍语。

打開Pre App Store目錄中的WordPress.app。為WORDPRESS.app的完整路徑分配一個終端變量WORDPRESS竖幔,如下所示:

WORDPRESS="/full/path/to/WordPress.app/"
配置文件

WordPress應(yīng)用程序中找到embedded.mobileprovision配置文件板乙,并對其使用security命令。

security cms -D -i "$WORDPRESS/embedded.mobileprovision"

在這個特定的配置文件中赏枚,可以看到以下內(nèi)容:

  • 蘋果公司分配給Automattic, Inc.公司的團(tuán)隊(duì)標(biāo)識是3TMU3BH3NK亡驰。
  • Wordpress應(yīng)用程序使用iCloud服務(wù):在授權(quán)字典中有com.apple.developer.icloud鍵晓猛。它還希望使用某些擴(kuò)展饿幅,如App Groups
  • get-task-allowfalse戒职,意味著我們無法附著調(diào)試器栗恩。因?yàn)閼?yīng)用程序是使用分發(fā)簽名標(biāo)識簽名的。

DeveloperCertificates密鑰復(fù)制base64編碼的數(shù)據(jù)洪燥。通過終端磕秤,將此值分配給名為CERT_DATA的變量:

CERT_DATA=MIIFozCCBIu...

變量CERT_DATA現(xiàn)在包含用于簽署應(yīng)用程序的base64編碼x509證書∪槲冢現(xiàn)在,解碼這個base64數(shù)據(jù)并將其導(dǎo)出到/tmp/wordpress_cert.cer市咆。之后執(zhí)行openssl命令進(jìn)行查看汉操。

echo "$CERT_DATA" | base64 -D > /tmp/wordpress_cert.cerecho "$CERT_DATA" | base64 -D > /tmp/wordpress_cert.cer

openssl x509 -in /tmp/wordpress_cert.cer -inform DER -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 786948871528664923 (0xaebcdd447dc4f5b)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Apple Inc., OU=Apple Worldwide Developer Relations, CN=Apple Worldwide Developer Relations Certification Authority
        Validity
            Not Before: Jan 17 13:26:41 2018 GMT
            Not After : Jan 17 13:26:41 2019 GMT
        Subject: UID=PZYM8XX95Q, CN=iPhone Distribution: Automattic, Inc. (PZYM8XX95Q), OU=PZYM8XX95Q, O=Automattic, Inc., C=US
...

這意味著,在Automattic, Inc的工作人員的keychain上有一個名為“iPhone Distribution: Automattic, Inc. (PZYM8XX95Q)”的標(biāo)識蒙兰,用于簽署此應(yīng)用程序磷瘤。

嵌入的可執(zhí)行文件

如果應(yīng)用程序包含擴(kuò)展(即share擴(kuò)展、today小部件或其他的)搜变,則在./Plugins目錄中會找到更多簽名的打包包采缚,其中包含它們自己的應(yīng)用程序標(biāo)識符和embedded.mobileprovision配置文件。

這些功能為應(yīng)用程序提供了應(yīng)用程序之外的附加功能挠他。

在深入./Plugins目錄中的容器時扳抽,可以使用相同的安全命令來驗(yàn)證這一點(diǎn),分別查看每個embedded.mobileprovision文件殖侵。

_CodeSignature文件夾

包含在真正的iOS應(yīng)用程序包(不在模擬器中)中的是一個名為_CodeSignature的文件夾贸呢,其中包含一個名為CodeResources的文件。這是一個XML plist文件拢军,它是該目錄中找到的每個不可執(zhí)行文件的校驗(yàn)和贮尉。例如:

cat "_CodeSignature/CodeResources" | head -10
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>files</key>
    <dict>
        <key>AboutViewController.nib</key>
        <data>
        rSZAWMReahogETtlwDpstztW6Ug=
        </data>

可以看到AboutViewController.nib文件的校驗(yàn)和
rSZAWMReahogETtlwDpstztW6Ug=

這個值可以通過openssl自己計(jì)算:

openssl sha1 -binary "AboutViewController.nib" | base64
rSZAWMReahogETtlwDpstztW6Ug=

蘋果已經(jīng)開始用Xcode 10為iOS應(yīng)用程序從SHA-1校驗(yàn)和向SHA-256過渡朴沿,為兩種算法生成校驗(yàn)和猜谚。

這個CodeResources文件本身有一個對文件執(zhí)行的校驗(yàn)和,它被嵌入到了實(shí)際的WordPress應(yīng)用程序中赌渣!這意味著魏铅,如果用戶要修改任何文件,甚至在.app目錄中添加一個目錄而不重新簽名WordPress應(yīng)用程序坚芜,iOS應(yīng)用程序都無法在用戶手機(jī)上進(jìn)行安裝览芳。

1.7 對WordPress app重新簽名

我們可以使用Apple簽名重新簽名應(yīng)用程序,將WordPress應(yīng)用程序安裝到iOS設(shè)備上鸿竖。

從高層的角度來看沧竟,您需要執(zhí)行以下操作:

  1. 將有效的配置文件復(fù)制到應(yīng)用程序WordPress .app目錄中的embedded.mobileprovision。
  2. Info.plistCFBundleIdentifier更改為新的配置文件中新的應(yīng)用程序標(biāo)識符缚忧。
  3. 使用適當(dāng)?shù)氖跈?quán)信息(也包括在配置文件中)通過嵌入的配置文件中包含的標(biāo)識為WordPress應(yīng)用程序重新簽名悟泵。

如果你有一個有效的、未過期的闪水、包含你的iOSUDID的配置文件糕非。連接上iOS設(shè)備,通過執(zhí)行mobdevim -f命令來獲取設(shè)備的UDID

復(fù)制配置文件

無論是創(chuàng)建一個新的配置文件或使用現(xiàn)有的配置文件朽肥,我們將使用它來重新簽名WordPress應(yīng)用程序禁筏。用它覆蓋WordPress.app文件夾下面的embedded.mobileprovision文件。

PP_PATH=~/Downloads/Code_Signing_Example_ProvisProfile_92618.mobileprovision

cp "$PP_PATH" "$WORDPRESS/embedded.mobileprovision"
刪除插件

WordPress應(yīng)用程序在主應(yīng)用程序中嵌入了幾個./Plugins目錄中的擴(kuò)展應(yīng)用程序衡招。每個配置文件都包含一個具有唯一應(yīng)用程序標(biāo)識符的唯一配置文件篱昔。我們可以為每個擴(kuò)展本身提供一個唯一的配置文件進(jìn)行簽名。但這個太麻煩了始腾,不是重點(diǎn)旱爆。我們不使用這些擴(kuò)展,刪除WordPress應(yīng)用程序的整個插件目錄窘茁。

修改Info.plist

希望你記住了配置文件的應(yīng)用程序ID的名稱怀伦,現(xiàn)在需要把它設(shè)置到Info.plist的鍵CFBundleIdentifier中。如果不記得山林,可以從配置文件中查詢它房待。以下是獲取這些信息的方法:

security cms -D -i "$PP_PATH" | grep application-identifier -A1
<key>application-identifier</key>
<string>H4U46V6494.com.selander.code-signing</string>

下面替換這個CFBundleIdentifier鍵中的值。

plutil -replace CFBundleIdentifier -string H4U46V6494.com.selander.code-signing "$WORDPRESS/Info.plist"

我們還可以更改它的顯示名稱:

plutil -replace CFBundleDisplayName -string "Woot" "$WORDPRESS/Info.plist"
提取授權(quán)信息

下一個任務(wù)是使用配置文件中的有效授權(quán)重新簽名應(yīng)用程序驼抹。

由于授權(quán)在配置文件中嵌入為字典而不是XML桑孩,因此可能更容易先從主可執(zhí)行文件中提取權(quán)限,然后用配置文件中找到的新權(quán)限修補(bǔ)該文件框冀。提取授權(quán)信息導(dǎo)出到/tmp/ent.xml

codesign -d --entitlements :/tmp/ent.xml "$WORDPRESS/WordPress"

可以通過cat進(jìn)行查看:

cat /tmp/ent.xml

如果授權(quán)有效流椒,則可以從當(dāng)前配置文件中提取授權(quán)并將其放入這個新文件中。

首先明也,將配置文件XML寫入名為/tmp/scratch的文件:

security cms -D -i "$PP_PATH" > /tmp/scratch

使用xpath命令只將權(quán)利信息提取到剪貼板宣虾。

 xpath /tmp/scratch '//*[text() = "Entitlements"]/following-sibling::dict' | pbcopy

現(xiàn)在剪貼板中有有效的授權(quán)信息。打開/tmp/ent.xml温数,刪除包含的<dict>之間的內(nèi)容并替換為剪貼板的內(nèi)容绣硝。最終的/tmp/ent.xml文件應(yīng)該如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http:// www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>keychain-access-groups</key>
    <array>
        <string>H4U46V6494.*</string>
    </array>
    <key>get-task-allow</key>
    <true />
    <key>application-identifier</key>
    <string>H4U46V6494.com.selander.code-signing</string>
    <key>com.apple.developer.team-identifier</key> 
    <string>H4U46V6494</string>
</dict>
</plist>
重新簽名WordPress

我們已經(jīng)執(zhí)行了所有設(shè)置。我們有一個有效的簽名標(biāo)識撑刺;在embedded.mobileprovisionWordPress應(yīng)用程序中嵌入了一個有效的配置文件鹉胖;刪除了插件目錄;并且擁有在/tmp/ent.xml中找到的新配置文件的授權(quán)够傍。

WordPress應(yīng)用程序Frameworks目錄中使用codesign命令和簽名標(biāo)識:

codesign -f -s "iPhone Developer: Derek Selander (8AW8QLCX5U)" "$WORDPRESS"/Frameworks/*

然后對文件夾進(jìn)行簽名:

codesign --entitlements /tmp/ent.xml -f -s "iPhone Developer: Derek Selander (8AW8QLCX5U)" "$WORDPRESS"

看看能否安裝WordPress應(yīng)用程序甫菠。在終端中,鍵入:

mobdevim -i "$WORDPRESS"

如果我們使用開發(fā)人員配置文件簽署了應(yīng)用程序冕屯。那么我們將擁有get-task-allow權(quán)限寂诱,這意味著我們可以調(diào)試這個WordPress應(yīng)用程序。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愕撰,一起剝皮案震驚了整個濱河市刹衫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌搞挣,老刑警劉巖带迟,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異囱桨,居然都是意外死亡仓犬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門舍肠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搀继,“玉大人,你說我怎么就攤上這事翠语∵辞” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵肌括,是天一觀的道長点骑。 經(jīng)常有香客問我,道長谍夭,這世上最難降的妖魔是什么黑滴? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮紧索,結(jié)果婚禮上袁辈,老公的妹妹穿的比我還像新娘。我一直安慰自己珠漂,他們只是感情好晚缩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著媳危,像睡著了一般橡羞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上济舆,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天卿泽,我揣著相機(jī)與錄音,去河邊找鬼滋觉。 笑死签夭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的椎侠。 我是一名探鬼主播第租,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼我纪!你這毒婦竟也來了慎宾?” 一聲冷哼從身側(cè)響起丐吓,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎趟据,沒想到半個月后券犁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汹碱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年粘衬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咳促。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡稚新,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跪腹,到底是詐尸還是另有隱情褂删,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布冲茸,位于F島的核電站笤妙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏噪裕。R本人自食惡果不足惜蹲盘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望膳音。 院中可真熱鬧召衔,春花似錦、人聲如沸祭陷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兵志。三九已至醇蝴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間想罕,已是汗流浹背悠栓。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留按价,地道東北人惭适。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像楼镐,于是被迫代替她去往敵國和親癞志。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

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