ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

固件Hook技术实战:OmniDrive如何用armips汇编在MT1959固件中注入补丁

固件Hook技术实战:OmniDrive如何用armips汇编在MT1959固件中注入补丁

【免费下载链接】OmniDrive

项目地址:https://gitcode.com/gh_mirrors/omn/OmniDrive
点击查看免费下载

OmniDrive 是一个针对 MediaTek MT1959 芯片光盘驱动器的固件 Hook 修改项目,它用 armips 汇编在 Hitachi-LG / ASUS 原厂固件的固定地址上"注入补丁",让光驱获得 lead-in/lead-out 读取、raw 扇区读取,以及一条全新的自定义 READ DISC RAW 命令(0xC0),从而可以完整转储 Xbox、PS3/PS4/PS5 等主机游戏光盘。🎯 本文带你拆解它的固件注入思路:从构建流程、汇编注入点定位,到 CMAC 签名修复,全程可照着做。

一、为什么需要固件 Hook:MT1959 是个"黑盒"

MT1959 是光驱主控芯片,厂商没有公开任何 SDK。想加新功能,只有两条路:

  • 逆向:从固件反汇编,找出关键函数和数据结构的内存地址(例如DVDReadCmd、BDReadCmd、scramble 寄存器);
  • 注入:在固件镜像里找空闲空间和指令空隙,把 Hook 代码"缝"进去,再让校验通过。

OmniDrive 就是这套路线的完整示范,代码量只有约 760 行,但覆盖了 Hook 的几乎所有经典手法。

二、项目结构速览:补丁是怎么组织的

OmniDrive/ ├── asm/ # armips 汇编:注入脚本 │ ├── HL-DT-ST_BD-RE_BU40N_1.00.asm # LG 薄驱:地址表 + 注入 │ ├── ASUS_BW-16D1HT_3.02.asm # 华硕台式驱:地址表 + 注入 │ ├── main.asm # 两款机型共用的注入逻辑 │ ├── mmio.asm # 硬件寄存器映射 │ └── version.asm # 版本号宏 ├── src/ # C 语言 Hook 函数(交叉编译成 Thumb 静态库) │ ├── main.c │ ├── defs.h │ └── mmio.h ├── scripts/update_cmac.py # 修复固件 CMAC 校验 ├── CMakeLists.txt # 构建:编译 C → 调 armips 注入 → 改签名 └── arm-toolchain.cmake # arm-none-eabi 工具链配置

每个机型一个.asm文件,开头是地址表——这是逆向的"成果",用 armips 的.definedatalabel/.definethumblabel把函数和数据的地址命名化,例如 asm/HL-DT-ST_BD-RE_BU40N_1.00.asm 里的:

.definethumblabel DVDReadCmd,0x11798C .definethumblabel BDReadCmd,0x0AE90C .definedatalabel ScrambleHookAddr,0x0A1D48

之后所有注入都按名字引用地址,换机型时只需改表,共用逻辑写在 asm/main.asm 里。

三、最快上手:三步完成固件打补丁

依赖:CMake 3.26+、ninja、arm-none-eabi-gcc 工具链、armips、Python 3 + pycryptodome。

git clone https://gitcode.com/gh_mirrors/omn/OmniDrive cd OmniDrive

第 1 步:放入原厂固件

把 LG BU40N 1.00 和华硕 BW-16D1HT 3.02 的固件放进firmware/目录,文件名和校验值必须匹配 README.md 中的表(如HL-DT-ST_BD-RE_BU40N_1.00.bin的 CRC32 为E3C1A315)。

第 2 步:构建

mkdir build && cd build cmake -G Ninja .. ninja

CMakeLists.txt 里的构建链是核心:编译src/main.c为静态库libOmniDrive.a→ 调armips执行注入脚本 → 调 scripts/update_cmac.py 修复签名,输出到patched_firmware/。

第 3 步:刷写

推荐用 MakeMKV 附带的sdftool刷写;BU40N 固件适用于所有薄型机,BW-16D1HT 固件适用于台式机。

四、汇编注入点定位:armips 的四个关键指令

看 asm/main.asm 就能数清四种注入手法:

1. 函数 Hook:bl前置调用

最常见的一招——在关键函数入口处插一条bl(Thumb 调用指令),先跑自己的包装函数,再回到原逻辑。例如 asm/main.asm:

.org ScrambleHookAddr bl ChangeDiscRWModeHook

对应的 C 侧包装在 src/main.c 中:先调用原版ChangeDiscRWMode(),再根据自定义命令的标志位改写解扰(scramble)寄存器,实现"可选解扰的 raw 读取"。

2. 条件分支强改:让判断"永远成立"

把条件跳转改成无条件跳转,直接绕过厂商的限制逻辑:

.org DVDLeadOutPatchAddr0 .d8 0xe0 ; bls -> b .org BDLeadOutPatchAddr .d8 0xE0 ; bne -> b

这一处改动就解锁了 DVD/BD 的lead-out 读取——原固件在这里判断"到 lead-out 就停",改成无条件跳转后继续读。类似的还有 asm/main.asm 里把beq改成b来放开 BD 识别流程。

3. NOP 掉限制逻辑

.org CDDataSpeedPatchAddr nop

把限速/检查类指令直接填成nop,是最粗暴也最有效的补丁。

4. 命令表重定向:注册自定义 SCSI 命令

MT1959 的固件里有一张 SCSI 命令分发表。OmniDrive 在固件空闲区(asm/main.asm 的CommandTableCustom)写入一张新表,把 0xC0 命令映射到CmdOmniDriveReadDiscRaw,再通过修改原表末尾条目把分发表"接力"过来——相当于给光驱注册了一个新命令,支持 FUA 绕过缓存、raw 寻址(CD 用 MSF、DVD/BD 用 PSN)、可选解扰。

五、C 代码如何被"搬进"固件:静态库 + importobj

固件空间紧张,但 C 代码可维护性最好。OmniDrive 的做法:

  1. 用arm-none-eabi-gcc -mthumb -march=armv5te -ffreestanding编译 src/main.c 为静态库(见 arm-toolchain.cmake);
  2. 在空闲区用一条指令把整个库搬进来(asm/main.asm):
.importobj "../build/libOmniDrive.a"
  1. 汇编里的bl ChangeDiscRWModeHook会自动解析成库中函数的实际地址。

这就是"汇编做手术台、C 语言做器官"的分工:注入点只有几十字节,真正的功能逻辑(如 src/main.c 的CmdOmniDriveReadDiscRaw)全部写在 C 里。

六、CMAC 签名修复:让补丁通过固件校验

MT1959 固件带有 AES-CMAC 校验,改一个字节刷写就会被拒。scripts/update_cmac.py 就是为此而生:

  • 从固件偏移0x10400读取 16 个"校验段"描述(启用标志 + 起止地址);
  • 对每段固件内容按 16 字节块字节反转后,用内置的 MT1959 密钥计算 CMAC;
  • 把新摘要(同样反转)写回描述表。

构建时它由 CMake 自动在 armips 之后执行,你几乎无感——这就是"改完固件还能刷进去"的关键一步。💡

七、刷写后验证:INQUIRY 里写着 OmniDrive

补丁会在 INQUIRY 应答数据里写入标识(asm/main.asm):

.org InquiryDataPatch .ascii "OmniDrive"

刷完固件后用sdftool inq或reseter --info查看产品信息:厂商/产品名变成OmniDrive并带版本号,就说明 Hook 全部生效了。之后即可用 Redumper 等工具通过 0xC0 命令读取 raw 扇区,转储 Xbox XGD3、PS4 等光盘。

八、小结:一套可复用的固件 Hook 配方

环节OmniDrive 的做法
地址定位每机型一张.definedatalabel地址表
功能 Hook入口处插bl,C 包装函数先改状态再调原函数
逻辑绕过条件跳转改无条件跳转 /nop
扩展功能空闲区放新命令表,重定向 SCSI 分发
代码注入C 编译为静态库,.importobj一次搬入
校验绕过AES-CMAC 按段重算并回写

这套"地址表 + 共用注入脚本 + 静态库 + 签名修复"的结构,对其它闭源固件的二次开发同样适用。想动手的可以从 asm/main.asm 和 src/main.c 这两个文件读起,760 行代码就能看完全貌。

【免费下载链接】OmniDrive

项目地址:https://gitcode.com/gh_mirrors/omn/OmniDrive
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进