版主
- 大洋
- 14985
- 阅读权限
- 140
|
本帖最后由 nnezyj 于 20-9-27 16:38 编辑
┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅
引言:感谢 世界哪有真情lu、9011、i6henl、だ`無ぺ窷. 、老黑、花九胖 大佬们提供技术支持与教程文档分享!
┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅
※※※※※※※※ 前言 ※※※※※※※※
原盘文件时间为 2016/12 的狮门原盘,也是狮门刚开始采取乱序设计的初期,此时的原盘代码与现在的 Radius60 狮门代码差异相比,代码格式没有现在这么统一,代码混淆也相对严重,但乱序设计思路已基本成型。
使用 DVDFAB 提取原盘修复乱序,会生成一个 FAB! 的目录,其内放置有原盘 AACS 等原盘保护文件。DVDFAB 在 jar 文件内新增了代码类,用于调用这个目录内的文件,作为狮门内部代码乱序验证使用,给狮门乱序代码验证程序一个当前播放为正版光盘的假象。但用户会有删除 FAB! 目录的习惯,因此造成乱序验证失效,原盘进入乱序播放状态。
这里通过修改 jar 内的文件代码,达到去除 FAB! 也能正确播放 MPLS 的目的。
本次修复的思路,和目前 DVDFAB 对 Radius60 乱序修复的思路一致,通过找到 BDLocator 这一最终播放 PlayList 的关键函数位置,在播放正片之前,对播放的 PlayListID 进行检测,修正为正确的 PlayLisID 。
本篇原盘的乱序问题,一个是主菜单章节跳转,从零开始播放,还有便是没有播放正确的 mpls 编号。
实际播放测试,主菜单 play movie 按钮,播放的 mpls 编号,和菜单上选择章节跳转,播放的 mpls 编号是不一样的!
前情提要:
在播放控制类里,没有章节跳转的单独函数,而是通过 new BDLocator(url) 的方式,建立一个包含 MarkID 的 PlayList 来播放。
和 Radius60 乱序一样,在通过 new BDLocator(url) 建立用于播放的 PlayList 时,会通过外部调用,修改 url 字符串,替换为其他 PlayListID 和 MarkID。
由于代码混淆程度较为严重,无法直接通过 SBDJ 修改类文件内容,这里采用了取巧的操作,将原本用于乱序 url 字符串的调用函数,指向了我们新建的 PlayListID 和 MarkID 处理类。
这里,需要使用 JByteMod-1.8.2 进行混淆 class 的字节码修改。
本篇实例操作原盘:The 9th Life of Louis Drax 2016 BluRay 1080p AVC DTS-HD MA5.1-CHDBits
※※※※※※※※ 正文 ※※※※※※※※
通过 jadx-gui 搜索 BDLocator,经过判断确认 fu.class 为播放控制类。
fu.class 播放控制类
其中关键的两个函数:
- /**
- * paramca.b 是返回 PlayListID 编号的字符串。
- * String ca.b(String arg0) 返回处理过的 "bd://PLAYLIST:" 字符串
- * ca.b(String) 为乱序函数
- *
- * 这里仅为 PlayListID 部分,即从头播放 "bd://PLAYLIST:xxxxx"
- * -------------------------------------------------------------------------------------
- * @param paramca |
- * @param paraman |
- */
- public synchronized void a(ca paramca, an paraman) {
- try {
- a(paramca, paraman, new BDLocator(ca.b("bd://PLAYLIST:" + paramca.b)));
- } catch (Throwable throwable) {
- ae.a(throwable);
- }
- }
- /**
- * int[] cu.a(int titleNumber, int playListId, int markId) 返回处理过的ID编号
- * cu.a(int, int, int) 为乱序函数
- *
- * 这里包含 MarkID 部分
- * -------------------------------------------------------------------------------------
- * @param paramca |
- * @param paraman |
- * @param paramInt |
- */
- public synchronized void a(ca paramca, an paraman, int paramInt) {
- try {
- String[] arrayOfString = null;
- int i = paramInt;
- byte b1 = -1;
- int j = paramca.e;
- byte b2 = -1;
- String str = null;
- int[] arrayOfInt = cu.a(b2, j, i); // 这里返回 {titleNumber, playListId, markId} 数组
- // public BDLocator(String discId, int titleNumber, int playListId, int playItemId, int markId, String[] componentTags)
- a(paramca, paraman, new BDLocator(str, arrayOfInt[0], arrayOfInt[1], b1, arrayOfInt[2], arrayOfString));
- } catch (Throwable throwable) {
- ae.a(throwable);
- }
- }
复制代码
通过 JByteMod-1.8.2 字节码工具,修改两个关键函数的乱序函数调用,指向我们新建的乱序处理类 PlayList.class 的函数:
其中关键的两个函数修改之后的代码:
- public synchronized void a(ca paramca, an paraman) {
- try {
- a(paramca, paraman, new BDLocator(PlayList.b("bd://PLAYLIST:" + paramca.b)));
- } catch (Throwable throwable) {
- ae.a(throwable);
- }
- }
-
-
- public synchronized void a(ca paramca, an paraman, int paramInt) {
- try {
- String[] arrayOfString = null;
- int i = paramInt;
- byte b1 = -1;
- int j = paramca.e;
- byte b2 = -1;
- String str = null;
- int[] arrayOfInt = PlayList.a(b2, j, i);
- a(paramca, paraman, new BDLocator(str, arrayOfInt[0], arrayOfInt[1], b1, arrayOfInt[2], arrayOfString));
- } catch (Throwable throwable) {
- ae.a(throwable);
- }
- }
复制代码
在 SBDJ 中新建一个 PlayList 类名 Class 文件,代码如下所示:
建立一个正常播放的非正片 mpls 编号数组,确认 PlayListID 是否是其中之一。这些非正片之外的 mpls 编号,便是正片编号了,然后统一处理返回正确的编号 730。
MarkID 也是同理,本身初始传递来的便是正确的 MarkID,但是经过处理变成了0,我们只需要维持输出的是原始传递来的 MarkID 即可。
PlayList.java 播放控制类
[代码见CHM文件]
以上方式字节码修改部分最少最为方便的方式。
※※※※※※※※ 正文 ● PlayList.java 修改补充 ※※※※※※※※
上文中 PlayList.java 代码,通过比对 MPLS 编号返回指定的正片 MPLS 编号!
实际上,如果不需要指定特定 MPLS 编号,我们的 PlayList.java 代码可以变得更简洁。唯一缺点是,我们需要在破解乱序代码问题后,实际播放一次以确定修复乱序后原盘的正片 MPLS 编号。
譬如,本次原盘测试结果,正片 MPLS 编号为 00000,章节跳转和直接播放按钮选择,都功能正常!
简洁 PlayList.java 代码如下:
修改原理解析:原盘通过 ca.class 类的乱序函数调用,将导入的 PlayListID 与 MarkID 数值,转换为其他数值。因此,我们维持原来的输入结果不变,即可达到破解乱序的目的。
- public class PlayList {
-
- public static String b(String url) {
- return url;
- }
-
- public static int[] a(int titleNumber, int playListId, int markId) {
- int[] ids = {titleNumber, playListId, markId};
- return ids;
- }
-
- }
复制代码
后续处理:
播放一次原盘,获取破解乱序后的固定的正片 MPLS 编号。
将原盘的正确 MPLS 编号文件,复制一份改名为固定的正片 MPLS 编号。
※※※※※※※※ 结语 ※※※※※※※※
狮门乱序看起来很复杂,但经过实际的分析,抽丝剥茧,还是能找到合理有效的解决方法的!
找到最关键的播放控制,也就等于找到解决问题的核心点!
┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅分割线┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅
以上是《狮门_路易的第九条命_乱序修复》的内容目录及片段,详细内容下载附件“狮门_路易的第九条命_乱序修复.chm”查阅。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
评分
-
查看全部评分
|