diff --git a/_config.fluid.yml b/_config.fluid.yml index 0dc8cf2..58da91d 100644 --- a/_config.fluid.yml +++ b/_config.fluid.yml @@ -1046,6 +1046,12 @@ links: link: "https://mywww0517.github.io/", avatar: "https://www.yuehaishibei.com/wp-content/uploads/2021/06/1622563432-b3ab24848d38a73.jpg" } + - { + title: "Sharelter", + intro: "Meow~", + link: "https://sharelter.github.io/", + avatar: "https://sharelter.github.io/img/sharelter-avatar_hub1f71be9b71dd17b212d94ded2d9ce34_23100_300x0_resize_q75_box.jpeg" + } - { title: "Cachy Blog", intro: "Blazingly Fast & Customizable", diff --git a/db.json b/db.json index 6776577..4f50fe3 100644 --- a/db.json +++ b/db.json @@ -1 +1 @@ -{"meta":{"version":1,"warehouse":"5.0.1"},"models":{"Asset":[{"_id":"source/images/1613f5602b203b38230f19699deb0219454454985.png","path":"images/1613f5602b203b38230f19699deb0219454454985.png","modified":1,"renderable":0},{"_id":"source/images/1730728153314.png","path":"images/1730728153314.png","modified":1,"renderable":0},{"_id":"source/images/20241027_222225.png","path":"images/20241027_222225.png","modified":1,"renderable":0},{"_id":"source/images/5364bba6d035326e82c53504dd53e7c2454454985.png","path":"images/5364bba6d035326e82c53504dd53e7c2454454985.png","modified":1,"renderable":0},{"_id":"source/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","path":"images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","modified":1,"renderable":0},{"_id":"source/images/Written-By-Human-Not-By-AI-Badge-white@2x.png","path":"images/Written-By-Human-Not-By-AI-Badge-white@2x.png","modified":1,"renderable":0},{"_id":"source/images/amd.webp","path":"images/amd.webp","modified":1,"renderable":0},{"_id":"source/images/archlinux-logo.png","path":"images/archlinux-logo.png","modified":1,"renderable":0},{"_id":"source/images/asc-events.png","path":"images/asc-events.png","modified":1,"renderable":0},{"_id":"source/images/asc.png","path":"images/asc.png","modified":1,"renderable":0},{"_id":"source/images/audiveris.png","path":"images/audiveris.png","modified":1,"renderable":0},{"_id":"source/images/b2054bbaf6197624d38cc2007d885fd1454454985.png","path":"images/b2054bbaf6197624d38cc2007d885fd1454454985.png","modified":1,"renderable":0},{"_id":"source/images/built_on_the_kde_platform.png","path":"images/built_on_the_kde_platform.png","modified":1,"renderable":0},{"_id":"source/images/caseclosed.png","path":"images/caseclosed.png","modified":1,"renderable":0},{"_id":"source/images/clonezilla.png","path":"images/clonezilla.png","modified":1,"renderable":0},{"_id":"source/images/lmms-import.png","path":"images/lmms-import.png","modified":1,"renderable":0},{"_id":"source/images/mhwilds4050.jpg","path":"images/mhwilds4050.jpg","modified":1,"renderable":0},{"_id":"source/images/mhwilds780M.jpg","path":"images/mhwilds780M.jpg","modified":1,"renderable":0},{"_id":"source/images/musecore-launch.png","path":"images/musecore-launch.png","modified":1,"renderable":0},{"_id":"source/images/musecore-to-midi.png","path":"images/musecore-to-midi.png","modified":1,"renderable":0},{"_id":"source/images/musecore.png","path":"images/musecore.png","modified":1,"renderable":0},{"_id":"source/images/phase1.png","path":"images/phase1.png","modified":1,"renderable":0},{"_id":"source/images/phase1_strings.png","path":"images/phase1_strings.png","modified":1,"renderable":0},{"_id":"source/images/phase_2_14.png","path":"images/phase_2_14.png","modified":1,"renderable":0},{"_id":"source/images/phase_4.png","path":"images/phase_4.png","modified":1,"renderable":0},{"_id":"source/images/searxng.png","path":"images/searxng.png","modified":1,"renderable":0},{"_id":"source/images/xb2score.png","path":"images/xb2score.png","modified":1,"renderable":0},{"_id":"source/images/zellij-helix.jpg","path":"images/zellij-helix.jpg","modified":1,"renderable":0},{"_id":"source/music/過ぎ去りし温もりの日々.mp3","path":"music/過ぎ去りし温もりの日々.mp3","modified":1,"renderable":0},{"_id":"themes/fluid/source/css/gitalk.css","path":"css/gitalk.css","modified":1,"renderable":1},{"_id":"themes/fluid/source/css/highlight-dark.styl","path":"css/highlight-dark.styl","modified":1,"renderable":1},{"_id":"themes/fluid/source/css/highlight.styl","path":"css/highlight.styl","modified":1,"renderable":1},{"_id":"themes/fluid/source/css/main.styl","path":"css/main.styl","modified":1,"renderable":1},{"_id":"themes/fluid/source/img/avatar.png","path":"img/avatar.png","modified":1,"renderable":1},{"_id":"themes/fluid/source/img/gensokyo.jpg","path":"img/gensokyo.jpg","modified":1,"renderable":1},{"_id":"themes/fluid/source/img/gh0s7.jpg","path":"img/gh0s7.jpg","modified":1,"renderable":1},{"_id":"themes/fluid/source/img/hifuu.png","path":"img/hifuu.png","modified":1,"renderable":1},{"_id":"themes/fluid/source/img/loading.gif","path":"img/loading.gif","modified":1,"renderable":1},{"_id":"themes/fluid/source/img/police_beian.png","path":"img/police_beian.png","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/boot.js","path":"js/boot.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/color-schema.js","path":"js/color-schema.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/events.js","path":"js/events.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/img-lazyload.js","path":"js/img-lazyload.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/leancloud.js","path":"js/leancloud.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/local-search.js","path":"js/local-search.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/plugins.js","path":"js/plugins.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/umami-view.js","path":"js/umami-view.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/js/utils.js","path":"js/utils.js","modified":1,"renderable":1},{"_id":"themes/fluid/source/xml/local-search.xml","path":"xml/local-search.xml","modified":1,"renderable":1}],"Cache":[{"_id":"source/about/index.md","hash":"ff7cd1481f3c669a04d7c8abf8851ab0cea5b2b9","modified":1740326480093},{"_id":"source/_posts/12月16-17日工作记录.md","hash":"9f5099a65180c2659f1a1ca218d518fc64965676","modified":1740320866747},{"_id":"source/_posts/12月18日工作记录.md","hash":"28892523fcc2fadb1514645a1c59d501ceab53da","modified":1740320866748},{"_id":"source/_posts/12月19日工作记录.md","hash":"058ca01b682cd36e202189ef025d6d4bb79259fb","modified":1740320866748},{"_id":"source/_posts/12月20日工作记录.md","hash":"0d883ab20ae59540f663c5377e799463762a3b11","modified":1740320866748},{"_id":"source/_posts/12月28日进度报告.md","hash":"4cbda36dc6a2c4bc67140e443638a73aadb18fdf","modified":1740320866748},{"_id":"source/_posts/12月31日进度报告.md","hash":"bf541fdb539029c98dedf975b0c15519adcea76e","modified":1740320866748},{"_id":"source/_posts/2025-5-21.md","hash":"2e1406ca2c83a1a91e78fd3453623ba732d81ee7","modified":1747834483639},{"_id":"source/_posts/BlogUpdate.md","hash":"2c694e3895b2ea0c0cea5f45ab2ec16a868a3df7","modified":1740320866748},{"_id":"source/_posts/CGH0S7-s-Blog.md","hash":"9a5c9461aba29f2447c0f6725f5425d5a05e32f0","modified":1740320866748},{"_id":"source/_posts/GentleJena.md","hash":"df1e35a93284d0b9e2d408635cd98481077d5155","modified":1740330871930},{"_id":"source/_posts/Vocaloid调教-晴天.md","hash":"9141182f5dbfbbd840ad340b3e5271507ddd8c94","modified":1740442745940},{"_id":"source/_posts/arch-nvidia.md","hash":"4144acad32a69e88ef6d5d7d5788da6d87a75193","modified":1738495295673},{"_id":"source/_posts/archlinux-game-fix.md","hash":"a4ab5bd2ca0cf941c5166d3945bd2a2076a54f1e","modified":1741618456788},{"_id":"source/_posts/archlinux-optimization.md","hash":"51c8c12110fb08a1edd1f727ab38a1b2568b690b","modified":1741619246618},{"_id":"source/_posts/clonezilla.md","hash":"598858976961c45ebbbf523014ee792951380dd3","modified":1740319930654},{"_id":"source/_posts/loopers.md","hash":"2b63f5abcfebc672e7f90b3e83cee1b5ac1d4eff","modified":1740320866748},{"_id":"source/_posts/mhwi.md","hash":"b9a73accf93684b8cfac0201288da9b2c5376423","modified":1731333619124},{"_id":"source/_posts/nudtbomblab.md","hash":"51b4410784657675d7c11e17d16c5dc0e5d4a455","modified":1740455795270},{"_id":"source/_posts/overleaf.md","hash":"0786994f4571ac178ee40bc130e3c0d8d2d511f9","modified":1730860316685},{"_id":"source/_posts/searxng.md","hash":"90f951d3c098aa1b062131b7489a4b7afab06792","modified":1741621615535},{"_id":"source/_posts/zellij-helix.md","hash":"7eb3072b50ecdb49a20355e05fc613a4a8b7fbdf","modified":1740326024966},{"_id":"source/_posts/原来我还有个博客.md","hash":"acd7e534b31b7a0173fae880fa584c7dc03fd2cd","modified":1740457594224},{"_id":"source/_posts/梦开始的地方.md","hash":"c0bbfefdd277c8ae2786a5cd4cc05f731af11436","modified":1740457544687},{"_id":"source/images/Written-By-Human-Not-By-AI-Badge-white@2x.png","hash":"994225c6fd72521b281144bdd98fefcca53e2c7b","modified":1731333731000},{"_id":"source/images/amd.webp","hash":"cb0cfd5da0b9c10b9b22c65bba881cfde485d763","modified":1731333907000},{"_id":"source/images/archlinux-logo.png","hash":"4f6075309fadcb7f7547164cb8a99b4949f74598","modified":1731333766000},{"_id":"source/images/asc-events.png","hash":"a0b3610962062d0a322fe091bcc8f083ab13bc6e","modified":1740329910965},{"_id":"source/images/asc.png","hash":"3a33b35bff1b3f527f7a87a9d6a7d6d9a072a946","modified":1740328627284},{"_id":"source/images/built_on_the_kde_platform.png","hash":"507b6a4323b23772800006505e6c588bb515ebf5","modified":1731334007000},{"_id":"source/images/phase1_strings.png","hash":"6fb457adddc5bb32aa463b6227542076c4b501e7","modified":1740382826998},{"_id":"source/images/searxng.png","hash":"9514f2bd14ac1cafa437f3655d9382d477667094","modified":1741619983804},{"_id":"source/images/caseclosed.png","hash":"628b54b49c86a23af595a52daba9e0557b81a17a","modified":1740454957882},{"_id":"source/images/audiveris.png","hash":"52aa9df5f93559c2e47b30afbf84fc6cc6b34002","modified":1744993135289},{"_id":"source/images/musecore-to-midi.png","hash":"02ba31b29ba069dfef0e1cf26c5ccec9dc3d2289","modified":1744993436860},{"_id":"source/images/1730728153314.png","hash":"95d44ea62557a311503cab58d1dec5cafc97e07d","modified":1740320866754},{"_id":"source/images/musecore.png","hash":"9b2eba87e7c93e57f2024697d1ff4217d206e5ac","modified":1744993264700},{"_id":"source/images/xb2score.png","hash":"03efbb07a7bb7f6c7d58b98ed125cafe42074b94","modified":1744992816374},{"_id":"source/images/phase1.png","hash":"42533712403be6036231f1e3770f125858bf91d7","modified":1740385026324},{"_id":"source/images/5364bba6d035326e82c53504dd53e7c2454454985.png","hash":"11b11f23ebebbe08e8cf826b48eb37b4084796cd","modified":1729572689000},{"_id":"themes/fluid/source/css/_pages/_tag/tag.styl","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1740320867063},{"_id":"source/images/1613f5602b203b38230f19699deb0219454454985.png","hash":"3d71204d9a0731384f97ad0f90802a5c9fd96776","modified":1729572689000},{"_id":"themes/fluid/.editorconfig","hash":"33218fbd623feb43edf5f99f15965392cecc44a6","modified":1740320867050},{"_id":"themes/fluid/.eslintrc","hash":"4bc2b19ce2b8c4d242f97d4ccf2d741e68ab0097","modified":1740320867050},{"_id":"themes/fluid/.gitignore","hash":"ae3bfcb89777657c5dfb5169d91445dcb0e5ab98","modified":1740320867051},{"_id":"themes/fluid/LICENSE","hash":"26f9356fd6e84b5a88df6d9014378f41b65ba209","modified":1740320867051},{"_id":"themes/fluid/README.md","hash":"ff9b0e1fb9dba665af2f1e4a577f8cb9e840464b","modified":1740320867051},{"_id":"themes/fluid/README_en.md","hash":"365184a73af40e7365504c3077f3d80dfee1d80e","modified":1740320867051},{"_id":"themes/fluid/package.json","hash":"7746460fc2eba7439b494c46aa9b5ded81370819","modified":1740320867057},{"_id":"themes/fluid/_config.yml","hash":"60403ea6aa5e0cab9dbc7bf0d77257e4a941babc","modified":1740329151304},{"_id":"themes/fluid/languages/de.yml","hash":"58dccef1d98b472dc4e6f4693c2297b0c9c5afba","modified":1740320867052},{"_id":"themes/fluid/languages/en.yml","hash":"9c580471257f5a32bee701a059a45ea96755dcdc","modified":1740320867052},{"_id":"themes/fluid/languages/eo.yml","hash":"7c1a0c9f6186b6643b19d3980f055329bdb4efa4","modified":1740320867052},{"_id":"themes/fluid/languages/es.yml","hash":"026ddf1a49bf8ddfef6ed86ab4d6af143c1dd95f","modified":1740320867052},{"_id":"themes/fluid/languages/ja.yml","hash":"550b95d3614a64592f02666938d235e9f11e449e","modified":1740320867052},{"_id":"themes/fluid/languages/ru.yml","hash":"93818f8bf07195fb1ebffbb5210e531b0e3a6ec4","modified":1740320867052},{"_id":"themes/fluid/languages/zh-CN.yml","hash":"a60847136709bb95586a98d9d67b50390a8d2c96","modified":1740320867052},{"_id":"themes/fluid/languages/zh-HK.yml","hash":"51c2b4d64c6992a39bfd2586a1bdf5fbbbdf0175","modified":1740320867052},{"_id":"themes/fluid/.gitattributes","hash":"a54f902957d49356376b59287b894b1a3d7a003f","modified":1740320867050},{"_id":"themes/fluid/languages/zh-TW.yml","hash":"e1043de394f6dcf5c0647adcfdefe60637f78426","modified":1740320867052},{"_id":"themes/fluid/layout/404.ejs","hash":"b84d575c7b7f778b4cb64e89ad3d0aed4a896820","modified":1740320867052},{"_id":"themes/fluid/layout/about.ejs","hash":"052e9fc19c753f53fdc083c7fb098e3668880140","modified":1740320867056},{"_id":"themes/fluid/layout/categories.ejs","hash":"13859726c27b6c79b5876ec174176d0f9c1ee164","modified":1740320867056},{"_id":"themes/fluid/layout/category.ejs","hash":"f099161b738a16a32253f42085b5444f902018ed","modified":1740320867056},{"_id":"themes/fluid/layout/index.ejs","hash":"33c3317cdcee062789de2336dd8d0cc7f86d3650","modified":1740320867056},{"_id":"themes/fluid/layout/layout.ejs","hash":"7e0023474128fbe4d68c467704c41f1712432415","modified":1740320867056},{"_id":"themes/fluid/layout/links.ejs","hash":"1cac32ec4579aaf7b9fa39d317497331d4c5e1dd","modified":1740320867056},{"_id":"themes/fluid/layout/page.ejs","hash":"ed5007a3feb8f14d3d2843271bfb298eb0c56219","modified":1740320867056},{"_id":"themes/fluid/layout/post.ejs","hash":"9bf0d357a607a282f3b9cb04525a4df0cc2a8b76","modified":1740320867056},{"_id":"themes/fluid/layout/tag.ejs","hash":"9d686364c4d16a1a9219471623af452035c5b966","modified":1740320867056},{"_id":"themes/fluid/layout/tags.ejs","hash":"1d06af34b6cf1d8a20d2eb565e309326ceba309f","modified":1740320867057},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/bug_report.md","hash":"554c0d0e086a0784d83ee71c83f8bceeb60aecc8","modified":1740320867050},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/bug_report_zh.md","hash":"c8b0d49c49e3c88872fd3b37909345ff5b2b6aa0","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/feature_request.md","hash":"c134dd57ffd269b93402ccfffe7dbe0f0b583bec","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/feature_request_zh.md","hash":"ed08574b196447376dd74411cca664ac9227a5d4","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/question.md","hash":"ab5eab9e3ff889c4ba7fd82846e7f5b7ae15bebc","modified":1740320867051},{"_id":"themes/fluid/layout/archive.ejs","hash":"7c1f44005849791feae4abaa10fae4cb983d3277","modified":1740320867056},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/question_zh.md","hash":"fff07ce0472afc368d388637cb9d438195da9b5b","modified":1740320867051},{"_id":"themes/fluid/.github/workflows/cr.yaml","hash":"19a8a00f5ba9607d82265572fe1202b64a8b0822","modified":1740320867051},{"_id":"themes/fluid/.github/workflows/limit.yaml","hash":"f8bd2edeb4424ee7a055b31583445d5d5dff91a4","modified":1740320867051},{"_id":"themes/fluid/.github/workflows/publish.yaml","hash":"6f02e6440d88629229556e3fd47d0280fe2240db","modified":1740320867051},{"_id":"themes/fluid/layout/_partials/archive-list.ejs","hash":"7520fbf91f762207c2ab06b2c293235cd5b23905","modified":1740320867052},{"_id":"themes/fluid/layout/_partials/category-chains.ejs","hash":"18309584aab83bc4deb20723ebad832149dd2e24","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/category-list.ejs","hash":"f8d2f1907450e61968e6d54443e9be8138196a77","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments.ejs","hash":"d707c47b2638c94e489bc43d4cfd098b7c58447f","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/css.ejs","hash":"1dadb118d580280524ed0a5f69bd34d234a92276","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/footer.ejs","hash":"b52aa2d61b6812588a805b676ffdf8b887023938","modified":1740330605855},{"_id":"themes/fluid/layout/_partials/head.ejs","hash":"67be642f99482c07904474f410cfbc2f99003288","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/header.ejs","hash":"0d5e397d30051e5fbabe7b47cfd1f1e6a5820af1","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/markdown-plugins.ejs","hash":"fc4bdf7de0cf1a66d0e5e4fba1b31d6f7ed49468","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/paginator.ejs","hash":"0f38a2c238169edcb63fc46c23bfc529ff3859b7","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/scripts.ejs","hash":"da5810785105e5075861593c7ac22c7aa9665a72","modified":1740320867056},{"_id":"themes/fluid/scripts/events/index.js","hash":"79de5a379b28cad759a49048351c7f6b8915bd7d","modified":1740320867057},{"_id":"themes/fluid/layout/_partials/search.ejs","hash":"70e1c929e084ca8a2648cedabf29b372511ea2b8","modified":1740320867056},{"_id":"themes/fluid/scripts/filters/default-injects.js","hash":"b2013ae8e189cd07ebc8a2ff48a78e153345210f","modified":1740320867057},{"_id":"themes/fluid/scripts/filters/locals.js","hash":"58d0fec976f6b1d35e7ea03edc45414088acf05c","modified":1740320867057},{"_id":"themes/fluid/scripts/filters/post-filter.js","hash":"82bb06686158ebe160a631c79f156cd4fde35656","modified":1740320867057},{"_id":"themes/fluid/scripts/generators/index-generator.js","hash":"9159fc22fa84a7b605dd15fe4104f01fe9c71147","modified":1740320867057},{"_id":"themes/fluid/scripts/generators/local-search.js","hash":"9ac5ddad06e9b0e6015ce531430018182a4bc0fa","modified":1740320867058},{"_id":"themes/fluid/scripts/generators/pages.js","hash":"d3e75f53c59674d171309e50702954671f31f1a4","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/date.js","hash":"9bda6382f61b40a20c24af466fe10c8366ebb74c","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/engine.js","hash":"d3a231d106795ce99cb0bc77eb65f9ae44515933","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/export-config.js","hash":"8e67b522c47aa250860e3fe2c733f1f958a506c0","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/import.js","hash":"ca53e8dbf7d44cfd372cfa79ac60f35a7d5b0076","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/injects.js","hash":"1ad2ae6b11bd8806ee7dd6eb7140d8b54a95d613","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/page.js","hash":"4607607445233b3029ef20ed5e91de0da0a7f9c5","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/scope.js","hash":"d41d9d658fcb54964b388598e996747aadb85b0f","modified":1740320867059},{"_id":"themes/fluid/scripts/helpers/url.js","hash":"2a6a8288176d0e0f6ec008056bf2745a86e8943e","modified":1740320867059},{"_id":"themes/fluid/scripts/helpers/utils.js","hash":"966689d7c5e4320008285395fbaa2751f6209be5","modified":1740320867059},{"_id":"themes/fluid/scripts/helpers/wordcount.js","hash":"4d48c424e47ff9a17a563167ea5f480890267adf","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/button.js","hash":"3eb43a8cdea0a64576ad6b31b4df6c2bf5698d4c","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/checkbox.js","hash":"6eaf53cf4bfc756a65bda18184cf8998a12c861d","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/fold.js","hash":"73e4fd12ce3e47981479391ed354b7d9d3279f70","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/group-image.js","hash":"4aeebb797026f1df25646a5d69f7fde79b1bcd26","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/label.js","hash":"f05a6d32cca79535b22907dc03edb9d3fa2d8176","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/mermaid.js","hash":"75160561e1ef3603b6d2ad2938464ab1cb77fd38","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/note.js","hash":"e3b456a079e5dc0032473b516c865b20f83d2c26","modified":1740320867059},{"_id":"themes/fluid/scripts/utils/compare-versions.js","hash":"dbbc928c914fc2bd242cd66aa0c45971aec13a5d","modified":1740320867059},{"_id":"themes/fluid/scripts/utils/crypto.js","hash":"ae4ad8a188ef5b3fa6818b01629fc962b3de8551","modified":1740320867060},{"_id":"themes/fluid/scripts/utils/object.js","hash":"33b57e4decdc5e75c518859f168c8ba80b2c665b","modified":1740320867060},{"_id":"themes/fluid/scripts/utils/resolve.js","hash":"8c4a8b62aa8608f12f1e9046231dff04859dc3e9","modified":1740320867060},{"_id":"themes/fluid/scripts/utils/url-join.js","hash":"718aab5e7b2059a06b093ca738de420d9afa44ba","modified":1740320867060},{"_id":"themes/fluid/source/css/highlight-dark.styl","hash":"45695ef75c31a4aa57324dd408b7e2327a337018","modified":1740320867063},{"_id":"themes/fluid/source/css/gitalk.css","hash":"a57b3cc8e04a0a4a27aefa07facf5b5e7bca0e76","modified":1740320867063},{"_id":"themes/fluid/source/css/highlight.styl","hash":"a9efc52a646a9e585439c768557e3e3c9e3326dc","modified":1740320867063},{"_id":"themes/fluid/source/css/main.styl","hash":"855ae5fe229c51afa57f7645f6997a27a705d7e4","modified":1740320867063},{"_id":"themes/fluid/source/img/avatar.png","hash":"fe739a158cc128f70f780eb5fa96f388b81d478f","modified":1740320867063},{"_id":"themes/fluid/source/img/loading.gif","hash":"2d2fc0f947940f98c21afafef39ecf226a2e8d55","modified":1740320867086},{"_id":"themes/fluid/source/js/events.js","hash":"6869811f67e4c3de3edfa4b08464bb242b97a402","modified":1740320867086},{"_id":"themes/fluid/source/img/police_beian.png","hash":"90efded6baa2dde599a9d6b1387973e8e64923ea","modified":1740320867086},{"_id":"themes/fluid/source/js/color-schema.js","hash":"1ef88c881b9f942deadde3d890387b94c617342a","modified":1740320867086},{"_id":"themes/fluid/source/js/leancloud.js","hash":"eff77c7a5c399fcaefda48884980571e15243fc9","modified":1740320867086},{"_id":"themes/fluid/source/js/local-search.js","hash":"b9945f76f8682f3ec32edfb285b26eb559f7b7e8","modified":1740320867086},{"_id":"themes/fluid/source/js/plugins.js","hash":"c34916291e392a774ff3e85c55badb83e8661297","modified":1740320867087},{"_id":"themes/fluid/source/js/img-lazyload.js","hash":"cbdeca434ec4da51f488c821d51b4d23c73294af","modified":1740320867086},{"_id":"themes/fluid/source/js/umami-view.js","hash":"33c4b3883fa747604074ad3921606eeeaeb50716","modified":1740320867087},{"_id":"themes/fluid/source/js/utils.js","hash":"b82e7c289a66dfd36064470fd41c0e96fc598b43","modified":1740320867087},{"_id":"themes/fluid/layout/_partials/comments/changyan.ejs","hash":"c9b2d68ed3d375f1953e7007307d2a3f75ed6249","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/cusdis.ejs","hash":"5f9dc012be27040bbe874d0c093c0d53958cc987","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/disqus.ejs","hash":"aab4a4d24c55231a37db308ae94414319cecdd9b","modified":1740320867053},{"_id":"themes/fluid/source/xml/local-search.xml","hash":"8c96ba6a064705602ce28d096fd7dd9069630a55","modified":1740320867087},{"_id":"themes/fluid/layout/_partials/comments/discuss.ejs","hash":"98d065b58ce06b7d18bff3c974e96fa0f34ae03a","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/giscus.ejs","hash":"95f8b866b158eff9352c381c243b332a155a5110","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/gitalk.ejs","hash":"843bc141a4545eb20d1c92fb63c85d459b4271ec","modified":1740320867053},{"_id":"themes/fluid/source/js/boot.js","hash":"38bd26c6b7acdafda86dda3560e6a3ca488d3c76","modified":1740320867086},{"_id":"themes/fluid/layout/_partials/comments/livere.ejs","hash":"2264758fed57542a7389c7aa9f00f1aefa17eb87","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/remark42.ejs","hash":"d4e9532feeb02aed61bd15eda536b5b631454dac","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/twikoo.ejs","hash":"d84bcb5ccd78470a60c067fc914ac0ac67ac8777","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/utterances.ejs","hash":"c7ccf7f28308334a6da6f5425b141a24b5eca0e2","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/comments/valine.ejs","hash":"19ba937553dddd317f827d682661a1066a7b1f30","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/comments/waline.ejs","hash":"3d08c73b77e412d2f06a24d9344565fc7dbc76f8","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/footer/beian.ejs","hash":"4fb9b5dd3f3e41a586d6af44e5069afe7c81fff2","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/footer/statistics.ejs","hash":"954a29b58d72647d20450da270b5d8fb2e0824f5","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/header/banner.ejs","hash":"e07757b59e7b89eea213d0e595cb5932f812fd32","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/header/navigation.ejs","hash":"37d750428772d7c71ba36ce0c2540780d90fadea","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/plugins/analytics.ejs","hash":"e6dcbf1c2f56314d56bb46b50aca86ff68cacebd","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/anchorjs.ejs","hash":"40181442d3a2b8734783a0ad7caf2d2522e3f2ab","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/code-widget.ejs","hash":"3a505cba37942badf62a56bbb8b605b72af330aa","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/encrypt.ejs","hash":"0fff24cf5bf99fbe5c56c292e2eac4a89bf29db4","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/fancybox.ejs","hash":"9d1ea2a46b8c8ad8c168594d578f40764818ef13","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/highlight.ejs","hash":"7529dd215b09d3557804333942377b9e20fa554e","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/math.ejs","hash":"dcbf9a381ee76f2f1f75fcbc22c50a502ec85023","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/mermaid.ejs","hash":"03ac02762f801970d1c4e73d6ec8d4c503780e50","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/moment.ejs","hash":"4ff3fb1b60ccc95a0af3bbdbd0757fedefc088b5","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/nprogress.ejs","hash":"4c2d39ce816b8a6dcd6b53113c8695f8bd650a23","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/typed.ejs","hash":"f345374885cd6a334f09a11f59c443b5d577c06c","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/category-bar.ejs","hash":"8772bce97ed297e7a88523f4e939ed6436c22f87","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/meta-bottom.ejs","hash":"375974ec017696e294dc12469fb0ae257800dc2d","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/copyright.ejs","hash":"cbfa32c5f5973133afd043853b24f8200455cb2d","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/meta-top.ejs","hash":"54dd479dbb440126e4ddd9d902229db5afaaae98","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/sidebar-left.ejs","hash":"9992c99b3eb728ad195970e1b84d665f2c8691c4","modified":1740320867056},{"_id":"themes/fluid/scripts/events/lib/compatible-configs.js","hash":"ef474d1fa5bbafc52619ced0f9dc7eaf2affb363","modified":1740320867057},{"_id":"themes/fluid/layout/_partials/post/toc.ejs","hash":"635a89060fbf72eeda066fc4bd0a97462f069417","modified":1740320867056},{"_id":"themes/fluid/scripts/events/lib/footnote.js","hash":"c19ac8050b82c3676b0332a56099ccfcc36d9d52","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/hello.js","hash":"bd8376e1cf7892dc2daa58f2f443574be559fdbf","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/highlight.js","hash":"a5fe1deccb73b5f578797dbb11038efc15f63ce8","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/injects.js","hash":"5ae4b07204683e54b5a1b74e931702bbce2ac23e","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/lazyload.js","hash":"9ba0d4bc224e22af8a5a48d6ff13e5a0fcfee2a4","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/merge-configs.js","hash":"7c944c43b2ece5dd84859bd9d1fe955d13427387","modified":1740320867057},{"_id":"themes/fluid/source/css/_functions/base.styl","hash":"2e46f3f4e2c9fe34c1ff1c598738fc7349ae8188","modified":1740320867060},{"_id":"themes/fluid/source/css/_mixins/base.styl","hash":"542e306ee9494e8a78e44d6d7d409605d94caeb3","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/pages.styl","hash":"b8e887bc7fb3b765a1f8ec9448eff8603a41984f","modified":1740320867063},{"_id":"themes/fluid/source/css/_variables/base.styl","hash":"4ed5f0ae105ef4c7dd92eaf652ceda176c38e502","modified":1740320867063},{"_id":"themes/fluid/source/css/_pages/_about/about.styl","hash":"97fe42516ea531fdad771489b68aa8b2a7f6ae46","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/base.styl","hash":"643284c567665f96915f0b64e59934dda315f74d","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/inline.styl","hash":"411a3fa3f924a87e00ff04d18b5c83283b049a4d","modified":1740320867061},{"_id":"themes/fluid/layout/_partials/post/sidebar-right.ejs","hash":"d5fcc9b60e02f869a29a8c17a16a6028ecc1e6d8","modified":1740320867056},{"_id":"themes/fluid/source/css/_pages/_base/keyframes.styl","hash":"94065ea50f5bef7566d184f2422f6ac20866ba22","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_base/color-schema.styl","hash":"85492ef64d7e5f70f0f7e46d570bbc911e686d7e","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/print.styl","hash":"166afbc596ea4b552bad7290ec372d25ec34db7b","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_category/category-bar.styl","hash":"cc6df43fef6bb3efecbfdd8b9e467424a1dea581","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_archive/archive.styl","hash":"c475e6681546d30350eaed11f23081ecae80c375","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_category/category-chain.styl","hash":"0cdf7ef50dfd0669d3b257821384ff31cd81b7c9","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_category/category-list.styl","hash":"7edfe1b571ecca7d08f5f4dbcf76f4ffdcfbf0b5","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_index/index.styl","hash":"25fb6fa4c783b847c632584c49a7e1593cdb2f5d","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_links/links.styl","hash":"5c7f2044e3f1da05a3229537c06bd879836f8d6e","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/comment.styl","hash":"780f3788e7357bcd3f3262d781cb91bb53976a93","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/highlight.styl","hash":"4df764d298fe556e501db4afc2b05686fe6ebcfb","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/markdown.styl","hash":"1e3d3a82721e7c10bcfcecec6d81cf2979039452","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/post-page.styl","hash":"7eee3f78296a3c81849a5415d1d43dcc6e03e6aa","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/post-tag.styl","hash":"c96d36aa8fe20f0c3c1a29ee2473cd8064b10f73","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_tag/tags.styl","hash":"65bfc01c76abc927fa1a23bf2422892b0d566c3f","modified":1740320867063},{"_id":"themes/fluid/source/css/_pages/_base/_widget/banner.styl","hash":"7a0bd629bc234fc75e3cc8e3715ffada92f09e73","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/anchorjs.styl","hash":"e0cebda4a6f499aff75e71417d88caa7ceb13b94","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/code-widget.styl","hash":"b66ab013f0f37d724a149b85b3c7432afcf460ad","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/board.styl","hash":"4397037fc3f0033dbe546c33cd9dbdabd8cb1632","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/copyright.styl","hash":"26f71a9cd60d96bb0cb5bbdf58150b8e524d9707","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/footer.styl","hash":"2caaca71dd1ff63d583099ed817677dd267b457e","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/footnote.styl","hash":"ae9289cc89649af2042907f8a003303b987f3404","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/header.styl","hash":"d42b748f2f49ef32aafb1a21d75991d2459da927","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/modal.styl","hash":"adf6c1e5c8e1fb41c77ce6e2258001df61245aa2","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/ngrogress.styl","hash":"5d225357b4a58d46118e6616377168336ed44cb2","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/noscript.styl","hash":"0cf2f2bb44f456150d428016675d5876a9d2e2aa","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/pagination.styl","hash":"8bb1b68e5f3552cb48c2ffa31edbc53646a8fb4c","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/qrcode.styl","hash":"78704a94c0436097abfb0e0a57abeb3429c749b7","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/scroll-btn.styl","hash":"f0e429a27fa8a7658fcbddbb4d4dbe4afa12499a","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/search.styl","hash":"10f7e91a91e681fb9fe46f9df7707b9ef78707c8","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/toc.styl","hash":"9e7452aa2372153f25d7a4675c9d36d281a65d24","modified":1740320867061},{"_id":"source/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","hash":"dddf72bb12aef01baa3eb2017bb867f274059f12","modified":1729572689000},{"_id":"source/images/mhwilds4050.jpg","hash":"9b2b15c66e2340c15b86cec0fa8f818b67e06384","modified":1730738910727},{"_id":"themes/fluid/source/img/hifuu.png","hash":"331b5950baf96f5d39192bb42b7da4d22a08992e","modified":1740320867086},{"_id":"source/images/mhwilds780M.jpg","hash":"e2c59c6caae452afb424d9f2fc3a255a44121b49","modified":1730738926927},{"_id":"source/images/clonezilla.png","hash":"7f443d79783df3744b2e51613422ee8fd7eea6f8","modified":1740318117703},{"_id":"source/images/phase_2_14.png","hash":"f50399a9eb469ed1e063ff4ccc0e8636c1b75f1e","modified":1740407245723},{"_id":"source/images/phase_4.png","hash":"81cd309a8990e015a8679b6a4e26a27d804c1da6","modified":1740410093173},{"_id":"themes/fluid/source/img/gh0s7.jpg","hash":"1c5af4f8cacdc3c6adbe8334866774cca2944910","modified":1740320867085},{"_id":"source/images/20241027_222225.png","hash":"f0595d1315d94e72e61c69e0499e5129e1821ba1","modified":1740320866763},{"_id":"source/images/b2054bbaf6197624d38cc2007d885fd1454454985.png","hash":"b021e971cedaa55b273eab2b10be94f795b06922","modified":1729572689000},{"_id":"source/images/lmms-import.png","hash":"002535b55a41f7a7dcba24517dd2397589416a64","modified":1744993882632},{"_id":"source/music/過ぎ去りし温もりの日々.mp3","hash":"22016dcdfcbac9393afd3fe97f2d6d6009cd57f5","modified":1747827275971},{"_id":"source/images/musecore-launch.png","hash":"0a6c5642d05b197555135cd602886311a9122df0","modified":1744993224514},{"_id":"source/images/zellij-helix.jpg","hash":"87fb5b7b51a4e3b062b891c04488a53457edded0","modified":1738492100321},{"_id":"themes/fluid/source/img/gensokyo.jpg","hash":"d82c0d5011c6cbc37109c9c80530d14cd266286f","modified":1740320867082},{"_id":"public/local-search.xml","hash":"e93da0932e27bf9935a9cc3b19b0e7cbdd5364bd","modified":1747835050737},{"_id":"public/about/index.html","hash":"cf21ca666c882e4bdb83f83119a48053a895b443","modified":1747835050737},{"_id":"public/2025/05/21/2025-5-21/index.html","hash":"2c3cdd1a87577f92b6e932a2ab7111f556ee5e40","modified":1747835050737},{"_id":"public/2025/03/10/archlinux-game-fix/index.html","hash":"9ae2ff5a413222135be2c4cc1bc0913ed39ad390","modified":1747835050737},{"_id":"public/2025/03/10/searxng/index.html","hash":"2c8ae7693b4ece22f83f7536e4d2a5032499da90","modified":1747835050737},{"_id":"public/2025/02/23/clonezilla/index.html","hash":"18b734abda3405019efcab2523f12e766bfa73a3","modified":1747835050737},{"_id":"public/2024/12/13/zellij-helix/index.html","hash":"952cd837e89121b41cef1b3fe92fc98f6253bcc4","modified":1747835050737},{"_id":"public/2025/02/24/nudtbomblab/index.html","hash":"0a6392b9894d41caded05b2012588c043d91cc68","modified":1747835050737},{"_id":"public/2024/11/11/mhwi/index.html","hash":"ebe1a9550fe14035a215f067342373d3e2a2e8c5","modified":1747835050737},{"_id":"public/2025/02/02/archlinux-optimization/index.html","hash":"1e3734b7817998fe800911dbb15e6c0fdb2f55f8","modified":1747835050737},{"_id":"public/2024/11/06/overleaf/index.html","hash":"bc411b1a10fcbb6a5f6d0d213fa63f093830cae3","modified":1747835050737},{"_id":"public/2024/11/04/BlogUpdate/index.html","hash":"ac98c86ad12b3074414a44bfdf3ed153320d3a03","modified":1747835050737},{"_id":"public/2024/11/04/Vocaloid调教-晴天/index.html","hash":"a3dd5c0b77bd2eb77555d349177492a02e17fd25","modified":1747835050737},{"_id":"public/2024/11/06/arch-nvidia/index.html","hash":"8ade129a78d71d3017432e1a65e1d6d292a16c53","modified":1747835050737},{"_id":"public/2024/06/03/原来我还有个博客/index.html","hash":"7215c9a90d0695469c179717d27194e346a8abd0","modified":1747835050737},{"_id":"public/2023/12/31/12月31日进度报告/index.html","hash":"03f909c8954f0e623ccaf2e30fa44a1d3f45814b","modified":1747835050737},{"_id":"public/2024/11/04/loopers/index.html","hash":"9eceb4b3fc581ba245f16a1b0217f5d2b1594b47","modified":1747835050737},{"_id":"public/2023/12/28/12月28日进度报告/index.html","hash":"5aa948c12c109b08b781baf308c9a80ddd3bc379","modified":1747835050737},{"_id":"public/2024/10/30/GentleJena/index.html","hash":"0747019314125e796e102155e09febb4cbdb9b67","modified":1747835050737},{"_id":"public/2023/12/19/12月19日工作记录/index.html","hash":"bac072049959ec19cb53ad4b9180b53476c3542f","modified":1747835050737},{"_id":"public/2023/12/18/12月18日工作记录/index.html","hash":"82d3d1cab693f7808b28ed48803229a5290ee798","modified":1747835050737},{"_id":"public/2023/12/20/12月20日工作记录/index.html","hash":"5ee7c6817c2202a86dcf8e7e6898d2559c69dcf2","modified":1747835050737},{"_id":"public/2023/12/06/CGH0S7-s-Blog/index.html","hash":"b13772d5d9a1a7a19d1f565a27e8a9432f0da543","modified":1747835050737},{"_id":"public/categories/更新/index.html","hash":"39ae73dfc0e214df88912e0a38b4cbf3b55e13a4","modified":1747835050737},{"_id":"public/2023/12/06/梦开始的地方/index.html","hash":"2df05084144d2567e92d3b9f59afbb720fbed05a","modified":1747835050737},{"_id":"public/categories/Rearrangement/index.html","hash":"d86532128355807b19a6eb69208699289b62cfb7","modified":1747835050737},{"_id":"public/2023/12/17/12月16-17日工作记录/index.html","hash":"2af885a19d1b28c3a1e6d4afdf110c6733a4c6b5","modified":1747835050737},{"_id":"public/categories/技术分享/index.html","hash":"af921a46b2c79d42f3f975638ec3b7133af7028b","modified":1747835050737},{"_id":"public/archives/index.html","hash":"ec5d891b47b66a9bdadb7992f2238e9442ea91d0","modified":1747835050737},{"_id":"public/categories/Vocaloid/index.html","hash":"048aca4e241b331d0209e9208c379fcf665a0fae","modified":1747835050737},{"_id":"public/archives/page/3/index.html","hash":"fabf4016d3a7de20c6e993c13e256b881c31e028","modified":1747835050737},{"_id":"public/archives/2023/index.html","hash":"cfb8cf3a7ef7b6198ff3171ea0628029c47db913","modified":1747835050737},{"_id":"public/archives/2024/index.html","hash":"e0f894ad4b73c368e89277e85b2a614df3ff09a6","modified":1747835050737},{"_id":"public/archives/2024/06/index.html","hash":"a3c935f35c85972f5b10ba27284dd24c7d472ce7","modified":1747835050737},{"_id":"public/archives/2024/10/index.html","hash":"1c12f925fc27101f6b03ebc42e03825d440f6707","modified":1747835050737},{"_id":"public/archives/page/2/index.html","hash":"1798734e7221b271d444c951b8bf02006ec76037","modified":1747835050737},{"_id":"public/archives/2023/12/index.html","hash":"f62e3338055fb72961ac5634ecae0121fdde4fb3","modified":1747835050737},{"_id":"public/archives/2024/11/index.html","hash":"5bc20671634ceee8c4ce04e232ceb8b7bbf69280","modified":1747835050737},{"_id":"public/archives/2025/02/index.html","hash":"1238bf1e6bedaee18e3f675e1d5b598a47fca834","modified":1747835050737},{"_id":"public/archives/2024/12/index.html","hash":"d0c61ba1cfa31da7518463074a7a929d2d66a9fd","modified":1747835050737},{"_id":"public/archives/2025/index.html","hash":"8fd7155ada55116ac449a5ab8d477b08e3840fe7","modified":1747835050737},{"_id":"public/index.html","hash":"13015942a11d8dce4d733c5f7bce17f78145b532","modified":1747835050737},{"_id":"public/archives/2025/03/index.html","hash":"528e8a89d9695104a97e6d966ea70fa4de7dde54","modified":1747835050737},{"_id":"public/page/2/index.html","hash":"b0ad31ca545b95c28a522d787ab371a5ca808ded","modified":1747835050737},{"_id":"public/archives/2025/05/index.html","hash":"39b473991ae981cb0dd5d015c3c2f22fe5b07838","modified":1747835050737},{"_id":"public/tags/日志/index.html","hash":"cd3c532135cca19a12e8d83d8964f4189ea2cf96","modified":1747835050737},{"_id":"public/page/3/index.html","hash":"af80593bf46520f11f7ce539bd6974b81f80914e","modified":1747835050737},{"_id":"public/tags/音乐/index.html","hash":"0c4de7bf53b25a52c23aaf27d7327d49d165268b","modified":1747835050737},{"_id":"public/tags/技术/index.html","hash":"1dea2413397a9fdfba26ee98c8c69adc280d17e9","modified":1747835050737},{"_id":"public/tags/Vocaloid/index.html","hash":"98440598d6da10f35250eb46e393c0f7199fd848","modified":1747835050737},{"_id":"public/tags/Archlinux/index.html","hash":"5a8f0e067e637caac2101ea74f750f5ad9d0e45d","modified":1747835050737},{"_id":"public/tags/系统优化/index.html","hash":"ff22e88f749e9ff6b5e47143fa5a24d3389a1795","modified":1747835050737},{"_id":"public/tags/技术分享/index.html","hash":"04a2f939d67c26b002b2a6e66fc8b7ce798263a7","modified":1747835050737},{"_id":"public/tags/TEST/index.html","hash":"2e5789b8e544c5e8404441c75b054f661294306a","modified":1747835050737},{"_id":"public/tags/学习/index.html","hash":"b754a2106f26f5f90fd1d4e6370b58904b39eda3","modified":1747835050737},{"_id":"public/tags/开源工具/index.html","hash":"413cb791b6e4f8b10b692a372aba73a022472720","modified":1747835050737},{"_id":"public/404.html","hash":"4696437e74fa558f8be811e50fdfd88f2a84e82b","modified":1747835050737},{"_id":"public/tags/生活/index.html","hash":"8b296e4d7b64147895e55bb3f111bffa0ca4ab8b","modified":1747835050737},{"_id":"public/categories/index.html","hash":"f2bbc847232265380a90a69b0d2f3bfb05137d31","modified":1747835050737},{"_id":"public/tags/index.html","hash":"d8f11049bfd72b2103dc113194a4c2c283e7ba8d","modified":1747835050737},{"_id":"public/links/index.html","hash":"ab10a393b689f1be4573589418321b506e66f699","modified":1747835050737},{"_id":"public/tags/板绘/index.html","hash":"05cf911d2c26ed5f6d104d875c11762e6e55b12e","modified":1747835050737},{"_id":"public/images/asc-events.png","hash":"a0b3610962062d0a322fe091bcc8f083ab13bc6e","modified":1747835050737},{"_id":"public/images/amd.webp","hash":"cb0cfd5da0b9c10b9b22c65bba881cfde485d763","modified":1747835050737},{"_id":"public/images/Written-By-Human-Not-By-AI-Badge-white@2x.png","hash":"994225c6fd72521b281144bdd98fefcca53e2c7b","modified":1747835050737},{"_id":"public/images/archlinux-logo.png","hash":"4f6075309fadcb7f7547164cb8a99b4949f74598","modified":1747835050737},{"_id":"public/images/asc.png","hash":"3a33b35bff1b3f527f7a87a9d6a7d6d9a072a946","modified":1747835050737},{"_id":"public/images/built_on_the_kde_platform.png","hash":"507b6a4323b23772800006505e6c588bb515ebf5","modified":1747835050737},{"_id":"public/img/avatar.png","hash":"fe739a158cc128f70f780eb5fa96f388b81d478f","modified":1747835050737},{"_id":"public/img/police_beian.png","hash":"90efded6baa2dde599a9d6b1387973e8e64923ea","modified":1747835050737},{"_id":"public/xml/local-search.xml","hash":"8c96ba6a064705602ce28d096fd7dd9069630a55","modified":1747835050737},{"_id":"public/img/loading.gif","hash":"2d2fc0f947940f98c21afafef39ecf226a2e8d55","modified":1747835050737},{"_id":"public/images/phase1_strings.png","hash":"6fb457adddc5bb32aa463b6227542076c4b501e7","modified":1747835050737},{"_id":"public/img/hifuu.png","hash":"331b5950baf96f5d39192bb42b7da4d22a08992e","modified":1747835050737},{"_id":"public/css/gitalk.css","hash":"a57b3cc8e04a0a4a27aefa07facf5b5e7bca0e76","modified":1747835050737},{"_id":"public/css/highlight.css","hash":"04d4ddbb5e1d1007447c2fe293ee05aae9b9563e","modified":1747835050737},{"_id":"public/css/main.css","hash":"06433abcb688c2f5473623a9355bff9865c48d3f","modified":1747835050737},{"_id":"public/css/highlight-dark.css","hash":"902294bada4323c0f51502d67cba8c3a0298952f","modified":1747835050737},{"_id":"public/js/boot.js","hash":"38bd26c6b7acdafda86dda3560e6a3ca488d3c76","modified":1747835050737},{"_id":"public/js/color-schema.js","hash":"1ef88c881b9f942deadde3d890387b94c617342a","modified":1747835050737},{"_id":"public/js/img-lazyload.js","hash":"cbdeca434ec4da51f488c821d51b4d23c73294af","modified":1747835050737},{"_id":"public/js/leancloud.js","hash":"eff77c7a5c399fcaefda48884980571e15243fc9","modified":1747835050737},{"_id":"public/js/plugins.js","hash":"c34916291e392a774ff3e85c55badb83e8661297","modified":1747835050737},{"_id":"public/js/local-search.js","hash":"b9945f76f8682f3ec32edfb285b26eb559f7b7e8","modified":1747835050737},{"_id":"public/js/events.js","hash":"6869811f67e4c3de3edfa4b08464bb242b97a402","modified":1747835050737},{"_id":"public/js/utils.js","hash":"b82e7c289a66dfd36064470fd41c0e96fc598b43","modified":1747835050737},{"_id":"public/js/umami-view.js","hash":"33c4b3883fa747604074ad3921606eeeaeb50716","modified":1747835050737},{"_id":"public/images/searxng.png","hash":"9514f2bd14ac1cafa437f3655d9382d477667094","modified":1747835050737},{"_id":"public/images/caseclosed.png","hash":"628b54b49c86a23af595a52daba9e0557b81a17a","modified":1747835050737},{"_id":"public/images/audiveris.png","hash":"52aa9df5f93559c2e47b30afbf84fc6cc6b34002","modified":1747835050737},{"_id":"public/images/musecore-to-midi.png","hash":"02ba31b29ba069dfef0e1cf26c5ccec9dc3d2289","modified":1747835050737},{"_id":"public/images/1730728153314.png","hash":"95d44ea62557a311503cab58d1dec5cafc97e07d","modified":1747835050737},{"_id":"public/images/musecore.png","hash":"9b2eba87e7c93e57f2024697d1ff4217d206e5ac","modified":1747835050737},{"_id":"public/img/gh0s7.jpg","hash":"1c5af4f8cacdc3c6adbe8334866774cca2944910","modified":1747835050737},{"_id":"public/images/xb2score.png","hash":"03efbb07a7bb7f6c7d58b98ed125cafe42074b94","modified":1747835050737},{"_id":"public/images/phase1.png","hash":"42533712403be6036231f1e3770f125858bf91d7","modified":1747835050737},{"_id":"public/images/5364bba6d035326e82c53504dd53e7c2454454985.png","hash":"11b11f23ebebbe08e8cf826b48eb37b4084796cd","modified":1747835050737},{"_id":"public/images/1613f5602b203b38230f19699deb0219454454985.png","hash":"3d71204d9a0731384f97ad0f90802a5c9fd96776","modified":1747835050737},{"_id":"public/images/mhwilds4050.jpg","hash":"9b2b15c66e2340c15b86cec0fa8f818b67e06384","modified":1747835050737},{"_id":"public/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","hash":"dddf72bb12aef01baa3eb2017bb867f274059f12","modified":1747835050737},{"_id":"public/images/mhwilds780M.jpg","hash":"e2c59c6caae452afb424d9f2fc3a255a44121b49","modified":1747835050737},{"_id":"public/images/clonezilla.png","hash":"7f443d79783df3744b2e51613422ee8fd7eea6f8","modified":1747835050737},{"_id":"public/images/phase_4.png","hash":"81cd309a8990e015a8679b6a4e26a27d804c1da6","modified":1747835050737},{"_id":"public/images/phase_2_14.png","hash":"f50399a9eb469ed1e063ff4ccc0e8636c1b75f1e","modified":1747835050737},{"_id":"public/images/20241027_222225.png","hash":"f0595d1315d94e72e61c69e0499e5129e1821ba1","modified":1747835050737},{"_id":"public/images/b2054bbaf6197624d38cc2007d885fd1454454985.png","hash":"b021e971cedaa55b273eab2b10be94f795b06922","modified":1747835050737},{"_id":"public/images/lmms-import.png","hash":"002535b55a41f7a7dcba24517dd2397589416a64","modified":1747835050737},{"_id":"public/music/過ぎ去りし温もりの日々.mp3","hash":"22016dcdfcbac9393afd3fe97f2d6d6009cd57f5","modified":1747835050737},{"_id":"public/images/musecore-launch.png","hash":"0a6c5642d05b197555135cd602886311a9122df0","modified":1747835050737},{"_id":"public/images/zellij-helix.jpg","hash":"87fb5b7b51a4e3b062b891c04488a53457edded0","modified":1747835050737},{"_id":"public/img/gensokyo.jpg","hash":"d82c0d5011c6cbc37109c9c80530d14cd266286f","modified":1747835050737}],"Category":[{"name":"更新","_id":"cmaxzv0q1000hp22bhluuaucj"},{"name":"Rearrangement","_id":"cmaxzv0q2000pp22betjg2hmk"},{"name":"Vocaloid","_id":"cmaxzv0q3000wp22be1q73d2r"},{"name":"技术分享","_id":"cmaxzv0q40012p22b1fahbd6c"}],"Data":[],"Page":[{"title":"About","date":"2024-11-04T14:46:12.000Z","layout":"about","_content":"\n白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧\n\n爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇\n\n截至目前最喜欢的歌手是宇多田光❤️\n\n联系方式:\n\n- Email: \n\n- Github: \n","source":"about/index.md","raw":"---\ntitle: About\ndate: 2024-11-04 22:46:12\nlayout: about\n---\n\n白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧\n\n爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇\n\n截至目前最喜欢的歌手是宇多田光❤️\n\n联系方式:\n\n- Email: \n\n- Github: \n","updated":"2025-02-23T16:01:20.093Z","path":"about/index.html","comments":1,"_id":"cmaxzv0pu0000p22bd8nm6uwd","content":"

白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧

\n

爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇

\n

截至目前最喜欢的歌手是宇多田光❤️

\n

联系方式:

\n\n","excerpt":"","more":"

白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧

\n

爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇

\n

截至目前最喜欢的歌手是宇多田光❤️

\n

联系方式:

\n\n"}],"Post":[{"title":"12月16-17日工作记录","date":"2023-12-17T14:26:17.000Z","_content":"## 12月16-17日\n1. 四级考试\n2. 自学cuda,openacc,了解GPU架构知识\n3. 参加超算队启动会\n4. 大计和高数期中考试\n5. 研究spack使用\n6. 学习cuda编程\n7. 补作业\n","source":"_posts/12月16-17日工作记录.md","raw":"---\ntitle: 12月16-17日工作记录\ndate: 2023-12-17 22:26:17\ntags: [日志]\n---\n## 12月16-17日\n1. 四级考试\n2. 自学cuda,openacc,了解GPU架构知识\n3. 参加超算队启动会\n4. 大计和高数期中考试\n5. 研究spack使用\n6. 学习cuda编程\n7. 补作业\n","slug":"12月16-17日工作记录","published":1,"updated":"2025-02-23T14:27:46.747Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pv0001p22bbzg168j1","content":"

12月16-17日

    \n
  1. 四级考试
  2. \n
  3. 自学cuda,openacc,了解GPU架构知识
  4. \n
  5. 参加超算队启动会
  6. \n
  7. 大计和高数期中考试
  8. \n
  9. 研究spack使用
  10. \n
  11. 学习cuda编程
  12. \n
  13. 补作业
  14. \n
\n","excerpt":"","more":"

12月16-17日

    \n
  1. 四级考试
  2. \n
  3. 自学cuda,openacc,了解GPU架构知识
  4. \n
  5. 参加超算队启动会
  6. \n
  7. 大计和高数期中考试
  8. \n
  9. 研究spack使用
  10. \n
  11. 学习cuda编程
  12. \n
  13. 补作业
  14. \n
\n"},{"title":"12月19日工作记录","date":"2023-12-19T13:59:47.000Z","_content":"## 12月18日\n1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;\n2. 学习cuda编程.\n","source":"_posts/12月19日工作记录.md","raw":"---\ntitle: 12月19日工作记录\ndate: 2023-12-19 21:59:47\ntags: [日志]\n---\n## 12月18日\n1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;\n2. 学习cuda编程.\n","slug":"12月19日工作记录","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pw0002p22bg7e11agp","content":"

12月18日

    \n
  1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;
  2. \n
  3. 学习cuda编程.
  4. \n
\n","excerpt":"","more":"

12月18日

    \n
  1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;
  2. \n
  3. 学习cuda编程.
  4. \n
\n"},{"title":"12月18日工作记录","date":"2023-12-18T13:57:34.000Z","_content":"## 12月18日\n1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;\n2. 协助Neko组完成任务;\n3. 找出spack存在网络原因无法下载时的手动解决方案.","source":"_posts/12月18日工作记录.md","raw":"---\ntitle: 12月18日工作记录\ndate: 2023-12-18 21:57:34\ntags: [日志]\n---\n## 12月18日\n1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;\n2. 协助Neko组完成任务;\n3. 找出spack存在网络原因无法下载时的手动解决方案.","slug":"12月18日工作记录","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0py0004p22ba4hiaw5j","content":"

12月18日

    \n
  1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;
  2. \n
  3. 协助Neko组完成任务;
  4. \n
  5. 找出spack存在网络原因无法下载时的手动解决方案.
  6. \n
\n","excerpt":"","more":"

12月18日

    \n
  1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;
  2. \n
  3. 协助Neko组完成任务;
  4. \n
  5. 找出spack存在网络原因无法下载时的手动解决方案.
  6. \n
\n"},{"title":"12月20日工作记录","date":"2023-12-20T13:56:42.000Z","_content":"## 12月20日\n\nOpenCAEPoro 小组(黄**,梁**,程**)\n\n1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果\n\n> 优化方向基本确定为OpenMP/OpenACC并行化+cuda移植\n\n2. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求\n","source":"_posts/12月20日工作记录.md","raw":"---\ntitle: 12月20日工作记录\ndate: 2023-12-20 21:56:42\ntags: 日志\n---\n## 12月20日\n\nOpenCAEPoro 小组(黄**,梁**,程**)\n\n1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果\n\n> 优化方向基本确定为OpenMP/OpenACC并行化+cuda移植\n\n2. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求\n","slug":"12月20日工作记录","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0py0005p22bc6um14kc","content":"

12月20日

OpenCAEPoro 小组(黄,梁,程**)

\n
    \n
  1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果
  2. \n
\n
\n

优化方向基本确定为OpenMP/OpenACC并行化+cuda移植

\n
\n
    \n
  1. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求
  2. \n
\n","excerpt":"","more":"

12月20日

OpenCAEPoro 小组(黄,梁,程**)

\n
    \n
  1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果
  2. \n
\n
\n

优化方向基本确定为OpenMP/OpenACC并行化+cuda移植

\n
\n
    \n
  1. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求
  2. \n
\n"},{"title":"12月28日进度报告","date":"2023-12-28T15:22:13.000Z","_content":"## 12月28日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果\n2. 继续学习openacc及cuda相关知识\n3. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备\n","source":"_posts/12月28日进度报告.md","raw":"---\ntitle: 12月28日进度报告\ndate: 2023-12-28 23:22:13\ntags: 日志\n---\n## 12月28日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果\n2. 继续学习openacc及cuda相关知识\n3. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备\n","slug":"12月28日进度报告","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0py0006p22bg7b6evz0","content":"

12月28日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果
  2. \n
  3. 继续学习openacc及cuda相关知识
  4. \n
  5. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备
  6. \n
\n","excerpt":"","more":"

12月28日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果
  2. \n
  3. 继续学习openacc及cuda相关知识
  4. \n
  5. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备
  6. \n
\n"},{"title":"12月30-31日进度报告","date":"2023-12-30T16:07:09.000Z","_content":"## 12月30-31日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;\n2. 收集运行数据用于proposal绘制图表;\n3. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.\n","source":"_posts/12月31日进度报告.md","raw":"---\ntitle: 12月30-31日进度报告\ndate: 2023-12-31 00:07:09\ntags: 日志\n---\n## 12月30-31日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;\n2. 收集运行数据用于proposal绘制图表;\n3. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.\n","slug":"12月31日进度报告","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pz0009p22bgrxx8ce1","content":"

12月30-31日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;
  2. \n
  3. 收集运行数据用于proposal绘制图表;
  4. \n
  5. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.
  6. \n
\n","excerpt":"","more":"

12月30-31日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;
  2. \n
  3. 收集运行数据用于proposal绘制图表;
  4. \n
  5. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.
  6. \n
\n"},{"title":"小满随笔——决断","date":"2025-05-21T11:59:21.000Z","_content":"\n
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。\n\n辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。\n\n小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。\n\n生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。\n\n因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。\n\n2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。\n\n*“回首向来萧瑟处,归去,也无风雨也无晴!”*\n","source":"_posts/2025-5-21.md","raw":"---\ntitle: 小满随笔——决断\ndate: 2025-05-21 19:59:21\ntags: 日志\n---\n\n
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。\n\n辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。\n\n小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。\n\n生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。\n\n因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。\n\n2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。\n\n*“回首向来萧瑟处,归去,也无风雨也无晴!”*\n","slug":"2025-5-21","published":1,"updated":"2025-05-21T13:34:43.639Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pz000bp22bbjfv42c1","content":"
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n

我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。

\n

辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。

\n

小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。

\n

生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。

\n

因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。

\n

2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。

\n

“回首向来萧瑟处,归去,也无风雨也无晴!”

\n","excerpt":"","more":"
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n

我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。

\n

辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。

\n

小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。

\n

生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。

\n

因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。

\n

2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。

\n

“回首向来萧瑟处,归去,也无风雨也无晴!”

\n"},{"title":"博客更新记录","date":"2024-11-04T15:18:02.000Z","_content":"\n- 博客主题更新为 `Fluid` 主题,原主题为 `Next`\n- 更新了访问地址为 `https://blog.hifuu.ink`\n- 新增了 `About` 页面\n- 新增了 `友链` 页面\n- 完善页面布局\n","source":"_posts/BlogUpdate.md","raw":"---\ntitle: 博客更新记录\ndate: 2024-11-04 23:18:02\ntags: 日志\ncategories: 更新\n---\n\n- 博客主题更新为 `Fluid` 主题,原主题为 `Next`\n- 更新了访问地址为 `https://blog.hifuu.ink`\n- 新增了 `About` 页面\n- 新增了 `友链` 页面\n- 完善页面布局\n","slug":"BlogUpdate","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q0000ep22b165ba4w7","content":"
    \n
  • 博客主题更新为 Fluid 主题,原主题为 Next
  • \n
  • 更新了访问地址为 https://blog.hifuu.ink
  • \n
  • 新增了 About 页面
  • \n
  • 新增了 友链 页面
  • \n
  • 完善页面布局
  • \n
\n","excerpt":"","more":"
    \n
  • 博客主题更新为 Fluid 主题,原主题为 Next
  • \n
  • 更新了访问地址为 https://blog.hifuu.ink
  • \n
  • 新增了 About 页面
  • \n
  • 新增了 友链 页面
  • \n
  • 完善页面布局
  • \n
\n"},{"title":"Welcome to CGH0S7's Blog","date":"2023-12-06T08:33:30.000Z","_content":"\nHello World !\n","source":"_posts/CGH0S7-s-Blog.md","raw":"---\ntitle: Welcome to CGH0S7's Blog \ndate: 2023-12-06 16:33:30\ntags: TEST\n---\n\nHello World !\n","slug":"CGH0S7-s-Blog","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q0000gp22b315z7q3g","content":"

Hello World !

\n","excerpt":"","more":"

Hello World !

\n"},{"title":"Gentle Jena","date":"2024-10-30T14:11:14.000Z","_content":"\n很喜欢的一首曲子\n顺便测试一下视频上传\n以后随缘更新各种乱七八糟的东西。。\n\n\n","source":"_posts/GentleJena.md","raw":"---\ntitle: Gentle Jena\ndate: 2024-10-30 22:11:14\ntags: 音乐\ncategories: Rearrangement\n---\n\n很喜欢的一首曲子\n顺便测试一下视频上传\n以后随缘更新各种乱七八糟的东西。。\n\n\n","slug":"GentleJena","published":1,"updated":"2025-02-23T17:14:31.930Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q1000jp22ba8qr4jxp","content":"

很喜欢的一首曲子
顺便测试一下视频上传
以后随缘更新各种乱七八糟的东西。。

\n\n","excerpt":"","more":"

很喜欢的一首曲子
顺便测试一下视频上传
以后随缘更新各种乱七八糟的东西。。

\n\n"},{"title":"Vocaloid调教-晴天(洛天依V4)","date":"2024-11-04T13:52:59.000Z","_content":"\n其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。\n\n“故事的小黄花,从出生那年就飘着...”\n\n{% raw %}\n\n{% endraw %}\n\n","source":"_posts/Vocaloid调教-晴天.md","raw":"---\ntitle: Vocaloid调教-晴天(洛天依v4)\ndate: 2024-11-04 21:52:59\ntags: [Vocaloid, 音乐]\ncategories: [Vocaloid]\n---\n\n其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。\n\n“故事的小黄花,从出生那年就飘着...”\n\n{% raw %}\n\n{% endraw %}\n\n","slug":"Vocaloid调教-晴天","published":1,"updated":"2025-02-25T00:19:05.940Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q1000mp22b0a2hee98","content":"

其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。

\n

“故事的小黄花,从出生那年就飘着…”

\n\n\n\n\n","excerpt":"","more":"

其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。

\n

“故事的小黄花,从出生那年就飘着…”

\n\n\n\n\n"},{"title":"Archlinux的KDE Plasma优先启用Nvidia独立显卡和混合显卡配置指北","date":"2024-11-06T02:02:04.000Z","_content":"本文将介绍在 **X11** 和 **Wayland** 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。**首先,请确保您已经正确安装了 Nvidia 驱动**(如果非 Mainline 内核,请使用 `nvidia-dkms` 或 `nvidia-open-dkms` 版本)。\n\n![Nvidia设置示意图](/images/5364bba6d035326e82c53504dd53e7c2454454985.png)\n\n### 适用系统\n\n对于 **CachyOS** 或 **EndeavourOS** 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:\n\n- Nvidia 驱动已安装,`nvidia-smi` 输出正常\n- KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显\n- 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象\n\n这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。\n\n---\n\n## 配置 X11 下的 Nvidia 显卡优先\n\n可以通过配置 `/etc/X11/xorg.conf` 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:\n\n```bash\nsudo nvidia-xconfig --prime\n```\n\n该命令会根据硬件情况自动生成配置文件。执行后 **重新登录会话** 即可生效(即使是 Wayland 用户也可以执行一次此命令)。\n\n![X11 Nvidia配置](/images/1613f5602b203b38230f19699deb0219454454985.png)\n\n---\n\n## 配置 Wayland 下的 Nvidia 显卡优先\n\n在 Wayland 下优先启用 Nvidia 显卡的步骤如下:\n\n1. 编辑 **GRUB 配置**文件:\n\n 打开 `/etc/default/grub` 文件,在 `GRUB_CMDLINE_LINUX_DEFAULT=\"\"` 中添加 `nvidia_drm.modeset=1`:\n\n ```bash\n GRUB_CMDLINE_LINUX_DEFAULT=\"nvidia_drm.modeset=1\"\n ```\n\n2. 重新生成 grub 配置:\n\n ```bash\n sudo grub-mkconfig -o /boot/grub/grub.cfg\n ```\n\n3. 配置 **Plasma 环境**文件:\n\n 在 `~/.config/plasma-workspace/env/nvidia.sh` 中写入以下内容:\n\n ```bash\n #!/bin/bash \n export __NV_PRIME_RENDER_OFFLOAD=1 \n export __GLX_VENDOR_LIBRARY_NAME=nvidia\n ```\n\n4. 保存并重启电脑,即可生效。\n\n![Wayland Nvidia配置](/images/b2054bbaf6197624d38cc2007d885fd1454454985.png)\n\n---\n\n## I+N 混合显卡方案\n\n如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。\n\n### 配置步骤\n\n1. 打开程序的 `.desktop` 启动文件:\n\n 位置可能在 `/usr/share/applications` 或 `~/.local/share/applications` 中。\n\n2. 在 `Exec=` 后添加 `prime-run` 参数。例如:\n\n ```text\n Exec=prime-run <程序启动命令>\n ```\n\n ![混合显卡配置示意图](/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png)\n\n### Vim 快捷配置\n\n如果使用 Vim,可以使用以下快捷键快速批量替换 `Exec=` 为 `Exec=prime-run`:\n\n```vim\nv -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter\n```\n\n---\n\n## 让 Plasma 桌面也使用独显\n\n如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:\n\n```bash\n#!/bin/bash \nexport __GLX_VENDOR_LIBRARY_NAME=nvidia\n```\n\n这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。\n\n---\n\n希望以上经验能为有此需求的用户提供参考帮助。\n","source":"_posts/arch-nvidia.md","raw":"---\ntitle: Archlinux的KDE Plasma优先启用Nvidia独立显卡和混合显卡配置指北\ndate: 2024-11-06 10:02:04\ntags: 技术\ncategories: [技术分享]\n---\n本文将介绍在 **X11** 和 **Wayland** 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。**首先,请确保您已经正确安装了 Nvidia 驱动**(如果非 Mainline 内核,请使用 `nvidia-dkms` 或 `nvidia-open-dkms` 版本)。\n\n![Nvidia设置示意图](/images/5364bba6d035326e82c53504dd53e7c2454454985.png)\n\n### 适用系统\n\n对于 **CachyOS** 或 **EndeavourOS** 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:\n\n- Nvidia 驱动已安装,`nvidia-smi` 输出正常\n- KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显\n- 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象\n\n这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。\n\n---\n\n## 配置 X11 下的 Nvidia 显卡优先\n\n可以通过配置 `/etc/X11/xorg.conf` 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:\n\n```bash\nsudo nvidia-xconfig --prime\n```\n\n该命令会根据硬件情况自动生成配置文件。执行后 **重新登录会话** 即可生效(即使是 Wayland 用户也可以执行一次此命令)。\n\n![X11 Nvidia配置](/images/1613f5602b203b38230f19699deb0219454454985.png)\n\n---\n\n## 配置 Wayland 下的 Nvidia 显卡优先\n\n在 Wayland 下优先启用 Nvidia 显卡的步骤如下:\n\n1. 编辑 **GRUB 配置**文件:\n\n 打开 `/etc/default/grub` 文件,在 `GRUB_CMDLINE_LINUX_DEFAULT=\"\"` 中添加 `nvidia_drm.modeset=1`:\n\n ```bash\n GRUB_CMDLINE_LINUX_DEFAULT=\"nvidia_drm.modeset=1\"\n ```\n\n2. 重新生成 grub 配置:\n\n ```bash\n sudo grub-mkconfig -o /boot/grub/grub.cfg\n ```\n\n3. 配置 **Plasma 环境**文件:\n\n 在 `~/.config/plasma-workspace/env/nvidia.sh` 中写入以下内容:\n\n ```bash\n #!/bin/bash \n export __NV_PRIME_RENDER_OFFLOAD=1 \n export __GLX_VENDOR_LIBRARY_NAME=nvidia\n ```\n\n4. 保存并重启电脑,即可生效。\n\n![Wayland Nvidia配置](/images/b2054bbaf6197624d38cc2007d885fd1454454985.png)\n\n---\n\n## I+N 混合显卡方案\n\n如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。\n\n### 配置步骤\n\n1. 打开程序的 `.desktop` 启动文件:\n\n 位置可能在 `/usr/share/applications` 或 `~/.local/share/applications` 中。\n\n2. 在 `Exec=` 后添加 `prime-run` 参数。例如:\n\n ```text\n Exec=prime-run <程序启动命令>\n ```\n\n ![混合显卡配置示意图](/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png)\n\n### Vim 快捷配置\n\n如果使用 Vim,可以使用以下快捷键快速批量替换 `Exec=` 为 `Exec=prime-run`:\n\n```vim\nv -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter\n```\n\n---\n\n## 让 Plasma 桌面也使用独显\n\n如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:\n\n```bash\n#!/bin/bash \nexport __GLX_VENDOR_LIBRARY_NAME=nvidia\n```\n\n这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。\n\n---\n\n希望以上经验能为有此需求的用户提供参考帮助。\n","slug":"arch-nvidia","published":1,"updated":"2025-02-02T11:21:35.673Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q2000op22b0gq70sf7","content":"

本文将介绍在 X11Wayland 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。首先,请确保您已经正确安装了 Nvidia 驱动(如果非 Mainline 内核,请使用 nvidia-dkmsnvidia-open-dkms 版本)。

\n

\"Nvidia设置示意图\"

\n

适用系统

对于 CachyOSEndeavourOS 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:

\n
    \n
  • Nvidia 驱动已安装,nvidia-smi 输出正常
  • \n
  • KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显
  • \n
  • 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象
  • \n
\n

这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。

\n
\n

配置 X11 下的 Nvidia 显卡优先

可以通过配置 /etc/X11/xorg.conf 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:

\n
1
sudo nvidia-xconfig --prime
\n\n

该命令会根据硬件情况自动生成配置文件。执行后 重新登录会话 即可生效(即使是 Wayland 用户也可以执行一次此命令)。

\n

\"X11

\n
\n

配置 Wayland 下的 Nvidia 显卡优先

在 Wayland 下优先启用 Nvidia 显卡的步骤如下:

\n
    \n
  1. 编辑 GRUB 配置文件:

    \n

    打开 /etc/default/grub 文件,在 GRUB_CMDLINE_LINUX_DEFAULT="" 中添加 nvidia_drm.modeset=1

    \n
    1
    GRUB_CMDLINE_LINUX_DEFAULT="nvidia_drm.modeset=1"
    \n
  2. \n
  3. 重新生成 grub 配置:

    \n
    1
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    \n
  4. \n
  5. 配置 Plasma 环境文件:

    \n

    ~/.config/plasma-workspace/env/nvidia.sh 中写入以下内容:

    \n
    1
    2
    3
    #!/bin/bash 
    export __NV_PRIME_RENDER_OFFLOAD=1
    export __GLX_VENDOR_LIBRARY_NAME=nvidia
    \n
  6. \n
  7. 保存并重启电脑,即可生效。

    \n
  8. \n
\n

\"Wayland

\n
\n

I+N 混合显卡方案

如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。

\n

配置步骤

    \n
  1. 打开程序的 .desktop 启动文件:

    \n

    位置可能在 /usr/share/applications~/.local/share/applications 中。

    \n
  2. \n
  3. Exec= 后添加 prime-run 参数。例如:

    \n
    1
    Exec=prime-run <程序启动命令>
    \n\n

    \"混合显卡配置示意图\"

    \n
  4. \n
\n

Vim 快捷配置

如果使用 Vim,可以使用以下快捷键快速批量替换 Exec=Exec=prime-run

\n
1
v -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter
\n\n
\n

让 Plasma 桌面也使用独显

如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:

\n
1
2
#!/bin/bash 
export __GLX_VENDOR_LIBRARY_NAME=nvidia
\n\n

这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。

\n
\n

希望以上经验能为有此需求的用户提供参考帮助。

\n","excerpt":"","more":"

本文将介绍在 X11Wayland 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。首先,请确保您已经正确安装了 Nvidia 驱动(如果非 Mainline 内核,请使用 nvidia-dkmsnvidia-open-dkms 版本)。

\n

\"Nvidia设置示意图\"

\n

适用系统

对于 CachyOSEndeavourOS 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:

\n
    \n
  • Nvidia 驱动已安装,nvidia-smi 输出正常
  • \n
  • KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显
  • \n
  • 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象
  • \n
\n

这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。

\n
\n

配置 X11 下的 Nvidia 显卡优先

可以通过配置 /etc/X11/xorg.conf 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:

\n
1
sudo nvidia-xconfig --prime
\n\n

该命令会根据硬件情况自动生成配置文件。执行后 重新登录会话 即可生效(即使是 Wayland 用户也可以执行一次此命令)。

\n

\"X11

\n
\n

配置 Wayland 下的 Nvidia 显卡优先

在 Wayland 下优先启用 Nvidia 显卡的步骤如下:

\n
    \n
  1. 编辑 GRUB 配置文件:

    \n

    打开 /etc/default/grub 文件,在 GRUB_CMDLINE_LINUX_DEFAULT="" 中添加 nvidia_drm.modeset=1

    \n
    1
    GRUB_CMDLINE_LINUX_DEFAULT="nvidia_drm.modeset=1"
    \n
  2. \n
  3. 重新生成 grub 配置:

    \n
    1
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    \n
  4. \n
  5. 配置 Plasma 环境文件:

    \n

    ~/.config/plasma-workspace/env/nvidia.sh 中写入以下内容:

    \n
    1
    2
    3
    #!/bin/bash 
    export __NV_PRIME_RENDER_OFFLOAD=1
    export __GLX_VENDOR_LIBRARY_NAME=nvidia
    \n
  6. \n
  7. 保存并重启电脑,即可生效。

    \n
  8. \n
\n

\"Wayland

\n
\n

I+N 混合显卡方案

如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。

\n

配置步骤

    \n
  1. 打开程序的 .desktop 启动文件:

    \n

    位置可能在 /usr/share/applications~/.local/share/applications 中。

    \n
  2. \n
  3. Exec= 后添加 prime-run 参数。例如:

    \n
    1
    Exec=prime-run <程序启动命令>
    \n\n

    \"混合显卡配置示意图\"

    \n
  4. \n
\n

Vim 快捷配置

如果使用 Vim,可以使用以下快捷键快速批量替换 Exec=Exec=prime-run

\n
1
v -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter
\n\n
\n

让 Plasma 桌面也使用独显

如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:

\n
1
2
#!/bin/bash 
export __GLX_VENDOR_LIBRARY_NAME=nvidia
\n\n

这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。

\n
\n

希望以上经验能为有此需求的用户提供参考帮助。

\n"},{"title":"Archlinux问题记录","date":"2025-03-10T14:47:08.000Z","_content":"\n前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~\n\n---\n\n### 1. 显卡功耗上限解锁\n**问题现象** \n使用 `nvidia-smi` 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:\n\n```bash\nnvidia-smi # 输出显示 Power Limit: 55.00 W\n```\n\n**解决方案** \n启用 NVIDIA 动态功耗管理服务即可:\n```bash\nsudo systemctl enable --now nvidia-powerd\n```\n\n---\n\n### 2. Steam Proton 输入失效\n**问题描述** \n使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。 \n⚠️ 经排查发现是 Wayland 协议兼容性问题导致。\n\n**解决方案** \n在 Steam 游戏启动选项中加入环境变量禁用 Wayland:\n```bash\nPROTON_ENABLE_WAYLAND=0 %command%\n```\n\n---\n\n","source":"_posts/archlinux-game-fix.md","raw":"---\ntitle: Archlinux问题记录\ndate: 2025-03-10 22:47:08\ntags: [生活, Archlinux]\n---\n\n前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~\n\n---\n\n### 1. 显卡功耗上限解锁\n**问题现象** \n使用 `nvidia-smi` 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:\n\n```bash\nnvidia-smi # 输出显示 Power Limit: 55.00 W\n```\n\n**解决方案** \n启用 NVIDIA 动态功耗管理服务即可:\n```bash\nsudo systemctl enable --now nvidia-powerd\n```\n\n---\n\n### 2. Steam Proton 输入失效\n**问题描述** \n使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。 \n⚠️ 经排查发现是 Wayland 协议兼容性问题导致。\n\n**解决方案** \n在 Steam 游戏启动选项中加入环境变量禁用 Wayland:\n```bash\nPROTON_ENABLE_WAYLAND=0 %command%\n```\n\n---\n\n","slug":"archlinux-game-fix","published":1,"updated":"2025-03-10T14:54:16.788Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q2000rp22bgtkodqs6","content":"

前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~

\n
\n

1. 显卡功耗上限解锁

问题现象
使用 nvidia-smi 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:

\n
1
nvidia-smi  # 输出显示 Power Limit: 55.00 W
\n\n

解决方案
启用 NVIDIA 动态功耗管理服务即可:

\n
1
sudo systemctl enable --now nvidia-powerd
\n\n
\n

2. Steam Proton 输入失效

问题描述
使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。
⚠️ 经排查发现是 Wayland 协议兼容性问题导致。

\n

解决方案
在 Steam 游戏启动选项中加入环境变量禁用 Wayland:

\n
1
PROTON_ENABLE_WAYLAND=0 %command%
\n\n
\n","excerpt":"","more":"

前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~

\n
\n

1. 显卡功耗上限解锁

问题现象
使用 nvidia-smi 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:

\n
1
nvidia-smi  # 输出显示 Power Limit: 55.00 W
\n\n

解决方案
启用 NVIDIA 动态功耗管理服务即可:

\n
1
sudo systemctl enable --now nvidia-powerd
\n\n
\n

2. Steam Proton 输入失效

问题描述
使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。
⚠️ 经排查发现是 Wayland 协议兼容性问题导致。

\n

解决方案
在 Steam 游戏启动选项中加入环境变量禁用 Wayland:

\n
1
PROTON_ENABLE_WAYLAND=0 %command%
\n\n
\n"},{"title":"Archlinux KDE体验优化总结","date":"2025-02-02T10:43:26.000Z","_content":"\n打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验\n\n本文章长期更新\n\n------\n\n## 更换CachyOS优化仓库\n\n![CachyOS Logo](https://wiki.cachyos.org/_astro/logo.DVTdAJi6.svg) \n通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。\n\n---\n\n### ▎前置准备\n**⚠️ 兼容性警告** \n1. 可以先通过命令`/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-`来查看你的处理器支持等级。\n2. 注意添加 `cachyos` 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性) \n ```bash\n cachyos-v3 # AVX2 优化\n cachyos-v4 # AVX512 优化\n cachyos-extra # 扩展软件包\n ```\n3. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以[点击这里](https://discuss.cachyos.org/t/zen-4-5-optimized-repository-testing/713/7)查看如何部署。\n\n---\n\n### ▎仓库配置流程\n#### ▶ 自动配置脚本\n```bash\n# 下载配置工具\ncurl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz\ntar xvf cachyos-repo.tar.xz && cd cachyos-repo\n\n# 执行自动配置(自动检测 CPU 指令集)\nsudo ./cachyos-repo.sh\n```\n📌 脚本特性: \n- 自动备份 `/etc/pacman.conf` \n- 智能匹配最优指令集版本 (v3/v4) \n- 支持 x86_64 和 aarch64 架构 \n\n#### ▶ 手动配置方式\n1. 编辑 pacman.conf\n```ini\n# 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)\n[cachyos-v3]\nSigLevel = Optional TrustAll\nInclude = /etc/pacman.d/cachyos-v3\n```\n\n2. ✅同步仓库数据库\n```bash\nsudo pacman -Syu\n```\n\n---\n\n### ▎仓库卸载方法\n#### ▶ 自动卸载\n```bash\ncd cachyos-repo\nsudo ./cachyos-repo.sh --remove\n```\n\n#### ▶ 手动卸载\n1. 删除 pacman.conf 中的 cachyos 仓库段\n2. 移除配置文件\n```bash\nsudo rm -rf /etc/pacman.d/cachyos*\n```\n---\n\n## 内核更换\n\n## KDE 配置\n\n\n\n","source":"_posts/archlinux-optimization.md","raw":"---\ntitle: Archlinux KDE体验优化总结\ndate: 2025-02-02 18:43:26\ntags: [Archlinux, 系统优化, 技术分享]\n---\n\n打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验\n\n本文章长期更新\n\n------\n\n## 更换CachyOS优化仓库\n\n![CachyOS Logo](https://wiki.cachyos.org/_astro/logo.DVTdAJi6.svg) \n通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。\n\n---\n\n### ▎前置准备\n**⚠️ 兼容性警告** \n1. 可以先通过命令`/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-`来查看你的处理器支持等级。\n2. 注意添加 `cachyos` 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性) \n ```bash\n cachyos-v3 # AVX2 优化\n cachyos-v4 # AVX512 优化\n cachyos-extra # 扩展软件包\n ```\n3. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以[点击这里](https://discuss.cachyos.org/t/zen-4-5-optimized-repository-testing/713/7)查看如何部署。\n\n---\n\n### ▎仓库配置流程\n#### ▶ 自动配置脚本\n```bash\n# 下载配置工具\ncurl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz\ntar xvf cachyos-repo.tar.xz && cd cachyos-repo\n\n# 执行自动配置(自动检测 CPU 指令集)\nsudo ./cachyos-repo.sh\n```\n📌 脚本特性: \n- 自动备份 `/etc/pacman.conf` \n- 智能匹配最优指令集版本 (v3/v4) \n- 支持 x86_64 和 aarch64 架构 \n\n#### ▶ 手动配置方式\n1. 编辑 pacman.conf\n```ini\n# 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)\n[cachyos-v3]\nSigLevel = Optional TrustAll\nInclude = /etc/pacman.d/cachyos-v3\n```\n\n2. ✅同步仓库数据库\n```bash\nsudo pacman -Syu\n```\n\n---\n\n### ▎仓库卸载方法\n#### ▶ 自动卸载\n```bash\ncd cachyos-repo\nsudo ./cachyos-repo.sh --remove\n```\n\n#### ▶ 手动卸载\n1. 删除 pacman.conf 中的 cachyos 仓库段\n2. 移除配置文件\n```bash\nsudo rm -rf /etc/pacman.d/cachyos*\n```\n---\n\n## 内核更换\n\n## KDE 配置\n\n\n\n","slug":"archlinux-optimization","published":1,"updated":"2025-03-10T15:07:26.618Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q3000up22bhurb7l9n","content":"

打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验

\n

本文章长期更新

\n
\n

更换CachyOS优化仓库

\"CachyOS
通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。

\n
\n

▎前置准备

⚠️ 兼容性警告

\n
    \n
  1. 可以先通过命令/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-来查看你的处理器支持等级。
  2. \n
  3. 注意添加 cachyos 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性)
    1
    2
    3
    cachyos-v3    # AVX2 优化
    cachyos-v4 # AVX512 优化
    cachyos-extra # 扩展软件包
  4. \n
  5. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以点击这里查看如何部署。
  6. \n
\n
\n

▎仓库配置流程

▶ 自动配置脚本

1
2
3
4
5
6
# 下载配置工具
curl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz
tar xvf cachyos-repo.tar.xz && cd cachyos-repo

# 执行自动配置(自动检测 CPU 指令集)
sudo ./cachyos-repo.sh
\n

📌 脚本特性:

\n
    \n
  • 自动备份 /etc/pacman.conf
  • \n
  • 智能匹配最优指令集版本 (v3/v4)
  • \n
  • 支持 x86_64 和 aarch64 架构
  • \n
\n

▶ 手动配置方式

    \n
  1. 编辑 pacman.conf

    \n
    1
    2
    3
    4
    # 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)
    [cachyos-v3]
    SigLevel = Optional TrustAll
    Include = /etc/pacman.d/cachyos-v3
    \n
  2. \n
  3. ✅同步仓库数据库

    \n
    1
    sudo pacman -Syu
  4. \n
\n
\n

▎仓库卸载方法

▶ 自动卸载

1
2
cd cachyos-repo
sudo ./cachyos-repo.sh --remove
\n\n

▶ 手动卸载

    \n
  1. 删除 pacman.conf 中的 cachyos 仓库段
  2. \n
  3. 移除配置文件
    1
    sudo rm -rf /etc/pacman.d/cachyos*
  4. \n
\n
\n

内核更换

KDE 配置

","excerpt":"","more":"

打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验

\n

本文章长期更新

\n
\n

更换CachyOS优化仓库

\"CachyOS
通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。

\n
\n

▎前置准备

⚠️ 兼容性警告

\n
    \n
  1. 可以先通过命令/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-来查看你的处理器支持等级。
  2. \n
  3. 注意添加 cachyos 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性)
    1
    2
    3
    cachyos-v3    # AVX2 优化
    cachyos-v4 # AVX512 优化
    cachyos-extra # 扩展软件包
  4. \n
  5. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以点击这里查看如何部署。
  6. \n
\n
\n

▎仓库配置流程

▶ 自动配置脚本

1
2
3
4
5
6
# 下载配置工具
curl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz
tar xvf cachyos-repo.tar.xz && cd cachyos-repo

# 执行自动配置(自动检测 CPU 指令集)
sudo ./cachyos-repo.sh
\n

📌 脚本特性:

\n
    \n
  • 自动备份 /etc/pacman.conf
  • \n
  • 智能匹配最优指令集版本 (v3/v4)
  • \n
  • 支持 x86_64 和 aarch64 架构
  • \n
\n

▶ 手动配置方式

    \n
  1. 编辑 pacman.conf

    \n
    1
    2
    3
    4
    # 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)
    [cachyos-v3]
    SigLevel = Optional TrustAll
    Include = /etc/pacman.d/cachyos-v3
    \n
  2. \n
  3. ✅同步仓库数据库

    \n
    1
    sudo pacman -Syu
  4. \n
\n
\n

▎仓库卸载方法

▶ 自动卸载

1
2
cd cachyos-repo
sudo ./cachyos-repo.sh --remove
\n\n

▶ 手动卸载

    \n
  1. 删除 pacman.conf 中的 cachyos 仓库段
  2. \n
  3. 移除配置文件
    1
    sudo rm -rf /etc/pacman.d/cachyos*
  4. \n
\n
\n

内核更换

KDE 配置

"},{"title":"使用Clonezilla备份和克隆系统","date":"2025-02-23T13:40:03.000Z","_content":"![Clonezilla官网](/images/clonezilla.png)\n[Clonezilla](https://clonezilla.org/)是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。\n\n---\n### **零.事前准备**:\n - 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。\n - 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。\n\n\n### **一.备份镜像到硬盘(Device-to-Image)**\n这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。\n\n#### **步骤说明**:\n2. **启动Clonezilla**:\n - 插入U盘,重启电脑并从U盘启动。\n - 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。\n\n3. **选择备份模式**:\n ```plaintext\n Choose mode: 选择 \"device-image\"(设备到镜像)\n Mount storage media: 选择 \"local_dev\"(本地存储设备)\n ```\n - 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 `/dev/sdb1`)。\n\n4. **配置备份参数**:\n - **源硬盘**:选择需要备份的硬盘(如 `/dev/sda`)。\n - **镜像存储路径**:指定目标位置(如外置硬盘的挂载目录)。\n - **镜像名称**:自定义名称(如 `2025-img-rockylinux-2-21`)。\n - **压缩选项**:默认即可,支持并行压缩加速。\n - **镜像分割**:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。\n\n5. **确认操作**:\n - 检查提示信息,输入 `y` 开始备份。\n - 完成后关机或重启。\n\n6. **镜像还原**:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。\n---\n\n### **二、直接克隆硬盘(Device-to-Device)**\n将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。\n\n#### **步骤说明**:\n1. **准备工作**:\n - 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)\n - **警告**:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!\n\n2. **启动Clonezilla**:\n - 同上,从U盘启动进入Clonezilla界面。\n\n3. **选择克隆模式**:\n ```plaintext\n Choose mode: 选择 \"device-device\"(设备到设备)\n ```\n\n4. **选择硬盘**:\n - **母碟硬盘**:选择原始硬盘(如 `/dev/sda`)。\n - **目标硬盘**:选择新硬盘(如 `/dev/sdb`)。\n\n5. **克隆选项**:\n 需要进入专家模式才能看到,一般直接新手模式默认即可。\n\n6. **执行克隆**:\n - 确认提示信息后输入 `y`,等待完成。\n - 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。\n\n---\n### **两种模式对比**:\n| **模式** | 特点 | \n|----------------|---------------------------|\n| 备份镜像 | 方便多机部署也可以用于留档|\n| 直接克隆 | 换硬盘快速迁移无需恢复过程|\n---\n\n### **Btrfs务必注意**:\n对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行`sudo btrfs balance start --full-balance /`来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。\n\n","source":"_posts/clonezilla.md","raw":"---\ntitle: 使用Clonezilla备份和克隆系统\ndate: 2025-02-23 21:40:03\ntags: 技术分享\n---\n![Clonezilla官网](/images/clonezilla.png)\n[Clonezilla](https://clonezilla.org/)是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。\n\n---\n### **零.事前准备**:\n - 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。\n - 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。\n\n\n### **一.备份镜像到硬盘(Device-to-Image)**\n这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。\n\n#### **步骤说明**:\n2. **启动Clonezilla**:\n - 插入U盘,重启电脑并从U盘启动。\n - 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。\n\n3. **选择备份模式**:\n ```plaintext\n Choose mode: 选择 \"device-image\"(设备到镜像)\n Mount storage media: 选择 \"local_dev\"(本地存储设备)\n ```\n - 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 `/dev/sdb1`)。\n\n4. **配置备份参数**:\n - **源硬盘**:选择需要备份的硬盘(如 `/dev/sda`)。\n - **镜像存储路径**:指定目标位置(如外置硬盘的挂载目录)。\n - **镜像名称**:自定义名称(如 `2025-img-rockylinux-2-21`)。\n - **压缩选项**:默认即可,支持并行压缩加速。\n - **镜像分割**:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。\n\n5. **确认操作**:\n - 检查提示信息,输入 `y` 开始备份。\n - 完成后关机或重启。\n\n6. **镜像还原**:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。\n---\n\n### **二、直接克隆硬盘(Device-to-Device)**\n将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。\n\n#### **步骤说明**:\n1. **准备工作**:\n - 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)\n - **警告**:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!\n\n2. **启动Clonezilla**:\n - 同上,从U盘启动进入Clonezilla界面。\n\n3. **选择克隆模式**:\n ```plaintext\n Choose mode: 选择 \"device-device\"(设备到设备)\n ```\n\n4. **选择硬盘**:\n - **母碟硬盘**:选择原始硬盘(如 `/dev/sda`)。\n - **目标硬盘**:选择新硬盘(如 `/dev/sdb`)。\n\n5. **克隆选项**:\n 需要进入专家模式才能看到,一般直接新手模式默认即可。\n\n6. **执行克隆**:\n - 确认提示信息后输入 `y`,等待完成。\n - 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。\n\n---\n### **两种模式对比**:\n| **模式** | 特点 | \n|----------------|---------------------------|\n| 备份镜像 | 方便多机部署也可以用于留档|\n| 直接克隆 | 换硬盘快速迁移无需恢复过程|\n---\n\n### **Btrfs务必注意**:\n对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行`sudo btrfs balance start --full-balance /`来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。\n\n","slug":"clonezilla","published":1,"updated":"2025-02-23T14:12:10.654Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q3000xp22bd6qo3kl3","content":"

\"Clonezilla官网\"
Clonezilla是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。

\n
\n

零.事前准备

    \n
  • 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。
  • \n
  • 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。
  • \n
\n

一.备份镜像到硬盘(Device-to-Image)

这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。

\n

步骤说明

    \n
  1. 启动Clonezilla

    \n
      \n
    • 插入U盘,重启电脑并从U盘启动。
    • \n
    • 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。
    • \n
    \n
  2. \n
  3. 选择备份模式

    \n
    1
    2
    Choose mode:         选择 "device-image"(设备到镜像)
    Mount storage media: 选择 "local_dev"(本地存储设备)
    \n
      \n
    • 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 /dev/sdb1)。
    • \n
    \n
  4. \n
  5. 配置备份参数

    \n
      \n
    • 源硬盘:选择需要备份的硬盘(如 /dev/sda)。
    • \n
    • 镜像存储路径:指定目标位置(如外置硬盘的挂载目录)。
    • \n
    • 镜像名称:自定义名称(如 2025-img-rockylinux-2-21)。
    • \n
    • 压缩选项:默认即可,支持并行压缩加速。
    • \n
    • 镜像分割:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。
    • \n
    \n
  6. \n
  7. 确认操作

    \n
      \n
    • 检查提示信息,输入 y 开始备份。
    • \n
    • 完成后关机或重启。
    • \n
    \n
  8. \n
  9. 镜像还原:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。

    \n
  10. \n
\n
\n

二、直接克隆硬盘(Device-to-Device)

将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。

\n

步骤说明

    \n
  1. 准备工作

    \n
      \n
    • 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)
    • \n
    • 警告:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!
    • \n
    \n
  2. \n
  3. 启动Clonezilla

    \n
      \n
    • 同上,从U盘启动进入Clonezilla界面。
    • \n
    \n
  4. \n
  5. 选择克隆模式

    \n
    1
    Choose mode:         选择 "device-device"(设备到设备)
    \n
  6. \n
  7. 选择硬盘

    \n
      \n
    • 母碟硬盘:选择原始硬盘(如 /dev/sda)。
    • \n
    • 目标硬盘:选择新硬盘(如 /dev/sdb)。
    • \n
    \n
  8. \n
  9. 克隆选项
    需要进入专家模式才能看到,一般直接新手模式默认即可。

    \n
  10. \n
  11. 执行克隆

    \n
      \n
    • 确认提示信息后输入 y,等待完成。
    • \n
    • 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。
    • \n
    \n
  12. \n
\n
\n

两种模式对比

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
模式特点
备份镜像方便多机部署也可以用于留档
直接克隆换硬盘快速迁移无需恢复过程
\n
\n

Btrfs务必注意

对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行sudo btrfs balance start --full-balance /来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。

\n","excerpt":"","more":"

\"Clonezilla官网\"
Clonezilla是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。

\n
\n

零.事前准备

    \n
  • 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。
  • \n
  • 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。
  • \n
\n

一.备份镜像到硬盘(Device-to-Image)

这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。

\n

步骤说明

    \n
  1. 启动Clonezilla

    \n
      \n
    • 插入U盘,重启电脑并从U盘启动。
    • \n
    • 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。
    • \n
    \n
  2. \n
  3. 选择备份模式

    \n
    1
    2
    Choose mode:         选择 "device-image"(设备到镜像)
    Mount storage media: 选择 "local_dev"(本地存储设备)
    \n
      \n
    • 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 /dev/sdb1)。
    • \n
    \n
  4. \n
  5. 配置备份参数

    \n
      \n
    • 源硬盘:选择需要备份的硬盘(如 /dev/sda)。
    • \n
    • 镜像存储路径:指定目标位置(如外置硬盘的挂载目录)。
    • \n
    • 镜像名称:自定义名称(如 2025-img-rockylinux-2-21)。
    • \n
    • 压缩选项:默认即可,支持并行压缩加速。
    • \n
    • 镜像分割:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。
    • \n
    \n
  6. \n
  7. 确认操作

    \n
      \n
    • 检查提示信息,输入 y 开始备份。
    • \n
    • 完成后关机或重启。
    • \n
    \n
  8. \n
  9. 镜像还原:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。

    \n
  10. \n
\n
\n

二、直接克隆硬盘(Device-to-Device)

将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。

\n

步骤说明

    \n
  1. 准备工作

    \n
      \n
    • 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)
    • \n
    • 警告:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!
    • \n
    \n
  2. \n
  3. 启动Clonezilla

    \n
      \n
    • 同上,从U盘启动进入Clonezilla界面。
    • \n
    \n
  4. \n
  5. 选择克隆模式

    \n
    1
    Choose mode:         选择 "device-device"(设备到设备)
    \n
  6. \n
  7. 选择硬盘

    \n
      \n
    • 母碟硬盘:选择原始硬盘(如 /dev/sda)。
    • \n
    • 目标硬盘:选择新硬盘(如 /dev/sdb)。
    • \n
    \n
  8. \n
  9. 克隆选项
    需要进入专家模式才能看到,一般直接新手模式默认即可。

    \n
  10. \n
  11. 执行克隆

    \n
      \n
    • 确认提示信息后输入 y,等待完成。
    • \n
    • 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。
    • \n
    \n
  12. \n
\n
\n

两种模式对比

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
模式特点
备份镜像方便多机部署也可以用于留档
直接克隆换硬盘快速迁移无需恢复过程
\n
\n

Btrfs务必注意

对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行sudo btrfs balance start --full-balance /来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。

\n"},{"title":"时隔一年再次拿起数位板能画出什么东西","date":"2024-11-04T15:47:54.000Z","_content":"\n如题,前段时间推完LOOPERS的时候有感而发对着画了张海报\n\n时隔一年,终于又拿起了数位板\n\n![LOOPERS](/images/20241027_222225.png \"LOOPERS\")\n","source":"_posts/loopers.md","raw":"---\ntitle: 时隔一年再次拿起数位板能画出什么东西\ndate: 2024-11-04 23:47:54\ntags: [板绘, 生活]\n---\n\n如题,前段时间推完LOOPERS的时候有感而发对着画了张海报\n\n时隔一年,终于又拿起了数位板\n\n![LOOPERS](/images/20241027_222225.png \"LOOPERS\")\n","slug":"loopers","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q3000zp22b76yib05t","content":"

如题,前段时间推完LOOPERS的时候有感而发对着画了张海报

\n

时隔一年,终于又拿起了数位板

\n

\"LOOPERS\"

\n","excerpt":"","more":"

如题,前段时间推完LOOPERS的时候有感而发对着画了张海报

\n

时隔一年,终于又拿起了数位板

\n

\"LOOPERS\"

\n"},{"title":"愿指引明路的苍蓝星永远为你闪耀","date":"2024-11-11T13:46:49.000Z","_content":"使用东方Project软音源THFont简单重置的MHWI主题曲\n\n雄关漫道真如铁,而今迈步从头越\n\n{% raw %}\n\n{% endraw %}\n\n","source":"_posts/mhwi.md","raw":"---\ntitle: 愿指引明路的苍蓝星永远为你闪耀\ndate: 2024-11-11 21:46:49\ntags: 音乐\ncategories: Rearrangement\n---\n使用东方Project软音源THFont简单重置的MHWI主题曲\n\n雄关漫道真如铁,而今迈步从头越\n\n{% raw %}\n\n{% endraw %}\n\n","slug":"mhwi","published":1,"updated":"2024-11-11T14:00:19.124Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q40013p22bb8qjfb28","content":"

使用东方Project软音源THFont简单重置的MHWI主题曲

\n

雄关漫道真如铁,而今迈步从头越

\n\n\n\n\n","excerpt":"","more":"

使用东方Project软音源THFont简单重置的MHWI主题曲

\n

雄关漫道真如铁,而今迈步从头越

\n\n\n\n\n"},{"title":"高地特供版CSAPP Bomb Lab全流程攻略","date":"2025-02-24T07:09:11.000Z","_content":"\n这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。\n\n笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。\n\n## **Phase_1**\n\n### **静态分析**\n\n#### **`strings`扫描**\n```bash\nstrings bomb_linux\n```\n先用strings寻找可能与`phase_1`相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。\n![strings](/images/phase1_strings.png)\n - 结果没有明文密码无法直接秒掉第一问,可惜。\n - 但是找到`GenerateRandomString`函数可能与密码生成相关。\n\n#### **用`objdump`反汇编**\n```bash\nobjdump -d bomb_linux > bomb.asm\n```\n搜索`GenerateRandomString`和`phase_1`函数的汇编代码。\n ```assembly\n 401b53 :\n 401b53: endbr64\n 401b57: push %rbp\n 401b58: mov %rsp,%rbp\n 401b5b: sub $0x20,%rsp\n 401b5f: mov %rdi,-0x18(%rbp)\n 401b63: lea -0xb(%rbp),%rax\n 401b67: mov %rax,%rdi\n 401b6a: callq 401ac1 # 调用密码生成函数\n 401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置\n 401b73: mov -0x18(%rbp),%rax\n 401b77: mov %rdx,%rsi\n 401b7a: mov %rax,%rdi\n 401b7d: callq 401c0c # 调用字符串比较函数\n 401b82: test %eax,%eax\n 401b84: je 401b8d \n 401b86: callq 401d67 # 比较失败则引爆炸弹\n ```\n - `phase_1`调用`GenerateRandomString`生成一个字符串。\n - 用户输入的字符串需要与此生成的字符串完全匹配。\n\n---\n\n### **动态调试**\n![phase_1](/images/phase1.png)\n下面是phase_1求解的完整流程:\n```lldb\nlldb bomb_linux <你的学号后六位>\n(lldb) b phase_1 # 在phase_1入口断点\n(lldb) run # 从入口开始执行\n请输入第1级的密码:114514 # 随便输入触发断点\n(lldb) b 0x401b6f # 在GenerateRandomString返回后断点\n(lldb) continue # 继续执行\n(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)\n0x7fffffffdaf5: \"mJHurpQZtY\" # 轻松拿下,这里是根据学号伪随机生成的哦\n```\n将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。\n\n---\n\n## **Phase_2**\n\n### **静态分析**\n\n这道题目还是比较一目了然的,观察`phase_2`代码不难发现其实构建了一张跳转表:\n```assembly\n0000000000401b8e :\n 401b8e:\tf3 0f 1e fa \tendbr64\n 401b92:\t55 \tpush %rbp\n 401b93:\t48 89 e5 \tmov %rsp,%rbp\n 401b96:\t48 83 ec 10 \tsub $0x10,%rsp\n 401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi\n 401ba3:\te8 05 fb ff ff \tcall 4016ad \n 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 \n 401baf:\t48 83 f8 0f \tcmp $0xf,%rax\n 401bb3:\t0f 87 16 01 00 00 \tja 401ccf \n 401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 401bc0:\t00 \n 401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>\n 401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 401bcb:\t48 98 \tcltq\n 401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>\n 401bd4:\t48 01 d0 \tadd %rdx,%rax\n 401bd7:\t3e ff e0 \tnotrack jmp *%rax\n 401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bde:\t48 89 c7 \tmov %rax,%rdi\n 401be1:\te8 f2 00 00 00 \tcall 401cd8 \n 401be6:\te9 ea 00 00 00 \tjmp 401cd5 \n 401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bef:\t48 89 c7 \tmov %rax,%rdi\n 401bf2:\te8 8b 01 00 00 \tcall 401d82 \n 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 \n 401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401c00:\t48 89 c7 \tmov %rax,%rdi\n ...\n```\n这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是`GenerateRandomNumber`这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。\n\n---\n\n### **动态调试**\n理解原理就没什么难度了,自己找几个断点打好然后关注一下`rand_div`的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向`phase_2_14`跳转:\n![phase_2_14](/images/phase_2_14.png)\n\n而除了`phase_2_14`还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。\n\n---\n## **Phase_3**\n\n### **静态分析**\n\n和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi\n\n本体其实没有什么好说的,这里我跳转的方向是`Phase_3_5`简要解释一下可供参考:\n\n```assembly\n0000000000403001 :\n 403001:\tf3 0f 1e fa \tendbr64\n 403005:\t55 \tpush %rbp\n 403006:\t48 89 e5 \tmov %rsp,%rbp\n 403009:\t48 83 ec 20 \tsub $0x20,%rsp\n 40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)\n 403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)\n 403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)\n 40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx\n 403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx\n 403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax\n 40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>\n 403032:\t48 89 c7 \tmov %rax,%rdi\n 403035:\tb8 00 00 00 00 \tmov $0x0,%eax\n 40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n 40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)\n 403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)\n 403046:\t7f 05 \tjg 40304d \n 403048:\te8 a9 2b 00 00 \tcall 405bf6 \n 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi\n 403052:\te8 56 e6 ff ff \tcall 4016ad \n 403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40305a:\t48 63 d0 \tmovslq %eax,%rdx\n 40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 \n 403064:\t48 39 c2 \tcmp %rax,%rdx\n 403067:\t74 05 \tje 40306e \n 403069:\te8 88 2b 00 00 \tcall 405bf6 \n 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 403073:\te8 35 e6 ff ff \tcall 4016ad \n 403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40307b:\t83 f8 07 \tcmp $0x7,%eax\n 40307e:\t0f 87 eb 00 00 00 \tja 40316f \n 403084:\t89 c0 \tmov %eax,%eax\n 403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 40308d:\t00 \n 40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>\n 403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 403098:\t48 98 \tcltq\n 40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>\n 4030a1:\t48 01 d0 \tadd %rdx,%rax\n 4030a4:\t3e ff e0 \tnotrack jmp *%rax\n 4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 \n 4030ae:\t89 c2 \tmov %eax,%edx\n 4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax\n 4030b3:\t01 d0 \tadd %edx,%eax\n 4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)\n 4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 4030bd:\te8 eb e5 ff ff \tcall 4016ad \n ...\n 403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax\n 403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里\n 40317a:\t74 05 \tje 403181 \n 40317c:\te8 75 2a 00 00 \tcall 405bf6 \n 403181:\t90 \tnop\n 403182:\tc9 \tleave\n 403183:\tc3 \tret\n\n```\n看起来一大堆很吓人对不对?实际上确实很吓人。\n\n但是发现其中玄机后其实简单的没边,最终答案就藏在`0x403177`里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接`run`一下重开qwq)。\n\n---\n\n### **动态调试**\n\n阅读`Phase_3_5`发现这一关其实需要两个输入,并且第一个输入必须是`rand_div`,这里建议通过`si`单步执行监控好`rand_div`值变化,确定正确结果后使用`run`重开正确输入第一个密码后才能进行下一步求解:\n```lldb\n(lldb) si\nProcess 13376 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377\nbomb_linux`phase_3_5:\n-> 0x40317a <+377>: je 0x403181 ; <+384>\n 0x40317c <+379>: callq 0x405bf6 ; explode_bomb\n 0x403181 <+384>: nop\n 0x403182 <+385>: leave\n(lldb) x/wx $rbp-0x4\n0x7fffffffdb0c: 0xffffffd7\n```\n例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。\n\n---\n\n## **Phase_4**\n\n### **静态分析**\n\n本题依旧开局跳转,笔者的跳转方向是`phase_4_01`,如何跳转不再强调关注`rand_div`的值即可,下面请D指导解读一下`phase_4_01`的内容:\n```assembly\n0000000000404895 :\n ; 函数入口,初始化栈帧\n 404895:\tf3 0f 1e fa \tendbr64 \n 404899:\t55 \tpush %rbp\n 40489a:\t48 89 e5 \tmov %rsp,%rbp\n 40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间\n\n ; 初始化斐波那契数组(F(10)~F(24)的十六进制值)\n 4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针\n 4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55\n 4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89\n 4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144\n 4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233\n 4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377\n 4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610\n 4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987\n 4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597\n 4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584\n 4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181\n 4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765\n 4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946\n 4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711\n 404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657\n 404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368\n\n ; 读取输入到局部变量(格式为\"%d\")\n 40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址\n 404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串\n 404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串\"%d\"\n 40491d:\t48 89 ce \tmov %rcx,%rsi\n 404920:\t48 89 c7 \tmov %rax,%rdi\n 404923:\tb8 00 00 00 00 \tmov $0x0,%eax\n 404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n\n ; 验证输入有效性(必须为1个正数)\n 40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值\n 404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数\n 404934:\t75 07 \tjne 40493d ; 失败则爆炸\n 404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N\n 404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0\n 40493b:\t7f 05 \tjg 404942 \n 40493d:\te8 b4 12 00 00 \tcall 405bf6 \n\n ; 检查输入值上限(必须 > 1999)\n 404942:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制\n 40494a:\t7f 05 \tjg 404951 ; N > 1999?\n 40494c:\te8 a5 12 00 00 \tcall 405bf6 \n\n ; 计算 N/2000(通过定点数乘法优化)\n 404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N\n 404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展\n 404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)\n 40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位\n 404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000\n 404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展\n 404968:\t89 c1 \tmov %eax,%ecx \n 40496a:\t89 d0 \tmov %edx,%eax \n 40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况\n 40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000\n\n ; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列\n 404971:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404974:\t89 c7 \tmov %eax,%edi ; 参数k\n 404976:\te8 ce fd ff ff \tcall 404749 ; 返回值eax=F(k+1)\n 40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果\n\n ; 生成随机索引并验证结果\n 40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15\n 404983:\te8 25 cd ff ff \tcall 4016ad ; 生成0~14随机数\n 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 ; 获取随机索引\n 40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值\n 404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?\n 404996:\t74 05 \tje 40499d \n 404998:\te8 59 12 00 00 \tcall 405bf6 \n```\n所以相对还是很明了的,依旧是关注`rand_div`。\n\n### **动态调试**\n先找出`rand_div`在最后判断前的取值,比如我下面的0xa:\n\n```lldb\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108\nbomb_linux`GenerateRandomNumber:\n-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div\n 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115\nbomb_linux`GenerateRandomNumber:\n-> 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n 0x401724 <+119>: retq\n(lldb) x/gx &rand_div\n0x00408820: 0x000000000000000a\n```\n\n而当 `rand_div = 0xa`(即十进制 **10**)时,输入值 `N` 的计算步骤如下:\n\n- 数组索引 **10** 的值是 **斐波那契数列第 20 项**(`F(20) = 6765`)。\n\n- `func4_0(k)` 实际计算的是 **标准斐波那契数列的第 `k+1` 项**(例如,`func4_0(0) = 1 = F(2)`) 需要满足:\n ```c\n func4_0(k) = F(k+1) = F(20)\n ```\n 解得:\n k + 1 = 20 → k = 19\n- `k = N / 2000` → `N = 2000 * k = 2000 * 19 = 38000`.\n从而得解。\n![phase_4](/images/phase_4.png)\n\n---\n\n## **Phase_Impossible**\n\nImpossible?\n\n从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:\n```c\nvoid phase_impossible(char *param_1)\n\n{\n int iVar1;\n size_t sVar2;\n undefined local_118 [256];\n long local_18;\n long local_10;\n \n local_10 = GetTickCount();\n sVar2 = strlen(param_1);\n if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {\n explode_bomb();\n }\n memset(local_118,0,0x100);\n tohex(local_118,param_1);\n GenerateRandomNumber(0x400);\n iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);\n if (iVar1 == 0) {\n puts(&DAT_00406518);\n explode_bomb();\n }\n GenerateRandomNumber(3);\n if (rand_div != 2) {\n if (2 < rand_div) goto LAB_00401891;\n if (rand_div == 0) {\n goto_buf_0(local_118);\n }\n else if (rand_div != 1) goto LAB_00401891;\n goto_buf_1(local_118);\n }\n goto_buf_2(local_118);\nLAB_00401891:\n explode_bomb();\n GenerateRandomNumber(0x400);\n if ((long)(int)result != rand_div) {\n printf(&DAT_00406560,rand_div,(ulong)result);\n explode_bomb();\n }\n local_18 = GetTickCount();\n if (1000 < (ulong)(local_18 - local_10)) {\n puts(&DAT_004065a8);\n explode_bomb();\n }\n return;\n}\n```\n最终任务还是很明确的,需要写一段机器码修改`result`的数值,但是注意要能通过`check_buf_valid`检测,并且最后指令必须是跳转到`0x401896`不然就会触发`phase_impossible`中`0x401891`处的`explode_bomb`函数,唯一的难点是跟踪`rand_div`的数值变化,建议使用`register write`来修改`check_buf_valid`的返回值使其强制通过然后监控`rand_div`每一次的数值变化(`x/gx &rand_div`),记录好`rand_div`的结果后开始指令设计,需要满足:\n\n - 指令的异或和为`rand_div`第一次的数值末尾八位以通过检查;\n - 修改`result`使其数值等于`rand_div`第三次数值;\n - 跳转到`0x401896`避免炸弹;\n\n 如果前几问都完成了到这里应该是没有问题的。\n\n---\n\n## **Phase_Secret**\n\n隐藏彩蛋,并非隐藏。汇编里写的非常清楚:\n```assembly\n0000000000401a8b :\n 401a8b:\tf3 0f 1e fa \tendbr64\n 401a8f:\t55 \tpush %rbp\n 401a90:\t48 89 e5 \tmov %rsp,%rbp\n 401a93:\t48 83 ec 10 \tsub $0x10,%rsp\n 401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>\n 401aa2:\t48 89 c7 \tmov %rax,%rdi\n 401aa5:\te8 76 f6 ff ff \tcall 401120 \n 401aaa:\t90 \tnop\n 401aab:\tc9 \tleave\n 401aac:\tc3 \tret\n```\n注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在`phase_5`中设计指令时加一个要求跳转到`0x401a8b`即可。\n\n完结\n![Case Closed](/images/caseclosed.png)\n","source":"_posts/nudtbomblab.md","raw":"---\ntitle: 高地特供版CSAPP Bomb Lab全流程攻略\ndate: 2025-02-24 15:09:11\ntags: [技术, 学习, 生活]\n---\n\n这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。\n\n笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。\n\n## **Phase_1**\n\n### **静态分析**\n\n#### **`strings`扫描**\n```bash\nstrings bomb_linux\n```\n先用strings寻找可能与`phase_1`相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。\n![strings](/images/phase1_strings.png)\n - 结果没有明文密码无法直接秒掉第一问,可惜。\n - 但是找到`GenerateRandomString`函数可能与密码生成相关。\n\n#### **用`objdump`反汇编**\n```bash\nobjdump -d bomb_linux > bomb.asm\n```\n搜索`GenerateRandomString`和`phase_1`函数的汇编代码。\n ```assembly\n 401b53 :\n 401b53: endbr64\n 401b57: push %rbp\n 401b58: mov %rsp,%rbp\n 401b5b: sub $0x20,%rsp\n 401b5f: mov %rdi,-0x18(%rbp)\n 401b63: lea -0xb(%rbp),%rax\n 401b67: mov %rax,%rdi\n 401b6a: callq 401ac1 # 调用密码生成函数\n 401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置\n 401b73: mov -0x18(%rbp),%rax\n 401b77: mov %rdx,%rsi\n 401b7a: mov %rax,%rdi\n 401b7d: callq 401c0c # 调用字符串比较函数\n 401b82: test %eax,%eax\n 401b84: je 401b8d \n 401b86: callq 401d67 # 比较失败则引爆炸弹\n ```\n - `phase_1`调用`GenerateRandomString`生成一个字符串。\n - 用户输入的字符串需要与此生成的字符串完全匹配。\n\n---\n\n### **动态调试**\n![phase_1](/images/phase1.png)\n下面是phase_1求解的完整流程:\n```lldb\nlldb bomb_linux <你的学号后六位>\n(lldb) b phase_1 # 在phase_1入口断点\n(lldb) run # 从入口开始执行\n请输入第1级的密码:114514 # 随便输入触发断点\n(lldb) b 0x401b6f # 在GenerateRandomString返回后断点\n(lldb) continue # 继续执行\n(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)\n0x7fffffffdaf5: \"mJHurpQZtY\" # 轻松拿下,这里是根据学号伪随机生成的哦\n```\n将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。\n\n---\n\n## **Phase_2**\n\n### **静态分析**\n\n这道题目还是比较一目了然的,观察`phase_2`代码不难发现其实构建了一张跳转表:\n```assembly\n0000000000401b8e :\n 401b8e:\tf3 0f 1e fa \tendbr64\n 401b92:\t55 \tpush %rbp\n 401b93:\t48 89 e5 \tmov %rsp,%rbp\n 401b96:\t48 83 ec 10 \tsub $0x10,%rsp\n 401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi\n 401ba3:\te8 05 fb ff ff \tcall 4016ad \n 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 \n 401baf:\t48 83 f8 0f \tcmp $0xf,%rax\n 401bb3:\t0f 87 16 01 00 00 \tja 401ccf \n 401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 401bc0:\t00 \n 401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>\n 401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 401bcb:\t48 98 \tcltq\n 401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>\n 401bd4:\t48 01 d0 \tadd %rdx,%rax\n 401bd7:\t3e ff e0 \tnotrack jmp *%rax\n 401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bde:\t48 89 c7 \tmov %rax,%rdi\n 401be1:\te8 f2 00 00 00 \tcall 401cd8 \n 401be6:\te9 ea 00 00 00 \tjmp 401cd5 \n 401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bef:\t48 89 c7 \tmov %rax,%rdi\n 401bf2:\te8 8b 01 00 00 \tcall 401d82 \n 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 \n 401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401c00:\t48 89 c7 \tmov %rax,%rdi\n ...\n```\n这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是`GenerateRandomNumber`这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。\n\n---\n\n### **动态调试**\n理解原理就没什么难度了,自己找几个断点打好然后关注一下`rand_div`的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向`phase_2_14`跳转:\n![phase_2_14](/images/phase_2_14.png)\n\n而除了`phase_2_14`还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。\n\n---\n## **Phase_3**\n\n### **静态分析**\n\n和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi\n\n本体其实没有什么好说的,这里我跳转的方向是`Phase_3_5`简要解释一下可供参考:\n\n```assembly\n0000000000403001 :\n 403001:\tf3 0f 1e fa \tendbr64\n 403005:\t55 \tpush %rbp\n 403006:\t48 89 e5 \tmov %rsp,%rbp\n 403009:\t48 83 ec 20 \tsub $0x20,%rsp\n 40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)\n 403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)\n 403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)\n 40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx\n 403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx\n 403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax\n 40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>\n 403032:\t48 89 c7 \tmov %rax,%rdi\n 403035:\tb8 00 00 00 00 \tmov $0x0,%eax\n 40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n 40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)\n 403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)\n 403046:\t7f 05 \tjg 40304d \n 403048:\te8 a9 2b 00 00 \tcall 405bf6 \n 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi\n 403052:\te8 56 e6 ff ff \tcall 4016ad \n 403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40305a:\t48 63 d0 \tmovslq %eax,%rdx\n 40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 \n 403064:\t48 39 c2 \tcmp %rax,%rdx\n 403067:\t74 05 \tje 40306e \n 403069:\te8 88 2b 00 00 \tcall 405bf6 \n 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 403073:\te8 35 e6 ff ff \tcall 4016ad \n 403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40307b:\t83 f8 07 \tcmp $0x7,%eax\n 40307e:\t0f 87 eb 00 00 00 \tja 40316f \n 403084:\t89 c0 \tmov %eax,%eax\n 403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 40308d:\t00 \n 40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>\n 403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 403098:\t48 98 \tcltq\n 40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>\n 4030a1:\t48 01 d0 \tadd %rdx,%rax\n 4030a4:\t3e ff e0 \tnotrack jmp *%rax\n 4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 \n 4030ae:\t89 c2 \tmov %eax,%edx\n 4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax\n 4030b3:\t01 d0 \tadd %edx,%eax\n 4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)\n 4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 4030bd:\te8 eb e5 ff ff \tcall 4016ad \n ...\n 403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax\n 403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里\n 40317a:\t74 05 \tje 403181 \n 40317c:\te8 75 2a 00 00 \tcall 405bf6 \n 403181:\t90 \tnop\n 403182:\tc9 \tleave\n 403183:\tc3 \tret\n\n```\n看起来一大堆很吓人对不对?实际上确实很吓人。\n\n但是发现其中玄机后其实简单的没边,最终答案就藏在`0x403177`里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接`run`一下重开qwq)。\n\n---\n\n### **动态调试**\n\n阅读`Phase_3_5`发现这一关其实需要两个输入,并且第一个输入必须是`rand_div`,这里建议通过`si`单步执行监控好`rand_div`值变化,确定正确结果后使用`run`重开正确输入第一个密码后才能进行下一步求解:\n```lldb\n(lldb) si\nProcess 13376 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377\nbomb_linux`phase_3_5:\n-> 0x40317a <+377>: je 0x403181 ; <+384>\n 0x40317c <+379>: callq 0x405bf6 ; explode_bomb\n 0x403181 <+384>: nop\n 0x403182 <+385>: leave\n(lldb) x/wx $rbp-0x4\n0x7fffffffdb0c: 0xffffffd7\n```\n例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。\n\n---\n\n## **Phase_4**\n\n### **静态分析**\n\n本题依旧开局跳转,笔者的跳转方向是`phase_4_01`,如何跳转不再强调关注`rand_div`的值即可,下面请D指导解读一下`phase_4_01`的内容:\n```assembly\n0000000000404895 :\n ; 函数入口,初始化栈帧\n 404895:\tf3 0f 1e fa \tendbr64 \n 404899:\t55 \tpush %rbp\n 40489a:\t48 89 e5 \tmov %rsp,%rbp\n 40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间\n\n ; 初始化斐波那契数组(F(10)~F(24)的十六进制值)\n 4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针\n 4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55\n 4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89\n 4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144\n 4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233\n 4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377\n 4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610\n 4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987\n 4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597\n 4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584\n 4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181\n 4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765\n 4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946\n 4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711\n 404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657\n 404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368\n\n ; 读取输入到局部变量(格式为\"%d\")\n 40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址\n 404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串\n 404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串\"%d\"\n 40491d:\t48 89 ce \tmov %rcx,%rsi\n 404920:\t48 89 c7 \tmov %rax,%rdi\n 404923:\tb8 00 00 00 00 \tmov $0x0,%eax\n 404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n\n ; 验证输入有效性(必须为1个正数)\n 40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值\n 404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数\n 404934:\t75 07 \tjne 40493d ; 失败则爆炸\n 404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N\n 404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0\n 40493b:\t7f 05 \tjg 404942 \n 40493d:\te8 b4 12 00 00 \tcall 405bf6 \n\n ; 检查输入值上限(必须 > 1999)\n 404942:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制\n 40494a:\t7f 05 \tjg 404951 ; N > 1999?\n 40494c:\te8 a5 12 00 00 \tcall 405bf6 \n\n ; 计算 N/2000(通过定点数乘法优化)\n 404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N\n 404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展\n 404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)\n 40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位\n 404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000\n 404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展\n 404968:\t89 c1 \tmov %eax,%ecx \n 40496a:\t89 d0 \tmov %edx,%eax \n 40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况\n 40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000\n\n ; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列\n 404971:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404974:\t89 c7 \tmov %eax,%edi ; 参数k\n 404976:\te8 ce fd ff ff \tcall 404749 ; 返回值eax=F(k+1)\n 40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果\n\n ; 生成随机索引并验证结果\n 40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15\n 404983:\te8 25 cd ff ff \tcall 4016ad ; 生成0~14随机数\n 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 ; 获取随机索引\n 40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值\n 404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?\n 404996:\t74 05 \tje 40499d \n 404998:\te8 59 12 00 00 \tcall 405bf6 \n```\n所以相对还是很明了的,依旧是关注`rand_div`。\n\n### **动态调试**\n先找出`rand_div`在最后判断前的取值,比如我下面的0xa:\n\n```lldb\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108\nbomb_linux`GenerateRandomNumber:\n-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div\n 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115\nbomb_linux`GenerateRandomNumber:\n-> 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n 0x401724 <+119>: retq\n(lldb) x/gx &rand_div\n0x00408820: 0x000000000000000a\n```\n\n而当 `rand_div = 0xa`(即十进制 **10**)时,输入值 `N` 的计算步骤如下:\n\n- 数组索引 **10** 的值是 **斐波那契数列第 20 项**(`F(20) = 6765`)。\n\n- `func4_0(k)` 实际计算的是 **标准斐波那契数列的第 `k+1` 项**(例如,`func4_0(0) = 1 = F(2)`) 需要满足:\n ```c\n func4_0(k) = F(k+1) = F(20)\n ```\n 解得:\n k + 1 = 20 → k = 19\n- `k = N / 2000` → `N = 2000 * k = 2000 * 19 = 38000`.\n从而得解。\n![phase_4](/images/phase_4.png)\n\n---\n\n## **Phase_Impossible**\n\nImpossible?\n\n从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:\n```c\nvoid phase_impossible(char *param_1)\n\n{\n int iVar1;\n size_t sVar2;\n undefined local_118 [256];\n long local_18;\n long local_10;\n \n local_10 = GetTickCount();\n sVar2 = strlen(param_1);\n if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {\n explode_bomb();\n }\n memset(local_118,0,0x100);\n tohex(local_118,param_1);\n GenerateRandomNumber(0x400);\n iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);\n if (iVar1 == 0) {\n puts(&DAT_00406518);\n explode_bomb();\n }\n GenerateRandomNumber(3);\n if (rand_div != 2) {\n if (2 < rand_div) goto LAB_00401891;\n if (rand_div == 0) {\n goto_buf_0(local_118);\n }\n else if (rand_div != 1) goto LAB_00401891;\n goto_buf_1(local_118);\n }\n goto_buf_2(local_118);\nLAB_00401891:\n explode_bomb();\n GenerateRandomNumber(0x400);\n if ((long)(int)result != rand_div) {\n printf(&DAT_00406560,rand_div,(ulong)result);\n explode_bomb();\n }\n local_18 = GetTickCount();\n if (1000 < (ulong)(local_18 - local_10)) {\n puts(&DAT_004065a8);\n explode_bomb();\n }\n return;\n}\n```\n最终任务还是很明确的,需要写一段机器码修改`result`的数值,但是注意要能通过`check_buf_valid`检测,并且最后指令必须是跳转到`0x401896`不然就会触发`phase_impossible`中`0x401891`处的`explode_bomb`函数,唯一的难点是跟踪`rand_div`的数值变化,建议使用`register write`来修改`check_buf_valid`的返回值使其强制通过然后监控`rand_div`每一次的数值变化(`x/gx &rand_div`),记录好`rand_div`的结果后开始指令设计,需要满足:\n\n - 指令的异或和为`rand_div`第一次的数值末尾八位以通过检查;\n - 修改`result`使其数值等于`rand_div`第三次数值;\n - 跳转到`0x401896`避免炸弹;\n\n 如果前几问都完成了到这里应该是没有问题的。\n\n---\n\n## **Phase_Secret**\n\n隐藏彩蛋,并非隐藏。汇编里写的非常清楚:\n```assembly\n0000000000401a8b :\n 401a8b:\tf3 0f 1e fa \tendbr64\n 401a8f:\t55 \tpush %rbp\n 401a90:\t48 89 e5 \tmov %rsp,%rbp\n 401a93:\t48 83 ec 10 \tsub $0x10,%rsp\n 401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>\n 401aa2:\t48 89 c7 \tmov %rax,%rdi\n 401aa5:\te8 76 f6 ff ff \tcall 401120 \n 401aaa:\t90 \tnop\n 401aab:\tc9 \tleave\n 401aac:\tc3 \tret\n```\n注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在`phase_5`中设计指令时加一个要求跳转到`0x401a8b`即可。\n\n完结\n![Case Closed](/images/caseclosed.png)\n","slug":"nudtbomblab","published":1,"updated":"2025-02-25T03:56:35.270Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q40015p22bbk3g76eg","content":"

这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。

\n

笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。

\n

Phase_1

静态分析

strings扫描

1
strings bomb_linux
\n

先用strings寻找可能与phase_1相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。
\"strings\"

\n
    \n
  • 结果没有明文密码无法直接秒掉第一问,可惜。
  • \n
  • 但是找到GenerateRandomString函数可能与密码生成相关。
  • \n
\n

objdump反汇编

1
objdump -d bomb_linux > bomb.asm
\n

搜索GenerateRandomStringphase_1函数的汇编代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
401b53 <phase_1>:
401b53: endbr64
401b57: push %rbp
401b58: mov %rsp,%rbp
401b5b: sub $0x20,%rsp
401b5f: mov %rdi,-0x18(%rbp)
401b63: lea -0xb(%rbp),%rax
401b67: mov %rax,%rdi
401b6a: callq 401ac1 <GenerateRandomString> # 调用密码生成函数
401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置
401b73: mov -0x18(%rbp),%rax
401b77: mov %rdx,%rsi
401b7a: mov %rax,%rdi
401b7d: callq 401c0c <string_compare> # 调用字符串比较函数
401b82: test %eax,%eax
401b84: je 401b8d <phase_1+0x3a>
401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹

\n
    \n
  • phase_1调用GenerateRandomString生成一个字符串。
  • \n
  • 用户输入的字符串需要与此生成的字符串完全匹配。
  • \n
\n
\n

动态调试

\"phase_1\"
下面是phase_1求解的完整流程:

\n
1
2
3
4
5
6
7
8
lldb bomb_linux <你的学号后六位>
(lldb) b phase_1 # 在phase_1入口断点
(lldb) run # 从入口开始执行
请输入第1级的密码:114514 # 随便输入触发断点
(lldb) b 0x401b6f # 在GenerateRandomString返回后断点
(lldb) continue # 继续执行
(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)
0x7fffffffdaf5: "mJHurpQZtY" # 轻松拿下,这里是根据学号伪随机生成的哦
\n

将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。

\n
\n

Phase_2

静态分析

这道题目还是比较一目了然的,观察phase_2代码不难发现其实构建了一张跳转表:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0000000000401b8e <phase_2>:
401b8e:\tf3 0f 1e fa \tendbr64
401b92:\t55 \tpush %rbp
401b93:\t48 89 e5 \tmov %rsp,%rbp
401b96:\t48 83 ec 10 \tsub $0x10,%rsp
401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi
401ba3:\te8 05 fb ff ff \tcall 4016ad <GenerateRandomNumber>
401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div>
401baf:\t48 83 f8 0f \tcmp $0xf,%rax
401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141>
401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
401bc0:\t00
401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>
401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
401bcb:\t48 98 \tcltq
401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>
401bd4:\t48 01 d0 \tadd %rdx,%rax
401bd7:\t3e ff e0 \tnotrack jmp *%rax
401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bde:\t48 89 c7 \tmov %rax,%rdi
401be1:\te8 f2 00 00 00 \tcall 401cd8 <phase_2_0>
401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bef:\t48 89 c7 \tmov %rax,%rdi
401bf2:\te8 8b 01 00 00 \tcall 401d82 <phase_2_1>
401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401c00:\t48 89 c7 \tmov %rax,%rdi
...
\n

这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是GenerateRandomNumber这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。

\n
\n

动态调试

理解原理就没什么难度了,自己找几个断点打好然后关注一下rand_div的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向phase_2_14跳转:
\"phase_2_14\"

\n

而除了phase_2_14还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。

\n
\n

Phase_3

静态分析

和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi

\n

本体其实没有什么好说的,这里我跳转的方向是Phase_3_5简要解释一下可供参考:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
0000000000403001 <phase_3_5>:
403001:\tf3 0f 1e fa \tendbr64
403005:\t55 \tpush %rbp
403006:\t48 89 e5 \tmov %rsp,%rbp
403009:\t48 83 ec 20 \tsub $0x20,%rsp
40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)
403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)
403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)
40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx
403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx
403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax
40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>
403032:\t48 89 c7 \tmov %rax,%rdi
403035:\tb8 00 00 00 00 \tmov $0x0,%eax
40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>
40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)
403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)
403046:\t7f 05 \tjg 40304d <phase_3_5+0x4c>
403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb>
40304d:\tbf 08 00 00 00 \tmov $0x8,%edi
403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40305a:\t48 63 d0 \tmovslq %eax,%rdx
40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 <rand_div>
403064:\t48 39 c2 \tcmp %rax,%rdx
403067:\t74 05 \tje 40306e <phase_3_5+0x6d>
403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb>
40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi
403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40307b:\t83 f8 07 \tcmp $0x7,%eax
40307e:\t0f 87 eb 00 00 00 \tja 40316f <phase_3_5+0x16e>
403084:\t89 c0 \tmov %eax,%eax
403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
40308d:\t00
40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>
403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
403098:\t48 98 \tcltq
40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>
4030a1:\t48 01 d0 \tadd %rdx,%rax
4030a4:\t3e ff e0 \tnotrack jmp *%rax
4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 <rand_div>
4030ae:\t89 c2 \tmov %eax,%edx
4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax
4030b3:\t01 d0 \tadd %edx,%eax
4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)
4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi
4030bd:\te8 eb e5 ff ff \tcall 4016ad <GenerateRandomNumber>
...
403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax
403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里
40317a:\t74 05 \tje 403181 <phase_3_5+0x180>
40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb>
403181:\t90 \tnop
403182:\tc9 \tleave
403183:\tc3 \tret

\n

看起来一大堆很吓人对不对?实际上确实很吓人。

\n

但是发现其中玄机后其实简单的没边,最终答案就藏在0x403177里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接run一下重开qwq)。

\n
\n

动态调试

阅读Phase_3_5发现这一关其实需要两个输入,并且第一个输入必须是rand_div,这里建议通过si单步执行监控好rand_div值变化,确定正确结果后使用run重开正确输入第一个密码后才能进行下一步求解:

\n
1
2
3
4
5
6
7
8
9
10
11
(lldb) si
Process 13376 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377
bomb_linux`phase_3_5:
-> 0x40317a <+377>: je 0x403181 ; <+384>
0x40317c <+379>: callq 0x405bf6 ; explode_bomb
0x403181 <+384>: nop
0x403182 <+385>: leave
(lldb) x/wx $rbp-0x4
0x7fffffffdb0c: 0xffffffd7
\n

例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。

\n
\n

Phase_4

静态分析

本题依旧开局跳转,笔者的跳转方向是phase_4_01,如何跳转不再强调关注rand_div的值即可,下面请D指导解读一下phase_4_01的内容:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
0000000000404895 <phase_4_01>:
; 函数入口,初始化栈帧
404895:\tf3 0f 1e fa \tendbr64
404899:\t55 \tpush %rbp
40489a:\t48 89 e5 \tmov %rsp,%rbp
40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间

; 初始化斐波那契数组(F(10)~F(24)的十六进制值)
4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针
4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55
4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89
4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144
4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233
4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377
4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610
4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987
4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597
4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584
4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181
4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765
4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946
4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711
404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657
404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368

; 读取输入到局部变量(格式为"%d")
40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址
404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串
404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串"%d"
40491d:\t48 89 ce \tmov %rcx,%rsi
404920:\t48 89 c7 \tmov %rax,%rdi
404923:\tb8 00 00 00 00 \tmov $0x0,%eax
404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>

; 验证输入有效性(必须为1个正数)
40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值
404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数
404934:\t75 07 \tjne 40493d <phase_4_01+0xa8> ; 失败则爆炸
404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N
404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0
40493b:\t7f 05 \tjg 404942 <phase_4_01+0xad>
40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb>

; 检查输入值上限(必须 > 1999)
404942:\t8b 45 ac \tmov -0x54(%rbp),%eax
404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制
40494a:\t7f 05 \tjg 404951 <phase_4_01+0xbc> ; N > 1999?
40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb>

; 计算 N/2000(通过定点数乘法优化)
404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N
404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展
404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)
40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位
404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000
404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展
404968:\t89 c1 \tmov %eax,%ecx
40496a:\t89 d0 \tmov %edx,%eax
40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况
40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000

; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列
404971:\t8b 45 ac \tmov -0x54(%rbp),%eax
404974:\t89 c7 \tmov %eax,%edi ; 参数k
404976:\te8 ce fd ff ff \tcall 404749 <func4_0> ; 返回值eax=F(k+1)
40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果

; 生成随机索引并验证结果
40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15
404983:\te8 25 cd ff ff \tcall 4016ad <GenerateRandomNumber> ; 生成0~14随机数
404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引
40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值
404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?
404996:\t74 05 \tje 40499d <phase_4_01+0x108>
404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb>
\n

所以相对还是很明了的,依旧是关注rand_div

\n

动态调试

先找出rand_div在最后判断前的取值,比如我下面的0xa:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108
bomb_linux`GenerateRandomNumber:
-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div
0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115
bomb_linux`GenerateRandomNumber:
-> 0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
0x401724 <+119>: retq
(lldb) x/gx &rand_div
0x00408820: 0x000000000000000a
\n\n

而当 rand_div = 0xa(即十进制 10)时,输入值 N 的计算步骤如下:

\n
    \n
  • 数组索引 10 的值是 斐波那契数列第 20 项F(20) = 6765)。

    \n
  • \n
  • func4_0(k) 实际计算的是 标准斐波那契数列的第 k+1(例如,func4_0(0) = 1 = F(2)) 需要满足:

    \n
    1
    func4_0(k) = F(k+1) = F(20)
    \n

    解得:
    k + 1 = 20 → k = 19

    \n
  • \n
  • k = N / 2000N = 2000 * k = 2000 * 19 = 38000.
    从而得解。
    \"phase_4\"

    \n
  • \n
\n
\n

Phase_Impossible

Impossible?

\n

从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void phase_impossible(char *param_1)

{
int iVar1;
size_t sVar2;
undefined local_118 [256];
long local_18;
long local_10;

local_10 = GetTickCount();
sVar2 = strlen(param_1);
if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {
explode_bomb();
}
memset(local_118,0,0x100);
tohex(local_118,param_1);
GenerateRandomNumber(0x400);
iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);
if (iVar1 == 0) {
puts(&DAT_00406518);
explode_bomb();
}
GenerateRandomNumber(3);
if (rand_div != 2) {
if (2 < rand_div) goto LAB_00401891;
if (rand_div == 0) {
goto_buf_0(local_118);
}
else if (rand_div != 1) goto LAB_00401891;
goto_buf_1(local_118);
}
goto_buf_2(local_118);
LAB_00401891:
explode_bomb();
GenerateRandomNumber(0x400);
if ((long)(int)result != rand_div) {
printf(&DAT_00406560,rand_div,(ulong)result);
explode_bomb();
}
local_18 = GetTickCount();
if (1000 < (ulong)(local_18 - local_10)) {
puts(&DAT_004065a8);
explode_bomb();
}
return;
}
\n

最终任务还是很明确的,需要写一段机器码修改result的数值,但是注意要能通过check_buf_valid检测,并且最后指令必须是跳转到0x401896不然就会触发phase_impossible0x401891处的explode_bomb函数,唯一的难点是跟踪rand_div的数值变化,建议使用register write来修改check_buf_valid的返回值使其强制通过然后监控rand_div每一次的数值变化(x/gx &rand_div),记录好rand_div的结果后开始指令设计,需要满足:

\n
    \n
  • 指令的异或和为rand_div第一次的数值末尾八位以通过检查;
  • \n
  • 修改result使其数值等于rand_div第三次数值;
  • \n
  • 跳转到0x401896避免炸弹;
  • \n
\n

如果前几问都完成了到这里应该是没有问题的。

\n
\n

Phase_Secret

隐藏彩蛋,并非隐藏。汇编里写的非常清楚:

\n
1
2
3
4
5
6
7
8
9
10
11
12
0000000000401a8b <phase_secret>:
401a8b:\tf3 0f 1e fa \tendbr64
401a8f:\t55 \tpush %rbp
401a90:\t48 89 e5 \tmov %rsp,%rbp
401a93:\t48 83 ec 10 \tsub $0x10,%rsp
401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>
401aa2:\t48 89 c7 \tmov %rax,%rdi
401aa5:\te8 76 f6 ff ff \tcall 401120 <puts@plt>
401aaa:\t90 \tnop
401aab:\tc9 \tleave
401aac:\tc3 \tret
\n

注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在phase_5中设计指令时加一个要求跳转到0x401a8b即可。

\n

完结
\"Case

\n","excerpt":"","more":"

这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。

\n

笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。

\n

Phase_1

静态分析

strings扫描

1
strings bomb_linux
\n

先用strings寻找可能与phase_1相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。
\"strings\"

\n
    \n
  • 结果没有明文密码无法直接秒掉第一问,可惜。
  • \n
  • 但是找到GenerateRandomString函数可能与密码生成相关。
  • \n
\n

objdump反汇编

1
objdump -d bomb_linux > bomb.asm
\n

搜索GenerateRandomStringphase_1函数的汇编代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
401b53 <phase_1>:
401b53: endbr64
401b57: push %rbp
401b58: mov %rsp,%rbp
401b5b: sub $0x20,%rsp
401b5f: mov %rdi,-0x18(%rbp)
401b63: lea -0xb(%rbp),%rax
401b67: mov %rax,%rdi
401b6a: callq 401ac1 <GenerateRandomString> # 调用密码生成函数
401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置
401b73: mov -0x18(%rbp),%rax
401b77: mov %rdx,%rsi
401b7a: mov %rax,%rdi
401b7d: callq 401c0c <string_compare> # 调用字符串比较函数
401b82: test %eax,%eax
401b84: je 401b8d <phase_1+0x3a>
401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹

\n
    \n
  • phase_1调用GenerateRandomString生成一个字符串。
  • \n
  • 用户输入的字符串需要与此生成的字符串完全匹配。
  • \n
\n
\n

动态调试

\"phase_1\"
下面是phase_1求解的完整流程:

\n
1
2
3
4
5
6
7
8
lldb bomb_linux <你的学号后六位>
(lldb) b phase_1 # 在phase_1入口断点
(lldb) run # 从入口开始执行
请输入第1级的密码:114514 # 随便输入触发断点
(lldb) b 0x401b6f # 在GenerateRandomString返回后断点
(lldb) continue # 继续执行
(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)
0x7fffffffdaf5: "mJHurpQZtY" # 轻松拿下,这里是根据学号伪随机生成的哦
\n

将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。

\n
\n

Phase_2

静态分析

这道题目还是比较一目了然的,观察phase_2代码不难发现其实构建了一张跳转表:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0000000000401b8e <phase_2>:
401b8e:\tf3 0f 1e fa \tendbr64
401b92:\t55 \tpush %rbp
401b93:\t48 89 e5 \tmov %rsp,%rbp
401b96:\t48 83 ec 10 \tsub $0x10,%rsp
401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi
401ba3:\te8 05 fb ff ff \tcall 4016ad <GenerateRandomNumber>
401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div>
401baf:\t48 83 f8 0f \tcmp $0xf,%rax
401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141>
401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
401bc0:\t00
401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>
401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
401bcb:\t48 98 \tcltq
401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>
401bd4:\t48 01 d0 \tadd %rdx,%rax
401bd7:\t3e ff e0 \tnotrack jmp *%rax
401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bde:\t48 89 c7 \tmov %rax,%rdi
401be1:\te8 f2 00 00 00 \tcall 401cd8 <phase_2_0>
401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bef:\t48 89 c7 \tmov %rax,%rdi
401bf2:\te8 8b 01 00 00 \tcall 401d82 <phase_2_1>
401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401c00:\t48 89 c7 \tmov %rax,%rdi
...
\n

这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是GenerateRandomNumber这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。

\n
\n

动态调试

理解原理就没什么难度了,自己找几个断点打好然后关注一下rand_div的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向phase_2_14跳转:
\"phase_2_14\"

\n

而除了phase_2_14还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。

\n
\n

Phase_3

静态分析

和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi

\n

本体其实没有什么好说的,这里我跳转的方向是Phase_3_5简要解释一下可供参考:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
0000000000403001 <phase_3_5>:
403001:\tf3 0f 1e fa \tendbr64
403005:\t55 \tpush %rbp
403006:\t48 89 e5 \tmov %rsp,%rbp
403009:\t48 83 ec 20 \tsub $0x20,%rsp
40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)
403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)
403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)
40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx
403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx
403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax
40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>
403032:\t48 89 c7 \tmov %rax,%rdi
403035:\tb8 00 00 00 00 \tmov $0x0,%eax
40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>
40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)
403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)
403046:\t7f 05 \tjg 40304d <phase_3_5+0x4c>
403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb>
40304d:\tbf 08 00 00 00 \tmov $0x8,%edi
403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40305a:\t48 63 d0 \tmovslq %eax,%rdx
40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 <rand_div>
403064:\t48 39 c2 \tcmp %rax,%rdx
403067:\t74 05 \tje 40306e <phase_3_5+0x6d>
403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb>
40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi
403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40307b:\t83 f8 07 \tcmp $0x7,%eax
40307e:\t0f 87 eb 00 00 00 \tja 40316f <phase_3_5+0x16e>
403084:\t89 c0 \tmov %eax,%eax
403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
40308d:\t00
40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>
403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
403098:\t48 98 \tcltq
40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>
4030a1:\t48 01 d0 \tadd %rdx,%rax
4030a4:\t3e ff e0 \tnotrack jmp *%rax
4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 <rand_div>
4030ae:\t89 c2 \tmov %eax,%edx
4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax
4030b3:\t01 d0 \tadd %edx,%eax
4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)
4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi
4030bd:\te8 eb e5 ff ff \tcall 4016ad <GenerateRandomNumber>
...
403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax
403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里
40317a:\t74 05 \tje 403181 <phase_3_5+0x180>
40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb>
403181:\t90 \tnop
403182:\tc9 \tleave
403183:\tc3 \tret

\n

看起来一大堆很吓人对不对?实际上确实很吓人。

\n

但是发现其中玄机后其实简单的没边,最终答案就藏在0x403177里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接run一下重开qwq)。

\n
\n

动态调试

阅读Phase_3_5发现这一关其实需要两个输入,并且第一个输入必须是rand_div,这里建议通过si单步执行监控好rand_div值变化,确定正确结果后使用run重开正确输入第一个密码后才能进行下一步求解:

\n
1
2
3
4
5
6
7
8
9
10
11
(lldb) si
Process 13376 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377
bomb_linux`phase_3_5:
-> 0x40317a <+377>: je 0x403181 ; <+384>
0x40317c <+379>: callq 0x405bf6 ; explode_bomb
0x403181 <+384>: nop
0x403182 <+385>: leave
(lldb) x/wx $rbp-0x4
0x7fffffffdb0c: 0xffffffd7
\n

例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。

\n
\n

Phase_4

静态分析

本题依旧开局跳转,笔者的跳转方向是phase_4_01,如何跳转不再强调关注rand_div的值即可,下面请D指导解读一下phase_4_01的内容:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
0000000000404895 <phase_4_01>:
; 函数入口,初始化栈帧
404895:\tf3 0f 1e fa \tendbr64
404899:\t55 \tpush %rbp
40489a:\t48 89 e5 \tmov %rsp,%rbp
40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间

; 初始化斐波那契数组(F(10)~F(24)的十六进制值)
4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针
4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55
4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89
4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144
4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233
4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377
4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610
4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987
4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597
4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584
4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181
4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765
4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946
4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711
404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657
404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368

; 读取输入到局部变量(格式为"%d")
40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址
404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串
404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串"%d"
40491d:\t48 89 ce \tmov %rcx,%rsi
404920:\t48 89 c7 \tmov %rax,%rdi
404923:\tb8 00 00 00 00 \tmov $0x0,%eax
404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>

; 验证输入有效性(必须为1个正数)
40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值
404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数
404934:\t75 07 \tjne 40493d <phase_4_01+0xa8> ; 失败则爆炸
404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N
404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0
40493b:\t7f 05 \tjg 404942 <phase_4_01+0xad>
40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb>

; 检查输入值上限(必须 > 1999)
404942:\t8b 45 ac \tmov -0x54(%rbp),%eax
404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制
40494a:\t7f 05 \tjg 404951 <phase_4_01+0xbc> ; N > 1999?
40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb>

; 计算 N/2000(通过定点数乘法优化)
404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N
404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展
404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)
40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位
404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000
404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展
404968:\t89 c1 \tmov %eax,%ecx
40496a:\t89 d0 \tmov %edx,%eax
40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况
40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000

; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列
404971:\t8b 45 ac \tmov -0x54(%rbp),%eax
404974:\t89 c7 \tmov %eax,%edi ; 参数k
404976:\te8 ce fd ff ff \tcall 404749 <func4_0> ; 返回值eax=F(k+1)
40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果

; 生成随机索引并验证结果
40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15
404983:\te8 25 cd ff ff \tcall 4016ad <GenerateRandomNumber> ; 生成0~14随机数
404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引
40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值
404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?
404996:\t74 05 \tje 40499d <phase_4_01+0x108>
404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb>
\n

所以相对还是很明了的,依旧是关注rand_div

\n

动态调试

先找出rand_div在最后判断前的取值,比如我下面的0xa:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108
bomb_linux`GenerateRandomNumber:
-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div
0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115
bomb_linux`GenerateRandomNumber:
-> 0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
0x401724 <+119>: retq
(lldb) x/gx &rand_div
0x00408820: 0x000000000000000a
\n\n

而当 rand_div = 0xa(即十进制 10)时,输入值 N 的计算步骤如下:

\n
    \n
  • 数组索引 10 的值是 斐波那契数列第 20 项F(20) = 6765)。

    \n
  • \n
  • func4_0(k) 实际计算的是 标准斐波那契数列的第 k+1(例如,func4_0(0) = 1 = F(2)) 需要满足:

    \n
    1
    func4_0(k) = F(k+1) = F(20)
    \n

    解得:
    k + 1 = 20 → k = 19

    \n
  • \n
  • k = N / 2000N = 2000 * k = 2000 * 19 = 38000.
    从而得解。
    \"phase_4\"

    \n
  • \n
\n
\n

Phase_Impossible

Impossible?

\n

从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void phase_impossible(char *param_1)

{
int iVar1;
size_t sVar2;
undefined local_118 [256];
long local_18;
long local_10;

local_10 = GetTickCount();
sVar2 = strlen(param_1);
if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {
explode_bomb();
}
memset(local_118,0,0x100);
tohex(local_118,param_1);
GenerateRandomNumber(0x400);
iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);
if (iVar1 == 0) {
puts(&DAT_00406518);
explode_bomb();
}
GenerateRandomNumber(3);
if (rand_div != 2) {
if (2 < rand_div) goto LAB_00401891;
if (rand_div == 0) {
goto_buf_0(local_118);
}
else if (rand_div != 1) goto LAB_00401891;
goto_buf_1(local_118);
}
goto_buf_2(local_118);
LAB_00401891:
explode_bomb();
GenerateRandomNumber(0x400);
if ((long)(int)result != rand_div) {
printf(&DAT_00406560,rand_div,(ulong)result);
explode_bomb();
}
local_18 = GetTickCount();
if (1000 < (ulong)(local_18 - local_10)) {
puts(&DAT_004065a8);
explode_bomb();
}
return;
}
\n

最终任务还是很明确的,需要写一段机器码修改result的数值,但是注意要能通过check_buf_valid检测,并且最后指令必须是跳转到0x401896不然就会触发phase_impossible0x401891处的explode_bomb函数,唯一的难点是跟踪rand_div的数值变化,建议使用register write来修改check_buf_valid的返回值使其强制通过然后监控rand_div每一次的数值变化(x/gx &rand_div),记录好rand_div的结果后开始指令设计,需要满足:

\n
    \n
  • 指令的异或和为rand_div第一次的数值末尾八位以通过检查;
  • \n
  • 修改result使其数值等于rand_div第三次数值;
  • \n
  • 跳转到0x401896避免炸弹;
  • \n
\n

如果前几问都完成了到这里应该是没有问题的。

\n
\n

Phase_Secret

隐藏彩蛋,并非隐藏。汇编里写的非常清楚:

\n
1
2
3
4
5
6
7
8
9
10
11
12
0000000000401a8b <phase_secret>:
401a8b:\tf3 0f 1e fa \tendbr64
401a8f:\t55 \tpush %rbp
401a90:\t48 89 e5 \tmov %rsp,%rbp
401a93:\t48 83 ec 10 \tsub $0x10,%rsp
401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>
401aa2:\t48 89 c7 \tmov %rax,%rdi
401aa5:\te8 76 f6 ff ff \tcall 401120 <puts@plt>
401aaa:\t90 \tnop
401aab:\tc9 \tleave
401aac:\tc3 \tret
\n

注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在phase_5中设计指令时加一个要求跳转到0x401a8b即可。

\n

完结
\"Case

\n"},{"title":"Overleaf Toolkit踩坑记录","date":"2024-11-06T01:56:18.000Z","_content":"\n在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。\n\n具体流程就不赘述了,先将访问[Overleaf Toolkit官方仓库](https://github.com/overleaf/toolkit)将代码clone下来并按照手册执行即可。\n\n## 问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像\n\n在执行 `bin/up` 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。\n\n截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。\n\n### 解决方案:为 Docker 设置代理\n\n通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:\n\n1. 创建一个 `systemd` 服务文件,为 Docker 设置代理。\n2. 编辑 `/etc/systemd/system/docker.service.d/proxy.conf` 文件,添加以下内容(确保已经设置了代理服务器):\n\n ```ini\n [Service]\n Environment=\"HTTP_PROXY=http://:\"\n Environment=\"HTTPS_PROXY=http://:\"\n Environment=\"NO_PROXY=localhost,127.0.0.1\"\n ```\n\n3. 重新加载 `systemd` 配置并重启 Docker:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl restart docker\n ```\n\n4. 重启 Docker 后再次执行 `sudo ./up`,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。\n\n\n---\n\n## 问题二:外部机器无法访问 Overleaf Web 服务\n\n先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。\n\n注意到在默认的 `lib/docker-compose.base.yml` 配置中,Overleaf Web 服务的端口映射方式为 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"`。\n\n### 解决方案:修改端口映射\n\n在 `docker-compose.base.yml` 文件中,删除 `${OVERLEAF_LISTEN_IP:-127.0.0.1}` 前缀,将 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"` 修改为 `\"${OVERLEAF_PORT:-80}:80\"`。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。\n\n修改后的 `docker-compose.base.yml` 端口映射配置如下:\n\n```yaml\n---\nservices:\n\n sharelatex:\n restart: always\n image: \"${IMAGE}\"\n container_name: sharelatex\n volumes:\n - \"${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}\"\n ports:\n #- \"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"\n - \"${OVERLEAF_PORT:-80}:80\"\n environment:\n GIT_BRIDGE_ENABLED: \"${GIT_BRIDGE_ENABLED}\"\n GIT_BRIDGE_HOST: \"git-bridge\"\n GIT_BRIDGE_PORT: \"8000\"\n REDIS_HOST: \"${REDIS_HOST}\"\n REDIS_PORT: \"${REDIS_PORT}\"\n V1_HISTORY_URL: \"http://sharelatex:3100/api\"\n env_file:\n - ../config/variables.env\n stop_grace_period: 60s\n```\n\n完成修改后,重新启动 Docker 服务:\n\n```bash\nsudo ./start\n```\n\n现在,外部机器可以通过服务器的 IP 地址加端口 `{Overleaf_Port}` 访问 Overleaf Web 服务。\n\n---\n\n## 总结\n\n这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 `docker-compose.base.yml` 中的端口映射使外部设备可以访问 Overleaf 服务。\n\n可以在这里参考我的本地[Overleaf](https://overleaf.hifuu.ink)效果,注意安装完后还需要配置latex包和中文字体。\n\n这篇记录希望能为遇到类似问题的朋友提供帮助。\n","source":"_posts/overleaf.md","raw":"---\ntitle: Overleaf Toolkit踩坑记录\ndate: 2024-11-06 09:56:18\ntags: 技术\ncategories: [技术分享]\n---\n\n在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。\n\n具体流程就不赘述了,先将访问[Overleaf Toolkit官方仓库](https://github.com/overleaf/toolkit)将代码clone下来并按照手册执行即可。\n\n## 问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像\n\n在执行 `bin/up` 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。\n\n截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。\n\n### 解决方案:为 Docker 设置代理\n\n通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:\n\n1. 创建一个 `systemd` 服务文件,为 Docker 设置代理。\n2. 编辑 `/etc/systemd/system/docker.service.d/proxy.conf` 文件,添加以下内容(确保已经设置了代理服务器):\n\n ```ini\n [Service]\n Environment=\"HTTP_PROXY=http://:\"\n Environment=\"HTTPS_PROXY=http://:\"\n Environment=\"NO_PROXY=localhost,127.0.0.1\"\n ```\n\n3. 重新加载 `systemd` 配置并重启 Docker:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl restart docker\n ```\n\n4. 重启 Docker 后再次执行 `sudo ./up`,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。\n\n\n---\n\n## 问题二:外部机器无法访问 Overleaf Web 服务\n\n先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。\n\n注意到在默认的 `lib/docker-compose.base.yml` 配置中,Overleaf Web 服务的端口映射方式为 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"`。\n\n### 解决方案:修改端口映射\n\n在 `docker-compose.base.yml` 文件中,删除 `${OVERLEAF_LISTEN_IP:-127.0.0.1}` 前缀,将 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"` 修改为 `\"${OVERLEAF_PORT:-80}:80\"`。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。\n\n修改后的 `docker-compose.base.yml` 端口映射配置如下:\n\n```yaml\n---\nservices:\n\n sharelatex:\n restart: always\n image: \"${IMAGE}\"\n container_name: sharelatex\n volumes:\n - \"${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}\"\n ports:\n #- \"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"\n - \"${OVERLEAF_PORT:-80}:80\"\n environment:\n GIT_BRIDGE_ENABLED: \"${GIT_BRIDGE_ENABLED}\"\n GIT_BRIDGE_HOST: \"git-bridge\"\n GIT_BRIDGE_PORT: \"8000\"\n REDIS_HOST: \"${REDIS_HOST}\"\n REDIS_PORT: \"${REDIS_PORT}\"\n V1_HISTORY_URL: \"http://sharelatex:3100/api\"\n env_file:\n - ../config/variables.env\n stop_grace_period: 60s\n```\n\n完成修改后,重新启动 Docker 服务:\n\n```bash\nsudo ./start\n```\n\n现在,外部机器可以通过服务器的 IP 地址加端口 `{Overleaf_Port}` 访问 Overleaf Web 服务。\n\n---\n\n## 总结\n\n这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 `docker-compose.base.yml` 中的端口映射使外部设备可以访问 Overleaf 服务。\n\n可以在这里参考我的本地[Overleaf](https://overleaf.hifuu.ink)效果,注意安装完后还需要配置latex包和中文字体。\n\n这篇记录希望能为遇到类似问题的朋友提供帮助。\n","slug":"overleaf","published":1,"updated":"2024-11-06T02:31:56.685Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q40018p22b4lpt3rxw","content":"

在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。

\n

具体流程就不赘述了,先将访问Overleaf Toolkit官方仓库将代码clone下来并按照手册执行即可。

\n

问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像

在执行 bin/up 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。

\n

截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。

\n

解决方案:为 Docker 设置代理

通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:

\n
    \n
  1. 创建一个 systemd 服务文件,为 Docker 设置代理。

    \n
  2. \n
  3. 编辑 /etc/systemd/system/docker.service.d/proxy.conf 文件,添加以下内容(确保已经设置了代理服务器):

    \n
    1
    2
    3
    4
    [Service]
    Environment="HTTP_PROXY=http://<your-proxy-server>:<port>"
    Environment="HTTPS_PROXY=http://<your-proxy-server>:<port>"
    Environment="NO_PROXY=localhost,127.0.0.1"
    \n
  4. \n
  5. 重新加载 systemd 配置并重启 Docker:

    \n
    1
    2
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    \n
  6. \n
  7. 重启 Docker 后再次执行 sudo ./up,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。

    \n
  8. \n
\n
\n

问题二:外部机器无法访问 Overleaf Web 服务

先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。

\n

注意到在默认的 lib/docker-compose.base.yml 配置中,Overleaf Web 服务的端口映射方式为 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"

\n

解决方案:修改端口映射

docker-compose.base.yml 文件中,删除 ${OVERLEAF_LISTEN_IP:-127.0.0.1} 前缀,将 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80" 修改为 "${OVERLEAF_PORT:-80}:80"。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。

\n

修改后的 docker-compose.base.yml 端口映射配置如下:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
services:

sharelatex:
restart: always
image: "${IMAGE}"
container_name: sharelatex
volumes:
- "${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}"
ports:
#- "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"
- "${OVERLEAF_PORT:-80}:80"
environment:
GIT_BRIDGE_ENABLED: "${GIT_BRIDGE_ENABLED}"
GIT_BRIDGE_HOST: "git-bridge"
GIT_BRIDGE_PORT: "8000"
REDIS_HOST: "${REDIS_HOST}"
REDIS_PORT: "${REDIS_PORT}"
V1_HISTORY_URL: "http://sharelatex:3100/api"
env_file:
- ../config/variables.env
stop_grace_period: 60s
\n\n

完成修改后,重新启动 Docker 服务:

\n
1
sudo ./start
\n\n

现在,外部机器可以通过服务器的 IP 地址加端口 {Overleaf_Port} 访问 Overleaf Web 服务。

\n
\n

总结

这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 docker-compose.base.yml 中的端口映射使外部设备可以访问 Overleaf 服务。

\n

可以在这里参考我的本地Overleaf效果,注意安装完后还需要配置latex包和中文字体。

\n

这篇记录希望能为遇到类似问题的朋友提供帮助。

\n","excerpt":"","more":"

在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。

\n

具体流程就不赘述了,先将访问Overleaf Toolkit官方仓库将代码clone下来并按照手册执行即可。

\n

问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像

在执行 bin/up 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。

\n

截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。

\n

解决方案:为 Docker 设置代理

通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:

\n
    \n
  1. 创建一个 systemd 服务文件,为 Docker 设置代理。

    \n
  2. \n
  3. 编辑 /etc/systemd/system/docker.service.d/proxy.conf 文件,添加以下内容(确保已经设置了代理服务器):

    \n
    1
    2
    3
    4
    [Service]
    Environment="HTTP_PROXY=http://<your-proxy-server>:<port>"
    Environment="HTTPS_PROXY=http://<your-proxy-server>:<port>"
    Environment="NO_PROXY=localhost,127.0.0.1"
    \n
  4. \n
  5. 重新加载 systemd 配置并重启 Docker:

    \n
    1
    2
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    \n
  6. \n
  7. 重启 Docker 后再次执行 sudo ./up,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。

    \n
  8. \n
\n
\n

问题二:外部机器无法访问 Overleaf Web 服务

先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。

\n

注意到在默认的 lib/docker-compose.base.yml 配置中,Overleaf Web 服务的端口映射方式为 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"

\n

解决方案:修改端口映射

docker-compose.base.yml 文件中,删除 ${OVERLEAF_LISTEN_IP:-127.0.0.1} 前缀,将 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80" 修改为 "${OVERLEAF_PORT:-80}:80"。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。

\n

修改后的 docker-compose.base.yml 端口映射配置如下:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
services:

sharelatex:
restart: always
image: "${IMAGE}"
container_name: sharelatex
volumes:
- "${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}"
ports:
#- "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"
- "${OVERLEAF_PORT:-80}:80"
environment:
GIT_BRIDGE_ENABLED: "${GIT_BRIDGE_ENABLED}"
GIT_BRIDGE_HOST: "git-bridge"
GIT_BRIDGE_PORT: "8000"
REDIS_HOST: "${REDIS_HOST}"
REDIS_PORT: "${REDIS_PORT}"
V1_HISTORY_URL: "http://sharelatex:3100/api"
env_file:
- ../config/variables.env
stop_grace_period: 60s
\n\n

完成修改后,重新启动 Docker 服务:

\n
1
sudo ./start
\n\n

现在,外部机器可以通过服务器的 IP 地址加端口 {Overleaf_Port} 访问 Overleaf Web 服务。

\n
\n

总结

这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 docker-compose.base.yml 中的端口映射使外部设备可以访问 Overleaf 服务。

\n

可以在这里参考我的本地Overleaf效果,注意安装完后还需要配置latex包和中文字体。

\n

这篇记录希望能为遇到类似问题的朋友提供帮助。

\n"},{"title":"相见恨晚的 SearXNG:打造私人搜索引擎全指南","date":"2025-03-10T14:55:04.000Z","_content":"\n![SearXNG 界面预览](/images/searxng.png) \n**厌倦了商业搜索引擎的广告追踪?** 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 [SearXNG](https://github.com/searxng/searxng) 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。\n\n---\n\n### ▍ 为什么选择 SearXNG?\n✅ **核心优势矩阵** \n| 特性 | 实现方式 | 用户收益 |\n|--------------------|----------------------------|------------------------|\n| 隐私保护 | 匿名聚合第三方结果 | 无搜索历史追踪 |\n| 结果去商业化 | 过滤 SEO 优化内容 | 提升技术资料检索效率 |\n| 多引擎支持 | 集成 Google/Bing/Brave 等 70+ 源 | 规避单一引擎局限 |\n| 界面定制 | 主题引擎分离设计 | 打造个性化搜索门户 |\n\n⚠️ 同类工具对比: \n此前使用的 [luxirty-search](https://github.com/KoriIku/luxirty-search) 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。\n\n之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。\n\n---\n\n### ▍ 极简部署方案\n#### ▶ 环境准备\n```bash\nmkdir -p ~/services/searxng && cd $_ # 随意找个地方创建专用目录\nexport SEARXNG_PORT=8080 # 设置服务端口\n```\n\n#### ▶ 容器化部署\n```bash\n# 拉取官方镜像\ndocker pull searxng/searxng\n\n# 启动容器(推荐绑定持久化配置)\ndocker run -d --restart=unless-stopped \\\n -p ${SEARXNG_PORT}:8080 \\\n -v \"${PWD}/config:/etc/searxng\" \\\n -e \"BASE_URL=http://your-domain.com\" \\\n -e \"INSTANCE_NAME=PrivateSearch\" \\\n searxng/searxng\n```\n📌 参数说明: \n- `-v` 挂载配置文件实现持久化 \n- `--restart` 确保服务异常退出后自动重启 \n- `BASE_URL` 需替换为实际访问域名,不过也可以后续再配置\n\n---\n\n### ▍ 高频问题排雷\n#### 🔴 镜像拉取失败\n**现象**:`Error response from daemon: pull access denied` \n✅ 解决方案: \n参考先前的 [Overleaf Toolkit 踩坑记录](https://blog.hifuu.ink/2024/11/06/overleaf/) 配置镜像加速源\n\n#### 🔴 Google 频繁拦截\n**现象**:`Too Many Requests` 错误频发 \n\n⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案\n\n✅ 实战验证方案: \n更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。\n\n📌 在配置文件设置代理: \n```yaml\noutgoing:\n proxies:\n all://:\n - http://
:\n```\n\n---\n\n### ▍ 效果展示与体验\n访问我的生产环境实例 [search.hifuu.ink](https://search.hifuu.ink) 可体验以下功能: \n- 🔍 多引擎结果聚合对比 \n- 🌍 支持 30+ 语言实时翻译 \n- 🛡️ 零 Cookie 跟踪的隐私模式 \n- 🎨 主题切换 \n\n---\n### ▍ 进阶优化建议\n1. **反向代理配置** \n\n网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。\n\n2. **定期维护命令** \n```bash\n# 更新搜索引擎引擎列表\ndocker exec -it searxng python -m searx.engines --update\n```\n\n3. **监控指标集成** \n通过 Prometheus 导出搜索统计:\n```bash\ndocker run -d --network=searxng-net \\\n -v \"${PWD}/metrics:/metrics\" \\\n prom/prometheus --config.file=/metrics/searxng.yml\n``` \n\n---\n\n**🚀 立即行动** \n\n快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。\n","source":"_posts/searxng.md","raw":"---\ntitle: 相见恨晚的 SearXNG:打造私人搜索引擎全指南\ndate: 2025-03-10 22:55:04\ntags: [开源工具, 技术分享]\n---\n\n![SearXNG 界面预览](/images/searxng.png) \n**厌倦了商业搜索引擎的广告追踪?** 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 [SearXNG](https://github.com/searxng/searxng) 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。\n\n---\n\n### ▍ 为什么选择 SearXNG?\n✅ **核心优势矩阵** \n| 特性 | 实现方式 | 用户收益 |\n|--------------------|----------------------------|------------------------|\n| 隐私保护 | 匿名聚合第三方结果 | 无搜索历史追踪 |\n| 结果去商业化 | 过滤 SEO 优化内容 | 提升技术资料检索效率 |\n| 多引擎支持 | 集成 Google/Bing/Brave 等 70+ 源 | 规避单一引擎局限 |\n| 界面定制 | 主题引擎分离设计 | 打造个性化搜索门户 |\n\n⚠️ 同类工具对比: \n此前使用的 [luxirty-search](https://github.com/KoriIku/luxirty-search) 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。\n\n之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。\n\n---\n\n### ▍ 极简部署方案\n#### ▶ 环境准备\n```bash\nmkdir -p ~/services/searxng && cd $_ # 随意找个地方创建专用目录\nexport SEARXNG_PORT=8080 # 设置服务端口\n```\n\n#### ▶ 容器化部署\n```bash\n# 拉取官方镜像\ndocker pull searxng/searxng\n\n# 启动容器(推荐绑定持久化配置)\ndocker run -d --restart=unless-stopped \\\n -p ${SEARXNG_PORT}:8080 \\\n -v \"${PWD}/config:/etc/searxng\" \\\n -e \"BASE_URL=http://your-domain.com\" \\\n -e \"INSTANCE_NAME=PrivateSearch\" \\\n searxng/searxng\n```\n📌 参数说明: \n- `-v` 挂载配置文件实现持久化 \n- `--restart` 确保服务异常退出后自动重启 \n- `BASE_URL` 需替换为实际访问域名,不过也可以后续再配置\n\n---\n\n### ▍ 高频问题排雷\n#### 🔴 镜像拉取失败\n**现象**:`Error response from daemon: pull access denied` \n✅ 解决方案: \n参考先前的 [Overleaf Toolkit 踩坑记录](https://blog.hifuu.ink/2024/11/06/overleaf/) 配置镜像加速源\n\n#### 🔴 Google 频繁拦截\n**现象**:`Too Many Requests` 错误频发 \n\n⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案\n\n✅ 实战验证方案: \n更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。\n\n📌 在配置文件设置代理: \n```yaml\noutgoing:\n proxies:\n all://:\n - http://
:\n```\n\n---\n\n### ▍ 效果展示与体验\n访问我的生产环境实例 [search.hifuu.ink](https://search.hifuu.ink) 可体验以下功能: \n- 🔍 多引擎结果聚合对比 \n- 🌍 支持 30+ 语言实时翻译 \n- 🛡️ 零 Cookie 跟踪的隐私模式 \n- 🎨 主题切换 \n\n---\n### ▍ 进阶优化建议\n1. **反向代理配置** \n\n网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。\n\n2. **定期维护命令** \n```bash\n# 更新搜索引擎引擎列表\ndocker exec -it searxng python -m searx.engines --update\n```\n\n3. **监控指标集成** \n通过 Prometheus 导出搜索统计:\n```bash\ndocker run -d --network=searxng-net \\\n -v \"${PWD}/metrics:/metrics\" \\\n prom/prometheus --config.file=/metrics/searxng.yml\n``` \n\n---\n\n**🚀 立即行动** \n\n快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。\n","slug":"searxng","published":1,"updated":"2025-03-10T15:46:55.535Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q5001ap22b3mby9fa5","content":"

\"SearXNG
厌倦了商业搜索引擎的广告追踪? 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 SearXNG 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。

\n
\n

▍ 为什么选择 SearXNG?

核心优势矩阵

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
特性实现方式用户收益
隐私保护匿名聚合第三方结果无搜索历史追踪
结果去商业化过滤 SEO 优化内容提升技术资料检索效率
多引擎支持集成 Google/Bing/Brave 等 70+ 源规避单一引擎局限
界面定制主题引擎分离设计打造个性化搜索门户
\n

⚠️ 同类工具对比:
此前使用的 luxirty-search 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。

\n

之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。

\n
\n

▍ 极简部署方案

▶ 环境准备

1
2
mkdir -p ~/services/searxng && cd $_  # 随意找个地方创建专用目录
export SEARXNG_PORT=8080 # 设置服务端口
\n\n

▶ 容器化部署

1
2
3
4
5
6
7
8
9
10
# 拉取官方镜像
docker pull searxng/searxng

# 启动容器(推荐绑定持久化配置)
docker run -d --restart=unless-stopped \\
-p ${SEARXNG_PORT}:8080 \\
-v "${PWD}/config:/etc/searxng" \\
-e "BASE_URL=http://your-domain.com" \\
-e "INSTANCE_NAME=PrivateSearch" \\
searxng/searxng
\n

📌 参数说明:

\n
    \n
  • -v 挂载配置文件实现持久化
  • \n
  • --restart 确保服务异常退出后自动重启
  • \n
  • BASE_URL 需替换为实际访问域名,不过也可以后续再配置
  • \n
\n
\n

▍ 高频问题排雷

🔴 镜像拉取失败

现象Error response from daemon: pull access denied
✅ 解决方案:
参考先前的 Overleaf Toolkit 踩坑记录 配置镜像加速源

\n

🔴 Google 频繁拦截

现象Too Many Requests 错误频发

\n

⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案

\n

✅ 实战验证方案:
更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。

\n

📌 在配置文件设置代理:

\n
1
2
3
4
outgoing:
proxies:
all://:
- http://<address>:<port>
\n\n
\n

▍ 效果展示与体验

访问我的生产环境实例 search.hifuu.ink 可体验以下功能:

\n
    \n
  • 🔍 多引擎结果聚合对比
  • \n
  • 🌍 支持 30+ 语言实时翻译
  • \n
  • 🛡️ 零 Cookie 跟踪的隐私模式
  • \n
  • 🎨 主题切换
  • \n
\n
\n

▍ 进阶优化建议

    \n
  1. 反向代理配置
  2. \n
\n

网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。

\n
    \n
  1. 定期维护命令

    \n
    1
    2
    # 更新搜索引擎引擎列表
    docker exec -it searxng python -m searx.engines --update
    \n
  2. \n
  3. 监控指标集成
    通过 Prometheus 导出搜索统计:

    \n
    1
    2
    3
    docker run -d --network=searxng-net \\
    -v "${PWD}/metrics:/metrics" \\
    prom/prometheus --config.file=/metrics/searxng.yml
  4. \n
\n
\n

🚀 立即行动

\n

快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。

\n","excerpt":"","more":"

\"SearXNG
厌倦了商业搜索引擎的广告追踪? 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 SearXNG 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。

\n
\n

▍ 为什么选择 SearXNG?

核心优势矩阵

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
特性实现方式用户收益
隐私保护匿名聚合第三方结果无搜索历史追踪
结果去商业化过滤 SEO 优化内容提升技术资料检索效率
多引擎支持集成 Google/Bing/Brave 等 70+ 源规避单一引擎局限
界面定制主题引擎分离设计打造个性化搜索门户
\n

⚠️ 同类工具对比:
此前使用的 luxirty-search 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。

\n

之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。

\n
\n

▍ 极简部署方案

▶ 环境准备

1
2
mkdir -p ~/services/searxng && cd $_  # 随意找个地方创建专用目录
export SEARXNG_PORT=8080 # 设置服务端口
\n\n

▶ 容器化部署

1
2
3
4
5
6
7
8
9
10
# 拉取官方镜像
docker pull searxng/searxng

# 启动容器(推荐绑定持久化配置)
docker run -d --restart=unless-stopped \\
-p ${SEARXNG_PORT}:8080 \\
-v "${PWD}/config:/etc/searxng" \\
-e "BASE_URL=http://your-domain.com" \\
-e "INSTANCE_NAME=PrivateSearch" \\
searxng/searxng
\n

📌 参数说明:

\n
    \n
  • -v 挂载配置文件实现持久化
  • \n
  • --restart 确保服务异常退出后自动重启
  • \n
  • BASE_URL 需替换为实际访问域名,不过也可以后续再配置
  • \n
\n
\n

▍ 高频问题排雷

🔴 镜像拉取失败

现象Error response from daemon: pull access denied
✅ 解决方案:
参考先前的 Overleaf Toolkit 踩坑记录 配置镜像加速源

\n

🔴 Google 频繁拦截

现象Too Many Requests 错误频发

\n

⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案

\n

✅ 实战验证方案:
更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。

\n

📌 在配置文件设置代理:

\n
1
2
3
4
outgoing:
proxies:
all://:
- http://<address>:<port>
\n\n
\n

▍ 效果展示与体验

访问我的生产环境实例 search.hifuu.ink 可体验以下功能:

\n
    \n
  • 🔍 多引擎结果聚合对比
  • \n
  • 🌍 支持 30+ 语言实时翻译
  • \n
  • 🛡️ 零 Cookie 跟踪的隐私模式
  • \n
  • 🎨 主题切换
  • \n
\n
\n

▍ 进阶优化建议

    \n
  1. 反向代理配置
  2. \n
\n

网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。

\n
    \n
  1. 定期维护命令

    \n
    1
    2
    # 更新搜索引擎引擎列表
    docker exec -it searxng python -m searx.engines --update
    \n
  2. \n
  3. 监控指标集成
    通过 Prometheus 导出搜索统计:

    \n
    1
    2
    3
    docker run -d --network=searxng-net \\
    -v "${PWD}/metrics:/metrics" \\
    prom/prometheus --config.file=/metrics/searxng.yml
  4. \n
\n
\n

🚀 立即行动

\n

快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。

\n"},{"title":"命令行编辑器的优雅新选择","date":"2024-12-12T17:40:27.000Z","_content":"\n意外发现Zellij+Helix还挺好用的\n\n避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境\n\n稍微了解一下二者的快捷键就能舒适码字了\n\n甚至还都是rust出品\n\n即刻尝试一下[Zellij](https://zellij.dev/)和[Helix](https://helix-editor.com/)吧!\n\n// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh\n\n![实际效果](/images/zellij-helix.jpg)\n","source":"_posts/zellij-helix.md","raw":"---\ntitle: 命令行编辑器的优雅新选择\ndate: 2024-12-13 01:40:27\ntags: [技术分享]\n---\n\n意外发现Zellij+Helix还挺好用的\n\n避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境\n\n稍微了解一下二者的快捷键就能舒适码字了\n\n甚至还都是rust出品\n\n即刻尝试一下[Zellij](https://zellij.dev/)和[Helix](https://helix-editor.com/)吧!\n\n// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh\n\n![实际效果](/images/zellij-helix.jpg)\n","slug":"zellij-helix","published":1,"updated":"2025-02-23T15:53:44.966Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q70029p22bhwa5h4c5","content":"

意外发现Zellij+Helix还挺好用的

\n

避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境

\n

稍微了解一下二者的快捷键就能舒适码字了

\n

甚至还都是rust出品

\n

即刻尝试一下ZellijHelix吧!

\n

// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh

\n

\"实际效果\"

\n","excerpt":"","more":"

意外发现Zellij+Helix还挺好用的

\n

避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境

\n

稍微了解一下二者的快捷键就能舒适码字了

\n

甚至还都是rust出品

\n

即刻尝试一下ZellijHelix吧!

\n

// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh

\n

\"实际效果\"

\n"},{"title":"原来我还有个博客","date":"2024-06-02T16:19:55.000Z","_content":"\n2025-02-25\n\n最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~\n","source":"_posts/原来我还有个博客.md","raw":"---\ntitle: 原来我还有个博客\ndate: 2024-06-03 00:19:55\ntags: 日志\n---\n\n2025-02-25\n\n最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~\n","slug":"原来我还有个博客","published":1,"updated":"2025-02-25T04:26:34.224Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q7002ap22b9dhe4v4j","content":"

2025-02-25

\n

最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~

\n","excerpt":"","more":"

2025-02-25

\n

最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~

\n"},{"title":"梦开始的地方","date":"2023-12-06T14:53:35.000Z","_content":"\n不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。\n\n今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。\n\n> P.S.最近我都经历了些什么:\n>\n> 1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;\n> 2. 学习了一些C++基础,在洛谷上刷了不少算法题;\n> 3. ACM招新赛被薄纱,差一题进入校队;\n> 4. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;\n> 5. 入坑战地,爽爽爽;\n> 6. 被一位巨强的学长发掘,加入NUDT超算队;\n> 7. 面临三个考试周,熬过去就是胜利;\n\n虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。\n\n这里,毕竟是我梦开始的地方。\n\n> 胸怀祖国,团结协作,志在高峰,奋勇拼搏!\n\n今天是2023年12月6日,加油!\n\n------------------------\n\n修改一下,有的话还是不适合明说哦\n\n5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==\n\n","source":"_posts/梦开始的地方.md","raw":"---\ntitle: 梦开始的地方\ndate: 2023-12-06 22:53:35\ntags: 日志\n---\n\n不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。\n\n今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。\n\n> P.S.最近我都经历了些什么:\n>\n> 1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;\n> 2. 学习了一些C++基础,在洛谷上刷了不少算法题;\n> 3. ACM招新赛被薄纱,差一题进入校队;\n> 4. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;\n> 5. 入坑战地,爽爽爽;\n> 6. 被一位巨强的学长发掘,加入NUDT超算队;\n> 7. 面临三个考试周,熬过去就是胜利;\n\n虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。\n\n这里,毕竟是我梦开始的地方。\n\n> 胸怀祖国,团结协作,志在高峰,奋勇拼搏!\n\n今天是2023年12月6日,加油!\n\n------------------------\n\n修改一下,有的话还是不适合明说哦\n\n5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==\n\n","slug":"梦开始的地方","published":1,"updated":"2025-02-25T04:25:44.687Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q8002cp22baf84a55t","content":"

不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。

\n

今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。

\n
\n

P.S.最近我都经历了些什么:

\n
    \n
  1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;
  2. \n
  3. 学习了一些C++基础,在洛谷上刷了不少算法题;
  4. \n
  5. ACM招新赛被薄纱,差一题进入校队;
  6. \n
  7. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;
  8. \n
  9. 入坑战地,爽爽爽;
  10. \n
  11. 被一位巨强的学长发掘,加入NUDT超算队;
  12. \n
  13. 面临三个考试周,熬过去就是胜利;
  14. \n
\n
\n

虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。

\n

这里,毕竟是我梦开始的地方。

\n
\n

胸怀祖国,团结协作,志在高峰,奋勇拼搏!

\n
\n

今天是2023年12月6日,加油!

\n
\n

修改一下,有的话还是不适合明说哦

\n

5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==

\n","excerpt":"","more":"

不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。

\n

今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。

\n
\n

P.S.最近我都经历了些什么:

\n
    \n
  1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;
  2. \n
  3. 学习了一些C++基础,在洛谷上刷了不少算法题;
  4. \n
  5. ACM招新赛被薄纱,差一题进入校队;
  6. \n
  7. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;
  8. \n
  9. 入坑战地,爽爽爽;
  10. \n
  11. 被一位巨强的学长发掘,加入NUDT超算队;
  12. \n
  13. 面临三个考试周,熬过去就是胜利;
  14. \n
\n
\n

虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。

\n

这里,毕竟是我梦开始的地方。

\n
\n

胸怀祖国,团结协作,志在高峰,奋勇拼搏!

\n
\n

今天是2023年12月6日,加油!

\n
\n

修改一下,有的话还是不适合明说哦

\n

5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==

\n"}],"PostAsset":[],"PostCategory":[{"post_id":"cmaxzv0q0000ep22b165ba4w7","category_id":"cmaxzv0q1000hp22bhluuaucj","_id":"cmaxzv0q3000vp22b6vqk5sdr"},{"post_id":"cmaxzv0q1000jp22ba8qr4jxp","category_id":"cmaxzv0q2000pp22betjg2hmk","_id":"cmaxzv0q40011p22bgdb7967n"},{"post_id":"cmaxzv0q1000mp22b0a2hee98","category_id":"cmaxzv0q3000wp22be1q73d2r","_id":"cmaxzv0q40016p22b0fe5ah8t"},{"post_id":"cmaxzv0q40013p22bb8qjfb28","category_id":"cmaxzv0q2000pp22betjg2hmk","_id":"cmaxzv0q5001bp22b12t5f15v"},{"post_id":"cmaxzv0q2000op22b0gq70sf7","category_id":"cmaxzv0q40012p22b1fahbd6c","_id":"cmaxzv0q5001dp22bb2pd6ml5"},{"post_id":"cmaxzv0q40018p22b4lpt3rxw","category_id":"cmaxzv0q40012p22b1fahbd6c","_id":"cmaxzv0q5001gp22b55f8hbyf"}],"PostTag":[{"post_id":"cmaxzv0py0005p22bc6um14kc","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0pz0008p22b8jqq0j4x"},{"post_id":"cmaxzv0pv0001p22bbzg168j1","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0pz000ap22bdukigsbu"},{"post_id":"cmaxzv0py0006p22bg7b6evz0","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q0000dp22b47688tpa"},{"post_id":"cmaxzv0pz0009p22bgrxx8ce1","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q0000fp22b9i38gth6"},{"post_id":"cmaxzv0pw0002p22bg7e11agp","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q1000ip22bd89ybpin"},{"post_id":"cmaxzv0pz000bp22bbjfv42c1","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q1000lp22bdifb1kgd"},{"post_id":"cmaxzv0q0000ep22b165ba4w7","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q2000np22bgtoscrd6"},{"post_id":"cmaxzv0py0004p22ba4hiaw5j","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q2000qp22bemqw5n5b"},{"post_id":"cmaxzv0q0000gp22b315z7q3g","tag_id":"cmaxzv0q1000kp22b6huz9koz","_id":"cmaxzv0q3000tp22b9sgzbyfk"},{"post_id":"cmaxzv0q1000jp22ba8qr4jxp","tag_id":"cmaxzv0q2000sp22b1lzy4dl2","_id":"cmaxzv0q40010p22b42cc5u0u"},{"post_id":"cmaxzv0q40013p22bb8qjfb28","tag_id":"cmaxzv0q2000sp22b1lzy4dl2","_id":"cmaxzv0q40017p22b3xy5d0b9"},{"post_id":"cmaxzv0q1000mp22b0a2hee98","tag_id":"cmaxzv0q3000yp22b16lt9lz6","_id":"cmaxzv0q5001cp22bc78e5h7h"},{"post_id":"cmaxzv0q1000mp22b0a2hee98","tag_id":"cmaxzv0q2000sp22b1lzy4dl2","_id":"cmaxzv0q5001ep22bgule0k3j"},{"post_id":"cmaxzv0q2000op22b0gq70sf7","tag_id":"cmaxzv0q50019p22b6h9rb8cl","_id":"cmaxzv0q5001hp22bh5tc0998"},{"post_id":"cmaxzv0q2000rp22bgtkodqs6","tag_id":"cmaxzv0q5001fp22bfap9gc3g","_id":"cmaxzv0q6001kp22b2hjmbm4z"},{"post_id":"cmaxzv0q2000rp22bgtkodqs6","tag_id":"cmaxzv0q5001ip22b4gp0ai2e","_id":"cmaxzv0q6001lp22b6klu8s2j"},{"post_id":"cmaxzv0q3000up22bhurb7l9n","tag_id":"cmaxzv0q5001ip22b4gp0ai2e","_id":"cmaxzv0q6001pp22b5k4d7rzh"},{"post_id":"cmaxzv0q3000up22bhurb7l9n","tag_id":"cmaxzv0q6001mp22b9g48cdxa","_id":"cmaxzv0q6001qp22b48phb1fu"},{"post_id":"cmaxzv0q3000up22bhurb7l9n","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q6001sp22bgiyka8kk"},{"post_id":"cmaxzv0q3000xp22bd6qo3kl3","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q6001tp22b61vn2ps4"},{"post_id":"cmaxzv0q3000zp22b76yib05t","tag_id":"cmaxzv0q6001rp22b3fjc5gam","_id":"cmaxzv0q6001wp22b6vel6bdp"},{"post_id":"cmaxzv0q3000zp22b76yib05t","tag_id":"cmaxzv0q5001fp22bfap9gc3g","_id":"cmaxzv0q6001xp22bgxfwgdcn"},{"post_id":"cmaxzv0q40015p22bbk3g76eg","tag_id":"cmaxzv0q50019p22b6h9rb8cl","_id":"cmaxzv0q60021p22b6uda07c1"},{"post_id":"cmaxzv0q40015p22bbk3g76eg","tag_id":"cmaxzv0q6001yp22b139b5r6n","_id":"cmaxzv0q60022p22bg3vv5afb"},{"post_id":"cmaxzv0q40015p22bbk3g76eg","tag_id":"cmaxzv0q5001fp22bfap9gc3g","_id":"cmaxzv0q60024p22b093qbkg5"},{"post_id":"cmaxzv0q40018p22b4lpt3rxw","tag_id":"cmaxzv0q50019p22b6h9rb8cl","_id":"cmaxzv0q60025p22bg5h2851h"},{"post_id":"cmaxzv0q5001ap22b3mby9fa5","tag_id":"cmaxzv0q60023p22b80c8cqwr","_id":"cmaxzv0q70027p22b4ryv8241"},{"post_id":"cmaxzv0q5001ap22b3mby9fa5","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q70028p22bd9iacahc"},{"post_id":"cmaxzv0q70029p22bhwa5h4c5","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q8002bp22b7kvc8xf1"},{"post_id":"cmaxzv0q7002ap22b9dhe4v4j","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q8002dp22b4ii58lph"},{"post_id":"cmaxzv0q8002cp22baf84a55t","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q8002ep22b2um12srn"}],"Tag":[{"name":"日志","_id":"cmaxzv0px0003p22b4o7wd9zu"},{"name":"TEST","_id":"cmaxzv0q1000kp22b6huz9koz"},{"name":"音乐","_id":"cmaxzv0q2000sp22b1lzy4dl2"},{"name":"Vocaloid","_id":"cmaxzv0q3000yp22b16lt9lz6"},{"name":"技术","_id":"cmaxzv0q50019p22b6h9rb8cl"},{"name":"生活","_id":"cmaxzv0q5001fp22bfap9gc3g"},{"name":"Archlinux","_id":"cmaxzv0q5001ip22b4gp0ai2e"},{"name":"系统优化","_id":"cmaxzv0q6001mp22b9g48cdxa"},{"name":"技术分享","_id":"cmaxzv0q6001np22bd8d9goty"},{"name":"板绘","_id":"cmaxzv0q6001rp22b3fjc5gam"},{"name":"学习","_id":"cmaxzv0q6001yp22b139b5r6n"},{"name":"开源工具","_id":"cmaxzv0q60023p22b80c8cqwr"}]}} \ No newline at end of file +{"meta":{"version":1,"warehouse":"5.0.1"},"models":{"Asset":[{"_id":"source/images/1613f5602b203b38230f19699deb0219454454985.png","path":"images/1613f5602b203b38230f19699deb0219454454985.png","modified":0,"renderable":0},{"_id":"source/images/1730728153314.png","path":"images/1730728153314.png","modified":0,"renderable":0},{"_id":"source/images/20241027_222225.png","path":"images/20241027_222225.png","modified":0,"renderable":0},{"_id":"source/images/5364bba6d035326e82c53504dd53e7c2454454985.png","path":"images/5364bba6d035326e82c53504dd53e7c2454454985.png","modified":0,"renderable":0},{"_id":"source/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","path":"images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","modified":0,"renderable":0},{"_id":"source/images/Written-By-Human-Not-By-AI-Badge-white@2x.png","path":"images/Written-By-Human-Not-By-AI-Badge-white@2x.png","modified":0,"renderable":0},{"_id":"source/images/amd.webp","path":"images/amd.webp","modified":0,"renderable":0},{"_id":"source/images/archlinux-logo.png","path":"images/archlinux-logo.png","modified":0,"renderable":0},{"_id":"source/images/asc-events.png","path":"images/asc-events.png","modified":0,"renderable":0},{"_id":"source/images/asc.png","path":"images/asc.png","modified":0,"renderable":0},{"_id":"source/images/audiveris.png","path":"images/audiveris.png","modified":0,"renderable":0},{"_id":"source/images/b2054bbaf6197624d38cc2007d885fd1454454985.png","path":"images/b2054bbaf6197624d38cc2007d885fd1454454985.png","modified":0,"renderable":0},{"_id":"source/images/built_on_the_kde_platform.png","path":"images/built_on_the_kde_platform.png","modified":0,"renderable":0},{"_id":"source/images/caseclosed.png","path":"images/caseclosed.png","modified":0,"renderable":0},{"_id":"source/images/clonezilla.png","path":"images/clonezilla.png","modified":0,"renderable":0},{"_id":"source/images/lmms-import.png","path":"images/lmms-import.png","modified":0,"renderable":0},{"_id":"source/images/mhwilds4050.jpg","path":"images/mhwilds4050.jpg","modified":0,"renderable":0},{"_id":"source/images/mhwilds780M.jpg","path":"images/mhwilds780M.jpg","modified":0,"renderable":0},{"_id":"source/images/musecore-launch.png","path":"images/musecore-launch.png","modified":0,"renderable":0},{"_id":"source/images/musecore-to-midi.png","path":"images/musecore-to-midi.png","modified":0,"renderable":0},{"_id":"source/images/musecore.png","path":"images/musecore.png","modified":0,"renderable":0},{"_id":"source/images/phase1.png","path":"images/phase1.png","modified":0,"renderable":0},{"_id":"source/images/phase1_strings.png","path":"images/phase1_strings.png","modified":0,"renderable":0},{"_id":"source/images/phase_2_14.png","path":"images/phase_2_14.png","modified":0,"renderable":0},{"_id":"source/images/phase_4.png","path":"images/phase_4.png","modified":0,"renderable":0},{"_id":"source/images/searxng.png","path":"images/searxng.png","modified":0,"renderable":0},{"_id":"source/images/xb2score.png","path":"images/xb2score.png","modified":0,"renderable":0},{"_id":"source/images/zellij-helix.jpg","path":"images/zellij-helix.jpg","modified":0,"renderable":0},{"_id":"source/music/過ぎ去りし温もりの日々.mp3","path":"music/過ぎ去りし温もりの日々.mp3","modified":0,"renderable":0},{"_id":"themes/fluid/source/css/gitalk.css","path":"css/gitalk.css","modified":0,"renderable":1},{"_id":"themes/fluid/source/css/highlight-dark.styl","path":"css/highlight-dark.styl","modified":0,"renderable":1},{"_id":"themes/fluid/source/css/highlight.styl","path":"css/highlight.styl","modified":0,"renderable":1},{"_id":"themes/fluid/source/css/main.styl","path":"css/main.styl","modified":0,"renderable":1},{"_id":"themes/fluid/source/img/avatar.png","path":"img/avatar.png","modified":0,"renderable":1},{"_id":"themes/fluid/source/img/gensokyo.jpg","path":"img/gensokyo.jpg","modified":0,"renderable":1},{"_id":"themes/fluid/source/img/gh0s7.jpg","path":"img/gh0s7.jpg","modified":0,"renderable":1},{"_id":"themes/fluid/source/img/hifuu.png","path":"img/hifuu.png","modified":0,"renderable":1},{"_id":"themes/fluid/source/img/loading.gif","path":"img/loading.gif","modified":0,"renderable":1},{"_id":"themes/fluid/source/img/police_beian.png","path":"img/police_beian.png","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/boot.js","path":"js/boot.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/color-schema.js","path":"js/color-schema.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/events.js","path":"js/events.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/img-lazyload.js","path":"js/img-lazyload.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/leancloud.js","path":"js/leancloud.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/local-search.js","path":"js/local-search.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/plugins.js","path":"js/plugins.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/umami-view.js","path":"js/umami-view.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/js/utils.js","path":"js/utils.js","modified":0,"renderable":1},{"_id":"themes/fluid/source/xml/local-search.xml","path":"xml/local-search.xml","modified":0,"renderable":1}],"Cache":[{"_id":"source/about/index.md","hash":"ff7cd1481f3c669a04d7c8abf8851ab0cea5b2b9","modified":1740326480093},{"_id":"source/_posts/12月16-17日工作记录.md","hash":"9f5099a65180c2659f1a1ca218d518fc64965676","modified":1740320866747},{"_id":"source/_posts/12月18日工作记录.md","hash":"28892523fcc2fadb1514645a1c59d501ceab53da","modified":1740320866748},{"_id":"source/_posts/12月19日工作记录.md","hash":"058ca01b682cd36e202189ef025d6d4bb79259fb","modified":1740320866748},{"_id":"source/_posts/12月20日工作记录.md","hash":"0d883ab20ae59540f663c5377e799463762a3b11","modified":1740320866748},{"_id":"source/_posts/12月28日进度报告.md","hash":"4cbda36dc6a2c4bc67140e443638a73aadb18fdf","modified":1740320866748},{"_id":"source/_posts/12月31日进度报告.md","hash":"bf541fdb539029c98dedf975b0c15519adcea76e","modified":1740320866748},{"_id":"source/_posts/2025-5-21.md","hash":"2e1406ca2c83a1a91e78fd3453623ba732d81ee7","modified":1747834483639},{"_id":"source/_posts/BlogUpdate.md","hash":"2c694e3895b2ea0c0cea5f45ab2ec16a868a3df7","modified":1740320866748},{"_id":"source/_posts/CGH0S7-s-Blog.md","hash":"9a5c9461aba29f2447c0f6725f5425d5a05e32f0","modified":1740320866748},{"_id":"source/_posts/GentleJena.md","hash":"df1e35a93284d0b9e2d408635cd98481077d5155","modified":1740330871930},{"_id":"source/_posts/Vocaloid调教-晴天.md","hash":"9141182f5dbfbbd840ad340b3e5271507ddd8c94","modified":1740442745940},{"_id":"source/_posts/arch-nvidia.md","hash":"4144acad32a69e88ef6d5d7d5788da6d87a75193","modified":1738495295673},{"_id":"source/_posts/archlinux-game-fix.md","hash":"a4ab5bd2ca0cf941c5166d3945bd2a2076a54f1e","modified":1741618456788},{"_id":"source/_posts/archlinux-optimization.md","hash":"51c8c12110fb08a1edd1f727ab38a1b2568b690b","modified":1741619246618},{"_id":"source/_posts/clonezilla.md","hash":"598858976961c45ebbbf523014ee792951380dd3","modified":1740319930654},{"_id":"source/_posts/loopers.md","hash":"2b63f5abcfebc672e7f90b3e83cee1b5ac1d4eff","modified":1740320866748},{"_id":"source/_posts/mhwi.md","hash":"b9a73accf93684b8cfac0201288da9b2c5376423","modified":1731333619124},{"_id":"source/_posts/nudtbomblab.md","hash":"51b4410784657675d7c11e17d16c5dc0e5d4a455","modified":1740455795270},{"_id":"source/_posts/overleaf.md","hash":"0786994f4571ac178ee40bc130e3c0d8d2d511f9","modified":1730860316685},{"_id":"source/_posts/searxng.md","hash":"90f951d3c098aa1b062131b7489a4b7afab06792","modified":1741621615535},{"_id":"source/_posts/zellij-helix.md","hash":"7eb3072b50ecdb49a20355e05fc613a4a8b7fbdf","modified":1740326024966},{"_id":"source/_posts/原来我还有个博客.md","hash":"acd7e534b31b7a0173fae880fa584c7dc03fd2cd","modified":1740457594224},{"_id":"source/_posts/梦开始的地方.md","hash":"c0bbfefdd277c8ae2786a5cd4cc05f731af11436","modified":1740457544687},{"_id":"source/images/Written-By-Human-Not-By-AI-Badge-white@2x.png","hash":"994225c6fd72521b281144bdd98fefcca53e2c7b","modified":1731333731000},{"_id":"source/images/amd.webp","hash":"cb0cfd5da0b9c10b9b22c65bba881cfde485d763","modified":1731333907000},{"_id":"source/images/archlinux-logo.png","hash":"4f6075309fadcb7f7547164cb8a99b4949f74598","modified":1731333766000},{"_id":"source/images/asc-events.png","hash":"a0b3610962062d0a322fe091bcc8f083ab13bc6e","modified":1740329910965},{"_id":"source/images/asc.png","hash":"3a33b35bff1b3f527f7a87a9d6a7d6d9a072a946","modified":1740328627284},{"_id":"source/images/built_on_the_kde_platform.png","hash":"507b6a4323b23772800006505e6c588bb515ebf5","modified":1731334007000},{"_id":"source/images/phase1_strings.png","hash":"6fb457adddc5bb32aa463b6227542076c4b501e7","modified":1740382826998},{"_id":"source/images/searxng.png","hash":"9514f2bd14ac1cafa437f3655d9382d477667094","modified":1741619983804},{"_id":"source/images/caseclosed.png","hash":"628b54b49c86a23af595a52daba9e0557b81a17a","modified":1740454957882},{"_id":"source/images/audiveris.png","hash":"52aa9df5f93559c2e47b30afbf84fc6cc6b34002","modified":1744993135289},{"_id":"source/images/musecore-to-midi.png","hash":"02ba31b29ba069dfef0e1cf26c5ccec9dc3d2289","modified":1744993436860},{"_id":"source/images/1730728153314.png","hash":"95d44ea62557a311503cab58d1dec5cafc97e07d","modified":1740320866754},{"_id":"source/images/musecore.png","hash":"9b2eba87e7c93e57f2024697d1ff4217d206e5ac","modified":1744993264700},{"_id":"source/images/xb2score.png","hash":"03efbb07a7bb7f6c7d58b98ed125cafe42074b94","modified":1744992816374},{"_id":"source/images/phase1.png","hash":"42533712403be6036231f1e3770f125858bf91d7","modified":1740385026324},{"_id":"source/images/5364bba6d035326e82c53504dd53e7c2454454985.png","hash":"11b11f23ebebbe08e8cf826b48eb37b4084796cd","modified":1729572689000},{"_id":"themes/fluid/source/css/_pages/_tag/tag.styl","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1740320867063},{"_id":"source/images/1613f5602b203b38230f19699deb0219454454985.png","hash":"3d71204d9a0731384f97ad0f90802a5c9fd96776","modified":1729572689000},{"_id":"themes/fluid/.editorconfig","hash":"33218fbd623feb43edf5f99f15965392cecc44a6","modified":1740320867050},{"_id":"themes/fluid/.eslintrc","hash":"4bc2b19ce2b8c4d242f97d4ccf2d741e68ab0097","modified":1740320867050},{"_id":"themes/fluid/.gitignore","hash":"ae3bfcb89777657c5dfb5169d91445dcb0e5ab98","modified":1740320867051},{"_id":"themes/fluid/LICENSE","hash":"26f9356fd6e84b5a88df6d9014378f41b65ba209","modified":1740320867051},{"_id":"themes/fluid/README.md","hash":"ff9b0e1fb9dba665af2f1e4a577f8cb9e840464b","modified":1740320867051},{"_id":"themes/fluid/README_en.md","hash":"365184a73af40e7365504c3077f3d80dfee1d80e","modified":1740320867051},{"_id":"themes/fluid/package.json","hash":"7746460fc2eba7439b494c46aa9b5ded81370819","modified":1740320867057},{"_id":"themes/fluid/_config.yml","hash":"60403ea6aa5e0cab9dbc7bf0d77257e4a941babc","modified":1740329151304},{"_id":"themes/fluid/languages/de.yml","hash":"58dccef1d98b472dc4e6f4693c2297b0c9c5afba","modified":1740320867052},{"_id":"themes/fluid/languages/en.yml","hash":"9c580471257f5a32bee701a059a45ea96755dcdc","modified":1740320867052},{"_id":"themes/fluid/languages/eo.yml","hash":"7c1a0c9f6186b6643b19d3980f055329bdb4efa4","modified":1740320867052},{"_id":"themes/fluid/languages/es.yml","hash":"026ddf1a49bf8ddfef6ed86ab4d6af143c1dd95f","modified":1740320867052},{"_id":"themes/fluid/languages/ja.yml","hash":"550b95d3614a64592f02666938d235e9f11e449e","modified":1740320867052},{"_id":"themes/fluid/languages/ru.yml","hash":"93818f8bf07195fb1ebffbb5210e531b0e3a6ec4","modified":1740320867052},{"_id":"themes/fluid/languages/zh-CN.yml","hash":"a60847136709bb95586a98d9d67b50390a8d2c96","modified":1740320867052},{"_id":"themes/fluid/languages/zh-HK.yml","hash":"51c2b4d64c6992a39bfd2586a1bdf5fbbbdf0175","modified":1740320867052},{"_id":"themes/fluid/.gitattributes","hash":"a54f902957d49356376b59287b894b1a3d7a003f","modified":1740320867050},{"_id":"themes/fluid/languages/zh-TW.yml","hash":"e1043de394f6dcf5c0647adcfdefe60637f78426","modified":1740320867052},{"_id":"themes/fluid/layout/404.ejs","hash":"b84d575c7b7f778b4cb64e89ad3d0aed4a896820","modified":1740320867052},{"_id":"themes/fluid/layout/about.ejs","hash":"052e9fc19c753f53fdc083c7fb098e3668880140","modified":1740320867056},{"_id":"themes/fluid/layout/categories.ejs","hash":"13859726c27b6c79b5876ec174176d0f9c1ee164","modified":1740320867056},{"_id":"themes/fluid/layout/category.ejs","hash":"f099161b738a16a32253f42085b5444f902018ed","modified":1740320867056},{"_id":"themes/fluid/layout/index.ejs","hash":"33c3317cdcee062789de2336dd8d0cc7f86d3650","modified":1740320867056},{"_id":"themes/fluid/layout/layout.ejs","hash":"7e0023474128fbe4d68c467704c41f1712432415","modified":1740320867056},{"_id":"themes/fluid/layout/links.ejs","hash":"1cac32ec4579aaf7b9fa39d317497331d4c5e1dd","modified":1740320867056},{"_id":"themes/fluid/layout/page.ejs","hash":"ed5007a3feb8f14d3d2843271bfb298eb0c56219","modified":1740320867056},{"_id":"themes/fluid/layout/post.ejs","hash":"9bf0d357a607a282f3b9cb04525a4df0cc2a8b76","modified":1740320867056},{"_id":"themes/fluid/layout/tag.ejs","hash":"9d686364c4d16a1a9219471623af452035c5b966","modified":1740320867056},{"_id":"themes/fluid/layout/tags.ejs","hash":"1d06af34b6cf1d8a20d2eb565e309326ceba309f","modified":1740320867057},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/bug_report.md","hash":"554c0d0e086a0784d83ee71c83f8bceeb60aecc8","modified":1740320867050},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/bug_report_zh.md","hash":"c8b0d49c49e3c88872fd3b37909345ff5b2b6aa0","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/feature_request.md","hash":"c134dd57ffd269b93402ccfffe7dbe0f0b583bec","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/feature_request_zh.md","hash":"ed08574b196447376dd74411cca664ac9227a5d4","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/question.md","hash":"ab5eab9e3ff889c4ba7fd82846e7f5b7ae15bebc","modified":1740320867051},{"_id":"themes/fluid/layout/archive.ejs","hash":"7c1f44005849791feae4abaa10fae4cb983d3277","modified":1740320867056},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/question_zh.md","hash":"fff07ce0472afc368d388637cb9d438195da9b5b","modified":1740320867051},{"_id":"themes/fluid/.github/workflows/cr.yaml","hash":"19a8a00f5ba9607d82265572fe1202b64a8b0822","modified":1740320867051},{"_id":"themes/fluid/.github/workflows/limit.yaml","hash":"f8bd2edeb4424ee7a055b31583445d5d5dff91a4","modified":1740320867051},{"_id":"themes/fluid/.github/workflows/publish.yaml","hash":"6f02e6440d88629229556e3fd47d0280fe2240db","modified":1740320867051},{"_id":"themes/fluid/layout/_partials/archive-list.ejs","hash":"7520fbf91f762207c2ab06b2c293235cd5b23905","modified":1740320867052},{"_id":"themes/fluid/layout/_partials/category-chains.ejs","hash":"18309584aab83bc4deb20723ebad832149dd2e24","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/category-list.ejs","hash":"f8d2f1907450e61968e6d54443e9be8138196a77","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments.ejs","hash":"d707c47b2638c94e489bc43d4cfd098b7c58447f","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/css.ejs","hash":"1dadb118d580280524ed0a5f69bd34d234a92276","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/footer.ejs","hash":"b52aa2d61b6812588a805b676ffdf8b887023938","modified":1740330605855},{"_id":"themes/fluid/layout/_partials/head.ejs","hash":"67be642f99482c07904474f410cfbc2f99003288","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/header.ejs","hash":"0d5e397d30051e5fbabe7b47cfd1f1e6a5820af1","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/markdown-plugins.ejs","hash":"fc4bdf7de0cf1a66d0e5e4fba1b31d6f7ed49468","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/paginator.ejs","hash":"0f38a2c238169edcb63fc46c23bfc529ff3859b7","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/scripts.ejs","hash":"da5810785105e5075861593c7ac22c7aa9665a72","modified":1740320867056},{"_id":"themes/fluid/scripts/events/index.js","hash":"79de5a379b28cad759a49048351c7f6b8915bd7d","modified":1740320867057},{"_id":"themes/fluid/layout/_partials/search.ejs","hash":"70e1c929e084ca8a2648cedabf29b372511ea2b8","modified":1740320867056},{"_id":"themes/fluid/scripts/filters/default-injects.js","hash":"b2013ae8e189cd07ebc8a2ff48a78e153345210f","modified":1740320867057},{"_id":"themes/fluid/scripts/filters/locals.js","hash":"58d0fec976f6b1d35e7ea03edc45414088acf05c","modified":1740320867057},{"_id":"themes/fluid/scripts/filters/post-filter.js","hash":"82bb06686158ebe160a631c79f156cd4fde35656","modified":1740320867057},{"_id":"themes/fluid/scripts/generators/index-generator.js","hash":"9159fc22fa84a7b605dd15fe4104f01fe9c71147","modified":1740320867057},{"_id":"themes/fluid/scripts/generators/local-search.js","hash":"9ac5ddad06e9b0e6015ce531430018182a4bc0fa","modified":1740320867058},{"_id":"themes/fluid/scripts/generators/pages.js","hash":"d3e75f53c59674d171309e50702954671f31f1a4","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/date.js","hash":"9bda6382f61b40a20c24af466fe10c8366ebb74c","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/engine.js","hash":"d3a231d106795ce99cb0bc77eb65f9ae44515933","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/export-config.js","hash":"8e67b522c47aa250860e3fe2c733f1f958a506c0","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/import.js","hash":"ca53e8dbf7d44cfd372cfa79ac60f35a7d5b0076","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/injects.js","hash":"1ad2ae6b11bd8806ee7dd6eb7140d8b54a95d613","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/page.js","hash":"4607607445233b3029ef20ed5e91de0da0a7f9c5","modified":1740320867058},{"_id":"themes/fluid/scripts/helpers/scope.js","hash":"d41d9d658fcb54964b388598e996747aadb85b0f","modified":1740320867059},{"_id":"themes/fluid/scripts/helpers/url.js","hash":"2a6a8288176d0e0f6ec008056bf2745a86e8943e","modified":1740320867059},{"_id":"themes/fluid/scripts/helpers/utils.js","hash":"966689d7c5e4320008285395fbaa2751f6209be5","modified":1740320867059},{"_id":"themes/fluid/scripts/helpers/wordcount.js","hash":"4d48c424e47ff9a17a563167ea5f480890267adf","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/button.js","hash":"3eb43a8cdea0a64576ad6b31b4df6c2bf5698d4c","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/checkbox.js","hash":"6eaf53cf4bfc756a65bda18184cf8998a12c861d","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/fold.js","hash":"73e4fd12ce3e47981479391ed354b7d9d3279f70","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/group-image.js","hash":"4aeebb797026f1df25646a5d69f7fde79b1bcd26","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/label.js","hash":"f05a6d32cca79535b22907dc03edb9d3fa2d8176","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/mermaid.js","hash":"75160561e1ef3603b6d2ad2938464ab1cb77fd38","modified":1740320867059},{"_id":"themes/fluid/scripts/tags/note.js","hash":"e3b456a079e5dc0032473b516c865b20f83d2c26","modified":1740320867059},{"_id":"themes/fluid/scripts/utils/compare-versions.js","hash":"dbbc928c914fc2bd242cd66aa0c45971aec13a5d","modified":1740320867059},{"_id":"themes/fluid/scripts/utils/crypto.js","hash":"ae4ad8a188ef5b3fa6818b01629fc962b3de8551","modified":1740320867060},{"_id":"themes/fluid/scripts/utils/object.js","hash":"33b57e4decdc5e75c518859f168c8ba80b2c665b","modified":1740320867060},{"_id":"themes/fluid/scripts/utils/resolve.js","hash":"8c4a8b62aa8608f12f1e9046231dff04859dc3e9","modified":1740320867060},{"_id":"themes/fluid/scripts/utils/url-join.js","hash":"718aab5e7b2059a06b093ca738de420d9afa44ba","modified":1740320867060},{"_id":"themes/fluid/source/css/highlight-dark.styl","hash":"45695ef75c31a4aa57324dd408b7e2327a337018","modified":1740320867063},{"_id":"themes/fluid/source/css/gitalk.css","hash":"a57b3cc8e04a0a4a27aefa07facf5b5e7bca0e76","modified":1740320867063},{"_id":"themes/fluid/source/css/highlight.styl","hash":"a9efc52a646a9e585439c768557e3e3c9e3326dc","modified":1740320867063},{"_id":"themes/fluid/source/css/main.styl","hash":"855ae5fe229c51afa57f7645f6997a27a705d7e4","modified":1740320867063},{"_id":"themes/fluid/source/img/avatar.png","hash":"fe739a158cc128f70f780eb5fa96f388b81d478f","modified":1740320867063},{"_id":"themes/fluid/source/img/loading.gif","hash":"2d2fc0f947940f98c21afafef39ecf226a2e8d55","modified":1740320867086},{"_id":"themes/fluid/source/js/events.js","hash":"6869811f67e4c3de3edfa4b08464bb242b97a402","modified":1740320867086},{"_id":"themes/fluid/source/img/police_beian.png","hash":"90efded6baa2dde599a9d6b1387973e8e64923ea","modified":1740320867086},{"_id":"themes/fluid/source/js/color-schema.js","hash":"1ef88c881b9f942deadde3d890387b94c617342a","modified":1740320867086},{"_id":"themes/fluid/source/js/leancloud.js","hash":"eff77c7a5c399fcaefda48884980571e15243fc9","modified":1740320867086},{"_id":"themes/fluid/source/js/local-search.js","hash":"b9945f76f8682f3ec32edfb285b26eb559f7b7e8","modified":1740320867086},{"_id":"themes/fluid/source/js/plugins.js","hash":"c34916291e392a774ff3e85c55badb83e8661297","modified":1740320867087},{"_id":"themes/fluid/source/js/img-lazyload.js","hash":"cbdeca434ec4da51f488c821d51b4d23c73294af","modified":1740320867086},{"_id":"themes/fluid/source/js/umami-view.js","hash":"33c4b3883fa747604074ad3921606eeeaeb50716","modified":1740320867087},{"_id":"themes/fluid/source/js/utils.js","hash":"b82e7c289a66dfd36064470fd41c0e96fc598b43","modified":1740320867087},{"_id":"themes/fluid/layout/_partials/comments/changyan.ejs","hash":"c9b2d68ed3d375f1953e7007307d2a3f75ed6249","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/cusdis.ejs","hash":"5f9dc012be27040bbe874d0c093c0d53958cc987","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/disqus.ejs","hash":"aab4a4d24c55231a37db308ae94414319cecdd9b","modified":1740320867053},{"_id":"themes/fluid/source/xml/local-search.xml","hash":"8c96ba6a064705602ce28d096fd7dd9069630a55","modified":1740320867087},{"_id":"themes/fluid/layout/_partials/comments/discuss.ejs","hash":"98d065b58ce06b7d18bff3c974e96fa0f34ae03a","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/giscus.ejs","hash":"95f8b866b158eff9352c381c243b332a155a5110","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/gitalk.ejs","hash":"843bc141a4545eb20d1c92fb63c85d459b4271ec","modified":1740320867053},{"_id":"themes/fluid/source/js/boot.js","hash":"38bd26c6b7acdafda86dda3560e6a3ca488d3c76","modified":1740320867086},{"_id":"themes/fluid/layout/_partials/comments/livere.ejs","hash":"2264758fed57542a7389c7aa9f00f1aefa17eb87","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/remark42.ejs","hash":"d4e9532feeb02aed61bd15eda536b5b631454dac","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/twikoo.ejs","hash":"d84bcb5ccd78470a60c067fc914ac0ac67ac8777","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/utterances.ejs","hash":"c7ccf7f28308334a6da6f5425b141a24b5eca0e2","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/comments/valine.ejs","hash":"19ba937553dddd317f827d682661a1066a7b1f30","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/comments/waline.ejs","hash":"3d08c73b77e412d2f06a24d9344565fc7dbc76f8","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/footer/beian.ejs","hash":"4fb9b5dd3f3e41a586d6af44e5069afe7c81fff2","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/footer/statistics.ejs","hash":"954a29b58d72647d20450da270b5d8fb2e0824f5","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/header/banner.ejs","hash":"e07757b59e7b89eea213d0e595cb5932f812fd32","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/header/navigation.ejs","hash":"37d750428772d7c71ba36ce0c2540780d90fadea","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/plugins/analytics.ejs","hash":"e6dcbf1c2f56314d56bb46b50aca86ff68cacebd","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/anchorjs.ejs","hash":"40181442d3a2b8734783a0ad7caf2d2522e3f2ab","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/code-widget.ejs","hash":"3a505cba37942badf62a56bbb8b605b72af330aa","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/encrypt.ejs","hash":"0fff24cf5bf99fbe5c56c292e2eac4a89bf29db4","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/fancybox.ejs","hash":"9d1ea2a46b8c8ad8c168594d578f40764818ef13","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/highlight.ejs","hash":"7529dd215b09d3557804333942377b9e20fa554e","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/math.ejs","hash":"dcbf9a381ee76f2f1f75fcbc22c50a502ec85023","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/mermaid.ejs","hash":"03ac02762f801970d1c4e73d6ec8d4c503780e50","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/moment.ejs","hash":"4ff3fb1b60ccc95a0af3bbdbd0757fedefc088b5","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/nprogress.ejs","hash":"4c2d39ce816b8a6dcd6b53113c8695f8bd650a23","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/plugins/typed.ejs","hash":"f345374885cd6a334f09a11f59c443b5d577c06c","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/category-bar.ejs","hash":"8772bce97ed297e7a88523f4e939ed6436c22f87","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/meta-bottom.ejs","hash":"375974ec017696e294dc12469fb0ae257800dc2d","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/copyright.ejs","hash":"cbfa32c5f5973133afd043853b24f8200455cb2d","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/meta-top.ejs","hash":"54dd479dbb440126e4ddd9d902229db5afaaae98","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/sidebar-left.ejs","hash":"9992c99b3eb728ad195970e1b84d665f2c8691c4","modified":1740320867056},{"_id":"themes/fluid/scripts/events/lib/compatible-configs.js","hash":"ef474d1fa5bbafc52619ced0f9dc7eaf2affb363","modified":1740320867057},{"_id":"themes/fluid/layout/_partials/post/toc.ejs","hash":"635a89060fbf72eeda066fc4bd0a97462f069417","modified":1740320867056},{"_id":"themes/fluid/scripts/events/lib/footnote.js","hash":"c19ac8050b82c3676b0332a56099ccfcc36d9d52","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/hello.js","hash":"bd8376e1cf7892dc2daa58f2f443574be559fdbf","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/highlight.js","hash":"a5fe1deccb73b5f578797dbb11038efc15f63ce8","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/injects.js","hash":"5ae4b07204683e54b5a1b74e931702bbce2ac23e","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/lazyload.js","hash":"9ba0d4bc224e22af8a5a48d6ff13e5a0fcfee2a4","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/merge-configs.js","hash":"7c944c43b2ece5dd84859bd9d1fe955d13427387","modified":1740320867057},{"_id":"themes/fluid/source/css/_functions/base.styl","hash":"2e46f3f4e2c9fe34c1ff1c598738fc7349ae8188","modified":1740320867060},{"_id":"themes/fluid/source/css/_mixins/base.styl","hash":"542e306ee9494e8a78e44d6d7d409605d94caeb3","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/pages.styl","hash":"b8e887bc7fb3b765a1f8ec9448eff8603a41984f","modified":1740320867063},{"_id":"themes/fluid/source/css/_variables/base.styl","hash":"4ed5f0ae105ef4c7dd92eaf652ceda176c38e502","modified":1740320867063},{"_id":"themes/fluid/source/css/_pages/_about/about.styl","hash":"97fe42516ea531fdad771489b68aa8b2a7f6ae46","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/base.styl","hash":"643284c567665f96915f0b64e59934dda315f74d","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/inline.styl","hash":"411a3fa3f924a87e00ff04d18b5c83283b049a4d","modified":1740320867061},{"_id":"themes/fluid/layout/_partials/post/sidebar-right.ejs","hash":"d5fcc9b60e02f869a29a8c17a16a6028ecc1e6d8","modified":1740320867056},{"_id":"themes/fluid/source/css/_pages/_base/keyframes.styl","hash":"94065ea50f5bef7566d184f2422f6ac20866ba22","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_base/color-schema.styl","hash":"85492ef64d7e5f70f0f7e46d570bbc911e686d7e","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/print.styl","hash":"166afbc596ea4b552bad7290ec372d25ec34db7b","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_category/category-bar.styl","hash":"cc6df43fef6bb3efecbfdd8b9e467424a1dea581","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_archive/archive.styl","hash":"c475e6681546d30350eaed11f23081ecae80c375","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_category/category-chain.styl","hash":"0cdf7ef50dfd0669d3b257821384ff31cd81b7c9","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_category/category-list.styl","hash":"7edfe1b571ecca7d08f5f4dbcf76f4ffdcfbf0b5","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_index/index.styl","hash":"25fb6fa4c783b847c632584c49a7e1593cdb2f5d","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_links/links.styl","hash":"5c7f2044e3f1da05a3229537c06bd879836f8d6e","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/comment.styl","hash":"780f3788e7357bcd3f3262d781cb91bb53976a93","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/highlight.styl","hash":"4df764d298fe556e501db4afc2b05686fe6ebcfb","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/markdown.styl","hash":"1e3d3a82721e7c10bcfcecec6d81cf2979039452","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/post-page.styl","hash":"7eee3f78296a3c81849a5415d1d43dcc6e03e6aa","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_post/post-tag.styl","hash":"c96d36aa8fe20f0c3c1a29ee2473cd8064b10f73","modified":1740320867062},{"_id":"themes/fluid/source/css/_pages/_tag/tags.styl","hash":"65bfc01c76abc927fa1a23bf2422892b0d566c3f","modified":1740320867063},{"_id":"themes/fluid/source/css/_pages/_base/_widget/banner.styl","hash":"7a0bd629bc234fc75e3cc8e3715ffada92f09e73","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/anchorjs.styl","hash":"e0cebda4a6f499aff75e71417d88caa7ceb13b94","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/code-widget.styl","hash":"b66ab013f0f37d724a149b85b3c7432afcf460ad","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/board.styl","hash":"4397037fc3f0033dbe546c33cd9dbdabd8cb1632","modified":1740320867060},{"_id":"themes/fluid/source/css/_pages/_base/_widget/copyright.styl","hash":"26f71a9cd60d96bb0cb5bbdf58150b8e524d9707","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/footer.styl","hash":"2caaca71dd1ff63d583099ed817677dd267b457e","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/footnote.styl","hash":"ae9289cc89649af2042907f8a003303b987f3404","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/header.styl","hash":"d42b748f2f49ef32aafb1a21d75991d2459da927","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/modal.styl","hash":"adf6c1e5c8e1fb41c77ce6e2258001df61245aa2","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/ngrogress.styl","hash":"5d225357b4a58d46118e6616377168336ed44cb2","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/noscript.styl","hash":"0cf2f2bb44f456150d428016675d5876a9d2e2aa","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/pagination.styl","hash":"8bb1b68e5f3552cb48c2ffa31edbc53646a8fb4c","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/qrcode.styl","hash":"78704a94c0436097abfb0e0a57abeb3429c749b7","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/scroll-btn.styl","hash":"f0e429a27fa8a7658fcbddbb4d4dbe4afa12499a","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/search.styl","hash":"10f7e91a91e681fb9fe46f9df7707b9ef78707c8","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/toc.styl","hash":"9e7452aa2372153f25d7a4675c9d36d281a65d24","modified":1740320867061},{"_id":"source/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","hash":"dddf72bb12aef01baa3eb2017bb867f274059f12","modified":1729572689000},{"_id":"source/images/mhwilds4050.jpg","hash":"9b2b15c66e2340c15b86cec0fa8f818b67e06384","modified":1730738910727},{"_id":"themes/fluid/source/img/hifuu.png","hash":"331b5950baf96f5d39192bb42b7da4d22a08992e","modified":1740320867086},{"_id":"source/images/mhwilds780M.jpg","hash":"e2c59c6caae452afb424d9f2fc3a255a44121b49","modified":1730738926927},{"_id":"source/images/clonezilla.png","hash":"7f443d79783df3744b2e51613422ee8fd7eea6f8","modified":1740318117703},{"_id":"source/images/phase_2_14.png","hash":"f50399a9eb469ed1e063ff4ccc0e8636c1b75f1e","modified":1740407245723},{"_id":"source/images/phase_4.png","hash":"81cd309a8990e015a8679b6a4e26a27d804c1da6","modified":1740410093173},{"_id":"themes/fluid/source/img/gh0s7.jpg","hash":"1c5af4f8cacdc3c6adbe8334866774cca2944910","modified":1740320867085},{"_id":"source/images/20241027_222225.png","hash":"f0595d1315d94e72e61c69e0499e5129e1821ba1","modified":1740320866763},{"_id":"source/images/b2054bbaf6197624d38cc2007d885fd1454454985.png","hash":"b021e971cedaa55b273eab2b10be94f795b06922","modified":1729572689000},{"_id":"source/images/lmms-import.png","hash":"002535b55a41f7a7dcba24517dd2397589416a64","modified":1744993882632},{"_id":"source/music/過ぎ去りし温もりの日々.mp3","hash":"22016dcdfcbac9393afd3fe97f2d6d6009cd57f5","modified":1747827275971},{"_id":"source/images/musecore-launch.png","hash":"0a6c5642d05b197555135cd602886311a9122df0","modified":1744993224514},{"_id":"source/images/zellij-helix.jpg","hash":"87fb5b7b51a4e3b062b891c04488a53457edded0","modified":1738492100321},{"_id":"themes/fluid/source/img/gensokyo.jpg","hash":"d82c0d5011c6cbc37109c9c80530d14cd266286f","modified":1740320867082},{"_id":"public/local-search.xml","hash":"c52e41f9d50ddb0d0d1fc704bc774bee3d573a07","modified":1747899672199},{"_id":"public/about/index.html","hash":"cf21ca666c882e4bdb83f83119a48053a895b443","modified":1747835050737},{"_id":"public/2025/05/21/2025-5-21/index.html","hash":"37881747e0ab8347571056ef1e32a7b578afb140","modified":1747899672199},{"_id":"public/2025/03/10/archlinux-game-fix/index.html","hash":"9ae2ff5a413222135be2c4cc1bc0913ed39ad390","modified":1747835050737},{"_id":"public/2025/03/10/searxng/index.html","hash":"2c8ae7693b4ece22f83f7536e4d2a5032499da90","modified":1747835050737},{"_id":"public/2025/02/23/clonezilla/index.html","hash":"18b734abda3405019efcab2523f12e766bfa73a3","modified":1747835050737},{"_id":"public/2024/12/13/zellij-helix/index.html","hash":"952cd837e89121b41cef1b3fe92fc98f6253bcc4","modified":1747835050737},{"_id":"public/2025/02/24/nudtbomblab/index.html","hash":"0a6392b9894d41caded05b2012588c043d91cc68","modified":1747835050737},{"_id":"public/2024/11/11/mhwi/index.html","hash":"ebe1a9550fe14035a215f067342373d3e2a2e8c5","modified":1747835050737},{"_id":"public/2025/02/02/archlinux-optimization/index.html","hash":"1e3734b7817998fe800911dbb15e6c0fdb2f55f8","modified":1747835050737},{"_id":"public/2024/11/06/overleaf/index.html","hash":"bc411b1a10fcbb6a5f6d0d213fa63f093830cae3","modified":1747835050737},{"_id":"public/2024/11/04/BlogUpdate/index.html","hash":"ac98c86ad12b3074414a44bfdf3ed153320d3a03","modified":1747835050737},{"_id":"public/2024/11/04/Vocaloid调教-晴天/index.html","hash":"a3dd5c0b77bd2eb77555d349177492a02e17fd25","modified":1747835050737},{"_id":"public/2024/11/06/arch-nvidia/index.html","hash":"8ade129a78d71d3017432e1a65e1d6d292a16c53","modified":1747835050737},{"_id":"public/2024/06/03/原来我还有个博客/index.html","hash":"7215c9a90d0695469c179717d27194e346a8abd0","modified":1747835050737},{"_id":"public/2023/12/31/12月31日进度报告/index.html","hash":"03f909c8954f0e623ccaf2e30fa44a1d3f45814b","modified":1747835050737},{"_id":"public/2024/11/04/loopers/index.html","hash":"9eceb4b3fc581ba245f16a1b0217f5d2b1594b47","modified":1747835050737},{"_id":"public/2023/12/28/12月28日进度报告/index.html","hash":"5aa948c12c109b08b781baf308c9a80ddd3bc379","modified":1747835050737},{"_id":"public/2024/10/30/GentleJena/index.html","hash":"0747019314125e796e102155e09febb4cbdb9b67","modified":1747835050737},{"_id":"public/2023/12/19/12月19日工作记录/index.html","hash":"bac072049959ec19cb53ad4b9180b53476c3542f","modified":1747835050737},{"_id":"public/2023/12/18/12月18日工作记录/index.html","hash":"82d3d1cab693f7808b28ed48803229a5290ee798","modified":1747835050737},{"_id":"public/2023/12/20/12月20日工作记录/index.html","hash":"5ee7c6817c2202a86dcf8e7e6898d2559c69dcf2","modified":1747835050737},{"_id":"public/2023/12/06/CGH0S7-s-Blog/index.html","hash":"b13772d5d9a1a7a19d1f565a27e8a9432f0da543","modified":1747835050737},{"_id":"public/categories/更新/index.html","hash":"39ae73dfc0e214df88912e0a38b4cbf3b55e13a4","modified":1747835050737},{"_id":"public/2023/12/06/梦开始的地方/index.html","hash":"2df05084144d2567e92d3b9f59afbb720fbed05a","modified":1747835050737},{"_id":"public/categories/Rearrangement/index.html","hash":"d86532128355807b19a6eb69208699289b62cfb7","modified":1747835050737},{"_id":"public/2023/12/17/12月16-17日工作记录/index.html","hash":"2af885a19d1b28c3a1e6d4afdf110c6733a4c6b5","modified":1747835050737},{"_id":"public/categories/技术分享/index.html","hash":"af921a46b2c79d42f3f975638ec3b7133af7028b","modified":1747835050737},{"_id":"public/archives/index.html","hash":"2e557cbbc621643eabf7bde677f1b280720bb940","modified":1747899672199},{"_id":"public/categories/Vocaloid/index.html","hash":"048aca4e241b331d0209e9208c379fcf665a0fae","modified":1747835050737},{"_id":"public/archives/page/3/index.html","hash":"890e99b1b83a4c139dfe654819a342c0518a89d1","modified":1747899672199},{"_id":"public/archives/2023/index.html","hash":"93001832510813a1e3d656448e9969bf4ee498f5","modified":1747899672199},{"_id":"public/archives/2024/index.html","hash":"dcca5dd0a819cd5aedaedd3e5c8327c6caaff491","modified":1747899672199},{"_id":"public/archives/2024/06/index.html","hash":"77a7c591f7cb894710066ca7aa4f2dd3348970c8","modified":1747899672199},{"_id":"public/archives/2024/10/index.html","hash":"cb3837a57c7b1ec97a6f7ceb05920c475610e910","modified":1747899672199},{"_id":"public/archives/page/2/index.html","hash":"9a3a4bb1dc546fba0532ff9ce8a3d9b535dead5e","modified":1747899672199},{"_id":"public/archives/2023/12/index.html","hash":"1c82c9a5b5f8a76b2af8dc28805113fdfcd86b06","modified":1747899672199},{"_id":"public/archives/2024/11/index.html","hash":"25b618969d1e159a79f0789df79a88d00298eddf","modified":1747899672199},{"_id":"public/archives/2025/02/index.html","hash":"2d7afb04692d90546c1939391c5d433a5fea2960","modified":1747899672199},{"_id":"public/archives/2024/12/index.html","hash":"2b0a125eb183fe01209c6343727afd20c4cff5f3","modified":1747899672199},{"_id":"public/archives/2025/index.html","hash":"78289d254176e22347426cf8ee9e87b1b5871b70","modified":1747899672199},{"_id":"public/index.html","hash":"dcce95fc88d7138f8f486e8801fd093bc4a0c645","modified":1747899672199},{"_id":"public/archives/2025/03/index.html","hash":"3e6e4a98d0f7f38c195d84415c4855464ae5f7bf","modified":1747899672199},{"_id":"public/page/2/index.html","hash":"a8e33d3fe15f44a42bd73e1bef2886c87fa95771","modified":1747899672199},{"_id":"public/archives/2025/05/index.html","hash":"5c06d3d3574a806ce7502dd26097a14fd802ef7e","modified":1747899672199},{"_id":"public/tags/日志/index.html","hash":"0160660df456d6993ffff1eb4e8397f5198d8d39","modified":1747899672199},{"_id":"public/page/3/index.html","hash":"766bf1df9b5c0ac21909270c251e28d535c94a94","modified":1747899672199},{"_id":"public/tags/音乐/index.html","hash":"0c4de7bf53b25a52c23aaf27d7327d49d165268b","modified":1747835050737},{"_id":"public/tags/技术/index.html","hash":"1dea2413397a9fdfba26ee98c8c69adc280d17e9","modified":1747835050737},{"_id":"public/tags/Vocaloid/index.html","hash":"98440598d6da10f35250eb46e393c0f7199fd848","modified":1747835050737},{"_id":"public/tags/Archlinux/index.html","hash":"5a8f0e067e637caac2101ea74f750f5ad9d0e45d","modified":1747835050737},{"_id":"public/tags/系统优化/index.html","hash":"ff22e88f749e9ff6b5e47143fa5a24d3389a1795","modified":1747835050737},{"_id":"public/tags/技术分享/index.html","hash":"04a2f939d67c26b002b2a6e66fc8b7ce798263a7","modified":1747835050737},{"_id":"public/tags/TEST/index.html","hash":"2e5789b8e544c5e8404441c75b054f661294306a","modified":1747835050737},{"_id":"public/tags/学习/index.html","hash":"b754a2106f26f5f90fd1d4e6370b58904b39eda3","modified":1747835050737},{"_id":"public/tags/开源工具/index.html","hash":"413cb791b6e4f8b10b692a372aba73a022472720","modified":1747835050737},{"_id":"public/404.html","hash":"4696437e74fa558f8be811e50fdfd88f2a84e82b","modified":1747835050737},{"_id":"public/tags/生活/index.html","hash":"8b296e4d7b64147895e55bb3f111bffa0ca4ab8b","modified":1747835050737},{"_id":"public/categories/index.html","hash":"f2bbc847232265380a90a69b0d2f3bfb05137d31","modified":1747835050737},{"_id":"public/tags/index.html","hash":"d8f11049bfd72b2103dc113194a4c2c283e7ba8d","modified":1747835050737},{"_id":"public/links/index.html","hash":"46f6120a630849e03697e69a4e74e876f37c1de1","modified":1747899672199},{"_id":"public/tags/板绘/index.html","hash":"05cf911d2c26ed5f6d104d875c11762e6e55b12e","modified":1747835050737},{"_id":"public/images/asc-events.png","hash":"a0b3610962062d0a322fe091bcc8f083ab13bc6e","modified":1747835050737},{"_id":"public/images/amd.webp","hash":"cb0cfd5da0b9c10b9b22c65bba881cfde485d763","modified":1747835050737},{"_id":"public/images/Written-By-Human-Not-By-AI-Badge-white@2x.png","hash":"994225c6fd72521b281144bdd98fefcca53e2c7b","modified":1747835050737},{"_id":"public/images/archlinux-logo.png","hash":"4f6075309fadcb7f7547164cb8a99b4949f74598","modified":1747835050737},{"_id":"public/images/asc.png","hash":"3a33b35bff1b3f527f7a87a9d6a7d6d9a072a946","modified":1747835050737},{"_id":"public/images/built_on_the_kde_platform.png","hash":"507b6a4323b23772800006505e6c588bb515ebf5","modified":1747835050737},{"_id":"public/img/avatar.png","hash":"fe739a158cc128f70f780eb5fa96f388b81d478f","modified":1747835050737},{"_id":"public/img/police_beian.png","hash":"90efded6baa2dde599a9d6b1387973e8e64923ea","modified":1747835050737},{"_id":"public/xml/local-search.xml","hash":"8c96ba6a064705602ce28d096fd7dd9069630a55","modified":1747835050737},{"_id":"public/img/loading.gif","hash":"2d2fc0f947940f98c21afafef39ecf226a2e8d55","modified":1747835050737},{"_id":"public/images/phase1_strings.png","hash":"6fb457adddc5bb32aa463b6227542076c4b501e7","modified":1747835050737},{"_id":"public/img/hifuu.png","hash":"331b5950baf96f5d39192bb42b7da4d22a08992e","modified":1747835050737},{"_id":"public/css/gitalk.css","hash":"a57b3cc8e04a0a4a27aefa07facf5b5e7bca0e76","modified":1747835050737},{"_id":"public/css/highlight.css","hash":"04d4ddbb5e1d1007447c2fe293ee05aae9b9563e","modified":1747835050737},{"_id":"public/css/main.css","hash":"06433abcb688c2f5473623a9355bff9865c48d3f","modified":1747835050737},{"_id":"public/css/highlight-dark.css","hash":"902294bada4323c0f51502d67cba8c3a0298952f","modified":1747835050737},{"_id":"public/js/boot.js","hash":"38bd26c6b7acdafda86dda3560e6a3ca488d3c76","modified":1747835050737},{"_id":"public/js/color-schema.js","hash":"1ef88c881b9f942deadde3d890387b94c617342a","modified":1747835050737},{"_id":"public/js/img-lazyload.js","hash":"cbdeca434ec4da51f488c821d51b4d23c73294af","modified":1747835050737},{"_id":"public/js/leancloud.js","hash":"eff77c7a5c399fcaefda48884980571e15243fc9","modified":1747835050737},{"_id":"public/js/plugins.js","hash":"c34916291e392a774ff3e85c55badb83e8661297","modified":1747835050737},{"_id":"public/js/local-search.js","hash":"b9945f76f8682f3ec32edfb285b26eb559f7b7e8","modified":1747835050737},{"_id":"public/js/events.js","hash":"6869811f67e4c3de3edfa4b08464bb242b97a402","modified":1747835050737},{"_id":"public/js/utils.js","hash":"b82e7c289a66dfd36064470fd41c0e96fc598b43","modified":1747835050737},{"_id":"public/js/umami-view.js","hash":"33c4b3883fa747604074ad3921606eeeaeb50716","modified":1747835050737},{"_id":"public/images/searxng.png","hash":"9514f2bd14ac1cafa437f3655d9382d477667094","modified":1747835050737},{"_id":"public/images/caseclosed.png","hash":"628b54b49c86a23af595a52daba9e0557b81a17a","modified":1747835050737},{"_id":"public/images/audiveris.png","hash":"52aa9df5f93559c2e47b30afbf84fc6cc6b34002","modified":1747835050737},{"_id":"public/images/musecore-to-midi.png","hash":"02ba31b29ba069dfef0e1cf26c5ccec9dc3d2289","modified":1747835050737},{"_id":"public/images/1730728153314.png","hash":"95d44ea62557a311503cab58d1dec5cafc97e07d","modified":1747835050737},{"_id":"public/images/musecore.png","hash":"9b2eba87e7c93e57f2024697d1ff4217d206e5ac","modified":1747835050737},{"_id":"public/img/gh0s7.jpg","hash":"1c5af4f8cacdc3c6adbe8334866774cca2944910","modified":1747835050737},{"_id":"public/images/xb2score.png","hash":"03efbb07a7bb7f6c7d58b98ed125cafe42074b94","modified":1747835050737},{"_id":"public/images/phase1.png","hash":"42533712403be6036231f1e3770f125858bf91d7","modified":1747835050737},{"_id":"public/images/5364bba6d035326e82c53504dd53e7c2454454985.png","hash":"11b11f23ebebbe08e8cf826b48eb37b4084796cd","modified":1747835050737},{"_id":"public/images/1613f5602b203b38230f19699deb0219454454985.png","hash":"3d71204d9a0731384f97ad0f90802a5c9fd96776","modified":1747835050737},{"_id":"public/images/mhwilds4050.jpg","hash":"9b2b15c66e2340c15b86cec0fa8f818b67e06384","modified":1747835050737},{"_id":"public/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","hash":"dddf72bb12aef01baa3eb2017bb867f274059f12","modified":1747835050737},{"_id":"public/images/mhwilds780M.jpg","hash":"e2c59c6caae452afb424d9f2fc3a255a44121b49","modified":1747835050737},{"_id":"public/images/clonezilla.png","hash":"7f443d79783df3744b2e51613422ee8fd7eea6f8","modified":1747835050737},{"_id":"public/images/phase_4.png","hash":"81cd309a8990e015a8679b6a4e26a27d804c1da6","modified":1747835050737},{"_id":"public/images/phase_2_14.png","hash":"f50399a9eb469ed1e063ff4ccc0e8636c1b75f1e","modified":1747835050737},{"_id":"public/images/20241027_222225.png","hash":"f0595d1315d94e72e61c69e0499e5129e1821ba1","modified":1747835050737},{"_id":"public/images/b2054bbaf6197624d38cc2007d885fd1454454985.png","hash":"b021e971cedaa55b273eab2b10be94f795b06922","modified":1747835050737},{"_id":"public/images/lmms-import.png","hash":"002535b55a41f7a7dcba24517dd2397589416a64","modified":1747835050737},{"_id":"public/music/過ぎ去りし温もりの日々.mp3","hash":"22016dcdfcbac9393afd3fe97f2d6d6009cd57f5","modified":1747835050737},{"_id":"public/images/musecore-launch.png","hash":"0a6c5642d05b197555135cd602886311a9122df0","modified":1747835050737},{"_id":"public/images/zellij-helix.jpg","hash":"87fb5b7b51a4e3b062b891c04488a53457edded0","modified":1747835050737},{"_id":"public/img/gensokyo.jpg","hash":"d82c0d5011c6cbc37109c9c80530d14cd266286f","modified":1747835050737},{"_id":"source/_posts/fortune.md","hash":"e249e56dad408ad79b11efc90aa42f764cf1c665","modified":1747899668523},{"_id":"public/2025/05/22/fortune/index.html","hash":"0d3c7f9e10c3c788f3b30273c9566bdb90f6f74e","modified":1747899672199},{"_id":"public/tags/日志/page/2/index.html","hash":"aa57dfa5c3f0f079ee752c53af3c798fd920d955","modified":1747899672199}],"Category":[{"name":"更新","_id":"cmaxzv0q1000hp22bhluuaucj"},{"name":"Rearrangement","_id":"cmaxzv0q2000pp22betjg2hmk"},{"name":"Vocaloid","_id":"cmaxzv0q3000wp22be1q73d2r"},{"name":"技术分享","_id":"cmaxzv0q40012p22b1fahbd6c"}],"Data":[],"Page":[{"title":"About","date":"2024-11-04T14:46:12.000Z","layout":"about","_content":"\n白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧\n\n爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇\n\n截至目前最喜欢的歌手是宇多田光❤️\n\n联系方式:\n\n- Email: \n\n- Github: \n","source":"about/index.md","raw":"---\ntitle: About\ndate: 2024-11-04 22:46:12\nlayout: about\n---\n\n白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧\n\n爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇\n\n截至目前最喜欢的歌手是宇多田光❤️\n\n联系方式:\n\n- Email: \n\n- Github: \n","updated":"2025-02-23T16:01:20.093Z","path":"about/index.html","comments":1,"_id":"cmaxzv0pu0000p22bd8nm6uwd","content":"

白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧

\n

爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇

\n

截至目前最喜欢的歌手是宇多田光❤️

\n

联系方式:

\n\n","excerpt":"","more":"

白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧

\n

爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇

\n

截至目前最喜欢的歌手是宇多田光❤️

\n

联系方式:

\n\n"}],"Post":[{"title":"12月16-17日工作记录","date":"2023-12-17T14:26:17.000Z","_content":"## 12月16-17日\n1. 四级考试\n2. 自学cuda,openacc,了解GPU架构知识\n3. 参加超算队启动会\n4. 大计和高数期中考试\n5. 研究spack使用\n6. 学习cuda编程\n7. 补作业\n","source":"_posts/12月16-17日工作记录.md","raw":"---\ntitle: 12月16-17日工作记录\ndate: 2023-12-17 22:26:17\ntags: [日志]\n---\n## 12月16-17日\n1. 四级考试\n2. 自学cuda,openacc,了解GPU架构知识\n3. 参加超算队启动会\n4. 大计和高数期中考试\n5. 研究spack使用\n6. 学习cuda编程\n7. 补作业\n","slug":"12月16-17日工作记录","published":1,"updated":"2025-02-23T14:27:46.747Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pv0001p22bbzg168j1","content":"

12月16-17日

    \n
  1. 四级考试
  2. \n
  3. 自学cuda,openacc,了解GPU架构知识
  4. \n
  5. 参加超算队启动会
  6. \n
  7. 大计和高数期中考试
  8. \n
  9. 研究spack使用
  10. \n
  11. 学习cuda编程
  12. \n
  13. 补作业
  14. \n
\n","excerpt":"","more":"

12月16-17日

    \n
  1. 四级考试
  2. \n
  3. 自学cuda,openacc,了解GPU架构知识
  4. \n
  5. 参加超算队启动会
  6. \n
  7. 大计和高数期中考试
  8. \n
  9. 研究spack使用
  10. \n
  11. 学习cuda编程
  12. \n
  13. 补作业
  14. \n
\n"},{"title":"12月19日工作记录","date":"2023-12-19T13:59:47.000Z","_content":"## 12月18日\n1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;\n2. 学习cuda编程.\n","source":"_posts/12月19日工作记录.md","raw":"---\ntitle: 12月19日工作记录\ndate: 2023-12-19 21:59:47\ntags: [日志]\n---\n## 12月18日\n1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;\n2. 学习cuda编程.\n","slug":"12月19日工作记录","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pw0002p22bg7e11agp","content":"

12月18日

    \n
  1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;
  2. \n
  3. 学习cuda编程.
  4. \n
\n","excerpt":"","more":"

12月18日

    \n
  1. 彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;
  2. \n
  3. 学习cuda编程.
  4. \n
\n"},{"title":"12月18日工作记录","date":"2023-12-18T13:57:34.000Z","_content":"## 12月18日\n1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;\n2. 协助Neko组完成任务;\n3. 找出spack存在网络原因无法下载时的手动解决方案.","source":"_posts/12月18日工作记录.md","raw":"---\ntitle: 12月18日工作记录\ndate: 2023-12-18 21:57:34\ntags: [日志]\n---\n## 12月18日\n1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;\n2. 协助Neko组完成任务;\n3. 找出spack存在网络原因无法下载时的手动解决方案.","slug":"12月18日工作记录","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0py0004p22ba4hiaw5j","content":"

12月18日

    \n
  1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;
  2. \n
  3. 协助Neko组完成任务;
  4. \n
  5. 找出spack存在网络原因无法下载时的手动解决方案.
  6. \n
\n","excerpt":"","more":"

12月18日

    \n
  1. 初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;
  2. \n
  3. 协助Neko组完成任务;
  4. \n
  5. 找出spack存在网络原因无法下载时的手动解决方案.
  6. \n
\n"},{"title":"12月20日工作记录","date":"2023-12-20T13:56:42.000Z","_content":"## 12月20日\n\nOpenCAEPoro 小组(黄**,梁**,程**)\n\n1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果\n\n> 优化方向基本确定为OpenMP/OpenACC并行化+cuda移植\n\n2. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求\n","source":"_posts/12月20日工作记录.md","raw":"---\ntitle: 12月20日工作记录\ndate: 2023-12-20 21:56:42\ntags: 日志\n---\n## 12月20日\n\nOpenCAEPoro 小组(黄**,梁**,程**)\n\n1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果\n\n> 优化方向基本确定为OpenMP/OpenACC并行化+cuda移植\n\n2. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求\n","slug":"12月20日工作记录","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0py0005p22bc6um14kc","content":"

12月20日

OpenCAEPoro 小组(黄,梁,程**)

\n
    \n
  1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果
  2. \n
\n
\n

优化方向基本确定为OpenMP/OpenACC并行化+cuda移植

\n
\n
    \n
  1. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求
  2. \n
\n","excerpt":"","more":"

12月20日

OpenCAEPoro 小组(黄,梁,程**)

\n
    \n
  1. 阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果
  2. \n
\n
\n

优化方向基本确定为OpenMP/OpenACC并行化+cuda移植

\n
\n
    \n
  1. 赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求
  2. \n
\n"},{"title":"12月28日进度报告","date":"2023-12-28T15:22:13.000Z","_content":"## 12月28日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果\n2. 继续学习openacc及cuda相关知识\n3. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备\n","source":"_posts/12月28日进度报告.md","raw":"---\ntitle: 12月28日进度报告\ndate: 2023-12-28 23:22:13\ntags: 日志\n---\n## 12月28日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果\n2. 继续学习openacc及cuda相关知识\n3. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备\n","slug":"12月28日进度报告","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0py0006p22bg7b6evz0","content":"

12月28日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果
  2. \n
  3. 继续学习openacc及cuda相关知识
  4. \n
  5. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备
  6. \n
\n","excerpt":"","more":"

12月28日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果
  2. \n
  3. 继续学习openacc及cuda相关知识
  4. \n
  5. 搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备
  6. \n
\n"},{"title":"12月30-31日进度报告","date":"2023-12-30T16:07:09.000Z","_content":"## 12月30-31日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;\n2. 收集运行数据用于proposal绘制图表;\n3. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.\n","source":"_posts/12月31日进度报告.md","raw":"---\ntitle: 12月30-31日进度报告\ndate: 2023-12-31 00:07:09\ntags: 日志\n---\n## 12月30-31日\n\nOpenCAEPoro 小组(黄**,梁**,程**,刘**)\n\n1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;\n2. 收集运行数据用于proposal绘制图表;\n3. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.\n","slug":"12月31日进度报告","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pz0009p22bgrxx8ce1","content":"

12月30-31日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;
  2. \n
  3. 收集运行数据用于proposal绘制图表;
  4. \n
  5. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.
  6. \n
\n","excerpt":"","more":"

12月30-31日

OpenCAEPoro 小组(黄,梁,程,刘

\n
    \n
  1. 服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;
  2. \n
  3. 收集运行数据用于proposal绘制图表;
  4. \n
  5. 继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.
  6. \n
\n"},{"title":"小满随笔——决断","date":"2025-05-21T11:59:21.000Z","_content":"\n
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。\n\n辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。\n\n小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。\n\n生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。\n\n因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。\n\n2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。\n\n*“回首向来萧瑟处,归去,也无风雨也无晴!”*\n","source":"_posts/2025-5-21.md","raw":"---\ntitle: 小满随笔——决断\ndate: 2025-05-21 19:59:21\ntags: 日志\n---\n\n
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。\n\n辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。\n\n小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。\n\n生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。\n\n因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。\n\n2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。\n\n*“回首向来萧瑟处,归去,也无风雨也无晴!”*\n","slug":"2025-5-21","published":1,"updated":"2025-05-21T13:34:43.639Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0pz000bp22bbjfv42c1","content":"
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n

我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。

\n

辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。

\n

小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。

\n

生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。

\n

因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。

\n

2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。

\n

“回首向来萧瑟处,归去,也无风雨也无晴!”

\n","excerpt":"","more":"
\n
\n Lost Days of Warmth - Yasunori Mitsuda\n
\n \n
\n\n

我本以为自己已经有足够的勇气和平静的心态去面对生活里的各种变故了,即便如此今天还是被突如其来的噩耗痛击得面目全非。

\n

辛辛苦苦和队友准备了大半年的ASC25失利,我想着以后回过头来看也不算什么以最快的速度调整心态;回校后一来就是各种烂摊子,写不完的作业补不完的课程,还有被脑子缺根筋的弱智评委恶意低分的大创立项成绩,我寻思这些事情烦完这阵也就过去了,人总不可能一直倒霉吧。结果就是今天下午排队验收CSAPP课程的shell实验时突然看到了外婆去世的消息,一时间两腿发软大脑空白不知所措,以至于后来排到我和教辅讲解实验过程时也是胡言乱语记不清自己到底说了什么,尽管最后还是被教辅满分放过了。

\n

小时候家里没现在景气,父母在市内打拼我则是被送到郊区被外婆抚养长大,上小学后为了让我进入一中直升班从二年级起我就被送进了奥数培训班,同时搬离了自己长大的地方,再到后来市政府改造,外婆家早已被拆得无影无踪,昔日的小伙伴杳无音信,温馨错杂的小居民区变成了陌生嘈杂的大酒店和菜市场,每次路过都不敢停留。从那以后外婆成了我和童年之间仅剩的联系,尽管老人后来连我的样貌也记不清楚。现如今童年记忆里最后的故人业已离开,再回首已是一片虚无。多年前外婆犯脑溢血被抢救回来的时候医生还承诺老人家活到抱孙子没问题,如今却猝不及防地驾鹤西去。在各种小说和游戏中经历过不少难忘的生死离别,可是到了现实亲自经历依旧痛心疾首难以放下。

\n

生物无法教会人们生命究竟是什么,生活却一点就通。上一次经历这种打击还是10年左右外公离开,那时候太小什么都不懂,等长大理解了经历的时间又足以抹平悲痛。如今在我的眼里,生命就是思念,是世间个体对其他个体的牵挂与个体之间互相建立的羁绊。我真的想停留在永远的当下,和自己爱的人永远定格在某一个瞬间,每天早上是一样的朝阳,出门是熟悉的面孔,回家是亲切的声音。然而活着就意味着必须面对各种苦楚,死去元知万事空,只有离开才是最好的解脱,活着的人要背负更多。长者的时间在一天天减少,他们的生命需要由后人去延续,但是后人的生活也不容易,面对各种困境放弃往往比坚持更加轻松,更有甚者勇敢地选择自戕从而摆脱一切,但是这样是不对的,让其他人代替自己承受痛苦是不对的,令人悲伤的选择是不应该做出的,活着的人哪怕再苦,只要身上背负了其他人的思念也只能继续前进。

\n

因此,我绝对不能气馁,我珍视现在和亲人朋友的点点滴滴,珍惜自己现在拥有的一切,我以最真诚的爱回馈所有爱我的人,不论面前有多少困难,我都会尽全力克服,这不是为我自己,现在我被摧残得只想躺平摆烂,但是为了所有信任我关心我的人,如今我绝对不能停下脚步。从来就没有永远的当下,连接我和童年最后的纽带已经被切断,再也不能回头,留给我的只剩下面前的未来,需要我亲手创造的未来,只有承受住来自各方的打击,我才有能力去维护由我创造的未来,既然选择了远方,便只顾风雨兼程。

\n

2025年的长沙小满格外燥热,痛定思过后的心是如此平静,没有多少时间可以浪费了,无需多言。

\n

“回首向来萧瑟处,归去,也无风雨也无晴!”

\n"},{"title":"博客更新记录","date":"2024-11-04T15:18:02.000Z","_content":"\n- 博客主题更新为 `Fluid` 主题,原主题为 `Next`\n- 更新了访问地址为 `https://blog.hifuu.ink`\n- 新增了 `About` 页面\n- 新增了 `友链` 页面\n- 完善页面布局\n","source":"_posts/BlogUpdate.md","raw":"---\ntitle: 博客更新记录\ndate: 2024-11-04 23:18:02\ntags: 日志\ncategories: 更新\n---\n\n- 博客主题更新为 `Fluid` 主题,原主题为 `Next`\n- 更新了访问地址为 `https://blog.hifuu.ink`\n- 新增了 `About` 页面\n- 新增了 `友链` 页面\n- 完善页面布局\n","slug":"BlogUpdate","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q0000ep22b165ba4w7","content":"
    \n
  • 博客主题更新为 Fluid 主题,原主题为 Next
  • \n
  • 更新了访问地址为 https://blog.hifuu.ink
  • \n
  • 新增了 About 页面
  • \n
  • 新增了 友链 页面
  • \n
  • 完善页面布局
  • \n
\n","excerpt":"","more":"
    \n
  • 博客主题更新为 Fluid 主题,原主题为 Next
  • \n
  • 更新了访问地址为 https://blog.hifuu.ink
  • \n
  • 新增了 About 页面
  • \n
  • 新增了 友链 页面
  • \n
  • 完善页面布局
  • \n
\n"},{"title":"Welcome to CGH0S7's Blog","date":"2023-12-06T08:33:30.000Z","_content":"\nHello World !\n","source":"_posts/CGH0S7-s-Blog.md","raw":"---\ntitle: Welcome to CGH0S7's Blog \ndate: 2023-12-06 16:33:30\ntags: TEST\n---\n\nHello World !\n","slug":"CGH0S7-s-Blog","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q0000gp22b315z7q3g","content":"

Hello World !

\n","excerpt":"","more":"

Hello World !

\n"},{"title":"Gentle Jena","date":"2024-10-30T14:11:14.000Z","_content":"\n很喜欢的一首曲子\n顺便测试一下视频上传\n以后随缘更新各种乱七八糟的东西。。\n\n\n","source":"_posts/GentleJena.md","raw":"---\ntitle: Gentle Jena\ndate: 2024-10-30 22:11:14\ntags: 音乐\ncategories: Rearrangement\n---\n\n很喜欢的一首曲子\n顺便测试一下视频上传\n以后随缘更新各种乱七八糟的东西。。\n\n\n","slug":"GentleJena","published":1,"updated":"2025-02-23T17:14:31.930Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q1000jp22ba8qr4jxp","content":"

很喜欢的一首曲子
顺便测试一下视频上传
以后随缘更新各种乱七八糟的东西。。

\n\n","excerpt":"","more":"

很喜欢的一首曲子
顺便测试一下视频上传
以后随缘更新各种乱七八糟的东西。。

\n\n"},{"title":"Vocaloid调教-晴天(洛天依V4)","date":"2024-11-04T13:52:59.000Z","_content":"\n其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。\n\n“故事的小黄花,从出生那年就飘着...”\n\n{% raw %}\n\n{% endraw %}\n\n","source":"_posts/Vocaloid调教-晴天.md","raw":"---\ntitle: Vocaloid调教-晴天(洛天依v4)\ndate: 2024-11-04 21:52:59\ntags: [Vocaloid, 音乐]\ncategories: [Vocaloid]\n---\n\n其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。\n\n“故事的小黄花,从出生那年就飘着...”\n\n{% raw %}\n\n{% endraw %}\n\n","slug":"Vocaloid调教-晴天","published":1,"updated":"2025-02-25T00:19:05.940Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q1000mp22b0a2hee98","content":"

其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。

\n

“故事的小黄花,从出生那年就飘着…”

\n\n\n\n\n","excerpt":"","more":"

其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。

\n

“故事的小黄花,从出生那年就飘着…”

\n\n\n\n\n"},{"title":"Archlinux的KDE Plasma优先启用Nvidia独立显卡和混合显卡配置指北","date":"2024-11-06T02:02:04.000Z","_content":"本文将介绍在 **X11** 和 **Wayland** 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。**首先,请确保您已经正确安装了 Nvidia 驱动**(如果非 Mainline 内核,请使用 `nvidia-dkms` 或 `nvidia-open-dkms` 版本)。\n\n![Nvidia设置示意图](/images/5364bba6d035326e82c53504dd53e7c2454454985.png)\n\n### 适用系统\n\n对于 **CachyOS** 或 **EndeavourOS** 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:\n\n- Nvidia 驱动已安装,`nvidia-smi` 输出正常\n- KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显\n- 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象\n\n这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。\n\n---\n\n## 配置 X11 下的 Nvidia 显卡优先\n\n可以通过配置 `/etc/X11/xorg.conf` 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:\n\n```bash\nsudo nvidia-xconfig --prime\n```\n\n该命令会根据硬件情况自动生成配置文件。执行后 **重新登录会话** 即可生效(即使是 Wayland 用户也可以执行一次此命令)。\n\n![X11 Nvidia配置](/images/1613f5602b203b38230f19699deb0219454454985.png)\n\n---\n\n## 配置 Wayland 下的 Nvidia 显卡优先\n\n在 Wayland 下优先启用 Nvidia 显卡的步骤如下:\n\n1. 编辑 **GRUB 配置**文件:\n\n 打开 `/etc/default/grub` 文件,在 `GRUB_CMDLINE_LINUX_DEFAULT=\"\"` 中添加 `nvidia_drm.modeset=1`:\n\n ```bash\n GRUB_CMDLINE_LINUX_DEFAULT=\"nvidia_drm.modeset=1\"\n ```\n\n2. 重新生成 grub 配置:\n\n ```bash\n sudo grub-mkconfig -o /boot/grub/grub.cfg\n ```\n\n3. 配置 **Plasma 环境**文件:\n\n 在 `~/.config/plasma-workspace/env/nvidia.sh` 中写入以下内容:\n\n ```bash\n #!/bin/bash \n export __NV_PRIME_RENDER_OFFLOAD=1 \n export __GLX_VENDOR_LIBRARY_NAME=nvidia\n ```\n\n4. 保存并重启电脑,即可生效。\n\n![Wayland Nvidia配置](/images/b2054bbaf6197624d38cc2007d885fd1454454985.png)\n\n---\n\n## I+N 混合显卡方案\n\n如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。\n\n### 配置步骤\n\n1. 打开程序的 `.desktop` 启动文件:\n\n 位置可能在 `/usr/share/applications` 或 `~/.local/share/applications` 中。\n\n2. 在 `Exec=` 后添加 `prime-run` 参数。例如:\n\n ```text\n Exec=prime-run <程序启动命令>\n ```\n\n ![混合显卡配置示意图](/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png)\n\n### Vim 快捷配置\n\n如果使用 Vim,可以使用以下快捷键快速批量替换 `Exec=` 为 `Exec=prime-run`:\n\n```vim\nv -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter\n```\n\n---\n\n## 让 Plasma 桌面也使用独显\n\n如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:\n\n```bash\n#!/bin/bash \nexport __GLX_VENDOR_LIBRARY_NAME=nvidia\n```\n\n这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。\n\n---\n\n希望以上经验能为有此需求的用户提供参考帮助。\n","source":"_posts/arch-nvidia.md","raw":"---\ntitle: Archlinux的KDE Plasma优先启用Nvidia独立显卡和混合显卡配置指北\ndate: 2024-11-06 10:02:04\ntags: 技术\ncategories: [技术分享]\n---\n本文将介绍在 **X11** 和 **Wayland** 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。**首先,请确保您已经正确安装了 Nvidia 驱动**(如果非 Mainline 内核,请使用 `nvidia-dkms` 或 `nvidia-open-dkms` 版本)。\n\n![Nvidia设置示意图](/images/5364bba6d035326e82c53504dd53e7c2454454985.png)\n\n### 适用系统\n\n对于 **CachyOS** 或 **EndeavourOS** 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:\n\n- Nvidia 驱动已安装,`nvidia-smi` 输出正常\n- KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显\n- 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象\n\n这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。\n\n---\n\n## 配置 X11 下的 Nvidia 显卡优先\n\n可以通过配置 `/etc/X11/xorg.conf` 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:\n\n```bash\nsudo nvidia-xconfig --prime\n```\n\n该命令会根据硬件情况自动生成配置文件。执行后 **重新登录会话** 即可生效(即使是 Wayland 用户也可以执行一次此命令)。\n\n![X11 Nvidia配置](/images/1613f5602b203b38230f19699deb0219454454985.png)\n\n---\n\n## 配置 Wayland 下的 Nvidia 显卡优先\n\n在 Wayland 下优先启用 Nvidia 显卡的步骤如下:\n\n1. 编辑 **GRUB 配置**文件:\n\n 打开 `/etc/default/grub` 文件,在 `GRUB_CMDLINE_LINUX_DEFAULT=\"\"` 中添加 `nvidia_drm.modeset=1`:\n\n ```bash\n GRUB_CMDLINE_LINUX_DEFAULT=\"nvidia_drm.modeset=1\"\n ```\n\n2. 重新生成 grub 配置:\n\n ```bash\n sudo grub-mkconfig -o /boot/grub/grub.cfg\n ```\n\n3. 配置 **Plasma 环境**文件:\n\n 在 `~/.config/plasma-workspace/env/nvidia.sh` 中写入以下内容:\n\n ```bash\n #!/bin/bash \n export __NV_PRIME_RENDER_OFFLOAD=1 \n export __GLX_VENDOR_LIBRARY_NAME=nvidia\n ```\n\n4. 保存并重启电脑,即可生效。\n\n![Wayland Nvidia配置](/images/b2054bbaf6197624d38cc2007d885fd1454454985.png)\n\n---\n\n## I+N 混合显卡方案\n\n如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。\n\n### 配置步骤\n\n1. 打开程序的 `.desktop` 启动文件:\n\n 位置可能在 `/usr/share/applications` 或 `~/.local/share/applications` 中。\n\n2. 在 `Exec=` 后添加 `prime-run` 参数。例如:\n\n ```text\n Exec=prime-run <程序启动命令>\n ```\n\n ![混合显卡配置示意图](/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png)\n\n### Vim 快捷配置\n\n如果使用 Vim,可以使用以下快捷键快速批量替换 `Exec=` 为 `Exec=prime-run`:\n\n```vim\nv -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter\n```\n\n---\n\n## 让 Plasma 桌面也使用独显\n\n如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:\n\n```bash\n#!/bin/bash \nexport __GLX_VENDOR_LIBRARY_NAME=nvidia\n```\n\n这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。\n\n---\n\n希望以上经验能为有此需求的用户提供参考帮助。\n","slug":"arch-nvidia","published":1,"updated":"2025-02-02T11:21:35.673Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q2000op22b0gq70sf7","content":"

本文将介绍在 X11Wayland 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。首先,请确保您已经正确安装了 Nvidia 驱动(如果非 Mainline 内核,请使用 nvidia-dkmsnvidia-open-dkms 版本)。

\n

\"Nvidia设置示意图\"

\n

适用系统

对于 CachyOSEndeavourOS 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:

\n
    \n
  • Nvidia 驱动已安装,nvidia-smi 输出正常
  • \n
  • KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显
  • \n
  • 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象
  • \n
\n

这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。

\n
\n

配置 X11 下的 Nvidia 显卡优先

可以通过配置 /etc/X11/xorg.conf 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:

\n
1
sudo nvidia-xconfig --prime
\n\n

该命令会根据硬件情况自动生成配置文件。执行后 重新登录会话 即可生效(即使是 Wayland 用户也可以执行一次此命令)。

\n

\"X11

\n
\n

配置 Wayland 下的 Nvidia 显卡优先

在 Wayland 下优先启用 Nvidia 显卡的步骤如下:

\n
    \n
  1. 编辑 GRUB 配置文件:

    \n

    打开 /etc/default/grub 文件,在 GRUB_CMDLINE_LINUX_DEFAULT="" 中添加 nvidia_drm.modeset=1

    \n
    1
    GRUB_CMDLINE_LINUX_DEFAULT="nvidia_drm.modeset=1"
    \n
  2. \n
  3. 重新生成 grub 配置:

    \n
    1
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    \n
  4. \n
  5. 配置 Plasma 环境文件:

    \n

    ~/.config/plasma-workspace/env/nvidia.sh 中写入以下内容:

    \n
    1
    2
    3
    #!/bin/bash 
    export __NV_PRIME_RENDER_OFFLOAD=1
    export __GLX_VENDOR_LIBRARY_NAME=nvidia
    \n
  6. \n
  7. 保存并重启电脑,即可生效。

    \n
  8. \n
\n

\"Wayland

\n
\n

I+N 混合显卡方案

如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。

\n

配置步骤

    \n
  1. 打开程序的 .desktop 启动文件:

    \n

    位置可能在 /usr/share/applications~/.local/share/applications 中。

    \n
  2. \n
  3. Exec= 后添加 prime-run 参数。例如:

    \n
    1
    Exec=prime-run <程序启动命令>
    \n\n

    \"混合显卡配置示意图\"

    \n
  4. \n
\n

Vim 快捷配置

如果使用 Vim,可以使用以下快捷键快速批量替换 Exec=Exec=prime-run

\n
1
v -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter
\n\n
\n

让 Plasma 桌面也使用独显

如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:

\n
1
2
#!/bin/bash 
export __GLX_VENDOR_LIBRARY_NAME=nvidia
\n\n

这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。

\n
\n

希望以上经验能为有此需求的用户提供参考帮助。

\n","excerpt":"","more":"

本文将介绍在 X11Wayland 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。首先,请确保您已经正确安装了 Nvidia 驱动(如果非 Mainline 内核,请使用 nvidia-dkmsnvidia-open-dkms 版本)。

\n

\"Nvidia设置示意图\"

\n

适用系统

对于 CachyOSEndeavourOS 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:

\n
    \n
  • Nvidia 驱动已安装,nvidia-smi 输出正常
  • \n
  • KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显
  • \n
  • 导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象
  • \n
\n

这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。

\n
\n

配置 X11 下的 Nvidia 显卡优先

可以通过配置 /etc/X11/xorg.conf 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:

\n
1
sudo nvidia-xconfig --prime
\n\n

该命令会根据硬件情况自动生成配置文件。执行后 重新登录会话 即可生效(即使是 Wayland 用户也可以执行一次此命令)。

\n

\"X11

\n
\n

配置 Wayland 下的 Nvidia 显卡优先

在 Wayland 下优先启用 Nvidia 显卡的步骤如下:

\n
    \n
  1. 编辑 GRUB 配置文件:

    \n

    打开 /etc/default/grub 文件,在 GRUB_CMDLINE_LINUX_DEFAULT="" 中添加 nvidia_drm.modeset=1

    \n
    1
    GRUB_CMDLINE_LINUX_DEFAULT="nvidia_drm.modeset=1"
    \n
  2. \n
  3. 重新生成 grub 配置:

    \n
    1
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    \n
  4. \n
  5. 配置 Plasma 环境文件:

    \n

    ~/.config/plasma-workspace/env/nvidia.sh 中写入以下内容:

    \n
    1
    2
    3
    #!/bin/bash 
    export __NV_PRIME_RENDER_OFFLOAD=1
    export __GLX_VENDOR_LIBRARY_NAME=nvidia
    \n
  6. \n
  7. 保存并重启电脑,即可生效。

    \n
  8. \n
\n

\"Wayland

\n
\n

I+N 混合显卡方案

如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。

\n

配置步骤

    \n
  1. 打开程序的 .desktop 启动文件:

    \n

    位置可能在 /usr/share/applications~/.local/share/applications 中。

    \n
  2. \n
  3. Exec= 后添加 prime-run 参数。例如:

    \n
    1
    Exec=prime-run <程序启动命令>
    \n\n

    \"混合显卡配置示意图\"

    \n
  4. \n
\n

Vim 快捷配置

如果使用 Vim,可以使用以下快捷键快速批量替换 Exec=Exec=prime-run

\n
1
v -> G -> :s/Exec=/Exec=prime-run /g Enter -> :wq Enter
\n\n
\n

让 Plasma 桌面也使用独显

如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:

\n
1
2
#!/bin/bash 
export __GLX_VENDOR_LIBRARY_NAME=nvidia
\n\n

这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。

\n
\n

希望以上经验能为有此需求的用户提供参考帮助。

\n"},{"title":"Archlinux问题记录","date":"2025-03-10T14:47:08.000Z","_content":"\n前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~\n\n---\n\n### 1. 显卡功耗上限解锁\n**问题现象** \n使用 `nvidia-smi` 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:\n\n```bash\nnvidia-smi # 输出显示 Power Limit: 55.00 W\n```\n\n**解决方案** \n启用 NVIDIA 动态功耗管理服务即可:\n```bash\nsudo systemctl enable --now nvidia-powerd\n```\n\n---\n\n### 2. Steam Proton 输入失效\n**问题描述** \n使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。 \n⚠️ 经排查发现是 Wayland 协议兼容性问题导致。\n\n**解决方案** \n在 Steam 游戏启动选项中加入环境变量禁用 Wayland:\n```bash\nPROTON_ENABLE_WAYLAND=0 %command%\n```\n\n---\n\n","source":"_posts/archlinux-game-fix.md","raw":"---\ntitle: Archlinux问题记录\ndate: 2025-03-10 22:47:08\ntags: [生活, Archlinux]\n---\n\n前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~\n\n---\n\n### 1. 显卡功耗上限解锁\n**问题现象** \n使用 `nvidia-smi` 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:\n\n```bash\nnvidia-smi # 输出显示 Power Limit: 55.00 W\n```\n\n**解决方案** \n启用 NVIDIA 动态功耗管理服务即可:\n```bash\nsudo systemctl enable --now nvidia-powerd\n```\n\n---\n\n### 2. Steam Proton 输入失效\n**问题描述** \n使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。 \n⚠️ 经排查发现是 Wayland 协议兼容性问题导致。\n\n**解决方案** \n在 Steam 游戏启动选项中加入环境变量禁用 Wayland:\n```bash\nPROTON_ENABLE_WAYLAND=0 %command%\n```\n\n---\n\n","slug":"archlinux-game-fix","published":1,"updated":"2025-03-10T14:54:16.788Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q2000rp22bgtkodqs6","content":"

前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~

\n
\n

1. 显卡功耗上限解锁

问题现象
使用 nvidia-smi 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:

\n
1
nvidia-smi  # 输出显示 Power Limit: 55.00 W
\n\n

解决方案
启用 NVIDIA 动态功耗管理服务即可:

\n
1
sudo systemctl enable --now nvidia-powerd
\n\n
\n

2. Steam Proton 输入失效

问题描述
使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。
⚠️ 经排查发现是 Wayland 协议兼容性问题导致。

\n

解决方案
在 Steam 游戏启动选项中加入环境变量禁用 Wayland:

\n
1
PROTON_ENABLE_WAYLAND=0 %command%
\n\n
\n","excerpt":"","more":"

前几周在使用 Arch Linux 时遇到了两个有趣的问题,顺手记录在此,或许能帮到有类似困扰的朋友~

\n
\n

1. 显卡功耗上限解锁

问题现象
使用 nvidia-smi 查看显卡功耗时,发现最大功耗被限制在 55W,性能无法完全释放:

\n
1
nvidia-smi  # 输出显示 Power Limit: 55.00 W
\n\n

解决方案
启用 NVIDIA 动态功耗管理服务即可:

\n
1
sudo systemctl enable --now nvidia-powerd
\n\n
\n

2. Steam Proton 输入失效

问题描述
使用 proton-cachyos 和 proton-ge-custom 版本时,Steam 游戏无法接收任何输入(键盘/手柄)。
⚠️ 经排查发现是 Wayland 协议兼容性问题导致。

\n

解决方案
在 Steam 游戏启动选项中加入环境变量禁用 Wayland:

\n
1
PROTON_ENABLE_WAYLAND=0 %command%
\n\n
\n"},{"title":"Archlinux KDE体验优化总结","date":"2025-02-02T10:43:26.000Z","_content":"\n打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验\n\n本文章长期更新\n\n------\n\n## 更换CachyOS优化仓库\n\n![CachyOS Logo](https://wiki.cachyos.org/_astro/logo.DVTdAJi6.svg) \n通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。\n\n---\n\n### ▎前置准备\n**⚠️ 兼容性警告** \n1. 可以先通过命令`/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-`来查看你的处理器支持等级。\n2. 注意添加 `cachyos` 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性) \n ```bash\n cachyos-v3 # AVX2 优化\n cachyos-v4 # AVX512 优化\n cachyos-extra # 扩展软件包\n ```\n3. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以[点击这里](https://discuss.cachyos.org/t/zen-4-5-optimized-repository-testing/713/7)查看如何部署。\n\n---\n\n### ▎仓库配置流程\n#### ▶ 自动配置脚本\n```bash\n# 下载配置工具\ncurl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz\ntar xvf cachyos-repo.tar.xz && cd cachyos-repo\n\n# 执行自动配置(自动检测 CPU 指令集)\nsudo ./cachyos-repo.sh\n```\n📌 脚本特性: \n- 自动备份 `/etc/pacman.conf` \n- 智能匹配最优指令集版本 (v3/v4) \n- 支持 x86_64 和 aarch64 架构 \n\n#### ▶ 手动配置方式\n1. 编辑 pacman.conf\n```ini\n# 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)\n[cachyos-v3]\nSigLevel = Optional TrustAll\nInclude = /etc/pacman.d/cachyos-v3\n```\n\n2. ✅同步仓库数据库\n```bash\nsudo pacman -Syu\n```\n\n---\n\n### ▎仓库卸载方法\n#### ▶ 自动卸载\n```bash\ncd cachyos-repo\nsudo ./cachyos-repo.sh --remove\n```\n\n#### ▶ 手动卸载\n1. 删除 pacman.conf 中的 cachyos 仓库段\n2. 移除配置文件\n```bash\nsudo rm -rf /etc/pacman.d/cachyos*\n```\n---\n\n## 内核更换\n\n## KDE 配置\n\n\n\n","source":"_posts/archlinux-optimization.md","raw":"---\ntitle: Archlinux KDE体验优化总结\ndate: 2025-02-02 18:43:26\ntags: [Archlinux, 系统优化, 技术分享]\n---\n\n打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验\n\n本文章长期更新\n\n------\n\n## 更换CachyOS优化仓库\n\n![CachyOS Logo](https://wiki.cachyos.org/_astro/logo.DVTdAJi6.svg) \n通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。\n\n---\n\n### ▎前置准备\n**⚠️ 兼容性警告** \n1. 可以先通过命令`/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-`来查看你的处理器支持等级。\n2. 注意添加 `cachyos` 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性) \n ```bash\n cachyos-v3 # AVX2 优化\n cachyos-v4 # AVX512 优化\n cachyos-extra # 扩展软件包\n ```\n3. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以[点击这里](https://discuss.cachyos.org/t/zen-4-5-optimized-repository-testing/713/7)查看如何部署。\n\n---\n\n### ▎仓库配置流程\n#### ▶ 自动配置脚本\n```bash\n# 下载配置工具\ncurl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz\ntar xvf cachyos-repo.tar.xz && cd cachyos-repo\n\n# 执行自动配置(自动检测 CPU 指令集)\nsudo ./cachyos-repo.sh\n```\n📌 脚本特性: \n- 自动备份 `/etc/pacman.conf` \n- 智能匹配最优指令集版本 (v3/v4) \n- 支持 x86_64 和 aarch64 架构 \n\n#### ▶ 手动配置方式\n1. 编辑 pacman.conf\n```ini\n# 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)\n[cachyos-v3]\nSigLevel = Optional TrustAll\nInclude = /etc/pacman.d/cachyos-v3\n```\n\n2. ✅同步仓库数据库\n```bash\nsudo pacman -Syu\n```\n\n---\n\n### ▎仓库卸载方法\n#### ▶ 自动卸载\n```bash\ncd cachyos-repo\nsudo ./cachyos-repo.sh --remove\n```\n\n#### ▶ 手动卸载\n1. 删除 pacman.conf 中的 cachyos 仓库段\n2. 移除配置文件\n```bash\nsudo rm -rf /etc/pacman.d/cachyos*\n```\n---\n\n## 内核更换\n\n## KDE 配置\n\n\n\n","slug":"archlinux-optimization","published":1,"updated":"2025-03-10T15:07:26.618Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q3000up22bhurb7l9n","content":"

打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验

\n

本文章长期更新

\n
\n

更换CachyOS优化仓库

\"CachyOS
通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。

\n
\n

▎前置准备

⚠️ 兼容性警告

\n
    \n
  1. 可以先通过命令/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-来查看你的处理器支持等级。
  2. \n
  3. 注意添加 cachyos 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性)
    1
    2
    3
    cachyos-v3    # AVX2 优化
    cachyos-v4 # AVX512 优化
    cachyos-extra # 扩展软件包
  4. \n
  5. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以点击这里查看如何部署。
  6. \n
\n
\n

▎仓库配置流程

▶ 自动配置脚本

1
2
3
4
5
6
# 下载配置工具
curl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz
tar xvf cachyos-repo.tar.xz && cd cachyos-repo

# 执行自动配置(自动检测 CPU 指令集)
sudo ./cachyos-repo.sh
\n

📌 脚本特性:

\n
    \n
  • 自动备份 /etc/pacman.conf
  • \n
  • 智能匹配最优指令集版本 (v3/v4)
  • \n
  • 支持 x86_64 和 aarch64 架构
  • \n
\n

▶ 手动配置方式

    \n
  1. 编辑 pacman.conf

    \n
    1
    2
    3
    4
    # 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)
    [cachyos-v3]
    SigLevel = Optional TrustAll
    Include = /etc/pacman.d/cachyos-v3
    \n
  2. \n
  3. ✅同步仓库数据库

    \n
    1
    sudo pacman -Syu
  4. \n
\n
\n

▎仓库卸载方法

▶ 自动卸载

1
2
cd cachyos-repo
sudo ./cachyos-repo.sh --remove
\n\n

▶ 手动卸载

    \n
  1. 删除 pacman.conf 中的 cachyos 仓库段
  2. \n
  3. 移除配置文件
    1
    sudo rm -rf /etc/pacman.d/cachyos*
  4. \n
\n
\n

内核更换

KDE 配置

","excerpt":"","more":"

打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验

\n

本文章长期更新

\n
\n

更换CachyOS优化仓库

\"CachyOS
通过 CachyOS 优化仓库获取 CPU 指令集级优化(x86-64-v3/v4/zen4)的软件包,提升 Arch Linux 系统性能。该仓库提供 PGO/LTO/BOLT 编译优化及持续维护的定制软件包。

\n
\n

▎前置准备

⚠️ 兼容性警告

\n
    \n
  1. 可以先通过命令/usr/lib64/ld-linux-x86-64.so.2 --help | grep -i x86-64-来查看你的处理器支持等级。
  2. \n
  3. 注意添加 cachyos 主仓库会替换官方 pacman 仓库(含 INSTALLED_FROM 等特性)
    1
    2
    3
    cachyos-v3    # AVX2 优化
    cachyos-v4 # AVX512 优化
    cachyos-extra # 扩展软件包
  4. \n
  5. CachyOS官方在前段时间专门推出了针对 AMD 的Zen4和Zen5架构优化仓库,如有需要可以点击这里查看如何部署。
  6. \n
\n
\n

▎仓库配置流程

▶ 自动配置脚本

1
2
3
4
5
6
# 下载配置工具
curl -LO https://mirror.cachyos.org/cachyos-repo.tar.xz
tar xvf cachyos-repo.tar.xz && cd cachyos-repo

# 执行自动配置(自动检测 CPU 指令集)
sudo ./cachyos-repo.sh
\n

📌 脚本特性:

\n
    \n
  • 自动备份 /etc/pacman.conf
  • \n
  • 智能匹配最优指令集版本 (v3/v4)
  • \n
  • 支持 x86_64 和 aarch64 架构
  • \n
\n

▶ 手动配置方式

    \n
  1. 编辑 pacman.conf

    \n
    1
    2
    3
    4
    # 在 /etc/pacman.conf 末尾添加(示例为 AVX2 优化)
    [cachyos-v3]
    SigLevel = Optional TrustAll
    Include = /etc/pacman.d/cachyos-v3
    \n
  2. \n
  3. ✅同步仓库数据库

    \n
    1
    sudo pacman -Syu
  4. \n
\n
\n

▎仓库卸载方法

▶ 自动卸载

1
2
cd cachyos-repo
sudo ./cachyos-repo.sh --remove
\n\n

▶ 手动卸载

    \n
  1. 删除 pacman.conf 中的 cachyos 仓库段
  2. \n
  3. 移除配置文件
    1
    sudo rm -rf /etc/pacman.d/cachyos*
  4. \n
\n
\n

内核更换

KDE 配置

"},{"title":"使用Clonezilla备份和克隆系统","date":"2025-02-23T13:40:03.000Z","_content":"![Clonezilla官网](/images/clonezilla.png)\n[Clonezilla](https://clonezilla.org/)是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。\n\n---\n### **零.事前准备**:\n - 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。\n - 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。\n\n\n### **一.备份镜像到硬盘(Device-to-Image)**\n这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。\n\n#### **步骤说明**:\n2. **启动Clonezilla**:\n - 插入U盘,重启电脑并从U盘启动。\n - 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。\n\n3. **选择备份模式**:\n ```plaintext\n Choose mode: 选择 \"device-image\"(设备到镜像)\n Mount storage media: 选择 \"local_dev\"(本地存储设备)\n ```\n - 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 `/dev/sdb1`)。\n\n4. **配置备份参数**:\n - **源硬盘**:选择需要备份的硬盘(如 `/dev/sda`)。\n - **镜像存储路径**:指定目标位置(如外置硬盘的挂载目录)。\n - **镜像名称**:自定义名称(如 `2025-img-rockylinux-2-21`)。\n - **压缩选项**:默认即可,支持并行压缩加速。\n - **镜像分割**:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。\n\n5. **确认操作**:\n - 检查提示信息,输入 `y` 开始备份。\n - 完成后关机或重启。\n\n6. **镜像还原**:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。\n---\n\n### **二、直接克隆硬盘(Device-to-Device)**\n将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。\n\n#### **步骤说明**:\n1. **准备工作**:\n - 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)\n - **警告**:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!\n\n2. **启动Clonezilla**:\n - 同上,从U盘启动进入Clonezilla界面。\n\n3. **选择克隆模式**:\n ```plaintext\n Choose mode: 选择 \"device-device\"(设备到设备)\n ```\n\n4. **选择硬盘**:\n - **母碟硬盘**:选择原始硬盘(如 `/dev/sda`)。\n - **目标硬盘**:选择新硬盘(如 `/dev/sdb`)。\n\n5. **克隆选项**:\n 需要进入专家模式才能看到,一般直接新手模式默认即可。\n\n6. **执行克隆**:\n - 确认提示信息后输入 `y`,等待完成。\n - 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。\n\n---\n### **两种模式对比**:\n| **模式** | 特点 | \n|----------------|---------------------------|\n| 备份镜像 | 方便多机部署也可以用于留档|\n| 直接克隆 | 换硬盘快速迁移无需恢复过程|\n---\n\n### **Btrfs务必注意**:\n对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行`sudo btrfs balance start --full-balance /`来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。\n\n","source":"_posts/clonezilla.md","raw":"---\ntitle: 使用Clonezilla备份和克隆系统\ndate: 2025-02-23 21:40:03\ntags: 技术分享\n---\n![Clonezilla官网](/images/clonezilla.png)\n[Clonezilla](https://clonezilla.org/)是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。\n\n---\n### **零.事前准备**:\n - 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。\n - 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。\n\n\n### **一.备份镜像到硬盘(Device-to-Image)**\n这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。\n\n#### **步骤说明**:\n2. **启动Clonezilla**:\n - 插入U盘,重启电脑并从U盘启动。\n - 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。\n\n3. **选择备份模式**:\n ```plaintext\n Choose mode: 选择 \"device-image\"(设备到镜像)\n Mount storage media: 选择 \"local_dev\"(本地存储设备)\n ```\n - 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 `/dev/sdb1`)。\n\n4. **配置备份参数**:\n - **源硬盘**:选择需要备份的硬盘(如 `/dev/sda`)。\n - **镜像存储路径**:指定目标位置(如外置硬盘的挂载目录)。\n - **镜像名称**:自定义名称(如 `2025-img-rockylinux-2-21`)。\n - **压缩选项**:默认即可,支持并行压缩加速。\n - **镜像分割**:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。\n\n5. **确认操作**:\n - 检查提示信息,输入 `y` 开始备份。\n - 完成后关机或重启。\n\n6. **镜像还原**:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。\n---\n\n### **二、直接克隆硬盘(Device-to-Device)**\n将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。\n\n#### **步骤说明**:\n1. **准备工作**:\n - 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)\n - **警告**:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!\n\n2. **启动Clonezilla**:\n - 同上,从U盘启动进入Clonezilla界面。\n\n3. **选择克隆模式**:\n ```plaintext\n Choose mode: 选择 \"device-device\"(设备到设备)\n ```\n\n4. **选择硬盘**:\n - **母碟硬盘**:选择原始硬盘(如 `/dev/sda`)。\n - **目标硬盘**:选择新硬盘(如 `/dev/sdb`)。\n\n5. **克隆选项**:\n 需要进入专家模式才能看到,一般直接新手模式默认即可。\n\n6. **执行克隆**:\n - 确认提示信息后输入 `y`,等待完成。\n - 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。\n\n---\n### **两种模式对比**:\n| **模式** | 特点 | \n|----------------|---------------------------|\n| 备份镜像 | 方便多机部署也可以用于留档|\n| 直接克隆 | 换硬盘快速迁移无需恢复过程|\n---\n\n### **Btrfs务必注意**:\n对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行`sudo btrfs balance start --full-balance /`来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。\n\n","slug":"clonezilla","published":1,"updated":"2025-02-23T14:12:10.654Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q3000xp22bd6qo3kl3","content":"

\"Clonezilla官网\"
Clonezilla是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。

\n
\n

零.事前准备

    \n
  • 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。
  • \n
  • 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。
  • \n
\n

一.备份镜像到硬盘(Device-to-Image)

这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。

\n

步骤说明

    \n
  1. 启动Clonezilla

    \n
      \n
    • 插入U盘,重启电脑并从U盘启动。
    • \n
    • 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。
    • \n
    \n
  2. \n
  3. 选择备份模式

    \n
    1
    2
    Choose mode:         选择 "device-image"(设备到镜像)
    Mount storage media: 选择 "local_dev"(本地存储设备)
    \n
      \n
    • 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 /dev/sdb1)。
    • \n
    \n
  4. \n
  5. 配置备份参数

    \n
      \n
    • 源硬盘:选择需要备份的硬盘(如 /dev/sda)。
    • \n
    • 镜像存储路径:指定目标位置(如外置硬盘的挂载目录)。
    • \n
    • 镜像名称:自定义名称(如 2025-img-rockylinux-2-21)。
    • \n
    • 压缩选项:默认即可,支持并行压缩加速。
    • \n
    • 镜像分割:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。
    • \n
    \n
  6. \n
  7. 确认操作

    \n
      \n
    • 检查提示信息,输入 y 开始备份。
    • \n
    • 完成后关机或重启。
    • \n
    \n
  8. \n
  9. 镜像还原:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。

    \n
  10. \n
\n
\n

二、直接克隆硬盘(Device-to-Device)

将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。

\n

步骤说明

    \n
  1. 准备工作

    \n
      \n
    • 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)
    • \n
    • 警告:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!
    • \n
    \n
  2. \n
  3. 启动Clonezilla

    \n
      \n
    • 同上,从U盘启动进入Clonezilla界面。
    • \n
    \n
  4. \n
  5. 选择克隆模式

    \n
    1
    Choose mode:         选择 "device-device"(设备到设备)
    \n
  6. \n
  7. 选择硬盘

    \n
      \n
    • 母碟硬盘:选择原始硬盘(如 /dev/sda)。
    • \n
    • 目标硬盘:选择新硬盘(如 /dev/sdb)。
    • \n
    \n
  8. \n
  9. 克隆选项
    需要进入专家模式才能看到,一般直接新手模式默认即可。

    \n
  10. \n
  11. 执行克隆

    \n
      \n
    • 确认提示信息后输入 y,等待完成。
    • \n
    • 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。
    • \n
    \n
  12. \n
\n
\n

两种模式对比

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
模式特点
备份镜像方便多机部署也可以用于留档
直接克隆换硬盘快速迁移无需恢复过程
\n
\n

Btrfs务必注意

对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行sudo btrfs balance start --full-balance /来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。

\n","excerpt":"","more":"

\"Clonezilla官网\"
Clonezilla是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。

\n
\n

零.事前准备

    \n
  • 下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。
  • \n
  • 准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。
  • \n
\n

一.备份镜像到硬盘(Device-to-Image)

这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。

\n

步骤说明

    \n
  1. 启动Clonezilla

    \n
      \n
    • 插入U盘,重启电脑并从U盘启动。
    • \n
    • 选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。
    • \n
    \n
  2. \n
  3. 选择备份模式

    \n
    1
    2
    Choose mode:         选择 "device-image"(设备到镜像)
    Mount storage media: 选择 "local_dev"(本地存储设备)
    \n
      \n
    • 按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 /dev/sdb1)。
    • \n
    \n
  4. \n
  5. 配置备份参数

    \n
      \n
    • 源硬盘:选择需要备份的硬盘(如 /dev/sda)。
    • \n
    • 镜像存储路径:指定目标位置(如外置硬盘的挂载目录)。
    • \n
    • 镜像名称:自定义名称(如 2025-img-rockylinux-2-21)。
    • \n
    • 压缩选项:默认即可,支持并行压缩加速。
    • \n
    • 镜像分割:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。
    • \n
    \n
  6. \n
  7. 确认操作

    \n
      \n
    • 检查提示信息,输入 y 开始备份。
    • \n
    • 完成后关机或重启。
    • \n
    \n
  8. \n
  9. 镜像还原:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。

    \n
  10. \n
\n
\n

二、直接克隆硬盘(Device-to-Device)

将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。

\n

步骤说明

    \n
  1. 准备工作

    \n
      \n
    • 连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)
    • \n
    • 警告:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!
    • \n
    \n
  2. \n
  3. 启动Clonezilla

    \n
      \n
    • 同上,从U盘启动进入Clonezilla界面。
    • \n
    \n
  4. \n
  5. 选择克隆模式

    \n
    1
    Choose mode:         选择 "device-device"(设备到设备)
    \n
  6. \n
  7. 选择硬盘

    \n
      \n
    • 母碟硬盘:选择原始硬盘(如 /dev/sda)。
    • \n
    • 目标硬盘:选择新硬盘(如 /dev/sdb)。
    • \n
    \n
  8. \n
  9. 克隆选项
    需要进入专家模式才能看到,一般直接新手模式默认即可。

    \n
  10. \n
  11. 执行克隆

    \n
      \n
    • 确认提示信息后输入 y,等待完成。
    • \n
    • 克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。
    • \n
    \n
  12. \n
\n
\n

两种模式对比

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
模式特点
备份镜像方便多机部署也可以用于留档
直接克隆换硬盘快速迁移无需恢复过程
\n
\n

Btrfs务必注意

对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行sudo btrfs balance start --full-balance /来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。

\n"},{"title":"时隔一年再次拿起数位板能画出什么东西","date":"2024-11-04T15:47:54.000Z","_content":"\n如题,前段时间推完LOOPERS的时候有感而发对着画了张海报\n\n时隔一年,终于又拿起了数位板\n\n![LOOPERS](/images/20241027_222225.png \"LOOPERS\")\n","source":"_posts/loopers.md","raw":"---\ntitle: 时隔一年再次拿起数位板能画出什么东西\ndate: 2024-11-04 23:47:54\ntags: [板绘, 生活]\n---\n\n如题,前段时间推完LOOPERS的时候有感而发对着画了张海报\n\n时隔一年,终于又拿起了数位板\n\n![LOOPERS](/images/20241027_222225.png \"LOOPERS\")\n","slug":"loopers","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q3000zp22b76yib05t","content":"

如题,前段时间推完LOOPERS的时候有感而发对着画了张海报

\n

时隔一年,终于又拿起了数位板

\n

\"LOOPERS\"

\n","excerpt":"","more":"

如题,前段时间推完LOOPERS的时候有感而发对着画了张海报

\n

时隔一年,终于又拿起了数位板

\n

\"LOOPERS\"

\n"},{"title":"愿指引明路的苍蓝星永远为你闪耀","date":"2024-11-11T13:46:49.000Z","_content":"使用东方Project软音源THFont简单重置的MHWI主题曲\n\n雄关漫道真如铁,而今迈步从头越\n\n{% raw %}\n\n{% endraw %}\n\n","source":"_posts/mhwi.md","raw":"---\ntitle: 愿指引明路的苍蓝星永远为你闪耀\ndate: 2024-11-11 21:46:49\ntags: 音乐\ncategories: Rearrangement\n---\n使用东方Project软音源THFont简单重置的MHWI主题曲\n\n雄关漫道真如铁,而今迈步从头越\n\n{% raw %}\n\n{% endraw %}\n\n","slug":"mhwi","published":1,"updated":"2024-11-11T14:00:19.124Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q40013p22bb8qjfb28","content":"

使用东方Project软音源THFont简单重置的MHWI主题曲

\n

雄关漫道真如铁,而今迈步从头越

\n\n\n\n\n","excerpt":"","more":"

使用东方Project软音源THFont简单重置的MHWI主题曲

\n

雄关漫道真如铁,而今迈步从头越

\n\n\n\n\n"},{"title":"高地特供版CSAPP Bomb Lab全流程攻略","date":"2025-02-24T07:09:11.000Z","_content":"\n这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。\n\n笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。\n\n## **Phase_1**\n\n### **静态分析**\n\n#### **`strings`扫描**\n```bash\nstrings bomb_linux\n```\n先用strings寻找可能与`phase_1`相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。\n![strings](/images/phase1_strings.png)\n - 结果没有明文密码无法直接秒掉第一问,可惜。\n - 但是找到`GenerateRandomString`函数可能与密码生成相关。\n\n#### **用`objdump`反汇编**\n```bash\nobjdump -d bomb_linux > bomb.asm\n```\n搜索`GenerateRandomString`和`phase_1`函数的汇编代码。\n ```assembly\n 401b53 :\n 401b53: endbr64\n 401b57: push %rbp\n 401b58: mov %rsp,%rbp\n 401b5b: sub $0x20,%rsp\n 401b5f: mov %rdi,-0x18(%rbp)\n 401b63: lea -0xb(%rbp),%rax\n 401b67: mov %rax,%rdi\n 401b6a: callq 401ac1 # 调用密码生成函数\n 401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置\n 401b73: mov -0x18(%rbp),%rax\n 401b77: mov %rdx,%rsi\n 401b7a: mov %rax,%rdi\n 401b7d: callq 401c0c # 调用字符串比较函数\n 401b82: test %eax,%eax\n 401b84: je 401b8d \n 401b86: callq 401d67 # 比较失败则引爆炸弹\n ```\n - `phase_1`调用`GenerateRandomString`生成一个字符串。\n - 用户输入的字符串需要与此生成的字符串完全匹配。\n\n---\n\n### **动态调试**\n![phase_1](/images/phase1.png)\n下面是phase_1求解的完整流程:\n```lldb\nlldb bomb_linux <你的学号后六位>\n(lldb) b phase_1 # 在phase_1入口断点\n(lldb) run # 从入口开始执行\n请输入第1级的密码:114514 # 随便输入触发断点\n(lldb) b 0x401b6f # 在GenerateRandomString返回后断点\n(lldb) continue # 继续执行\n(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)\n0x7fffffffdaf5: \"mJHurpQZtY\" # 轻松拿下,这里是根据学号伪随机生成的哦\n```\n将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。\n\n---\n\n## **Phase_2**\n\n### **静态分析**\n\n这道题目还是比较一目了然的,观察`phase_2`代码不难发现其实构建了一张跳转表:\n```assembly\n0000000000401b8e :\n 401b8e:\tf3 0f 1e fa \tendbr64\n 401b92:\t55 \tpush %rbp\n 401b93:\t48 89 e5 \tmov %rsp,%rbp\n 401b96:\t48 83 ec 10 \tsub $0x10,%rsp\n 401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi\n 401ba3:\te8 05 fb ff ff \tcall 4016ad \n 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 \n 401baf:\t48 83 f8 0f \tcmp $0xf,%rax\n 401bb3:\t0f 87 16 01 00 00 \tja 401ccf \n 401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 401bc0:\t00 \n 401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>\n 401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 401bcb:\t48 98 \tcltq\n 401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>\n 401bd4:\t48 01 d0 \tadd %rdx,%rax\n 401bd7:\t3e ff e0 \tnotrack jmp *%rax\n 401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bde:\t48 89 c7 \tmov %rax,%rdi\n 401be1:\te8 f2 00 00 00 \tcall 401cd8 \n 401be6:\te9 ea 00 00 00 \tjmp 401cd5 \n 401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bef:\t48 89 c7 \tmov %rax,%rdi\n 401bf2:\te8 8b 01 00 00 \tcall 401d82 \n 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 \n 401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401c00:\t48 89 c7 \tmov %rax,%rdi\n ...\n```\n这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是`GenerateRandomNumber`这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。\n\n---\n\n### **动态调试**\n理解原理就没什么难度了,自己找几个断点打好然后关注一下`rand_div`的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向`phase_2_14`跳转:\n![phase_2_14](/images/phase_2_14.png)\n\n而除了`phase_2_14`还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。\n\n---\n## **Phase_3**\n\n### **静态分析**\n\n和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi\n\n本体其实没有什么好说的,这里我跳转的方向是`Phase_3_5`简要解释一下可供参考:\n\n```assembly\n0000000000403001 :\n 403001:\tf3 0f 1e fa \tendbr64\n 403005:\t55 \tpush %rbp\n 403006:\t48 89 e5 \tmov %rsp,%rbp\n 403009:\t48 83 ec 20 \tsub $0x20,%rsp\n 40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)\n 403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)\n 403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)\n 40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx\n 403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx\n 403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax\n 40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>\n 403032:\t48 89 c7 \tmov %rax,%rdi\n 403035:\tb8 00 00 00 00 \tmov $0x0,%eax\n 40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n 40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)\n 403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)\n 403046:\t7f 05 \tjg 40304d \n 403048:\te8 a9 2b 00 00 \tcall 405bf6 \n 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi\n 403052:\te8 56 e6 ff ff \tcall 4016ad \n 403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40305a:\t48 63 d0 \tmovslq %eax,%rdx\n 40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 \n 403064:\t48 39 c2 \tcmp %rax,%rdx\n 403067:\t74 05 \tje 40306e \n 403069:\te8 88 2b 00 00 \tcall 405bf6 \n 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 403073:\te8 35 e6 ff ff \tcall 4016ad \n 403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40307b:\t83 f8 07 \tcmp $0x7,%eax\n 40307e:\t0f 87 eb 00 00 00 \tja 40316f \n 403084:\t89 c0 \tmov %eax,%eax\n 403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 40308d:\t00 \n 40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>\n 403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 403098:\t48 98 \tcltq\n 40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>\n 4030a1:\t48 01 d0 \tadd %rdx,%rax\n 4030a4:\t3e ff e0 \tnotrack jmp *%rax\n 4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 \n 4030ae:\t89 c2 \tmov %eax,%edx\n 4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax\n 4030b3:\t01 d0 \tadd %edx,%eax\n 4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)\n 4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 4030bd:\te8 eb e5 ff ff \tcall 4016ad \n ...\n 403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax\n 403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里\n 40317a:\t74 05 \tje 403181 \n 40317c:\te8 75 2a 00 00 \tcall 405bf6 \n 403181:\t90 \tnop\n 403182:\tc9 \tleave\n 403183:\tc3 \tret\n\n```\n看起来一大堆很吓人对不对?实际上确实很吓人。\n\n但是发现其中玄机后其实简单的没边,最终答案就藏在`0x403177`里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接`run`一下重开qwq)。\n\n---\n\n### **动态调试**\n\n阅读`Phase_3_5`发现这一关其实需要两个输入,并且第一个输入必须是`rand_div`,这里建议通过`si`单步执行监控好`rand_div`值变化,确定正确结果后使用`run`重开正确输入第一个密码后才能进行下一步求解:\n```lldb\n(lldb) si\nProcess 13376 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377\nbomb_linux`phase_3_5:\n-> 0x40317a <+377>: je 0x403181 ; <+384>\n 0x40317c <+379>: callq 0x405bf6 ; explode_bomb\n 0x403181 <+384>: nop\n 0x403182 <+385>: leave\n(lldb) x/wx $rbp-0x4\n0x7fffffffdb0c: 0xffffffd7\n```\n例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。\n\n---\n\n## **Phase_4**\n\n### **静态分析**\n\n本题依旧开局跳转,笔者的跳转方向是`phase_4_01`,如何跳转不再强调关注`rand_div`的值即可,下面请D指导解读一下`phase_4_01`的内容:\n```assembly\n0000000000404895 :\n ; 函数入口,初始化栈帧\n 404895:\tf3 0f 1e fa \tendbr64 \n 404899:\t55 \tpush %rbp\n 40489a:\t48 89 e5 \tmov %rsp,%rbp\n 40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间\n\n ; 初始化斐波那契数组(F(10)~F(24)的十六进制值)\n 4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针\n 4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55\n 4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89\n 4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144\n 4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233\n 4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377\n 4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610\n 4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987\n 4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597\n 4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584\n 4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181\n 4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765\n 4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946\n 4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711\n 404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657\n 404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368\n\n ; 读取输入到局部变量(格式为\"%d\")\n 40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址\n 404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串\n 404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串\"%d\"\n 40491d:\t48 89 ce \tmov %rcx,%rsi\n 404920:\t48 89 c7 \tmov %rax,%rdi\n 404923:\tb8 00 00 00 00 \tmov $0x0,%eax\n 404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n\n ; 验证输入有效性(必须为1个正数)\n 40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值\n 404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数\n 404934:\t75 07 \tjne 40493d ; 失败则爆炸\n 404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N\n 404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0\n 40493b:\t7f 05 \tjg 404942 \n 40493d:\te8 b4 12 00 00 \tcall 405bf6 \n\n ; 检查输入值上限(必须 > 1999)\n 404942:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制\n 40494a:\t7f 05 \tjg 404951 ; N > 1999?\n 40494c:\te8 a5 12 00 00 \tcall 405bf6 \n\n ; 计算 N/2000(通过定点数乘法优化)\n 404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N\n 404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展\n 404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)\n 40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位\n 404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000\n 404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展\n 404968:\t89 c1 \tmov %eax,%ecx \n 40496a:\t89 d0 \tmov %edx,%eax \n 40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况\n 40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000\n\n ; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列\n 404971:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404974:\t89 c7 \tmov %eax,%edi ; 参数k\n 404976:\te8 ce fd ff ff \tcall 404749 ; 返回值eax=F(k+1)\n 40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果\n\n ; 生成随机索引并验证结果\n 40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15\n 404983:\te8 25 cd ff ff \tcall 4016ad ; 生成0~14随机数\n 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 ; 获取随机索引\n 40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值\n 404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?\n 404996:\t74 05 \tje 40499d \n 404998:\te8 59 12 00 00 \tcall 405bf6 \n```\n所以相对还是很明了的,依旧是关注`rand_div`。\n\n### **动态调试**\n先找出`rand_div`在最后判断前的取值,比如我下面的0xa:\n\n```lldb\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108\nbomb_linux`GenerateRandomNumber:\n-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div\n 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115\nbomb_linux`GenerateRandomNumber:\n-> 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n 0x401724 <+119>: retq\n(lldb) x/gx &rand_div\n0x00408820: 0x000000000000000a\n```\n\n而当 `rand_div = 0xa`(即十进制 **10**)时,输入值 `N` 的计算步骤如下:\n\n- 数组索引 **10** 的值是 **斐波那契数列第 20 项**(`F(20) = 6765`)。\n\n- `func4_0(k)` 实际计算的是 **标准斐波那契数列的第 `k+1` 项**(例如,`func4_0(0) = 1 = F(2)`) 需要满足:\n ```c\n func4_0(k) = F(k+1) = F(20)\n ```\n 解得:\n k + 1 = 20 → k = 19\n- `k = N / 2000` → `N = 2000 * k = 2000 * 19 = 38000`.\n从而得解。\n![phase_4](/images/phase_4.png)\n\n---\n\n## **Phase_Impossible**\n\nImpossible?\n\n从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:\n```c\nvoid phase_impossible(char *param_1)\n\n{\n int iVar1;\n size_t sVar2;\n undefined local_118 [256];\n long local_18;\n long local_10;\n \n local_10 = GetTickCount();\n sVar2 = strlen(param_1);\n if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {\n explode_bomb();\n }\n memset(local_118,0,0x100);\n tohex(local_118,param_1);\n GenerateRandomNumber(0x400);\n iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);\n if (iVar1 == 0) {\n puts(&DAT_00406518);\n explode_bomb();\n }\n GenerateRandomNumber(3);\n if (rand_div != 2) {\n if (2 < rand_div) goto LAB_00401891;\n if (rand_div == 0) {\n goto_buf_0(local_118);\n }\n else if (rand_div != 1) goto LAB_00401891;\n goto_buf_1(local_118);\n }\n goto_buf_2(local_118);\nLAB_00401891:\n explode_bomb();\n GenerateRandomNumber(0x400);\n if ((long)(int)result != rand_div) {\n printf(&DAT_00406560,rand_div,(ulong)result);\n explode_bomb();\n }\n local_18 = GetTickCount();\n if (1000 < (ulong)(local_18 - local_10)) {\n puts(&DAT_004065a8);\n explode_bomb();\n }\n return;\n}\n```\n最终任务还是很明确的,需要写一段机器码修改`result`的数值,但是注意要能通过`check_buf_valid`检测,并且最后指令必须是跳转到`0x401896`不然就会触发`phase_impossible`中`0x401891`处的`explode_bomb`函数,唯一的难点是跟踪`rand_div`的数值变化,建议使用`register write`来修改`check_buf_valid`的返回值使其强制通过然后监控`rand_div`每一次的数值变化(`x/gx &rand_div`),记录好`rand_div`的结果后开始指令设计,需要满足:\n\n - 指令的异或和为`rand_div`第一次的数值末尾八位以通过检查;\n - 修改`result`使其数值等于`rand_div`第三次数值;\n - 跳转到`0x401896`避免炸弹;\n\n 如果前几问都完成了到这里应该是没有问题的。\n\n---\n\n## **Phase_Secret**\n\n隐藏彩蛋,并非隐藏。汇编里写的非常清楚:\n```assembly\n0000000000401a8b :\n 401a8b:\tf3 0f 1e fa \tendbr64\n 401a8f:\t55 \tpush %rbp\n 401a90:\t48 89 e5 \tmov %rsp,%rbp\n 401a93:\t48 83 ec 10 \tsub $0x10,%rsp\n 401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>\n 401aa2:\t48 89 c7 \tmov %rax,%rdi\n 401aa5:\te8 76 f6 ff ff \tcall 401120 \n 401aaa:\t90 \tnop\n 401aab:\tc9 \tleave\n 401aac:\tc3 \tret\n```\n注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在`phase_5`中设计指令时加一个要求跳转到`0x401a8b`即可。\n\n完结\n![Case Closed](/images/caseclosed.png)\n","source":"_posts/nudtbomblab.md","raw":"---\ntitle: 高地特供版CSAPP Bomb Lab全流程攻略\ndate: 2025-02-24 15:09:11\ntags: [技术, 学习, 生活]\n---\n\n这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。\n\n笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。\n\n## **Phase_1**\n\n### **静态分析**\n\n#### **`strings`扫描**\n```bash\nstrings bomb_linux\n```\n先用strings寻找可能与`phase_1`相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。\n![strings](/images/phase1_strings.png)\n - 结果没有明文密码无法直接秒掉第一问,可惜。\n - 但是找到`GenerateRandomString`函数可能与密码生成相关。\n\n#### **用`objdump`反汇编**\n```bash\nobjdump -d bomb_linux > bomb.asm\n```\n搜索`GenerateRandomString`和`phase_1`函数的汇编代码。\n ```assembly\n 401b53 :\n 401b53: endbr64\n 401b57: push %rbp\n 401b58: mov %rsp,%rbp\n 401b5b: sub $0x20,%rsp\n 401b5f: mov %rdi,-0x18(%rbp)\n 401b63: lea -0xb(%rbp),%rax\n 401b67: mov %rax,%rdi\n 401b6a: callq 401ac1 # 调用密码生成函数\n 401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置\n 401b73: mov -0x18(%rbp),%rax\n 401b77: mov %rdx,%rsi\n 401b7a: mov %rax,%rdi\n 401b7d: callq 401c0c # 调用字符串比较函数\n 401b82: test %eax,%eax\n 401b84: je 401b8d \n 401b86: callq 401d67 # 比较失败则引爆炸弹\n ```\n - `phase_1`调用`GenerateRandomString`生成一个字符串。\n - 用户输入的字符串需要与此生成的字符串完全匹配。\n\n---\n\n### **动态调试**\n![phase_1](/images/phase1.png)\n下面是phase_1求解的完整流程:\n```lldb\nlldb bomb_linux <你的学号后六位>\n(lldb) b phase_1 # 在phase_1入口断点\n(lldb) run # 从入口开始执行\n请输入第1级的密码:114514 # 随便输入触发断点\n(lldb) b 0x401b6f # 在GenerateRandomString返回后断点\n(lldb) continue # 继续执行\n(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)\n0x7fffffffdaf5: \"mJHurpQZtY\" # 轻松拿下,这里是根据学号伪随机生成的哦\n```\n将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。\n\n---\n\n## **Phase_2**\n\n### **静态分析**\n\n这道题目还是比较一目了然的,观察`phase_2`代码不难发现其实构建了一张跳转表:\n```assembly\n0000000000401b8e :\n 401b8e:\tf3 0f 1e fa \tendbr64\n 401b92:\t55 \tpush %rbp\n 401b93:\t48 89 e5 \tmov %rsp,%rbp\n 401b96:\t48 83 ec 10 \tsub $0x10,%rsp\n 401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi\n 401ba3:\te8 05 fb ff ff \tcall 4016ad \n 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 \n 401baf:\t48 83 f8 0f \tcmp $0xf,%rax\n 401bb3:\t0f 87 16 01 00 00 \tja 401ccf \n 401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 401bc0:\t00 \n 401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>\n 401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 401bcb:\t48 98 \tcltq\n 401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>\n 401bd4:\t48 01 d0 \tadd %rdx,%rax\n 401bd7:\t3e ff e0 \tnotrack jmp *%rax\n 401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bde:\t48 89 c7 \tmov %rax,%rdi\n 401be1:\te8 f2 00 00 00 \tcall 401cd8 \n 401be6:\te9 ea 00 00 00 \tjmp 401cd5 \n 401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401bef:\t48 89 c7 \tmov %rax,%rdi\n 401bf2:\te8 8b 01 00 00 \tcall 401d82 \n 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 \n 401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax\n 401c00:\t48 89 c7 \tmov %rax,%rdi\n ...\n```\n这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是`GenerateRandomNumber`这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。\n\n---\n\n### **动态调试**\n理解原理就没什么难度了,自己找几个断点打好然后关注一下`rand_div`的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向`phase_2_14`跳转:\n![phase_2_14](/images/phase_2_14.png)\n\n而除了`phase_2_14`还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。\n\n---\n## **Phase_3**\n\n### **静态分析**\n\n和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi\n\n本体其实没有什么好说的,这里我跳转的方向是`Phase_3_5`简要解释一下可供参考:\n\n```assembly\n0000000000403001 :\n 403001:\tf3 0f 1e fa \tendbr64\n 403005:\t55 \tpush %rbp\n 403006:\t48 89 e5 \tmov %rsp,%rbp\n 403009:\t48 83 ec 20 \tsub $0x20,%rsp\n 40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)\n 403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)\n 403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)\n 40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx\n 403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx\n 403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax\n 40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>\n 403032:\t48 89 c7 \tmov %rax,%rdi\n 403035:\tb8 00 00 00 00 \tmov $0x0,%eax\n 40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n 40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)\n 403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)\n 403046:\t7f 05 \tjg 40304d \n 403048:\te8 a9 2b 00 00 \tcall 405bf6 \n 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi\n 403052:\te8 56 e6 ff ff \tcall 4016ad \n 403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40305a:\t48 63 d0 \tmovslq %eax,%rdx\n 40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 \n 403064:\t48 39 c2 \tcmp %rax,%rdx\n 403067:\t74 05 \tje 40306e \n 403069:\te8 88 2b 00 00 \tcall 405bf6 \n 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 403073:\te8 35 e6 ff ff \tcall 4016ad \n 403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax\n 40307b:\t83 f8 07 \tcmp $0x7,%eax\n 40307e:\t0f 87 eb 00 00 00 \tja 40316f \n 403084:\t89 c0 \tmov %eax,%eax\n 403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx\n 40308d:\t00 \n 40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>\n 403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax\n 403098:\t48 98 \tcltq\n 40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>\n 4030a1:\t48 01 d0 \tadd %rdx,%rax\n 4030a4:\t3e ff e0 \tnotrack jmp *%rax\n 4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 \n 4030ae:\t89 c2 \tmov %eax,%edx\n 4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax\n 4030b3:\t01 d0 \tadd %edx,%eax\n 4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)\n 4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 4030bd:\te8 eb e5 ff ff \tcall 4016ad \n ...\n 403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax\n 403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里\n 40317a:\t74 05 \tje 403181 \n 40317c:\te8 75 2a 00 00 \tcall 405bf6 \n 403181:\t90 \tnop\n 403182:\tc9 \tleave\n 403183:\tc3 \tret\n\n```\n看起来一大堆很吓人对不对?实际上确实很吓人。\n\n但是发现其中玄机后其实简单的没边,最终答案就藏在`0x403177`里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接`run`一下重开qwq)。\n\n---\n\n### **动态调试**\n\n阅读`Phase_3_5`发现这一关其实需要两个输入,并且第一个输入必须是`rand_div`,这里建议通过`si`单步执行监控好`rand_div`值变化,确定正确结果后使用`run`重开正确输入第一个密码后才能进行下一步求解:\n```lldb\n(lldb) si\nProcess 13376 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377\nbomb_linux`phase_3_5:\n-> 0x40317a <+377>: je 0x403181 ; <+384>\n 0x40317c <+379>: callq 0x405bf6 ; explode_bomb\n 0x403181 <+384>: nop\n 0x403182 <+385>: leave\n(lldb) x/wx $rbp-0x4\n0x7fffffffdb0c: 0xffffffd7\n```\n例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。\n\n---\n\n## **Phase_4**\n\n### **静态分析**\n\n本题依旧开局跳转,笔者的跳转方向是`phase_4_01`,如何跳转不再强调关注`rand_div`的值即可,下面请D指导解读一下`phase_4_01`的内容:\n```assembly\n0000000000404895 :\n ; 函数入口,初始化栈帧\n 404895:\tf3 0f 1e fa \tendbr64 \n 404899:\t55 \tpush %rbp\n 40489a:\t48 89 e5 \tmov %rsp,%rbp\n 40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间\n\n ; 初始化斐波那契数组(F(10)~F(24)的十六进制值)\n 4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针\n 4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55\n 4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89\n 4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144\n 4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233\n 4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377\n 4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610\n 4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987\n 4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597\n 4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584\n 4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181\n 4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765\n 4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946\n 4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711\n 404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657\n 404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368\n\n ; 读取输入到局部变量(格式为\"%d\")\n 40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址\n 404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串\n 404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串\"%d\"\n 40491d:\t48 89 ce \tmov %rcx,%rsi\n 404920:\t48 89 c7 \tmov %rax,%rdi\n 404923:\tb8 00 00 00 00 \tmov $0x0,%eax\n 404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>\n\n ; 验证输入有效性(必须为1个正数)\n 40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值\n 404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数\n 404934:\t75 07 \tjne 40493d ; 失败则爆炸\n 404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N\n 404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0\n 40493b:\t7f 05 \tjg 404942 \n 40493d:\te8 b4 12 00 00 \tcall 405bf6 \n\n ; 检查输入值上限(必须 > 1999)\n 404942:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制\n 40494a:\t7f 05 \tjg 404951 ; N > 1999?\n 40494c:\te8 a5 12 00 00 \tcall 405bf6 \n\n ; 计算 N/2000(通过定点数乘法优化)\n 404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N\n 404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展\n 404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)\n 40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位\n 404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000\n 404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展\n 404968:\t89 c1 \tmov %eax,%ecx \n 40496a:\t89 d0 \tmov %edx,%eax \n 40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况\n 40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000\n\n ; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列\n 404971:\t8b 45 ac \tmov -0x54(%rbp),%eax \n 404974:\t89 c7 \tmov %eax,%edi ; 参数k\n 404976:\te8 ce fd ff ff \tcall 404749 ; 返回值eax=F(k+1)\n 40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果\n\n ; 生成随机索引并验证结果\n 40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15\n 404983:\te8 25 cd ff ff \tcall 4016ad ; 生成0~14随机数\n 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 ; 获取随机索引\n 40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值\n 404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?\n 404996:\t74 05 \tje 40499d \n 404998:\te8 59 12 00 00 \tcall 405bf6 \n```\n所以相对还是很明了的,依旧是关注`rand_div`。\n\n### **动态调试**\n先找出`rand_div`在最后判断前的取值,比如我下面的0xa:\n\n```lldb\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108\nbomb_linux`GenerateRandomNumber:\n-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div\n 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n(lldb) si\nProcess 27027 stopped\n* thread #1, name = 'bomb_linux', stop reason = instruction step into\n frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115\nbomb_linux`GenerateRandomNumber:\n-> 0x401720 <+115>: jmp 0x401723 ; <+118>\n 0x401722 <+117>: nop\n 0x401723 <+118>: popq %rbp\n 0x401724 <+119>: retq\n(lldb) x/gx &rand_div\n0x00408820: 0x000000000000000a\n```\n\n而当 `rand_div = 0xa`(即十进制 **10**)时,输入值 `N` 的计算步骤如下:\n\n- 数组索引 **10** 的值是 **斐波那契数列第 20 项**(`F(20) = 6765`)。\n\n- `func4_0(k)` 实际计算的是 **标准斐波那契数列的第 `k+1` 项**(例如,`func4_0(0) = 1 = F(2)`) 需要满足:\n ```c\n func4_0(k) = F(k+1) = F(20)\n ```\n 解得:\n k + 1 = 20 → k = 19\n- `k = N / 2000` → `N = 2000 * k = 2000 * 19 = 38000`.\n从而得解。\n![phase_4](/images/phase_4.png)\n\n---\n\n## **Phase_Impossible**\n\nImpossible?\n\n从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:\n```c\nvoid phase_impossible(char *param_1)\n\n{\n int iVar1;\n size_t sVar2;\n undefined local_118 [256];\n long local_18;\n long local_10;\n \n local_10 = GetTickCount();\n sVar2 = strlen(param_1);\n if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {\n explode_bomb();\n }\n memset(local_118,0,0x100);\n tohex(local_118,param_1);\n GenerateRandomNumber(0x400);\n iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);\n if (iVar1 == 0) {\n puts(&DAT_00406518);\n explode_bomb();\n }\n GenerateRandomNumber(3);\n if (rand_div != 2) {\n if (2 < rand_div) goto LAB_00401891;\n if (rand_div == 0) {\n goto_buf_0(local_118);\n }\n else if (rand_div != 1) goto LAB_00401891;\n goto_buf_1(local_118);\n }\n goto_buf_2(local_118);\nLAB_00401891:\n explode_bomb();\n GenerateRandomNumber(0x400);\n if ((long)(int)result != rand_div) {\n printf(&DAT_00406560,rand_div,(ulong)result);\n explode_bomb();\n }\n local_18 = GetTickCount();\n if (1000 < (ulong)(local_18 - local_10)) {\n puts(&DAT_004065a8);\n explode_bomb();\n }\n return;\n}\n```\n最终任务还是很明确的,需要写一段机器码修改`result`的数值,但是注意要能通过`check_buf_valid`检测,并且最后指令必须是跳转到`0x401896`不然就会触发`phase_impossible`中`0x401891`处的`explode_bomb`函数,唯一的难点是跟踪`rand_div`的数值变化,建议使用`register write`来修改`check_buf_valid`的返回值使其强制通过然后监控`rand_div`每一次的数值变化(`x/gx &rand_div`),记录好`rand_div`的结果后开始指令设计,需要满足:\n\n - 指令的异或和为`rand_div`第一次的数值末尾八位以通过检查;\n - 修改`result`使其数值等于`rand_div`第三次数值;\n - 跳转到`0x401896`避免炸弹;\n\n 如果前几问都完成了到这里应该是没有问题的。\n\n---\n\n## **Phase_Secret**\n\n隐藏彩蛋,并非隐藏。汇编里写的非常清楚:\n```assembly\n0000000000401a8b :\n 401a8b:\tf3 0f 1e fa \tendbr64\n 401a8f:\t55 \tpush %rbp\n 401a90:\t48 89 e5 \tmov %rsp,%rbp\n 401a93:\t48 83 ec 10 \tsub $0x10,%rsp\n 401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)\n 401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>\n 401aa2:\t48 89 c7 \tmov %rax,%rdi\n 401aa5:\te8 76 f6 ff ff \tcall 401120 \n 401aaa:\t90 \tnop\n 401aab:\tc9 \tleave\n 401aac:\tc3 \tret\n```\n注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在`phase_5`中设计指令时加一个要求跳转到`0x401a8b`即可。\n\n完结\n![Case Closed](/images/caseclosed.png)\n","slug":"nudtbomblab","published":1,"updated":"2025-02-25T03:56:35.270Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q40015p22bbk3g76eg","content":"

这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。

\n

笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。

\n

Phase_1

静态分析

strings扫描

1
strings bomb_linux
\n

先用strings寻找可能与phase_1相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。
\"strings\"

\n
    \n
  • 结果没有明文密码无法直接秒掉第一问,可惜。
  • \n
  • 但是找到GenerateRandomString函数可能与密码生成相关。
  • \n
\n

objdump反汇编

1
objdump -d bomb_linux > bomb.asm
\n

搜索GenerateRandomStringphase_1函数的汇编代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
401b53 <phase_1>:
401b53: endbr64
401b57: push %rbp
401b58: mov %rsp,%rbp
401b5b: sub $0x20,%rsp
401b5f: mov %rdi,-0x18(%rbp)
401b63: lea -0xb(%rbp),%rax
401b67: mov %rax,%rdi
401b6a: callq 401ac1 <GenerateRandomString> # 调用密码生成函数
401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置
401b73: mov -0x18(%rbp),%rax
401b77: mov %rdx,%rsi
401b7a: mov %rax,%rdi
401b7d: callq 401c0c <string_compare> # 调用字符串比较函数
401b82: test %eax,%eax
401b84: je 401b8d <phase_1+0x3a>
401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹

\n
    \n
  • phase_1调用GenerateRandomString生成一个字符串。
  • \n
  • 用户输入的字符串需要与此生成的字符串完全匹配。
  • \n
\n
\n

动态调试

\"phase_1\"
下面是phase_1求解的完整流程:

\n
1
2
3
4
5
6
7
8
lldb bomb_linux <你的学号后六位>
(lldb) b phase_1 # 在phase_1入口断点
(lldb) run # 从入口开始执行
请输入第1级的密码:114514 # 随便输入触发断点
(lldb) b 0x401b6f # 在GenerateRandomString返回后断点
(lldb) continue # 继续执行
(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)
0x7fffffffdaf5: "mJHurpQZtY" # 轻松拿下,这里是根据学号伪随机生成的哦
\n

将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。

\n
\n

Phase_2

静态分析

这道题目还是比较一目了然的,观察phase_2代码不难发现其实构建了一张跳转表:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0000000000401b8e <phase_2>:
401b8e:\tf3 0f 1e fa \tendbr64
401b92:\t55 \tpush %rbp
401b93:\t48 89 e5 \tmov %rsp,%rbp
401b96:\t48 83 ec 10 \tsub $0x10,%rsp
401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi
401ba3:\te8 05 fb ff ff \tcall 4016ad <GenerateRandomNumber>
401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div>
401baf:\t48 83 f8 0f \tcmp $0xf,%rax
401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141>
401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
401bc0:\t00
401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>
401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
401bcb:\t48 98 \tcltq
401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>
401bd4:\t48 01 d0 \tadd %rdx,%rax
401bd7:\t3e ff e0 \tnotrack jmp *%rax
401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bde:\t48 89 c7 \tmov %rax,%rdi
401be1:\te8 f2 00 00 00 \tcall 401cd8 <phase_2_0>
401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bef:\t48 89 c7 \tmov %rax,%rdi
401bf2:\te8 8b 01 00 00 \tcall 401d82 <phase_2_1>
401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401c00:\t48 89 c7 \tmov %rax,%rdi
...
\n

这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是GenerateRandomNumber这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。

\n
\n

动态调试

理解原理就没什么难度了,自己找几个断点打好然后关注一下rand_div的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向phase_2_14跳转:
\"phase_2_14\"

\n

而除了phase_2_14还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。

\n
\n

Phase_3

静态分析

和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi

\n

本体其实没有什么好说的,这里我跳转的方向是Phase_3_5简要解释一下可供参考:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
0000000000403001 <phase_3_5>:
403001:\tf3 0f 1e fa \tendbr64
403005:\t55 \tpush %rbp
403006:\t48 89 e5 \tmov %rsp,%rbp
403009:\t48 83 ec 20 \tsub $0x20,%rsp
40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)
403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)
403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)
40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx
403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx
403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax
40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>
403032:\t48 89 c7 \tmov %rax,%rdi
403035:\tb8 00 00 00 00 \tmov $0x0,%eax
40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>
40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)
403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)
403046:\t7f 05 \tjg 40304d <phase_3_5+0x4c>
403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb>
40304d:\tbf 08 00 00 00 \tmov $0x8,%edi
403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40305a:\t48 63 d0 \tmovslq %eax,%rdx
40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 <rand_div>
403064:\t48 39 c2 \tcmp %rax,%rdx
403067:\t74 05 \tje 40306e <phase_3_5+0x6d>
403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb>
40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi
403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40307b:\t83 f8 07 \tcmp $0x7,%eax
40307e:\t0f 87 eb 00 00 00 \tja 40316f <phase_3_5+0x16e>
403084:\t89 c0 \tmov %eax,%eax
403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
40308d:\t00
40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>
403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
403098:\t48 98 \tcltq
40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>
4030a1:\t48 01 d0 \tadd %rdx,%rax
4030a4:\t3e ff e0 \tnotrack jmp *%rax
4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 <rand_div>
4030ae:\t89 c2 \tmov %eax,%edx
4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax
4030b3:\t01 d0 \tadd %edx,%eax
4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)
4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi
4030bd:\te8 eb e5 ff ff \tcall 4016ad <GenerateRandomNumber>
...
403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax
403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里
40317a:\t74 05 \tje 403181 <phase_3_5+0x180>
40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb>
403181:\t90 \tnop
403182:\tc9 \tleave
403183:\tc3 \tret

\n

看起来一大堆很吓人对不对?实际上确实很吓人。

\n

但是发现其中玄机后其实简单的没边,最终答案就藏在0x403177里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接run一下重开qwq)。

\n
\n

动态调试

阅读Phase_3_5发现这一关其实需要两个输入,并且第一个输入必须是rand_div,这里建议通过si单步执行监控好rand_div值变化,确定正确结果后使用run重开正确输入第一个密码后才能进行下一步求解:

\n
1
2
3
4
5
6
7
8
9
10
11
(lldb) si
Process 13376 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377
bomb_linux`phase_3_5:
-> 0x40317a <+377>: je 0x403181 ; <+384>
0x40317c <+379>: callq 0x405bf6 ; explode_bomb
0x403181 <+384>: nop
0x403182 <+385>: leave
(lldb) x/wx $rbp-0x4
0x7fffffffdb0c: 0xffffffd7
\n

例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。

\n
\n

Phase_4

静态分析

本题依旧开局跳转,笔者的跳转方向是phase_4_01,如何跳转不再强调关注rand_div的值即可,下面请D指导解读一下phase_4_01的内容:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
0000000000404895 <phase_4_01>:
; 函数入口,初始化栈帧
404895:\tf3 0f 1e fa \tendbr64
404899:\t55 \tpush %rbp
40489a:\t48 89 e5 \tmov %rsp,%rbp
40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间

; 初始化斐波那契数组(F(10)~F(24)的十六进制值)
4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针
4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55
4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89
4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144
4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233
4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377
4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610
4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987
4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597
4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584
4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181
4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765
4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946
4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711
404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657
404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368

; 读取输入到局部变量(格式为"%d")
40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址
404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串
404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串"%d"
40491d:\t48 89 ce \tmov %rcx,%rsi
404920:\t48 89 c7 \tmov %rax,%rdi
404923:\tb8 00 00 00 00 \tmov $0x0,%eax
404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>

; 验证输入有效性(必须为1个正数)
40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值
404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数
404934:\t75 07 \tjne 40493d <phase_4_01+0xa8> ; 失败则爆炸
404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N
404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0
40493b:\t7f 05 \tjg 404942 <phase_4_01+0xad>
40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb>

; 检查输入值上限(必须 > 1999)
404942:\t8b 45 ac \tmov -0x54(%rbp),%eax
404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制
40494a:\t7f 05 \tjg 404951 <phase_4_01+0xbc> ; N > 1999?
40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb>

; 计算 N/2000(通过定点数乘法优化)
404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N
404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展
404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)
40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位
404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000
404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展
404968:\t89 c1 \tmov %eax,%ecx
40496a:\t89 d0 \tmov %edx,%eax
40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况
40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000

; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列
404971:\t8b 45 ac \tmov -0x54(%rbp),%eax
404974:\t89 c7 \tmov %eax,%edi ; 参数k
404976:\te8 ce fd ff ff \tcall 404749 <func4_0> ; 返回值eax=F(k+1)
40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果

; 生成随机索引并验证结果
40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15
404983:\te8 25 cd ff ff \tcall 4016ad <GenerateRandomNumber> ; 生成0~14随机数
404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引
40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值
404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?
404996:\t74 05 \tje 40499d <phase_4_01+0x108>
404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb>
\n

所以相对还是很明了的,依旧是关注rand_div

\n

动态调试

先找出rand_div在最后判断前的取值,比如我下面的0xa:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108
bomb_linux`GenerateRandomNumber:
-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div
0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115
bomb_linux`GenerateRandomNumber:
-> 0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
0x401724 <+119>: retq
(lldb) x/gx &rand_div
0x00408820: 0x000000000000000a
\n\n

而当 rand_div = 0xa(即十进制 10)时,输入值 N 的计算步骤如下:

\n
    \n
  • 数组索引 10 的值是 斐波那契数列第 20 项F(20) = 6765)。

    \n
  • \n
  • func4_0(k) 实际计算的是 标准斐波那契数列的第 k+1(例如,func4_0(0) = 1 = F(2)) 需要满足:

    \n
    1
    func4_0(k) = F(k+1) = F(20)
    \n

    解得:
    k + 1 = 20 → k = 19

    \n
  • \n
  • k = N / 2000N = 2000 * k = 2000 * 19 = 38000.
    从而得解。
    \"phase_4\"

    \n
  • \n
\n
\n

Phase_Impossible

Impossible?

\n

从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void phase_impossible(char *param_1)

{
int iVar1;
size_t sVar2;
undefined local_118 [256];
long local_18;
long local_10;

local_10 = GetTickCount();
sVar2 = strlen(param_1);
if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {
explode_bomb();
}
memset(local_118,0,0x100);
tohex(local_118,param_1);
GenerateRandomNumber(0x400);
iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);
if (iVar1 == 0) {
puts(&DAT_00406518);
explode_bomb();
}
GenerateRandomNumber(3);
if (rand_div != 2) {
if (2 < rand_div) goto LAB_00401891;
if (rand_div == 0) {
goto_buf_0(local_118);
}
else if (rand_div != 1) goto LAB_00401891;
goto_buf_1(local_118);
}
goto_buf_2(local_118);
LAB_00401891:
explode_bomb();
GenerateRandomNumber(0x400);
if ((long)(int)result != rand_div) {
printf(&DAT_00406560,rand_div,(ulong)result);
explode_bomb();
}
local_18 = GetTickCount();
if (1000 < (ulong)(local_18 - local_10)) {
puts(&DAT_004065a8);
explode_bomb();
}
return;
}
\n

最终任务还是很明确的,需要写一段机器码修改result的数值,但是注意要能通过check_buf_valid检测,并且最后指令必须是跳转到0x401896不然就会触发phase_impossible0x401891处的explode_bomb函数,唯一的难点是跟踪rand_div的数值变化,建议使用register write来修改check_buf_valid的返回值使其强制通过然后监控rand_div每一次的数值变化(x/gx &rand_div),记录好rand_div的结果后开始指令设计,需要满足:

\n
    \n
  • 指令的异或和为rand_div第一次的数值末尾八位以通过检查;
  • \n
  • 修改result使其数值等于rand_div第三次数值;
  • \n
  • 跳转到0x401896避免炸弹;
  • \n
\n

如果前几问都完成了到这里应该是没有问题的。

\n
\n

Phase_Secret

隐藏彩蛋,并非隐藏。汇编里写的非常清楚:

\n
1
2
3
4
5
6
7
8
9
10
11
12
0000000000401a8b <phase_secret>:
401a8b:\tf3 0f 1e fa \tendbr64
401a8f:\t55 \tpush %rbp
401a90:\t48 89 e5 \tmov %rsp,%rbp
401a93:\t48 83 ec 10 \tsub $0x10,%rsp
401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>
401aa2:\t48 89 c7 \tmov %rax,%rdi
401aa5:\te8 76 f6 ff ff \tcall 401120 <puts@plt>
401aaa:\t90 \tnop
401aab:\tc9 \tleave
401aac:\tc3 \tret
\n

注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在phase_5中设计指令时加一个要求跳转到0x401a8b即可。

\n

完结
\"Case

\n","excerpt":"","more":"

这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。

\n

笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。

\n

Phase_1

静态分析

strings扫描

1
strings bomb_linux
\n

先用strings寻找可能与phase_1相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。
\"strings\"

\n
    \n
  • 结果没有明文密码无法直接秒掉第一问,可惜。
  • \n
  • 但是找到GenerateRandomString函数可能与密码生成相关。
  • \n
\n

objdump反汇编

1
objdump -d bomb_linux > bomb.asm
\n

搜索GenerateRandomStringphase_1函数的汇编代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
401b53 <phase_1>:
401b53: endbr64
401b57: push %rbp
401b58: mov %rsp,%rbp
401b5b: sub $0x20,%rsp
401b5f: mov %rdi,-0x18(%rbp)
401b63: lea -0xb(%rbp),%rax
401b67: mov %rax,%rdi
401b6a: callq 401ac1 <GenerateRandomString> # 调用密码生成函数
401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置
401b73: mov -0x18(%rbp),%rax
401b77: mov %rdx,%rsi
401b7a: mov %rax,%rdi
401b7d: callq 401c0c <string_compare> # 调用字符串比较函数
401b82: test %eax,%eax
401b84: je 401b8d <phase_1+0x3a>
401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹

\n
    \n
  • phase_1调用GenerateRandomString生成一个字符串。
  • \n
  • 用户输入的字符串需要与此生成的字符串完全匹配。
  • \n
\n
\n

动态调试

\"phase_1\"
下面是phase_1求解的完整流程:

\n
1
2
3
4
5
6
7
8
lldb bomb_linux <你的学号后六位>
(lldb) b phase_1 # 在phase_1入口断点
(lldb) run # 从入口开始执行
请输入第1级的密码:114514 # 随便输入触发断点
(lldb) b 0x401b6f # 在GenerateRandomString返回后断点
(lldb) continue # 继续执行
(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)
0x7fffffffdaf5: "mJHurpQZtY" # 轻松拿下,这里是根据学号伪随机生成的哦
\n

将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。

\n
\n

Phase_2

静态分析

这道题目还是比较一目了然的,观察phase_2代码不难发现其实构建了一张跳转表:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0000000000401b8e <phase_2>:
401b8e:\tf3 0f 1e fa \tendbr64
401b92:\t55 \tpush %rbp
401b93:\t48 89 e5 \tmov %rsp,%rbp
401b96:\t48 83 ec 10 \tsub $0x10,%rsp
401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi
401ba3:\te8 05 fb ff ff \tcall 4016ad <GenerateRandomNumber>
401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div>
401baf:\t48 83 f8 0f \tcmp $0xf,%rax
401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141>
401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
401bc0:\t00
401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614>
401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
401bcb:\t48 98 \tcltq
401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614>
401bd4:\t48 01 d0 \tadd %rdx,%rax
401bd7:\t3e ff e0 \tnotrack jmp *%rax
401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bde:\t48 89 c7 \tmov %rax,%rdi
401be1:\te8 f2 00 00 00 \tcall 401cd8 <phase_2_0>
401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401bef:\t48 89 c7 \tmov %rax,%rdi
401bf2:\te8 8b 01 00 00 \tcall 401d82 <phase_2_1>
401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147>
401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax
401c00:\t48 89 c7 \tmov %rax,%rdi
...
\n

这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是GenerateRandomNumber这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。

\n
\n

动态调试

理解原理就没什么难度了,自己找几个断点打好然后关注一下rand_div的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向phase_2_14跳转:
\"phase_2_14\"

\n

而除了phase_2_14还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。

\n
\n

Phase_3

静态分析

和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi

\n

本体其实没有什么好说的,这里我跳转的方向是Phase_3_5简要解释一下可供参考:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
0000000000403001 <phase_3_5>:
403001:\tf3 0f 1e fa \tendbr64
403005:\t55 \tpush %rbp
403006:\t48 89 e5 \tmov %rsp,%rbp
403009:\t48 83 ec 20 \tsub $0x20,%rsp
40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)
403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)
403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)
40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx
403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx
403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax
40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c>
403032:\t48 89 c7 \tmov %rax,%rdi
403035:\tb8 00 00 00 00 \tmov $0x0,%eax
40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt>
40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)
403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)
403046:\t7f 05 \tjg 40304d <phase_3_5+0x4c>
403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb>
40304d:\tbf 08 00 00 00 \tmov $0x8,%edi
403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40305a:\t48 63 d0 \tmovslq %eax,%rdx
40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 <rand_div>
403064:\t48 39 c2 \tcmp %rax,%rdx
403067:\t74 05 \tje 40306e <phase_3_5+0x6d>
403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb>
40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi
403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber>
403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax
40307b:\t83 f8 07 \tcmp $0x7,%eax
40307e:\t0f 87 eb 00 00 00 \tja 40316f <phase_3_5+0x16e>
403084:\t89 c0 \tmov %eax,%eax
403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx
40308d:\t00
40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734>
403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax
403098:\t48 98 \tcltq
40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734>
4030a1:\t48 01 d0 \tadd %rdx,%rax
4030a4:\t3e ff e0 \tnotrack jmp *%rax
4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 <rand_div>
4030ae:\t89 c2 \tmov %eax,%edx
4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax
4030b3:\t01 d0 \tadd %edx,%eax
4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)
4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi
4030bd:\te8 eb e5 ff ff \tcall 4016ad <GenerateRandomNumber>
...
403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax
403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里
40317a:\t74 05 \tje 403181 <phase_3_5+0x180>
40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb>
403181:\t90 \tnop
403182:\tc9 \tleave
403183:\tc3 \tret

\n

看起来一大堆很吓人对不对?实际上确实很吓人。

\n

但是发现其中玄机后其实简单的没边,最终答案就藏在0x403177里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接run一下重开qwq)。

\n
\n

动态调试

阅读Phase_3_5发现这一关其实需要两个输入,并且第一个输入必须是rand_div,这里建议通过si单步执行监控好rand_div值变化,确定正确结果后使用run重开正确输入第一个密码后才能进行下一步求解:

\n
1
2
3
4
5
6
7
8
9
10
11
(lldb) si
Process 13376 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377
bomb_linux`phase_3_5:
-> 0x40317a <+377>: je 0x403181 ; <+384>
0x40317c <+379>: callq 0x405bf6 ; explode_bomb
0x403181 <+384>: nop
0x403182 <+385>: leave
(lldb) x/wx $rbp-0x4
0x7fffffffdb0c: 0xffffffd7
\n

例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。

\n
\n

Phase_4

静态分析

本题依旧开局跳转,笔者的跳转方向是phase_4_01,如何跳转不再强调关注rand_div的值即可,下面请D指导解读一下phase_4_01的内容:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
0000000000404895 <phase_4_01>:
; 函数入口,初始化栈帧
404895:\tf3 0f 1e fa \tendbr64
404899:\t55 \tpush %rbp
40489a:\t48 89 e5 \tmov %rsp,%rbp
40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间

; 初始化斐波那契数组(F(10)~F(24)的十六进制值)
4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针
4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55
4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89
4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144
4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233
4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377
4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610
4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987
4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597
4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584
4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181
4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765
4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946
4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711
404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657
404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368

; 读取输入到局部变量(格式为"%d")
40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址
404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串
404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串"%d"
40491d:\t48 89 ce \tmov %rcx,%rsi
404920:\t48 89 c7 \tmov %rax,%rdi
404923:\tb8 00 00 00 00 \tmov $0x0,%eax
404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt>

; 验证输入有效性(必须为1个正数)
40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值
404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数
404934:\t75 07 \tjne 40493d <phase_4_01+0xa8> ; 失败则爆炸
404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N
404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0
40493b:\t7f 05 \tjg 404942 <phase_4_01+0xad>
40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb>

; 检查输入值上限(必须 > 1999)
404942:\t8b 45 ac \tmov -0x54(%rbp),%eax
404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制
40494a:\t7f 05 \tjg 404951 <phase_4_01+0xbc> ; N > 1999?
40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb>

; 计算 N/2000(通过定点数乘法优化)
404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N
404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展
404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)
40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位
404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000
404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展
404968:\t89 c1 \tmov %eax,%ecx
40496a:\t89 d0 \tmov %edx,%eax
40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况
40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000

; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列
404971:\t8b 45 ac \tmov -0x54(%rbp),%eax
404974:\t89 c7 \tmov %eax,%edi ; 参数k
404976:\te8 ce fd ff ff \tcall 404749 <func4_0> ; 返回值eax=F(k+1)
40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果

; 生成随机索引并验证结果
40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15
404983:\te8 25 cd ff ff \tcall 4016ad <GenerateRandomNumber> ; 生成0~14随机数
404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引
40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值
404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?
404996:\t74 05 \tje 40499d <phase_4_01+0x108>
404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb>
\n

所以相对还是很明了的,依旧是关注rand_div

\n

动态调试

先找出rand_div在最后判断前的取值,比如我下面的0xa:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108
bomb_linux`GenerateRandomNumber:
-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div
0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
(lldb) si
Process 27027 stopped
* thread #1, name = 'bomb_linux', stop reason = instruction step into
frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115
bomb_linux`GenerateRandomNumber:
-> 0x401720 <+115>: jmp 0x401723 ; <+118>
0x401722 <+117>: nop
0x401723 <+118>: popq %rbp
0x401724 <+119>: retq
(lldb) x/gx &rand_div
0x00408820: 0x000000000000000a
\n\n

而当 rand_div = 0xa(即十进制 10)时,输入值 N 的计算步骤如下:

\n
    \n
  • 数组索引 10 的值是 斐波那契数列第 20 项F(20) = 6765)。

    \n
  • \n
  • func4_0(k) 实际计算的是 标准斐波那契数列的第 k+1(例如,func4_0(0) = 1 = F(2)) 需要满足:

    \n
    1
    func4_0(k) = F(k+1) = F(20)
    \n

    解得:
    k + 1 = 20 → k = 19

    \n
  • \n
  • k = N / 2000N = 2000 * k = 2000 * 19 = 38000.
    从而得解。
    \"phase_4\"

    \n
  • \n
\n
\n

Phase_Impossible

Impossible?

\n

从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void phase_impossible(char *param_1)

{
int iVar1;
size_t sVar2;
undefined local_118 [256];
long local_18;
long local_10;

local_10 = GetTickCount();
sVar2 = strlen(param_1);
if ((sVar2 < 10) || (sVar2 = strlen(param_1), 0x300 < sVar2)) {
explode_bomb();
}
memset(local_118,0,0x100);
tohex(local_118,param_1);
GenerateRandomNumber(0x400);
iVar1 = check_buf_valid(local_118,rand_div & 0xffffffff);
if (iVar1 == 0) {
puts(&DAT_00406518);
explode_bomb();
}
GenerateRandomNumber(3);
if (rand_div != 2) {
if (2 < rand_div) goto LAB_00401891;
if (rand_div == 0) {
goto_buf_0(local_118);
}
else if (rand_div != 1) goto LAB_00401891;
goto_buf_1(local_118);
}
goto_buf_2(local_118);
LAB_00401891:
explode_bomb();
GenerateRandomNumber(0x400);
if ((long)(int)result != rand_div) {
printf(&DAT_00406560,rand_div,(ulong)result);
explode_bomb();
}
local_18 = GetTickCount();
if (1000 < (ulong)(local_18 - local_10)) {
puts(&DAT_004065a8);
explode_bomb();
}
return;
}
\n

最终任务还是很明确的,需要写一段机器码修改result的数值,但是注意要能通过check_buf_valid检测,并且最后指令必须是跳转到0x401896不然就会触发phase_impossible0x401891处的explode_bomb函数,唯一的难点是跟踪rand_div的数值变化,建议使用register write来修改check_buf_valid的返回值使其强制通过然后监控rand_div每一次的数值变化(x/gx &rand_div),记录好rand_div的结果后开始指令设计,需要满足:

\n
    \n
  • 指令的异或和为rand_div第一次的数值末尾八位以通过检查;
  • \n
  • 修改result使其数值等于rand_div第三次数值;
  • \n
  • 跳转到0x401896避免炸弹;
  • \n
\n

如果前几问都完成了到这里应该是没有问题的。

\n
\n

Phase_Secret

隐藏彩蛋,并非隐藏。汇编里写的非常清楚:

\n
1
2
3
4
5
6
7
8
9
10
11
12
0000000000401a8b <phase_secret>:
401a8b:\tf3 0f 1e fa \tendbr64
401a8f:\t55 \tpush %rbp
401a90:\t48 89 e5 \tmov %rsp,%rbp
401a93:\t48 83 ec 10 \tsub $0x10,%rsp
401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)
401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8>
401aa2:\t48 89 c7 \tmov %rax,%rdi
401aa5:\te8 76 f6 ff ff \tcall 401120 <puts@plt>
401aaa:\t90 \tnop
401aab:\tc9 \tleave
401aac:\tc3 \tret
\n

注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在phase_5中设计指令时加一个要求跳转到0x401a8b即可。

\n

完结
\"Case

\n"},{"title":"Overleaf Toolkit踩坑记录","date":"2024-11-06T01:56:18.000Z","_content":"\n在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。\n\n具体流程就不赘述了,先将访问[Overleaf Toolkit官方仓库](https://github.com/overleaf/toolkit)将代码clone下来并按照手册执行即可。\n\n## 问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像\n\n在执行 `bin/up` 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。\n\n截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。\n\n### 解决方案:为 Docker 设置代理\n\n通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:\n\n1. 创建一个 `systemd` 服务文件,为 Docker 设置代理。\n2. 编辑 `/etc/systemd/system/docker.service.d/proxy.conf` 文件,添加以下内容(确保已经设置了代理服务器):\n\n ```ini\n [Service]\n Environment=\"HTTP_PROXY=http://:\"\n Environment=\"HTTPS_PROXY=http://:\"\n Environment=\"NO_PROXY=localhost,127.0.0.1\"\n ```\n\n3. 重新加载 `systemd` 配置并重启 Docker:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl restart docker\n ```\n\n4. 重启 Docker 后再次执行 `sudo ./up`,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。\n\n\n---\n\n## 问题二:外部机器无法访问 Overleaf Web 服务\n\n先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。\n\n注意到在默认的 `lib/docker-compose.base.yml` 配置中,Overleaf Web 服务的端口映射方式为 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"`。\n\n### 解决方案:修改端口映射\n\n在 `docker-compose.base.yml` 文件中,删除 `${OVERLEAF_LISTEN_IP:-127.0.0.1}` 前缀,将 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"` 修改为 `\"${OVERLEAF_PORT:-80}:80\"`。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。\n\n修改后的 `docker-compose.base.yml` 端口映射配置如下:\n\n```yaml\n---\nservices:\n\n sharelatex:\n restart: always\n image: \"${IMAGE}\"\n container_name: sharelatex\n volumes:\n - \"${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}\"\n ports:\n #- \"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"\n - \"${OVERLEAF_PORT:-80}:80\"\n environment:\n GIT_BRIDGE_ENABLED: \"${GIT_BRIDGE_ENABLED}\"\n GIT_BRIDGE_HOST: \"git-bridge\"\n GIT_BRIDGE_PORT: \"8000\"\n REDIS_HOST: \"${REDIS_HOST}\"\n REDIS_PORT: \"${REDIS_PORT}\"\n V1_HISTORY_URL: \"http://sharelatex:3100/api\"\n env_file:\n - ../config/variables.env\n stop_grace_period: 60s\n```\n\n完成修改后,重新启动 Docker 服务:\n\n```bash\nsudo ./start\n```\n\n现在,外部机器可以通过服务器的 IP 地址加端口 `{Overleaf_Port}` 访问 Overleaf Web 服务。\n\n---\n\n## 总结\n\n这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 `docker-compose.base.yml` 中的端口映射使外部设备可以访问 Overleaf 服务。\n\n可以在这里参考我的本地[Overleaf](https://overleaf.hifuu.ink)效果,注意安装完后还需要配置latex包和中文字体。\n\n这篇记录希望能为遇到类似问题的朋友提供帮助。\n","source":"_posts/overleaf.md","raw":"---\ntitle: Overleaf Toolkit踩坑记录\ndate: 2024-11-06 09:56:18\ntags: 技术\ncategories: [技术分享]\n---\n\n在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。\n\n具体流程就不赘述了,先将访问[Overleaf Toolkit官方仓库](https://github.com/overleaf/toolkit)将代码clone下来并按照手册执行即可。\n\n## 问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像\n\n在执行 `bin/up` 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。\n\n截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。\n\n### 解决方案:为 Docker 设置代理\n\n通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:\n\n1. 创建一个 `systemd` 服务文件,为 Docker 设置代理。\n2. 编辑 `/etc/systemd/system/docker.service.d/proxy.conf` 文件,添加以下内容(确保已经设置了代理服务器):\n\n ```ini\n [Service]\n Environment=\"HTTP_PROXY=http://:\"\n Environment=\"HTTPS_PROXY=http://:\"\n Environment=\"NO_PROXY=localhost,127.0.0.1\"\n ```\n\n3. 重新加载 `systemd` 配置并重启 Docker:\n\n ```bash\n sudo systemctl daemon-reload\n sudo systemctl restart docker\n ```\n\n4. 重启 Docker 后再次执行 `sudo ./up`,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。\n\n\n---\n\n## 问题二:外部机器无法访问 Overleaf Web 服务\n\n先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。\n\n注意到在默认的 `lib/docker-compose.base.yml` 配置中,Overleaf Web 服务的端口映射方式为 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"`。\n\n### 解决方案:修改端口映射\n\n在 `docker-compose.base.yml` 文件中,删除 `${OVERLEAF_LISTEN_IP:-127.0.0.1}` 前缀,将 `\"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"` 修改为 `\"${OVERLEAF_PORT:-80}:80\"`。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。\n\n修改后的 `docker-compose.base.yml` 端口映射配置如下:\n\n```yaml\n---\nservices:\n\n sharelatex:\n restart: always\n image: \"${IMAGE}\"\n container_name: sharelatex\n volumes:\n - \"${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}\"\n ports:\n #- \"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80\"\n - \"${OVERLEAF_PORT:-80}:80\"\n environment:\n GIT_BRIDGE_ENABLED: \"${GIT_BRIDGE_ENABLED}\"\n GIT_BRIDGE_HOST: \"git-bridge\"\n GIT_BRIDGE_PORT: \"8000\"\n REDIS_HOST: \"${REDIS_HOST}\"\n REDIS_PORT: \"${REDIS_PORT}\"\n V1_HISTORY_URL: \"http://sharelatex:3100/api\"\n env_file:\n - ../config/variables.env\n stop_grace_period: 60s\n```\n\n完成修改后,重新启动 Docker 服务:\n\n```bash\nsudo ./start\n```\n\n现在,外部机器可以通过服务器的 IP 地址加端口 `{Overleaf_Port}` 访问 Overleaf Web 服务。\n\n---\n\n## 总结\n\n这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 `docker-compose.base.yml` 中的端口映射使外部设备可以访问 Overleaf 服务。\n\n可以在这里参考我的本地[Overleaf](https://overleaf.hifuu.ink)效果,注意安装完后还需要配置latex包和中文字体。\n\n这篇记录希望能为遇到类似问题的朋友提供帮助。\n","slug":"overleaf","published":1,"updated":"2024-11-06T02:31:56.685Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q40018p22b4lpt3rxw","content":"

在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。

\n

具体流程就不赘述了,先将访问Overleaf Toolkit官方仓库将代码clone下来并按照手册执行即可。

\n

问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像

在执行 bin/up 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。

\n

截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。

\n

解决方案:为 Docker 设置代理

通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:

\n
    \n
  1. 创建一个 systemd 服务文件,为 Docker 设置代理。

    \n
  2. \n
  3. 编辑 /etc/systemd/system/docker.service.d/proxy.conf 文件,添加以下内容(确保已经设置了代理服务器):

    \n
    1
    2
    3
    4
    [Service]
    Environment="HTTP_PROXY=http://<your-proxy-server>:<port>"
    Environment="HTTPS_PROXY=http://<your-proxy-server>:<port>"
    Environment="NO_PROXY=localhost,127.0.0.1"
    \n
  4. \n
  5. 重新加载 systemd 配置并重启 Docker:

    \n
    1
    2
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    \n
  6. \n
  7. 重启 Docker 后再次执行 sudo ./up,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。

    \n
  8. \n
\n
\n

问题二:外部机器无法访问 Overleaf Web 服务

先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。

\n

注意到在默认的 lib/docker-compose.base.yml 配置中,Overleaf Web 服务的端口映射方式为 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"

\n

解决方案:修改端口映射

docker-compose.base.yml 文件中,删除 ${OVERLEAF_LISTEN_IP:-127.0.0.1} 前缀,将 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80" 修改为 "${OVERLEAF_PORT:-80}:80"。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。

\n

修改后的 docker-compose.base.yml 端口映射配置如下:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
services:

sharelatex:
restart: always
image: "${IMAGE}"
container_name: sharelatex
volumes:
- "${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}"
ports:
#- "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"
- "${OVERLEAF_PORT:-80}:80"
environment:
GIT_BRIDGE_ENABLED: "${GIT_BRIDGE_ENABLED}"
GIT_BRIDGE_HOST: "git-bridge"
GIT_BRIDGE_PORT: "8000"
REDIS_HOST: "${REDIS_HOST}"
REDIS_PORT: "${REDIS_PORT}"
V1_HISTORY_URL: "http://sharelatex:3100/api"
env_file:
- ../config/variables.env
stop_grace_period: 60s
\n\n

完成修改后,重新启动 Docker 服务:

\n
1
sudo ./start
\n\n

现在,外部机器可以通过服务器的 IP 地址加端口 {Overleaf_Port} 访问 Overleaf Web 服务。

\n
\n

总结

这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 docker-compose.base.yml 中的端口映射使外部设备可以访问 Overleaf 服务。

\n

可以在这里参考我的本地Overleaf效果,注意安装完后还需要配置latex包和中文字体。

\n

这篇记录希望能为遇到类似问题的朋友提供帮助。

\n","excerpt":"","more":"

在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。

\n

具体流程就不赘述了,先将访问Overleaf Toolkit官方仓库将代码clone下来并按照手册执行即可。

\n

问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像

在执行 bin/up 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。

\n

截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。

\n

解决方案:为 Docker 设置代理

通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:

\n
    \n
  1. 创建一个 systemd 服务文件,为 Docker 设置代理。

    \n
  2. \n
  3. 编辑 /etc/systemd/system/docker.service.d/proxy.conf 文件,添加以下内容(确保已经设置了代理服务器):

    \n
    1
    2
    3
    4
    [Service]
    Environment="HTTP_PROXY=http://<your-proxy-server>:<port>"
    Environment="HTTPS_PROXY=http://<your-proxy-server>:<port>"
    Environment="NO_PROXY=localhost,127.0.0.1"
    \n
  4. \n
  5. 重新加载 systemd 配置并重启 Docker:

    \n
    1
    2
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    \n
  6. \n
  7. 重启 Docker 后再次执行 sudo ./up,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。

    \n
  8. \n
\n
\n

问题二:外部机器无法访问 Overleaf Web 服务

先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。

\n

注意到在默认的 lib/docker-compose.base.yml 配置中,Overleaf Web 服务的端口映射方式为 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"

\n

解决方案:修改端口映射

docker-compose.base.yml 文件中,删除 ${OVERLEAF_LISTEN_IP:-127.0.0.1} 前缀,将 "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80" 修改为 "${OVERLEAF_PORT:-80}:80"。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。

\n

修改后的 docker-compose.base.yml 端口映射配置如下:

\n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
services:

sharelatex:
restart: always
image: "${IMAGE}"
container_name: sharelatex
volumes:
- "${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}"
ports:
#- "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"
- "${OVERLEAF_PORT:-80}:80"
environment:
GIT_BRIDGE_ENABLED: "${GIT_BRIDGE_ENABLED}"
GIT_BRIDGE_HOST: "git-bridge"
GIT_BRIDGE_PORT: "8000"
REDIS_HOST: "${REDIS_HOST}"
REDIS_PORT: "${REDIS_PORT}"
V1_HISTORY_URL: "http://sharelatex:3100/api"
env_file:
- ../config/variables.env
stop_grace_period: 60s
\n\n

完成修改后,重新启动 Docker 服务:

\n
1
sudo ./start
\n\n

现在,外部机器可以通过服务器的 IP 地址加端口 {Overleaf_Port} 访问 Overleaf Web 服务。

\n
\n

总结

这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 docker-compose.base.yml 中的端口映射使外部设备可以访问 Overleaf 服务。

\n

可以在这里参考我的本地Overleaf效果,注意安装完后还需要配置latex包和中文字体。

\n

这篇记录希望能为遇到类似问题的朋友提供帮助。

\n"},{"title":"相见恨晚的 SearXNG:打造私人搜索引擎全指南","date":"2025-03-10T14:55:04.000Z","_content":"\n![SearXNG 界面预览](/images/searxng.png) \n**厌倦了商业搜索引擎的广告追踪?** 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 [SearXNG](https://github.com/searxng/searxng) 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。\n\n---\n\n### ▍ 为什么选择 SearXNG?\n✅ **核心优势矩阵** \n| 特性 | 实现方式 | 用户收益 |\n|--------------------|----------------------------|------------------------|\n| 隐私保护 | 匿名聚合第三方结果 | 无搜索历史追踪 |\n| 结果去商业化 | 过滤 SEO 优化内容 | 提升技术资料检索效率 |\n| 多引擎支持 | 集成 Google/Bing/Brave 等 70+ 源 | 规避单一引擎局限 |\n| 界面定制 | 主题引擎分离设计 | 打造个性化搜索门户 |\n\n⚠️ 同类工具对比: \n此前使用的 [luxirty-search](https://github.com/KoriIku/luxirty-search) 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。\n\n之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。\n\n---\n\n### ▍ 极简部署方案\n#### ▶ 环境准备\n```bash\nmkdir -p ~/services/searxng && cd $_ # 随意找个地方创建专用目录\nexport SEARXNG_PORT=8080 # 设置服务端口\n```\n\n#### ▶ 容器化部署\n```bash\n# 拉取官方镜像\ndocker pull searxng/searxng\n\n# 启动容器(推荐绑定持久化配置)\ndocker run -d --restart=unless-stopped \\\n -p ${SEARXNG_PORT}:8080 \\\n -v \"${PWD}/config:/etc/searxng\" \\\n -e \"BASE_URL=http://your-domain.com\" \\\n -e \"INSTANCE_NAME=PrivateSearch\" \\\n searxng/searxng\n```\n📌 参数说明: \n- `-v` 挂载配置文件实现持久化 \n- `--restart` 确保服务异常退出后自动重启 \n- `BASE_URL` 需替换为实际访问域名,不过也可以后续再配置\n\n---\n\n### ▍ 高频问题排雷\n#### 🔴 镜像拉取失败\n**现象**:`Error response from daemon: pull access denied` \n✅ 解决方案: \n参考先前的 [Overleaf Toolkit 踩坑记录](https://blog.hifuu.ink/2024/11/06/overleaf/) 配置镜像加速源\n\n#### 🔴 Google 频繁拦截\n**现象**:`Too Many Requests` 错误频发 \n\n⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案\n\n✅ 实战验证方案: \n更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。\n\n📌 在配置文件设置代理: \n```yaml\noutgoing:\n proxies:\n all://:\n - http://
:\n```\n\n---\n\n### ▍ 效果展示与体验\n访问我的生产环境实例 [search.hifuu.ink](https://search.hifuu.ink) 可体验以下功能: \n- 🔍 多引擎结果聚合对比 \n- 🌍 支持 30+ 语言实时翻译 \n- 🛡️ 零 Cookie 跟踪的隐私模式 \n- 🎨 主题切换 \n\n---\n### ▍ 进阶优化建议\n1. **反向代理配置** \n\n网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。\n\n2. **定期维护命令** \n```bash\n# 更新搜索引擎引擎列表\ndocker exec -it searxng python -m searx.engines --update\n```\n\n3. **监控指标集成** \n通过 Prometheus 导出搜索统计:\n```bash\ndocker run -d --network=searxng-net \\\n -v \"${PWD}/metrics:/metrics\" \\\n prom/prometheus --config.file=/metrics/searxng.yml\n``` \n\n---\n\n**🚀 立即行动** \n\n快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。\n","source":"_posts/searxng.md","raw":"---\ntitle: 相见恨晚的 SearXNG:打造私人搜索引擎全指南\ndate: 2025-03-10 22:55:04\ntags: [开源工具, 技术分享]\n---\n\n![SearXNG 界面预览](/images/searxng.png) \n**厌倦了商业搜索引擎的广告追踪?** 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 [SearXNG](https://github.com/searxng/searxng) 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。\n\n---\n\n### ▍ 为什么选择 SearXNG?\n✅ **核心优势矩阵** \n| 特性 | 实现方式 | 用户收益 |\n|--------------------|----------------------------|------------------------|\n| 隐私保护 | 匿名聚合第三方结果 | 无搜索历史追踪 |\n| 结果去商业化 | 过滤 SEO 优化内容 | 提升技术资料检索效率 |\n| 多引擎支持 | 集成 Google/Bing/Brave 等 70+ 源 | 规避单一引擎局限 |\n| 界面定制 | 主题引擎分离设计 | 打造个性化搜索门户 |\n\n⚠️ 同类工具对比: \n此前使用的 [luxirty-search](https://github.com/KoriIku/luxirty-search) 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。\n\n之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。\n\n---\n\n### ▍ 极简部署方案\n#### ▶ 环境准备\n```bash\nmkdir -p ~/services/searxng && cd $_ # 随意找个地方创建专用目录\nexport SEARXNG_PORT=8080 # 设置服务端口\n```\n\n#### ▶ 容器化部署\n```bash\n# 拉取官方镜像\ndocker pull searxng/searxng\n\n# 启动容器(推荐绑定持久化配置)\ndocker run -d --restart=unless-stopped \\\n -p ${SEARXNG_PORT}:8080 \\\n -v \"${PWD}/config:/etc/searxng\" \\\n -e \"BASE_URL=http://your-domain.com\" \\\n -e \"INSTANCE_NAME=PrivateSearch\" \\\n searxng/searxng\n```\n📌 参数说明: \n- `-v` 挂载配置文件实现持久化 \n- `--restart` 确保服务异常退出后自动重启 \n- `BASE_URL` 需替换为实际访问域名,不过也可以后续再配置\n\n---\n\n### ▍ 高频问题排雷\n#### 🔴 镜像拉取失败\n**现象**:`Error response from daemon: pull access denied` \n✅ 解决方案: \n参考先前的 [Overleaf Toolkit 踩坑记录](https://blog.hifuu.ink/2024/11/06/overleaf/) 配置镜像加速源\n\n#### 🔴 Google 频繁拦截\n**现象**:`Too Many Requests` 错误频发 \n\n⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案\n\n✅ 实战验证方案: \n更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。\n\n📌 在配置文件设置代理: \n```yaml\noutgoing:\n proxies:\n all://:\n - http://
:\n```\n\n---\n\n### ▍ 效果展示与体验\n访问我的生产环境实例 [search.hifuu.ink](https://search.hifuu.ink) 可体验以下功能: \n- 🔍 多引擎结果聚合对比 \n- 🌍 支持 30+ 语言实时翻译 \n- 🛡️ 零 Cookie 跟踪的隐私模式 \n- 🎨 主题切换 \n\n---\n### ▍ 进阶优化建议\n1. **反向代理配置** \n\n网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。\n\n2. **定期维护命令** \n```bash\n# 更新搜索引擎引擎列表\ndocker exec -it searxng python -m searx.engines --update\n```\n\n3. **监控指标集成** \n通过 Prometheus 导出搜索统计:\n```bash\ndocker run -d --network=searxng-net \\\n -v \"${PWD}/metrics:/metrics\" \\\n prom/prometheus --config.file=/metrics/searxng.yml\n``` \n\n---\n\n**🚀 立即行动** \n\n快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。\n","slug":"searxng","published":1,"updated":"2025-03-10T15:46:55.535Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q5001ap22b3mby9fa5","content":"

\"SearXNG
厌倦了商业搜索引擎的广告追踪? 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 SearXNG 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。

\n
\n

▍ 为什么选择 SearXNG?

核心优势矩阵

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
特性实现方式用户收益
隐私保护匿名聚合第三方结果无搜索历史追踪
结果去商业化过滤 SEO 优化内容提升技术资料检索效率
多引擎支持集成 Google/Bing/Brave 等 70+ 源规避单一引擎局限
界面定制主题引擎分离设计打造个性化搜索门户
\n

⚠️ 同类工具对比:
此前使用的 luxirty-search 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。

\n

之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。

\n
\n

▍ 极简部署方案

▶ 环境准备

1
2
mkdir -p ~/services/searxng && cd $_  # 随意找个地方创建专用目录
export SEARXNG_PORT=8080 # 设置服务端口
\n\n

▶ 容器化部署

1
2
3
4
5
6
7
8
9
10
# 拉取官方镜像
docker pull searxng/searxng

# 启动容器(推荐绑定持久化配置)
docker run -d --restart=unless-stopped \\
-p ${SEARXNG_PORT}:8080 \\
-v "${PWD}/config:/etc/searxng" \\
-e "BASE_URL=http://your-domain.com" \\
-e "INSTANCE_NAME=PrivateSearch" \\
searxng/searxng
\n

📌 参数说明:

\n
    \n
  • -v 挂载配置文件实现持久化
  • \n
  • --restart 确保服务异常退出后自动重启
  • \n
  • BASE_URL 需替换为实际访问域名,不过也可以后续再配置
  • \n
\n
\n

▍ 高频问题排雷

🔴 镜像拉取失败

现象Error response from daemon: pull access denied
✅ 解决方案:
参考先前的 Overleaf Toolkit 踩坑记录 配置镜像加速源

\n

🔴 Google 频繁拦截

现象Too Many Requests 错误频发

\n

⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案

\n

✅ 实战验证方案:
更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。

\n

📌 在配置文件设置代理:

\n
1
2
3
4
outgoing:
proxies:
all://:
- http://<address>:<port>
\n\n
\n

▍ 效果展示与体验

访问我的生产环境实例 search.hifuu.ink 可体验以下功能:

\n
    \n
  • 🔍 多引擎结果聚合对比
  • \n
  • 🌍 支持 30+ 语言实时翻译
  • \n
  • 🛡️ 零 Cookie 跟踪的隐私模式
  • \n
  • 🎨 主题切换
  • \n
\n
\n

▍ 进阶优化建议

    \n
  1. 反向代理配置
  2. \n
\n

网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。

\n
    \n
  1. 定期维护命令

    \n
    1
    2
    # 更新搜索引擎引擎列表
    docker exec -it searxng python -m searx.engines --update
    \n
  2. \n
  3. 监控指标集成
    通过 Prometheus 导出搜索统计:

    \n
    1
    2
    3
    docker run -d --network=searxng-net \\
    -v "${PWD}/metrics:/metrics" \\
    prom/prometheus --config.file=/metrics/searxng.yml
  4. \n
\n
\n

🚀 立即行动

\n

快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。

\n","excerpt":"","more":"

\"SearXNG
厌倦了商业搜索引擎的广告追踪? 受够技术社区被 SEO 污染的水文?希望搜索结果里尽量不要呈现C*DN等平台的低质内容?这款开源元搜索引擎 SearXNG 现在让我直呼真香爱不释手,使用频率远超 Nextcloud 等自建服务。

\n
\n

▍ 为什么选择 SearXNG?

核心优势矩阵

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
特性实现方式用户收益
隐私保护匿名聚合第三方结果无搜索历史追踪
结果去商业化过滤 SEO 优化内容提升技术资料检索效率
多引擎支持集成 Google/Bing/Brave 等 70+ 源规避单一引擎局限
界面定制主题引擎分离设计打造个性化搜索门户
\n

⚠️ 同类工具对比:
此前使用的 luxirty-search 也很不错但是依赖 Google CSE,对于内网环境日常使用多少有点不友好。

\n

之前看了下网上普遍推荐docker方案不过部署流程与官方文档有不少出入而且在我本地没法正常运行,这里我们直接按照官方文档来,事不宜迟直接开始部署。

\n
\n

▍ 极简部署方案

▶ 环境准备

1
2
mkdir -p ~/services/searxng && cd $_  # 随意找个地方创建专用目录
export SEARXNG_PORT=8080 # 设置服务端口
\n\n

▶ 容器化部署

1
2
3
4
5
6
7
8
9
10
# 拉取官方镜像
docker pull searxng/searxng

# 启动容器(推荐绑定持久化配置)
docker run -d --restart=unless-stopped \\
-p ${SEARXNG_PORT}:8080 \\
-v "${PWD}/config:/etc/searxng" \\
-e "BASE_URL=http://your-domain.com" \\
-e "INSTANCE_NAME=PrivateSearch" \\
searxng/searxng
\n

📌 参数说明:

\n
    \n
  • -v 挂载配置文件实现持久化
  • \n
  • --restart 确保服务异常退出后自动重启
  • \n
  • BASE_URL 需替换为实际访问域名,不过也可以后续再配置
  • \n
\n
\n

▍ 高频问题排雷

🔴 镜像拉取失败

现象Error response from daemon: pull access denied
✅ 解决方案:
参考先前的 Overleaf Toolkit 踩坑记录 配置镜像加速源

\n

🔴 Google 频繁拦截

现象Too Many Requests 错误频发

\n

⚠️ 这算是一个玄学问题除了更换代理我还没有发现更好的解决方案

\n

✅ 实战验证方案:
更换你的代理服务器比如笔者目前在🇺🇸🇭🇰🇯🇵均有购买VPS服务器可作为代理,经尝试总会有可以使用的节点。

\n

📌 在配置文件设置代理:

\n
1
2
3
4
outgoing:
proxies:
all://:
- http://<address>:<port>
\n\n
\n

▍ 效果展示与体验

访问我的生产环境实例 search.hifuu.ink 可体验以下功能:

\n
    \n
  • 🔍 多引擎结果聚合对比
  • \n
  • 🌍 支持 30+ 语言实时翻译
  • \n
  • 🛡️ 零 Cookie 跟踪的隐私模式
  • \n
  • 🎨 主题切换
  • \n
\n
\n

▍ 进阶优化建议

    \n
  1. 反向代理配置
  2. \n
\n

网上相关教程应该很多这里不再重复,我的SearXNG服务器通过香港VPS反代到公网使用。

\n
    \n
  1. 定期维护命令

    \n
    1
    2
    # 更新搜索引擎引擎列表
    docker exec -it searxng python -m searx.engines --update
    \n
  2. \n
  3. 监控指标集成
    通过 Prometheus 导出搜索统计:

    \n
    1
    2
    3
    docker run -d --network=searxng-net \\
    -v "${PWD}/metrics:/metrics" \\
    prom/prometheus --config.file=/metrics/searxng.yml
  4. \n
\n
\n

🚀 立即行动

\n

快速拥有对抗 SEO 污染的利器,快来打造你的私人搜索门户吧!部署过程遇到问题欢迎联系笔者交流。

\n"},{"title":"命令行编辑器的优雅新选择","date":"2024-12-12T17:40:27.000Z","_content":"\n意外发现Zellij+Helix还挺好用的\n\n避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境\n\n稍微了解一下二者的快捷键就能舒适码字了\n\n甚至还都是rust出品\n\n即刻尝试一下[Zellij](https://zellij.dev/)和[Helix](https://helix-editor.com/)吧!\n\n// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh\n\n![实际效果](/images/zellij-helix.jpg)\n","source":"_posts/zellij-helix.md","raw":"---\ntitle: 命令行编辑器的优雅新选择\ndate: 2024-12-13 01:40:27\ntags: [技术分享]\n---\n\n意外发现Zellij+Helix还挺好用的\n\n避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境\n\n稍微了解一下二者的快捷键就能舒适码字了\n\n甚至还都是rust出品\n\n即刻尝试一下[Zellij](https://zellij.dev/)和[Helix](https://helix-editor.com/)吧!\n\n// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh\n\n![实际效果](/images/zellij-helix.jpg)\n","slug":"zellij-helix","published":1,"updated":"2025-02-23T15:53:44.966Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q70029p22bhwa5h4c5","content":"

意外发现Zellij+Helix还挺好用的

\n

避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境

\n

稍微了解一下二者的快捷键就能舒适码字了

\n

甚至还都是rust出品

\n

即刻尝试一下ZellijHelix吧!

\n

// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh

\n

\"实际效果\"

\n","excerpt":"","more":"

意外发现Zellij+Helix还挺好用的

\n

避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境

\n

稍微了解一下二者的快捷键就能舒适码字了

\n

甚至还都是rust出品

\n

即刻尝试一下ZellijHelix吧!

\n

// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh

\n

\"实际效果\"

\n"},{"title":"原来我还有个博客","date":"2024-06-02T16:19:55.000Z","_content":"\n2025-02-25\n\n最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~\n","source":"_posts/原来我还有个博客.md","raw":"---\ntitle: 原来我还有个博客\ndate: 2024-06-03 00:19:55\ntags: 日志\n---\n\n2025-02-25\n\n最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~\n","slug":"原来我还有个博客","published":1,"updated":"2025-02-25T04:26:34.224Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q7002ap22b9dhe4v4j","content":"

2025-02-25

\n

最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~

\n","excerpt":"","more":"

2025-02-25

\n

最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~

\n"},{"title":"梦开始的地方","date":"2023-12-06T14:53:35.000Z","_content":"\n不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。\n\n今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。\n\n> P.S.最近我都经历了些什么:\n>\n> 1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;\n> 2. 学习了一些C++基础,在洛谷上刷了不少算法题;\n> 3. ACM招新赛被薄纱,差一题进入校队;\n> 4. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;\n> 5. 入坑战地,爽爽爽;\n> 6. 被一位巨强的学长发掘,加入NUDT超算队;\n> 7. 面临三个考试周,熬过去就是胜利;\n\n虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。\n\n这里,毕竟是我梦开始的地方。\n\n> 胸怀祖国,团结协作,志在高峰,奋勇拼搏!\n\n今天是2023年12月6日,加油!\n\n------------------------\n\n修改一下,有的话还是不适合明说哦\n\n5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==\n\n","source":"_posts/梦开始的地方.md","raw":"---\ntitle: 梦开始的地方\ndate: 2023-12-06 22:53:35\ntags: 日志\n---\n\n不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。\n\n今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。\n\n> P.S.最近我都经历了些什么:\n>\n> 1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;\n> 2. 学习了一些C++基础,在洛谷上刷了不少算法题;\n> 3. ACM招新赛被薄纱,差一题进入校队;\n> 4. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;\n> 5. 入坑战地,爽爽爽;\n> 6. 被一位巨强的学长发掘,加入NUDT超算队;\n> 7. 面临三个考试周,熬过去就是胜利;\n\n虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。\n\n这里,毕竟是我梦开始的地方。\n\n> 胸怀祖国,团结协作,志在高峰,奋勇拼搏!\n\n今天是2023年12月6日,加油!\n\n------------------------\n\n修改一下,有的话还是不适合明说哦\n\n5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==\n\n","slug":"梦开始的地方","published":1,"updated":"2025-02-25T04:25:44.687Z","comments":1,"layout":"post","photos":[],"_id":"cmaxzv0q8002cp22baf84a55t","content":"

不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。

\n

今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。

\n
\n

P.S.最近我都经历了些什么:

\n
    \n
  1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;
  2. \n
  3. 学习了一些C++基础,在洛谷上刷了不少算法题;
  4. \n
  5. ACM招新赛被薄纱,差一题进入校队;
  6. \n
  7. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;
  8. \n
  9. 入坑战地,爽爽爽;
  10. \n
  11. 被一位巨强的学长发掘,加入NUDT超算队;
  12. \n
  13. 面临三个考试周,熬过去就是胜利;
  14. \n
\n
\n

虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。

\n

这里,毕竟是我梦开始的地方。

\n
\n

胸怀祖国,团结协作,志在高峰,奋勇拼搏!

\n
\n

今天是2023年12月6日,加油!

\n
\n

修改一下,有的话还是不适合明说哦

\n

5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==

\n","excerpt":"","more":"

不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。

\n

今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。

\n
\n

P.S.最近我都经历了些什么:

\n
    \n
  1. 时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;
  2. \n
  3. 学习了一些C++基础,在洛谷上刷了不少算法题;
  4. \n
  5. ACM招新赛被薄纱,差一题进入校队;
  6. \n
  7. 对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;
  8. \n
  9. 入坑战地,爽爽爽;
  10. \n
  11. 被一位巨强的学长发掘,加入NUDT超算队;
  12. \n
  13. 面临三个考试周,熬过去就是胜利;
  14. \n
\n
\n

虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。

\n

这里,毕竟是我梦开始的地方。

\n
\n

胸怀祖国,团结协作,志在高峰,奋勇拼搏!

\n
\n

今天是2023年12月6日,加油!

\n
\n

修改一下,有的话还是不适合明说哦

\n

5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==

\n"},{"title":"Random Fortune","date":"2025-05-22T07:29:07.000Z","_content":"\nKeep peace of mind with fortune...\n\n❯ fortune\n\nThe nice thing about standards is that there are so many of them to choose\nfrom.\n -- Andrew S. Tanenbaum\n\n❯ fortune\n\n看蓬门秋草,年年破巷,疏窗细雨,夜夜孤灯。\n -- 郑板桥《沁园春·恨》\n\n❯ fortune\n\nAn alcoholic is someone you don't like who drinks as much as you do.\n -- Dylan Thomas\n\n❯ fortune\n\nIf you put tomfoolery into a computer, nothing comes out but tomfoolery.\nBut this tomfoolery, having passed through a very expensive machine,\nis somehow ennobled and no-one dare criticise it.\n -- Pierre Gallois\n\n❯ fortune\n\n秋色渐将晚,霜信报黄花。\n -- 叶梦得《水调歌头·秋色渐将晚》\n\n❯ fortune\n\n水精帘里颇黎枕,暖香惹梦鸳鸯锦。江上柳如烟,雁飞残月天。\n藕丝秋色浅,人胜参差剪。双鬓隔香红,玉钗头上风。\n -- 温庭筠《菩萨蛮》\n\n❯ fortune\n\n A disciple of another sect once came to Drescher as he was eating\nhis morning meal. \"I would like to give you this personality test\", said\nthe outsider, \"because I want you to be happy.\"\n Drescher took the paper that was offered him and put it into the\ntoaster -- \"I wish the toaster to be happy too\".\n\n❯ fortune\n\nExample is not the main thing in influencing others. It is the only thing.\n -- Albert Schweitzer\n\n❯ fortune\n\nWe have art that we do not die of the truth.\n -- Nietzsche\n\n❯ fortune\n\n \"Java for the COBOL Programmer\"\n who writes these things?\n people on crack\n and cobol programmers\n :)\n that's redundant.\n\n❯ fortune\n\nI was in this prematurely air conditioned supermarket and there were all\nthese aisles and there were these bathing caps you could buy that had these\nkind of Fourth of July plumes on them that were red and yellow and blue and\nI wasn't tempted to buy one but I was reminded of the fact that I had been\navoiding the beach.\n -- Lucinda Childs \"Einstein On The Beach\"\n\n❯ fortune\n\nIt doesn't matter whether you win or lose -- until you lose.\n\n❯ fortune\n\nTrue leadership is the art of changing a group from what it is to what\nit ought to be.\n -- Virginia Allan\n\n❯ fortune\n\nI keep hearing and reading this nice proverb *if it ain't broke, don't fix\nit*. The latest appearance was in response to [Shlomi\nFish](http://community.livejournal.com/shlomif_tech/37969.html) suggesting\nthat some Ancient Perl code should be replaced by Modern Perl code.\n\nI am not saying that every piece of code should be rewritten every 6 months,\nbut in my understanding that sentence actually translates to *let's wait till\nit breaks and then panic*.\n\nI think people who say that sentence are afraid that the new version will\nbreak something. Sure, there is always a chance that a change introduces an\nerror, but, if we are afraid to touch the code, what will happen when later on\nwe encounter a case where it does not work? For example, if we need to use it\nin a new environment. Will we have the courage to change the code then? How\nmuch will it cost in money, time, and lost sleep?\n\nI think we have been trying to teach ourselves that we should have really good\ntest coverage of our code and then we can easily refactor it and get rid of\ntechnical debt. So why do we keep hearing that sentence?\n\n -- Gabor Szabo\n -- What does \"If it ain't broke, don't fix it.\" really mean? ( )\n\n❯ fortune\n\nPsychoanalysis is that mental illness for which it regards itself a therapy.\n -- Karl Kraus\n\n❯ fortune\n\nWith a rubber duck, one's never alone.\n -- \"The Hitchhiker's Guide to the Galaxy\"\n\n❯ fortune\n\n(Presuming for the sake of argument that it's even *possible* to design\nbetter code in Perl than in C. :-)\n -- Larry Wall on core code vs. module code design\n\n❯ fortune\n\nBut, officer, he's not drunk, I just saw his fingers twitch!\n\n❯ fortune\n\nImbalance of power corrupts and monopoly of power corrupts absolutely.\n -- Genji\n\n❯ fortune\n\nI want a VEGETARIAN BURRITO to go ... with EXTRA MSG!!\n\n❯ fortune\n\n如果你不知道如何表现地高人一等,找个Unix用户,让他做给你看。\n -- Dilbert newsletter 3.0, 1994\n\n❯ fortune\n\n\"The picture's pretty bleak, gentlemen... The world's climates are changing,\nthe mammals are taking over, and we all have a brain about the size of a\nwalnut.\"\n -- some dinosaurs from The Far Side, by Gary Larson\n\n❯ fortune\n\nMost of us feel that marketing types are like a dangerous weapon - keep\n'em unloaded and locked up in a cupboard, and only bring them out when\nyou need them to do a job.\n -- Craig Sanders\n\n❯ fortune\n\n不寐倦长更,披衣出户行。月寒秋竹冷,风切夜窗声。\n -- 李煜《三台令》\n\n❯ fortune\n\n子曰:“由,诲女知之乎!知之为知之,不知为不知,是知也。”\n-- 论语,为政篇\n\n❯ fortune\n\n \"The jig's up, Elman.\"\n \"Which jig?\"\n -- Jeff Elman\n\n❯ fortune\n\n\"First things first -- but not necessarily in that order\"\n -- The Doctor, \"Doctor Who\"\n\n❯ fortune\n\n波影摇涟,趁熏风,一舸来时,翠阴清昼。去郭轩楹才数里,藓磴松关云岫。\n快屐齿,筇枝先后。空半危亭堪聚远,看洞庭,缥缈争奇秀。人自老,景如旧。\n来帆去棹还知否,问古今,几度斜阳,几番回首?晓色一川谁管领,都付雨荷烟柳,\n知我者,燕朋鸥友。笑拍阑干呼范蠡,甚平吴,却倩垂纶手?吁万古,付卮酒。\n -- 周密《长亭怨慢》\n\n❯ fortune\n\nI'm telling you that the kernel is stable not because it's a kernel,\nbut because I refuse to listen to arguments like this.\n -- Linus Torvalds\n\n❯ fortune\n\nA girl's conscience doesn't really keep her from doing anything wrong--\nit merely keeps her from enjoying it.\n\n❯ fortune\n\nThere are few people more often in the wrong than those who cannot endure\nto be thought so.\n\n❯ fortune\n\nOne does not thank logic.\n -- Sarek, \"Journey to Babel\", stardate 3842.4\n\n❯ fortune\n\nFree yourself from negative influence. Negative thoughts are the old\nhabits that gnaw at the roots of the soul.\nMoses Shongo, (Seneca)\n\n❯ fortune\n\n日月照之何不及此?惟有北风号怒天上来。\n -- 李白《北风行》\n\n❯ fortune\n\nAnyone who is capable of getting themselves made President should on no\naccount be allowed to do the job.\n -- Douglas Adams, \"The Hitchhiker's Guide to the Galaxy\"\n\nAnd here are my mods:-)\n\n❯ pacman -Qs fortune\nlocal/cowfortune 0.1.2-8\n Configurable fortune cookie proclaiming cow (and a few other creatures)\nlocal/fortune-mod 3.22.0-1.1\n The Fortune Cookie Program from BSD games\nlocal/fortune-mod-zh 2.98-1 (fortune-mods)\n Chinese poems for fortune-mod\n","source":"_posts/fortune.md","raw":"---\ntitle: Random fortune \ndate: 2025-05-22 15:29:07\ntags: 日志\n---\n\nKeep peace of mind with fortune...\n\n❯ fortune\n\nThe nice thing about standards is that there are so many of them to choose\nfrom.\n -- Andrew S. Tanenbaum\n\n❯ fortune\n\n看蓬门秋草,年年破巷,疏窗细雨,夜夜孤灯。\n -- 郑板桥《沁园春·恨》\n\n❯ fortune\n\nAn alcoholic is someone you don't like who drinks as much as you do.\n -- Dylan Thomas\n\n❯ fortune\n\nIf you put tomfoolery into a computer, nothing comes out but tomfoolery.\nBut this tomfoolery, having passed through a very expensive machine,\nis somehow ennobled and no-one dare criticise it.\n -- Pierre Gallois\n\n❯ fortune\n\n秋色渐将晚,霜信报黄花。\n -- 叶梦得《水调歌头·秋色渐将晚》\n\n❯ fortune\n\n水精帘里颇黎枕,暖香惹梦鸳鸯锦。江上柳如烟,雁飞残月天。\n藕丝秋色浅,人胜参差剪。双鬓隔香红,玉钗头上风。\n -- 温庭筠《菩萨蛮》\n\n❯ fortune\n\n A disciple of another sect once came to Drescher as he was eating\nhis morning meal. \"I would like to give you this personality test\", said\nthe outsider, \"because I want you to be happy.\"\n Drescher took the paper that was offered him and put it into the\ntoaster -- \"I wish the toaster to be happy too\".\n\n❯ fortune\n\nExample is not the main thing in influencing others. It is the only thing.\n -- Albert Schweitzer\n\n❯ fortune\n\nWe have art that we do not die of the truth.\n -- Nietzsche\n\n❯ fortune\n\n \"Java for the COBOL Programmer\"\n who writes these things?\n people on crack\n and cobol programmers\n :)\n that's redundant.\n\n❯ fortune\n\nI was in this prematurely air conditioned supermarket and there were all\nthese aisles and there were these bathing caps you could buy that had these\nkind of Fourth of July plumes on them that were red and yellow and blue and\nI wasn't tempted to buy one but I was reminded of the fact that I had been\navoiding the beach.\n -- Lucinda Childs \"Einstein On The Beach\"\n\n❯ fortune\n\nIt doesn't matter whether you win or lose -- until you lose.\n\n❯ fortune\n\nTrue leadership is the art of changing a group from what it is to what\nit ought to be.\n -- Virginia Allan\n\n❯ fortune\n\nI keep hearing and reading this nice proverb *if it ain't broke, don't fix\nit*. The latest appearance was in response to [Shlomi\nFish](http://community.livejournal.com/shlomif_tech/37969.html) suggesting\nthat some Ancient Perl code should be replaced by Modern Perl code.\n\nI am not saying that every piece of code should be rewritten every 6 months,\nbut in my understanding that sentence actually translates to *let's wait till\nit breaks and then panic*.\n\nI think people who say that sentence are afraid that the new version will\nbreak something. Sure, there is always a chance that a change introduces an\nerror, but, if we are afraid to touch the code, what will happen when later on\nwe encounter a case where it does not work? For example, if we need to use it\nin a new environment. Will we have the courage to change the code then? How\nmuch will it cost in money, time, and lost sleep?\n\nI think we have been trying to teach ourselves that we should have really good\ntest coverage of our code and then we can easily refactor it and get rid of\ntechnical debt. So why do we keep hearing that sentence?\n\n -- Gabor Szabo\n -- What does \"If it ain't broke, don't fix it.\" really mean? ( )\n\n❯ fortune\n\nPsychoanalysis is that mental illness for which it regards itself a therapy.\n -- Karl Kraus\n\n❯ fortune\n\nWith a rubber duck, one's never alone.\n -- \"The Hitchhiker's Guide to the Galaxy\"\n\n❯ fortune\n\n(Presuming for the sake of argument that it's even *possible* to design\nbetter code in Perl than in C. :-)\n -- Larry Wall on core code vs. module code design\n\n❯ fortune\n\nBut, officer, he's not drunk, I just saw his fingers twitch!\n\n❯ fortune\n\nImbalance of power corrupts and monopoly of power corrupts absolutely.\n -- Genji\n\n❯ fortune\n\nI want a VEGETARIAN BURRITO to go ... with EXTRA MSG!!\n\n❯ fortune\n\n如果你不知道如何表现地高人一等,找个Unix用户,让他做给你看。\n -- Dilbert newsletter 3.0, 1994\n\n❯ fortune\n\n\"The picture's pretty bleak, gentlemen... The world's climates are changing,\nthe mammals are taking over, and we all have a brain about the size of a\nwalnut.\"\n -- some dinosaurs from The Far Side, by Gary Larson\n\n❯ fortune\n\nMost of us feel that marketing types are like a dangerous weapon - keep\n'em unloaded and locked up in a cupboard, and only bring them out when\nyou need them to do a job.\n -- Craig Sanders\n\n❯ fortune\n\n不寐倦长更,披衣出户行。月寒秋竹冷,风切夜窗声。\n -- 李煜《三台令》\n\n❯ fortune\n\n子曰:“由,诲女知之乎!知之为知之,不知为不知,是知也。”\n-- 论语,为政篇\n\n❯ fortune\n\n \"The jig's up, Elman.\"\n \"Which jig?\"\n -- Jeff Elman\n\n❯ fortune\n\n\"First things first -- but not necessarily in that order\"\n -- The Doctor, \"Doctor Who\"\n\n❯ fortune\n\n波影摇涟,趁熏风,一舸来时,翠阴清昼。去郭轩楹才数里,藓磴松关云岫。\n快屐齿,筇枝先后。空半危亭堪聚远,看洞庭,缥缈争奇秀。人自老,景如旧。\n来帆去棹还知否,问古今,几度斜阳,几番回首?晓色一川谁管领,都付雨荷烟柳,\n知我者,燕朋鸥友。笑拍阑干呼范蠡,甚平吴,却倩垂纶手?吁万古,付卮酒。\n -- 周密《长亭怨慢》\n\n❯ fortune\n\nI'm telling you that the kernel is stable not because it's a kernel,\nbut because I refuse to listen to arguments like this.\n -- Linus Torvalds\n\n❯ fortune\n\nA girl's conscience doesn't really keep her from doing anything wrong--\nit merely keeps her from enjoying it.\n\n❯ fortune\n\nThere are few people more often in the wrong than those who cannot endure\nto be thought so.\n\n❯ fortune\n\nOne does not thank logic.\n -- Sarek, \"Journey to Babel\", stardate 3842.4\n\n❯ fortune\n\nFree yourself from negative influence. Negative thoughts are the old\nhabits that gnaw at the roots of the soul.\nMoses Shongo, (Seneca)\n\n❯ fortune\n\n日月照之何不及此?惟有北风号怒天上来。\n -- 李白《北风行》\n\n❯ fortune\n\nAnyone who is capable of getting themselves made President should on no\naccount be allowed to do the job.\n -- Douglas Adams, \"The Hitchhiker's Guide to the Galaxy\"\n\nAnd here are my mods:-)\n\n❯ pacman -Qs fortune\nlocal/cowfortune 0.1.2-8\n Configurable fortune cookie proclaiming cow (and a few other creatures)\nlocal/fortune-mod 3.22.0-1.1\n The Fortune Cookie Program from BSD games\nlocal/fortune-mod-zh 2.98-1 (fortune-mods)\n Chinese poems for fortune-mod\n","slug":"fortune","published":1,"updated":"2025-05-22T07:41:08.523Z","comments":1,"layout":"post","photos":[],"_id":"cmaz2c2xm0000tz2b34byazwp","content":"

Keep peace of mind with fortune…

\n

❯ fortune

\n

The nice thing about standards is that there are so many of them to choose
from.
– Andrew S. Tanenbaum

\n

❯ fortune

\n

看蓬门秋草,年年破巷,疏窗细雨,夜夜孤灯。
– 郑板桥《沁园春·恨》

\n

❯ fortune

\n

An alcoholic is someone you don’t like who drinks as much as you do.
– Dylan Thomas

\n

❯ fortune

\n

If you put tomfoolery into a computer, nothing comes out but tomfoolery.
But this tomfoolery, having passed through a very expensive machine,
is somehow ennobled and no-one dare criticise it.
– Pierre Gallois

\n

❯ fortune

\n

秋色渐将晚,霜信报黄花。
– 叶梦得《水调歌头·秋色渐将晚》

\n

❯ fortune

\n

水精帘里颇黎枕,暖香惹梦鸳鸯锦。江上柳如烟,雁飞残月天。
藕丝秋色浅,人胜参差剪。双鬓隔香红,玉钗头上风。
– 温庭筠《菩萨蛮》

\n

❯ fortune

\n
    A disciple of another sect once came to Drescher as he was eating\n
\n

his morning meal. “I would like to give you this personality test”, said
the outsider, “because I want you to be happy.”
Drescher took the paper that was offered him and put it into the
toaster – “I wish the toaster to be happy too”.

\n

❯ fortune

\n

Example is not the main thing in influencing others. It is the only thing.
– Albert Schweitzer

\n

❯ fortune

\n

We have art that we do not die of the truth.
– Nietzsche

\n

❯ fortune

\n

“Java for the COBOL Programmer”
who writes these things?
people on crack
and cobol programmers
:)
that’s redundant.

\n

❯ fortune

\n

I was in this prematurely air conditioned supermarket and there were all
these aisles and there were these bathing caps you could buy that had these
kind of Fourth of July plumes on them that were red and yellow and blue and
I wasn’t tempted to buy one but I was reminded of the fact that I had been
avoiding the beach.
– Lucinda Childs “Einstein On The Beach”

\n

❯ fortune

\n

It doesn’t matter whether you win or lose – until you lose.

\n

❯ fortune

\n

True leadership is the art of changing a group from what it is to what
it ought to be.
– Virginia Allan

\n

❯ fortune

\n

I keep hearing and reading this nice proverb if it ain’t broke, don’t fix
it
. The latest appearance was in response to Shlomi
Fish
suggesting
that some Ancient Perl code should be replaced by Modern Perl code.

\n

I am not saying that every piece of code should be rewritten every 6 months,
but in my understanding that sentence actually translates to let’s wait till
it breaks and then panic
.

\n

I think people who say that sentence are afraid that the new version will
break something. Sure, there is always a chance that a change introduces an
error, but, if we are afraid to touch the code, what will happen when later on
we encounter a case where it does not work? For example, if we need to use it
in a new environment. Will we have the courage to change the code then? How
much will it cost in money, time, and lost sleep?

\n

I think we have been trying to teach ourselves that we should have really good
test coverage of our code and then we can easily refactor it and get rid of
technical debt. So why do we keep hearing that sentence?

\n
-- Gabor Szabo\n-- What does "If it ain't broke, don't fix it." really mean? (  )\n
\n

❯ fortune

\n

Psychoanalysis is that mental illness for which it regards itself a therapy.
– Karl Kraus

\n

❯ fortune

\n

With a rubber duck, one’s never alone.
– “The Hitchhiker’s Guide to the Galaxy”

\n

❯ fortune

\n

(Presuming for the sake of argument that it’s even possible to design
better code in Perl than in C. :-)
– Larry Wall on core code vs. module code design

\n

❯ fortune

\n

But, officer, he’s not drunk, I just saw his fingers twitch!

\n

❯ fortune

\n

Imbalance of power corrupts and monopoly of power corrupts absolutely.
– Genji

\n

❯ fortune

\n

I want a VEGETARIAN BURRITO to go … with EXTRA MSG!!

\n

❯ fortune

\n

如果你不知道如何表现地高人一等,找个Unix用户,让他做给你看。
– Dilbert newsletter 3.0, 1994

\n

❯ fortune

\n

“The picture’s pretty bleak, gentlemen… The world’s climates are changing,
the mammals are taking over, and we all have a brain about the size of a
walnut.”
– some dinosaurs from The Far Side, by Gary Larson

\n

❯ fortune

\n

Most of us feel that marketing types are like a dangerous weapon - keep
‘em unloaded and locked up in a cupboard, and only bring them out when
you need them to do a job.
– Craig Sanders

\n

❯ fortune

\n

不寐倦长更,披衣出户行。月寒秋竹冷,风切夜窗声。
– 李煜《三台令》

\n

❯ fortune

\n

子曰:“由,诲女知之乎!知之为知之,不知为不知,是知也。”
– 论语,为政篇

\n

❯ fortune

\n
    "The jig's up, Elman."\n    "Which jig?"\n            -- Jeff Elman\n
\n

❯ fortune

\n

“First things first – but not necessarily in that order”
– The Doctor, “Doctor Who”

\n

❯ fortune

\n

波影摇涟,趁熏风,一舸来时,翠阴清昼。去郭轩楹才数里,藓磴松关云岫。
快屐齿,筇枝先后。空半危亭堪聚远,看洞庭,缥缈争奇秀。人自老,景如旧。
来帆去棹还知否,问古今,几度斜阳,几番回首?晓色一川谁管领,都付雨荷烟柳,
知我者,燕朋鸥友。笑拍阑干呼范蠡,甚平吴,却倩垂纶手?吁万古,付卮酒。
– 周密《长亭怨慢》

\n

❯ fortune

\n

I’m telling you that the kernel is stable not because it’s a kernel,
but because I refuse to listen to arguments like this.
– Linus Torvalds

\n

❯ fortune

\n

A girl’s conscience doesn’t really keep her from doing anything wrong–
it merely keeps her from enjoying it.

\n

❯ fortune

\n

There are few people more often in the wrong than those who cannot endure
to be thought so.

\n

❯ fortune

\n

One does not thank logic.
– Sarek, “Journey to Babel”, stardate 3842.4

\n

❯ fortune

\n

Free yourself from negative influence. Negative thoughts are the old
habits that gnaw at the roots of the soul.
Moses Shongo, (Seneca)

\n

❯ fortune

\n

日月照之何不及此?惟有北风号怒天上来。
– 李白《北风行》

\n

❯ fortune

\n

Anyone who is capable of getting themselves made President should on no
account be allowed to do the job.
– Douglas Adams, “The Hitchhiker’s Guide to the Galaxy”

\n

And here are my mods:-)

\n

❯ pacman -Qs fortune
local/cowfortune 0.1.2-8
Configurable fortune cookie proclaiming cow (and a few other creatures)
local/fortune-mod 3.22.0-1.1
The Fortune Cookie Program from BSD games
local/fortune-mod-zh 2.98-1 (fortune-mods)
Chinese poems for fortune-mod

\n","excerpt":"","more":"

Keep peace of mind with fortune…

\n

❯ fortune

\n

The nice thing about standards is that there are so many of them to choose
from.
– Andrew S. Tanenbaum

\n

❯ fortune

\n

看蓬门秋草,年年破巷,疏窗细雨,夜夜孤灯。
– 郑板桥《沁园春·恨》

\n

❯ fortune

\n

An alcoholic is someone you don’t like who drinks as much as you do.
– Dylan Thomas

\n

❯ fortune

\n

If you put tomfoolery into a computer, nothing comes out but tomfoolery.
But this tomfoolery, having passed through a very expensive machine,
is somehow ennobled and no-one dare criticise it.
– Pierre Gallois

\n

❯ fortune

\n

秋色渐将晚,霜信报黄花。
– 叶梦得《水调歌头·秋色渐将晚》

\n

❯ fortune

\n

水精帘里颇黎枕,暖香惹梦鸳鸯锦。江上柳如烟,雁飞残月天。
藕丝秋色浅,人胜参差剪。双鬓隔香红,玉钗头上风。
– 温庭筠《菩萨蛮》

\n

❯ fortune

\n
    A disciple of another sect once came to Drescher as he was eating\n
\n

his morning meal. “I would like to give you this personality test”, said
the outsider, “because I want you to be happy.”
Drescher took the paper that was offered him and put it into the
toaster – “I wish the toaster to be happy too”.

\n

❯ fortune

\n

Example is not the main thing in influencing others. It is the only thing.
– Albert Schweitzer

\n

❯ fortune

\n

We have art that we do not die of the truth.
– Nietzsche

\n

❯ fortune

\n

“Java for the COBOL Programmer”
who writes these things?
people on crack
and cobol programmers
:)
that’s redundant.

\n

❯ fortune

\n

I was in this prematurely air conditioned supermarket and there were all
these aisles and there were these bathing caps you could buy that had these
kind of Fourth of July plumes on them that were red and yellow and blue and
I wasn’t tempted to buy one but I was reminded of the fact that I had been
avoiding the beach.
– Lucinda Childs “Einstein On The Beach”

\n

❯ fortune

\n

It doesn’t matter whether you win or lose – until you lose.

\n

❯ fortune

\n

True leadership is the art of changing a group from what it is to what
it ought to be.
– Virginia Allan

\n

❯ fortune

\n

I keep hearing and reading this nice proverb if it ain’t broke, don’t fix
it
. The latest appearance was in response to Shlomi
Fish
suggesting
that some Ancient Perl code should be replaced by Modern Perl code.

\n

I am not saying that every piece of code should be rewritten every 6 months,
but in my understanding that sentence actually translates to let’s wait till
it breaks and then panic
.

\n

I think people who say that sentence are afraid that the new version will
break something. Sure, there is always a chance that a change introduces an
error, but, if we are afraid to touch the code, what will happen when later on
we encounter a case where it does not work? For example, if we need to use it
in a new environment. Will we have the courage to change the code then? How
much will it cost in money, time, and lost sleep?

\n

I think we have been trying to teach ourselves that we should have really good
test coverage of our code and then we can easily refactor it and get rid of
technical debt. So why do we keep hearing that sentence?

\n
-- Gabor Szabo\n-- What does "If it ain't broke, don't fix it." really mean? (  )\n
\n

❯ fortune

\n

Psychoanalysis is that mental illness for which it regards itself a therapy.
– Karl Kraus

\n

❯ fortune

\n

With a rubber duck, one’s never alone.
– “The Hitchhiker’s Guide to the Galaxy”

\n

❯ fortune

\n

(Presuming for the sake of argument that it’s even possible to design
better code in Perl than in C. :-)
– Larry Wall on core code vs. module code design

\n

❯ fortune

\n

But, officer, he’s not drunk, I just saw his fingers twitch!

\n

❯ fortune

\n

Imbalance of power corrupts and monopoly of power corrupts absolutely.
– Genji

\n

❯ fortune

\n

I want a VEGETARIAN BURRITO to go … with EXTRA MSG!!

\n

❯ fortune

\n

如果你不知道如何表现地高人一等,找个Unix用户,让他做给你看。
– Dilbert newsletter 3.0, 1994

\n

❯ fortune

\n

“The picture’s pretty bleak, gentlemen… The world’s climates are changing,
the mammals are taking over, and we all have a brain about the size of a
walnut.”
– some dinosaurs from The Far Side, by Gary Larson

\n

❯ fortune

\n

Most of us feel that marketing types are like a dangerous weapon - keep
‘em unloaded and locked up in a cupboard, and only bring them out when
you need them to do a job.
– Craig Sanders

\n

❯ fortune

\n

不寐倦长更,披衣出户行。月寒秋竹冷,风切夜窗声。
– 李煜《三台令》

\n

❯ fortune

\n

子曰:“由,诲女知之乎!知之为知之,不知为不知,是知也。”
– 论语,为政篇

\n

❯ fortune

\n
    "The jig's up, Elman."\n    "Which jig?"\n            -- Jeff Elman\n
\n

❯ fortune

\n

“First things first – but not necessarily in that order”
– The Doctor, “Doctor Who”

\n

❯ fortune

\n

波影摇涟,趁熏风,一舸来时,翠阴清昼。去郭轩楹才数里,藓磴松关云岫。
快屐齿,筇枝先后。空半危亭堪聚远,看洞庭,缥缈争奇秀。人自老,景如旧。
来帆去棹还知否,问古今,几度斜阳,几番回首?晓色一川谁管领,都付雨荷烟柳,
知我者,燕朋鸥友。笑拍阑干呼范蠡,甚平吴,却倩垂纶手?吁万古,付卮酒。
– 周密《长亭怨慢》

\n

❯ fortune

\n

I’m telling you that the kernel is stable not because it’s a kernel,
but because I refuse to listen to arguments like this.
– Linus Torvalds

\n

❯ fortune

\n

A girl’s conscience doesn’t really keep her from doing anything wrong–
it merely keeps her from enjoying it.

\n

❯ fortune

\n

There are few people more often in the wrong than those who cannot endure
to be thought so.

\n

❯ fortune

\n

One does not thank logic.
– Sarek, “Journey to Babel”, stardate 3842.4

\n

❯ fortune

\n

Free yourself from negative influence. Negative thoughts are the old
habits that gnaw at the roots of the soul.
Moses Shongo, (Seneca)

\n

❯ fortune

\n

日月照之何不及此?惟有北风号怒天上来。
– 李白《北风行》

\n

❯ fortune

\n

Anyone who is capable of getting themselves made President should on no
account be allowed to do the job.
– Douglas Adams, “The Hitchhiker’s Guide to the Galaxy”

\n

And here are my mods:-)

\n

❯ pacman -Qs fortune
local/cowfortune 0.1.2-8
Configurable fortune cookie proclaiming cow (and a few other creatures)
local/fortune-mod 3.22.0-1.1
The Fortune Cookie Program from BSD games
local/fortune-mod-zh 2.98-1 (fortune-mods)
Chinese poems for fortune-mod

\n"}],"PostAsset":[],"PostCategory":[{"post_id":"cmaxzv0q0000ep22b165ba4w7","category_id":"cmaxzv0q1000hp22bhluuaucj","_id":"cmaxzv0q3000vp22b6vqk5sdr"},{"post_id":"cmaxzv0q1000jp22ba8qr4jxp","category_id":"cmaxzv0q2000pp22betjg2hmk","_id":"cmaxzv0q40011p22bgdb7967n"},{"post_id":"cmaxzv0q1000mp22b0a2hee98","category_id":"cmaxzv0q3000wp22be1q73d2r","_id":"cmaxzv0q40016p22b0fe5ah8t"},{"post_id":"cmaxzv0q40013p22bb8qjfb28","category_id":"cmaxzv0q2000pp22betjg2hmk","_id":"cmaxzv0q5001bp22b12t5f15v"},{"post_id":"cmaxzv0q2000op22b0gq70sf7","category_id":"cmaxzv0q40012p22b1fahbd6c","_id":"cmaxzv0q5001dp22bb2pd6ml5"},{"post_id":"cmaxzv0q40018p22b4lpt3rxw","category_id":"cmaxzv0q40012p22b1fahbd6c","_id":"cmaxzv0q5001gp22b55f8hbyf"}],"PostTag":[{"post_id":"cmaxzv0py0005p22bc6um14kc","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0pz0008p22b8jqq0j4x"},{"post_id":"cmaxzv0pv0001p22bbzg168j1","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0pz000ap22bdukigsbu"},{"post_id":"cmaxzv0py0006p22bg7b6evz0","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q0000dp22b47688tpa"},{"post_id":"cmaxzv0pz0009p22bgrxx8ce1","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q0000fp22b9i38gth6"},{"post_id":"cmaxzv0pw0002p22bg7e11agp","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q1000ip22bd89ybpin"},{"post_id":"cmaxzv0pz000bp22bbjfv42c1","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q1000lp22bdifb1kgd"},{"post_id":"cmaxzv0q0000ep22b165ba4w7","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q2000np22bgtoscrd6"},{"post_id":"cmaxzv0py0004p22ba4hiaw5j","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q2000qp22bemqw5n5b"},{"post_id":"cmaxzv0q0000gp22b315z7q3g","tag_id":"cmaxzv0q1000kp22b6huz9koz","_id":"cmaxzv0q3000tp22b9sgzbyfk"},{"post_id":"cmaxzv0q1000jp22ba8qr4jxp","tag_id":"cmaxzv0q2000sp22b1lzy4dl2","_id":"cmaxzv0q40010p22b42cc5u0u"},{"post_id":"cmaxzv0q40013p22bb8qjfb28","tag_id":"cmaxzv0q2000sp22b1lzy4dl2","_id":"cmaxzv0q40017p22b3xy5d0b9"},{"post_id":"cmaxzv0q1000mp22b0a2hee98","tag_id":"cmaxzv0q3000yp22b16lt9lz6","_id":"cmaxzv0q5001cp22bc78e5h7h"},{"post_id":"cmaxzv0q1000mp22b0a2hee98","tag_id":"cmaxzv0q2000sp22b1lzy4dl2","_id":"cmaxzv0q5001ep22bgule0k3j"},{"post_id":"cmaxzv0q2000op22b0gq70sf7","tag_id":"cmaxzv0q50019p22b6h9rb8cl","_id":"cmaxzv0q5001hp22bh5tc0998"},{"post_id":"cmaxzv0q2000rp22bgtkodqs6","tag_id":"cmaxzv0q5001fp22bfap9gc3g","_id":"cmaxzv0q6001kp22b2hjmbm4z"},{"post_id":"cmaxzv0q2000rp22bgtkodqs6","tag_id":"cmaxzv0q5001ip22b4gp0ai2e","_id":"cmaxzv0q6001lp22b6klu8s2j"},{"post_id":"cmaxzv0q3000up22bhurb7l9n","tag_id":"cmaxzv0q5001ip22b4gp0ai2e","_id":"cmaxzv0q6001pp22b5k4d7rzh"},{"post_id":"cmaxzv0q3000up22bhurb7l9n","tag_id":"cmaxzv0q6001mp22b9g48cdxa","_id":"cmaxzv0q6001qp22b48phb1fu"},{"post_id":"cmaxzv0q3000up22bhurb7l9n","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q6001sp22bgiyka8kk"},{"post_id":"cmaxzv0q3000xp22bd6qo3kl3","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q6001tp22b61vn2ps4"},{"post_id":"cmaxzv0q3000zp22b76yib05t","tag_id":"cmaxzv0q6001rp22b3fjc5gam","_id":"cmaxzv0q6001wp22b6vel6bdp"},{"post_id":"cmaxzv0q3000zp22b76yib05t","tag_id":"cmaxzv0q5001fp22bfap9gc3g","_id":"cmaxzv0q6001xp22bgxfwgdcn"},{"post_id":"cmaxzv0q40015p22bbk3g76eg","tag_id":"cmaxzv0q50019p22b6h9rb8cl","_id":"cmaxzv0q60021p22b6uda07c1"},{"post_id":"cmaxzv0q40015p22bbk3g76eg","tag_id":"cmaxzv0q6001yp22b139b5r6n","_id":"cmaxzv0q60022p22bg3vv5afb"},{"post_id":"cmaxzv0q40015p22bbk3g76eg","tag_id":"cmaxzv0q5001fp22bfap9gc3g","_id":"cmaxzv0q60024p22b093qbkg5"},{"post_id":"cmaxzv0q40018p22b4lpt3rxw","tag_id":"cmaxzv0q50019p22b6h9rb8cl","_id":"cmaxzv0q60025p22bg5h2851h"},{"post_id":"cmaxzv0q5001ap22b3mby9fa5","tag_id":"cmaxzv0q60023p22b80c8cqwr","_id":"cmaxzv0q70027p22b4ryv8241"},{"post_id":"cmaxzv0q5001ap22b3mby9fa5","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q70028p22bd9iacahc"},{"post_id":"cmaxzv0q70029p22bhwa5h4c5","tag_id":"cmaxzv0q6001np22bd8d9goty","_id":"cmaxzv0q8002bp22b7kvc8xf1"},{"post_id":"cmaxzv0q7002ap22b9dhe4v4j","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q8002dp22b4ii58lph"},{"post_id":"cmaxzv0q8002cp22baf84a55t","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaxzv0q8002ep22b2um12srn"},{"post_id":"cmaz2c2xm0000tz2b34byazwp","tag_id":"cmaxzv0px0003p22b4o7wd9zu","_id":"cmaz2c2xo0001tz2b67je2hrj"}],"Tag":[{"name":"日志","_id":"cmaxzv0px0003p22b4o7wd9zu"},{"name":"TEST","_id":"cmaxzv0q1000kp22b6huz9koz"},{"name":"音乐","_id":"cmaxzv0q2000sp22b1lzy4dl2"},{"name":"Vocaloid","_id":"cmaxzv0q3000yp22b16lt9lz6"},{"name":"技术","_id":"cmaxzv0q50019p22b6h9rb8cl"},{"name":"生活","_id":"cmaxzv0q5001fp22bfap9gc3g"},{"name":"Archlinux","_id":"cmaxzv0q5001ip22b4gp0ai2e"},{"name":"系统优化","_id":"cmaxzv0q6001mp22b9g48cdxa"},{"name":"技术分享","_id":"cmaxzv0q6001np22bd8d9goty"},{"name":"板绘","_id":"cmaxzv0q6001rp22b3fjc5gam"},{"name":"学习","_id":"cmaxzv0q6001yp22b139b5r6n"},{"name":"开源工具","_id":"cmaxzv0q60023p22b80c8cqwr"}]}} \ No newline at end of file diff --git a/source/_posts/fortune.md b/source/_posts/fortune.md new file mode 100644 index 0000000..68989d5 --- /dev/null +++ b/source/_posts/fortune.md @@ -0,0 +1,237 @@ +--- +title: Random fortune +date: 2025-05-22 15:29:07 +tags: 日志 +--- + +Keep peace of mind with fortune... + +❯ fortune + +The nice thing about standards is that there are so many of them to choose +from. + -- Andrew S. Tanenbaum + +❯ fortune + +看蓬门秋草,年年破巷,疏窗细雨,夜夜孤灯。 + -- 郑板桥《沁园春·恨》 + +❯ fortune + +An alcoholic is someone you don't like who drinks as much as you do. + -- Dylan Thomas + +❯ fortune + +If you put tomfoolery into a computer, nothing comes out but tomfoolery. +But this tomfoolery, having passed through a very expensive machine, +is somehow ennobled and no-one dare criticise it. + -- Pierre Gallois + +❯ fortune + +秋色渐将晚,霜信报黄花。 + -- 叶梦得《水调歌头·秋色渐将晚》 + +❯ fortune + +水精帘里颇黎枕,暖香惹梦鸳鸯锦。江上柳如烟,雁飞残月天。 +藕丝秋色浅,人胜参差剪。双鬓隔香红,玉钗头上风。 + -- 温庭筠《菩萨蛮》 + +❯ fortune + + A disciple of another sect once came to Drescher as he was eating +his morning meal. "I would like to give you this personality test", said +the outsider, "because I want you to be happy." + Drescher took the paper that was offered him and put it into the +toaster -- "I wish the toaster to be happy too". + +❯ fortune + +Example is not the main thing in influencing others. It is the only thing. + -- Albert Schweitzer + +❯ fortune + +We have art that we do not die of the truth. + -- Nietzsche + +❯ fortune + + "Java for the COBOL Programmer" + who writes these things? + people on crack + and cobol programmers + :) + that's redundant. + +❯ fortune + +I was in this prematurely air conditioned supermarket and there were all +these aisles and there were these bathing caps you could buy that had these +kind of Fourth of July plumes on them that were red and yellow and blue and +I wasn't tempted to buy one but I was reminded of the fact that I had been +avoiding the beach. + -- Lucinda Childs "Einstein On The Beach" + +❯ fortune + +It doesn't matter whether you win or lose -- until you lose. + +❯ fortune + +True leadership is the art of changing a group from what it is to what +it ought to be. + -- Virginia Allan + +❯ fortune + +I keep hearing and reading this nice proverb *if it ain't broke, don't fix +it*. The latest appearance was in response to [Shlomi +Fish](http://community.livejournal.com/shlomif_tech/37969.html) suggesting +that some Ancient Perl code should be replaced by Modern Perl code. + +I am not saying that every piece of code should be rewritten every 6 months, +but in my understanding that sentence actually translates to *let's wait till +it breaks and then panic*. + +I think people who say that sentence are afraid that the new version will +break something. Sure, there is always a chance that a change introduces an +error, but, if we are afraid to touch the code, what will happen when later on +we encounter a case where it does not work? For example, if we need to use it +in a new environment. Will we have the courage to change the code then? How +much will it cost in money, time, and lost sleep? + +I think we have been trying to teach ourselves that we should have really good +test coverage of our code and then we can easily refactor it and get rid of +technical debt. So why do we keep hearing that sentence? + + -- Gabor Szabo + -- What does "If it ain't broke, don't fix it." really mean? ( ) + +❯ fortune + +Psychoanalysis is that mental illness for which it regards itself a therapy. + -- Karl Kraus + +❯ fortune + +With a rubber duck, one's never alone. + -- "The Hitchhiker's Guide to the Galaxy" + +❯ fortune + +(Presuming for the sake of argument that it's even *possible* to design +better code in Perl than in C. :-) + -- Larry Wall on core code vs. module code design + +❯ fortune + +But, officer, he's not drunk, I just saw his fingers twitch! + +❯ fortune + +Imbalance of power corrupts and monopoly of power corrupts absolutely. + -- Genji + +❯ fortune + +I want a VEGETARIAN BURRITO to go ... with EXTRA MSG!! + +❯ fortune + +如果你不知道如何表现地高人一等,找个Unix用户,让他做给你看。 + -- Dilbert newsletter 3.0, 1994 + +❯ fortune + +"The picture's pretty bleak, gentlemen... The world's climates are changing, +the mammals are taking over, and we all have a brain about the size of a +walnut." + -- some dinosaurs from The Far Side, by Gary Larson + +❯ fortune + +Most of us feel that marketing types are like a dangerous weapon - keep +'em unloaded and locked up in a cupboard, and only bring them out when +you need them to do a job. + -- Craig Sanders + +❯ fortune + +不寐倦长更,披衣出户行。月寒秋竹冷,风切夜窗声。 + -- 李煜《三台令》 + +❯ fortune + +子曰:“由,诲女知之乎!知之为知之,不知为不知,是知也。” +-- 论语,为政篇 + +❯ fortune + + "The jig's up, Elman." + "Which jig?" + -- Jeff Elman + +❯ fortune + +"First things first -- but not necessarily in that order" + -- The Doctor, "Doctor Who" + +❯ fortune + +波影摇涟,趁熏风,一舸来时,翠阴清昼。去郭轩楹才数里,藓磴松关云岫。 +快屐齿,筇枝先后。空半危亭堪聚远,看洞庭,缥缈争奇秀。人自老,景如旧。 +来帆去棹还知否,问古今,几度斜阳,几番回首?晓色一川谁管领,都付雨荷烟柳, +知我者,燕朋鸥友。笑拍阑干呼范蠡,甚平吴,却倩垂纶手?吁万古,付卮酒。 + -- 周密《长亭怨慢》 + +❯ fortune + +I'm telling you that the kernel is stable not because it's a kernel, +but because I refuse to listen to arguments like this. + -- Linus Torvalds + +❯ fortune + +A girl's conscience doesn't really keep her from doing anything wrong-- +it merely keeps her from enjoying it. + +❯ fortune + +There are few people more often in the wrong than those who cannot endure +to be thought so. + +❯ fortune + +One does not thank logic. + -- Sarek, "Journey to Babel", stardate 3842.4 + +❯ fortune + +Free yourself from negative influence. Negative thoughts are the old +habits that gnaw at the roots of the soul. +Moses Shongo, (Seneca) + +❯ fortune + +日月照之何不及此?惟有北风号怒天上来。 + -- 李白《北风行》 + +❯ fortune + +Anyone who is capable of getting themselves made President should on no +account be allowed to do the job. + -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" + +And here are my mods:-) + +❯ pacman -Qs fortune +local/cowfortune 0.1.2-8 + Configurable fortune cookie proclaiming cow (and a few other creatures) +local/fortune-mod 3.22.0-1.1 + The Fortune Cookie Program from BSD games +local/fortune-mod-zh 2.98-1 (fortune-mods) + Chinese poems for fortune-mod