安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

使用Windbg静态分析dump文件(实战经验总结)

9月17日 孤小单投稿
  在日常分析C软件异常的日常工作中,大多数情况下我们都是使用Windbg去静态分析dump文件去排查软件异常的,今天我们就来详细地讲一下如何使用Windbg去静态分析dump文件,以供参考。
  image。png1、概述
  基本大部分软件都内置了异常捕获模块,在软件发生闪退崩溃时,都会弹出相关的提示框,比如PC版的微信在崩溃时,其内置的异常捕获模块会捕获到并生成日志及dump文件,同时会弹出如下的发送错误报告的提示框:
  image。png
  提示框的下方会自动带上崩溃相关的文件,其中最后一个文件就是我们要讲的dump文件,点击确定则会将这些文件发送到腾讯远端的服务器上。腾讯后台的运维人员就会收到通知,然后到服务器上将dump等文件下载下去去分析。
  有些软件可能没有上传崩溃日志到服务器的功能,捕捉到异常时会自动将dump文件保存到指定的路径中,事后可以到该路径中取到对应的dump文件。如果客户机器上遇到崩溃,可以和客户联系,让客户帮忙从对应的路径中取来dump文件。
  下面就来详细讲一下拿到dump文件之后如何使用Windbg去静态分析dump文件。2、静态分析dump文件的一般步骤
  用Windbg打开dump文件,先使用。ecxr命令切换到异常的上下文,然后根据切换成功后显示的异常类型(ExceptionCode值对应的含义,比如0xC0000005对应的就是AccessViolation内存访问违例)、发生崩溃的那条汇编指令及相关寄存器的值。通过查看汇编指令及各寄存器的值,可以初步判断当前发生的是什么异常,比如C类空指针、内存访问违例。
  image。png
  接着,使用knkvkp查看函数调用堆栈,看看是调用了什么函数触发的异常。调用堆栈中会显示函数所在模块信息,一般我们需要拿到这些模块的pdb文件,加载pdb文件后函数堆栈中才会显示具体的函数名和行号的。我们需要使用lm命令查看这些模块的时间戳,然后找来这些模块对应的pdb文件,然后将pdb文件的路径设置到windbg中。
  然后,根据函数调用堆栈中显示的函数名及行号,对照着源代码去分析发生异常的原因。有时候为了搞清楚发生异常的本质,我们还需要使用IDA查看相关二进制文件的汇编代码,查看一下发生异常的那条汇编指令的上下文,对照着C源码,看看那条汇编指令为啥会出现异常。3、分析实例说明
  我们为了方便展开讲解,我们特意使用VisualStudio创建了一个基于MFC对话框的exe程序工程,对话框中有个名为button1的按钮,如下所示:
  image。png
  我们在此按钮的响应中添加了一段引发崩溃的测试代码,故意让程序产生崩溃,测试然后拿到崩溃时的dump文件。
  具体的测试代码如下所示:添加的一段测试代码SHELLEXECUTEINFOpShExeInfoNULL;intnValpShExeInfocbS通过空指针访问结构体成员,导致崩溃CStringstrTstrTip。Format(T(nVald。),nVal);AfxMessageBox(strTip);
  代码中使用到的结构体SHELLEXECUTEINFO定义如下:typedefstructSHELLEXECUTEINFOW{DWORDcbSin,required,sizeofofthisstructureULONGfMin,SEEMASKXXXvaluesHWNDin,optionalLPCWSTRlpVin,optionalwhenunspecifiedthedefaultverbischoosenLPCWSTRlpFin,eitherthisvalueorlpIDListmustbespecifiedLPCWSTRlpPin,optionalLPCWSTRlpDin,optionalintnSin,requiredHINSTANCEhInstAoutwhenSEEMASKNOCLOSEPROCESSisspecifiedvoidlpIDLin,validwhenSEEMASKIDLISTisspecified,PCIDLISTABSOLUTE,forusewithSEEMASKIDLISTSEEMASKINVOKEIDLISTLPCWSTRlpCin,validwhenSEEMASKCLASSNAMEisspecifiedHKEYhkeyCin,validwhenSEEMASKCLASSKEYisspecifiedDWORDdwHotKin,validwhenSEEMASKHOTKEYisspecifiedunion{HANDLEhInotusedif(NTDDIVERSIONNTDDIWIN2K)HANDLEhMin,validwhenSEEMASKHMONITORspecifiedendif(NTDDIVERSIONNTDDIWIN2K)}DUMMYUNIONNAME;HANDLEhPout,validwhenSEEMASKNOCLOSEPROCESSspecified}SHELLEXECUTEINFOW,LPSHELLEXECUTEINFOW;ifdefUNICODEtypedefSHELLEXECUTEINFOWSHELLEXECUTEINFO;typedefLPSHELLEXECUTEINFOWLPSHELLEXECUTEINFO;elsetypedefSHELLEXECUTEINFOASHELLEXECUTEINFO;typedefLPSHELLEXECUTEINFOALPSHELLEXECUTEINFO;endifUNICODE
  在测试代码中定义了SHELLEXECUTEINFO结构体指针pShExeInfo,并初始化为NULL,然后并没有给该指针赋一个有效的结构体对象地址,然后使用pShExeInfo访问结构体的cbSize成员的内存,因为pShExeInfo中的值为NULL,所以结构体cbSize成员的内存地址是结构体对象起始地址的偏移,因为结构体对象地址为NULL,cbSize成员位于结构体的首位,所以cbSize成员就是结构体对象的首地址,就是NULL,所以就访问64KB小地址内存块的异常,引发内存访问违例,导致程序发生崩溃闪退。
  至于如何在程序中设置异常捕获模块去捕获异常、自动生成dump文件,可以尝试使用google开源的CrashRpt库,我们产品很早就有了,具体怎么获取目前还没有研究过,大家需要的话可以到网上搜一下。4、用Windbg打开dump文件,初步分析
  使用Windbg打开dump文件(直接将dump文件拖入到Windbg),然后输入。ecxr命令,切换到异常的上下文,就可以发生的异常类型、发生了异常崩溃的那条汇编及崩溃时的各个寄存器的值。
  首先,我们查看一下发生的异常类型,比如AccessViolation内存访问违例、StackOverflow线程栈溢出的异常,这样对异常有个初步的认知,如下:
  image。png
  接着就是查看发生异常的那条指令,查看指令的构成以及崩溃时的各个寄存器的值,可能能初步估计出发生异常的原因。如果指令中访问了一个很小的地址或者访问了一个很大的地址,都会触发内存访问违例。
  1)访问64KB小地址内存区,引发访问违例
  在Windows系统中,64KB以内的内存地址是禁止访问的,如果程序访问这个范围内的内存,则会触发内存访问违例,系统会强行将进程终止掉。
  2)访问了内核态的大地址内存区,引发访问违例
  对于32位程序,系统会给进程分配4GB的虚拟内存,一般情况下用户态和内核态会各占一半,即各占2GB,我们编写的代码基本都是运行在用户态的,用户态的代码时不能访问内核态内存地址的(内核态地址是供系统内核模块使用的),如果崩溃指令中访问了一个很大的内存地址,超过用户态的地址范围02GB,内存地址大于0x8000000,则会触发内存违例,因为用户态的代码是禁止访问内核态内存地址的。
  如果汇编指令中使用到了ecx寄存器进行地址计算,去访问计算出来的内存地址,如果访问了一个小内存地址并且ecx寄存器为0,那么这个崩溃可能是空指针引发的。在C中,在调用C类的成员函数时是通过ecx寄存器传递C对象地址的,所以在通过C类对象去调用虚函数(调用虚函数时的二次寻址)及通过C对象去访问对象中的数据成员时,都会用到ecx寄存器的。
  上面故意添加的会引发崩溃的测试代码,运行后产生dump文件,我们来分析一下这个dump文件。用Windbg打开dump文件后,输入。excr命令,接着输入kn命令,查看到如下的结果:
  image。png
  首先,这是AccessViolation内存访问违例的异常。其次,从崩溃的这条汇编指令来看,是访问了小地址0x00000000地址,这是访问了小于64KB小地址内存区,这个范围的地址是禁止访问的,所以引发了内存访问违例。从汇编指令及寄存器的值来看,看不出来什么明显的线索。
  所以接着输入了kn命令,将函数调用堆栈打印出来。函数调用堆栈是从下往上看的,最上面一行就是最后调用的一个函数,也是崩溃的那条汇编指令所在的函数。从函数调用堆栈的最后一帧调用的函数来看,程序的崩溃是发生在TestDlg。exe文件模块中,不是其他的dll模块。显示的函数地址是相对TestDlg。exe文件模块起始地址的偏移,为啥看不到模块中具体函数名称呢?那是因为Windbg找不到TestDlg。exe对应的pdb文件,pdb文件中包含对应的二进制文件中的函数名称及变量等信息,Windbg加载到pdb文件才能显示完整的函数名。查看函数调用堆栈的命令,除了kn,还有kv和kp命令,其中kv还可以看到函数调用堆栈中调用函数时传递的参数,如下所示:
  我们需要取来pdb符号库文件,去查看具体的函数名及行号的,这样才好找到直接的线索的。下面就来看看如何获取到TestDlg。exe模块的pdb文件。5、找到pdb文件,设置到windbg中,查看完整的函数调用堆栈
  如何才能找到TestDlg。exe文件对应的dpb文件?我们可以通过查看TestDlg。exe文件的时间戳找到文件的编译时间,通过编译时间找到文件对应的pdb文件。在Windbg中输入lmvmTestDlg命令,可以查看到TestDlg。exe文件的详细信息,其中就包含文件的时间戳:(当前的lm命令中使用m通配符参数,所以在TestDlg后面加上了号)
  image。png
  可以看到文件是2022年6月25日8点26分23秒生成的,就可以找到对应时间点的pdb文件了。一般在公司正式的项目中,通过自动化软件编译系统,每天都会自动编译软件版本,并将软件的安装包及相关模块的pdb文件保存到文件服务器中,如下所示:
  这样我们就可以根据模块的编译时间找到对应版本的pdb文件了。
  我们找到了TestDlg。exe对应的pdb文件TestDlg。pdb,将其所在的路径设置到Windbg中。点击Windbg菜单栏中的FileSymbolFilePath。。。,打开设置pdb文件路径的窗口,将pdb文件的路径设置进去,如下所示:
  image。png
  点击OK按钮之前,最好勾选上Reload选项,这样Windbg就会去自动加载pdb文件了。但有时勾选了该选项,好像不会自动去加载,我们就需要使用。reloadfTestDlg。exe命令去让Windbg强制去加载pdb文件(命令中必须是包含文件后缀的文件全名)。
  设置完成后,我们可以再次运行lmvmTestDlg命令去看看pdb文件有没有加载进来:
  image。png
  如果已经加载进来,则会在上图中的位置显示出已经加载进来的pdb文件的完整路径。,如上所示。
  加载到TestDlg。exe文件对应的pdb文件之后,我们再次执行kn命令就可以包含具体的函数名及及代码的行号信息了,如下:
  image。png
  我们看到了具体的函数名CTestDlgDlg::OnBnClickedButton1,还看到了对应的代码行号312。通过这些信息,我们就能到源代码中找到对应的位置了,如下所示:
  image。png
  是访问了空指针产生的异常。当然上面的代码是我们故意这样写的,目的是为了构造一个异常来详细讲解如何使用Windbg进行动态调试跟踪的。6、将C源代码路径设置到Windbg中,Windbg会自动跳转到源代码行号上
  为了方便查看,我们可以直接在Windbg中设置C源码路径,这样Windbg会自动跳转到源码对应的位置。点击Windbg菜单栏的FileSourceFilePath。。。,将源码路径设置进去:
  image。png
  然后Windbg会自动跳转到对应的函数及行号上:
  image。png
  然后点击函数调用堆栈中每行最前面的数字超链接,就可以自动切换到对应的函数中。上图中的函数调用堆栈中很多模块是系统库中的,比如mfc100u、User32等,这些库是系统库,是没有源码的。我们可以点击最下面的第23个链接,其位于我们应用程序的模块中,会自动跳转到对应的代码中,如下:
  image。png7、有时需要查看函数调用堆栈中函数的局部变量或C类对象中变量的值
  有时我们通过查看变量的值,找到排查问题的线索,比如变量中值为0或者很大的异常值。这点我们在多次问题排查中使用到,确实能找到一些线索。
  可以查看函数中局部变量的值,也可以查看函数所在类对象的this指针指向的类对象中变量的值。我们要查看哪个函数,就点击函数调用堆栈中每一行前面的数字超链接,如下所示:
  image。png
  我们看到了局部变量pShExeInfo的值:structSHELLEXECUTEINFOWpShExeInfo0x00000000
  我们可以点击this对象的超链接:
  image。png
  就能查看当前函数对应的C类对象中成员变量的值,如下:
  image。png
  但有时不一定能查看变量的值,因为当前通过异常捕获模块自动生成的dump文件一般是minidump文件,文件也就几MB左右,不可能包含所有变量的值。所以要在minidump文件中查看变量的值,要看运气的,有时能查看到,有时是看不到的。这里要讲一下dump文件的分类,主要分为minidump文件和全dump文件。
  我们将windbg附加到进程上使用。dump命令导出的dump文件,是全dump文件,全dump文件中包含了所有的信息,可以查看到所有变量的信息。另外通过任务管理器导出的dump文件:
  image。png
  也是全dump文件。全dump文件因为包含了所有的信息,所以会比较大,会达到数百MB,甚至上GB的大小。但如果通过安装在程序的异常捕获模块CrashReport导出的dump文件就是非全dump文件,是minidump文件,大概只有几MB左右,因为异常捕获模块捕获到异常后,会自动导出dump文件,保存到磁盘上,如果都导出体量很大的全dump文件,很大量消耗用户的磁盘空间,所以我们会设置生成minidump文件。
  在异常捕获模块中我们是通过调用系统API函数MiniDumpWriteDump导出dump文件的,我们通过设置不同的函数调用参数去控制生成minidump文件的。8、有时我们需要用IDA打开二进制文件去查看汇编代码上下文
  有时通过函数调用堆栈中函数及行号,我们很难搞清楚到底为什么会发生崩溃,这时候我们就需要回归本源了,就需要去查看发生异常崩溃的那条汇编指令的上下文了。
  汇编指令最能直观地反映出问题的本质,通过阅读汇编代码,就能搞清楚为啥会触发崩溃了。一般我们在使用。ecxr命令切换到发生异常的汇编指令时,我们可以直接在该条汇编指令的上下文了,点击菜单栏的ViewDisassembly,即可打开显示汇编代码的页面,如下所示:
  image。png
  但直接在Windbg中查看汇编代码,对于我们这些不精通汇编代码的人来说,是有很大困难的,我们是大概率看不懂的。
  一般需要借助IDA工具打开二进制文件去查看汇编代码的,IDA在解析出汇编时会在汇编代码中加上一些注释,特别是在有pdb符号库文件时,会添加更多的注释,通过这些注释,我们就能对照了C源代码,就能大概读懂汇编上下文了。如果能找到pdb符号库文件,则需要将pdb文件放在目标二进制文件的同级目录中,IDA打开二进制文件时会去自动加载pdb文件。8。1、IDA工具介绍
  image。png
  IDA是比利时HexRays公司出品的一款交互式静态反汇编工具。它可以直接反汇编出二进制文件的汇编代码,是目前软件逆向与安全分析领域最好用、最强大的一个静态反汇编软件,已成为众多软件安全分析人员不可缺少的利器!它支持Windows、Linux等多个平台,支持IntelX84、X64、ARM、MIPS等数十种CPU指令集。
  在实际工作中,我们一般使用反汇编工具IDA去打开二进制文件,查看二进制文件中的汇编代码。IDA既支持打开Windows下的。exe、。dll等二进制文件,也可以打开Linux下的。bin、。so等二进制文件。8。2、使用IDA打开二进制文件
  IDA安装完成后,双击启动程序,会弹出如下的提示框:
  image。png
  点击New即新建一个对象。紧接着弹出让选择要打开的文件:
  image。png
  可以找到目标文件的路径,打开目标文件即可。也可以点击取消,然后直接将文件拖到IDA中。打开文件时会让选择加载文件的方式:
  image。png
  对于Windows库,选择PE方式即可。接下来,会弹出是否要加载pdb文件的提示框:
  image。png
  选择Yes即可。前面我们说过,需要将pdb文件放置到目标二进制文件的同一级目录中,这样IDA在打开二进制文件时就会搜索到对应的pdb文件,回去自动加载pdb文件。
  打开后的效果如下:
  image。png
  默认是先是GrapgView图状关系视图,需要右键点击视图区域,在弹出的右键菜单中点击TextView菜单项,切换到TextView文字视图,这样就能看到具体的汇编代码了:
  image。png8。3、在有pdb文件时到IDA中定位到发生异常的汇编指令的位置
  Windbg中发生异常的那条汇编指令,我们需要到IDA中找到对应的位置,然后查看目标位置的汇编指令的上下文。在目标二进制文件有pdb的情况下,要在IDA中定位到发生异常的汇编指令的位置,会比较简单。
  首先在Windbg中显示的函数调用堆栈中找到发生崩溃的那条汇编指令所在的函数名CTestDlgDlg::OnBnClickedButton1,如下:
  image。png
  然后到IDA中,点击菜单栏的JumpJumptofunction。。。,在打开的函数列表窗口中,点击下方的Search按钮,在搜索框中输入函数名后搜索:
  image。png
  在列表中找到函数,双击之久切换到该函数的汇编代码处:
  image。png
  这样就看到该函数的代码段地址,然后加上Windbg中显示的偏移值:
  image。png
  即:CTestDlgDlg::OnBnClickedButton10x320x00401A300x320x00401A62
  就得到发生崩溃的那条汇编指令在当前二进制中的地址,因为汇编指令就为在当前这个函数中,鼠标向下拉动找到地址即可,这样就能找到发生异常的那条汇编指令了。
  其实还有个快捷操作,在计算出发生异常的那条汇编指令的地址后,按下快捷键G,在弹出窗口中输入刚才的地址0x00401A62,就可以直接go到发生异常的那条汇编指令的位置,如下:
  image。png8。4、在没有pdb文件时到IDA中定位到发生异常的汇编指令的位置
  在没有目标二进制文件的pdb文件的情况下,要在IDA中定位到发生异常的汇编指令的位置,会相对麻烦一点。
  发生异常的汇编指令的地址,是程序实际运行时的代码段地址,需要在Windbg中计算出该条汇编指令的地址相对于所在模块起始地址的偏移值,然后加上IDA中该模块的的默认加载地址,就能得到当前汇编指令在IDA中的静态地址,然后直接go过去,就能看到产生异常的汇编指令的上下文了。在本例中,发生异常的汇编指令的地址就是0x00401a62,如下:(发生异常的这行汇编指令最前面的那个地址,就是当前汇编指令的地址)
  image。png
  从函数调用堆栈上看,当前这条发生异常的汇编指令所在的函数为:TestDlg!CTestDlgDlg::OnBnClickedButton10x32
  所以这条指令所属模块为TestDlg。exe,所以使用lm命令查看TestDlg。exe模块的起始地址:
  image。png
  TestDlg。exe模块其实地址为0x00400000(这是系统将TestDlg。exe模块加载到进程空间中的起始地址,代码段地址),所以发生异常的这条汇编指令相对于所在模块TestDlg。exe的偏移地址为:0x00401a620x004000000x00001a62
  然后再到打开TestDlg。exe二进制文件的IDA中,查看该TestDlg。exe模块默认的加载地址:(将滚轮滚动到最上面即可看到,注意此处是默认预加载地址,并不是加载起来后的真正的地址)
  image。png
  这样根据之前计算出来的偏移,加上TestDlg。exe模块的默认加载地址,就得到发生异常的那条汇编指令在IDA打开的静态文件中的位置:0x00001a620x004000000x00401a62
  然后到IDA中按下G快捷键,GO到0x00401a62地址处,即找到发生异常的那条汇编指令:
  image。png
  在IDA中找到发生异常的汇编指令的位置,就可以去查看其附近的汇编代码上下文了。8。5、阅读汇编代码上下文
  我们在阅读汇编代码的上下文时,一般是对照着C源码进行的,然后依托汇编代码上下文中的注释,找到汇编代码与C源码的对应关系。在阅读汇编代码时,要了解一些常用的汇编指令及常用寄存器的使用(比如EAX用来存放函数的返回值,ECX用来传递C对象地址的),熟悉函数调用时的参数入栈、栈分布及参数寻址,了解内存拷贝的汇编代码实现、了解虚函数调用的二次寻址的过程,去啃发生异常的那条汇编指令的上下文中的汇编代码。
  汇编指令比较多,我们只需要了解一些常用的汇编指令即可,如果遇到不熟悉的汇编指令去搜索一下就可以了。
  此外,有一点需要注意的是,在Release下编译器会对C源码会做优化,部分C源码可能会被优化掉,C源码有时不能完全和汇编代码对应起来的,但这基本不影响汇编代码上下文的阅读。
投诉 评论

琅南塔森林村落孩童走吊桥女人抽烟斗《南塔》这里,是位于老挝琅南塔省国家森林保护区中的一个村落。这里,仍然保持着老挝人过去的传统的生活方式,他们靠天吃饭,以大自然为生。这里,人们住在高脚楼里,走……杨紫琼20大精品撑腰贵气全开登上9月号时尚杂志封面以《疯狂亚洲富豪》红遍全球的女星杨紫琼,近日登上9月号时尚杂志封面,不但狂换8套造型,从服装、珠宝、鞋子到帽子更是有超过20大精品撑腰加持,让姐华丽登场贵气全开!八月刚满……朱小伟陈萌婚纱照网络曝光,大衣哥赠豪车豪宅尽显诚意近日,国内知名歌唱家大衣哥朱之文,其儿子朱小伟与新儿媳陈萌,婚纱照拍摄花絮在网络曝光。据知情人爆料,大衣哥朱之文对于此次儿子婚礼相当忠实,更是公开宣布会在陈萌过门前,送上百万婚……超长续航超大运存,OPPOA57亲民价位满足用户刚需现如今的手机市场中,大部分热度都在高端手机上,让人忽略掉中端市场,然而许多品牌都会推出覆盖几乎所有价位段的机型满足不同消费者的需求,让消费者们有更多选择。尤其像中端机型发展到现……使用Windbg静态分析dump文件(实战经验总结)在日常分析C软件异常的日常工作中,大多数情况下我们都是使用Windbg去静态分析dump文件去排查软件异常的,今天我们就来详细地讲一下如何使用Windbg去静态分析dump文件……除了基本养老金待遇,还有9大福利也很实惠,看看你能享受多少大家年轻时工作参保,除了要努力挣钱,维持基本生活,同时也是为了让自己年老后过得更轻松一些。只要满足国家法定退休年龄,并且累计缴纳养老保险满15年,到时候即便不再工作也有钱花,要……北京冬奥会首个开赛项目是冰壶,比赛场馆冰立方四条赛道完工了北京冬奥会冰壶比赛制冰工作进展顺利,国家游泳中心冰立方四条赛道已完工。北京冬奥会冰壶比赛将于2月2日晚开赛,是本届冬奥会首个开赛项目。经过前期制冰、喷漆、布线等施工,冰立……幻塔能让原神谦虚一点吗?本文来自微信公众号:壹娱观察(ID:yiyuguancha),文邢书博。即便《原神》的应用商店版本还停留在2。3版本,但米哈游官方还是在12月26日发布了新版本2。4的前……网飞新剧热度第一,却扑得很难看,网友看完两集被气的血压高在这个好剧本稀缺,同质化剧本泛滥的年代,原著改编和经典重拍已经成了香饽饽。但贩卖情怀,也不是那么容易的,尤其是近几年,翻拍剧扑街早已不是什么新鲜事。无论是国内还是国……中年人的惜命,从不再逼自己开始人到中年,行至半坡,我们的身上,少了年轻时的锋芒毕露,多了几分身不由己。困扰我们的,是扑面而来的生活压力,猝不及防的职场危机,以及大不如前的身体。在这种时候,与其咬……看到不良人3就润!什么比(一声)游戏能把充值入口放这么大(主页有视频更直观)兄弟们,速度速度速度!我来上班了!好久没遇到能让我这么激情开麦的比游戏了,我的大大刀已经饥渴难耐了。游戏名称:《不良人3》taptap评分……什么是藏南?9万平方公里的西藏小江南,少为人知的中国固有领土西藏自治区的东南部,一块约9万平方公里面积的土地藏南一个淡漠在公众视野的中国固有领土。有些国家长期试图夺取藏南领土主权,非法占据领土,而中国始终坚定对主权的正义的掌握而必……
小人物历史第一流浪汉,12年13队,邓肯保罗校友,继续负重前魅族双十一手机推荐旗舰机下沉市场,性价比超越友商?新一代双芯旗舰来袭!vivoX80系列持续散发魅力原来有刘海的赵丽颖这么嫩,年龄跨度大效果没差,这张肯定没见过设计鉴赏酒店ampampampGloriette酒店一次穿越39岁的刘翔晒照,他和妻子不要孩子,粉丝认为刘翔这样做太自私化身成金龙长着翅膀,试玩乐高幻影忍者71769寇的神龙战车人类的存在原因被称为Q球的奇怪量子体可以解释老辈最爱的6道下酒菜,如今已经逐渐被遗忘,吃过的至少有50岁干练的极简风搭配帅炸了,低调奢华显高级,飒到没边了埃及之旅(四)宝鸡游66路公交车明天开通微小说老婆一建筑工地上,挖出一具尸骨!竟是苏联神秘失踪的王牌飞行员?跑男C位团宠将易主,宋雨琦疑似取代Angelababy电器火灾的几大急救要点留守儿童容易遭受那些暴力高考材料作文青山一道同风雨送郑翁还广其一产品实践案例:蘑菇街电商内容化尝试鹅掌风偏方董先生献方不吃造句用不吃造句大全浅析如何提高县级供电企业农电安全管理水平悲伤爱情的语录

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利