如何完美破解AquaticPrime License

本练习对象为Exces,一款小工具软件。下载地址:http://excesapp.com。作者本人其实已经描述了如何破解Exces,只是文中方法是暴力破解。笔者认为稍显简单粗暴——技不止于此!因此,尝试从真正注册license入手,实现完美破解!
Exces是如何注册的呢?运行Exces,见下图,可以看到注册license方法。在Preferences弹出框中,拖入一个有效的license文件。

Snip20171031_6.png

Snip20171031_4.png

那这个license文件是怎么样的呢?我们在Hopper中分析。

0x1 代码分析

在Hopper中打开Exces,找到verifyLicenseFile:方法。



        ; ================ B E G I N N I N G   O F   P R O C E D U R E ================

        ; Variables:
        ;    arg_8: 16
        ;    _cmd: 12
        ;    self: 8
        ;    var_1C: -28
        ;    var_34: -52
        ;    var_38: -56
        ;    var_3C: -60
        ;    var_40: -64
        ;    var_44: -68
        ;    var_48: -72


             -[SSExcesAppController verifyLicenseFile:]:
000051fc         push       ebp                                                 ; Objective C Implementation defined at 0x14ef8 (instance method)
000051fd         mov        ebp, esp
000051ff         push       edi
00005200         push       esi
00005201         push       ebx
00005202         sub        esp, 0x3c
00005205         mov        eax, dword [ebp+arg_8]
00005208         mov        edi, dword [ebp+self]
0000520b         mov        dword [ebp+var_1C], eax
0000520e         mov        dword [esp+0x48+var_40], eax
00005212         mov        eax, dword [objc_msg_verifyPath_]                   ; @selector(verifyPath:)
00005217         mov        dword [esp+0x48+var_48], edi                        ; argument #1 for method imp___jump_table__objc_msgSend
0000521a         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000521e         call       imp___jump_table__objc_msgSend
00005223         test       eax, eax
00005225         je         loc_530d

0000522b         mov        eax, dword [objc_msg_alloc]                         ; @selector(alloc)
00005230         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00005234         mov        eax, dword [cls_NSTask]                             ; cls_NSTask
00005239         mov        dword [esp+0x48+var_48], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
0000523c         call       imp___jump_table__objc_msgSend
00005241         mov        edx, dword [objc_msg_init]                          ; @selector(init)
00005247         mov        dword [esp+0x48+var_44], edx                        ; argument #2 for method imp___jump_table__objc_msgSend
0000524b         mov        dword [esp+0x48+var_48], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
0000524e         call       imp___jump_table__objc_msgSend
00005253         mov        dword [esp+0x48+var_40], 0x12418                    ; @"/bin/cp"
0000525b         mov        ebx, eax
0000525d         mov        eax, dword [objc_msg_setLaunchPath_]                ; @selector(setLaunchPath:)
00005262         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
00005265         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00005269         call       imp___jump_table__objc_msgSend
0000526e         mov        eax, dword [objc_msg_stringByExpandingTildeInPath]  ; @selector(stringByExpandingTildeInPath)
00005273         mov        esi, dword [cls_NSArray]                            ; cls_NSArray
00005279         mov        dword [esp+0x48+var_48], 0x123b8                    ; @"~/Library/Preferences/com.seosoft.exces.licence.excli", argument #1 for method imp___jump_table__objc_msgSend
00005280         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00005284         call       imp___jump_table__objc_msgSend
00005289         mov        dword [esp+0x48+var_34], 0x0
00005291         mov        dword [esp+0x48+var_38], eax
00005295         mov        eax, dword [ebp+var_1C]
00005298         mov        dword [esp+0x48+var_40], 0x12428                    ; @"-r"
000052a0         mov        dword [esp+0x48+var_3C], eax
000052a4         mov        eax, dword [objc_msg_arrayWithObjects_]             ; @selector(arrayWithObjects:)
000052a9         mov        dword [esp+0x48+var_48], esi                        ; argument #1 for method imp___jump_table__objc_msgSend
000052ac         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000052b0         call       imp___jump_table__objc_msgSend
000052b5         mov        dword [esp+0x48+var_40], eax
000052b9         mov        eax, dword [objc_msg_setArguments_]                 ; @selector(setArguments:)
000052be         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
000052c1         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000052c5         call       imp___jump_table__objc_msgSend
000052ca         mov        eax, dword [objc_msg_launch]                        ; @selector(launch)
000052cf         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
000052d2         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000052d6         call       imp___jump_table__objc_msgSend
000052db         mov        ebx, dword [edi+0xc]
000052de         mov        byte [edi+0x2c], 0x1
000052e2         mov        eax, dword [objc_msg_selectedToolbarItem]           ; @selector(selectedToolbarItem)
000052e7         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
000052ea         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000052ee         call       imp___jump_table__objc_msgSend
000052f3         mov        dword [ebp+arg_8], eax
000052f6         mov        eax, dword [objc_msg_toolbarHit_]                   ; @selector(toolbarHit:)
000052fb         mov        dword [ebp+self], ebx
000052fe         mov        dword [ebp+_cmd], eax
00005301         add        esp, 0x3c
00005304         pop        ebx
00005305         pop        esi
00005306         pop        edi
00005307         leave
00005308         jmp        imp___jump_table__objc_msgSend
                        ; endp

             loc_530d:
0000530d         add        esp, 0x3c                                           ; CODE XREF=-[SSExcesAppController verifyLicenseFile:]+41
00005310         pop        ebx
00005311         pop        esi
00005312         pop        edi
00005313         leave
00005314         ret
                        ; endp

其中,关键点为调用的verifyPath:方法;如果verifyPath方法通过,便将License文件cp(拷贝) 到~/Library/Preferences/com.seosoft.exces.licence.excli。由此得到 一点提示,即licence 文件为excli后缀。

接下来看verifyPath:方法。

00005315         push       ebp                                                 ; Objective C Implementation defined at 0x14eec (instance method)
00005316         mov        ebp, esp
00005318         push       edi
00005319         push       esi
0000531a         push       ebx
0000531b         sub        esp, 0x1c
0000531e         mov        eax, dword [objc_msg_string]                        ; @selector(string)
00005323         mov        edi, dword [ebp+self]
00005326         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000532a         mov        eax, dword [cls_NSMutableString]                    ; cls_NSMutableString
0000532f         mov        dword [esp+0x28+var_28], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00005332         call       imp___jump_table__objc_msgSend
00005337         mov        dword [esp+0x28+var_20], 0x12438                    ; @"0xE6242CBE8E7686CB4AFB143FAF6D"
0000533f         mov        ebx, eax
00005341         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005346         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
00005349         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000534d         call       imp___jump_table__objc_msgSend
00005352         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005357         mov        dword [esp+0x28+var_20], 0x12448                    ; @"6B7805475B6D856812"
0000535f         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
00005362         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00005366         call       imp___jump_table__objc_msgSend
0000536b         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005370         mov        dword [esp+0x28+var_20], 0x12458                    ; @"9"
00005378         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
0000537b         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000537f         call       imp___jump_table__objc_msgSend
00005384         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005389         mov        dword [esp+0x28+var_20], 0x12458                    ; @"9"
00005391         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
00005394         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00005398         call       imp___jump_table__objc_msgSend
0000539d         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
000053a2         mov        dword [esp+0x28+var_20], 0x12468                    ; @"1D6547D406"
000053aa         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
000053ad         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000053b1         call       imp___jump_table__objc_msgSend
000053b6         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
000053bb         mov        dword [esp+0x28+var_20], 0x12478                    ; @"A2C26"
000053c3         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
000053c6         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000053ca         call       imp___jump_table__objc_msgSend
000053cf         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
000053d4         mov        dword [esp+0x28+var_20], 0x12488                    ; @"3"
000053dc         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
000053df         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000053e3         call       imp___jump_table__objc_msgSend
000053e8         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
000053ed         mov        dword [esp+0x28+var_20], 0x12488                    ; @"3"
000053f5         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
000053f8         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000053fc         call       imp___jump_table__objc_msgSend
00005401         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005406         mov        dword [esp+0x28+var_20], 0x12498                    ; @"BE7F9494B188D12EE391D7A"
0000540e         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
00005411         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00005415         call       imp___jump_table__objc_msgSend
0000541a         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
0000541f         mov        dword [esp+0x28+var_20], 0x124a8                    ; @"9C9E84B05"
00005427         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
0000542a         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000542e         call       imp___jump_table__objc_msgSend
00005433         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005438         mov        dword [esp+0x28+var_20], 0x124b8                    ; @"8"
00005440         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
00005443         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00005447         call       imp___jump_table__objc_msgSend
0000544c         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)  
.....
.....

代码太长,看伪代码就比较清晰了。

void * -[SSExcesAppController verifyPath:](void * self, void * _cmd, void * arg_8) {
    edi = self;
    ebx = [NSMutableString string];
    [ebx appendString:@"0xE6242CBE8E7686CB4AFB143FAF6D"];
    [ebx appendString:@"6B7805475B6D856812"];
    [ebx appendString:@"9"];
    [ebx appendString:@"9"];
    [ebx appendString:@"1D6547D406"];
    [ebx appendString:@"A2C26"];
    [ebx appendString:@"3"];
    [ebx appendString:@"3"];
    [ebx appendString:@"BE7F9494B188D12EE391D7A"];
    [ebx appendString:@"9C9E84B05"];
    [ebx appendString:@"8"];
    [ebx appendString:@"8"];
    [ebx appendString:@"742EAE04CFE6831F338"];
    [ebx appendString:@"B2D"];
    [ebx appendString:@"9"];
    [ebx appendString:@"9"];
    [ebx appendString:@"E4AC7202CE86FEDDF170EF6AE"];
    [ebx appendString:@"1"];
    [ebx appendString:@"D"];
    [ebx appendString:@"D"];
    [ebx appendString:@"50DC8A8EDE47CA3EC1B11B86BED"];
    [ebx appendString:@"945AB07989D"];
    [ebx appendString:@"B"];
    [ebx appendString:@"B"];
    [ebx appendString:@"A634511AE20B8ADFC"];
    [ebx appendString:@"501D130BE"];
    [ebx appendString:@"4"];
    [ebx appendString:@"4"];
    [ebx appendString:@"EDF1DC6129A929A12A8"];
    [ebx appendString:@"506739EE47871476D5"];
    esi = [[AquaticPrime aquaticPrimeWithKey:ebx] dictionaryForLicenseFile:arg_8];
    if (([[esi objectForKey:@"Expires"] isEqualToString:@"never"] == 0x0) && ([[NSCalendarDate calendarDate] isGreaterThan:[NSCalendarDate dateWithString:[esi objectForKey:@"Expires"] calendarFormat:@"%d/%m/%Y"]] != 0x0)) {
            esi = 0x0;
    }
    else {
            if (*(edi + 0xc) == 0x0) {
                    *(edi + 0xc) = [SSExcesPrefController new];
            }
            [*(edi + 0xc) setLicenseDictionary:esi];
    }
    eax = esi;
    return eax;
}

从代码可以看出,先拼接出Key,因此这个Key是写死在APP里面的。然后调用[AquaticPrime aquaticPrimeWithKey],通过dictionaryForLicenseFile方法从license文件中读出Expires字段。如果Expires为never或者Expires定义的日期在当前日期后面,则校验通过。所以,看来验证的逻辑比较简单。但如何伪装一份license让APP接受,那就要看AquaticPrime调用的aquaticPrimeWithKey方法。

0x2 AquaticPrime Framework

AquaticPrime是什么?Google一下,就知道AquaticPrime为Mac OS X上流行的利用RSA加密算法进行license验证的Framework。大概原理是生成RSA公钥、私钥对,用私钥加密生成license文件。公钥则放APP里,用来解密和检验license。由于RSA具有非对称性,使用私钥加密的字符,配对的公钥(即上述拼接的Key)才能解密,并且从公钥无法得到私钥,所以具备很好的保密性。由于APP无法知道私钥,无从知道license怎么来的,也无法解密任意的license。看到这里,似乎非暴力破解此APP是无望了。开始笔者也是这么认为的。还好,AquaticPrime为开源软件,在github找到AquaticPrimeFramework源代码,看到了希望的曙光。

0x3 破解AquaticPrime

AquaticPrimeFramework源码提供了生成license文件的APP,可以生成出一对RSA钥匙和对应的license文件。所以,破解的思路就是自制一份license文件和RSA公、私钥,然后将APP中的公钥替换为自制公钥 。

(1)生成license和RSA公、私钥

如下图。根据代码分析,license中的Expires字段设为never,后缀名为excli。


Snip20171101_9.png
Snip20171101_8.png

(2)使用自制的公钥替换APP公钥

这里使用了Hex Fiend二进制编辑工具。用Hex Fiend打开APP,找到公钥字符串,全部替换为自制的公钥。如下二图。

替换前:


Snip20171101_11.png

替换后:

Snip20171101_12.png

(3)修改verifyPath方法,导入自制的公钥

在Hopper中编辑verifyPath方法,只保留第一个objc_msg_appendString_ 0x12438方法,然后在0x12438定义的字符串中将length设为0x102。即一次性将公钥导入,省去混淆公钥的过程(代码太长,省略部分)。

...
...
0000531e         mov        eax, dword [objc_msg_string]                        ; @selector(string)
00005323         mov        edi, dword [ebp+8]
00005326         mov        dword [esp+4], eax                                  ; argument #2 for method imp___jump_table__objc_msgSend
0000532a         mov        eax, dword [cls_NSMutableString]                    ; cls_NSMutableString
0000532f         mov        dword [esp], eax                                    ; argument #1 for method imp___jump_table__objc_msgSend
00005332         call       imp___jump_table__objc_msgSend
00005337         mov        dword [esp+8], 0x12438                              ; @"0xDC24E2A5B7C87320A6663704670BC09E4B6AE5301D40CDCCE5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE…"
0000533f         mov        ebx, eax
00005341         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005346         mov        dword [esp], ebx                                    ; argument #1
00005349         mov        dword [esp+4], eax                                  ; argument #2
0000534d         call       imp___jump_table__objc_msgSend
00005352         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005357         mov        dword [esp+8], 0x12448                              ; @"09E4B6AE5301D40CDCCE5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
0000535f         mov        dword [esp], ebx                                    ; argument #1
00005362         mov        dword [esp+4], eax                                  ; argument #2
00005366         nop        dword [eax+eax]
0000536b         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005370         mov        dword [esp+8], 0x12458                              ; @"E5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
00005378         mov        dword [esp], ebx                                    ; argument #1
0000537b         mov        dword [esp+4], eax                                  ; argument #2
0000537f         nop        dword [eax+eax]
00005384         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
00005389         mov        dword [esp+8], 0x12458                              ; @"E5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
00005391         mov        dword [esp], ebx                                    ; argument #1
00005394         mov        dword [esp+4], eax                                  ; argument #2
00005398         nop        dword [eax+eax]
0000539d         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
000053a2         mov        dword [esp+8], 0x12468                              ; @"F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
000053aa         mov        dword [esp], ebx                                    ; argument #1
000053ad         mov        dword [esp+4], eax                                  ; argument #2
...
...

0x4 程序验证

将自制的license文件拖入Exces,验证成功!:)!

Snip20171031_3.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容