环境:绿联 DX4600(N5105)/ Unraid 7.3.1 老毛子破解版 / 内部 eMMC 启动

背景

绿联 DX4600 自带 29G 内部 eMMC。前期已将 Unraid 系统盘从 U 盘迁移到 eMMC(/boot 挂载于 /dev/mmcblk0p1),启动不再依赖 U 盘。但许可证验证仍然需要 U 盘插着——拔掉 U 盘重启后立即掉许可(invalid key - EGUID)。

原理

双层 GUID 验证

Unraid 破解版许可证验证涉及两个独立计算的 GUID,必须完全匹配才有效:

  • flashGUID:emhttpd 自己算。通过 /dev/disk/by-label/UNRAID 找到闪存设备,从 sysfs 读取硬件序列号,按设备类型选择 GUID 格式(USB → VVVV-MMMM-SSSS-...,eMMC → 01-XXXXXX...

  • regGUID:unraider 破解组件算。通过 unraid_init 函数决定来源,构造后与 flashGUID 比对

U 盘在场时 by-label/UNRAID 指向 U 盘,两个 GUID 都从 U 盘算出,匹配 → 有效。拔掉 U 盘后 by-label/UNRAID 指向 eMMC,flashGUID 变成 eMMC 的值,但 regGUID 失去来源变成空值 → 不匹配 → 失效。

关键发现:变量名不匹配

逆向分析 unraider.so 的 unraid_init 函数,发现 regGUID 的来源逻辑:

unraid_init():
  1. 检查进程名是否为 "emhttpd"
  2. 设置 RSA hook(fake_RSA_public_decrypt 替换 RSA_public_decrypt)
  3. 调用 getenv("UNRAID_UUID")
     ├─ 有值 → 直接用作 regGUID(跳过 USB 读取)
     └─ 无值 → 回退到 USB 设备读取 udev 属性

go 文件里设置的是 UNRAID_GUID,但 unraider.so 实际读取的是 UNRAID_UUID——两个不同的变量名:

strings /tmp/unraider.so | grep -c 'UNRAID_GUID'   # → 0
strings /tmp/unraider.so | grep -c 'UNRAID_UUID'   # → 1

go 文件里那行 export UNRAID_GUID=... 从来就是个空操作。因为 UNRAID_UUID 从未被设置,unraider 一直走 USB 回退路径——这就是拔 U 盘掉许可的根因。

修复思路

emhttpd 从 eMMC 硬件算出的 flashGUID 是固定值(由 eMMC 序列号决定)。只要设置 UNRAID_UUID 环境变量等于这个值,regGUID 就直接来自环境变量,不再依赖 USB,两者匹配 → 许可证有效。

操作步骤

1. 获取 eMMC 的 GUID

拔掉 U 盘,重启(此时许可证会失效,但 SSH 仍可用),查看 flashGUID:

grep flashGUID /var/local/emhttp/var.ini
# 输出:flashGUID="01-XXXXXXXXXXXXXXXXXXXXXXXXXX"

这个值就是 eMMC 的自然 GUID,固定不变。

获取后可以先插回 U 盘恢复正常使用,后续步骤不需要在掉许可状态下操作。

2. 修改 go 文件

cp /boot/config/go /boot/config/go.bak   # 备份
​
# 在 unraider 启动行之前添加一行
export UNRAID_UUID=01-XXXXXXXXXXXXXXXXXXXXXXXXXX

修改后的 go 文件关键部分:

#!/bin/bash
export UNRAID_GUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX   # 原有,无用但保留
export UNRAID_UUID=01-XXXXXXXXXXXXXXXXXXXXXXXXXX             # ← 新增
export UNRAID_NAME=Tower
export UNRAID_DATE=1654646400
export UNRAID_VERSION=Pro
/lib64/ld-linux-x86-64.so.2 /boot/config/unraider
/usr/local/sbin/emhttp
# ... 其余不变

3. 关机 → 拔 U 盘 → 开机

poweroff
# 拔掉 U 盘,开机

4. 验证

grep -E "flashGUID|regGUID|regTy|configValid|mdState" /var/local/emhttp/var.ini

预期输出:

configValid="yes"
flashGUID="01-XXXXXXXXXXXXXXXXXXXXXXXXXX"
regGUID="01-XXXXXXXXXXXXXXXXXXXXXXXXXX"
regTy="Pro"
mdState="STARTED"

flashGUID == regGUIDregTy="Pro" → 许可证有效。

回退

如果修改后许可证失效,恢复很简单:

cp /boot/config/go.bak /boot/config/go

插回 U 盘,重启即可恢复。

升级注意事项

升级流程不变(下载新版 → 替换 /boot/config/unraider → WebUI 升级),但升级后需确认两点:

1. go 文件仍有 UNRAID_UUID

grep UNRAID_UUID /boot/config/go

如果丢失,补回去:

echo 'export UNRAID_UUID=01-XXXXXXXXXXXXXXXXXXXXXXXXXX' >> /boot/config/go

2. 新版 unraider 仍读 UNRAID_UUID

strings /tmp/unraider.so | grep UNRAID_UUID

有输出 → 修复继续有效。无输出 → 新版改了逻辑,需要重新逆向分析。

前提条件

  • /boot 已迁移到内部 eMMC(/dev/mmcblk0p1),系统从 eMMC 启动

  • Pro.key 位于 /boot/config/Pro.key(在 eMMC 上)

  • eMMC 分区 label 为 UNRAID(拔 U 盘后 by-label/UNRAID 自动指向 eMMC)