# CoAUEReader **Repository Path**: dubious/co-auereader ## Basic Information - **Project Name**: CoAUEReader - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-30 - **Last Updated**: 2026-07-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CoAUEReader 晶核 CoA(Seria.exe,UE4.23+ Shipping,无 PDB)只读内存工具集。 从定位 GNames / GWorld 起步,现已打通:**玩家链、血量、面板属性、怪物列表+血量、相机 POV、全对象枚举(GUObjectArray)**。 > 全程 ReadProcessMemory 只读,不写进程。需**管理员权限**运行 Python(仅标准库 ctypes)。 > 游戏重启无需改动(ASLR 自动适配);游戏版本更新后重跑 `find_gnames.py` / `find_gworld.py`。 ## 快速开始 ```bash cd D:\Workspace\Python\CoAUEReader python ue_reader.py world # GWorld / 当前地图 / PersistentLevel python ue_reader.py player [-w 1] # 玩家: 坐标 + 生命/上限 + 能量/精力/经验 + 相机POV python ue_reader.py monsters [-w 1] # 怪物/NPC/魔偶: 分类 + 距离 + 坐标 + 血量 python ue_reader.py gobjects [类名] # GUObjectArray: 13.6万对象按类名秒搜 python ue_reader.py tp [序号] [--hold 秒] # [写内存!] 瞬移到怪物身边 2.5m python ue_reader.py attrs [-f] # 玩家名称/战力/能量/精力 (ASC/PIC 链) python ue_reader.py actors # 场景 Actor 统计 python ue_reader.py dump_names # 导出 FName 名字池 python ue_reader.py name 3 # 解析 FName 索引 ``` python 不在 PATH 时:`.\ue.bat <命令>` 或 `uv run ue_reader.py <命令>`。 ## 可视化 GUI(PyQt5) ```bash coa_gui.bat # 双击即可;或:python coa_gui.py (需管理员,脚本自动提权) ``` 后台线程 300ms 刷新、UI 不卡顿的实时窗口: - **概览**:当前地图 / UWorld 类 / 玩家坐标 / 生命条(当前·上限) / 面板(能量/精力/经验) / 相机 POV - **怪物表**:分类·距离·类名·对象名·坐标,`[怪物]` 行带血量条(绿/黄/红,仅战斗场景受击后下发) - **雷达俯视图**(右侧):玩家居中,实体按相对位置着色(怪物红 / NPC 蓝 / 魔偶绿 / 物件灰),可勾选「跟随相机」让前方朝上,范围可调(20–120m) - **对象**:按类名子串搜 GUObjectArray(13.6 万对象秒搜,命中前 2000 条) - **日志**:附加 / 搜索 / 错误带时间戳 工具栏:暂停/继续 · 立即刷新 · 刷新周期(300/500/1000ms) · 重试附加。仅 import `ue_reader` 的数据函数,不持有偏移,游戏版本更新后跟随 `ue_reader.py` 自动生效。 ## 网络狩猎(明文发包点,进行中) 已锁定:**战斗服务器 = TCP 47.117.165.231:51001,战斗 socket fd = 11040 (0x2B20)**(句柄遍历+getsockname 实证,重登游戏后重跑 `probes/find_fd.py` 取新值)。 ```bash python probes/find_fd.py # 句柄遍历: 列出全部 socket fd 及端点身份 python probes/disasm_callsites.py # capstone 反汇编 socket 调用点函数(注解字符串/跳板) python probes/vtable_live_scan.py # 各网络簇 vtable 活对象扫描 python probes/pe_exports.py # 磁盘 DLL 导出表解析(零依赖) ``` - 完整 ws2_32 跳板表已解析(`+0x513D488..+0x513D5B8`,send +4E0 / recv +520 / sendto +4B8 …)。 - 模块簇身份:0x139D=LuaSocket、0x2E1=UE4 FSocketBSD、0x472=Apache Thrift(明文点 `TSocket::write_partial` = `+0x472C3F0`)、0x49F8/0x482=Wwise 音频、0x5022=libcurl+OpenSSL;sscronet/GNA/RTC 均在用。 - 已排除:裸 Thrift TSocket、已知 FSocket 包装类(均无活对象)。 - 最后一里(动态):对 `ws2_32!send`/`sendto` 下条件断点 `RCX==fd`,放技能后栈顶返回地址即明文发包调用点。 - 全部细节:[probes/packet_hunt_notes.md](probes/packet_hunt_notes.md) · 方法论沉淀:[skill/ue-memory-reader/references/coa-network.md](skill/ue-memory-reader/references/coa-network.md) ## 关键偏移速查(2026-07-30 游戏版本,相对 Seria.exe 基址) ### 引擎全局 | 目标 | 偏移 | |---|---| | GWorld 槽位 | `+0x74063A0` | | FNamePool 结构体 | `+0x7269440`(Blocks 数组 +0x10) | | **GUObjectArray** | `+0x72A5B60`(ObjObjects.Objects 槽位;FUObjectItem 0x18 字节、每 chunk 65536 项) | | **GEngine** | `+0x7402938`(+0x7E0 → GameViewportClient) | ### 玩家链(GameInstance 路径,副本/城镇通用) ``` UWorld+0x1C0 → GameInstance+0x40(LocalPlayers) → LocalPlayer+0x30 → PlayerController PC+0x310 → PlayerState PC+0x338/0x388 → Pawn PS+0x368 → Pawn(备用) PS+0x3E8 玩家名(FString) PS+0x490 玩家ID(int) PC+0x820 → PIC, PIC+0x2150 战力(int) UWorld+0x178 Levels 数组(子关卡, 副本内容在这) ULevel+0x98 Actors(Num+0xA0) ``` ### 血量 / 属性 ★ ``` 任意 Pawn+0x1060 → 属性块: 当前血 = 块内 int32 签名 (V,0,1,0) 上限 = (1,0,V,0) (仅城镇块加载) 玩家/怪物同构; 怪物首次受击后才下发, 玩家刚进图未下发时开一次角色面板触发推送 玩家专属 arena (面板仓库, 跨地图稳定): 记录签名 (ptr_lo, 310/311, 68, id, V, 0, 19, flags) ← flags 可变, 匹配必须放宽! 锚点=当前血记录(id=-7)地址, 缓存 probes/player_arena_cache.txt 锚点+0x04 当前血 -0x1C 上限 -0x4BC 经验 -0x1DC 精力 -0x1BC 能量上限 -0x13C 能量 自动定位: mt 扫描找 pack('<5i', -7, 当前血, 0, 19, 48) 相机: PC+0x3A0 → CameraManager+0x1190 = POV{Loc(3f) Rot(3f) FOV +0x18, Aspect +0x2C} GameState (Actors 里类名含 GameState): +0x334 = ElapsedTime (float, 秒) ``` ## 逆向方法论(三天血泪教训) 1. **别猜数据类型**——怪物血量按 float 扫了两天,实际是 int32。扫描必须 int/float/double/文本并行。 2. **值跟随实验是杀手锏**:换装改上限,1537 个 `int=旧值` 候选只剩 8 个跟随;受击找"下降"字段同理。 3. **签名 > 偏移**:字段位置随场景漂移(+0x2D0/+0x300/+0x2E8),四 int 签名 `(V,0,1,0)` 稳定。 4. **服务器按需下发**:读不到 ≠ 工具 bug。开角色面板/首次伤害才推送,怪 aggro 不推、掉血才推。 5. **记录签名必须放宽**:flags 字段会变(19,48 / 19,131…),严格匹配 = 莫名丢数据。 6. **多线程扫描**:ThreadPoolExecutor + ctypes RPM 释放 GIL,4.1GB 全内存指针反查 23 秒。 7. **指针反查爬容器**:目标无直接指针时,VirtualQuery 拿区域 → 扫"指向区域的指针" → 逐级上爬。 ## 文件清单 | 文件 | 用途 | |---|---| | `ue_reader.py` | 主工具(9 个命令) | | `coa_gui.py` / `coa_gui.bat` | 可视化 GUI(PyQt5):地图/玩家/怪物表/雷达/血量条/对象搜索/日志 | | `find_gnames.py` / `find_gworld.py` | GNames/GWorld 定位脚本(版本更新后重跑) | | `find_attrs.py` | 玩家属性定位的验证脚本 | | `probes/mt_ptrscan.py` | 多线程指针反查:`mt_ptrscan.py [span]` | | `probes/mt_hpscan.py` | CE 式下降值扫描:`pass1` 采样 → 打怪 → `pass2` 对比 | | `probes/hp_hunt_notes.md` | 血量逆向完整狩猎日志(三次实证+全部结论) | | `probes/ambush*.py` | ASC 高频监视脚本(float 路线,已证伪,留档) | | `gnames_report.md` / `gworld_report.md` | 初始定位报告 | | `README_usage.md` | 早期使用说明 | ## 技能同步 本项目的全部经验已同步到 Kimi 技能 `ue-memory-reader` (`%APPDATA%\kimi-desktop\daimon-share\daimon\skills\ue-memory-reader\`): SKILL.md 工作流、`references/ue4-layouts.md` 结构偏移、`references/coa-attrs.md` 属性逆向手册、scripts 工具集。 ## 注意 - 仅用于本地调试/逆向学习。在线游戏内存操作可能违反用户协议并导致封号。 - 已知限制:副本倒计时字段未最终验证(GameState+0xC1C 静态 180.0 待副本内确认);怪物血量服务器按需推送,未受击时属性块为 0(血条 UI arena 里有满血副本,但多怪无法逐只关联,定稿方案=受击后显示);物攻/魔攻/防御等战斗属性疑似开面板时实时计算,未找到稳定存储。 ## 血条 UI arena(2026-07-31 新增) 怪物血量在血条 UI 子系统有独立副本,进图未受击就存在(=满血): - 记录格式 `(owner_ptr:8B, 68, id, V, 0, 19, flags)`(0x20 步进);第一字段是完整 64 位指针 - owner 是常驻任务对象(+0x18 ASCII 名 `CreateScreenHPUI`/`ClearBar`),跨进图不换、单例 - arena 每图重分配 → 按图重扫记录(小区域签名扫 ~3s),图内缓存 0ms - owner 文件缓存 `probes/hpui_owners.txt`(按 PID),跨命令调用免重扫 - 记录无入边指针(ptrscan 验证)→ 最后一跳只能签名扫 - Duo/木桩图 pawn 不在关卡 Actors 列表 → `monsters` 已加 GUObjectArray 全对象扫描兜底(0.2s)