chuj Vidar-Team | PWN | A student | try to learn

github
    chuj October 25th, 2021 at 07:14 pm

    今天看到了 C++ 中兼顾多态和性能的设计模式,即奇异递归模板模式,通过把派生类作为基类模板的类型参数在编译器实现运行期多态,避免了通过虚表进行函数调用。

    这篇文章讲的很友好 https://liam.page/2016/11/26/Introduction-to-CRTP-in-Cpp/

    我根据这种思想也写了个 demo,很有趣。

    // my test of curiously recurring template pattern
    // this is a really curious pattern
    
    #include <iostream>
    
    class Animal
    {
    public:
        virtual void sayName() = 0;
    };
    template <typename SubClass>
    class Animal_CRTP :
        public Animal
    {
    public:
        void sayName()
        {
            this->sayName_impl();
        }
    
        void sayName_impl()
        {
            static_cast<const SubClass*>(this)->sayName_impl();
        }
    };
    
    class Dog : public Animal_CRTP<Dog>
    {
    public:
        void sayName_impl() const
        {
            std::cout << "I'm dog!\n";
        }
    };
    
    class Duck : public Animal_CRTP<Duck>
    {
    public:
        void sayName_impl() const
        {
            std::cout << "I'm duck!\n";
        }
    };
    
    int main()
    {
        Animal* duck = new Animal_CRTP<Dog>();
        Animal* dog = new Animal_CRTP<Duck>();
    
        duck->sayName();
        dog->sayName();
    }
    chuj October 18th, 2021 at 10:06 am

    两天时间打完祥云杯,最后拿了个第六,打了一些奖金,也算是值回票价。

    chuj October 12th, 2021 at 08:52 am

    花了一天时间看完了图解 http,很棒的一本小书。学习计网的开始

    chuj October 5th, 2021 at 10:26 am

    最近在学习 js,真是一门神奇的语言

    chuj August 24th, 2021 at 10:31 pm

    今天开始写 COOL 的语法分析,遗憾的是毫无进展,还没有理解提供的 AST 模块的用法和原理,文档是有的,也不是很长,但是是英文的,说起来也挺好笑的,学了十多年英语看这点东西还是有点吃力,看了一段时间发现有点难以理解就放弃了,明天再弄吧。bison 也还不会用。看看明天能不能尽量实现一下这个。
    虽然说起来语法分析这种更加偏向于数学的东西对我来讲可能不大有用,但是我感觉还挺有意思的,而且对于 jit 语言来说词法、语法分析应该也是很重要的(毕竟是运行时),所以并不愿放过,之后也准备整理一下学到的相关的知识点。

    chuj August 23rd, 2021 at 05:40 pm

    今天终于弄完了服务器的迁移。由于阿里云学生机取消,原来买的 ecs 就不能原价续费了,所以用老云翼买了一个轻量应用服务器。刚开始嫌麻烦就用了宝塔的一键迁移,结果 502 了,最后还是老老实实地重装了一遍,很奇怪的是在发表文章的时候会有 api 未配置错误,不过反正文章还是能发布,就不多管了。

    chuj August 20th, 2021 at 11:25 am

    有前辈翻译了 flex 的部分文档 https://eternalsakura13.com/2020/05/27/flex/,我看了之后才知道有 input/yyinput 这个方法(前者用于 C,后者用于 C++)让我们可以在 pattern 的 action 中读取输入,由此对注释和字符串的处理就变得简单了。昨天一直在尝试用正则直接把注释匹配出来,由于 COOL 的块注释是可以嵌套的,所以一直弄不好,可以用 input 自己处理就简单许多了。

    说到用正则匹配注释,在嵌套的时候需要用正则处理字符串中间不含字串 STR 且以 STR 结尾这样的问题,据说正则其实不适合做这样的事情,不过我也有看到解决方法,也就是先写出,NFA 然后从 NFA 转回到正则 https://www.seas.upenn.edu/~cit596/notes/dave/regexp-nfa4.html
    不过这里给出了表达式https://www.it-swarm.cn/zh/regex/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%EF%BC%8C%E4%B8%8D%E5%8C%85%E5%90%AB%E6%9F%90%E4%BA%9B%E5%AD%97%E7%AC%A6%E4%B8%B2/957945248/

    chuj August 19th, 2021 at 08:58 pm

    花了一些时间写 COOL 的词法分析,进展不甚顺利。flex 的写法还是不太懂

    chuj August 18th, 2021 at 11:18 pm

    编译原理学习小记:
    关于词法分析的设计过程。感觉这确实是很简单的一个操作。首先写出根据词法规则写出正则表达式(上一篇时光机中提到了),然后根据正则表达式写出 NFA,然后根据 NFA 写出 DFA,最后实现 DFA。当然根据需求不同也可以直接实现 NFA。

    之前浅浅地看过自动机的慕课(应该是哈工大的),正好也是看到 NFA 为止。哈工大的慕课中说到 NFA 是对同一个输入,一个状态可以有转移到多个状态,而编译原理的慕课中,把一个状态转移到多个状态拆分为了空跳(即不需要消耗数据就可转移,也就是输入为 epsilon)加一个状态转移到一个状态。这样就把 NFA 和 DFA 的区别变为了 NFA 允许有空跳(且一个状态可以拥有多个空跳),DFA 不允许。
    看似两种定义没有特别大的区别,但是在 NFA 和 DFA 的转换上变得简单明了了许多。首先引入 epsilon-closure 的概念,也就是一个状态经过 0、1 或多个空跳可以转移到的所有状态集合,那么把 NFA 转移到 DFA 时,DFA 的初始状态就是 NFA 的初始状态的 epsilon-closure(注意 DFA 的状态变为了 NFA 的状态集合)。然后每个 DFA 的每个转移就是状态集中每个状态对应得转移状态和 epsilon-closure 的并集,此并集就是目标状态了。最后 NAF 终止状态处于的集合都是 DFA 的终止状态。这样转换之后首先状态可能会爆炸,因为有 2^N -1 中可能状态,另外每个状态都可能很复杂。对于状态爆炸使用行重用可以缓解。比较有趣的是每个状态很复杂这个问题,实际上这根本不是问题,因为在我们确定了所有的状态和终止状态后就不需要知道每个集合的确切结构了。
    DFA 的优势在于匹配快速,NFA 则更省空间。

    明天争取实现 COOL 的词法分析。

    chuj August 18th, 2021 at 07:24 pm

    编译原理学习小记:
    编译的过程可以分为五步:词法分析(lexical analysis),语法分析(parsing),语义分析(Semantic Analysis),优化(optimization)和代码生成(code generation)。

    今天花了点时间看了一下慕课,了解了词法分析的原理。即使用正则语言识别代码,从而生成 token(词法单元),即 <类别, 词素>这样一个二元组。我们通过正则表达式表达出所有的词素,然后对代码进行匹配即可将代码转换为 tokens。
    这里表达出所有的词素的正则表达式实际上是多个正则表达式的和,举例来说也就是 R = R_Identifier + R_Variable + ...

    一些细节问题挺有意思的
    首先是匹配歧义的问题,以英语举例,对 input 这个字符串从左往右扫描,扫到 "n" 的时候其实已经可以匹配了,因为 "in" 就是一个合法的词素,但是正常人都会看到 "t" 为止,把这个字符串理解为 "input",这就是最长匹配原则,当对代码进行匹配时,如果碰到 "==",虽然 "=" 也显然满足正则表达式,但是我们仍然应该匹配到最长,也就是匹配失败的上一个接受状态。
    然后是匹配优先级的问题,对于 else 这个标识符来说,它是一个关键字,那么它可以被 R_Keyword 匹配。但是光看变量的定义(即字母开头,由字母数字下划线组成的字符串)时,我们会发现 else 也会被 R_Variable 匹配。当然大多数(PL1 不是这样的)的语言都不允许变量是关键字,那么我们如何改写正则表达式呢?比较难。所以一个更好的方法是在匹配 R 的时候优先匹配 R_Keyword 这个表达式,这样 else 就不会被识别为变量了。
    最后是词法错误的情况,如果代码中出现了词法错误,让匹配直接出错崩溃看似不是很好,所以可以加一个 R_Fault,这个正则表达式包含了所有的错误情况。有了匹配优先级的思想,我们可以比较简单地写出这个表达式,然后放到 R 的最后。那么匹配不了的都会被这个正则表达式识别,然后对词法错误进行异常处理即可。

    chuj August 17th, 2021 at 10:07 am

    关于 InCTF Kqueue 一题:当时找到了堆溢出后不知道怎么 leak 就放弃了。赛后看了一下公开的 exp 后才发现原来是没有开启 smep(Supervisor Mode Execution Protection,不同态间不可执行)和 smap(Supervisor Mode Access Protection,不同态间不可访问),可以直接 ret2usr。那么劫持 tty 虚表为用户函数,执行 mov rax, [rbp + 8] ret 回来返回值就是内核地址了,完成 leak。之后继续 ret2usr 提权就很容易了。

    这样看来题目其实很简单,没有仔细看 qemu 启动参数真的是非常大的失误。

    chuj August 15th, 2021 at 09:37 pm

    InCTF 结束了,做出了两道 pwn。如果中间没有一些摸鱼的时间可能可以多出一道 kernel pwn 的题,不过那道题虽然找到了洞,但是不知道怎么 leak,所以有更多的时间可能也是做不出来。两天 6 道题目是有点多,甚至没来的及看过每道题。

    明天要考科一了,所以 WP 明天再来补。

    还是需要提高自己的知识水平。

    chuj August 11th, 2021 at 12:00 pm

    关于模板方法模式和钩子:
    对于多个有相似算法的类,可以应用模板方法模式,将算法骨架抽离,定义为一个超类。对于算法中不同的地方,把它变成一个虚函数,有子类实现自己需要的逻辑。超类也可以实现这个虚函数提供默认操作。
    有时子类可能需要自己拓展算法的功能,这个时候可以添加钩子函数。所谓钩子函数,其实就是一个函数指针(当然根据钩子的实现者不同也可以定义为虚函数),子类只要实现钩子函数就可以添加新的功能,如果不需要扩展那就提供一个空的函数即可。
    C++ stl 中的 std::sort 就是一个应用模板方法的例子,我们在 sort 时,可以提供自己的比较函数来定义被排序对象的大小关系,这里提供的就是钩子函数了。
    应用模板方法模式可以减少重复代码,并且提取了公共代码,便于系统的维护。通过钩子和抽象函数也提高了系统的弹性。
    这里也体现了 OO 中所谓的“好莱坞原则”:高层调用低层方法,低层方法不调用高层。这样便于他人理解系统,避免了“依赖腐败”。

    chuj August 10th, 2021 at 11:07 pm

    睡前记录一下今天学习到的知识:
    今天在重构代码的时候碰到了工厂模式的环形依赖问题,也就是工厂里有产品的头文件,产品里有工厂的头文件,导致 VS 报了近百个错误。

    一度毫无头绪,后来网上冲浪了一下得知,在 A has-a B 这种组合关系时,编译时编译器并不需要知道 A 的具体属性,只要提供一个指针即可,所以在 B 类定义前声明 A 类即可,不需要包含头文件。

    头文件包含应当尽量少,以加快编译速度。尽量使用 #ifdef 或 #pragam once 来避免重复包含。

    谢谢这篇文章的作者,帮我解决了头疼的问题 https://blog.51cto.com/5885774088/242124

    chuj August 9th, 2021 at 11:27 pm

    这三天打了一场英国排名第二的战队的比赛 RaRCTF,本以为是高质量国际赛,做了才发现题目的难度非常温暖人心。花了两天做完了所有的 pwn,现在着实有点憔悴。

    chuj August 7th, 2021 at 06:58 pm

    今天学习了单件模式,适配器模式,外观模式,命令模式。

    单件模式很好理解,通过这种设计方式可以保证一个类最多被实例化一次,具体的方式就是将构造函数定义为私有,然后提供一个静态的 getInstance 方法根据类是否被实例化过选择调用构造函数。这个方法需要考虑条件竞争的问题,一种解决的方法是加锁,但是加锁会造成性能的损失,于是我学习到了一种 fancy 的加锁方式

    if (instance == NULL)
    {
        pthread_mutex_lock(&mutex);
        if (instance == NULL)
        {
            instance = new ...;
        }
        pthread_mutex_unlock(&mutex);
    }
    return instance;
    

    这种加锁方式感觉挺有意思的,算是一个小 trick 了吧。

    然后是适配器模式,做的是接口的转换,也很好理解。一个简单的 java iterator 适配器可以这样写

    package priv.chuj.adapter;
    
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.Iterator;
    
    public class IterAdapter implements Enumeration {
    
        Iterator iterator;
    
        public IterAdapter(Iterator iterator) {
            this.iterator = iterator;
        }
    
        @Override
        public boolean hasMoreElements() {
            return iterator.hasNext();
        }
    
        @Override
        public Object nextElement() {
            return iterator.next();
        }
    }
    

    这样就可以用 enumeration 的方法来访问 iterator 了。
    当客户使用的类在更新时发生了 api 更改时可以把原类用一个适配器适配出来,就可以避免对原来的代码进行大面积的修改
    适配器模式分为类适配器和对象适配器,前者使用继承,后者使用组合。

    外观模式也比较容易理解,使用一个类对大量组件类的方法的进行了包装,使客户可以更容易地调用组件群。

    命令模式感觉还没有理解清楚。

    chuj August 6th, 2021 at 08:47 pm

    《HEAD FIRST 设计模式》告诉我“依赖倒置原则”这个专有名词可以让我加薪。很棒,记录一下。

    也就是说,OO 设计时,应当依赖抽象,而非依赖具体类。

    倒置就体现在对于满足“依赖倒置”的 OO 设计,低层和高层类都会依赖于较高层的抽象类。

    为了实现“依赖倒置”,书中提供了三点建议:

    1、变量不可以持有具体类的引用 也就是说避免使用 new,可以使用工厂模式来替代。

    2、不要让类派生自具体类 派生自具体类就是依赖了具体类,尽量派生自抽象类

    3、不要重写基类已实现的虚函数 如果需要重写基类虚函数,就说明基类不适合被继承。基类中已实现的方法应当共享给所有的子类

    当然,在实际开发时,不可能完全按照该原则进行,只应当尽量。再引用书中的话就是“如果你在 Hello World 的时候都考虑用什么设计模式的话,那可能已经病了”

    chuj August 3rd, 2021 at 09:33 am

    之前碰到了一个 read 时 nbytes 过大会无法读取的问题,今天调试了一下发现原因是在 fs/read_write.c 中的 vfs_read 函数中的 if (unlikely(!access_ok(buf, count))) 这个检查无法通过

    chuj July 16th, 2021 at 12:28 pm

    今天终于把强网杯的 notebook 复现了,挺简单的 kernel pwn 复现了两天多,不过还是学到了新知识,挺棒的。之后准备研究一下给 http 服务器的那种 pwn 题,每次碰到这种题都不知道该怎么下手,有必要学习一下

    chuj July 13th, 2021 at 02:05 pm

    kernel pwn 好难啊

    chuj July 8th, 2021 at 07:02 pm

    受不了 typecho 这个在线编辑器了,已经第二次在我写完文章后卡死导致数据完全丢失了

    chuj June 27th, 2021 at 09:12 pm

    今年的夏促感觉没有游戏可买,感觉已经失去了对游戏的热情了,这真的很奇怪

    chuj June 22nd, 2021 at 10:51 pm

    最近这段时间考试周开始了,复习倒也没复习,但是就是没有学习的动力,的确有些许颓废。今天还忘了大物的小测,非常的烦。大一一年下来学到的东西全是自学的,平时上课反而是影响了我的学习,想想就觉得很不舒服

    chuj June 18th, 2021 at 05:46 pm

    今天突然发现了 apple music 的空间音频这个新功能(6 月 8 号实装的,我火星了),感受了一下,实在是牛。
    由于是新技术,只有一部分歌曲能够以该模式播放,其中我比较喜欢的歌有 Sweet Child O' Mine, Don't Know What You Got, I Want You Back 和 Here Comes The Sun 这四首,推荐听一下,真的是全新的体验。
    所以什么时候可以全面进入空间音频时代呢?比较期待《Have a nice day》和《Use Your Illusion》这两张专辑

    chuj June 3rd, 2021 at 07:15 pm

    用了很长一段时间的 cmder 做终端,vimplus 做编辑器,其实这样操作挺方便的,但是今天突然发现 VScode 可以 ssh 到 wsl 和远程服务器,而且做到非常的好。所以决定了,cmder 拜拜。

    chuj June 2nd, 2021 at 07:40 pm

    本来想复现一下 XCTF-FINAL 的 hellostack 这道题,比赛的时候学长很快做出来了,就看都没有看。现在看了一下想想还是算了,没什么意思,这道题就是自己实现了一套类似影子堆栈的系统,对每个函数的返回地址都做了检查,但是存在很裸的 UAF 和 double free,可以直接攻击其备份返回地址的结构。别的地方都难以控制,只有 main 的返回地址可以随便控制。同时,有一个后门提供了无限溢出,所以可以直接溢出掉整个栈,在 main 退出时进行 rop。
    以上为预期解,实际上 2.27 下有 double free 和 UAF,堆的攻击是非常简单的,出题者为了避免直接这样攻击便未提供输出,无法直接 leak,但是攻击 IO_2_1_stdout 结构体仍然可以 leak。所以还是可以 leak 之后直接打 __free_hook。一般来说这种方法需要进行一个 1/16 的爆破,不过本题的输入方式导致需要爆破 12 位,每一次启动 sleep 了 10 秒,所以爆破理论上可行,但是代价应该是不可接受的。
    总体来说这题应该是此次比赛的 PWN 签到。

    chuj May 27th, 2021 at 09:54 am

    更新了博客版本,看看时光机还能不能用

    chuj May 15th, 2021 at 07:28 pm

    发现突然多出很多想学的东西,罗列一下免得忘了
    看 ptmalloc,下一步 sysmalloc
    学 OS,看《操作系统真象还原》
    学习 driller 的使用和原理
    多了解一点符号执行相关的测试技术

    chuj May 14th, 2021 at 03:30 pm

    终于看完 _int_malloc 了,收获还是有的,发现了一些原来不知道的细节,也获得了相对理性的认知,对 4 bin 1 cache 的操作也有了理性的认知。之后准备看一下 sysmalloc。很有成就感!

    chuj April 25th, 2021 at 10:35 pm

    Source Insight 真的很棒!

    chuj April 23rd, 2021 at 10:03 pm

    wiki 通过了我的第二次 PR,现在也可以在首页的 Contributors 里看到我啦!

    chuj April 20th, 2021 at 08:30 pm

    最近很颓废,感觉没有学习的目标了,题目也都不会做,好难受

    chuj April 18th, 2021 at 09:47 pm

    plaidctf pwn 出了一道比较简单的菜单类题,很开心,终于不至于在比赛一直 0 解了

    chuj April 10th, 2021 at 07:11 pm

    本来是准备把 vtable 里面的函数都分析完再一起发出来的,但是实在太多了,第一篇以深度优先的顺序分析完了 _finish。过程中解决了我对之前 _IO_2_1_stdout 攻击中的疑惑,还是有收获的。

    chuj April 8th, 2021 at 09:55 pm

    今日继续推进了对 vtable 的分析,但是进度不甚快,而且也有许多操作系统 I/O 的知识需要补。有段时间没有做题了,有一丝丝的不适,但是我觉得还是有必要先啃啃源码。

    chuj April 7th, 2021 at 10:57 pm

    ctf-wiki merge 了我的 pull request 了!很开心,我也是参与开源项目的人了!

    chuj April 7th, 2021 at 09:24 pm

    今天一天都比较摸,上午满课,下午出去吃了顿饭,马上接着上形策,所以很遗憾没有做题。但是令我满意的是我终于开始有效地阅读起了 _IO_FILE 相关的源码,分析的文章我一定会尽快写完的

    chuj April 6th, 2021 at 10:36 pm

    今日看完 困在时间里的父亲 这部电影。其实看得迷迷糊糊

    chuj April 2nd, 2021 at 09:48 pm

    花了快一个星期,断断续续看完了导演剪辑版的正义联盟,确实比几年前的院线版要优秀不少。

    chuj March 27th, 2021 at 09:51 pm

    今天没有做出题.. 尝试学习一下反弹 shell 然而发现搞不出来,心态有些崩。确实状态不是很好

    chuj March 22nd, 2021 at 10:45 pm

    今天不想做题,写作业写的非常生气,真的是服了英语精读这垃圾课了,学分这么少作业还这么多。

    chuj March 17th, 2021 at 09:44 pm

    今天有两件事令我开心:
    1.成功进入 Vidar-Team
    2.观看了重映的阿凡达,终于在银幕上观看了这部电影,3D 确实比以前在电脑上看 2D 要震撼

    chuj March 16th, 2021 at 08:51 pm

    今天只做了一道水题,而且自己还没有想出来,明明都是已知的知识但是无法实现融会贯通,实在是遗憾和伤心。不过考虑到中午睡觉起来刷了 2 分钟暗黑2就出了塔拉夏头的份上,心情也不是特别失落。

    chuj March 14th, 2021 at 07:40 pm

    今天颓了一天,这大概是比赛后遗症了吧,的确是无心学习,V&N 的公开赛也没什么心思去打(主要是因为什么的都不会)

    chuj March 10th, 2021 at 10:51 pm

    今天一天比较颓废,因为被 _IO_FILE 卡了。本来是准备看一下源码的,但是发现很难读,就颓了。
    但是这是不行的,这里还是要读的。

    chuj March 9th, 2021 at 09:09 pm

    我终于日穿 House of Orange 啦!

    chuj March 8th, 2021 at 09:34 am

    接下来的安排:可以暂缓题目的进度了,下一步先做个 House of Orange,然后开始研究源码,特别是 IO 相关的,都值得一看。同时还有一个 AFL 要看。

    chuj February 22nd, 2021 at 09:52 am

    可能还是有必要在本地编译一个2.23的ld,题目提供的ld都无法用。每次都在wsl开一个docker,虚拟机套虚拟机是有点呆了

    chuj February 15th, 2021 at 08:46 pm

    我终于明白为什么rop的时候可以随便改rbp了!rsp才决定了栈在哪里,每一次新进一个函数的时候,rbp都会被置为rsp。难以想象我竟然被这个问题困扰了这么久

    chuj February 13th, 2021 at 06:07 pm

    不拼别的方向的题了,不系统地学做了也是白做,为了这点分没啥意义

    chuj February 10th, 2021 at 11:36 am

    做个密码学的题目碰到扩欧,不禁回想起当年打OI的时光,头疼啊

    chuj February 7th, 2021 at 09:15 pm

    对着exp看了一个多小时完全想不通为什么打不通,然后才发现是payload没送出去..

    chuj January 30th, 2021 at 11:03 pm

    hgame真的好难啊..

    chuj January 24th, 2021 at 10:28 pm

    去年hgame的题看起来好难啊,今年这场比赛我可能比较蓝了

    chuj January 22nd, 2021 at 11:11 pm

    堆利用好难学啊

    chuj January 15th, 2021 at 09:45 pm

    看完剪刀手爱德华,我又哭了

    chuj January 13th, 2021 at 03:55 pm

    关于近期可能出现的长时间停更:由于考试周的逼近,本人需要进行小小的突击,否则面临退院的可能,考虑到最近做题也都是做水题,没时间学习新的利用法(特别是堆),干脆就不做了,因此可能会出现大面积的停更。有些遗憾,更多的是无奈

    chuj January 10th, 2021 at 08:18 pm

    关于这几天没做什么有意义的题,今天甚至颓到可能一题都不会做一事:我忏悔

    chuj January 8th, 2021 at 01:00 pm

    现在感觉学的非常累,会做的题目都是简单的毫无意义的题,能学到东西题目是真的做不出来,感觉都和魔法一样。这条路感觉确实比较难走

    chuj January 5th, 2021 at 11:59 am

    今日上午的学习效率极低,两个多小时什么成果都没有,有一丝伤心

    chuj January 4th, 2021 at 10:30 pm

    花了这么久,libc的问题还是无法解决,还是考虑用dockers吧,虽然在虚拟机里面开dockers显得很呆,但是这也许是现在最好的解决方法了

    chuj January 2nd, 2021 at 09:54 pm

    echo_back这道io_file题解不出来,比较重要的原因是gdb还是用不来,明天尽量把指定libc运行的方法搞好

    chuj January 2nd, 2021 at 05:00 pm

    https://www.796t.com/article.php?id=181322
    这个网站竟然盗取了我的文章,还有300的阅读量,一方面被盗取也是我的文章质量尚可的表现,另一方面是真的非常难受啊,其实我并不介意被转载,相反我非常欢迎,但是至少要声明清楚是从我这里转载去的啊。

    chuj January 1st, 2021 at 08:28 pm

    看到我chrome杂乱无章的收藏夹,突然动了删除用不上的书签的想法,这一删仿佛时光倒流,从三年多前刚保送时买电脑到现在的往事全部闪过,泪目

    chuj December 30th, 2020 at 11:04 pm

    试一试时光机的功能

联系方式
  • 1768485949@qq.com
  • 1768485949

关于我

  • 来自杭州,地址 120.55.55.46