1 line
256 KiB
JSON
1 line
256 KiB
JSON
{"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/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/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/phase1.png","path":"images/phase1.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/phase1_strings.png","path":"images/phase1_strings.png","modified":1,"renderable":0},{"_id":"source/images/phase_4.png","path":"images/phase_4.png","modified":1,"renderable":0},{"_id":"source/images/zellij-helix.jpg","path":"images/zellij-helix.jpg","modified":1,"renderable":0},{"_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/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/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/_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月31日进度报告.md","hash":"bf541fdb539029c98dedf975b0c15519adcea76e","modified":1740320866748},{"_id":"source/_posts/12月28日进度报告.md","hash":"4cbda36dc6a2c4bc67140e443638a73aadb18fdf","modified":1740320866748},{"_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-optimization.md","hash":"b61ce5702b3a1b302e8c02f4f46d9a1cd3f5e6e4","modified":1740320942471},{"_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/zellij-helix.md","hash":"7eb3072b50ecdb49a20355e05fc613a4a8b7fbdf","modified":1740326024966},{"_id":"source/about/index.md","hash":"ff7cd1481f3c669a04d7c8abf8851ab0cea5b2b9","modified":1740326480093},{"_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/caseclosed.png","hash":"628b54b49c86a23af595a52daba9e0557b81a17a","modified":1740454957882},{"_id":"source/images/1730728153314.png","hash":"95d44ea62557a311503cab58d1dec5cafc97e07d","modified":1740320866754},{"_id":"source/images/phase1.png","hash":"42533712403be6036231f1e3770f125858bf91d7","modified":1740385026324},{"_id":"source/images/5364bba6d035326e82c53504dd53e7c2454454985.png","hash":"11b11f23ebebbe08e8cf826b48eb37b4084796cd","modified":1729572689000},{"_id":"source/images/1613f5602b203b38230f19699deb0219454454985.png","hash":"3d71204d9a0731384f97ad0f90802a5c9fd96776","modified":1729572689000},{"_id":"themes/fluid/source/css/_pages/_tag/tag.styl","hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709","modified":1740320867063},{"_id":"source/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","hash":"dddf72bb12aef01baa3eb2017bb867f274059f12","modified":1729572689000},{"_id":"source/images/mhwilds4050.jpg","hash":"9b2b15c66e2340c15b86cec0fa8f818b67e06384","modified":1730738910727},{"_id":"themes/fluid/.editorconfig","hash":"33218fbd623feb43edf5f99f15965392cecc44a6","modified":1740320867050},{"_id":"themes/fluid/.gitattributes","hash":"a54f902957d49356376b59287b894b1a3d7a003f","modified":1740320867050},{"_id":"themes/fluid/.gitignore","hash":"ae3bfcb89777657c5dfb5169d91445dcb0e5ab98","modified":1740320867051},{"_id":"themes/fluid/.eslintrc","hash":"4bc2b19ce2b8c4d242f97d4ccf2d741e68ab0097","modified":1740320867050},{"_id":"themes/fluid/LICENSE","hash":"26f9356fd6e84b5a88df6d9014378f41b65ba209","modified":1740320867051},{"_id":"themes/fluid/README_en.md","hash":"365184a73af40e7365504c3077f3d80dfee1d80e","modified":1740320867051},{"_id":"themes/fluid/README.md","hash":"ff9b0e1fb9dba665af2f1e4a577f8cb9e840464b","modified":1740320867051},{"_id":"themes/fluid/package.json","hash":"7746460fc2eba7439b494c46aa9b5ded81370819","modified":1740320867057},{"_id":"themes/fluid/_config.yml","hash":"60403ea6aa5e0cab9dbc7bf0d77257e4a941babc","modified":1740329151304},{"_id":"themes/fluid/languages/en.yml","hash":"9c580471257f5a32bee701a059a45ea96755dcdc","modified":1740320867052},{"_id":"themes/fluid/languages/de.yml","hash":"58dccef1d98b472dc4e6f4693c2297b0c9c5afba","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/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/archive.ejs","hash":"7c1f44005849791feae4abaa10fae4cb983d3277","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_zh.md","hash":"c8b0d49c49e3c88872fd3b37909345ff5b2b6aa0","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/bug_report.md","hash":"554c0d0e086a0784d83ee71c83f8bceeb60aecc8","modified":1740320867050},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/feature_request_zh.md","hash":"ed08574b196447376dd74411cca664ac9227a5d4","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/feature_request.md","hash":"c134dd57ffd269b93402ccfffe7dbe0f0b583bec","modified":1740320867051},{"_id":"themes/fluid/.github/ISSUE_TEMPLATE/question.md","hash":"ab5eab9e3ff889c4ba7fd82846e7f5b7ae15bebc","modified":1740320867051},{"_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/scripts/events/index.js","hash":"79de5a379b28cad759a49048351c7f6b8915bd7d","modified":1740320867057},{"_id":"themes/fluid/.github/workflows/publish.yaml","hash":"6f02e6440d88629229556e3fd47d0280fe2240db","modified":1740320867051},{"_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/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/header.ejs","hash":"0d5e397d30051e5fbabe7b47cfd1f1e6a5820af1","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/markdown-plugins.ejs","hash":"fc4bdf7de0cf1a66d0e5e4fba1b31d6f7ed49468","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/head.ejs","hash":"67be642f99482c07904474f410cfbc2f99003288","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/paginator.ejs","hash":"0f38a2c238169edcb63fc46c23bfc529ff3859b7","modified":1740320867054},{"_id":"themes/fluid/layout/_partials/search.ejs","hash":"70e1c929e084ca8a2648cedabf29b372511ea2b8","modified":1740320867056},{"_id":"themes/fluid/layout/_partials/scripts.ejs","hash":"da5810785105e5075861593c7ac22c7aa9665a72","modified":1740320867056},{"_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/img/police_beian.png","hash":"90efded6baa2dde599a9d6b1387973e8e64923ea","modified":1740320867086},{"_id":"themes/fluid/source/css/gitalk.css","hash":"a57b3cc8e04a0a4a27aefa07facf5b5e7bca0e76","modified":1740320867063},{"_id":"themes/fluid/source/css/highlight-dark.styl","hash":"45695ef75c31a4aa57324dd408b7e2327a337018","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/js/boot.js","hash":"38bd26c6b7acdafda86dda3560e6a3ca488d3c76","modified":1740320867086},{"_id":"themes/fluid/source/js/color-schema.js","hash":"1ef88c881b9f942deadde3d890387b94c617342a","modified":1740320867086},{"_id":"themes/fluid/source/js/events.js","hash":"6869811f67e4c3de3edfa4b08464bb242b97a402","modified":1740320867086},{"_id":"themes/fluid/source/js/img-lazyload.js","hash":"cbdeca434ec4da51f488c821d51b4d23c73294af","modified":1740320867086},{"_id":"themes/fluid/source/js/leancloud.js","hash":"eff77c7a5c399fcaefda48884980571e15243fc9","modified":1740320867086},{"_id":"themes/fluid/source/js/plugins.js","hash":"c34916291e392a774ff3e85c55badb83e8661297","modified":1740320867087},{"_id":"themes/fluid/source/js/local-search.js","hash":"b9945f76f8682f3ec32edfb285b26eb559f7b7e8","modified":1740320867086},{"_id":"themes/fluid/source/js/utils.js","hash":"b82e7c289a66dfd36064470fd41c0e96fc598b43","modified":1740320867087},{"_id":"themes/fluid/source/xml/local-search.xml","hash":"8c96ba6a064705602ce28d096fd7dd9069630a55","modified":1740320867087},{"_id":"themes/fluid/scripts/events/lib/footnote.js","hash":"c19ac8050b82c3676b0332a56099ccfcc36d9d52","modified":1740320867057},{"_id":"themes/fluid/scripts/events/lib/compatible-configs.js","hash":"ef474d1fa5bbafc52619ced0f9dc7eaf2affb363","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/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/discuss.ejs","hash":"98d065b58ce06b7d18bff3c974e96fa0f34ae03a","modified":1740320867053},{"_id":"themes/fluid/layout/_partials/comments/disqus.ejs","hash":"aab4a4d24c55231a37db308ae94414319cecdd9b","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/layout/_partials/comments/livere.ejs","hash":"2264758fed57542a7389c7aa9f00f1aefa17eb87","modified":1740320867053},{"_id":"themes/fluid/source/js/umami-view.js","hash":"33c4b3883fa747604074ad3921606eeeaeb50716","modified":1740320867087},{"_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/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/comments/valine.ejs","hash":"19ba937553dddd317f827d682661a1066a7b1f30","modified":1740320867054},{"_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/sidebar-left.ejs","hash":"9992c99b3eb728ad195970e1b84d665f2c8691c4","modified":1740320867056},{"_id":"themes/fluid/layout/_partials/post/meta-top.ejs","hash":"54dd479dbb440126e4ddd9d902229db5afaaae98","modified":1740320867055},{"_id":"themes/fluid/layout/_partials/post/sidebar-right.ejs","hash":"d5fcc9b60e02f869a29a8c17a16a6028ecc1e6d8","modified":1740320867056},{"_id":"themes/fluid/layout/_partials/post/toc.ejs","hash":"635a89060fbf72eeda066fc4bd0a97462f069417","modified":1740320867056},{"_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/_archive/archive.styl","hash":"c475e6681546d30350eaed11f23081ecae80c375","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/source/css/_pages/_base/color-schema.styl","hash":"85492ef64d7e5f70f0f7e46d570bbc911e686d7e","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/keyframes.styl","hash":"94065ea50f5bef7566d184f2422f6ac20866ba22","modified":1740320867062},{"_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/_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/board.styl","hash":"4397037fc3f0033dbe546c33cd9dbdabd8cb1632","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/copyright.styl","hash":"26f71a9cd60d96bb0cb5bbdf58150b8e524d9707","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/footer.styl","hash":"2caaca71dd1ff63d583099ed817677dd267b457e","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/search.styl","hash":"10f7e91a91e681fb9fe46f9df7707b9ef78707c8","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/toc.styl","hash":"9e7452aa2372153f25d7a4675c9d36d281a65d24","modified":1740320867061},{"_id":"themes/fluid/source/css/_pages/_base/_widget/scroll-btn.styl","hash":"f0e429a27fa8a7658fcbddbb4d4dbe4afa12499a","modified":1740320867061},{"_id":"themes/fluid/source/img/hifuu.png","hash":"331b5950baf96f5d39192bb42b7da4d22a08992e","modified":1740320867086},{"_id":"source/images/clonezilla.png","hash":"7f443d79783df3744b2e51613422ee8fd7eea6f8","modified":1740318117703},{"_id":"source/images/mhwilds780M.jpg","hash":"e2c59c6caae452afb424d9f2fc3a255a44121b49","modified":1730738926927},{"_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/zellij-helix.jpg","hash":"87fb5b7b51a4e3b062b891c04488a53457edded0","modified":1738492100321},{"_id":"themes/fluid/source/img/gensokyo.jpg","hash":"d82c0d5011c6cbc37109c9c80530d14cd266286f","modified":1740320867082},{"_id":"public/local-search.xml","hash":"754a0e0ed27d9ebf1f90e96b277307f52e94d550","modified":1740457601245},{"_id":"public/about/index.html","hash":"aed578d02d2a907f749b64e32efda908b0ac4c04","modified":1740457601245},{"_id":"public/2025/02/24/nudtbomblab/index.html","hash":"4965d39647cf126e07ca43a02612bf7c5875f6cd","modified":1740457601245},{"_id":"public/2025/02/02/archlinux-optimization/index.html","hash":"1a79f7454ac4a0dcb73256697a4e4197559b5297","modified":1740457601245},{"_id":"public/2024/12/13/zellij-helix/index.html","hash":"952cd837e89121b41cef1b3fe92fc98f6253bcc4","modified":1740457601245},{"_id":"public/2025/02/23/clonezilla/index.html","hash":"18b734abda3405019efcab2523f12e766bfa73a3","modified":1740457601245},{"_id":"public/2024/11/06/overleaf/index.html","hash":"bc411b1a10fcbb6a5f6d0d213fa63f093830cae3","modified":1740457601245},{"_id":"public/2024/11/04/loopers/index.html","hash":"52c2990102d50fb0fc874c3bb7363776b68255e3","modified":1740457601245},{"_id":"public/2024/11/06/arch-nvidia/index.html","hash":"8ade129a78d71d3017432e1a65e1d6d292a16c53","modified":1740457601245},{"_id":"public/2024/11/04/Vocaloid调教-晴天/index.html","hash":"a3dd5c0b77bd2eb77555d349177492a02e17fd25","modified":1740457601245},{"_id":"public/2024/10/30/GentleJena/index.html","hash":"0747019314125e796e102155e09febb4cbdb9b67","modified":1740457601245},{"_id":"public/2024/06/03/原来我还有个博客/index.html","hash":"7215c9a90d0695469c179717d27194e346a8abd0","modified":1740457601245},{"_id":"public/2023/12/31/12月31日进度报告/index.html","hash":"03f909c8954f0e623ccaf2e30fa44a1d3f45814b","modified":1740457601245},{"_id":"public/2024/11/11/mhwi/index.html","hash":"ebe1a9550fe14035a215f067342373d3e2a2e8c5","modified":1740457601245},{"_id":"public/2023/12/20/12月20日工作记录/index.html","hash":"5ee7c6817c2202a86dcf8e7e6898d2559c69dcf2","modified":1740457601245},{"_id":"public/2024/11/04/BlogUpdate/index.html","hash":"ac98c86ad12b3074414a44bfdf3ed153320d3a03","modified":1740457601245},{"_id":"public/2023/12/19/12月19日工作记录/index.html","hash":"bac072049959ec19cb53ad4b9180b53476c3542f","modified":1740457601245},{"_id":"public/2023/12/17/12月16-17日工作记录/index.html","hash":"2af885a19d1b28c3a1e6d4afdf110c6733a4c6b5","modified":1740457601245},{"_id":"public/2023/12/18/12月18日工作记录/index.html","hash":"82d3d1cab693f7808b28ed48803229a5290ee798","modified":1740457601245},{"_id":"public/2023/12/28/12月28日进度报告/index.html","hash":"5aa948c12c109b08b781baf308c9a80ddd3bc379","modified":1740457601245},{"_id":"public/archives/index.html","hash":"0d906c7fed598af264e44bca6478b13bb89de30a","modified":1740457601245},{"_id":"public/2023/12/06/CGH0S7-s-Blog/index.html","hash":"b13772d5d9a1a7a19d1f565a27e8a9432f0da543","modified":1740457601245},{"_id":"public/archives/page/2/index.html","hash":"3c3e1c104a6b6a3fbea1e5502199a2319398b1d0","modified":1740457601245},{"_id":"public/2023/12/06/梦开始的地方/index.html","hash":"2df05084144d2567e92d3b9f59afbb720fbed05a","modified":1740457601245},{"_id":"public/archives/2023/12/index.html","hash":"13bad1d512244b2c6fe7a9ec6896be520eafcb18","modified":1740457601245},{"_id":"public/archives/2024/06/index.html","hash":"5a6f5a882ef61bda49289f6fa169105f3adab3c8","modified":1740457601245},{"_id":"public/archives/2024/10/index.html","hash":"bc50342e110a5e979e61101bcca106f8967a2c77","modified":1740457601245},{"_id":"public/archives/2023/index.html","hash":"61317006ccd7a25a201d8a6e8e4a6f9882e6d857","modified":1740457601245},{"_id":"public/archives/2024/12/index.html","hash":"6a913f1615fe45879e3772bfef32f2b24c2f1e38","modified":1740457601245},{"_id":"public/archives/2025/index.html","hash":"864a4e41d5b27be3db543b52501805e6b8a51880","modified":1740457601245},{"_id":"public/archives/2024/index.html","hash":"64d5411e304b7e132a50fb6c8c4c336342493ba9","modified":1740457601245},{"_id":"public/categories/更新/index.html","hash":"39ae73dfc0e214df88912e0a38b4cbf3b55e13a4","modified":1740457601245},{"_id":"public/archives/2025/02/index.html","hash":"67d9de757d3d34ef4ef8a88b3c286ef882697182","modified":1740457601245},{"_id":"public/categories/Vocaloid/index.html","hash":"048aca4e241b331d0209e9208c379fcf665a0fae","modified":1740457601245},{"_id":"public/archives/2024/11/index.html","hash":"25d7617dc8ac9e7953dcdb516753afe742e19cdc","modified":1740457601245},{"_id":"public/index.html","hash":"43e9960f33bf1daa18c2aae68f11b2a0fab2e172","modified":1740457601245},{"_id":"public/categories/技术分享/index.html","hash":"af921a46b2c79d42f3f975638ec3b7133af7028b","modified":1740457601245},{"_id":"public/page/2/index.html","hash":"01b94453e6ae77a30d0f48d5ec6e51fba646e6a8","modified":1740457601245},{"_id":"public/tags/日志/index.html","hash":"bf4fbe21c0376cb80cd8b282a0ed31f4d7e16e10","modified":1740457601245},{"_id":"public/categories/Rearrangement/index.html","hash":"d86532128355807b19a6eb69208699289b62cfb7","modified":1740457601245},{"_id":"public/tags/音乐/index.html","hash":"0c4de7bf53b25a52c23aaf27d7327d49d165268b","modified":1740457601245},{"_id":"public/tags/技术/index.html","hash":"1dea2413397a9fdfba26ee98c8c69adc280d17e9","modified":1740457601245},{"_id":"public/tags/技术分享/index.html","hash":"008bf090272f222a7b84fa903de3702231b8516b","modified":1740457601245},{"_id":"public/tags/TEST/index.html","hash":"2e5789b8e544c5e8404441c75b054f661294306a","modified":1740457601245},{"_id":"public/tags/生活/index.html","hash":"794d127e0a2d30942dada57f68dfc5659be687be","modified":1740457601245},{"_id":"public/tags/板绘/index.html","hash":"05cf911d2c26ed5f6d104d875c11762e6e55b12e","modified":1740457601245},{"_id":"public/404.html","hash":"4696437e74fa558f8be811e50fdfd88f2a84e82b","modified":1740457601245},{"_id":"public/tags/index.html","hash":"781105ac669cdf678cfee017c02a6b706f5d1354","modified":1740457601245},{"_id":"public/categories/index.html","hash":"f2bbc847232265380a90a69b0d2f3bfb05137d31","modified":1740457601245},{"_id":"public/links/index.html","hash":"4591acb90903a2e0e2a889de931883ac7119c23e","modified":1740457601245},{"_id":"public/tags/学习/index.html","hash":"b754a2106f26f5f90fd1d4e6370b58904b39eda3","modified":1740457601245},{"_id":"public/tags/Vocaloid/index.html","hash":"98440598d6da10f35250eb46e393c0f7199fd848","modified":1740457601245},{"_id":"public/images/amd.webp","hash":"cb0cfd5da0b9c10b9b22c65bba881cfde485d763","modified":1740457601245},{"_id":"public/images/asc-events.png","hash":"a0b3610962062d0a322fe091bcc8f083ab13bc6e","modified":1740457601245},{"_id":"public/images/built_on_the_kde_platform.png","hash":"507b6a4323b23772800006505e6c588bb515ebf5","modified":1740457601245},{"_id":"public/images/asc.png","hash":"3a33b35bff1b3f527f7a87a9d6a7d6d9a072a946","modified":1740457601245},{"_id":"public/images/archlinux-logo.png","hash":"4f6075309fadcb7f7547164cb8a99b4949f74598","modified":1740457601245},{"_id":"public/images/Written-By-Human-Not-By-AI-Badge-white@2x.png","hash":"994225c6fd72521b281144bdd98fefcca53e2c7b","modified":1740457601245},{"_id":"public/img/avatar.png","hash":"fe739a158cc128f70f780eb5fa96f388b81d478f","modified":1740457601245},{"_id":"public/img/police_beian.png","hash":"90efded6baa2dde599a9d6b1387973e8e64923ea","modified":1740457601245},{"_id":"public/xml/local-search.xml","hash":"8c96ba6a064705602ce28d096fd7dd9069630a55","modified":1740457601245},{"_id":"public/img/loading.gif","hash":"2d2fc0f947940f98c21afafef39ecf226a2e8d55","modified":1740457601245},{"_id":"public/images/phase1_strings.png","hash":"6fb457adddc5bb32aa463b6227542076c4b501e7","modified":1740457601245},{"_id":"public/img/hifuu.png","hash":"331b5950baf96f5d39192bb42b7da4d22a08992e","modified":1740457601245},{"_id":"public/css/gitalk.css","hash":"a57b3cc8e04a0a4a27aefa07facf5b5e7bca0e76","modified":1740457601245},{"_id":"public/css/highlight.css","hash":"04d4ddbb5e1d1007447c2fe293ee05aae9b9563e","modified":1740457601245},{"_id":"public/css/highlight-dark.css","hash":"902294bada4323c0f51502d67cba8c3a0298952f","modified":1740457601245},{"_id":"public/js/boot.js","hash":"38bd26c6b7acdafda86dda3560e6a3ca488d3c76","modified":1740457601245},{"_id":"public/css/main.css","hash":"06433abcb688c2f5473623a9355bff9865c48d3f","modified":1740457601245},{"_id":"public/js/events.js","hash":"6869811f67e4c3de3edfa4b08464bb242b97a402","modified":1740457601245},{"_id":"public/js/leancloud.js","hash":"eff77c7a5c399fcaefda48884980571e15243fc9","modified":1740457601245},{"_id":"public/js/color-schema.js","hash":"1ef88c881b9f942deadde3d890387b94c617342a","modified":1740457601245},{"_id":"public/js/plugins.js","hash":"c34916291e392a774ff3e85c55badb83e8661297","modified":1740457601245},{"_id":"public/js/utils.js","hash":"b82e7c289a66dfd36064470fd41c0e96fc598b43","modified":1740457601245},{"_id":"public/js/local-search.js","hash":"b9945f76f8682f3ec32edfb285b26eb559f7b7e8","modified":1740457601245},{"_id":"public/js/umami-view.js","hash":"33c4b3883fa747604074ad3921606eeeaeb50716","modified":1740457601245},{"_id":"public/js/img-lazyload.js","hash":"cbdeca434ec4da51f488c821d51b4d23c73294af","modified":1740457601245},{"_id":"public/images/caseclosed.png","hash":"628b54b49c86a23af595a52daba9e0557b81a17a","modified":1740457601245},{"_id":"public/images/1730728153314.png","hash":"95d44ea62557a311503cab58d1dec5cafc97e07d","modified":1740457601245},{"_id":"public/img/gh0s7.jpg","hash":"1c5af4f8cacdc3c6adbe8334866774cca2944910","modified":1740457601245},{"_id":"public/images/phase1.png","hash":"42533712403be6036231f1e3770f125858bf91d7","modified":1740457601245},{"_id":"public/images/5364bba6d035326e82c53504dd53e7c2454454985.png","hash":"11b11f23ebebbe08e8cf826b48eb37b4084796cd","modified":1740457601245},{"_id":"public/images/1613f5602b203b38230f19699deb0219454454985.png","hash":"3d71204d9a0731384f97ad0f90802a5c9fd96776","modified":1740457601245},{"_id":"public/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png","hash":"dddf72bb12aef01baa3eb2017bb867f274059f12","modified":1740457601245},{"_id":"public/images/mhwilds4050.jpg","hash":"9b2b15c66e2340c15b86cec0fa8f818b67e06384","modified":1740457601245},{"_id":"public/images/mhwilds780M.jpg","hash":"e2c59c6caae452afb424d9f2fc3a255a44121b49","modified":1740457601245},{"_id":"public/images/clonezilla.png","hash":"7f443d79783df3744b2e51613422ee8fd7eea6f8","modified":1740457601245},{"_id":"public/images/phase_4.png","hash":"81cd309a8990e015a8679b6a4e26a27d804c1da6","modified":1740457601245},{"_id":"public/images/phase_2_14.png","hash":"f50399a9eb469ed1e063ff4ccc0e8636c1b75f1e","modified":1740457601245},{"_id":"public/images/b2054bbaf6197624d38cc2007d885fd1454454985.png","hash":"b021e971cedaa55b273eab2b10be94f795b06922","modified":1740457601245},{"_id":"public/images/20241027_222225.png","hash":"f0595d1315d94e72e61c69e0499e5129e1821ba1","modified":1740457601245},{"_id":"public/images/zellij-helix.jpg","hash":"87fb5b7b51a4e3b062b891c04488a53457edded0","modified":1740457601245},{"_id":"public/img/gensokyo.jpg","hash":"d82c0d5011c6cbc37109c9c80530d14cd266286f","modified":1740457601245}],"Category":[{"name":"更新","_id":"cm7jziods000fwi2b6sz39o2v"},{"name":"Rearrangement","_id":"cm7jziodu000nwi2bg9k8dxzp"},{"name":"Vocaloid","_id":"cm7jziodu000uwi2b02p27nyj"},{"name":"技术分享","_id":"cm7jziodv0010wi2b1nt86jtj"}],"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: <c_gh0s7@nudt.edu.cn>\n\n- Github: <https://github.com/CGH0S7>\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: <c_gh0s7@nudt.edu.cn>\n\n- Github: <https://github.com/CGH0S7>\n","updated":"2025-02-23T16:01:20.093Z","path":"about/index.html","comments":1,"_id":"cm7jziodm0000wi2b8fohhnl9","content":"<p>白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧</p>\n<p>爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇</p>\n<p>截至目前最喜欢的歌手是宇多田光❤️</p>\n<p>联系方式:</p>\n<ul>\n<li><p>Email: <a href=\"mailto:c_gh0s7@nudt.edu.cn\">c_gh0s7@nudt.edu.cn</a></p>\n</li>\n<li><p>Github: <a href=\"https://github.com/CGH0S7\">https://github.com/CGH0S7</a></p>\n</li>\n</ul>\n","excerpt":"","more":"<p>白茅铺高地玄院第N任非菌群主🐳,Linux六年牢用户🐧</p>\n<p>爱好编程,绘画,编曲,Vocaloid调教,Blender建模等😇</p>\n<p>截至目前最喜欢的歌手是宇多田光❤️</p>\n<p>联系方式:</p>\n<ul>\n<li><p>Email: <a href=\"mailto:c_gh0s7@nudt.edu.cn\">c_gh0s7@nudt.edu.cn</a></p>\n</li>\n<li><p>Github: <a href=\"https://github.com/CGH0S7\">https://github.com/CGH0S7</a></p>\n</li>\n</ul>\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":"cm7jziodn0001wi2b80cf2h59","content":"<h2 id=\"12月16-17日\"><a href=\"#12月16-17日\" class=\"headerlink\" title=\"12月16-17日\"></a>12月16-17日</h2><ol>\n<li>四级考试</li>\n<li>自学cuda,openacc,了解GPU架构知识</li>\n<li>参加超算队启动会</li>\n<li>大计和高数期中考试</li>\n<li>研究spack使用</li>\n<li>学习cuda编程</li>\n<li>补作业</li>\n</ol>\n","excerpt":"","more":"<h2 id=\"12月16-17日\"><a href=\"#12月16-17日\" class=\"headerlink\" title=\"12月16-17日\"></a>12月16-17日</h2><ol>\n<li>四级考试</li>\n<li>自学cuda,openacc,了解GPU架构知识</li>\n<li>参加超算队启动会</li>\n<li>大计和高数期中考试</li>\n<li>研究spack使用</li>\n<li>学习cuda编程</li>\n<li>补作业</li>\n</ol>\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":"cm7jziodo0002wi2bhhu604l9","content":"<h2 id=\"12月18日\"><a href=\"#12月18日\" class=\"headerlink\" title=\"12月18日\"></a>12月18日</h2><ol>\n<li>初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;</li>\n<li>协助Neko组完成任务;</li>\n<li>找出spack存在网络原因无法下载时的手动解决方案.</li>\n</ol>\n","excerpt":"","more":"<h2 id=\"12月18日\"><a href=\"#12月18日\" class=\"headerlink\" title=\"12月18日\"></a>12月18日</h2><ol>\n<li>初步了解opencaeporo,尝试在本地docker环境使用gcc完成编译安装,目前完成各项依赖安装,由于晚上停电计划明天开始编译安装opencaeporo本体并在本地调优;</li>\n<li>协助Neko组完成任务;</li>\n<li>找出spack存在网络原因无法下载时的手动解决方案.</li>\n</ol>\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":"cm7jziodp0004wi2baobvgc5p","content":"<h2 id=\"12月18日\"><a href=\"#12月18日\" class=\"headerlink\" title=\"12月18日\"></a>12月18日</h2><ol>\n<li>彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;</li>\n<li>学习cuda编程.</li>\n</ol>\n","excerpt":"","more":"<h2 id=\"12月18日\"><a href=\"#12月18日\" class=\"headerlink\" title=\"12月18日\"></a>12月18日</h2><ol>\n<li>彻底完成opencaeporo安装部署,本地和服务器均已安装,明天正式开始调优工作;</li>\n<li>学习cuda编程.</li>\n</ol>\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":"cm7jziodq0005wi2b46qac5mo","content":"<h2 id=\"12月28日\"><a href=\"#12月28日\" class=\"headerlink\" title=\"12月28日\"></a>12月28日</h2><p>OpenCAEPoro 小组(黄<strong>,梁</strong>,程<strong>,刘</strong>)</p>\n<ol>\n<li>各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果</li>\n<li>继续学习openacc及cuda相关知识</li>\n<li>搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备</li>\n</ol>\n","excerpt":"","more":"<h2 id=\"12月28日\"><a href=\"#12月28日\" class=\"headerlink\" title=\"12月28日\"></a>12月28日</h2><p>OpenCAEPoro 小组(黄<strong>,梁</strong>,程<strong>,刘</strong>)</p>\n<ol>\n<li>各组员继续进行优化工作,部分函数完成cuda移植,取得一定优化效果</li>\n<li>继续学习openacc及cuda相关知识</li>\n<li>搜集多孔介质流动模拟与opencaeporo相关论文资料为proposal做准备</li>\n</ol>\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":"cm7jziodq0006wi2bhm74a0a9","content":"<h2 id=\"12月20日\"><a href=\"#12月20日\" class=\"headerlink\" title=\"12月20日\"></a>12月20日</h2><p>OpenCAEPoro 小组(黄<strong>,梁</strong>,程**)</p>\n<ol>\n<li>阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果</li>\n</ol>\n<blockquote>\n<p>优化方向基本确定为OpenMP/OpenACC并行化+cuda移植</p>\n</blockquote>\n<ol start=\"2\">\n<li>赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求</li>\n</ol>\n","excerpt":"","more":"<h2 id=\"12月20日\"><a href=\"#12月20日\" class=\"headerlink\" title=\"12月20日\"></a>12月20日</h2><p>OpenCAEPoro 小组(黄<strong>,梁</strong>,程**)</p>\n<ol>\n<li>阅读代码,开展优化工作,初步使用openacc完成petsc_solver的优化,取得一定优化效果</li>\n</ol>\n<blockquote>\n<p>优化方向基本确定为OpenMP/OpenACC并行化+cuda移植</p>\n</blockquote>\n<ol start=\"2\">\n<li>赛题环境汇总,目前各组工作有序开展,CentOS 7符合要求暂未发现更换系统需求</li>\n</ol>\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":"cm7jziodr0009wi2b5h330fp7","content":"<h2 id=\"12月30-31日\"><a href=\"#12月30-31日\" class=\"headerlink\" title=\"12月30-31日\"></a>12月30-31日</h2><p>OpenCAEPoro 小组(黄<strong>,梁</strong>,程<strong>,刘</strong>)</p>\n<ol>\n<li>服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;</li>\n<li>收集运行数据用于proposal绘制图表;</li>\n<li>继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.</li>\n</ol>\n","excerpt":"","more":"<h2 id=\"12月30-31日\"><a href=\"#12月30-31日\" class=\"headerlink\" title=\"12月30-31日\"></a>12月30-31日</h2><p>OpenCAEPoro 小组(黄<strong>,梁</strong>,程<strong>,刘</strong>)</p>\n<ol>\n<li>服务器上的Opencaeporo改用nvhpc编译器编译以支持cuda;</li>\n<li>收集运行数据用于proposal绘制图表;</li>\n<li>继续尝试优化,同时已经查阅收集了一些相关资料以尽量理解相关含义便于工作开展.</li>\n</ol>\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":"cm7jziodr000bwi2bdhi71dk3","content":"<ul>\n<li>博客主题更新为 <code>Fluid</code> 主题,原主题为 <code>Next</code></li>\n<li>更新了访问地址为 <code>https://blog.hifuu.ink</code></li>\n<li>新增了 <code>About</code> 页面</li>\n<li>新增了 <code>友链</code> 页面</li>\n<li>完善页面布局</li>\n</ul>\n","excerpt":"","more":"<ul>\n<li>博客主题更新为 <code>Fluid</code> 主题,原主题为 <code>Next</code></li>\n<li>更新了访问地址为 <code>https://blog.hifuu.ink</code></li>\n<li>新增了 <code>About</code> 页面</li>\n<li>新增了 <code>友链</code> 页面</li>\n<li>完善页面布局</li>\n</ul>\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":"cm7jziods000ewi2bdc6000t9","content":"<p>Hello World !</p>\n","excerpt":"","more":"<p>Hello World !</p>\n"},{"title":"Gentle Jena","date":"2024-10-30T14:11:14.000Z","_content":"\n很喜欢的一首曲子\n顺便测试一下视频上传\n以后随缘更新各种乱七八糟的东西。。\n\n<video controls width=\"600\" height=\"400\">\n <source src=\"https://ik.imagekit.io/7grujzz8i/2024-09-22%2014-05-02.mp4?updatedAt=1738496025016\" type=\"video/mp4\" width=\"50%\">\n</video>\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<video controls width=\"600\" height=\"400\">\n <source src=\"https://ik.imagekit.io/7grujzz8i/2024-09-22%2014-05-02.mp4?updatedAt=1738496025016\" type=\"video/mp4\" width=\"50%\">\n</video>\n","slug":"GentleJena","published":1,"updated":"2025-02-23T17:14:31.930Z","comments":1,"layout":"post","photos":[],"_id":"cm7jziods000hwi2b19t43c6n","content":"<p>很喜欢的一首曲子<br>顺便测试一下视频上传<br>以后随缘更新各种乱七八糟的东西。。</p>\n<video controls width=\"600\" height=\"400\">\n <source src=\"https://ik.imagekit.io/7grujzz8i/2024-09-22%2014-05-02.mp4?updatedAt=1738496025016\" type=\"video/mp4\" width=\"50%\">\n</video>\n","excerpt":"","more":"<p>很喜欢的一首曲子<br>顺便测试一下视频上传<br>以后随缘更新各种乱七八糟的东西。。</p>\n<video controls width=\"600\" height=\"400\">\n <source src=\"https://ik.imagekit.io/7grujzz8i/2024-09-22%2014-05-02.mp4?updatedAt=1738496025016\" type=\"video/mp4\" width=\"50%\">\n</video>\n"},{"title":"Vocaloid调教-晴天(洛天依V4)","date":"2024-11-04T13:52:59.000Z","_content":"\n其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。\n\n“故事的小黄花,从出生那年就飘着...”\n\n{% raw %}\n<iframe src=\"//player.bilibili.com/player.html?bvid=BV1xzPteRErF&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\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<iframe src=\"//player.bilibili.com/player.html?bvid=BV1xzPteRErF&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\n{% endraw %}\n\n","slug":"Vocaloid调教-晴天","published":1,"updated":"2025-02-25T00:19:05.940Z","comments":1,"layout":"post","photos":[],"_id":"cm7jziodt000kwi2b320w2nl5","content":"<p>其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。</p>\n<p>“故事的小黄花,从出生那年就飘着…”</p>\n\n<iframe src=\"//player.bilibili.com/player.html?bvid=BV1xzPteRErF&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\n\n\n","excerpt":"","more":"<p>其实是今年年初的作品想起来可以搬上来,这是我调教的第一首v曲。</p>\n<p>“故事的小黄花,从出生那年就飘着…”</p>\n\n<iframe src=\"//player.bilibili.com/player.html?bvid=BV1xzPteRErF&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\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\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\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\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 \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\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\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\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 \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":"cm7jziodt000mwi2bcvznhn4q","content":"<p>本文将介绍在 <strong>X11</strong> 和 <strong>Wayland</strong> 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。<strong>首先,请确保您已经正确安装了 Nvidia 驱动</strong>(如果非 Mainline 内核,请使用 <code>nvidia-dkms</code> 或 <code>nvidia-open-dkms</code> 版本)。</p>\n<p><img src=\"/images/5364bba6d035326e82c53504dd53e7c2454454985.png\" alt=\"Nvidia设置示意图\"></p>\n<h3 id=\"适用系统\"><a href=\"#适用系统\" class=\"headerlink\" title=\"适用系统\"></a>适用系统</h3><p>对于 <strong>CachyOS</strong> 或 <strong>EndeavourOS</strong> 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:</p>\n<ul>\n<li>Nvidia 驱动已安装,<code>nvidia-smi</code> 输出正常</li>\n<li>KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显</li>\n<li>导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象</li>\n</ul>\n<p>这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。</p>\n<hr>\n<h2 id=\"配置-X11-下的-Nvidia-显卡优先\"><a href=\"#配置-X11-下的-Nvidia-显卡优先\" class=\"headerlink\" title=\"配置 X11 下的 Nvidia 显卡优先\"></a>配置 X11 下的 Nvidia 显卡优先</h2><p>可以通过配置 <code>/etc/X11/xorg.conf</code> 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo nvidia-xconfig --prime<br></code></pre></td></tr></table></figure>\n\n<p>该命令会根据硬件情况自动生成配置文件。执行后 <strong>重新登录会话</strong> 即可生效(即使是 Wayland 用户也可以执行一次此命令)。</p>\n<p><img src=\"/images/1613f5602b203b38230f19699deb0219454454985.png\" alt=\"X11 Nvidia配置\"></p>\n<hr>\n<h2 id=\"配置-Wayland-下的-Nvidia-显卡优先\"><a href=\"#配置-Wayland-下的-Nvidia-显卡优先\" class=\"headerlink\" title=\"配置 Wayland 下的 Nvidia 显卡优先\"></a>配置 Wayland 下的 Nvidia 显卡优先</h2><p>在 Wayland 下优先启用 Nvidia 显卡的步骤如下:</p>\n<ol>\n<li><p>编辑 <strong>GRUB 配置</strong>文件:</p>\n<p>打开 <code>/etc/default/grub</code> 文件,在 <code>GRUB_CMDLINE_LINUX_DEFAULT=""</code> 中添加 <code>nvidia_drm.modeset=1</code>:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">GRUB_CMDLINE_LINUX_DEFAULT=<span class=\"hljs-string\">"nvidia_drm.modeset=1"</span><br></code></pre></td></tr></table></figure>\n</li>\n<li><p>重新生成 grub 配置:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo grub-mkconfig -o /boot/grub/grub.cfg<br></code></pre></td></tr></table></figure>\n</li>\n<li><p>配置 <strong>Plasma 环境</strong>文件:</p>\n<p>在 <code>~/.config/plasma-workspace/env/nvidia.sh</code> 中写入以下内容:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\"><span class=\"hljs-meta\">#!/bin/bash </span><br><span class=\"hljs-built_in\">export</span> __NV_PRIME_RENDER_OFFLOAD=1 <br><span class=\"hljs-built_in\">export</span> __GLX_VENDOR_LIBRARY_NAME=nvidia<br></code></pre></td></tr></table></figure>\n</li>\n<li><p>保存并重启电脑,即可生效。</p>\n</li>\n</ol>\n<p><img src=\"/images/b2054bbaf6197624d38cc2007d885fd1454454985.png\" alt=\"Wayland Nvidia配置\"></p>\n<hr>\n<h2 id=\"I-N-混合显卡方案\"><a href=\"#I-N-混合显卡方案\" class=\"headerlink\" title=\"I+N 混合显卡方案\"></a>I+N 混合显卡方案</h2><p>如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。</p>\n<h3 id=\"配置步骤\"><a href=\"#配置步骤\" class=\"headerlink\" title=\"配置步骤\"></a>配置步骤</h3><ol>\n<li><p>打开程序的 <code>.desktop</code> 启动文件:</p>\n<p>位置可能在 <code>/usr/share/applications</code> 或 <code>~/.local/share/applications</code> 中。</p>\n</li>\n<li><p>在 <code>Exec=</code> 后添加 <code>prime-run</code> 参数。例如:</p>\n<figure class=\"highlight text\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs text\">Exec=prime-run <程序启动命令><br></code></pre></td></tr></table></figure>\n\n<p><img src=\"/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png\" alt=\"混合显卡配置示意图\"></p>\n</li>\n</ol>\n<h3 id=\"Vim-快捷配置\"><a href=\"#Vim-快捷配置\" class=\"headerlink\" title=\"Vim 快捷配置\"></a>Vim 快捷配置</h3><p>如果使用 Vim,可以使用以下快捷键快速批量替换 <code>Exec=</code> 为 <code>Exec=prime-run</code>:</p>\n<figure class=\"highlight vim\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs vim\">v -> G -> :s/Exec=/Exec=prime-run /g Enter -> :<span class=\"hljs-keyword\">wq</span> Enter<br></code></pre></td></tr></table></figure>\n\n<hr>\n<h2 id=\"让-Plasma-桌面也使用独显\"><a href=\"#让-Plasma-桌面也使用独显\" class=\"headerlink\" title=\"让 Plasma 桌面也使用独显\"></a>让 Plasma 桌面也使用独显</h2><p>如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\"><span class=\"hljs-meta\">#!/bin/bash </span><br><span class=\"hljs-built_in\">export</span> __GLX_VENDOR_LIBRARY_NAME=nvidia<br></code></pre></td></tr></table></figure>\n\n<p>这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。</p>\n<hr>\n<p>希望以上经验能为有此需求的用户提供参考帮助。</p>\n","excerpt":"","more":"<p>本文将介绍在 <strong>X11</strong> 和 <strong>Wayland</strong> 两种会话下,如何在 KDE Plasma 中优先启用 Nvidia 独立显卡,并提供 I+N 混合显卡的配置方案。<strong>首先,请确保您已经正确安装了 Nvidia 驱动</strong>(如果非 Mainline 内核,请使用 <code>nvidia-dkms</code> 或 <code>nvidia-open-dkms</code> 版本)。</p>\n<p><img src=\"/images/5364bba6d035326e82c53504dd53e7c2454454985.png\" alt=\"Nvidia设置示意图\"></p>\n<h3 id=\"适用系统\"><a href=\"#适用系统\" class=\"headerlink\" title=\"适用系统\"></a>适用系统</h3><p>对于 <strong>CachyOS</strong> 或 <strong>EndeavourOS</strong> 等 Arch Linux 衍生版,这些配置大多开箱即用,但对于刚刚入坑 Arch Linux 且使用 KDE 的新手可能会遇到这样的问题:</p>\n<ul>\n<li>Nvidia 驱动已安装,<code>nvidia-smi</code> 输出正常</li>\n<li>KDE 系统信息显示仍在使用核显,程序运行时也优先使用核显</li>\n<li>导致某些应用(如浏览器、Blender)可能出现卡顿或掉帧现象</li>\n</ul>\n<p>这是因为 Arch Linux 的高自定义性,许多功能需要用户手动配置。以下是详细的解决方案。</p>\n<hr>\n<h2 id=\"配置-X11-下的-Nvidia-显卡优先\"><a href=\"#配置-X11-下的-Nvidia-显卡优先\" class=\"headerlink\" title=\"配置 X11 下的 Nvidia 显卡优先\"></a>配置 X11 下的 Nvidia 显卡优先</h2><p>可以通过配置 <code>/etc/X11/xorg.conf</code> 实现 Nvidia 独显输出。幸运的是,Nvidia 提供了自动生成配置文件的工具,用户无需手动编写:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo nvidia-xconfig --prime<br></code></pre></td></tr></table></figure>\n\n<p>该命令会根据硬件情况自动生成配置文件。执行后 <strong>重新登录会话</strong> 即可生效(即使是 Wayland 用户也可以执行一次此命令)。</p>\n<p><img src=\"/images/1613f5602b203b38230f19699deb0219454454985.png\" alt=\"X11 Nvidia配置\"></p>\n<hr>\n<h2 id=\"配置-Wayland-下的-Nvidia-显卡优先\"><a href=\"#配置-Wayland-下的-Nvidia-显卡优先\" class=\"headerlink\" title=\"配置 Wayland 下的 Nvidia 显卡优先\"></a>配置 Wayland 下的 Nvidia 显卡优先</h2><p>在 Wayland 下优先启用 Nvidia 显卡的步骤如下:</p>\n<ol>\n<li><p>编辑 <strong>GRUB 配置</strong>文件:</p>\n<p>打开 <code>/etc/default/grub</code> 文件,在 <code>GRUB_CMDLINE_LINUX_DEFAULT=""</code> 中添加 <code>nvidia_drm.modeset=1</code>:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">GRUB_CMDLINE_LINUX_DEFAULT=<span class=\"hljs-string\">"nvidia_drm.modeset=1"</span><br></code></pre></td></tr></table></figure>\n</li>\n<li><p>重新生成 grub 配置:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo grub-mkconfig -o /boot/grub/grub.cfg<br></code></pre></td></tr></table></figure>\n</li>\n<li><p>配置 <strong>Plasma 环境</strong>文件:</p>\n<p>在 <code>~/.config/plasma-workspace/env/nvidia.sh</code> 中写入以下内容:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\"><span class=\"hljs-meta\">#!/bin/bash </span><br><span class=\"hljs-built_in\">export</span> __NV_PRIME_RENDER_OFFLOAD=1 <br><span class=\"hljs-built_in\">export</span> __GLX_VENDOR_LIBRARY_NAME=nvidia<br></code></pre></td></tr></table></figure>\n</li>\n<li><p>保存并重启电脑,即可生效。</p>\n</li>\n</ol>\n<p><img src=\"/images/b2054bbaf6197624d38cc2007d885fd1454454985.png\" alt=\"Wayland Nvidia配置\"></p>\n<hr>\n<h2 id=\"I-N-混合显卡方案\"><a href=\"#I-N-混合显卡方案\" class=\"headerlink\" title=\"I+N 混合显卡方案\"></a>I+N 混合显卡方案</h2><p>如果不希望全局启用独显,可以选择让大部分程序默认使用核显,而少数高性能需求的程序使用独显。这种方法能有效节省功耗,同时将独显资源集中分配给需要的程序(如 Steam 游戏、Blender 等)。缺点是每个程序需要手动配置启动项。</p>\n<h3 id=\"配置步骤\"><a href=\"#配置步骤\" class=\"headerlink\" title=\"配置步骤\"></a>配置步骤</h3><ol>\n<li><p>打开程序的 <code>.desktop</code> 启动文件:</p>\n<p>位置可能在 <code>/usr/share/applications</code> 或 <code>~/.local/share/applications</code> 中。</p>\n</li>\n<li><p>在 <code>Exec=</code> 后添加 <code>prime-run</code> 参数。例如:</p>\n<figure class=\"highlight text\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs text\">Exec=prime-run <程序启动命令><br></code></pre></td></tr></table></figure>\n\n<p><img src=\"/images/71a5357ef4bd808b10429bc2ea46cb6f454454985.png\" alt=\"混合显卡配置示意图\"></p>\n</li>\n</ol>\n<h3 id=\"Vim-快捷配置\"><a href=\"#Vim-快捷配置\" class=\"headerlink\" title=\"Vim 快捷配置\"></a>Vim 快捷配置</h3><p>如果使用 Vim,可以使用以下快捷键快速批量替换 <code>Exec=</code> 为 <code>Exec=prime-run</code>:</p>\n<figure class=\"highlight vim\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs vim\">v -> G -> :s/Exec=/Exec=prime-run /g Enter -> :<span class=\"hljs-keyword\">wq</span> Enter<br></code></pre></td></tr></table></figure>\n\n<hr>\n<h2 id=\"让-Plasma-桌面也使用独显\"><a href=\"#让-Plasma-桌面也使用独显\" class=\"headerlink\" title=\"让 Plasma 桌面也使用独显\"></a>让 Plasma 桌面也使用独显</h2><p>如果希望 Plasma 桌面也通过独显运行,可以修改 Wayland 配置文件并删除第二行:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\"><span class=\"hljs-meta\">#!/bin/bash </span><br><span class=\"hljs-built_in\">export</span> __GLX_VENDOR_LIBRARY_NAME=nvidia<br></code></pre></td></tr></table></figure>\n\n<p>这样 Plasma 桌面会通过独显启动,其他程序则默认使用核显。</p>\n<hr>\n<p>希望以上经验能为有此需求的用户提供参考帮助。</p>\n"},{"title":"Archlinux KDE体验优化总结","date":"2025-02-02T10:43:26.000Z","_content":"\n打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验\n\n本文章长期更新\n\n------\n\n## 软件优化\n\n## 快捷键设置\n\n## \n","source":"_posts/archlinux-optimization.md","raw":"---\ntitle: Archlinux KDE体验优化总结\ndate: 2025-02-02 18:43:26\ntags: [技术分享]\n---\n\n打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验\n\n本文章长期更新\n\n------\n\n## 软件优化\n\n## 快捷键设置\n\n## \n","slug":"archlinux-optimization","published":1,"updated":"2025-02-23T14:29:02.471Z","comments":1,"layout":"post","photos":[],"_id":"cm7jziodu000pwi2b49gyhjcz","content":"<p>打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验</p>\n<p>本文章长期更新</p>\n<hr>\n<h2 id=\"软件优化\"><a href=\"#软件优化\" class=\"headerlink\" title=\"软件优化\"></a>软件优化</h2><h2 id=\"快捷键设置\"><a href=\"#快捷键设置\" class=\"headerlink\" title=\"快捷键设置\"></a>快捷键设置</h2><h2 id=\"\"><a href=\"#\" class=\"headerlink\" title=\"\"></a></h2>","excerpt":"","more":"<p>打算开一个坑记录这么久以来的Archlinux系统性能和操作体验优化经验</p>\n<p>本文章长期更新</p>\n<hr>\n<h2 id=\"软件优化\"><a href=\"#软件优化\" class=\"headerlink\" title=\"软件优化\"></a>软件优化</h2><h2 id=\"快捷键设置\"><a href=\"#快捷键设置\" class=\"headerlink\" title=\"快捷键设置\"></a>快捷键设置</h2><h2 id=\"\"><a href=\"#\" class=\"headerlink\" title=\"\"></a></h2>"},{"title":"使用Clonezilla备份和克隆系统","date":"2025-02-23T13:40:03.000Z","_content":"\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\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":"cm7jziodu000swi2ba2br64lz","content":"<p><img src=\"/images/clonezilla.png\" alt=\"Clonezilla官网\"><br><a href=\"https://clonezilla.org/\">Clonezilla</a>是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。</p>\n<hr>\n<h3 id=\"零-事前准备:\"><a href=\"#零-事前准备:\" class=\"headerlink\" title=\"零.事前准备:\"></a><strong>零.事前准备</strong>:</h3><ul>\n<li>下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。</li>\n<li>准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。</li>\n</ul>\n<h3 id=\"一-备份镜像到硬盘(Device-to-Image)\"><a href=\"#一-备份镜像到硬盘(Device-to-Image)\" class=\"headerlink\" title=\"一.备份镜像到硬盘(Device-to-Image)\"></a><strong>一.备份镜像到硬盘(Device-to-Image)</strong></h3><p>这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。</p>\n<h4 id=\"步骤说明:\"><a href=\"#步骤说明:\" class=\"headerlink\" title=\"步骤说明:\"></a><strong>步骤说明</strong>:</h4><ol start=\"2\">\n<li><p><strong>启动Clonezilla</strong>:</p>\n<ul>\n<li>插入U盘,重启电脑并从U盘启动。</li>\n<li>选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。</li>\n</ul>\n</li>\n<li><p><strong>选择备份模式</strong>:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs plaintext\">Choose mode: 选择 "device-image"(设备到镜像)<br>Mount storage media: 选择 "local_dev"(本地存储设备)<br></code></pre></td></tr></table></figure>\n<ul>\n<li>按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 <code>/dev/sdb1</code>)。</li>\n</ul>\n</li>\n<li><p><strong>配置备份参数</strong>:</p>\n<ul>\n<li><strong>源硬盘</strong>:选择需要备份的硬盘(如 <code>/dev/sda</code>)。</li>\n<li><strong>镜像存储路径</strong>:指定目标位置(如外置硬盘的挂载目录)。</li>\n<li><strong>镜像名称</strong>:自定义名称(如 <code>2025-img-rockylinux-2-21</code>)。</li>\n<li><strong>压缩选项</strong>:默认即可,支持并行压缩加速。</li>\n<li><strong>镜像分割</strong>:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。</li>\n</ul>\n</li>\n<li><p><strong>确认操作</strong>:</p>\n<ul>\n<li>检查提示信息,输入 <code>y</code> 开始备份。</li>\n<li>完成后关机或重启。</li>\n</ul>\n</li>\n<li><p><strong>镜像还原</strong>:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。</p>\n</li>\n</ol>\n<hr>\n<h3 id=\"二、直接克隆硬盘(Device-to-Device)\"><a href=\"#二、直接克隆硬盘(Device-to-Device)\" class=\"headerlink\" title=\"二、直接克隆硬盘(Device-to-Device)\"></a><strong>二、直接克隆硬盘(Device-to-Device)</strong></h3><p>将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。</p>\n<h4 id=\"步骤说明:-1\"><a href=\"#步骤说明:-1\" class=\"headerlink\" title=\"步骤说明:\"></a><strong>步骤说明</strong>:</h4><ol>\n<li><p><strong>准备工作</strong>:</p>\n<ul>\n<li>连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)</li>\n<li><strong>警告</strong>:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!</li>\n</ul>\n</li>\n<li><p><strong>启动Clonezilla</strong>:</p>\n<ul>\n<li>同上,从U盘启动进入Clonezilla界面。</li>\n</ul>\n</li>\n<li><p><strong>选择克隆模式</strong>:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs plaintext\">Choose mode: 选择 "device-device"(设备到设备)<br></code></pre></td></tr></table></figure>\n</li>\n<li><p><strong>选择硬盘</strong>:</p>\n<ul>\n<li><strong>母碟硬盘</strong>:选择原始硬盘(如 <code>/dev/sda</code>)。</li>\n<li><strong>目标硬盘</strong>:选择新硬盘(如 <code>/dev/sdb</code>)。</li>\n</ul>\n</li>\n<li><p><strong>克隆选项</strong>:<br> 需要进入专家模式才能看到,一般直接新手模式默认即可。</p>\n</li>\n<li><p><strong>执行克隆</strong>:</p>\n<ul>\n<li>确认提示信息后输入 <code>y</code>,等待完成。</li>\n<li>克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。</li>\n</ul>\n</li>\n</ol>\n<hr>\n<h3 id=\"两种模式对比:\"><a href=\"#两种模式对比:\" class=\"headerlink\" title=\"两种模式对比:\"></a><strong>两种模式对比</strong>:</h3><table>\n<thead>\n<tr>\n<th><strong>模式</strong></th>\n<th>特点</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>备份镜像</td>\n<td>方便多机部署也可以用于留档</td>\n</tr>\n<tr>\n<td>直接克隆</td>\n<td>换硬盘快速迁移无需恢复过程</td>\n</tr>\n</tbody></table>\n<hr>\n<h3 id=\"Btrfs务必注意:\"><a href=\"#Btrfs务必注意:\" class=\"headerlink\" title=\"Btrfs务必注意:\"></a><strong>Btrfs务必注意</strong>:</h3><p>对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行<code>sudo btrfs balance start --full-balance /</code>来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。</p>\n","excerpt":"","more":"<p><img src=\"/images/clonezilla.png\" alt=\"Clonezilla官网\"><br><a href=\"https://clonezilla.org/\">Clonezilla</a>是一款非常好用的系统迁移工具,本文将介绍其基本用法(不包含网络迁移及Clonezilla服务器等进阶内容)以及在克隆Btrfs磁盘时遇到的问题解法。</p>\n<hr>\n<h3 id=\"零-事前准备:\"><a href=\"#零-事前准备:\" class=\"headerlink\" title=\"零.事前准备:\"></a><strong>零.事前准备</strong>:</h3><ul>\n<li>下载Clonezilla Live镜像(ISO),制作启动U盘(有手就行)。</li>\n<li>准备目标存储设备(如U盘,需要迁移的新硬盘等),确保有足够空间(建议大于源硬盘已用空间的1.2倍)。</li>\n</ul>\n<h3 id=\"一-备份镜像到硬盘(Device-to-Image)\"><a href=\"#一-备份镜像到硬盘(Device-to-Image)\" class=\"headerlink\" title=\"一.备份镜像到硬盘(Device-to-Image)\"></a><strong>一.备份镜像到硬盘(Device-to-Image)</strong></h3><p>这个模式可以将硬盘完整备份为一个镜像文件(可保存到本地硬盘、外置硬盘或网络存储)方便多机部署。注意如果只是将一个硬盘的系统完全克隆到新盘可以跳过此部分。</p>\n<h4 id=\"步骤说明:\"><a href=\"#步骤说明:\" class=\"headerlink\" title=\"步骤说明:\"></a><strong>步骤说明</strong>:</h4><ol start=\"2\">\n<li><p><strong>启动Clonezilla</strong>:</p>\n<ul>\n<li>插入U盘,重启电脑并从U盘启动。</li>\n<li>选择默认选项(语言,键盘布局,Beginner模式)进入Clonezilla的TUI界面。</li>\n</ul>\n</li>\n<li><p><strong>选择备份模式</strong>:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs plaintext\">Choose mode: 选择 "device-image"(设备到镜像)<br>Mount storage media: 选择 "local_dev"(本地存储设备)<br></code></pre></td></tr></table></figure>\n<ul>\n<li>按提示挂载目标存储设备(注意这里选择的是你要存储镜像的设备且文件系统一般不限,如外置硬盘),确认路径(如 <code>/dev/sdb1</code>)。</li>\n</ul>\n</li>\n<li><p><strong>配置备份参数</strong>:</p>\n<ul>\n<li><strong>源硬盘</strong>:选择需要备份的硬盘(如 <code>/dev/sda</code>)。</li>\n<li><strong>镜像存储路径</strong>:指定目标位置(如外置硬盘的挂载目录)。</li>\n<li><strong>镜像名称</strong>:自定义名称(如 <code>2025-img-rockylinux-2-21</code>)。</li>\n<li><strong>压缩选项</strong>:默认即可,支持并行压缩加速。</li>\n<li><strong>镜像分割</strong>:若目标存储设备为FAT32格式(单文件最大4GB),选择自动分割。</li>\n</ul>\n</li>\n<li><p><strong>确认操作</strong>:</p>\n<ul>\n<li>检查提示信息,输入 <code>y</code> 开始备份。</li>\n<li>完成后关机或重启。</li>\n</ul>\n</li>\n<li><p><strong>镜像还原</strong>:和备份非常相似,只是选项换成restore to disk,顺着指引操作即可。</p>\n</li>\n</ol>\n<hr>\n<h3 id=\"二、直接克隆硬盘(Device-to-Device)\"><a href=\"#二、直接克隆硬盘(Device-to-Device)\" class=\"headerlink\" title=\"二、直接克隆硬盘(Device-to-Device)\"></a><strong>二、直接克隆硬盘(Device-to-Device)</strong></h3><p>将源硬盘完整克隆到目标硬盘(适合硬盘升级或快速迁移),比如笔者最近白嫖了一个三星的2T硬盘直接把原来512G硬盘里的CachyOS无损迁移了进去。</p>\n<h4 id=\"步骤说明:-1\"><a href=\"#步骤说明:-1\" class=\"headerlink\" title=\"步骤说明:\"></a><strong>步骤说明</strong>:</h4><ol>\n<li><p><strong>准备工作</strong>:</p>\n<ul>\n<li>连接目标硬盘(需容量≥源硬盘已用空间,还原镜像操作也是如此,注意Clonezilla支持小分区到大分区迁移不支持大分区到小分区,后者出门右转Rsync)</li>\n<li><strong>警告</strong>:目标硬盘数据将被覆盖,操作前如有需要务必备份重要数据!</li>\n</ul>\n</li>\n<li><p><strong>启动Clonezilla</strong>:</p>\n<ul>\n<li>同上,从U盘启动进入Clonezilla界面。</li>\n</ul>\n</li>\n<li><p><strong>选择克隆模式</strong>:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs plaintext\">Choose mode: 选择 "device-device"(设备到设备)<br></code></pre></td></tr></table></figure>\n</li>\n<li><p><strong>选择硬盘</strong>:</p>\n<ul>\n<li><strong>母碟硬盘</strong>:选择原始硬盘(如 <code>/dev/sda</code>)。</li>\n<li><strong>目标硬盘</strong>:选择新硬盘(如 <code>/dev/sdb</code>)。</li>\n</ul>\n</li>\n<li><p><strong>克隆选项</strong>:<br> 需要进入专家模式才能看到,一般直接新手模式默认即可。</p>\n</li>\n<li><p><strong>执行克隆</strong>:</p>\n<ul>\n<li>确认提示信息后输入 <code>y</code>,等待完成。</li>\n<li>克隆结束后关机,移除旧硬盘并测试新硬盘(主要是查看能不能启动进入系统,若能进入一般不会有问题,而且一般都能进入因为Clonezilla是高精确的块对块克隆)。</li>\n</ul>\n</li>\n</ol>\n<hr>\n<h3 id=\"两种模式对比:\"><a href=\"#两种模式对比:\" class=\"headerlink\" title=\"两种模式对比:\"></a><strong>两种模式对比</strong>:</h3><table>\n<thead>\n<tr>\n<th><strong>模式</strong></th>\n<th>特点</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>备份镜像</td>\n<td>方便多机部署也可以用于留档</td>\n</tr>\n<tr>\n<td>直接克隆</td>\n<td>换硬盘快速迁移无需恢复过程</td>\n</tr>\n</tbody></table>\n<hr>\n<h3 id=\"Btrfs务必注意:\"><a href=\"#Btrfs务必注意:\" class=\"headerlink\" title=\"Btrfs务必注意:\"></a><strong>Btrfs务必注意</strong>:</h3><p>对Btrfs直接进行Clonezilla克隆大概率会碰到一个边界错误,这是由于Btrfs本身使用一段时间后碎片化存储导致的,你需要执行<code>sudo btrfs balance start --full-balance /</code>来进行整理,但是这也算是一个风险操作要确保完整执行不能在执行时意外中断导致文件系统出错,并且在后续克隆时不能使用新手模式要进入专家模式勾选-p1支持所有文件系统但是效率降低的选项来确保顺利克隆(未勾选此选项可能导致文件系统无法识别的错误),其他步骤参照前文即可。</p>\n"},{"title":"时隔一年再次拿起数位板能画出什么东西","date":"2024-11-04T15:47:54.000Z","_content":"\n如题,前段时间推完LOOPERS的时候有感而发对着画了张海报\n\n时隔一年,终于又拿起了数位板\n\n\n","source":"_posts/loopers.md","raw":"---\ntitle: 时隔一年再次拿起数位板能画出什么东西\ndate: 2024-11-04 23:47:54\ntags: [板绘, 生活]\n---\n\n如题,前段时间推完LOOPERS的时候有感而发对着画了张海报\n\n时隔一年,终于又拿起了数位板\n\n\n","slug":"loopers","published":1,"updated":"2025-02-23T14:27:46.748Z","comments":1,"layout":"post","photos":[],"_id":"cm7jziodv000vwi2baw0jbh0g","content":"<p>如题,前段时间推完LOOPERS的时候有感而发对着画了张海报</p>\n<p>时隔一年,终于又拿起了数位板</p>\n<p><img src=\"/images/20241027_222225.png\" alt=\"LOOPERS\" title=\"LOOPERS\"></p>\n","excerpt":"","more":"<p>如题,前段时间推完LOOPERS的时候有感而发对着画了张海报</p>\n<p>时隔一年,终于又拿起了数位板</p>\n<p><img src=\"/images/20241027_222225.png\" alt=\"LOOPERS\" title=\"LOOPERS\"></p>\n"},{"title":"愿指引明路的苍蓝星永远为你闪耀","date":"2024-11-11T13:46:49.000Z","_content":"使用东方Project软音源THFont简单重置的MHWI主题曲\n\n雄关漫道真如铁,而今迈步从头越\n\n{% raw %}\n<iframe src=\"//player.bilibili.com/player.html?bvid=BV1WymmYNEAk&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\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<iframe src=\"//player.bilibili.com/player.html?bvid=BV1WymmYNEAk&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\n{% endraw %}\n\n","slug":"mhwi","published":1,"updated":"2024-11-11T14:00:19.124Z","comments":1,"layout":"post","photos":[],"_id":"cm7jziodv000xwi2b6ebgcwqs","content":"<p>使用东方Project软音源THFont简单重置的MHWI主题曲</p>\n<p>雄关漫道真如铁,而今迈步从头越</p>\n\n<iframe src=\"//player.bilibili.com/player.html?bvid=BV1WymmYNEAk&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\n\n\n","excerpt":"","more":"<p>使用东方Project软音源THFont简单重置的MHWI主题曲</p>\n<p>雄关漫道真如铁,而今迈步从头越</p>\n\n<iframe src=\"//player.bilibili.com/player.html?bvid=BV1WymmYNEAk&page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\" width=\"100%\" height=\"500\"></iframe>\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\n - 结果没有明文密码无法直接秒掉第一问,可惜。\n - 但是找到`GenerateRandomString`函数可能与密码生成相关。\n\n#### **用`objdump`反汇编**\n```bash\nobjdump -d bomb_linux > bomb.asm\n```\n搜索`GenerateRandomString`和`phase_1`函数的汇编代码。\n ```assembly\n 401b53 <phase_1>:\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 <GenerateRandomString> # 调用密码生成函数\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 <string_compare> # 调用字符串比较函数\n 401b82: test %eax,%eax\n 401b84: je 401b8d <phase_1+0x3a>\n 401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹\n ```\n - `phase_1`调用`GenerateRandomString`生成一个字符串。\n - 用户输入的字符串需要与此生成的字符串完全匹配。\n\n---\n\n### **动态调试**\n\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 <phase_2>:\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 <GenerateRandomNumber>\n 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div>\n 401baf:\t48 83 f8 0f \tcmp $0xf,%rax\n 401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141>\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 <phase_2_0>\n 401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147>\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 <phase_2_1>\n 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147>\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\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 <phase_3_5>:\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 <phase_3_5+0x4c>\n 403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb>\n 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi\n 403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber>\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 <rand_div>\n 403064:\t48 39 c2 \tcmp %rax,%rdx\n 403067:\t74 05 \tje 40306e <phase_3_5+0x6d>\n 403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb>\n 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber>\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 <phase_3_5+0x16e>\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 <rand_div>\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 <GenerateRandomNumber>\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 <phase_3_5+0x180>\n 40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb>\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 <phase_4_01>:\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 <phase_4_01+0xa8> ; 失败则爆炸\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 <phase_4_01+0xad>\n 40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb>\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 <phase_4_01+0xbc> ; N > 1999?\n 40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb>\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 <func4_0> ; 返回值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 <GenerateRandomNumber> ; 生成0~14随机数\n 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引\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 <phase_4_01+0x108>\n 404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb>\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\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 <phase_secret>:\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 <puts@plt>\n 401aaa:\t90 \tnop\n 401aab:\tc9 \tleave\n 401aac:\tc3 \tret\n```\n注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在`phase_5`中设计指令时加一个要求跳转到`0x401a8b`即可。\n\n完结\n\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\n - 结果没有明文密码无法直接秒掉第一问,可惜。\n - 但是找到`GenerateRandomString`函数可能与密码生成相关。\n\n#### **用`objdump`反汇编**\n```bash\nobjdump -d bomb_linux > bomb.asm\n```\n搜索`GenerateRandomString`和`phase_1`函数的汇编代码。\n ```assembly\n 401b53 <phase_1>:\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 <GenerateRandomString> # 调用密码生成函数\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 <string_compare> # 调用字符串比较函数\n 401b82: test %eax,%eax\n 401b84: je 401b8d <phase_1+0x3a>\n 401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹\n ```\n - `phase_1`调用`GenerateRandomString`生成一个字符串。\n - 用户输入的字符串需要与此生成的字符串完全匹配。\n\n---\n\n### **动态调试**\n\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 <phase_2>:\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 <GenerateRandomNumber>\n 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div>\n 401baf:\t48 83 f8 0f \tcmp $0xf,%rax\n 401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141>\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 <phase_2_0>\n 401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147>\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 <phase_2_1>\n 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147>\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\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 <phase_3_5>:\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 <phase_3_5+0x4c>\n 403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb>\n 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi\n 403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber>\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 <rand_div>\n 403064:\t48 39 c2 \tcmp %rax,%rdx\n 403067:\t74 05 \tje 40306e <phase_3_5+0x6d>\n 403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb>\n 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi\n 403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber>\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 <phase_3_5+0x16e>\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 <rand_div>\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 <GenerateRandomNumber>\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 <phase_3_5+0x180>\n 40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb>\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 <phase_4_01>:\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 <phase_4_01+0xa8> ; 失败则爆炸\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 <phase_4_01+0xad>\n 40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb>\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 <phase_4_01+0xbc> ; N > 1999?\n 40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb>\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 <func4_0> ; 返回值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 <GenerateRandomNumber> ; 生成0~14随机数\n 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引\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 <phase_4_01+0x108>\n 404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb>\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\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 <phase_secret>:\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 <puts@plt>\n 401aaa:\t90 \tnop\n 401aab:\tc9 \tleave\n 401aac:\tc3 \tret\n```\n注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在`phase_5`中设计指令时加一个要求跳转到`0x401a8b`即可。\n\n完结\n\n","slug":"nudtbomblab","published":1,"updated":"2025-02-25T03:56:35.270Z","comments":1,"layout":"post","photos":[],"_id":"cm7jziodv0011wi2bauxoh2vo","content":"<p>这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。</p>\n<p>笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。</p>\n<h2 id=\"Phase-1\"><a href=\"#Phase-1\" class=\"headerlink\" title=\"Phase_1\"></a><strong>Phase_1</strong></h2><h3 id=\"静态分析\"><a href=\"#静态分析\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><h4 id=\"strings扫描\"><a href=\"#strings扫描\" class=\"headerlink\" title=\"strings扫描\"></a><strong><code>strings</code>扫描</strong></h4><figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">strings bomb_linux<br></code></pre></td></tr></table></figure>\n<p>先用strings寻找可能与<code>phase_1</code>相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。<br><img src=\"/images/phase1_strings.png\" alt=\"strings\"></p>\n<ul>\n<li>结果没有明文密码无法直接秒掉第一问,可惜。</li>\n<li>但是找到<code>GenerateRandomString</code>函数可能与密码生成相关。</li>\n</ul>\n<h4 id=\"用objdump反汇编\"><a href=\"#用objdump反汇编\" class=\"headerlink\" title=\"用objdump反汇编\"></a><strong>用<code>objdump</code>反汇编</strong></h4><figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">objdump -d bomb_linux > bomb.asm<br></code></pre></td></tr></table></figure>\n<p>搜索<code>GenerateRandomString</code>和<code>phase_1</code>函数的汇编代码。<br> <figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">401b53 <phase_1>:<br> 401b53: endbr64<br> 401b57: push %rbp<br> 401b58: mov %rsp,%rbp<br> 401b5b: sub $0x20,%rsp<br> 401b5f: mov %rdi,-0x18(%rbp)<br> 401b63: lea -0xb(%rbp),%rax<br> 401b67: mov %rax,%rdi<br> 401b6a: callq 401ac1 <GenerateRandomString> # 调用密码生成函数<br> 401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置<br> 401b73: mov -0x18(%rbp),%rax<br> 401b77: mov %rdx,%rsi<br> 401b7a: mov %rax,%rdi<br> 401b7d: callq 401c0c <string_compare> # 调用字符串比较函数<br> 401b82: test %eax,%eax<br> 401b84: je 401b8d <phase_1+0x3a><br> 401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹<br></code></pre></td></tr></table></figure></p>\n<ul>\n<li><code>phase_1</code>调用<code>GenerateRandomString</code>生成一个字符串。</li>\n<li>用户输入的字符串需要与此生成的字符串完全匹配。</li>\n</ul>\n<hr>\n<h3 id=\"动态调试\"><a href=\"#动态调试\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p><img src=\"/images/phase1.png\" alt=\"phase_1\"><br>下面是phase_1求解的完整流程:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs lldb\">lldb bomb_linux <你的学号后六位><br>(lldb) b phase_1 # 在phase_1入口断点<br>(lldb) run # 从入口开始执行<br>请输入第1级的密码:114514 # 随便输入触发断点<br>(lldb) b 0x401b6f # 在GenerateRandomString返回后断点<br>(lldb) continue # 继续执行<br>(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)<br>0x7fffffffdaf5: "mJHurpQZtY" # 轻松拿下,这里是根据学号伪随机生成的哦<br></code></pre></td></tr></table></figure>\n<p>将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。</p>\n<hr>\n<h2 id=\"Phase-2\"><a href=\"#Phase-2\" class=\"headerlink\" title=\"Phase_2\"></a><strong>Phase_2</strong></h2><h3 id=\"静态分析-1\"><a href=\"#静态分析-1\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><p>这道题目还是比较一目了然的,观察<code>phase_2</code>代码不难发现其实构建了一张跳转表:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000401b8e <phase_2>:<br> 401b8e:\tf3 0f 1e fa \tendbr64<br> 401b92:\t55 \tpush %rbp<br> 401b93:\t48 89 e5 \tmov %rsp,%rbp<br> 401b96:\t48 83 ec 10 \tsub $0x10,%rsp<br> 401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)<br> 401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi<br> 401ba3:\te8 05 fb ff ff \tcall 4016ad <GenerateRandomNumber><br> 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div><br> 401baf:\t48 83 f8 0f \tcmp $0xf,%rax<br> 401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141><br> 401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx<br> 401bc0:\t00 <br> 401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614><br> 401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax<br> 401bcb:\t48 98 \tcltq<br> 401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614><br> 401bd4:\t48 01 d0 \tadd %rdx,%rax<br> 401bd7:\t3e ff e0 \tnotrack jmp *%rax<br> 401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax<br> 401bde:\t48 89 c7 \tmov %rax,%rdi<br> 401be1:\te8 f2 00 00 00 \tcall 401cd8 <phase_2_0><br> 401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147><br> 401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax<br> 401bef:\t48 89 c7 \tmov %rax,%rdi<br> 401bf2:\te8 8b 01 00 00 \tcall 401d82 <phase_2_1><br> 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147><br> 401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax<br> 401c00:\t48 89 c7 \tmov %rax,%rdi<br> ...<br></code></pre></td></tr></table></figure>\n<p>这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是<code>GenerateRandomNumber</code>这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。</p>\n<hr>\n<h3 id=\"动态调试-1\"><a href=\"#动态调试-1\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p>理解原理就没什么难度了,自己找几个断点打好然后关注一下<code>rand_div</code>的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向<code>phase_2_14</code>跳转:<br><img src=\"/images/phase_2_14.png\" alt=\"phase_2_14\"></p>\n<p>而除了<code>phase_2_14</code>还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。</p>\n<hr>\n<h2 id=\"Phase-3\"><a href=\"#Phase-3\" class=\"headerlink\" title=\"Phase_3\"></a><strong>Phase_3</strong></h2><h3 id=\"静态分析-2\"><a href=\"#静态分析-2\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><p>和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi</p>\n<p>本体其实没有什么好说的,这里我跳转的方向是<code>Phase_3_5</code>简要解释一下可供参考:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br><span class=\"line\">31</span><br><span class=\"line\">32</span><br><span class=\"line\">33</span><br><span class=\"line\">34</span><br><span class=\"line\">35</span><br><span class=\"line\">36</span><br><span class=\"line\">37</span><br><span class=\"line\">38</span><br><span class=\"line\">39</span><br><span class=\"line\">40</span><br><span class=\"line\">41</span><br><span class=\"line\">42</span><br><span class=\"line\">43</span><br><span class=\"line\">44</span><br><span class=\"line\">45</span><br><span class=\"line\">46</span><br><span class=\"line\">47</span><br><span class=\"line\">48</span><br><span class=\"line\">49</span><br><span class=\"line\">50</span><br><span class=\"line\">51</span><br><span class=\"line\">52</span><br><span class=\"line\">53</span><br><span class=\"line\">54</span><br><span class=\"line\">55</span><br><span class=\"line\">56</span><br><span class=\"line\">57</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000403001 <phase_3_5>:<br> 403001:\tf3 0f 1e fa \tendbr64<br> 403005:\t55 \tpush %rbp<br> 403006:\t48 89 e5 \tmov %rsp,%rbp<br> 403009:\t48 83 ec 20 \tsub $0x20,%rsp<br> 40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)<br> 403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)<br> 403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)<br> 40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx<br> 403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx<br> 403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax<br> 40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c><br> 403032:\t48 89 c7 \tmov %rax,%rdi<br> 403035:\tb8 00 00 00 00 \tmov $0x0,%eax<br> 40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt><br> 40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)<br> 403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)<br> 403046:\t7f 05 \tjg 40304d <phase_3_5+0x4c><br> 403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb><br> 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi<br> 403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber><br> 403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax<br> 40305a:\t48 63 d0 \tmovslq %eax,%rdx<br> 40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 <rand_div><br> 403064:\t48 39 c2 \tcmp %rax,%rdx<br> 403067:\t74 05 \tje 40306e <phase_3_5+0x6d><br> 403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb><br> 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi<br> 403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber><br> 403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax<br> 40307b:\t83 f8 07 \tcmp $0x7,%eax<br> 40307e:\t0f 87 eb 00 00 00 \tja 40316f <phase_3_5+0x16e><br> 403084:\t89 c0 \tmov %eax,%eax<br> 403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx<br> 40308d:\t00 <br> 40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734><br> 403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax<br> 403098:\t48 98 \tcltq<br> 40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734><br> 4030a1:\t48 01 d0 \tadd %rdx,%rax<br> 4030a4:\t3e ff e0 \tnotrack jmp *%rax<br> 4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 <rand_div><br> 4030ae:\t89 c2 \tmov %eax,%edx<br> 4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax<br> 4030b3:\t01 d0 \tadd %edx,%eax<br> 4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)<br> 4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi<br> 4030bd:\te8 eb e5 ff ff \tcall 4016ad <GenerateRandomNumber><br> ...<br> 403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax<br> 403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里<br> 40317a:\t74 05 \tje 403181 <phase_3_5+0x180><br> 40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb><br> 403181:\t90 \tnop<br> 403182:\tc9 \tleave<br> 403183:\tc3 \tret<br><br></code></pre></td></tr></table></figure>\n<p>看起来一大堆很吓人对不对?实际上确实很吓人。</p>\n<p>但是发现其中玄机后其实简单的没边,最终答案就藏在<code>0x403177</code>里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接<code>run</code>一下重开qwq)。</p>\n<hr>\n<h3 id=\"动态调试-2\"><a href=\"#动态调试-2\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p>阅读<code>Phase_3_5</code>发现这一关其实需要两个输入,并且第一个输入必须是<code>rand_div</code>,这里建议通过<code>si</code>单步执行监控好<code>rand_div</code>值变化,确定正确结果后使用<code>run</code>重开正确输入第一个密码后才能进行下一步求解:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs lldb\">(lldb) si<br>Process 13376 stopped<br>* thread #1, name = 'bomb_linux', stop reason = instruction step into<br> frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377<br>bomb_linux`phase_3_5:<br>-> 0x40317a <+377>: je 0x403181 ; <+384><br> 0x40317c <+379>: callq 0x405bf6 ; explode_bomb<br> 0x403181 <+384>: nop<br> 0x403182 <+385>: leave<br>(lldb) x/wx $rbp-0x4<br>0x7fffffffdb0c: 0xffffffd7<br></code></pre></td></tr></table></figure>\n<p>例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。</p>\n<hr>\n<h2 id=\"Phase-4\"><a href=\"#Phase-4\" class=\"headerlink\" title=\"Phase_4\"></a><strong>Phase_4</strong></h2><h3 id=\"静态分析-3\"><a href=\"#静态分析-3\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><p>本题依旧开局跳转,笔者的跳转方向是<code>phase_4_01</code>,如何跳转不再强调关注<code>rand_div</code>的值即可,下面请D指导解读一下<code>phase_4_01</code>的内容:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br><span class=\"line\">31</span><br><span class=\"line\">32</span><br><span class=\"line\">33</span><br><span class=\"line\">34</span><br><span class=\"line\">35</span><br><span class=\"line\">36</span><br><span class=\"line\">37</span><br><span class=\"line\">38</span><br><span class=\"line\">39</span><br><span class=\"line\">40</span><br><span class=\"line\">41</span><br><span class=\"line\">42</span><br><span class=\"line\">43</span><br><span class=\"line\">44</span><br><span class=\"line\">45</span><br><span class=\"line\">46</span><br><span class=\"line\">47</span><br><span class=\"line\">48</span><br><span class=\"line\">49</span><br><span class=\"line\">50</span><br><span class=\"line\">51</span><br><span class=\"line\">52</span><br><span class=\"line\">53</span><br><span class=\"line\">54</span><br><span class=\"line\">55</span><br><span class=\"line\">56</span><br><span class=\"line\">57</span><br><span class=\"line\">58</span><br><span class=\"line\">59</span><br><span class=\"line\">60</span><br><span class=\"line\">61</span><br><span class=\"line\">62</span><br><span class=\"line\">63</span><br><span class=\"line\">64</span><br><span class=\"line\">65</span><br><span class=\"line\">66</span><br><span class=\"line\">67</span><br><span class=\"line\">68</span><br><span class=\"line\">69</span><br><span class=\"line\">70</span><br><span class=\"line\">71</span><br><span class=\"line\">72</span><br><span class=\"line\">73</span><br><span class=\"line\">74</span><br><span class=\"line\">75</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000404895 <phase_4_01>:<br> ; 函数入口,初始化栈帧<br> 404895:\tf3 0f 1e fa \tendbr64 <br> 404899:\t55 \tpush %rbp<br> 40489a:\t48 89 e5 \tmov %rsp,%rbp<br> 40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间<br><br> ; 初始化斐波那契数组(F(10)~F(24)的十六进制值)<br> 4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针<br> 4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55<br> 4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89<br> 4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144<br> 4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233<br> 4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377<br> 4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610<br> 4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987<br> 4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597<br> 4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584<br> 4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181<br> 4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765<br> 4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946<br> 4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711<br> 404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657<br> 404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368<br><br> ; 读取输入到局部变量(格式为"%d")<br> 40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址<br> 404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串<br> 404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串"%d"<br> 40491d:\t48 89 ce \tmov %rcx,%rsi<br> 404920:\t48 89 c7 \tmov %rax,%rdi<br> 404923:\tb8 00 00 00 00 \tmov $0x0,%eax<br> 404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt><br><br> ; 验证输入有效性(必须为1个正数)<br> 40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值<br> 404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数<br> 404934:\t75 07 \tjne 40493d <phase_4_01+0xa8> ; 失败则爆炸<br> 404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N<br> 404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0<br> 40493b:\t7f 05 \tjg 404942 <phase_4_01+0xad><br> 40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb><br><br> ; 检查输入值上限(必须 > 1999)<br> 404942:\t8b 45 ac \tmov -0x54(%rbp),%eax <br> 404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制<br> 40494a:\t7f 05 \tjg 404951 <phase_4_01+0xbc> ; N > 1999?<br> 40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb><br><br> ; 计算 N/2000(通过定点数乘法优化)<br> 404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N<br> 404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展<br> 404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)<br> 40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位<br> 404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000<br> 404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展<br> 404968:\t89 c1 \tmov %eax,%ecx <br> 40496a:\t89 d0 \tmov %edx,%eax <br> 40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况<br> 40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000<br><br> ; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列<br> 404971:\t8b 45 ac \tmov -0x54(%rbp),%eax <br> 404974:\t89 c7 \tmov %eax,%edi ; 参数k<br> 404976:\te8 ce fd ff ff \tcall 404749 <func4_0> ; 返回值eax=F(k+1)<br> 40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果<br><br> ; 生成随机索引并验证结果<br> 40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15<br> 404983:\te8 25 cd ff ff \tcall 4016ad <GenerateRandomNumber> ; 生成0~14随机数<br> 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引<br> 40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值<br> 404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?<br> 404996:\t74 05 \tje 40499d <phase_4_01+0x108><br> 404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb><br></code></pre></td></tr></table></figure>\n<p>所以相对还是很明了的,依旧是关注<code>rand_div</code>。</p>\n<h3 id=\"动态调试-3\"><a href=\"#动态调试-3\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p>先找出<code>rand_div</code>在最后判断前的取值,比如我下面的0xa:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs lldb\">(lldb) si<br>Process 27027 stopped<br>* thread #1, name = 'bomb_linux', stop reason = instruction step into<br> frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108<br>bomb_linux`GenerateRandomNumber:<br>-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div<br> 0x401720 <+115>: jmp 0x401723 ; <+118><br> 0x401722 <+117>: nop<br> 0x401723 <+118>: popq %rbp<br>(lldb) si<br>Process 27027 stopped<br>* thread #1, name = 'bomb_linux', stop reason = instruction step into<br> frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115<br>bomb_linux`GenerateRandomNumber:<br>-> 0x401720 <+115>: jmp 0x401723 ; <+118><br> 0x401722 <+117>: nop<br> 0x401723 <+118>: popq %rbp<br> 0x401724 <+119>: retq<br>(lldb) x/gx &rand_div<br>0x00408820: 0x000000000000000a<br></code></pre></td></tr></table></figure>\n\n<p>而当 <code>rand_div = 0xa</code>(即十进制 <strong>10</strong>)时,输入值 <code>N</code> 的计算步骤如下:</p>\n<ul>\n<li><p>数组索引 <strong>10</strong> 的值是 <strong>斐波那契数列第 20 项</strong>(<code>F(20) = 6765</code>)。</p>\n</li>\n<li><p><code>func4_0(k)</code> 实际计算的是 <strong>标准斐波那契数列的第 <code>k+1</code> 项</strong>(例如,<code>func4_0(0) = 1 = F(2)</code>) 需要满足:</p>\n<figure class=\"highlight c\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs c\">func4_0(k) = F(k+<span class=\"hljs-number\">1</span>) = F(<span class=\"hljs-number\">20</span>)<br></code></pre></td></tr></table></figure>\n<p>解得:<br>k + 1 = 20 → k = 19</p>\n</li>\n<li><p><code>k = N / 2000</code> → <code>N = 2000 * k = 2000 * 19 = 38000</code>.<br>从而得解。<br><img src=\"/images/phase_4.png\" alt=\"phase_4\"></p>\n</li>\n</ul>\n<hr>\n<h2 id=\"Phase-Impossible\"><a href=\"#Phase-Impossible\" class=\"headerlink\" title=\"Phase_Impossible\"></a><strong>Phase_Impossible</strong></h2><p>Impossible?</p>\n<p>从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:</p>\n<figure class=\"highlight c\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br><span class=\"line\">31</span><br><span class=\"line\">32</span><br><span class=\"line\">33</span><br><span class=\"line\">34</span><br><span class=\"line\">35</span><br><span class=\"line\">36</span><br><span class=\"line\">37</span><br><span class=\"line\">38</span><br><span class=\"line\">39</span><br><span class=\"line\">40</span><br><span class=\"line\">41</span><br><span class=\"line\">42</span><br><span class=\"line\">43</span><br><span class=\"line\">44</span><br><span class=\"line\">45</span><br><span class=\"line\">46</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs c\"><span class=\"hljs-type\">void</span> <span class=\"hljs-title function_\">phase_impossible</span><span class=\"hljs-params\">(<span class=\"hljs-type\">char</span> *param_1)</span><br><br>{<br> <span class=\"hljs-type\">int</span> iVar1;<br> <span class=\"hljs-type\">size_t</span> sVar2;<br> undefined local_118 [<span class=\"hljs-number\">256</span>];<br> <span class=\"hljs-type\">long</span> local_18;<br> <span class=\"hljs-type\">long</span> local_10;<br> <br> local_10 = GetTickCount();<br> sVar2 = <span class=\"hljs-built_in\">strlen</span>(param_1);<br> <span class=\"hljs-keyword\">if</span> ((sVar2 < <span class=\"hljs-number\">10</span>) || (sVar2 = <span class=\"hljs-built_in\">strlen</span>(param_1), <span class=\"hljs-number\">0x300</span> < sVar2)) {<br> explode_bomb();<br> }<br> <span class=\"hljs-built_in\">memset</span>(local_118,<span class=\"hljs-number\">0</span>,<span class=\"hljs-number\">0x100</span>);<br> tohex(local_118,param_1);<br> GenerateRandomNumber(<span class=\"hljs-number\">0x400</span>);<br> iVar1 = check_buf_valid(local_118,rand_div & <span class=\"hljs-number\">0xffffffff</span>);<br> <span class=\"hljs-keyword\">if</span> (iVar1 == <span class=\"hljs-number\">0</span>) {<br> <span class=\"hljs-built_in\">puts</span>(&DAT_00406518);<br> explode_bomb();<br> }<br> GenerateRandomNumber(<span class=\"hljs-number\">3</span>);<br> <span class=\"hljs-keyword\">if</span> (rand_div != <span class=\"hljs-number\">2</span>) {<br> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-number\">2</span> < rand_div) <span class=\"hljs-keyword\">goto</span> LAB_00401891;<br> <span class=\"hljs-keyword\">if</span> (rand_div == <span class=\"hljs-number\">0</span>) {<br> goto_buf_0(local_118);<br> }<br> <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (rand_div != <span class=\"hljs-number\">1</span>) <span class=\"hljs-keyword\">goto</span> LAB_00401891;<br> goto_buf_1(local_118);<br> }<br> goto_buf_2(local_118);<br>LAB_00401891:<br> explode_bomb();<br> GenerateRandomNumber(<span class=\"hljs-number\">0x400</span>);<br> <span class=\"hljs-keyword\">if</span> ((<span class=\"hljs-type\">long</span>)(<span class=\"hljs-type\">int</span>)result != rand_div) {<br> <span class=\"hljs-built_in\">printf</span>(&DAT_00406560,rand_div,(ulong)result);<br> explode_bomb();<br> }<br> local_18 = GetTickCount();<br> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-number\">1000</span> < (ulong)(local_18 - local_10)) {<br> <span class=\"hljs-built_in\">puts</span>(&DAT_004065a8);<br> explode_bomb();<br> }<br> <span class=\"hljs-keyword\">return</span>;<br>}<br></code></pre></td></tr></table></figure>\n<p>最终任务还是很明确的,需要写一段机器码修改<code>result</code>的数值,但是注意要能通过<code>check_buf_valid</code>检测,并且最后指令必须是跳转到<code>0x401896</code>不然就会触发<code>phase_impossible</code>中<code>0x401891</code>处的<code>explode_bomb</code>函数,唯一的难点是跟踪<code>rand_div</code>的数值变化,建议使用<code>register write</code>来修改<code>check_buf_valid</code>的返回值使其强制通过然后监控<code>rand_div</code>每一次的数值变化(<code>x/gx &rand_div</code>),记录好<code>rand_div</code>的结果后开始指令设计,需要满足:</p>\n<ul>\n<li>指令的异或和为<code>rand_div</code>第一次的数值末尾八位以通过检查;</li>\n<li>修改<code>result</code>使其数值等于<code>rand_div</code>第三次数值;</li>\n<li>跳转到<code>0x401896</code>避免炸弹;</li>\n</ul>\n<p> 如果前几问都完成了到这里应该是没有问题的。</p>\n<hr>\n<h2 id=\"Phase-Secret\"><a href=\"#Phase-Secret\" class=\"headerlink\" title=\"Phase_Secret\"></a><strong>Phase_Secret</strong></h2><p>隐藏彩蛋,并非隐藏。汇编里写的非常清楚:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000401a8b <phase_secret>:<br> 401a8b:\tf3 0f 1e fa \tendbr64<br> 401a8f:\t55 \tpush %rbp<br> 401a90:\t48 89 e5 \tmov %rsp,%rbp<br> 401a93:\t48 83 ec 10 \tsub $0x10,%rsp<br> 401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)<br> 401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8><br> 401aa2:\t48 89 c7 \tmov %rax,%rdi<br> 401aa5:\te8 76 f6 ff ff \tcall 401120 <puts@plt><br> 401aaa:\t90 \tnop<br> 401aab:\tc9 \tleave<br> 401aac:\tc3 \tret<br></code></pre></td></tr></table></figure>\n<p>注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在<code>phase_5</code>中设计指令时加一个要求跳转到<code>0x401a8b</code>即可。</p>\n<p>完结<br><img src=\"/images/caseclosed.png\" alt=\"Case Closed\"></p>\n","excerpt":"","more":"<p>这篇文章记录高地CSAPP课程Bomblab实验操作流程,仅供参考交流(答案是随机生成的和学号相关)。</p>\n<p>笔者实验环境为Archlinux/CachyOS,使用lldb作为调试器(和gdb操作差不多),其余用到的工具主要为objdump,strings,neovim/helix和zellij,全程开源环境不使用IDA。</p>\n<h2 id=\"Phase-1\"><a href=\"#Phase-1\" class=\"headerlink\" title=\"Phase_1\"></a><strong>Phase_1</strong></h2><h3 id=\"静态分析\"><a href=\"#静态分析\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><h4 id=\"strings扫描\"><a href=\"#strings扫描\" class=\"headerlink\" title=\"strings扫描\"></a><strong><code>strings</code>扫描</strong></h4><figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">strings bomb_linux<br></code></pre></td></tr></table></figure>\n<p>先用strings寻找可能与<code>phase_1</code>相关的字符串或函数名,运气好说不定能直接找到密码毕竟是第一题。<br><img src=\"/images/phase1_strings.png\" alt=\"strings\"></p>\n<ul>\n<li>结果没有明文密码无法直接秒掉第一问,可惜。</li>\n<li>但是找到<code>GenerateRandomString</code>函数可能与密码生成相关。</li>\n</ul>\n<h4 id=\"用objdump反汇编\"><a href=\"#用objdump反汇编\" class=\"headerlink\" title=\"用objdump反汇编\"></a><strong>用<code>objdump</code>反汇编</strong></h4><figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">objdump -d bomb_linux > bomb.asm<br></code></pre></td></tr></table></figure>\n<p>搜索<code>GenerateRandomString</code>和<code>phase_1</code>函数的汇编代码。<br> <figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">401b53 <phase_1>:<br> 401b53: endbr64<br> 401b57: push %rbp<br> 401b58: mov %rsp,%rbp<br> 401b5b: sub $0x20,%rsp<br> 401b5f: mov %rdi,-0x18(%rbp)<br> 401b63: lea -0xb(%rbp),%rax<br> 401b67: mov %rax,%rdi<br> 401b6a: callq 401ac1 <GenerateRandomString> # 调用密码生成函数<br> 401b6f: lea -0xb(%rbp),%rdx # 生成的字符串地址%rbp-0xb存入%rdx,即密码存储位置<br> 401b73: mov -0x18(%rbp),%rax<br> 401b77: mov %rdx,%rsi<br> 401b7a: mov %rax,%rdi<br> 401b7d: callq 401c0c <string_compare> # 调用字符串比较函数<br> 401b82: test %eax,%eax<br> 401b84: je 401b8d <phase_1+0x3a><br> 401b86: callq 401d67 <explode_bomb> # 比较失败则引爆炸弹<br></code></pre></td></tr></table></figure></p>\n<ul>\n<li><code>phase_1</code>调用<code>GenerateRandomString</code>生成一个字符串。</li>\n<li>用户输入的字符串需要与此生成的字符串完全匹配。</li>\n</ul>\n<hr>\n<h3 id=\"动态调试\"><a href=\"#动态调试\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p><img src=\"/images/phase1.png\" alt=\"phase_1\"><br>下面是phase_1求解的完整流程:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs lldb\">lldb bomb_linux <你的学号后六位><br>(lldb) b phase_1 # 在phase_1入口断点<br>(lldb) run # 从入口开始执行<br>请输入第1级的密码:114514 # 随便输入触发断点<br>(lldb) b 0x401b6f # 在GenerateRandomString返回后断点<br>(lldb) continue # 继续执行<br>(lldb) x/s $rbp - 0xb # 计算字符串地址(-0xb偏移量)<br>0x7fffffffdaf5: "mJHurpQZtY" # 轻松拿下,这里是根据学号伪随机生成的哦<br></code></pre></td></tr></table></figure>\n<p>将得到的密码保存入bomb_<学号后六位>.txt即可,避免后续重复输入。</p>\n<hr>\n<h2 id=\"Phase-2\"><a href=\"#Phase-2\" class=\"headerlink\" title=\"Phase_2\"></a><strong>Phase_2</strong></h2><h3 id=\"静态分析-1\"><a href=\"#静态分析-1\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><p>这道题目还是比较一目了然的,观察<code>phase_2</code>代码不难发现其实构建了一张跳转表:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000401b8e <phase_2>:<br> 401b8e:\tf3 0f 1e fa \tendbr64<br> 401b92:\t55 \tpush %rbp<br> 401b93:\t48 89 e5 \tmov %rsp,%rbp<br> 401b96:\t48 83 ec 10 \tsub $0x10,%rsp<br> 401b9a:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)<br> 401b9e:\tbf 10 00 00 00 \tmov $0x10,%edi<br> 401ba3:\te8 05 fb ff ff \tcall 4016ad <GenerateRandomNumber><br> 401ba8:\t48 8b 05 71 6c 00 00 \tmov 0x6c71(%rip),%rax # 408820 <rand_div><br> 401baf:\t48 83 f8 0f \tcmp $0xf,%rax<br> 401bb3:\t0f 87 16 01 00 00 \tja 401ccf <phase_2+0x141><br> 401bb9:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx<br> 401bc0:\t00 <br> 401bc1:\t48 8d 05 4c 4a 00 00 \tlea 0x4a4c(%rip),%rax # 406614 <_IO_stdin_used+0x614><br> 401bc8:\t8b 04 02 \tmov (%rdx,%rax,1),%eax<br> 401bcb:\t48 98 \tcltq<br> 401bcd:\t48 8d 15 40 4a 00 00 \tlea 0x4a40(%rip),%rdx # 406614 <_IO_stdin_used+0x614><br> 401bd4:\t48 01 d0 \tadd %rdx,%rax<br> 401bd7:\t3e ff e0 \tnotrack jmp *%rax<br> 401bda:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax<br> 401bde:\t48 89 c7 \tmov %rax,%rdi<br> 401be1:\te8 f2 00 00 00 \tcall 401cd8 <phase_2_0><br> 401be6:\te9 ea 00 00 00 \tjmp 401cd5 <phase_2+0x147><br> 401beb:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax<br> 401bef:\t48 89 c7 \tmov %rax,%rdi<br> 401bf2:\te8 8b 01 00 00 \tcall 401d82 <phase_2_1><br> 401bf7:\te9 d9 00 00 00 \tjmp 401cd5 <phase_2+0x147><br> 401bfc:\t48 8b 45 f8 \tmov -0x8(%rbp),%rax<br> 401c00:\t48 89 c7 \tmov %rax,%rdi<br> ...<br></code></pre></td></tr></table></figure>\n<p>这里面需要注意的关键点是rand_div,它会决定你的跳转方向,而你的学号又决定了它的取值。然后是<code>GenerateRandomNumber</code>这个函数的原理需要了解一下,而这个函数将在跳转前后分别调用一次,第一次决定你的跳转方向,第二次则决定了你的密码线索。</p>\n<hr>\n<h3 id=\"动态调试-1\"><a href=\"#动态调试-1\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p>理解原理就没什么难度了,自己找几个断点打好然后关注一下<code>rand_div</code>的值就好,观察自己的学号向哪个函数跳转并理解相应函数计算即可,比如我这里向<code>phase_2_14</code>跳转:<br><img src=\"/images/phase_2_14.png\" alt=\"phase_2_14\"></p>\n<p>而除了<code>phase_2_14</code>还有其他函数也是非常好理解的,第二题依旧可以轻松拿下。</p>\n<hr>\n<h2 id=\"Phase-3\"><a href=\"#Phase-3\" class=\"headerlink\" title=\"Phase_3\"></a><strong>Phase_3</strong></h2><h3 id=\"静态分析-2\"><a href=\"#静态分析-2\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><p>和Phase_2一样开局先跳转尽可能防止同学们答案雷同互相帮助(bushi</p>\n<p>本体其实没有什么好说的,这里我跳转的方向是<code>Phase_3_5</code>简要解释一下可供参考:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br><span class=\"line\">31</span><br><span class=\"line\">32</span><br><span class=\"line\">33</span><br><span class=\"line\">34</span><br><span class=\"line\">35</span><br><span class=\"line\">36</span><br><span class=\"line\">37</span><br><span class=\"line\">38</span><br><span class=\"line\">39</span><br><span class=\"line\">40</span><br><span class=\"line\">41</span><br><span class=\"line\">42</span><br><span class=\"line\">43</span><br><span class=\"line\">44</span><br><span class=\"line\">45</span><br><span class=\"line\">46</span><br><span class=\"line\">47</span><br><span class=\"line\">48</span><br><span class=\"line\">49</span><br><span class=\"line\">50</span><br><span class=\"line\">51</span><br><span class=\"line\">52</span><br><span class=\"line\">53</span><br><span class=\"line\">54</span><br><span class=\"line\">55</span><br><span class=\"line\">56</span><br><span class=\"line\">57</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000403001 <phase_3_5>:<br> 403001:\tf3 0f 1e fa \tendbr64<br> 403005:\t55 \tpush %rbp<br> 403006:\t48 89 e5 \tmov %rsp,%rbp<br> 403009:\t48 83 ec 20 \tsub $0x20,%rsp<br> 40300d:\t48 89 7d e8 \tmov %rdi,-0x18(%rbp)<br> 403011:\tc7 45 fc 00 00 00 00 \tmovl $0x0,-0x4(%rbp)<br> 403018:\tc7 45 f8 00 00 00 00 \tmovl $0x0,-0x8(%rbp)<br> 40301f:\t48 8d 4d f0 \tlea -0x10(%rbp),%rcx<br> 403023:\t48 8d 55 f4 \tlea -0xc(%rbp),%rdx<br> 403027:\t48 8b 45 e8 \tmov -0x18(%rbp),%rax<br> 40302b:\t48 8d 35 5a 36 00 00 \tlea 0x365a(%rip),%rsi # 40668c <_IO_stdin_used+0x68c><br> 403032:\t48 89 c7 \tmov %rax,%rdi<br> 403035:\tb8 00 00 00 00 \tmov $0x0,%eax<br> 40303a:\te8 51 e1 ff ff \tcall 401190 <__isoc99_sscanf@plt><br> 40303f:\t89 45 f8 \tmov %eax,-0x8(%rbp)<br> 403042:\t83 7d f8 01 \tcmpl $0x1,-0x8(%rbp)<br> 403046:\t7f 05 \tjg 40304d <phase_3_5+0x4c><br> 403048:\te8 a9 2b 00 00 \tcall 405bf6 <explode_bomb><br> 40304d:\tbf 08 00 00 00 \tmov $0x8,%edi<br> 403052:\te8 56 e6 ff ff \tcall 4016ad <GenerateRandomNumber><br> 403057:\t8b 45 f4 \tmov -0xc(%rbp),%eax<br> 40305a:\t48 63 d0 \tmovslq %eax,%rdx<br> 40305d:\t48 8b 05 bc 57 00 00 \tmov 0x57bc(%rip),%rax # 408820 <rand_div><br> 403064:\t48 39 c2 \tcmp %rax,%rdx<br> 403067:\t74 05 \tje 40306e <phase_3_5+0x6d><br> 403069:\te8 88 2b 00 00 \tcall 405bf6 <explode_bomb><br> 40306e:\tbf c8 00 00 00 \tmov $0xc8,%edi<br> 403073:\te8 35 e6 ff ff \tcall 4016ad <GenerateRandomNumber><br> 403078:\t8b 45 f4 \tmov -0xc(%rbp),%eax<br> 40307b:\t83 f8 07 \tcmp $0x7,%eax<br> 40307e:\t0f 87 eb 00 00 00 \tja 40316f <phase_3_5+0x16e><br> 403084:\t89 c0 \tmov %eax,%eax<br> 403086:\t48 8d 14 85 00 00 00 \tlea 0x0(,%rax,4),%rdx<br> 40308d:\t00 <br> 40308e:\t48 8d 05 9f 36 00 00 \tlea 0x369f(%rip),%rax # 406734 <_IO_stdin_used+0x734><br> 403095:\t8b 04 02 \tmov (%rdx,%rax,1),%eax<br> 403098:\t48 98 \tcltq<br> 40309a:\t48 8d 15 93 36 00 00 \tlea 0x3693(%rip),%rdx # 406734 <_IO_stdin_used+0x734><br> 4030a1:\t48 01 d0 \tadd %rdx,%rax<br> 4030a4:\t3e ff e0 \tnotrack jmp *%rax<br> 4030a7:\t48 8b 05 72 57 00 00 \tmov 0x5772(%rip),%rax # 408820 <rand_div><br> 4030ae:\t89 c2 \tmov %eax,%edx<br> 4030b0:\t8b 45 fc \tmov -0x4(%rbp),%eax<br> 4030b3:\t01 d0 \tadd %edx,%eax<br> 4030b5:\t89 45 fc \tmov %eax,-0x4(%rbp)<br> 4030b8:\tbf c8 00 00 00 \tmov $0xc8,%edi<br> 4030bd:\te8 eb e5 ff ff \tcall 4016ad <GenerateRandomNumber><br> ...<br> 403174:\t8b 45 f0 \tmov -0x10(%rbp),%eax<br> 403177:\t39 45 fc \tcmp %eax,-0x4(%rbp) # 注意这里<br> 40317a:\t74 05 \tje 403181 <phase_3_5+0x180><br> 40317c:\te8 75 2a 00 00 \tcall 405bf6 <explode_bomb><br> 403181:\t90 \tnop<br> 403182:\tc9 \tleave<br> 403183:\tc3 \tret<br><br></code></pre></td></tr></table></figure>\n<p>看起来一大堆很吓人对不对?实际上确实很吓人。</p>\n<p>但是发现其中玄机后其实简单的没边,最终答案就藏在<code>0x403177</code>里面,前提是确保这一步前炸弹不爆炸(意识到要爆炸了直接<code>run</code>一下重开qwq)。</p>\n<hr>\n<h3 id=\"动态调试-2\"><a href=\"#动态调试-2\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p>阅读<code>Phase_3_5</code>发现这一关其实需要两个输入,并且第一个输入必须是<code>rand_div</code>,这里建议通过<code>si</code>单步执行监控好<code>rand_div</code>值变化,确定正确结果后使用<code>run</code>重开正确输入第一个密码后才能进行下一步求解:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs lldb\">(lldb) si<br>Process 13376 stopped<br>* thread #1, name = 'bomb_linux', stop reason = instruction step into<br> frame #0: 0x000000000040317a bomb_linux`phase_3_5 + 377<br>bomb_linux`phase_3_5:<br>-> 0x40317a <+377>: je 0x403181 ; <+384><br> 0x40317c <+379>: callq 0x405bf6 ; explode_bomb<br> 0x403181 <+384>: nop<br> 0x403182 <+385>: leave<br>(lldb) x/wx $rbp-0x4<br>0x7fffffffdb0c: 0xffffffd7<br></code></pre></td></tr></table></figure>\n<p>例如这里我可以打印出第二个值结合第一个值得到第三关正确结果。</p>\n<hr>\n<h2 id=\"Phase-4\"><a href=\"#Phase-4\" class=\"headerlink\" title=\"Phase_4\"></a><strong>Phase_4</strong></h2><h3 id=\"静态分析-3\"><a href=\"#静态分析-3\" class=\"headerlink\" title=\"静态分析\"></a><strong>静态分析</strong></h3><p>本题依旧开局跳转,笔者的跳转方向是<code>phase_4_01</code>,如何跳转不再强调关注<code>rand_div</code>的值即可,下面请D指导解读一下<code>phase_4_01</code>的内容:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br><span class=\"line\">31</span><br><span class=\"line\">32</span><br><span class=\"line\">33</span><br><span class=\"line\">34</span><br><span class=\"line\">35</span><br><span class=\"line\">36</span><br><span class=\"line\">37</span><br><span class=\"line\">38</span><br><span class=\"line\">39</span><br><span class=\"line\">40</span><br><span class=\"line\">41</span><br><span class=\"line\">42</span><br><span class=\"line\">43</span><br><span class=\"line\">44</span><br><span class=\"line\">45</span><br><span class=\"line\">46</span><br><span class=\"line\">47</span><br><span class=\"line\">48</span><br><span class=\"line\">49</span><br><span class=\"line\">50</span><br><span class=\"line\">51</span><br><span class=\"line\">52</span><br><span class=\"line\">53</span><br><span class=\"line\">54</span><br><span class=\"line\">55</span><br><span class=\"line\">56</span><br><span class=\"line\">57</span><br><span class=\"line\">58</span><br><span class=\"line\">59</span><br><span class=\"line\">60</span><br><span class=\"line\">61</span><br><span class=\"line\">62</span><br><span class=\"line\">63</span><br><span class=\"line\">64</span><br><span class=\"line\">65</span><br><span class=\"line\">66</span><br><span class=\"line\">67</span><br><span class=\"line\">68</span><br><span class=\"line\">69</span><br><span class=\"line\">70</span><br><span class=\"line\">71</span><br><span class=\"line\">72</span><br><span class=\"line\">73</span><br><span class=\"line\">74</span><br><span class=\"line\">75</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000404895 <phase_4_01>:<br> ; 函数入口,初始化栈帧<br> 404895:\tf3 0f 1e fa \tendbr64 <br> 404899:\t55 \tpush %rbp<br> 40489a:\t48 89 e5 \tmov %rsp,%rbp<br> 40489d:\t48 83 ec 70 \tsub $0x70,%rsp ; 分配栈空间<br><br> ; 初始化斐波那契数组(F(10)~F(24)的十六进制值)<br> 4048a1:\t48 89 7d 98 \tmov %rdi,-0x68(%rbp) ; 保存输入字符串指针<br> 4048a5:\tc7 45 b0 37 00 00 00 \tmovl $0x37,-0x50(%rbp) ; F(10)=55<br> 4048ac:\tc7 45 b4 59 00 00 00 \tmovl $0x59,-0x4c(%rbp) ; F(11)=89<br> 4048b3:\tc7 45 b8 90 00 00 00 \tmovl $0x90,-0x48(%rbp) ; F(12)=144<br> 4048ba:\tc7 45 bc e9 00 00 00 \tmovl $0xe9,-0x44(%rbp) ; F(13)=233<br> 4048c1:\tc7 45 c0 79 01 00 00 \tmovl $0x179,-0x40(%rbp) ; F(14)=377<br> 4048c8:\tc7 45 c4 62 02 00 00 \tmovl $0x262,-0x3c(%rbp) ; F(15)=610<br> 4048cf:\tc7 45 c8 db 03 00 00 \tmovl $0x3db,-0x38(%rbp) ; F(16)=987<br> 4048d6:\tc7 45 cc 3d 06 00 00 \tmovl $0x63d,-0x34(%rbp) ; F(17)=1597<br> 4048dd:\tc7 45 d0 18 0a 00 00 \tmovl $0xa18,-0x30(%rbp) ; F(18)=2584<br> 4048e4:\tc7 45 d4 55 10 00 00 \tmovl $0x1055,-0x2c(%rbp) ; F(19)=4181<br> 4048eb:\tc7 45 d8 6d 1a 00 00 \tmovl $0x1a6d,-0x28(%rbp) ; F(20)=6765<br> 4048f2:\tc7 45 dc c2 2a 00 00 \tmovl $0x2ac2,-0x24(%rbp) ; F(21)=10946<br> 4048f9:\tc7 45 e0 2f 45 00 00 \tmovl $0x452f,-0x20(%rbp) ; F(22)=17711<br> 404900:\tc7 45 e4 f1 6f 00 00 \tmovl $0x6ff1,-0x1c(%rbp) ; F(23)=28657<br> 404907:\tc7 45 e8 20 b5 00 00 \tmovl $0xb520,-0x18(%rbp) ; F(24)=46368<br><br> ; 读取输入到局部变量(格式为"%d")<br> 40490e:\t48 8d 55 ac \tlea -0x54(%rbp),%rdx ; 输入存储地址<br> 404912:\t48 8b 45 98 \tmov -0x68(%rbp),%rax ; 输入字符串<br> 404916:\t48 8d 0d 93 1f 00 00 \tlea 0x1f93(%rip),%rcx ; 格式字符串"%d"<br> 40491d:\t48 89 ce \tmov %rcx,%rsi<br> 404920:\t48 89 c7 \tmov %rax,%rdi<br> 404923:\tb8 00 00 00 00 \tmov $0x0,%eax<br> 404928:\te8 63 c8 ff ff \tcall 401190 <__isoc99_sscanf@plt><br><br> ; 验证输入有效性(必须为1个正数)<br> 40492d:\t89 45 fc \tmov %eax,-0x4(%rbp) ; sscanf返回值<br> 404930:\t83 7d fc 01 \tcmpl $0x1,-0x4(%rbp) ; 检查是否读取1个参数<br> 404934:\t75 07 \tjne 40493d <phase_4_01+0xa8> ; 失败则爆炸<br> 404936:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 获取输入值N<br> 404939:\t85 c0 \ttest %eax,%eax ; 检查N > 0<br> 40493b:\t7f 05 \tjg 404942 <phase_4_01+0xad><br> 40493d:\te8 b4 12 00 00 \tcall 405bf6 <explode_bomb><br><br> ; 检查输入值上限(必须 > 1999)<br> 404942:\t8b 45 ac \tmov -0x54(%rbp),%eax <br> 404945:\t3d cf 07 00 00 \tcmp $0x7cf,%eax ; 1999的十六进制<br> 40494a:\t7f 05 \tjg 404951 <phase_4_01+0xbc> ; N > 1999?<br> 40494c:\te8 a5 12 00 00 \tcall 405bf6 <explode_bomb><br><br> ; 计算 N/2000(通过定点数乘法优化)<br> 404951:\t8b 45 ac \tmov -0x54(%rbp),%eax ; 输入值N<br> 404954:\t48 63 d0 \tmovslq %eax,%rdx ; 符号扩展<br> 404957:\t48 69 d2 d3 4d 62 10 \timul $0x10624dd3,%rdx,%rdx ; 乘以274877907(≈2^32/2000)<br> 40495e:\t48 c1 ea 20 \tshr $0x20,%rdx ; 取高32位<br> 404962:\tc1 fa 07 \tsar $0x7,%edx ; 算术右移7位 → N/2000<br> 404965:\tc1 f8 1f \tsar $0x1f,%eax ; 符号位扩展<br> 404968:\t89 c1 \tmov %eax,%ecx <br> 40496a:\t89 d0 \tmov %edx,%eax <br> 40496c:\t29 c8 \tsub %ecx,%eax ; 处理负数情况<br> 40496e:\t89 45 ac \tmov %eax,-0x54(%rbp) ; 保存k = N/2000<br><br> ; 调用递归函数func4_0(k), 这个函数用于计算斐波那契数列<br> 404971:\t8b 45 ac \tmov -0x54(%rbp),%eax <br> 404974:\t89 c7 \tmov %eax,%edi ; 参数k<br> 404976:\te8 ce fd ff ff \tcall 404749 <func4_0> ; 返回值eax=F(k+1)<br> 40497b:\t89 45 f8 \tmov %eax,-0x8(%rbp) ; 保存结果<br><br> ; 生成随机索引并验证结果<br> 40497e:\tbf 0f 00 00 00 \tmov $0xf,%edi ; 参数15<br> 404983:\te8 25 cd ff ff \tcall 4016ad <GenerateRandomNumber> ; 生成0~14随机数<br> 404988:\t48 8b 05 91 3e 00 00 \tmov 0x3e91(%rip),%rax # 408820 <rand_div> ; 获取随机索引<br> 40498f:\t8b 44 85 b0 \tmov -0x50(%rbp,%rax,4),%eax ; 取数组[rand_div]的值<br> 404993:\t39 45 f8 \tcmp %eax,-0x8(%rbp) ; 比较func4_0(k) == 数组值?<br> 404996:\t74 05 \tje 40499d <phase_4_01+0x108><br> 404998:\te8 59 12 00 00 \tcall 405bf6 <explode_bomb><br></code></pre></td></tr></table></figure>\n<p>所以相对还是很明了的,依旧是关注<code>rand_div</code>。</p>\n<h3 id=\"动态调试-3\"><a href=\"#动态调试-3\" class=\"headerlink\" title=\"动态调试\"></a><strong>动态调试</strong></h3><p>先找出<code>rand_div</code>在最后判断前的取值,比如我下面的0xa:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs lldb\">(lldb) si<br>Process 27027 stopped<br>* thread #1, name = 'bomb_linux', stop reason = instruction step into<br> frame #0: 0x0000000000401719 bomb_linux`GenerateRandomNumber + 108<br>bomb_linux`GenerateRandomNumber:<br>-> 0x401719 <+108>: movq %rax, 0x7100(%rip) ; rand_div<br> 0x401720 <+115>: jmp 0x401723 ; <+118><br> 0x401722 <+117>: nop<br> 0x401723 <+118>: popq %rbp<br>(lldb) si<br>Process 27027 stopped<br>* thread #1, name = 'bomb_linux', stop reason = instruction step into<br> frame #0: 0x0000000000401720 bomb_linux`GenerateRandomNumber + 115<br>bomb_linux`GenerateRandomNumber:<br>-> 0x401720 <+115>: jmp 0x401723 ; <+118><br> 0x401722 <+117>: nop<br> 0x401723 <+118>: popq %rbp<br> 0x401724 <+119>: retq<br>(lldb) x/gx &rand_div<br>0x00408820: 0x000000000000000a<br></code></pre></td></tr></table></figure>\n\n<p>而当 <code>rand_div = 0xa</code>(即十进制 <strong>10</strong>)时,输入值 <code>N</code> 的计算步骤如下:</p>\n<ul>\n<li><p>数组索引 <strong>10</strong> 的值是 <strong>斐波那契数列第 20 项</strong>(<code>F(20) = 6765</code>)。</p>\n</li>\n<li><p><code>func4_0(k)</code> 实际计算的是 <strong>标准斐波那契数列的第 <code>k+1</code> 项</strong>(例如,<code>func4_0(0) = 1 = F(2)</code>) 需要满足:</p>\n<figure class=\"highlight c\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs c\">func4_0(k) = F(k+<span class=\"hljs-number\">1</span>) = F(<span class=\"hljs-number\">20</span>)<br></code></pre></td></tr></table></figure>\n<p>解得:<br>k + 1 = 20 → k = 19</p>\n</li>\n<li><p><code>k = N / 2000</code> → <code>N = 2000 * k = 2000 * 19 = 38000</code>.<br>从而得解。<br><img src=\"/images/phase_4.png\" alt=\"phase_4\"></p>\n</li>\n</ul>\n<hr>\n<h2 id=\"Phase-Impossible\"><a href=\"#Phase-Impossible\" class=\"headerlink\" title=\"Phase_Impossible\"></a><strong>Phase_Impossible</strong></h2><p>Impossible?</p>\n<p>从这道题开始偷懒了,掏出ghidra直接看c代码了解一下大概流程再去objdump看汇编:</p>\n<figure class=\"highlight c\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br><span class=\"line\">23</span><br><span class=\"line\">24</span><br><span class=\"line\">25</span><br><span class=\"line\">26</span><br><span class=\"line\">27</span><br><span class=\"line\">28</span><br><span class=\"line\">29</span><br><span class=\"line\">30</span><br><span class=\"line\">31</span><br><span class=\"line\">32</span><br><span class=\"line\">33</span><br><span class=\"line\">34</span><br><span class=\"line\">35</span><br><span class=\"line\">36</span><br><span class=\"line\">37</span><br><span class=\"line\">38</span><br><span class=\"line\">39</span><br><span class=\"line\">40</span><br><span class=\"line\">41</span><br><span class=\"line\">42</span><br><span class=\"line\">43</span><br><span class=\"line\">44</span><br><span class=\"line\">45</span><br><span class=\"line\">46</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs c\"><span class=\"hljs-type\">void</span> <span class=\"hljs-title function_\">phase_impossible</span><span class=\"hljs-params\">(<span class=\"hljs-type\">char</span> *param_1)</span><br><br>{<br> <span class=\"hljs-type\">int</span> iVar1;<br> <span class=\"hljs-type\">size_t</span> sVar2;<br> undefined local_118 [<span class=\"hljs-number\">256</span>];<br> <span class=\"hljs-type\">long</span> local_18;<br> <span class=\"hljs-type\">long</span> local_10;<br> <br> local_10 = GetTickCount();<br> sVar2 = <span class=\"hljs-built_in\">strlen</span>(param_1);<br> <span class=\"hljs-keyword\">if</span> ((sVar2 < <span class=\"hljs-number\">10</span>) || (sVar2 = <span class=\"hljs-built_in\">strlen</span>(param_1), <span class=\"hljs-number\">0x300</span> < sVar2)) {<br> explode_bomb();<br> }<br> <span class=\"hljs-built_in\">memset</span>(local_118,<span class=\"hljs-number\">0</span>,<span class=\"hljs-number\">0x100</span>);<br> tohex(local_118,param_1);<br> GenerateRandomNumber(<span class=\"hljs-number\">0x400</span>);<br> iVar1 = check_buf_valid(local_118,rand_div & <span class=\"hljs-number\">0xffffffff</span>);<br> <span class=\"hljs-keyword\">if</span> (iVar1 == <span class=\"hljs-number\">0</span>) {<br> <span class=\"hljs-built_in\">puts</span>(&DAT_00406518);<br> explode_bomb();<br> }<br> GenerateRandomNumber(<span class=\"hljs-number\">3</span>);<br> <span class=\"hljs-keyword\">if</span> (rand_div != <span class=\"hljs-number\">2</span>) {<br> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-number\">2</span> < rand_div) <span class=\"hljs-keyword\">goto</span> LAB_00401891;<br> <span class=\"hljs-keyword\">if</span> (rand_div == <span class=\"hljs-number\">0</span>) {<br> goto_buf_0(local_118);<br> }<br> <span class=\"hljs-keyword\">else</span> <span class=\"hljs-keyword\">if</span> (rand_div != <span class=\"hljs-number\">1</span>) <span class=\"hljs-keyword\">goto</span> LAB_00401891;<br> goto_buf_1(local_118);<br> }<br> goto_buf_2(local_118);<br>LAB_00401891:<br> explode_bomb();<br> GenerateRandomNumber(<span class=\"hljs-number\">0x400</span>);<br> <span class=\"hljs-keyword\">if</span> ((<span class=\"hljs-type\">long</span>)(<span class=\"hljs-type\">int</span>)result != rand_div) {<br> <span class=\"hljs-built_in\">printf</span>(&DAT_00406560,rand_div,(ulong)result);<br> explode_bomb();<br> }<br> local_18 = GetTickCount();<br> <span class=\"hljs-keyword\">if</span> (<span class=\"hljs-number\">1000</span> < (ulong)(local_18 - local_10)) {<br> <span class=\"hljs-built_in\">puts</span>(&DAT_004065a8);<br> explode_bomb();<br> }<br> <span class=\"hljs-keyword\">return</span>;<br>}<br></code></pre></td></tr></table></figure>\n<p>最终任务还是很明确的,需要写一段机器码修改<code>result</code>的数值,但是注意要能通过<code>check_buf_valid</code>检测,并且最后指令必须是跳转到<code>0x401896</code>不然就会触发<code>phase_impossible</code>中<code>0x401891</code>处的<code>explode_bomb</code>函数,唯一的难点是跟踪<code>rand_div</code>的数值变化,建议使用<code>register write</code>来修改<code>check_buf_valid</code>的返回值使其强制通过然后监控<code>rand_div</code>每一次的数值变化(<code>x/gx &rand_div</code>),记录好<code>rand_div</code>的结果后开始指令设计,需要满足:</p>\n<ul>\n<li>指令的异或和为<code>rand_div</code>第一次的数值末尾八位以通过检查;</li>\n<li>修改<code>result</code>使其数值等于<code>rand_div</code>第三次数值;</li>\n<li>跳转到<code>0x401896</code>避免炸弹;</li>\n</ul>\n<p> 如果前几问都完成了到这里应该是没有问题的。</p>\n<hr>\n<h2 id=\"Phase-Secret\"><a href=\"#Phase-Secret\" class=\"headerlink\" title=\"Phase_Secret\"></a><strong>Phase_Secret</strong></h2><p>隐藏彩蛋,并非隐藏。汇编里写的非常清楚:</p>\n<figure class=\"highlight plaintext\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs assembly\">0000000000401a8b <phase_secret>:<br> 401a8b:\tf3 0f 1e fa \tendbr64<br> 401a8f:\t55 \tpush %rbp<br> 401a90:\t48 89 e5 \tmov %rsp,%rbp<br> 401a93:\t48 83 ec 10 \tsub $0x10,%rsp<br> 401a97:\t48 89 7d f8 \tmov %rdi,-0x8(%rbp)<br> 401a9b:\t48 8d 05 26 4b 00 00 \tlea 0x4b26(%rip),%rax # 4065c8 <_IO_stdin_used+0x5c8><br> 401aa2:\t48 89 c7 \tmov %rax,%rdi<br> 401aa5:\te8 76 f6 ff ff \tcall 401120 <puts@plt><br> 401aaa:\t90 \tnop<br> 401aab:\tc9 \tleave<br> 401aac:\tc3 \tret<br></code></pre></td></tr></table></figure>\n<p>注意到这段指令在原程序中完全没有执行说明是需要用户自己跳转的,也非常简单只需要在<code>phase_5</code>中设计指令时加一个要求跳转到<code>0x401a8b</code>即可。</p>\n<p>完结<br><img src=\"/images/caseclosed.png\" alt=\"Case Closed\"></p>\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://<your-proxy-server>:<port>\"\n Environment=\"HTTPS_PROXY=http://<your-proxy-server>:<port>\"\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://<your-proxy-server>:<port>\"\n Environment=\"HTTPS_PROXY=http://<your-proxy-server>:<port>\"\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":"cm7jziody001pwi2bck6n2j6b","content":"<p>在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。</p>\n<p>具体流程就不赘述了,先将访问<a href=\"https://github.com/overleaf/toolkit\">Overleaf Toolkit官方仓库</a>将代码clone下来并按照手册执行即可。</p>\n<h2 id=\"问题一:无法-Pull-Mongo、Redis-和-Sharelatex-镜像\"><a href=\"#问题一:无法-Pull-Mongo、Redis-和-Sharelatex-镜像\" class=\"headerlink\" title=\"问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像\"></a>问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像</h2><p>在执行 <code>bin/up</code> 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。</p>\n<p>截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。</p>\n<h3 id=\"解决方案:为-Docker-设置代理\"><a href=\"#解决方案:为-Docker-设置代理\" class=\"headerlink\" title=\"解决方案:为 Docker 设置代理\"></a>解决方案:为 Docker 设置代理</h3><p>通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:</p>\n<ol>\n<li><p>创建一个 <code>systemd</code> 服务文件,为 Docker 设置代理。</p>\n</li>\n<li><p>编辑 <code>/etc/systemd/system/docker.service.d/proxy.conf</code> 文件,添加以下内容(确保已经设置了代理服务器):</p>\n <figure class=\"highlight ini\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs ini\"><span class=\"hljs-section\">[Service]</span><br><span class=\"hljs-attr\">Environment</span>=<span class=\"hljs-string\">"HTTP_PROXY=http://<your-proxy-server>:<port>"</span><br><span class=\"hljs-attr\">Environment</span>=<span class=\"hljs-string\">"HTTPS_PROXY=http://<your-proxy-server>:<port>"</span><br><span class=\"hljs-attr\">Environment</span>=<span class=\"hljs-string\">"NO_PROXY=localhost,127.0.0.1"</span><br></code></pre></td></tr></table></figure>\n</li>\n<li><p>重新加载 <code>systemd</code> 配置并重启 Docker:</p>\n <figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo systemctl daemon-reload<br>sudo systemctl restart docker<br></code></pre></td></tr></table></figure>\n</li>\n<li><p>重启 Docker 后再次执行 <code>sudo ./up</code>,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。</p>\n</li>\n</ol>\n<hr>\n<h2 id=\"问题二:外部机器无法访问-Overleaf-Web-服务\"><a href=\"#问题二:外部机器无法访问-Overleaf-Web-服务\" class=\"headerlink\" title=\"问题二:外部机器无法访问 Overleaf Web 服务\"></a>问题二:外部机器无法访问 Overleaf Web 服务</h2><p>先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。</p>\n<p>注意到在默认的 <code>lib/docker-compose.base.yml</code> 配置中,Overleaf Web 服务的端口映射方式为 <code>"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"</code>。</p>\n<h3 id=\"解决方案:修改端口映射\"><a href=\"#解决方案:修改端口映射\" class=\"headerlink\" title=\"解决方案:修改端口映射\"></a>解决方案:修改端口映射</h3><p>在 <code>docker-compose.base.yml</code> 文件中,删除 <code>${OVERLEAF_LISTEN_IP:-127.0.0.1}</code> 前缀,将 <code>"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"</code> 修改为 <code>"${OVERLEAF_PORT:-80}:80"</code>。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。</p>\n<p>修改后的 <code>docker-compose.base.yml</code> 端口映射配置如下:</p>\n<figure class=\"highlight yaml\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs yaml\"><span class=\"hljs-meta\">---</span><br><span class=\"hljs-attr\">services:</span><br><br> <span class=\"hljs-attr\">sharelatex:</span><br> <span class=\"hljs-attr\">restart:</span> <span class=\"hljs-string\">always</span><br> <span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">"${IMAGE}"</span><br> <span class=\"hljs-attr\">container_name:</span> <span class=\"hljs-string\">sharelatex</span><br> <span class=\"hljs-attr\">volumes:</span><br> <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">"${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}"</span><br> <span class=\"hljs-attr\">ports:</span><br> <span class=\"hljs-comment\">#- "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"</span><br> <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">"${OVERLEAF_PORT:-80}:80"</span><br> <span class=\"hljs-attr\">environment:</span><br> <span class=\"hljs-attr\">GIT_BRIDGE_ENABLED:</span> <span class=\"hljs-string\">"${GIT_BRIDGE_ENABLED}"</span><br> <span class=\"hljs-attr\">GIT_BRIDGE_HOST:</span> <span class=\"hljs-string\">"git-bridge"</span><br> <span class=\"hljs-attr\">GIT_BRIDGE_PORT:</span> <span class=\"hljs-string\">"8000"</span><br> <span class=\"hljs-attr\">REDIS_HOST:</span> <span class=\"hljs-string\">"${REDIS_HOST}"</span><br> <span class=\"hljs-attr\">REDIS_PORT:</span> <span class=\"hljs-string\">"${REDIS_PORT}"</span><br> <span class=\"hljs-attr\">V1_HISTORY_URL:</span> <span class=\"hljs-string\">"http://sharelatex:3100/api"</span><br> <span class=\"hljs-attr\">env_file:</span><br> <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">../config/variables.env</span><br> <span class=\"hljs-attr\">stop_grace_period:</span> <span class=\"hljs-string\">60s</span><br></code></pre></td></tr></table></figure>\n\n<p>完成修改后,重新启动 Docker 服务:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo ./start<br></code></pre></td></tr></table></figure>\n\n<p>现在,外部机器可以通过服务器的 IP 地址加端口 <code>{Overleaf_Port}</code> 访问 Overleaf Web 服务。</p>\n<hr>\n<h2 id=\"总结\"><a href=\"#总结\" class=\"headerlink\" title=\"总结\"></a>总结</h2><p>这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 <code>docker-compose.base.yml</code> 中的端口映射使外部设备可以访问 Overleaf 服务。</p>\n<p>可以在这里参考我的本地<a href=\"https://overleaf.hifuu.ink/\">Overleaf</a>效果,注意安装完后还需要配置latex包和中文字体。</p>\n<p>这篇记录希望能为遇到类似问题的朋友提供帮助。</p>\n","excerpt":"","more":"<p>在安装 Overleaf Toolkit 时,表面上看起来很简单只要执行一些脚本就行,但是在某地区网络环境下还是遇到了一些问题和困难,这里记录安装过程中的问题和解决方案,方便以后参考。</p>\n<p>具体流程就不赘述了,先将访问<a href=\"https://github.com/overleaf/toolkit\">Overleaf Toolkit官方仓库</a>将代码clone下来并按照手册执行即可。</p>\n<h2 id=\"问题一:无法-Pull-Mongo、Redis-和-Sharelatex-镜像\"><a href=\"#问题一:无法-Pull-Mongo、Redis-和-Sharelatex-镜像\" class=\"headerlink\" title=\"问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像\"></a>问题一:无法 Pull Mongo、Redis 和 Sharelatex 镜像</h2><p>在执行 <code>bin/up</code> 脚本启动服务时,发现 Mongo、Redis 和 Sharelatex 镜像无法拉取。主要原因是 Docker 在国内网络环境中,直接访问 Docker Hub 可能会被限制,导致拉取镜像失败。</p>\n<p>截至这篇博客编写时网上提供的镜像均无法解决只能使用代理。</p>\n<h3 id=\"解决方案:为-Docker-设置代理\"><a href=\"#解决方案:为-Docker-设置代理\" class=\"headerlink\" title=\"解决方案:为 Docker 设置代理\"></a>解决方案:为 Docker 设置代理</h3><p>通过配置 Docker 的代理,可以解决拉取镜像受限的问题。步骤如下:</p>\n<ol>\n<li><p>创建一个 <code>systemd</code> 服务文件,为 Docker 设置代理。</p>\n</li>\n<li><p>编辑 <code>/etc/systemd/system/docker.service.d/proxy.conf</code> 文件,添加以下内容(确保已经设置了代理服务器):</p>\n <figure class=\"highlight ini\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs ini\"><span class=\"hljs-section\">[Service]</span><br><span class=\"hljs-attr\">Environment</span>=<span class=\"hljs-string\">"HTTP_PROXY=http://<your-proxy-server>:<port>"</span><br><span class=\"hljs-attr\">Environment</span>=<span class=\"hljs-string\">"HTTPS_PROXY=http://<your-proxy-server>:<port>"</span><br><span class=\"hljs-attr\">Environment</span>=<span class=\"hljs-string\">"NO_PROXY=localhost,127.0.0.1"</span><br></code></pre></td></tr></table></figure>\n</li>\n<li><p>重新加载 <code>systemd</code> 配置并重启 Docker:</p>\n <figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo systemctl daemon-reload<br>sudo systemctl restart docker<br></code></pre></td></tr></table></figure>\n</li>\n<li><p>重启 Docker 后再次执行 <code>sudo ./up</code>,此时应该可以正常拉取 Mongo、Redis 和 Sharelatex 的镜像。等待执行完成即可。</p>\n</li>\n</ol>\n<hr>\n<h2 id=\"问题二:外部机器无法访问-Overleaf-Web-服务\"><a href=\"#问题二:外部机器无法访问-Overleaf-Web-服务\" class=\"headerlink\" title=\"问题二:外部机器无法访问 Overleaf Web 服务\"></a>问题二:外部机器无法访问 Overleaf Web 服务</h2><p>先确认ipv4和ipv6转发功能没有问题,但是依旧出现只能本机访问127.0.0.1,其他方式均无法访问,甚至nmap扫描端口也发现并未开放sharelatex端口,可以通过修改docker-compose配置文件解决。</p>\n<p>注意到在默认的 <code>lib/docker-compose.base.yml</code> 配置中,Overleaf Web 服务的端口映射方式为 <code>"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"</code>。</p>\n<h3 id=\"解决方案:修改端口映射\"><a href=\"#解决方案:修改端口映射\" class=\"headerlink\" title=\"解决方案:修改端口映射\"></a>解决方案:修改端口映射</h3><p>在 <code>docker-compose.base.yml</code> 文件中,删除 <code>${OVERLEAF_LISTEN_IP:-127.0.0.1}</code> 前缀,将 <code>"${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"</code> 修改为 <code>"${OVERLEAF_PORT:-80}:80"</code>。这样可以使 Docker 将 Overleaf 的 Web 服务端口暴露给所有网络接口,从而允许外部机器访问。</p>\n<p>修改后的 <code>docker-compose.base.yml</code> 端口映射配置如下:</p>\n<figure class=\"highlight yaml\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br><span class=\"line\">2</span><br><span class=\"line\">3</span><br><span class=\"line\">4</span><br><span class=\"line\">5</span><br><span class=\"line\">6</span><br><span class=\"line\">7</span><br><span class=\"line\">8</span><br><span class=\"line\">9</span><br><span class=\"line\">10</span><br><span class=\"line\">11</span><br><span class=\"line\">12</span><br><span class=\"line\">13</span><br><span class=\"line\">14</span><br><span class=\"line\">15</span><br><span class=\"line\">16</span><br><span class=\"line\">17</span><br><span class=\"line\">18</span><br><span class=\"line\">19</span><br><span class=\"line\">20</span><br><span class=\"line\">21</span><br><span class=\"line\">22</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs yaml\"><span class=\"hljs-meta\">---</span><br><span class=\"hljs-attr\">services:</span><br><br> <span class=\"hljs-attr\">sharelatex:</span><br> <span class=\"hljs-attr\">restart:</span> <span class=\"hljs-string\">always</span><br> <span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">"${IMAGE}"</span><br> <span class=\"hljs-attr\">container_name:</span> <span class=\"hljs-string\">sharelatex</span><br> <span class=\"hljs-attr\">volumes:</span><br> <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">"${OVERLEAF_DATA_PATH}:${OVERLEAF_IN_CONTAINER_DATA_PATH}"</span><br> <span class=\"hljs-attr\">ports:</span><br> <span class=\"hljs-comment\">#- "${OVERLEAF_LISTEN_IP:-127.0.0.1}:${OVERLEAF_PORT:-80}:80"</span><br> <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">"${OVERLEAF_PORT:-80}:80"</span><br> <span class=\"hljs-attr\">environment:</span><br> <span class=\"hljs-attr\">GIT_BRIDGE_ENABLED:</span> <span class=\"hljs-string\">"${GIT_BRIDGE_ENABLED}"</span><br> <span class=\"hljs-attr\">GIT_BRIDGE_HOST:</span> <span class=\"hljs-string\">"git-bridge"</span><br> <span class=\"hljs-attr\">GIT_BRIDGE_PORT:</span> <span class=\"hljs-string\">"8000"</span><br> <span class=\"hljs-attr\">REDIS_HOST:</span> <span class=\"hljs-string\">"${REDIS_HOST}"</span><br> <span class=\"hljs-attr\">REDIS_PORT:</span> <span class=\"hljs-string\">"${REDIS_PORT}"</span><br> <span class=\"hljs-attr\">V1_HISTORY_URL:</span> <span class=\"hljs-string\">"http://sharelatex:3100/api"</span><br> <span class=\"hljs-attr\">env_file:</span><br> <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">../config/variables.env</span><br> <span class=\"hljs-attr\">stop_grace_period:</span> <span class=\"hljs-string\">60s</span><br></code></pre></td></tr></table></figure>\n\n<p>完成修改后,重新启动 Docker 服务:</p>\n<figure class=\"highlight bash\"><table><tr><td class=\"gutter\"><pre><span class=\"line\">1</span><br></pre></td><td class=\"code\"><pre><code class=\"hljs bash\">sudo ./start<br></code></pre></td></tr></table></figure>\n\n<p>现在,外部机器可以通过服务器的 IP 地址加端口 <code>{Overleaf_Port}</code> 访问 Overleaf Web 服务。</p>\n<hr>\n<h2 id=\"总结\"><a href=\"#总结\" class=\"headerlink\" title=\"总结\"></a>总结</h2><p>这次安装 Overleaf Toolkit 时,主要遇到的两个问题分别是镜像拉取失败和端口映射受限。通过为 Docker 设置代理解决了拉取镜像的问题,而通过修改 <code>docker-compose.base.yml</code> 中的端口映射使外部设备可以访问 Overleaf 服务。</p>\n<p>可以在这里参考我的本地<a href=\"https://overleaf.hifuu.ink/\">Overleaf</a>效果,注意安装完后还需要配置latex包和中文字体。</p>\n<p>这篇记录希望能为遇到类似问题的朋友提供帮助。</p>\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\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\n","slug":"zellij-helix","published":1,"updated":"2025-02-23T15:53:44.966Z","comments":1,"layout":"post","photos":[],"_id":"cm7jziody001qwi2ba7oj09d4","content":"<p>意外发现Zellij+Helix还挺好用的</p>\n<p>避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境</p>\n<p>稍微了解一下二者的快捷键就能舒适码字了</p>\n<p>甚至还都是rust出品</p>\n<p>即刻尝试一下<a href=\"https://zellij.dev/\">Zellij</a>和<a href=\"https://helix-editor.com/\">Helix</a>吧!</p>\n<p>// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh</p>\n<p><img src=\"/images/zellij-helix.jpg\" alt=\"实际效果\"></p>\n","excerpt":"","more":"<p>意外发现Zellij+Helix还挺好用的</p>\n<p>避免了vim/neovim的配置流程直接就能上手的轻量命令行开发环境</p>\n<p>稍微了解一下二者的快捷键就能舒适码字了</p>\n<p>甚至还都是rust出品</p>\n<p>即刻尝试一下<a href=\"https://zellij.dev/\">Zellij</a>和<a href=\"https://helix-editor.com/\">Helix</a>吧!</p>\n<p>// 至于Helix没有文件树显示的方案,反正Helix选择文件挺方便的要文件树无非是希望编辑窗口居于窗口中央,倒是可以用watch和tree命令来代替还能手动设置哪些文件不用显示hhh</p>\n<p><img src=\"/images/zellij-helix.jpg\" alt=\"实际效果\"></p>\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":"cm7jziody001swi2bfmuk60pc","content":"<p>2025-02-25</p>\n<p>最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~</p>\n","excerpt":"","more":"<p>2025-02-25</p>\n<p>最近整理了一下缓存部署起来方便多了,有空就写点东西记录一下吧~</p>\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":"cm7jziody001uwi2b4q3m2491","content":"<p>不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。</p>\n<p>今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。</p>\n<blockquote>\n<p>P.S.最近我都经历了些什么:</p>\n<ol>\n<li>时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;</li>\n<li>学习了一些C++基础,在洛谷上刷了不少算法题;</li>\n<li>ACM招新赛被薄纱,差一题进入校队;</li>\n<li>对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;</li>\n<li>入坑战地,爽爽爽;</li>\n<li>被一位巨强的学长发掘,加入NUDT超算队;</li>\n<li>面临三个考试周,熬过去就是胜利;</li>\n</ol>\n</blockquote>\n<p>虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。</p>\n<p>这里,毕竟是我梦开始的地方。</p>\n<blockquote>\n<p>胸怀祖国,团结协作,志在高峰,奋勇拼搏!</p>\n</blockquote>\n<p>今天是2023年12月6日,加油!</p>\n<hr>\n<p>修改一下,有的话还是不适合明说哦</p>\n<p>5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==</p>\n","excerpt":"","more":"<p>不知不觉已经高中毕业快半年了,现在在NUDT的生活还算适应吧,交到了一些很有趣的朋友并且在技术方面取得了一定突破(很期待明年的asc2024呢),今天看到华科一位学长的博客突然想起我还没好好搭建过自己的Blog,于是心血来潮搞了下我的Github Pages。</p>\n<p>今后会在这里更新记录自己的生活,学习,工作,以及一些想法,希望能坚持下来吧。</p>\n<blockquote>\n<p>P.S.最近我都经历了些什么:</p>\n<ol>\n<li>时长21天军训,认识了一群很可爱的班长(尤其是负责我们5班6班的英子),初步和队里的同学了解;</li>\n<li>学习了一些C++基础,在洛谷上刷了不少算法题;</li>\n<li>ACM招新赛被薄纱,差一题进入校队;</li>\n<li>对算法竞赛感到疑惑,尝试学习Flutter和操作系统开阔视野;</li>\n<li>入坑战地,爽爽爽;</li>\n<li>被一位巨强的学长发掘,加入NUDT超算队;</li>\n<li>面临三个考试周,熬过去就是胜利;</li>\n</ol>\n</blockquote>\n<p>虽然天天早八满课很不爽,但是平时还是可以学习自己想学的技术周末也可以打游戏感觉还行吧,我还是相信NUDT,既来之则安之。</p>\n<p>这里,毕竟是我梦开始的地方。</p>\n<blockquote>\n<p>胸怀祖国,团结协作,志在高峰,奋勇拼搏!</p>\n</blockquote>\n<p>今天是2023年12月6日,加油!</p>\n<hr>\n<p>修改一下,有的话还是不适合明说哦</p>\n<p>5YK75a2p5a2Q5Lus77yM5b+r6YCD5ZWK77yB77yB77yBCg==</p>\n"}],"PostAsset":[],"PostCategory":[{"post_id":"cm7jziodr000bwi2bdhi71dk3","category_id":"cm7jziods000fwi2b6sz39o2v","_id":"cm7jziodu000twi2b8ee81dmz"},{"post_id":"cm7jziods000hwi2b19t43c6n","category_id":"cm7jziodu000nwi2bg9k8dxzp","_id":"cm7jziodv000zwi2b12zyds9h"},{"post_id":"cm7jziodt000kwi2b320w2nl5","category_id":"cm7jziodu000uwi2b02p27nyj","_id":"cm7jziodw0014wi2bab972bli"},{"post_id":"cm7jziodv000xwi2b6ebgcwqs","category_id":"cm7jziodu000nwi2bg9k8dxzp","_id":"cm7jziodw0016wi2b4hlk8p77"},{"post_id":"cm7jziodt000mwi2bcvznhn4q","category_id":"cm7jziodv0010wi2b1nt86jtj","_id":"cm7jziodw0018wi2b3s1j4w7g"},{"post_id":"cm7jziody001pwi2bck6n2j6b","category_id":"cm7jziodv0010wi2b1nt86jtj","_id":"cm7jziodz001vwi2bbp098ntb"}],"PostTag":[{"post_id":"cm7jziodq0005wi2b46qac5mo","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziodr0008wi2b05p82hfn"},{"post_id":"cm7jziodn0001wi2b80cf2h59","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziodr000awi2b1miz4vlj"},{"post_id":"cm7jziodq0006wi2bhm74a0a9","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziods000dwi2bbszzcsxv"},{"post_id":"cm7jziodr0009wi2b5h330fp7","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziods000gwi2b3rlb77wm"},{"post_id":"cm7jziodo0002wi2bhhu604l9","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziodt000jwi2bc1ow4yga"},{"post_id":"cm7jziodr000bwi2bdhi71dk3","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziodt000lwi2bf95dfmcu"},{"post_id":"cm7jziodp0004wi2baobvgc5p","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziodu000owi2b21bqckyf"},{"post_id":"cm7jziods000ewi2bdc6000t9","tag_id":"cm7jziodt000iwi2bfqt12taw","_id":"cm7jziodu000rwi2b8ik6285y"},{"post_id":"cm7jziods000hwi2b19t43c6n","tag_id":"cm7jziodu000qwi2bazol064r","_id":"cm7jziodv000ywi2bhmqc29j3"},{"post_id":"cm7jziodv000xwi2b6ebgcwqs","tag_id":"cm7jziodu000qwi2bazol064r","_id":"cm7jziodw0013wi2b97dk31nx"},{"post_id":"cm7jziodt000kwi2b320w2nl5","tag_id":"cm7jziodv000wwi2bdhq12weu","_id":"cm7jziodw0017wi2b8i031bka"},{"post_id":"cm7jziodt000kwi2b320w2nl5","tag_id":"cm7jziodu000qwi2bazol064r","_id":"cm7jziodw0019wi2bb4x9hl4j"},{"post_id":"cm7jziodt000mwi2bcvznhn4q","tag_id":"cm7jziodw0015wi2b0pf17f27","_id":"cm7jziodw001bwi2b67m7fq36"},{"post_id":"cm7jziodu000pwi2b49gyhjcz","tag_id":"cm7jziodw001awi2bdhuo5k7e","_id":"cm7jziodw001dwi2bf033hi6l"},{"post_id":"cm7jziodu000swi2ba2br64lz","tag_id":"cm7jziodw001awi2bdhuo5k7e","_id":"cm7jziodw001fwi2b0qug30wm"},{"post_id":"cm7jziodv000vwi2baw0jbh0g","tag_id":"cm7jziodw001ewi2b09f1fndp","_id":"cm7jziodx001iwi2bguwveo74"},{"post_id":"cm7jziodv000vwi2baw0jbh0g","tag_id":"cm7jziodx001gwi2b4umfd84q","_id":"cm7jziodx001jwi2b2ol893th"},{"post_id":"cm7jziodv0011wi2bauxoh2vo","tag_id":"cm7jziodw0015wi2b0pf17f27","_id":"cm7jziodx001mwi2b97lyhx5q"},{"post_id":"cm7jziodv0011wi2bauxoh2vo","tag_id":"cm7jziodx001kwi2bei49d5xr","_id":"cm7jziodx001nwi2b8hy800xl"},{"post_id":"cm7jziodv0011wi2bauxoh2vo","tag_id":"cm7jziodx001gwi2b4umfd84q","_id":"cm7jziodx001owi2bbvgn2lio"},{"post_id":"cm7jziody001pwi2bck6n2j6b","tag_id":"cm7jziodw0015wi2b0pf17f27","_id":"cm7jziody001rwi2b3d1zaebh"},{"post_id":"cm7jziody001qwi2ba7oj09d4","tag_id":"cm7jziodw001awi2bdhuo5k7e","_id":"cm7jziody001twi2ba7og07d0"},{"post_id":"cm7jziody001swi2bfmuk60pc","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziodz001wwi2b0gvi282t"},{"post_id":"cm7jziody001uwi2b4q3m2491","tag_id":"cm7jziodp0003wi2be4zr9g22","_id":"cm7jziodz001xwi2bhi5dgpwn"}],"Tag":[{"name":"日志","_id":"cm7jziodp0003wi2be4zr9g22"},{"name":"TEST","_id":"cm7jziodt000iwi2bfqt12taw"},{"name":"音乐","_id":"cm7jziodu000qwi2bazol064r"},{"name":"Vocaloid","_id":"cm7jziodv000wwi2bdhq12weu"},{"name":"技术","_id":"cm7jziodw0015wi2b0pf17f27"},{"name":"技术分享","_id":"cm7jziodw001awi2bdhuo5k7e"},{"name":"板绘","_id":"cm7jziodw001ewi2b09f1fndp"},{"name":"生活","_id":"cm7jziodx001gwi2b4umfd84q"},{"name":"学习","_id":"cm7jziodx001kwi2bei49d5xr"}]}} |