iOS逆向記錄(五)微信搶紅包第一篇

14. 項(xiàng)目實(shí)戰(zhàn)(微信搶紅包插件)

14.1 定位紅包消息響應(yīng)方法

14.1.1 砸殼和導(dǎo)出頭文件以供分析用

詳細(xì)過(guò)程見(jiàn)筆記第7章

 DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/749DC69A-3A8D-4B5C-9926-1220E69FC85F/WeChat.app/WeChat
  
class-dump -s -S -H WeChat.decrypted -o ./MyHeaders

14.1.2 借助cycript來(lái)動(dòng)態(tài)分析界面定位視圖控制器(ViewController)

  • 打開(kāi)應(yīng)用并使用cycript附加進(jìn)程
  cycript -p WeChat
  • 使用recursiveDescription打印UIView對(duì)象
 [[UIApp keyWindow] recursiveDescription].toString()
 或者
 UIApp.keyWindow.recursiveDescription().toString()
  • 選擇一個(gè)UIView對(duì)象的id,借助nextResponder方法獲取視圖控制器
 <UIView: 0x14eaed070; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x14eafa130>>
  
 //使用nextResponder找到視圖控制器(ViewController)
 cy# [#0x14eaed070 nextResponder]
 #"<BaseMsgContentViewController: 0x14f1dc200>"
  • 在class-dump到處的頭文件中姿骏,查找BaseMsgContentViewController相關(guān)的文件
 ? ls -al *BaseMsgContentViewController*
 -rw-r--r--  1 liuzhongzheng  staff  26105 Aug 25 15:59 BaseMsgContentViewController.h
  • cycript的其它用法介紹

    • _printHierarchy - 直接打印所有UIViewController

      [[[UIWindow keyWindow] rootViewController] _printHierarchy].toString()
      
    • _autolayoutTrace - recursiveDescription的簡(jiǎn)化版甩栈,去掉了UIView的一些描述

    [[UIApp keyWindow] _autolayoutTrace].toString()
    
    • 獲取bundle info
    [[NSBundle mainBundle] infoDictionary].toString()
    

14.1.3 借助Reveal來(lái)動(dòng)態(tài)分析界面定位視圖控制器(ViewController)

  • OSX 上安裝Reveal
    官網(wǎng):https://revealapp.com/

  • iOS 上安裝Reveal Loader
    通過(guò)Cydia搜索安裝Reveal Loader

  • 使用Reveal觀察界面結(jié)構(gòu)

14.1.4 借助thoes模塊Logify來(lái)精確定位消息響應(yīng)方法

  • 創(chuàng)建Tweak工程

  • 批量生成hook BaseMsgContentViewController.h文件中方法的Tweak.xm文件

/opt/theos/bin/logify.pl ../WeChat/Headers/BaseMsgContentViewController.h > Tweak.xm
  • 用logify.pl生成的Tweak.xm文件替換Tweak工程中的Tweak.xm文件

  • 編譯Tweak工程并安裝

make package
make install
  • 通過(guò)查看和分析日志定位消息響應(yīng)的方法
tail -f /var/log/syslog | grep WeChat
 
[<BaseMsgContentViewController: 0x1368e9c00> addMessageNode:{m_uiMesLocalID=38, m_ui64MesSvrID=6021494297990342718, m_nsFromUsr=wxi*431~19, m_nsToUsr=wxi*r12~19, m_uiStatus=4, type=1, msgSource="<msgsource><sequence_id>649531066</sequence_id></msgsource>"}  layout:1 addMoreMsg:0]
 
//定位到與消息響應(yīng)相關(guān)的方法
- (void)addMessageNode:(id)arg1 layout:(_Bool)arg2 addMoreMsg:(_Bool)arg3 { %log; %orig; }

14.1.5 借助lldb進(jìn)行動(dòng)態(tài)調(diào)試

  • 在iOS上配置debugserver
  • 把iPhone連接xcode尿孔,在iOS上/Developer/usr/bin/目錄下面生成調(diào)試工具debugserver
 Flongers-iPhone:/Developer/usr/bin root# ls
 DTDeviceArbitration*  ScreenShotr*  XcodeDeviceMonitor*  debugserver*  iprofiler*  xctest*
  • 給debugserver瘦身和重新簽名祠汇,并放入/usr/bin/目錄下方便隨時(shí)調(diào)用
    lipo(靜態(tài)庫(kù)拆分與合并)命令的介紹: http://www.reibang.com/p/e590f041c5f6

    //拷貝到OS X上去
    scp debugserver luz@192.168.1.138:/tmp 
     
    //查看CPU架構(gòu)信息
    ?lipo -info debugserver 
    Architectures in the fat file: debugserver are: armv7 armv7s arm64
    
    //瘦身
    lipo -thin arm64 debugserver -output debugserver.thin
     
    //使用ldid添加task_for_pid權(quán)限
    ?  ldid -Sent.xml debugserver.thin 
    ?  ldid -e debugserver.thin 
     <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
     <plist version="1.0">
     <dict>
             <key>com.apple.springboard.debugapplications</key>
             <true/>
             <key>get-task-allow</key>
             <true/>
             <key>task_for_pid-allow</key>
             <true/>
             <key>run-unsigned-code</key>
             <true/>
     </dict>
     </plist>
      
    //使用codesign添加task_for_pid權(quán)限
    codesign -s - --entitlements ent.plist -f debugserver.thin
    ? ldid -e  debugserver.thin
     <?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>com.apple.springboard.debugapplications</key>
         <true/>
         <key>run-unsigned-code</key>
         <true/>
         <key>get-task-allow</key>
         <true/>
         <key>task_for_pid-allow</key>
         <true/>
     </dict> 
     </plist>
    
  • 在iOS使用debugserver附加程序

    • 打開(kāi)調(diào)試
    debugserver -x backboard IP:port /path/to/executable
    
    • 附加調(diào)試
    debugserver *:9527 -a "WeChat"
    
  • 在OSX使用lldb連接debugserver進(jìn)行調(diào)試

 lldb 
 process connect connect://192.168.1.113:9527  //ip是iPhone的地址,端口要一致
  • 使用usbmuxd工具通過(guò)USB口轉(zhuǎn)發(fā)ssh和調(diào)式信息
  • 通過(guò)USB口轉(zhuǎn)發(fā)ssh
 //把本地2222端口轉(zhuǎn)發(fā)到iOS的22(ssh)端口
 ./tcprelay.py -t 22:2222
 Forwarding local port 2222 to remote port 22

 //ssh進(jìn)行連接 - localhost(127.0.0.1)是本地主機(jī)(本機(jī)的標(biāo)準(zhǔn)域名)
 ssh root@localhost -p 2222   
  • 通過(guò)USB口轉(zhuǎn)發(fā)lldb調(diào)試

    //把本地9527端口轉(zhuǎn)發(fā)到iOS的9527端口
    ./tcprelay.py -t 9527:9527
     
    //在iOS上指定debugserver監(jiān)聽(tīng)的端口號(hào)(要與9527:9527冒號(hào)前面的一致9527)
    debugserver *:9527 -a "WeChat" 
     
    //在OSX上指定連接的端口號(hào)(要與9527:9527冒號(hào)后面的一致)
    lldb 
    process connect connect://localhost:9527 
    
  • 查看ASLR偏移

image list -o -f 
 
(lldb) image list -o -f
[  0] 0x0000000000054000 /private/var/mobile/Containers/Bundle/Application/749DC69A-3A8D-4B5C-9926-1220E69FC85F/WeChat.app/WeChat(0x0000000100054000)

偏移后模塊基地址 = 偏移前模塊基地址 + 模塊的ASLR偏移
偏移后符號(hào)基地址 = 偏移前符號(hào)基地址 + 符號(hào)所在模塊的ASLR偏移(一般用在這兒)
偏移后指令基地址 = 偏移前指令基地址 + 指令所在模塊的ASLR偏移
  • 使用Hopper查看函數(shù)基地址
 -[BaseMsgContentViewController addMessageNode:layout:addMoreMsg:]:
0000000101dcbb0c         db  0xe9 ; '.'                                         
0000000101dcbb0d         db  0x23 ; '#'
  • 使用lldb的br命令設(shè)備斷點(diǎn)br

     br s -a '0x0000000000054000+0x0000000101dcbb0c'
     
     設(shè)置斷點(diǎn)
     b function
     br s –a address
     br s –a 'ASLROffset+address'
      
     //查看所有斷點(diǎn)
     br list
      
     //刪除斷點(diǎn)
     br delete 1
      
     //程序繼續(xù)運(yùn)行
      
    
  • 發(fā)送消息锨侯,等待觸發(fā)斷點(diǎn)斤斧,然后查看函數(shù)調(diào)用堆棧

(lldb) bt
   * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
     * frame #0: 0x0000000101defb0c WeChat`_mcwxh_dydx33_8to8(_VDecStruct*, unsigned char*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int) + 23979876
       frame #1: 0x0000000102035434 WeChat`_mcwxh_dydx33_8to8(_VDecStruct*, unsigned char*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int) + 26361996
       frame #2: 0x000000010202059c WeChat`_mcwxh_dydx33_8to8(_VDecStruct*, unsigned char*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int) + 26276340
       frame #3: 
       WeChat`_mcwxh_dydx33_8to8(_VDecStruct*, unsigned char*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int) + 34703800
       frame #4: 0x0000000187955f9c Foundation`__NSThreadPerformPerform + 372
       frame #5: 0x0000000186a0c240 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
       frame #6: 0x0000000186a0b4e4 CoreFoundation`__CFRunLoopDoSources0 + 264
       frame #7: 0x0000000186a09594 CoreFoundation`__CFRunLoopRun + 712
       frame #8: 0x00000001869352d4 CoreFoundation`CFRunLoopRunSpecific + 396
       frame #9: 0x00000001901536fc GraphicsServices`GSEventRunModal + 168
       frame #10: 0x000000018b4fafac UIKit`UIApplicationMain + 1488
       frame #11: 0x00000001000bab5c WeChat`_mh_execute_header + 617308
       frame #12: 0x00000001988a6a08 libdyld.dylib`start + 4
  
 //計(jì)算函數(shù)地址
偏移后符號(hào)基地址 = 偏移前符號(hào)基地址 + 符號(hào)所在模塊的ASLR偏移
偏移后符號(hào)基地址 - 符號(hào)所在模塊的ASLR偏移 = 偏移前符號(hào)基地址
0x0000000101e3db24 -  00000000000f4000 =  101D49B24
  • 在Hopper或者IDA中分析函數(shù)調(diào)用關(guān)系

    0x0000000101dcbb0c
    -[BaseMsgContentViewController addMessageNode:layout:addMoreMsg:]
    
    //在此處設(shè)置斷點(diǎn),發(fā)現(xiàn)只有在當(dāng)前聊天界面才會(huì)觸發(fā)递胧,不是我們找的目標(biāo)方法
    0x102011434 = 0x0000000102035434 - 0x0000000000024000 
    -[BaseMsgContentLogicController DidAddMsg:]
    
    a //在此處設(shè)置斷點(diǎn)碑韵,發(fā)現(xiàn)只有在當(dāng)前聊天界面才會(huì)觸發(fā),不是我們找的目標(biāo)方法
    0x101FFC59C = 0x000000010202059c - 0x0000000000024000 
    -[BaseMsgContentLogicController OnAddMsg:MsgWrap:]
    
    //在此處設(shè)置斷點(diǎn)缎脾,只要收到消息就會(huì)觸發(fā)祝闻,符合我們尋址的目標(biāo)方法
    0x102805D60 = 0x0000000102829d60 - 0x0000000000024000 
    -[CMessageMgr MainThreadNotifyToExt:]
     
    注:定位到另一個(gè)與消息接收有關(guān)的類(lèi)CMessageMgr,在微信到處頭文件中發(fā)現(xiàn)有同名文件CMessageMgr.h
    
  • 繼續(xù)使用Tweak來(lái)hook CMessageMgr中的方法遗菠,觀察日志輸出

    //使用logify來(lái)繼續(xù)追蹤C(jī)MessageMgr這個(gè)類(lèi)联喘,發(fā)現(xiàn)消息到來(lái)時(shí),這幾個(gè)方法有響應(yīng)
     
    //單獨(dú)分析這幾個(gè)方法
    %hook CMessageMgr
    - (void)AsyncOnPreAddMsg:(id)arg1 MsgWrap:(id)arg2 { %log; %orig; }
    - (void)AsyncOnAddMsg:(id)arg1 MsgWrap:(id)arg2 { %log; %orig; }
    - (void)AsyncOnPushMsg:(id)arg1 { %log; %orig; }
    - (void)CheckMessageStatus:(id)arg1 Msg:(id)arg2 { %log; %orig; }
    %end
     
    1.打開(kāi)聊天界面時(shí)CheckMessageStatus有反應(yīng)舷蒲,所以排除它
    2.AsyncOnPreAddMsg耸袜、AsyncOnAddMsg、AsyncOnPushMsg這三個(gè)方法都是在消息到來(lái)時(shí)觸發(fā)牲平,從
      方法命名AsyncOnPreAddMsg應(yīng)該是消息的前置處理堤框,AsyncOnPushMsg可能是往隊(duì)列里面添加消息。
      這三個(gè)方法都可以用來(lái)備選纵柿,我們先選AsyncOnAddMsg蜈抓。
     
    //分析AsyncOnAddMsg的參數(shù) 
    %hook CMessageMgr
    - (void)AsyncOnAddMsg:(id)arg1 MsgWrap:(id)arg2 {
        NSLog(@"arg1 = %@ , arg2 = %@", arg1, arg2); 
        NSLog(@"arg1 class = %@ , arg2 class = %@", [arg1 class], [arg2 class]);  
        %orig; 
    }
    %end
    //參數(shù)輸出日志如下
    Sep  9 16:39:53 Flongers-iPhone WeChat[16048]: arg1 = wxid_lx85gyfaib9431 , arg2 = {m_uiMesLocalID=61, m_ui64MesSvrID=6890149828648546534, m_nsFromUsr=wxi*431~19, m_nsToUsr=wxi*r12~19, m_uiStatus=3, type=1, msgSource="<msgsource><sequence_id>649531092</sequence_id></msgsource>"} 
    Sep  9 16:39:53 Flongers-iPhone WeChat[16048]: arg1 = __NSCFString , arg2 = CMessageWrap
    //所以消息響應(yīng)函數(shù)如下,CMessageWrap亦有同名的導(dǎo)出頭文件CMessageWrap.h
    - (void)AsyncOnAddMsg:(NSString *)wxid MsgWrap:(CMessageWrap *)wrap; 
    
  • 分析消息內(nèi)容相關(guān)的類(lèi)CMessageWrap

@interface CMessageWrap
  @property (nonatomic, strong) NSString* m_nsContent;
  @property (nonatomic, assign) NSInteger m_uiMessageType;
  @property(retain, nonatomic) NSString *m_nsFromUsr;
  @property(retain, nonatomic) NSString *m_nsToUsr; 

  @property(retain, nonatomic) NSString *m_nsAtUserList; // @synthesize m_nsAtUserList;
  @property(retain, nonatomic) NSString *m_nsBizChatId; // @synthesize m_nsBizChatId;
  @property(retain, nonatomic) NSString *m_nsBizClientMsgID; // @synthesize m_nsBizClientMsgID;
  @property(retain, nonatomic) NSString *m_nsDisplayName; // @synthesize m_nsDisplayName;
  @property(retain, nonatomic) NSString *m_nsKFWorkerOpenID; // @synthesize m_nsKFWorkerOpenID;
  @property(retain, nonatomic) NSString *m_nsMsgSource; // @synthesize m_nsMsgSource;
  @property(retain, nonatomic) NSString *m_nsPattern; // @synthesize m_nsPattern;
  @property(retain, nonatomic) NSString *m_nsPushContent; // @synthesize m_nushContent;
  @property(retain, nonatomic) NSString *m_nsRealChatUsr; // @synthesize m_nsRealChatUsr;
  @end
   
  %hook CMessageMgr
  - (void)AsyncOnAddMsg:(NSString *)wxid MsgWrap:(CMessageWrap *)wrap {
    %orig;
    NSInteger uiMessageType = [wrap m_uiMessageType];
    NSString* content = [wrap m_nsContent];
    NSString* nsFromUsr = [wrap m_nsFromUsr];
    NSString* nsToUsr = [wrap m_nsToUsr];
    NSString* nsAtUserList = [wrap m_nsAtUserList];
    NSString* nsBizChatId = [wrap m_nsBizChatId];
    NSString* nsBizClientMsgID = [wrap m_nsBizClientMsgID];
    NSString* nsKFWorkerOpenID = [wrap m_nsKFWorkerOpenID];
    NSString* nsMsgSource = [wrap m_nsMsgSource];
    NSString* nsDisplayName = [wrap m_nsDisplayName];
    NSString* nsPattern = [wrap m_nsPattern];
    NSString* nsRealChatUsr = [wrap m_nsRealChatUsr];
    NSString* nsPushContent = [wrap m_nsPushContent];
     
    NSLog(@"m_uiMessageType=%zd m_nsContent=%@ m_nsFromUsr=%@ m_nsToUsr=%@ m_nsAtUserList=%@ m_nsBizChatId=%@ m_nsBizClientMsgID=%@ m_nsDisplayName=%@ m_nsKFWorkerOpenID=%@ m_nsMsgSource=%@ m_nsPattern=%@ m_nsPushContent=%@ m_nsRealChatUsr=%@",
                                          uiMessageType,
                                          content,
                                          nsFromUsr,
                                          nsToUsr,
                                          nsAtUserList,nsBizChatId,                 
                                          nsBizClientMsgID,
                                          nsDisplayName,
                                          nsKFWorkerOpenID,
                                          nsMsgSource,
                                          nsPattern,
                                          nsPushContent,
                                          nsRealChatUsr);
                                            //記錄消息 
    if( 1 == uiMessageType ){ //普通消息
      if( 0 == nsPushContent.length){
          if([nsToUsr rangeOfString:@"filehelper"].location != NSNotFound)
              NSLog(@"[文件助手: %@]",content);
          else  NSLog(@"[我: %@]",content);
      }else
        NSLog(@"[%@]",nsPushContent);      
    }else if ( 3 == uiMessageType ){ //圖片消息
       NSLog(@"收到圖片消息");
    }else if ( 49 == uiMessageType ){ //紅包消息
       NSLog(@"收到紅包消息");
    }  
  }%end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昂儒,一起剝皮案震驚了整個(gè)濱河市沟使,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渊跋,老刑警劉巖腊嗡,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件着倾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡燕少,警方通過(guò)查閱死者的電腦和手機(jī)卡者,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)客们,“玉大人崇决,你說(shuō)我怎么就攤上這事〉状欤” “怎么了恒傻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)建邓。 經(jīng)常有香客問(wèn)我盈厘,道長(zhǎng),這世上最難降的妖魔是什么官边? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任扑庞,我火速辦了婚禮,結(jié)果婚禮上拒逮,老公的妹妹穿的比我還像新娘。我一直安慰自己臀规,他們只是感情好滩援,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著塔嬉,像睡著了一般玩徊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谨究,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天恩袱,我揣著相機(jī)與錄音,去河邊找鬼胶哲。 笑死畔塔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鸯屿。 我是一名探鬼主播澈吨,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寄摆!你這毒婦竟也來(lái)了谅辣?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤婶恼,失蹤者是張志新(化名)和其女友劉穎桑阶,沒(méi)想到半個(gè)月后柏副,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚣录,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年割择,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片包归。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锨推,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出公壤,到底是詐尸還是另有隱情换可,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布厦幅,位于F島的核電站沾鳄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏确憨。R本人自食惡果不足惜译荞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望休弃。 院中可真熱鬧吞歼,春花似錦、人聲如沸塔猾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丈甸。三九已至糯俗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間睦擂,已是汗流浹背得湘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顿仇,地道東北人淘正。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像臼闻,于是被迫代替她去往敵國(guó)和親跪帝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

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