我是怎样一步一步实现微信自动抢红包的?

在逆向工程中,我们可以使用静态分析和动态调试的方法去寻找我们的目标函数!本文我将分享一下逆向微信实现微信自动抢红包的实战经验越狱,非越狱机器 都可适用,项目 GitHub 地址: RHWeChat

本项目在以下环境下测试运行:

  • 非越狱 iOS10.3.2,iPhone 6设备
  • 开发环境:Xcode 8.3.2 , MonkeyDev
简单说下环境搭建:
  • 安装最新的 theos:命令行式的开发 Tweak 的编译环境
sudo git clone --recursive https://github.com/theos/theos.git /opt/theos
  • 安装 ldid:签名工具
    • 自己编译
    • 使用 brew 安装, 有点慢!
// 自己编译
sudo mv ldidpath /opt/theos/bin
sudo chmod 777 /opt/theos/bin/ldid
// brew 安装
brew install ldid
  • 安装 MonkeyDev:基于 theos 实现的Xcode的开发环境。
git clone https://github.com/AloneMonkey/MonkeyDev.git
cd MonkeyDev/bin
sudo ./md-install

关于MonkeyDev详情,请参见:MonkeyDev的文档
大家踊跃给猴神 star 啊!
猴神在他的 MonkeyDev 中,默认集成了Reveal.framework,Cycript.framework,class-dump;并且在MonkeyDev中,你不需要手动提取ipa中的二进制文件, 修改二进制文件的Load Commands列表,加入要hook的dylib ,hook.dylib在函数constructor函数中完成对特定函数的hook,对修改后的ipa进行重签名,打包和安装,等一系列复杂的过程!Command+R 一键搞定,若要生成 ipa 文件只需在 Command+R 运行之后在源代码的 LatestBuild 目录双击createIPA.command 生成。

逆向思路:

要实现自动抢红包的功能,我们首先应该知道一个手动抢红包的流程!
所以我们先分析手动抢红包实现:

  • 首先我们从 UI 入手
    使用 reveal 找到打开红包的按钮,获取内存地址,通过 UIControl 的以下方法获取target和action
- (NSSet *)allTargets;                                                                     // set may include NSNull to indicate at least one nil target
- (UIControlEvents)allControlEvents;                                                       
- (nullable NSArray<NSString *> *)actionsForTarget:(nullable id)target forControlEvent:(UIControlEvents)controlEvent;    // single event. returns NSArray of NSString selector names. returns nil if none
image.png
  • 打开 Hopper Disassembler,载入经过解密的微信可执行文件,搜索得到的 target 和 action,分别对应:WCRedEnvelopesReceiveHomeView 的 OnOpenRedEnvelopes 方法!
image.png
  • 由汇编代码得到他的 delegate 调用了
    WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes 方法
  • 我们继续在 class-dump 得到的头文件中搜索关键字WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes 方法
image.png
  • 我们找到了 WCRedEnvelopesReceiveControlLogic 类,实现了该代理方法,所以我们继续打开 Hopper Disassembler 搜索WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes 方法
image.png
image.png
image.png
  • 可以大致分析出拆开一个红包大致需要 msgtype,sendid,channelid,nickName,headImg,nativeUrl,sessionUserName,timingIdentifier,这些参数,最后调用 OpenRedEnvelopesRequest: 打开红包
image.png
  • 以上是看汇编代码大致得出的结论,具体还要结合测试验证,我们 hook OpenRedEnvelopesRequest:方法
CHDeclareClass(WCRedEnvelopesLogicMgr)
CHOptimizedMethod1(self, void, WCRedEnvelopesLogicMgr, ReceiverQueryRedEnvelopesRequest, id, arg1) {
    NSLog(@"%@", arg1);
    CHSuper1(WCRedEnvelopesLogicMgr, ReceiverQueryRedEnvelopesRequest, arg1);
}
  • 运行程序打上断点,运行打开红包流程,看会不会进断点,进了断点看下打印内容!果真如我们所预料的一样,进了参数打印如下:
{
    channelId = 1;
    headImg = "http://wx.qlogo.cn/mmhead/ver_1/tUsGXv3VM2C4f6Nj1vibaWy2jJUFPMnUfobCtP1iajd5QLCn8B7YM6L6E1UTwSzxkiaichIJuVibBx2BRiaAIu1UkYfjMnJiatYxpvlWdHdfBD8xKU/132";
    msgType = 1;
    nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039501201709137014370817311&sendusername=wxid_mryox0wndn8122&ver=6&sign=8f446c219788bb6db911ff7de1eefd3ac9a66298b8d8d9be3f0018f14524bbb16ca78e0b22357967ebeb36860b892b0d5300d8ae5ae70ac29759a3c673cea9f6205adb65ae01d71d29a7b7a2b757333c0f264b07f893dfb88c28ece6e9869236";
    nickName = "xxxx";
    sendId = xxx;
    sessionUserName = "xxxxx";
    timingIdentifier = 88BF75742FFAB59D7F88C494670C3FE3;
}
  • 接下来我们要仔细分析一下每个参数如何获取:

    • nickName,headImg通过 CContactMgr 的 getSelfContact 获取到 selfContact,selfContact的m_nsHeadImgUrl和getContactDisplayName属性分别对应headImg,nickName


      image.png
    • msgType 为常数1


      image.png
    • nativeUrl,应该是截取红包 url 的一段字符串,通过上面的打印参数可以验证!


      image.png
    • sessionUserName,没太看懂,应该是发红包人的名字,因为上文有个 nickName 我看懂了是 selfContact,自己的名称!
    • sendid,channelid,timingIdentifier,通过 objectForKey: 获取,上文字典的获取只有通过 WCBizUtil 的 dictionaryWithDecodedComponets:separator: 获取


      image.png
  • 所以我们接着进入 dictionaryWithDecodedComponets:separator: 函数的汇编代码分析

  • 参数我没有分析出来是什么类型的,我们Hook dictionaryWithDecodedComponets:separator: 方法

%hook WCBizUtil

+ (id)dictionaryWithDecodedComponets:(id)arg1 separator:(id)arg2 {
    %log;
    return %orig;
}

%end
�[m +[<WCBizUtil: 0x103b28eb8> dictionaryWithDecodedComponets:msgtype=1&channelid=1&sendid=xxxxxxxxxxxxx&sendusername= xxx-com&ver=6&sign=f4455577adc87b21387127f45e6c3803649800302ac90134018c10c4a87b3a0a5df85d4360028ad28b997bbdb4e52e6b8b62804fc04444185bb4f6617359a8c41565d1592d5d251c1a8b0aaef1fdb3de576d88890323720ae701bb3e56b3e900 separator:&]
  • 他的参数应该是红包 url 的 get 参数,我们使用 & 解析出来然后我们可以得到以下参数 sendid,channelid,sessionUserName!
  • 至此 我们得到了除 timingIdentifier 之外的所有参数
  • 但是这个 timingIdentifier 怎么解决呢?
image.png
  • 可以分析出来的是从 m_structDicRedEnvelopesBaseInfo �获取到的,在 class-dump 出来的头文件搜索 ,发现这个字段在WCRedEnvelopesControlData中,但是怎么获取,我本人没有从汇编代码中研究出 timingIdentifier 的来源!
  • google 了一下 timingIdentifier 应该是微信加的一个防止机器人抢红包的字段,怎么解决呢?
  • 猜!既然不在点击打开红包按钮的时候获取,会不会在点击红包进入打开红包页面的时候获取呢?
    继续从 UI 入手


    image.png
  • 首先从[BaseMsgContentViewController tableView:didSelectRowAtIndexPath:] 的汇编代码来看,没有找到类似的请求!
  • 那就从 Cell 本身去看,在class-dump 的头文件中,搜索 WCPayC2CMessageCellView本身没有类似方法
  • 继续找它的父类WCPayBaseMessageCellView,onTouchUpInside方法有可能是我们的目标


    image.png
  • 查看onTouchUpInside汇编代码


    image.png
  • 调用了 tapAppNodeView方法 搜索tapAppNodeView,发现在BaseMsgContentViewController中,我们继续回到BaseMsgContentViewController
  • 查看BaseMsgContentViewController的tapAppNodeView方法的汇编代码:


    image.png

    image.png
  • 调用了[WCRedEnvelopesControlMgr startReceiveRedEnvelopesLogicByC2C:Data:] 查看汇编代码没有找到!
  • 继续查看 tapAppNodeView 汇编代码发现最后调用了
    [WCRedEnvelopesControlMgr startReceiveRedEnvelopesLogic:Data:]方法


    image.png
  • 查看汇编代码,我们发现 startReceiveRedEnvelopesLogic:Data 调用了WCRedEnvelopesReceiveControlLogic的startLogic 方法
  • 于是我们又回到了 WCRedEnvelopesReceiveControlLogic中,使用 Hopper 打开WCRedEnvelopesReceiveControlLogic 的 startLogic实现


    image.png

    image.png
  • 我们发现显示为灰色,完全看不懂,查了一下Hopper 的官方文档发现灰色代表undefined,不知道为什么!这个问题想了很久没想通!但是在搜索关键字的时候有一个极其相似的方法:
    [WCRedEnvelopesGreetingReceiveControlLogic startLogic]
    然后我就想这两个会不会实现类似,于是我分析了该函数发现


    image.png

    image.png
  • 以上调用了 WCRedEnvelopesLogicMgr的ReceiverQueryRedEnvelopesRequest
    方法,接下来就是验证看有没有调用这个方法,hook 该方法,打上断点
CHDeclareClass(WCRedEnvelopesLogicMgr);

CHOptimizedMethod1(self, void, WCRedEnvelopesLogicMgr, ReceiverQueryRedEnvelopesRequest, id, arg1) {
    NSLog(@"%@", arg1);
    /*
     agreeDuty = 0;
     channelId = 1;
     inWay = 1;
     msgType = 1;
     nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039501201709137007742337288&sendusername=jirenbang-com&ver=6&sign=f4455577adc87b21387127f45e6c3803649800302ac90134018c10c4a87b3a0a5df85d4360028ad28b997bbdb4e52e6b8b62804fc04444185bb4f6617359a8c41565d1592d5d251c1a8b0aaef1fdb3de576d88890323720ae701bb3e56b3e900";
     sendId = 1000039501201709137007742337288;
     */
    CHSuper1(WCRedEnvelopesLogicMgr, ReceiverQueryRedEnvelopesRequest, arg1);
}
  • 点击红包消息,发现触发了断点,打印参数同上面打开红包获取的一样,接下来我们测试一下ReceiverQueryRedEnvelopesRequest:方法的参数
  • 查看汇编代码


    image.png
  • 没看懂,只能又靠猜,这里肯定是发了一个网络请求,肯定会有响应!我们查看一下WCRedEnvelopesLogicMgr的头文件搜索 response发现以下OnWCToHongbaoCommonResponse: Request:方法有点像,我们测试一下该方法:
CHOptimizedMethod2(self, void, WCRedEnvelopesLogicMgr, OnWCToHongbaoCommonResponse, id, arg1, Request, id, arg2) {
    
    NSLog(@"%@", arg1);
    NSLog(@"%@", arg2);
    /*
     <HongBaoRes: 0x1123400f0>
     <HongBaoReq: 0x1123805f0> 
    */
    CHSuper2(WCRedEnvelopesLogicMgr, OnWCToHongbaoCommonResponse, arg1, Request, arg2);
}
  • 我们搜索打开HongBaoRes.h文件,查看发现了一个可疑的retText属性类型为SKBuiltinBuffer_t
@property(retain, nonatomic) SKBuiltinBuffer_t *retText; // 
  • 我们继续搜索SKBuiltinBuffer_t.h 文件,我们又发现
@property(retain, nonatomic) NSData *buffer; // @dynamic buffer;
  • 一般我们的网络数据返回都是 json 格式,我们不妨写代码测试一下
        if ([NSStringFromClass([arg1 class]) isEqualToString:@"HongBaoRes"]) {
            NSData *data = [[arg1 retText] buffer];
            
            if (nil != data && 0 < [data length]) {
                NSError* error = nil;
                id jsonObj = [NSJSONSerialization JSONObjectWithData:data
                                                             options:NSJSONReadingAllowFragments
                                                               error:&error];
              }
        }
  • 经调试,如我们所猜测的一样,我们的 jsonObj 中含有timingIdentifier字段!
  • 到此,我们完整的分析出了手动领取一个红包的目标函数,所要的所有参数,和所有的参数是如何获取的!
接下来我们就应该着手实现自动抢红包的逻辑!
  • 不用多想,自动抢红包的时机,肯定是在收到消息的时候咯!所以我们去 hook 收到消息的方法!
  • 接下来我们分析消息,对于这种没有 UI 的方法,我的逆向思路就是猜!关键字搜索是我用来最常用的猜测方法,消息英文 message,缩写msg!
  • 我们在 class-dump 头文件中搜索 message


    image.png
  • 上图红框部分这几个最像了,点击一个一个查看!最终定位到CMessageMgr的方法最像了,CMessage,CMessageWrap更像是模型,CMessageMgr是管理消息的地方!
  • 我们打开CMessageMgr.h文件,搜索关键字 receive没有,搜索 message,也没有,搜索 msg


    image.png
  • 这些画红圈是我认为比较可以可疑的方法,不过我觉的最可疑的还是
- (void)AsyncOnAddMsg:(id)arg1 MsgWrap:(id)arg2;
  • 这个方法,原因很简单,首先即有 msg,又有 msgwrap,然后一般这种多参数的方法,按照我写代码的思路来说,参数越多说明这个方法越受约束,越不不通用,这样想的话我首先 hook AsyncOnAddMsg:MsgWrap:方法!
  • 接下来就是写代码验证了:
CHDeclareClass(CMessageMgr);
CHMethod(2, void, CMessageMgr, AsyncOnAddMsg, id, arg1, MsgWrap, id, arg2) {
    NSLog(@"%@", arg1);
    NSLog(@"%@", arg2);
    CHSuper(2, CMessageMgr, AsyncOnAddMsg, arg1, MsgWrap, arg2);
}
  • 叫人发个红包给我们,触发断点,查看参数:


    image.png
  • 上图我们需要关注的是 m_uiMessageType 和 m_nsContent
  • m_uiMessageType == 49 为 红包消息
  • m_nsContent 如下图
<msg>
    <appmsg appid="" sdkver="">
        <des><![CDATA[我给你发了一个红包,赶紧去拆!]]></des>
        <url><![CDATA[https://wxapp.tenpay.com/mmpayhb/wxhb_personalreceive?showwxpaytitle=1&msgtype=1&channelid=1&sendid=1000039501201709137014370817311&ver=6&sign=8f446c219788bb6db911ff7de1eefd3ac9a66298b8d8d9be3f0018f14524bbb16ca78e0b22357967ebeb36860b892b0d5300d8ae5ae70ac29759a3c673cea9f6205adb65ae01d71d29a7b7a2b757333c0f264b07f893dfb88c28ece6e9869236]]></url>
        <type><![CDATA[2001]]></type>
        <title><![CDATA[微信红包]]></title>
        <thumburl><![CDATA[http://wx.gtimg.com/hongbao/1701/hb.png]]></thumburl>
        <wcpayinfo>
            <templateid><![CDATA[7a2a165d31da7fce6dd77e05c300028a]]></templateid>
            <url><![CDATA[https://wxapp.tenpay.com/mmpayhb/wxhb_personalreceive?showwxpaytitle=1&msgtype=1&channelid=1&sendid=1000039501201709137014370817311&ver=6&sign=8f446c219788bb6db911ff7de1eefd3ac9a66298b8d8d9be3f0018f14524bbb16ca78e0b22357967ebeb36860b892b0d5300d8ae5ae70ac29759a3c673cea9f6205adb65ae01d71d29a7b7a2b757333c0f264b07f893dfb88c28ece6e9869236]]></url>
            <iconurl><![CDATA[http://wx.gtimg.com/hongbao/1701/hb.png]]></iconurl>
            <receivertitle><![CDATA[Best wishes]]></receivertitle>
            <sendertitle><![CDATA[Best wishes]]></sendertitle>
            <scenetext><![CDATA[微信红包]]></scenetext>
            <senderdes><![CDATA[查看红包]]></senderdes>
            <receiverdes><![CDATA[领取红包]]></receiverdes>
            <nativeurl><![CDATA[wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039501201709137014370817311&sendusername=wxid_mryox0wndn8122&ver=6&sign=8f446c219788bb6db911ff7de1eefd3ac9a66298b8d8d9be3f0018f14524bbb16ca78e0b22357967ebeb36860b892b0d5300d8ae5ae70ac29759a3c673cea9f6205adb65ae01d71d29a7b7a2b757333c0f264b07f893dfb88c28ece6e9869236]]></nativeurl>
            <sceneid><![CDATA[1002]]></sceneid>
            <innertype><![CDATA[0]]></innertype>
            <paymsgid><![CDATA[1000039501201709137014370817311]]></paymsgid>
            <scenetext>微信红包</scenetext>
            <locallogoicon><![CDATA[c2c_hongbao_icon_cn]]></locallogoicon>
            <invalidtime><![CDATA[1505373603]]></invalidtime>
        </wcpayinfo>
    </appmsg>
    <fromusername><![CDATA[wxid_mryox0wndn8122]]></fromusername>
</msg>
  • 对比刚开始的 dictionaryWithDecodedComponets:separator:方法传入的参数就是我们的 url 的一部分!

  • 我们可以通过 url 获取到msgType,sendId,channelId

  • 至于nickName ,headImg我们可以从前面的汇编代码还原出实现来

  • nativeUrl截取 url 的一部分

  • sessionUserName可以从 arg2 中获得

  • 至此我们已经获取到了打开红包除了 timingIdentifier 外的所有参数

  • timingIdentifier参数,我们调用前面分析出来的 [WCRedEnvelopesLogicMgr ReceiverQueryRedEnvelopesRequest:] 方法来获取

  • 该方法需要以下参数都可以通过 m_nsContent 获取到

     agreeDuty = 0;
     channelId = 1;
     inWay = 1;
     msgType = 1;
     nativeUrl = "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039501201709137007742337288&sendusername=jirenbang-com&ver=6&sign=f4455577adc87b21387127f45e6c3803649800302ac90134018c10c4a87b3a0a5df85d4360028ad28b997bbdb4e52e6b8b62804fc04444185bb4f6617359a8c41565d1592d5d251c1a8b0aaef1fdb3de576d88890323720ae701bb3e56b3e900";
     sendId = 1000039501201709137007742337288;
  • 之后我们 hook WCRedEnvelopesLogicMgr 的
    OnWCToHongbaoCommonResponse方法,通过arg1取到 timingIdentifier字段!
  • 最终我们打开红包的所有参数获取完毕,接下来只需要调用OpenRedEnvelopesRequest:方法,便可以实现自动抢红包功能!
  • 至此,我们成功实现了微信自动抢红包的功能!
总结:

在逆向抢红包的过程中,我主要使用了静态分析和动态调试的手段:

  • 静态分析,主要是从 class-dump 出来的头文件,辅助 Reveal,cycript,来寻找目标类或者目标函数,涉及到具体逻辑的时候,我会使用 Hopper Disassembler 来查看具体方法的具体实现,来进一步的猜测实现逻辑
  • 动态调试,我们静态分析出来的结果或猜测,需要动态的去调试验证!
    • 由于我是未越狱设备,我主要使用的是 Xcode + MonkeyDev 来 Hook 原方法,然后打印参数等简单的调试
    • 如果你是越狱设备你可以使用 lldb+debugserver 神器来调试你的程序,那样的话理论上整个程序对你来说都是透明,因为你可以像在 Xcode正向开发应用一样具体一步一步的调试,对那些感兴趣的功能点,你可以下断点,然后去触发断点,跟踪调试!
最后分享一下我的逆向技巧:
  • 猜 + 验证,用关键字去猜,想想如果是自己写这个 App 会怎样去写,会怎样命名!
    • 然后你可以使用 Finder 的搜索功能,说句题外话,Finder 的搜索功能确实好用不仅可以搜索到文件名,内容也可以搜索到!
    • 当然你也可以使用 Xcode 新建一个工程将 class-dump 出来的头文件添加到工程,利用 Xcode 的搜索shift+cmd+o 搜索文件,shift+cmd+f,全局搜索关键字!
  • 一般我都是使用常用的命名去搜,比如在寻找微信消息收发目标函数的时候,我们没有 UI 辅助,这时候只能靠猜,我使用了 message msg receive 等关键字查找定位
  • 在获取 timingIdentifier 参数的时候我不知道 我通过分析找到了
    ReceiverQueryRedEnvelopesRequest方法来获取该参数,但是它的实现我看不太懂,这时候我又使用了猜,搜索了 response,找到了
    ReceiverQueryRedEnvelopesResponse 方法!最终获取到了timingIdentifier 参数!
  • 当然猜的过程中你可能会出错,这是一个非常枯燥的过程,逆向工程相对于正向开发来说是一件比较枯燥的事情,可能你花了几天最终得到的只是一个目标函数!而在正向开发过程中,你写的代码都会转换为成果!或许是一个完美的动画,或许是流畅的界面!
  • 所以看完如果你能够完整看完本文,然后一步一步去实践的话,那说明你还是比较适合干这个的,如果不能那还是老老实实搞点 app 开发吧!
本人是个逆向新手,若有错误之处,请多多指正
参考文章:

iOS 应用逆向工程(入门书籍)
iOS冰与火之歌 – UAF and Kernel Pwn - 蒸米
MonkeyDev 文档

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

推荐阅读更多精彩内容