Skip to content

About

项目已经停止维护,需要的可以自己拿去改

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

ppSR 水印补丁器(ppsr_watermark_patcher)

给 ppSR 私服(ppsr.exe,Honkai: Star Rail 4.4.5X)游戏左下角水印打运行时补丁的工具:把默认的 ppSR / discord.gg/ppSR 水印替换成自定义的两行文字,支持整行配色和逐字配色。

不修改 ppsr.exe 文件本身 —— 每次启动服务器时自动注入,exe 保持原样。


快速开始

exe 版本(推荐)

有打包好的 ppsr_watermark_patcher.exe(配置 ppsr_watermark.json ,改它即可):

  1. 编辑 ppsr_watermark.json(两行水印文字 + 颜色)
  2. 双击 ppsr_watermark_patcher.exe,UAC 弹窗点"是"
  3. 服务器启动,游戏客户端连上来,左下角水印就是你的文字

配置必须与 exe 放在同一目录(exe 只认自己旁边的 ppsr_watermark.json,缺失会自动生成默认配置)。 命令行用法同 python 版:--attach / --dry-run。

python 版

# 1. 编辑配置(两行水印文字 + 颜色)
#    同目录下 ppsr_watermark.json

# 2. 用补丁器启动服务器(会弹出 UAC 提权确认,点"是")
python ppsr_watermark_patcher.py
命令 说明
python ppsr_watermark_patcher.py 启动 ppsr.exe + 打水印补丁(推荐日常使用)
python ppsr_watermark_patcher.py --attach ppsr.exe 已在运行,只打补丁
python ppsr_watermark_patcher.py --dry-run 离线自检:验证配置能否装入槽位,不启动服务器

需要管理员权限(ppsr.exe 本身要求提权,补丁器要写入它的进程内存)。 直接双击运行或从普通 CMD 运行都会自动弹 UAC 请求提权。

重新打包 exe(改了代码后)

pip install pyinstaller
pyinstaller --onefile --console --name ppsr_watermark_patcher ppsr_watermark_patcher.py
# 产物在 dist\ppsr_watermark_patcher.exe,连同 ppsr_watermark.json 一起拷贝使用

配置说明(ppsr_watermark.json)

{
  // ppsr.exe 的路径(可绝对路径或相对本文件所在目录)
  "ppsr_exe": "E:\\HSRBetaPS\\ppSR_REL_4.4.5X\\ppsr.exe",

  // 第一行(主标)—— 替换原 "ppSR"
  "line1": {
    "text": "MY SERVER",          // 水印文字,任意字符
    "size": 18,                    // 字号(Unity 富文本)
    "color": "#FFD700"             // 整行单色:一个 #RRGGBB
  },

  // 第二行(副标)—— 替换原 "discord.gg/ppSR"
  "line2": {
    "text": "qq 12345678",
    "size": 12,
    "color": "#9C80D6"             // 整行单色写法
    // "color": ["#FE9A9A", "#D990B0", "#B586C7"]   // 逐字配色写法:
    //                                            //   颜色数组长度必须与 text 字符数一致
  }
}

color 字段两种写法

写法 效果 占用容量
"color": "#FFD700" 整行统一颜色,一个 <color> 包裹 小(约 6 字节/字)
"color": ["#FE9A9A", "#D990B0", ...] 逐字着色,每字一个 <color> 大(约 19 字节/字)

容量上限

水印 Lua 在 ppsr.dll 内存里是定长槽位,新内容(两行文字的富文本标记总字节数)不能超过:

槽位 base64 长度 解码后上限
Lua1(旧版水印) 1732 字符 1299 字节
Lua2(新版水印) 2168 字符 1626 字节

超限会明确报错,提示缩短文字或减少逐字配色。参考容量:整行单色约 6 字节/字,两行合计可用 1000+ 字节,正常使用绰绰有余;逐字配色每字约 19 字节,两行合计约 80 字以内。

注:逐字配色时若与整行单色混用(line1 单色、line2 逐字),按各自写法分别计算。


工作原理

  1. 结构:ppsr.exe 是定制版 PyInstaller onefile(载荷加密,无法直接改文件)。运行时解压到 %TEMP%\onefile_<pid>_*,实际服务器本体是 ppsr.dll —— Nuitka 编译的 Python(FreeSR 改版),子进程将其加载进内存。
  2. 水印机制:服务器在玩家每次心跳(PlayerHeartBeatCsReq)时经 ClientDownloadDataScNotify 推送一段 base64 编码的 Lua 给游戏客户端,客户端 LuaShell 执行:
    • beta_text():把 UIRoot/AboveDialog/BetaHintDialog(Clone) 移到左下角 (-10, 10, 0),文字改为水印第一行;
    • version_text():把 VersionText 改为水印第二行;
    • mhy_text():隐藏官方提示文字。
  3. 补丁方式:水印 base64 以明文存在 ppsr.dll 的 .rdata 字符串表中(Nuitka 条目:标记字节 + base64 + NUL 分隔)。补丁器按特征前缀 bG9jYWwgZnVuY3Rpb24gYmV0YV90ZXh0(即 local function beta_text)在内存中定位两个槽位,把新 Lua 重新 base64 编码后等长原位写回(长度不足用 = 填充,Python 的 base64 解码容忍尾部填充),写入后读回验证。
ppsr_watermark_patcher.py
 ├─ 1. 自提权(UAC)
 ├─ 2. 启动 ppsr.exe
 ├─ 3. 轮询找到加载了 ppsr.dll 的子进程(Toolhelp 快照)
 ├─ 4. 读取 .rdata → 扫描水印 base64 槽位(2 个)
 ├─ 5. 配置 → 生成新 Lua → base64 等长写回(WriteProcessMemory)
 └─ 6. 读回解码验证,打印补丁后的水印文字

常见问题

Q:提示"新水印 Lua 太大"? 缩短 line1/line2 的文字,或把逐字配色 color 数组改成整行单色写法。

Q:游戏里水印没变?

  • 确认是用 ppsr_watermark_patcher.py 启动的服务器(而不是直接运行 ppsr.exe);
  • 确认补丁输出显示两个 [OK] 且读回的文字是你配置的内容;
  • 游戏客户端需要重新连接(水印随心跳下发,连上后下一次心跳生效);
  • 如果之前直接跑过 ppsr.exe,先结束所有 ppsr 进程再用补丁器启动。

Q:弹 UAC 提示是正常的吗? 正常。ppsr.exe 本身要求管理员权限,补丁器也需要同样的权限写入其进程内存。

Q:会修改 ppsr.exe 文件吗? 不会。只写入运行中进程的内存,exe 与 ppsr.dll 文件均保持原样;重启后补丁需要重新打(补丁器每次启动自动完成)。

Q:换了新版本/新客户端后还能用吗? 补丁器按特征前缀扫描定位,不依赖固定偏移,只要水印 Lua 结构不变(local function beta_text)就能工作。若 ppSR 大版本更新改变了水印实现,需重新适配。

Q:--dry-run 显示没有 ppsr.dll? 离线自检会读取 misc\_dump\ 下运行时提取的 ppsr.dll 样本。该目录是分析时留存的,被清理后 dry-run 只跳过自检;正常启动不受影响。


目录结构

ppSR_REL_4.4.5X/
├── ppsr.exe                      # 服务器本体(不动它)
├── ppsr_watermark_patcher.py     # 本补丁器
├── ppsr_watermark.json           # 水印配置(改这里)
├── README.md                     # 本文档
└── misc/                         # 服务器数据(hotfix.json、freesr-data.json、resources/ 等)

逆向过程备忘(开发者向)

  • 外层 exe:MSVC 壳(.text 仅 50KB)+ 14MB 高熵加密载荷,无标准 PyInstaller COOKIE/PYZ 魔数 → 定制 onefile。
  • 运行时释放 %TEMP%\onefile_<pid>_*:ppsr.dll(33.8MB,Nuitka 编译,.text 21.5MB + .rdata 11.9MB)、python314.dll、__mypyc.pyd 等。
  • 进程模型:父进程 = 引导器(负责解压与清理),子进程 = 实际应用(加载 ppsr.dll)。杀掉父进程会让解压目录残留在 %TEMP%。
  • 服务器 = FreeSR 改版:Flask dispatch(/query_dispatch、/query_gateway、账号 API、/srtools)+ KCP 游戏服(game/handlers/*、game/services/*、msg/classes_pb2.py)。
  • 启动时有密码校验("Enter the correct password:",key 存于 misc/persistent.json)。
  • 水印 Lua 两段完整源码见分析记录(解码产物含 beta_text/version_text/mhy_text 三个函数)。

About

项目已经停止维护,需要的可以自己拿去改

Resources

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages