设为首页收藏本站 今天是: 2023-10-04    "世界动物日"  热爱动物并和动物们建立了“兄弟姐妹”般的关系

复仇者黑客组织

 找回密码
 立即注册

QQ登录

只需一步,快速开始

    查看: 113|回复: 11

    某东和文泉在线阅读epub解密

    [复制链接]

    该用户从未签到

    6

    主题

    19

    帖子

    33

    积分

    新手上路

    Rank: 1

    积分
    33
    发表于 2023-9-18 18:28:57 | 显示全部楼层 |阅读模式
    在线阅读epub解密简单分析

    参考文章:
      JavaScript 教程
      JavaScript AST其实很简单
      反爬虫AST原理与还原混淆实战(微课视频版)
      Epub格式电子书格式解析
      ast自动扣webpack脚本实战
      某网站webpack逆向
      python下载文泉学堂求助
    • jwt
      前言
      1.    测试的网址都比较简单,适合新手练手,我也刚学
      复制代码
      本文仅仅针对标准的epub格式,有兴趣可以去了解下,这里放一张图对比。仅仅涉及解密过程,不涉及下载。
      TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(1)
    ​    温馨提示,本文内容仅做学习交流,禁止用于批量或非法爬取。如有侵犯你的权益请联系我,将于24h内删除。
    某东专业版pc+h5_1

    目标网站:dG9iLW0uamQuY29t,aHR0cHM6Ly9neC5qZC5jb20vZ3gvZ3hfaW5kZXguYWN0aW9u;
    打开网站,随便打开一本书,按下F12,先别刷新,直接点下一章,因为这样方便定位请求的地址
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(2)
    很明显请求的就是这个地址,但k后面的内容以及响应的内容貌似是加密的,先分析请求中的k值,注意前面的关键词read_chapter.action,直接搜索,很容易定位到这里,下个断点,刷新,在控制台执行一下代码
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(3)
    很好就是这个,跟下去,格式化一下,点左下角{}
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(4)
    1. var _0xodF='jsjiami.com.v6',
    2. *********
    3. _0x49ac=_0xodF='jsjiami.com.v6';
    复制代码
    jsjiami.com.v6加密的,有兴趣的看一下上面提到的ast系列文章,尝试还原一下,在附件里面我上传了混淆和还原后的js
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(5)
    因为很短就直接分析了懒得替换,搜索关键词readType,定位到关键代码,下个断点,在控制台中执行关键的代码,很容易发现原始和加密后的数据
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(6)
    然后又是一个混淆了的,和上面一样,不多讲了,很短没必要还原,直接看就行了
    1. var pc1 = new PC1();
    2. function encryption(_0x30c8da) {
    3.     var _0x138c44 = {
    4.         'ovOTw': _0x1ad9('5d', 'ch8w')
    5.     };
    6.     return pc1[_0x1ad9('5e', 'DJHM')](pc1[_0x1ad9('5f', 'N!8d')](pc1['utf16ToBytes'](_0x30c8da), pc1['stringToBytes'](_0x138c44['ovOTw']), ![]));
    7. }
    8. function decryption(_0x547fb5) {
    9.     var _0x156c4 = {
    10.         'EapRO': _0x1ad9('60', 'tlv1')
    11.     };
    12.     return pc1['bytesToUtf16'](pc1[_0x1ad9('61', 'qelS')](pc1['hexToBytes'](_0x547fb5), pc1[_0x1ad9('62', 'n(Db')](_0x156c4['EapRO']), !![]));
    13. }
    复制代码
    很明显了下面是写了一个调用上面的函数,看不懂,没关系,只需要知道,加密是函数 encryption同时传入了参数_0x30c8da(从上面可知是{"encrypt":1,"bookId":"30734545","chapterId":"90594508"}),然后干了啥,不需要知道,直接保存下来,用python调用,因为很短,逻辑很清晰可以这样,执行py,网页返回的信息,完全一样,没有问题。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(7)
    然后就是解密响应内容了,根据上面的分析,很容易发现,在加密的下面,就是解密,同样的调用js,解密内容。
    1. decryption = context.call("decryption", content)
    2. 原始数据 {"encrypt":1,"bookId":"30734545","chapterId":"90594508"}
    3. 加密后的内容 c32bc*******c9493
    4. 返回的数据 3d7bddef9dad847e1bb12aae18 ****省略***456b9af5
    5. 解密后的内容 {"contentList":[{"content":"<?xml version="1.0" encoding="utf-8" standalone="no"?><!DOCTYPE html PUBLIC \****省略***\/html>"}]}
    复制代码
    很明显content里面的内容就是我们所需要的,具体怎么处理转换成epub就不讲了,我也不会,可以自己了解一下epub格式。
    还剩最后一个问题,chapterId,是从哪里来的,直接搜什么内容也没有,那么很明显了就是加密的,直接搜关键词chapterId,发现有很多。
    但我们前面,讲了一个加密解密的方法,那么很明显,按照摸鱼三大法则,大胆猜测肯定也在这里附近,直接在加密和解密这下个断点,刷新,果然发现了和之前的不一样,原始数据没有chapterId,再继续执行,看返回后的数据解密后,果然
    chapterId就在这里面,虽然名字不叫chapterId,但看长度一搜明显就是,到此关键的部分结束了。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(8)
    这里分析的是H5-1,pc网页和这个是完全一样的只是名字稍微改了一下,就不多讲了。
    某东专业版H5-2

    测试网站:aHR0cHM6Ly9tLXRvYi5qZC5jb20vcmVhZGVydG9iL3JlYWRlcj9lYm9va0lkPTMwNjc0MDQ3
    重复上面的第一步,然后定位到关键的位置
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(9)
    是个webpack,有兴趣可以了解一下,同样搜索关键词,定位到关键函数
    1.             enData: function(e) {
    2.                 var t = this.getKey(this.time)
    3.                   , n = this.encrypt(e.split("?")[1], t, this.time);
    4.                 return e = e.split("?")[0] + "?enc=1&app=" + this.app + "&tm=" + this.time + "¶ms=" + encodeURIComponent(n)
    5.             }
    复制代码
    控制台执行,发现多了很多未知的参数
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(10)
    先不管,后面再来解决,继续跟进
    1. return n % 2 == 0 ? this.AESEncrypt(e, t) : this.DESEncrypt(e, t)
    复制代码
    那么很明显了,根据上面n是时间戳,根据时间戳为奇数或者偶数分为了,AES和DES,为了方便我把时间戳写死了,写成偶数,因为不太熟悉DES。
    继续执行,发现就是一个AES/ECB/Pkcs7,然后e为待加密的内容,t取md5值作为key
    1.             AESEncrypt: function(e, t) {
    2.                 var n = U.a.enc.Utf8.parse(e)
    3.                   , o = U.a.MD5(U.a.enc.Utf8.parse(t));#取
    4.                 return U.a.AES.encrypt(n, o, {
    5.                     mode: U.a.mode.ECB,
    6.                     padding: U.a.pad.Pkcs7
    7.                 }).toString()
    8.             }
    复制代码
    防止魔改,用其他软件实现对比一下,没有问题
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(11)
    然后查看返回数据发现依旧是加密的,同样的根据摸鱼三大定律,解密部分就在加密下面,根据时间戳来判断解密方式,e为加密内容,t取md5值作为key
    1.             AESDecrypt: function(e, t) {
    2.                 var n = U.a.MD5(U.a.enc.Utf8.parse(t))
    3.                   , o = U.a.AES.decrypt(e, n, {
    4.                     mode: U.a.mode.ECB,
    5.                     padding: U.a.pad.Pkcs7
    6.                 });
    7.                 return U.a.enc.Utf8.stringify(o).toString()
    8.             }
    复制代码
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(12)
    那么就只剩下上面提到的一些参数了,随便搜一下,team_id是学校的编号固定的,cookie里面有,就不分析了
    1. /jdread/api/download/chapter/30470981?app=tob-web&tm=1651292175581&team_id=*****&uuid=****&client=pc&os=web&sign=*****
    复制代码
    搜索关键词uuid,定位到关键代码,下断点
    1.             getUuid: function(e) {
    2.                 var t = ""
    3.                   , n = Q.a.get("u") || "";
    4.                 return e.uuid ? t = e.uuid : (n ? localStorage.setItem("_u", n) : (n = localStorage.getItem("_u")) || (n = "h5" + this.guid(),
    5.                 localStorage.setItem("_u", n)),
    6.                 t = n),
    7.                 _e.uid || t
    8.             }
    复制代码
    结果发现信息在这之前就有了,无论怎么调试,一直都找不到关键位置
    凭借我初中水平(因为小学没学英语)的英语注意到localStorage(本地**),说明在这之前就存入了
    那么我们先清空,控制台输localStorage.clear(),刷新发现回到了登录界面,很明显了,多半就是登录的时候写入了,搜索关键词,下断点,刷新,进入关键函数
    这里需要自己扣代码,或者一步步调试进入js,详情可以看看上面的webpack,关键就差不多这样,结果意外发现sign也在这里,先记住,在这里明显看出,uuid:h5+guid(),那么进入关键函数
    1. import Cookies from 'js-cookie'
    2. import md5 from 'blueimp-md5'
    3. import { HOST, APP } from './global'
    4. import { getQuery, guid, getOS } from './common'
    5. *******
    6.   if (url.indexOf('uuid=') === -1) {
    7.     if (u) {
    8.       localStorage.setItem('_u', u)
    9.     } else {
    10.       u = localStorage.getItem('_u')
    11.       if (!u) {
    12.         u = 'h5' + guid()##########
    13.         localStorage.setItem('_u', u)
    14.       }
    15. *********
    16. // 加密内容*********
    17.   const salt = md5(app + time + uuid)
    18.   return salt
    19.   *********
    20. // 加密签名
    21. *********
    22.   const sign = md5(salt + URI + queryString)
    23.   *********
    24. // WEBPACK FOOTER //
    25. // ./src/utils/encrypt.js
    复制代码
    发现就是最常用生成的uuid的方法,那就没什么好讲的了,自行百度吧。
    1. import { mediaWidth } from '../config'
    2. **********
    3. // 生成唯一id
    4. const guid = () => {
    5.   function S4 () {
    6.     return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
    7.   }
    8.   return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4())
    9. }
    10. **********
    11. // WEBPACK FOOTER //
    12. // ./src/utils/common.js
    复制代码
    然后只剩下sign了,上面已经提到了sign加密函数,就简单看一下,首先是对取(app + time + uuid)的MD5值得到salt,app对应类型tob-web是固定的,time是时间戳,uuid就是上面提到的,为了方便同样把时间写死,然后再对salt + URI + queryString取MD5值,url和queryString自己看图,和前面的进行对比完全一样,到此所有加密参数都基本搞定了
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(13)
    某学堂

    aHR0cHM6Ly93cWJvb2sud3F4dWV0YW5nLmNvbS9kZWVwL3JlYWQvZXB1Yj9iaWQ9MTAzNzQx
    学堂有两个部分需要解密,第一个就是,请求内容时候的k值,这里面python下载文泉学堂求助说的很清楚了,自己去看看吧。
    然后呢对于pdf来说,返回的就是图片,不用解密,但对于epub来说返回的数据还是加密的,还需要继续解密,直接开搞
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(14)
    快速定位到相关位置,点进去。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(15)
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(16)
    一个ob混淆,而且很大,试了下一键还原的插件不行,那么自己想办法还原,整个五一加一周学了下ast。
    然后准备先还原js,还原之前,先大致了解js内容,看图吧。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(17)
    先分析下第一个整体结构,大致就这样。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(18)
    再分析内部的基本结构与逻辑。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(19)
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(20)
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(21)
    删除第一个,继续分析下一个,就简单分析一下
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(22)
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(23)
    后面没啥好讲的了,基本就是平坦流,花指令啊之类的,基本可以用插件一键还原。
    然后花了,整个五一假期门都没出加一周学ast,还原js,结果
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(24)
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(25)
    没什么好说的了,就是CryptoJS,改了下,重新分析网页
    既然返回的数据是加密的,对于js来说,肯定要解析内容,转化成数组,直接搜Uint8Array,定位到解密后的函数
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(26)
    运气很好,很快注意到,response以及,Uint8Array(t);,这里面创建了很多数组,注意我标注的位置,后面都有用到,唯一有一个,dpbt函数是自己写的,反混淆后长这样。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(27)
    1. dpbt = function(t) {
    2.                 for (var r = new Uint8Array(4), e = r.length - 1, i = t.length - 1; e >= 0; e--,
    3.                 i--)
    4.                     r[e] = i >= 0 ? t[i] : 0;
    5.                 var n = (255 & r[0]) << 24
    6.                   , o = (255 & r[1]) << 16
    7.                   , a = (255 & r[2]) << 8
    8.                   , s = 255 & r[3];
    9.                 return n + o + a + s
    10.             }
    复制代码
    其实,对于解密epub来说,可以看出来,o始终是定值,那么a也始终是定值48,很容易想到16+32,大胆猜测,算了继续看下去吧。
    继续跟进,来到了今天的正题。
    首先传进来了几个值,t就是上面的l,n是上面的f,i是CryptoJS,其余两个没啥用。然后就开始了两次AES/ECB解密,第一次就用到了前面提到的16+32,第二次就用第一次解密后的内容作为key解密epub内容,但要注意解密的并不是全部返回数据,而是去掉了前十位后的数据再解密,至此解密完成了。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(28)
    再用软件还原对比一下,防止魔改。
    TBC茶馆-复仇者黑客组织在线阅读epub解密简朴分析参考文章:JavaScript 教程JavaScript AST实在很简朴反爬虫AST原理与还原混复仇者黑客组织(29)
    很好,没有问题,到此全部结束了,原本还打算继续加一个圣才(很简单)和可知(很麻烦)的,是在没时间了,看后续有时间再继续写。
    大部分内容能给的都上传到附件了,就别问我了,没写下载软件也不会。
    附件




    上一篇:PWN入门-格式化字符串漏洞
    下一篇:fiddler everywhere 3.3.0 去除授权校验

    该用户从未签到

    2

    主题

    1258

    帖子

    381

    积分

    中级会员

    Rank: 3Rank: 3

    积分
    381
    发表于 2023-9-18 18:29:07 | 显示全部楼层
    @无敌小儿
    @poke2008
    (4/6更新) 密码学工具 v1.12.3~~新版本全功能发布,按需配置~~
    https://www.52pojie.cn/thread-1501153-1-1.html
    (出处: 吾爱破解论坛)
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    1158

    帖子

    890

    积分

    高级会员

    Rank: 4

    积分
    890
    发表于 2023-9-18 18:29:36 | 显示全部楼层
    其实如果只是想把资源搞下来的话,某学堂那个还真不需要费劲解密,可以这样
    document.querySelector("#iFrame").contentDocument.documentElement.ownerDocument.querySelector("body")
    然后把每个结果处理下单独保存到html文件中就行了,具体代码如下,这个可比下pdf简单多了
    [JavaScript]  
    1. // ==UserScript==
    2. // @name         文泉epub下载
    3. // @namespace    http://tampermonkey.net/
    4. // @version      0.1
    5. // @description  下载文泉学堂的epub格式图书,将内容保存在一个压缩包中,后续可以用pandoc处理
    6. // @author       kbtx
    7. // @match        https://*.wqxuetang.com/deep/read/epub?bid=*
    8. // @match        http://*.wqxuetang.com/deep/read/epub?bid=*
    9. // @icon         https://www.google.com/s2/favicons?sz=64&domain=wqxuetang.com
    10. // @require https://cdn.bootcdn.net/ajax/libs/jszip/3.7.1/jszip.min.js
    11. // @grant        none
    12. // ==/UserScript==
    13. (function() {
    14.     'use strict';
    15.     // Your code here...
    16.     let button = document.createElement('button');
    17.     button.textContent = '正在初始化...';
    18.     // 设置按钮的样式
    19.     button.style.position = 'fixed';
    20.     button.style.bottom = '150px';
    21.     button.style.right = '50px';
    22.     document.body.appendChild(button);
    23.     // 设置延迟,防止网页未加载导致的问题
    24.     setTimeout( ()=>{
    25.         let btn_prev = document.querySelector("#pagebox > div.read-content-btn-wrapper > a:nth-child(1)")
    26.         let btn_next = document.querySelector("#pagebox > div.read-content-btn-wrapper > a:nth-child(2)")
    27.         let btn_single_layout = document.querySelector("#app > div.page > div.read-header > div > div.read-header-left > div:nth-child(3) > div > div.popup-item.infeed-wrapper > div.popup-content-row > a:nth-child(1)")
    28.         let current_page_count = 0;
    29.         let zip = new JSZip();
    30.         // 打包并下载zip
    31.         function packZip(){
    32.             zip.generateAsync({ type: 'blob' }).then(blob => {
    33.                 const link = document.createElement('a');
    34.                 link.href = URL.createObjectURL(blob);
    35.                 // 将文件命名为 "当前书名.zip"
    36.                 link.download = document.querySelector("#app > div.page > div.read-header > div > div.read-header-title").innerText + ".zip";
    37.                 link.click();
    38.             });
    39.         }
    40.         button.textContent = '立即导出已有内容';
    41.         button.addEventListener('click', packZip);
    42.         let page_switcher = setInterval( ()=>{
    43.             // 如果当前找不到翻页按钮,说明在双栏布局下,此时切换到单栏布局,并重新定位翻页按钮
    44.             if(!btn_next || !btn_next.click){
    45.                 btn_single_layout.click();
    46.                 btn_prev = document.querySelector("#pagebox > div.read-content-btn-wrapper > a:nth-child(1)")
    47.                 btn_next = document.querySelector("#pagebox > div.read-content-btn-wrapper > a:nth-child(2)")
    48.             }
    49.             current_page_count++;
    50.             if(btn_next.classList[0] === 'disabled'){
    51.                 // 已经到达最后一页,清理定时器
    52.                 clearInterval(page_switcher);
    53.                 packZip();
    54.             }else{
    55.                 // 由于可能切换布局导致重新加载,这里要略微延迟一下,等待浏览器重新排版
    56.                 setTimeout( ()=>{
    57.                     // 获取到的页面数据,格式为html
    58.                     let page_data = document.querySelector("#iFrame").contentDocument.documentElement.ownerDocument.querySelector("body").innerHTML;
    59.                     // 将data-src中的图片地址替换掉src的
    60.                     page_data = page_data.replaceAll('data-src', 'data-sss')
    61.                         .replaceAll(/src="([^"]*)"/g, '')
    62.                         .replaceAll('data-sss', 'src');
    63.                     // 将数据存入压缩包中
    64.                     zip.file(current_page_count.toString().padStart(4, '0')+'.html', page_data)
    65.                     // 先获取数据再翻页,可以确保所需数据已经加载
    66.                     btn_next.click();
    67.                 },500);
    68.             }
    69.         }, 5000 )
    70.         }, 5000 )
    71. })();
    复制代码
    回复

    使用道具 举报

    该用户从未签到

    2

    主题

    1218

    帖子

    194

    积分

    注册会员

    Rank: 2

    积分
    194
    发表于 2023-9-18 18:29:57 | 显示全部楼层
    努力学习生争取早日白嫖
    回复

    使用道具 举报

    该用户从未签到

    4

    主题

    1266

    帖子

    1010

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1010
    发表于 2023-9-18 18:30:33 | 显示全部楼层
    谢谢分享,学习一下
    回复

    使用道具 举报

    该用户从未签到

    2

    主题

    1265

    帖子

    1245

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1245
    发表于 2023-9-18 18:31:30 | 显示全部楼层
    谢谢分享
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    1158

    帖子

    890

    积分

    高级会员

    Rank: 4

    积分
    890
    发表于 2023-9-18 18:31:39 | 显示全部楼层
    感谢分享,辛苦了
    回复

    使用道具 举报

    该用户从未签到

    4

    主题

    1266

    帖子

    1010

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1010
    发表于 2023-9-18 18:32:22 | 显示全部楼层
    我是来学习的!谢楼主!
    回复

    使用道具 举报

    该用户从未签到

    3

    主题

    1266

    帖子

    1261

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1261
    发表于 2023-9-18 18:33:02 | 显示全部楼层
    收藏,慢慢看,向大佬学习
    回复

    使用道具 举报

    该用户从未签到

    4

    主题

    1266

    帖子

    1010

    积分

    金牌会员

    Rank: 6Rank: 6

    积分
    1010
    发表于 2023-9-18 18:33:36 | 显示全部楼层
    认真学习
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭Powered by ©科大讯飞语音云
    嗨!您好:
    欢迎来到 复仇者黑客组织。
    我的名字叫小光
    很高兴能够为您服务!
    如果已经注册【立即登录】
    还没有账号请立即注册
    Loading...
    快速回复 返回顶部 返回列表