DEV Community

钟智强
钟智强

Posted on

不打包,打款先:基于 Gradle 的构建开关设计

本文内容及所涉及的技术,仅限用于合法授权下的安全研究、教学演示、
以及漏洞复现。严禁将本文技术用于未授权的渗透、监听、植入、操控行为。

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

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

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

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

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

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

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

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

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

📛 作者立场中立,仅为安全教育目的演示,不对滥用技术行为负责。
Enter fullscreen mode Exit fullscreen mode

💭 当您遇到无赖时,咋办?

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

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

👀 这时候你是选择原谅他?还是礼貌开战?

哼!礼貌? 我就不~ 😤🙂‍↔️

软件开发不是慈善,付费是尊重!

在我们程序员的世界里,最宝贵的不是代码,而是心血和专业积累。

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


为什么要做这个?

在我们做外包 / 项目交付 / App 定制化开发的时候,常见一种客户类型:

“能不能先给我一个 APK?我们内部先看看。”

然后是:

“我看你这包是能打出来的,那交付就是完成了嘛!我尾款晚点结~”

再然后是:你打的包,被他们改名、上传、上线、变现。尾款没了,人也拉黑了。

如果你做的是 FlutterReact Native、原生 Android (Kotlin/Java) 项目,哪怕不给源码,只要有 flutter build apk./gradlew assembleRelease 权限,他们就能绕过你。

这,就是我们为什么要写一个远程构建许可系统。


系统目标

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


系统原理:一句话总结

“在 Gradle 构建流程开始前,远程请求一个 JSON 接口,决定构建是否允许继续。”

这个 JSON 配置长这样:

{
  "x": false
}
Enter fullscreen mode Exit fullscreen mode
  • x = true 时,构建将被强制中止。
  • x = false 时,构建流程正常继续。

⚠️ 默认策略是:如果无法连接接口(超时/错误),构建也会被禁止,确保安全优先。

快速集成指南

第一步:编写构建控制脚本

命名为 back_door.gradle(或你喜欢的名字,如 config.gradle, 请不要取太明显的命名

// =====================================================================
// 🌸 构建许可控制脚本
// 可嵌入到 settings.gradle 中,以远程配置形式启用/禁用构建功能。
// 用途:防止客户未付款擅自构建 APK,或用于控制构建许可。
// =====================================================================

// ✅ 加载 Groovy JSON 解析器
import groovy.json.JsonSlurper

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

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

// =====================================================================
// 🛡️ 如果是构建任务,则执行远程许可检查
// =====================================================================
if (isBuildTask) {

    try {
        // 🌍 建立远程连接(读取 JSON 文件)
        def conn = new URL(endpoint).openConnection()
        conn.setConnectTimeout(3000) // 网络连接超时:3秒
        conn.setReadTimeout(3000)    // 数据读取超时:3秒
        conn.setRequestProperty("User-Agent", "Build_Checker/1.0")

        // 🧠 使用 JsonSlurper 解析远程 JSON 内容
        def json = new JsonSlurper().parse(conn.getInputStream())

        // ✅ 校验返回的字段格式:必须包含布尔型字段 x
        if (!(json?.x in [true, false])) {
            println("🛑 配置错误:字段 `x` 必须是 true 或 false(布尔值)")
            System.exit(1)
        }

        // ❌ 如果 x 为 true,则拒绝构建
        if (json.x == true) {
            println("🛑 灵儿封锁构建通道!你还没付尾款 💸")
            System.exit(1)
        }

        // ✅ 一切正常,输出许可通过
        println("✅ 远程许可通过 ✨")

    } catch (Exception e) {
        // 🌐 网络异常、解析失败或接口无响应时也终止构建
        println("🛑 无法完成远程验证:${e.class.name} - ${e.message}")
        System.exit(1)
    }
}
Enter fullscreen mode Exit fullscreen mode

第二步:在 settings.gradle 添加 hook

放到最后一行:

apply from: "back_door.gradle"
Enter fullscreen mode Exit fullscreen mode


apply from: "config.gradle"
Enter fullscreen mode Exit fullscreen mode

⚠️ 注意:脚本文件需与 settings.gradle 同级。建议不要命名为 build.gradle,避免和已有构建文件冲突。

支持平台

平台类型 插入方式
Flutter settings.gradle 添加 apply from: 'path/to/secretguardian.gradle'
React Native 同 Flutter,在项目根目录的 settings.gradle 添加相同配置
Java / Kotlin settings.gradlebuild.gradle 添加依赖和扫描任务
Unity (Android) 修改 mainTemplate.gradle 插入自动检测逻辑
Cordova / Expo 通过 Hook 机制集成到打包脚本 (after_prepare 等阶段)

测试方法

Flutter:

  1. 创建一个 Flutter 项目:
 flutter create build_lock_demo
Enter fullscreen mode Exit fullscreen mode
  1. 添加 back_door.gradle 并修改 settings.gradle
  2. 尝试运行:
flutter build apk
Enter fullscreen mode Exit fullscreen mode
  • 如果接口返回 { "x": true } → 构建失败,显示锁定信息
  • 如果返回 { "x": false } → 构建通过

其他平台(React Native / 原生 Android / Cordova / Unity)测试:

  1. 正常创建或打开项目
  2. back_door.gradle 放入与 settings.gradle 同级目录
  3. 在 settings.gradle 最后一行添加:
apply from: "{您的构建名称}.gradle"
Enter fullscreen mode Exit fullscreen mode
  1. 执行正常构建命令:
./gradlew assembleRelease
Enter fullscreen mode Exit fullscreen mode


如果你使用的是 Android Studio,直接点击『Run』或『Build』即可。

  • 构建过程会被远程 JSON 控制是否继续,行为与 Flutter 项目一致。

这套构建许可系统不是为了报复,而是:

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

你可以把它集成进所有项目模板,作为开发者默认的「合法防身系统」。

记住,

代码你可以复制,良心你抄不来。

Top comments (0)