吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 9899|回复: 165
上一主题 下一主题
收起左侧

[Web逆向] 阿里云Web播放器,m3u8的ts文件解密下载过程实现

    [复制链接]
跳转到指定楼层
楼主
billsmiless 发表于 2021-8-27 17:33 回帖奖励
本帖最后由 billsmiless 于 2021-8-29 06:06 编辑


阿里云Web播放器,m3u8的ts文件解密下载过程实现


        声明:本文为吾爱破解原创首发!以发帖时间为准! 文中所用图片均添加个人水印(Bill原创,首发吾爱破解,截止转载)!

1  前言        现在网页上所播放的视频,都是m3u8的片段式的数据格式,ts本质是mpeg-2编码,优势就是可拆分为多个文件,这有利于网络传输。为防止视频被传播,ts文件会被加密。 一般的加密方式都是基于ts文件整体使用AES加密,这种只要拿到key,都可以解密成功。 阿里云播放器加密有3种,但万变不离其宗,道高一尺魔高一丈。只要认真,没有翻不过的火焰山。  因此,本文将介绍 鄙人过去这几天对阿里云ts文件解密的过程。  本人非js专业,有不专业之处,还望指点,本文着重叙述 实现的过程、思路、以及遇到的问题
2  工具与环境
        Safari浏览器、Sublime文本编辑器
3  分析视频   打开视频地址(这里以51CTO的视频(登录vip才能看)为例,地址就不公布了),打开网页检查器,清空缓存,重新刷新网页,在网页检查器中选择网络 -- XHR ,观察网络请求。
        

        可以发现,有四个主要http请求,ts文件是我们想要的文件,如果直接下载ts,是无法播放的,因为加密了。所以我们的目的就是解密ts。那么既然解密,就要找到解密的代码。

        如何找解密代码?因为数据都是由http请求最终返回,所以我们从http请求入手。一步一步追踪返回的数据,看数据最终如何被处理。

4  分析http请求

        由上步,我们知道主要的4个http请求,其中有一部分是ts文件的,就不必分析了,所以我们就依次分析vod-play-auth、vod.cn-shanghai.aliyuncs.com、m3u8的这3个http请求的数据内容。
     
        
      
        先看m3u8的内容,可以发现其中包含,ts的链接地址(虽然不全),加密类型以及解密的key(显然已加密)。          vod-play-auth返回的数据,主要有 playAuth字段以及数据格式和加密类型,由此猜测此请求应该是用来提供解密的key的。
        vod.cn-shanghai.aliyuncs.com 对于此接口请求,可以发现返回内容中有加密类型以及 m3u8的请求地址。
        
        综上,按如下思路:
  • 找到vod.cn-shanghai.aliyuncs.com 请求代码  
  • 得到m3u8的的请求代码
  • 根据m3u8返回内容,找到ts地址
  • 根据ts内容,找到解密代码



5  查找代码,断点调试

        按上面分析的4个步骤继续,为了查找vod.cn-shanghai.aliyuncs.com请求的代码在哪里,我们直接全局搜索请求的名称。


         


        没有搜索到结果,别灰心。 既然接口名搜索无结果,我们看看这个请求的参数,按参数搜索。
        打开网页检查器 -->  网络  -->  XHR  -->   选中vod.cn-shanghai.aliyuncs.com接口  --> 选择右侧子菜单栏的“标头”


        

        由上图可看到,在请求的URL中,问号后面的字段是AccessKeyId,这就是参数之一。我们接下来,全局搜索该字段。        依旧在右上角的输入框输入,  输入AccessKeyId后回车。
     
         

        依次点击搜索结果,根据经验观察哪些可能是请求的参数,就在哪个文件的AccessKeyId所在的函数处打上断点。
        也可以在AccessKeyId所在的全部函数都打上断点。
        接下来,点击网页检查器上的刷新按钮,左上带小箭头图片的按钮。然后观察程序是否停在了断点处。


        我这里断点在aliplayer.cto.js|v=9196257513 文件中的第23076行,程序停在了这个断点处。
        当程序停在断点处时,注意页面布局,这时是在“来源”菜单下的,左侧有函数调用堆栈,调试按钮,文件名,代码区,右侧就是代码文件的信息。
        函数调用堆栈可以让我们知道调用顺序,此时大家可以自行点击调用堆栈的各个函数观察一下。
     
         

        我们必须靠函数调用堆栈以及调试按钮 才能发现解密代码。
        这里介绍下 调试按钮的各个作用:
  • 第一个:断点开关,作用是:是否开启断点。
  • 第二个:跳过断点,继续运行
  • 第三个:单步执行(一行一行代码的执行,遇到函数调用会跳过,如果想进入函数用第四个按钮)   
  • 第四个:进入函数
  • 第五个:跳出函数


        OK,接下来我们分析,当前停止在断点处的函数。看函数的内容,我们发现,在23096行处的代码和我们的要找的接口名字有点像,那么我们就验证下。        点击单步执行按钮,一行一行的执行到23097行,停在这里,把鼠标放到23096行处的 i 变量上,就会弹出该变量的值。

        

        看i的值,和我们查找的接口请求很像,但是i值没有展示全,此时可以调试窗口中 使用 console.log(i) 来打印i的值。
        经过对比,确认这就是我们要找的vod.cn-shanghai.aliyuncs.com接口请求代码所在处,在 js文件 aliplayer.cto.js|v=9196257513 中的第23097行。

        接下来,我们继续分析,把鼠标放在23097行处的get的后面,查看get函数的内容。(或者使用“进入函数”的按钮直接跳入该函数,但一般都是先看看函数内容)
     
        

        由上图,根据get内容中调用的函数名猜测,get函数就是一个一个ajax请求的封装。因此猜测get函数的第3个参数(参数类型为函数),应该就是请求的返回数据处了。        因此,我们在23098行,打下断点,按下调试按钮的第二个,就是跳过断点的按钮。 程序会停留在23098行,若没有停留,则可能是超时,则重新刷新网页。查看变量e的值。
   
         

        由此可以看到,变量e的值就是我们vod.cn-shanghai.aliyuncs.com 请求返回的数据内容。也可以打印e的值,这样看的更全。此时e的数据是还未解析的json字符串,下一行的代码就是json解析。
        接下来就顺着这个数据,继续往下走。
   
        接着,一行一行的单步执行,遇到函数,可以查看下函数的内容,这里就不过多查看,直接到我已分析过的函数中。
        单步执行到23108行,查看 l 的值,以及函数h的值。


        
        这里图上,没有放 l 的值,l的值是m3u8的地址。h函数的参数中有 l,可以确定,数据会在h函数中处理,那么我们查看h函数的值,        在h的函数的右上角,会显示函数所在文件以及所在行,点击即进入该函数,并在该函数内的第一行也就是22830行处设置断点,使用跳过断点按钮,程序会进入h函数,停留在22830行。
         

        查看传过来的参数e的值,确认m3u8的地址传递过来了。
        接下来,单步执行,一行一行的分析(限于篇幅,这里就不分析了),这里我直接跳到我们需要的函数了。 单步执行到22875行,查看22973行的变量t、h、rand、plaintext以及函数   
         _sce_dlgtqred的值。通过各个参数的值,特别是变量t是个16位的整型数组,以及函数内容,以及函数名等,大概猜测变量t的值是 解密的秘钥。  因此我们暂时记住变量t的值。
     
         

        继续单步执行至22878行,我们查看d.initPlay函数,点右上角的函数行号,进入函数initPlay内部。然后在initPlay函数内部第一行设置断点,然后使用“跳过断点”按钮,
        继续执行,程序会停留在initPlay函数内的断点上。如下图:

        

        单步执行到22342行,到这里我们发现,这一行是initPlay函数的最后一行了,如果继续使用单步执行,就会执行到函数末尾了,接下来就只能跳出函数。
        仔细观察这一行的代码,有1个参数是个函数,其实这个函数的作用是加载hls的js, 这一步很关键,当然这也是我后来发现的,一开始也不知道是干啥的,因为反复调试,代码看的多了,就发现了猫腻。
        因此,这里我们直接在22348行(也就是loadJS函数内部)设置断点,然后使用“跳过断点,继续执行”按钮,你会发现,程序会停留在loadJS内部的断点上。

         

        接下来,使用进入函数按钮进入22351行,然后继续使用进入函数,跳转到r函数内部,即22299行,单步执行到22309行,然后反复使用进入和跳出函数,
        直到停留在s._hls.attachMedia(s.tag) 函数上。如下图

        

        进入attachMedia函数内部,继续进入attachMedia函数内部的 trigger函数(8802行),使用进入函数按钮,直到停留在8819行,在8821行设置断点,并执行到此处

        
        继续使用“进入函数”按钮,跳转进emit函数内,然后使用单步调试,跳转到3153行,然后继续使用“进入函数”按钮,进入2646行,继续使用“进入函数”,        进入到onEventGenericha函数,并查看参数 t 的值。
               

        观察参数t的值,是不是有点熟悉,还记得我们是从哪个函数进来的吗? 没错,前面调用了attachMedia函数。        分析到这里,似乎发现了点什么,是的,现在正在执行的代码是 aliplayer-hls-min.js 中的代码。
        但是 现在这个onEventGeneric函数还是让我疑惑,为什么会调用到这里。 因此,就打断点吧,多跑几次看看,最后发现,断点经常停留在这个函数。
        而且参数 t 的值,似乎有规律。因此,决定搜索其值,按Command+F文件内搜索,最后发现,有很多类似的值。

        

        因此,我们猜测大部分函数的执行都会经过这里,那么我们通过打印日志来验证下。        在网页检查器上,选择 网络 --> js  --> aliplayer-hls-min.js ,右键 点击创建本地覆盖。有了覆盖文件,我们就可以编辑js文件了,相当于可以直接写代码了。

        

        回到“来源”菜单下,在左侧的“本地覆盖”栏目下,找到我们创建的aliplayer-hls-min.js覆盖文件,找到onEventGeneric函数,在内部输入console.log("bill_"+t)打印参数t的值。        然后再safari菜单中, 选择清空缓存,然后重加载页面,在网页检查器中,把断点全部停用。在控制台页面,观察我们的日志打印。我们发现,打了很多值, 确认了我们的猜测。

        
        

        最后,我们发现,几乎所有的事件处理,都会调用本方法,包括ts文件的加载以及数据处理。  
        其中,hlsFragLoading 加载的是ts的数据。由此,我们可以根据 断点--函数调用栈--找到ts的http请求在哪里(限于篇幅,此处不再分析)。
         
        我们直接开始分析 数据处理的部分,hlsFragLoaded 代表ts文件数据加载完成,接下来就是开始处理数据(解密-->保存-->添加至播放器)。

        因此我们在onEventGeneric函数中设置断点,观察参数 t 的值,如果不是hlsFragLoaded则使用跳过按钮,继续执行,直到参数t的值为 hlsFragLoaded时,准备好单步调试。


        

        单步执行到 2659行,使用进入函数按钮,会跳到2653行的函数内部,继续单步执行到2656行,然后使用进入函数按钮,会重新跳到2659行,此时继续使用进入函数按钮,        则进入 e.prototype.onFragLoaded = function(t) { }  函数。

        

        注意!!!
        因为onFragLoaded函数有很多个,有可能进入的不是我们进行数据处理。因为数据加载后,需要做其他工作,所以未必一开始就开始处理数据。那么此时我们跳过断点继续执行,
        会发现程序又停在onEventGenegic函数的断点上,而且参数t的值依然是hlsFragLoaded.   然后依次重复上面的 操作步骤,直到我们进入到下图的onFragLoaded的函数,
        并单步执行到17817行,即d.push... 函数行。 (若单步执行,没有到达这一行,则跳过断点继续执行,按以上步骤再来一次)

        

6  去除worker动态调试的限制           

        分析到此处,如果继续按之前的方法继续,那么我们会发现,部分函数的断点失效了,日志会打印,但是断点却不走。这是因为为了防止大家反调试,因此他们使用woker创建了混淆代码,
        每次运行都会新建一个原来js的副本文件,因为每次都会新建副本,所以我们设置的断点就会失效,这个副本是在woker内用js代码自动生成的。关于worker大家自行百度之。   
        解决方案: 关闭worker。不同的代码可能实现方式不同,这里是有一个worker开关,猜测是为了兼容老版本。

        具体步骤:
        1. 在aliplayer-hls-min.js 中搜索  ”enableWorker “  ,可以看到分号后面的值是  !0  , 我们知道0代表否,!代表取反,所以!0代表true,  因此我们把 ! 去掉,则关闭了woker.
        2. 新建 aliplayer.cto.js 本地覆盖文件,然后操作步骤同1   , 这两个文件的woker都需要关闭。

        


        接下来,就愉快的打断点吧  


7 开始数据解密            

        继续接上面的步骤,一步一步的分析,直到我们找到数据解密函数。  这里就不过多分析了。我们直接跳到数据解析函数在18481行, t.prototype.append = function(e, r, i, n) {} ,并设置断点。
        这里我们简单介绍下ts的文件结构: ts文件由多个 ts包组成,每个ts包188字节,ts包内含有pes包,一个pes包可存在于多个ts中。
        
        分析   t.prototype.append = function(e, r, i, n) {}  函数,我们发现:此函数就是在解析ts文件内容,找到每个ts包的数据,同时会解析出pes包,然后对pes包进行解密。 解密函数是 D,
        到这里,我们进入解密函数D,最后发现D函数返回的数据就是解密后的pes包数据。


        

        我们进入解密函数D,分析下其内容。我们直接跳到D函数,断点。        分析后,我们发现,此函数就是parsePES,  即通过ts包的数据,解析出pes数据,同时对pes数据进行aes解密。看下图:

        

        我们分析下 o = l(o, p) 代码中的 l 函数,进入 I 函数,  查看参数t  和 e的值,我们发现 t 为刚刚解析的pes的数据, e 为我们之前猜测的解密key。如下图:

        

        至此,我们就明白了,ts数据是如何解密的,一般的ts片段都是整个文件直接aes加密,而阿里云的是在pes数据上加密,因此解密起来就要了解ts文件结构,还有的就是调试起来比较困难。

8 下载解密后的ts文件            

        我们已经知道如何解密的了,接下来就是保存解密后的文件。  那么如何保存呢?  

        思路如下,既然ts中的pes是加密的,那么我们把解密后的pes数据,替换掉原有的pes数据,然后重新保存ts文件,就可以了。
      
        接下来开始分析具体操作:
        因为解密的时候,是解密一个完整的pes包,而一个pes包,有可能存在于多个ts包中,且pes包长度不定,每个ts包中都有ts包头,
        也就是说pes包可能分散于多个ts包中,且pes包的数据并不在 ts中连续,举个例子  如果某个pes包存在于3个ts包中,也就是说pes包存在 3个188字节中,这3个188字节中,会有3个ts包头,
        以及一个pes包包头,pes包也有包头,pes包头不会别加密,所以替换的时候,还需要考虑pes包头数据。

        鉴于以上分析,我们替换的时候,必须知道pes包中的数据,分别存在于那些ts包中,以及存在于该ts包的中起始位置索引。
        因此,我们在开始解析pes数据的时候,记录下每个ts包中的pes数据的起始索引以及该ts包中的pes长度。在pes包解密后,再把pes数据重新分割都ts中。
        这样,我们就可以将ts包中pes片段数据,插入到ts文件数据中了。


        下面开始代码实现:
        首先在parsePES中,将解密后的pes数据,分割到对应的ts文件中
        带有bill注释的代码,都是我们添加的代码

        

        接下来,我们在数据解析的函数中接收,我们带有正确pes数据的ts包数据。以及替换ts包中的数据,当数据解析完毕后,我们保存解密后的ts文件。请看下图:

        

        至此,就完成了  阿里云ts文件解密下载的过程。  看下结果:

        

9  后记
       本篇文章,写了2天,中间不小心页面关了,再次打开就乱了布局,图片没了,且也传不上去新图了,503错误,最后不得不上传网盘。

        

        像web页面的反分析,最大的难处就是核心代码的寻找,只要耐心,剩下的就是时间问题。结合解密过程,本人也写了一个mac版本的小工具。
        写总结文章,也会收获很多,让逻辑更清晰,当然真实的分析过程,肯定比文章中的要困难一些,有时候一个思路很久都想不到。

        坚持就会胜利!!!


v11.jpg (474.68 KB, 下载次数: 18)

v11查看秘钥t值

v11查看秘钥t值

免费评分

参与人数 108吾爱币 +109 热心值 +98 收起 理由
努力加载中 + 1 + 1 热心回复!
zcy2nn + 1 + 1 用心讨论,共获提升!
zhangpan0912 + 1 + 1 谢谢@Thanks!
weiyongsheng + 1 + 1 谢谢@Thanks!
lclp1314 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
bpzm1987 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
asiaboy1984 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wtlone001 + 1 + 1 用心讨论,共获提升!
TeMoon + 1 + 1 你真的有闲心
suojinghuan + 1 + 1 我很赞同!
gba626 + 1 我很赞同!
Laojiuguan + 1 + 1 很赞
kwnthink + 1 + 1 用心讨论,共获提升!
anwen + 1 好东西
eoo + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
又是馒头 + 1 + 1 用心讨论,共获提升!
qlu50of5 + 1 + 1 热心回复!
nobiyou + 1 + 1 用心讨论,共获提升!
JssDream + 1 + 1 鼓励转贴优秀软件安全工具和文档!
gagmeng + 1 + 1 谢谢@Thanks!
jackej + 1 + 1 谢谢@Thanks!
JinxBoy + 1 谢谢@Thanks!
duanduan520 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Hao6 + 1 + 1 用心讨论,共获提升!
pdcba + 1 + 1 谢谢@Thanks!
zhhmok + 1 我很赞同!
kindbigbear0 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
cyw + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
411183343 + 1 谢谢@Thanks!
大白小子 + 1 用心讨论,共获提升!
bugof52pj + 1 + 1 谢谢@Thanks!
olvc + 1 + 1 我很赞同!
DancingLight + 1 + 1 用心讨论,共获提升!
zhangyimeng + 1 + 1 我很赞同!
blywq + 1 + 1 谢谢@Thanks!
Duck547 + 1 + 1 热心回复!
georgez1379 + 1 + 1 用心讨论,共获提升!
schedule + 1 谢谢@Thanks!
cgj08 + 1 + 1 热心回复!
春落秋开 + 1 + 1 热心回复!
Arsenal + 1 + 1 我很赞同!
wan456 + 1 热心回复!
Lopht + 2 + 1 难得的好文。
bjd1111 + 1 + 1 我很赞同!
gubs + 1 用心讨论,共获提升!
404undefined + 1 + 1 我很赞同!
zhengjim + 1 + 1 用心讨论,共获提升!
ZainFelice + 1 我很赞同!
hj170520 + 2 + 1 我很赞同!
ZHHua + 1 + 1 谢谢@Thanks!
pelephone + 1 + 1 我很赞同!
j171801 + 1 + 1 用心讨论,共获提升!
cooleephone + 1 + 1 用心讨论,共获提升!
Nicklolo + 1 + 1 谢谢@Thanks!
aide315 + 1 + 1 谢谢@Thanks!
xbxbxbxb + 1 + 1 谢谢@Thanks!
wohnfgh + 1 鼓励转贴优秀软件安全工具和文档!
小粑666 + 1 + 1 谢谢@Thanks!
zuxin521 + 1 + 1 谢谢@Thanks!
dingyx99 + 1 + 1 用心讨论,共获提升!
chenjingyes + 1 + 1 我就喜欢看ts解密的技术文章
常胜将军 + 1 + 1 热心回复!
penz + 1 我很赞同!
挑战走狗 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
kingarrow + 1 我很赞同!
jiangpengbh + 1 + 1 用心讨论,共获提升!
Li7 + 1 谢谢@Thanks!
52weiv + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
抱歉、 + 1 用心讨论,共获提升!
-yuy- + 1 + 1 用心讨论,共获提升!
baojingchuan + 1 热心回复!
Plus32 + 1 + 1 用心讨论,共获提升!
yzyuan007 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
某些人 + 1 + 1 谢谢@Thanks!
zybing + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
nimeilai + 1 谢谢@Thanks!
xmmyzht + 1 + 1 谢谢@Thanks!
漁滒 + 3 + 1 我很赞同!
tonyiyong + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
你应该是一缕风 + 1 + 1 热心回复!
miniliang + 1 谢谢@Thanks!
独行风云 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ufldh + 1 + 1 热心回复!
五花小鱼 + 1 + 1 出个win+chrom的吧
jimmyzang + 3 + 1 我很赞同!
菜鸟小兵 + 1 + 1 谢谢@Thanks!
yippee + 1 + 1 我很赞同!
gaosld + 1 + 1 谢谢@Thanks!
Kai1222 + 1 用心讨论,共获提升!
A913830 + 1 + 1 谢谢@Thanks!
yiyiwangru + 1 + 1 我很赞同!
爱你小吉君 + 1 我很赞同!
purefeeling + 1 + 1 我很赞同!
victos + 1 + 1 谢谢@Thanks!
shuaibaby + 1 + 1 用心讨论,共获提升!
fengbolee + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
mantuner + 1 + 1 谢谢@Thanks!
chermy + 2 + 1 热心回复!
夜泉 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
RainH + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
ATTYCHEN 发表于 2021-9-8 00:38
vtor 发表于 2021-8-30 09:10
我只记得以前使用qq浏览器查看视频,然后可以在qq浏览器文件夹目录下面找到它的缓冲文件
缓冲文件就是m3u8 ...

用它 ffmpeg
推荐
vtor 发表于 2021-8-30 09:10
我只记得以前使用qq浏览器查看视频,然后可以在qq浏览器文件夹目录下面找到它的缓冲文件
缓冲文件就是m3u8为后缀,还有一个相同文件名的文件夹,里面有1.ts,2.ts,3.ts之类的文件
这里的ts文件没有加密,可以直接打开
当时我还想过使用bat脚本将这些文件整合到一块,但是实在没有太菜了,所以最终不了了之了,不过也没关系,都是些不重要的视频
4#
ynboyinkm 发表于 2021-8-28 16:59
5#
89684828 发表于 2021-8-28 17:11
标记一下,谢谢楼主!
6#
renpeng009 发表于 2021-8-28 18:29
一时半会儿消化不了,标记再看
7#
ysjd22 发表于 2021-8-28 18:32
我嫩是没有看完。不过支持楼主
8#
逍遥一仙 发表于 2021-8-28 19:36
key已经拿到了的话,win下有现成工具解ts
9#
孙忠山 发表于 2021-8-28 20:07
逍遥一仙 发表于 2021-8-28 19:36
key已经拿到了的话,win下有现成工具解ts

大仙,请问保利的KEY如何获取
10#
无言Y 发表于 2021-8-28 20:40
感谢分享
11#
zhpsxq 发表于 2021-8-28 21:27
今天终于注册了阿里云盘,希望越用越好1
12#
xiaoshanyu 发表于 2021-8-28 23:02
孙忠山 发表于 2021-8-28 20:07
大仙,请问保利的KEY如何获取

同问大仙
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2021-9-18 05:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表