objval/osu-helper

GitHub: objval/osu-helper

一个面向 osu!lazer 的 Relax 游戏辅助引擎,通过读取游戏内存和解析谱面来实现拟人的自动按键。

Stars: 0 | Forks: 0

# osu-helper **一个用于 osu!lazer 的合法 relax 工具** 从内存中读取游戏状态,从磁盘解析 beatmap,并注入 类似人类的按键操作,具有可配置的 timing jitter、hold durations、 error injection 和 fatigue simulation。
## 功能 | 功能 | 描述 | |---------|-------------| | **类似人类的 timing** | 带有提前偏置的 Gaussian jitter、BPM scaling 和 fatigue | | **可变 holds** | 因按键和 BPM 而异的 Skewed-normal hold 持续时间 | | **智能交替** | 具有感知 BPM 的 Z/X 交替,并以 singletap 作为后备 | | **Error injection** | 5% 的几率出现“bad hits”,以模仿人类的不稳定性 | | **Fatigue simulation** | 在长时间游玩中 timing 会有轻微下降 | | **Scancode injection** | 使用 KEYEVENTF_SCANCODE,而不是 virtual keys | | **字符串混淆** | 编译时的 XOR —— 二进制文件中没有敏感字符串 | | **配置热重载** | 游玩时编辑 config.ini,2 秒内自动重载 | | **Debug 日志** | 可选的 debug.log,用于诊断 timing 和按键操作 | | **最小足迹** | 3 个 DLL 导入,387KB 的二进制文件,无 overlay,无 hooks | ## 架构 ``` ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │ main.cpp │────▶│ lazer.h │────▶│ process.h │ │ (game loop)│ │ (pointer │ │ (memory │ │ │ │ chain) │ │ reading) │ └──────┬──────┘ └──────────────┘ └──────────────┘ │ ▼ ┌──────────────┐ ┌──────────────┐ │ relax.h │────▶│ beatmap.h │ │ (key sched │ │ (.osu file │ │ + timing) │ │ parser) │ └──────────────┘ └──────────────┘ ``` **数据流:** 1. `process.h` 找到 osu!.exe 的 PID 并打开一个只读句柄 2. `lazer.h` 扫描 anchor pattern,遍历 .NET 指针链以找到游戏基地址 3. `lazer.h` 从内存中读取游戏时间、beatmap 信息和游玩状态 4. `beatmap.h` 从磁盘解析当前的 .osu 文件(lazer 的 content-addressed store) 5. `relax.h` 在 beatmap 物件时间点以类似人类的 timing 调度按键操作 6. `relax.h` 通过带有 scancode 的 SendInput 注入按键 ## 构建 ### 前置条件 - Windows 10/11 - Visual Studio 2022(任意版本)包含 C++ 桌面开发工作负载 - 无外部依赖(所有库均为 Windows SDK) ### 构建 ``` build.bat ``` 这会调用 `vcvarsall.bat x64`,然后使用以下参数进行编译: - `/O2` — 速度优化 - `/GL /LTCG` — 全程序与链接时优化 - `/EHsc /MT` — 静态 CRT,无 DLL 依赖 - `/GS-` — 禁用安全 cookies(更小的二进制文件) - `/DNDEBUG` — 无 debug 断言 输出:`AppHelper.exe` (387KB) ## 用法 1. 构建项目 2. 打开 osu!lazer 3. 运行 `AppHelper.exe`(控制台会自动隐藏) 4. 开始一张地图 —— **只需用鼠标瞄准,bot 会按下 Z/X** 5. 在游玩时编辑 `config.ini` —— 更改将在 2 秒内自动重载 ### 控制 | 按键 | 动作 | |-----|--------| | `Insert` | 暂停 / 恢复(暂停时释放所有按键) | ## 配置参考 所有设置都在 `config.ini` 中。可以在游玩时编辑 —— 会自动重载。 ### Timing | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `hit_jitter_ms` | float | `12` | 基础 timing jitter(±ms,Gaussian)。数值越低 = 越紧凑 | | `timing_bias_ms` | float | `-2` | Timing 偏置。负数 = 提前击打(人类玩家会这样做) | | `bpm_jitter_scale` | float | `0.002` | BPM 增加 jitter 的程度。`0.002` = 每 100 BPM 增加 +0.2ms | ### Hold 持续时间 | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `hold_center_k1` | float | `65` | K1 hold 持续时间中心(ms) | | `hold_spread_k1` | float | `15` | K1 hold 持续时间散布(Gaussian) | | `hold_center_k2` | float | `75` | K2 hold 持续时间中心(ms) | | `hold_spread_k2` | float | `14` | K2 hold 持续时间散布(Gaussian) | | `hold_floor` | float | `25` | 最小 hold 时间(ms) | | `hold_ceiling` | float | `120` | 最大 hold 时间(ms) | | `bpm_hold_scale` | float | `0.001` | BPM 缩短 hold 的程度。`0.001` = 每 100 BPM 减少 -10ms | ### Error Injection | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `error_chance` | float | `0.05` | 出现“bad hit”的几率(5%)。使 timing 分布更宽 | | `error_multiplier` | float | `2.5` | bad hit 的严重程度(2.5倍更宽的 jitter) | ### Release | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `release_jitter_ms` | float | `4` | 按键 release timing 的 jitter(±ms)。增加真实感 | ### 全局 | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `manual_offset_ms` | int | `0` | 全局 timing 偏移。负数 = 更早,正数 = 更晚 | | `bpm_alternate_threshold` | int | `120` | 高于该 BPM 则始终进行交替按键 | | `singletap_mode` | bool | `false` | 强制 singletap(除非 BPM > 阈值,否则仅使用 K1) | ### Fatigue | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `fatigue_rate` | float | `0.0001` | 每游玩一秒增加的 jitter | | `fatigue_max` | float | `1.5` | 最大 fatigue 乘数(1.5 = 多 50% 的 jitter) | ### 按键 | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `left_key` | int | `90` | 左键 VK 码(90=Z, 67=C) | | `right_key` | int | `88` | 右键 VK 码(88=X, 86=V) | ### 系统 | 键 | 类型 | 默认值 | 描述 | |-----|------|---------|-------------| | `tick_ms` | int | `2` | 主循环 sleep 时间(ms)。2 = ~500Hz | | `tick_jitter_ms` | int | `1` | sleep 时的随机 jitter(±ms) | ## 推荐配置 ### 紧凑(看起来像高熟练度玩家) ``` hit_jitter_ms=8 timing_bias_ms=-3 hold_center_k1=55 hold_spread_k1=10 hold_center_k2=60 hold_spread_k2=10 error_chance=0.03 ``` ### 默认(平衡的类人表现) ``` hit_jitter_ms=12 timing_bias_ms=-2 hold_center_k1=65 hold_spread_k1=15 hold_center_k2=75 hold_spread_k2=14 error_chance=0.05 ``` ### 宽松(看起来像休闲玩家) ``` hit_jitter_ms=18 timing_bias_ms=-1 hold_center_k1=75 hold_spread_k1=20 hold_center_k2=85 hold_spread_k2=18 error_chance=0.08 ``` ## 检测分析 ### Import Table ``` KERNEL32.dll — OpenProcess, ReadProcessMemory, VirtualQueryEx USER32.dll — SendInput, GetCursorPos, GetForegroundWindow, MapVirtualKeyA SHELL32.dll — SHGetFolderPathW ``` 没有 D3D11,没有 ImGui,没有 hooks,没有 VirtualAlloc,没有 WriteProcessMemory。 ### 反检测措施 | 措施 | 状态 | |---------|--------| | 编译时字符串 XOR | 所有敏感字符串均已混淆 | | 只读进程访问 | 仅限 VM_READ + QUERY_INFO | | Scancode injection | KEYEVENTF_SCANCODE,而非 virtual keys | | 零 dwExtraInfo | SendInput 上无注入指纹 | | 隐藏控制台 | 启动时 SW_HIDE | | 静态 CRT | /MT —— 无 MSVCRT 依赖 | | 无 overlay | 无 D3D11,无 DXGI,无窗口创建 | | 无 hooks | 无 WH_MOUSE_LL,无 WH_KEYBOARD_LL | | 配置热重载 | 无需重启即可更改设置 | ### 残余风险 | 风险 | 级别 | 缓解措施 | |------|-------|------------| | 进程句柄 | 低 | 许多合法工具也会打开 osu! 句柄 | | 内存读取 | 低 | 每 tick 2-3 次指针读取,足迹极小 | | SendInput | 中 | Scancode injection,类人 timing | | 统计分析 | 低 | Gaussian jitter,error injection,fatigue | ## 项目结构 ``` osu-helper/ ├── README.md ← this file ├── ARCHITECTURE.md ← full technical map ├── config.ini ← runtime settings ├── build.bat ← MSVC build script ├── .gitignore └── src/ ├── main.cpp ← entry point, game loop ├── config.h ← INI parser, hot-reload ├── process.h ← process attachment, memory reading ├── lazer.h ← lazer pointer chain, game state ├── beatmap.h ← .osu file parser ├── relax.h ← relax bot engine ├── obf.h ← compile-time string obfuscation ├── dbg.h ← debug logging ├── playfield.h ← coordinate projection ├── human.h ← human-like mouse movement └── aim.h ← aim assist engine (unused) ``` ## 工作原理 ### 指针链 (osu!lazer 2026.518.0) ``` 1. Scan for anchor: 1024.0f, 768.0f as floats in memory 2. Go back 0x24 bytes → ExternalLinkOpener pointer 3. Read ExternalLinkOpener + 536 → APIAccess pointer 4. Read APIAccess + 784 → OsuGameBase pointer 5. Read OsuGameBase + 1232 → BeatmapClock → CurrentTime 6. Read OsuGameBase + 1104 → Beatmap → BeatmapInfo ``` ### Timing 分布 ``` Human player: ████░░░░░░ (Gaussian, centered slightly early) Blatant relax: ██████████ (uniform, perfect timing every hit) osu-helper: █████░░░░░ (Gaussian, early bias, 5% error injection) ``` ### Hold 持续时间 ``` Fixed: ██████████ (same duration every hit) osu-helper: █████░░░░░ (skewed-normal, BPM-scaled, per-key variation) ``` ## 致谢 - [osu!](https://osu.ppy.sh) 作者 peppy - [osu!lazer](https://github.com/ppy/osu) —— 开源客户端 - osu! 社区提供的 beatmap 格式文档 ## 许可证 本项目仅供教育目的使用。
标签:C++, osu!, 内存读取, 安全意识培训, 按键注入, 数据擦除, 游戏外挂, 游戏辅助, 端点可见性