前天帮某人弄的时候顺便就做了。考虑到之前好像没太多关于LBA保护的资料,就顺便写一下了。
PS:另外,如果大家有什么问题也欢迎在下面留言。

首先说明LBA保护是什么。讲到这里就插入一点背景知识。
PSP的UMD数据基于ISO9660格式存储。(关于ISO9660的具体信息请查阅相关资料)
众所周知,ISO9660的数据存储基于逻辑块(Logical Block)。数据必须以逻辑块为单位对齐。
其大小可在VolumeDescriptor结构的logical_block_size中获得。
在PSP上,这个值是0x800,也就是2048字节。
sony为PSP的isofs驱动(在用户层一般由disc0访问)提供了一种特殊的访问模式。
这种模式就是LBA,也就是Logical Block Addressing,即逻辑块寻址模式。
可以使用户通过提供逻辑块编号和文件长度,直接访问相应位置的数据,而不需要沿ISO数据结构下溯。
(事实上,下溯的结果也只是这两个数据而已。)
但事实上,提供这种方法的主要目的并不是节约寻址时间。
由于UMD的读取速度强差人意,对于需要频繁读取数据的游戏,将数据平均的分散在1.8G的存储空间内将有助于减少平均读取时间。
——这才是提供LBA的目的。
出于这种目的,很多游戏开发者也会选择使用LBA。
但同时,LBA的使用也对游戏数据的修改造成了影响——自然,这种影响是在开发的时候不需要考虑到的。
在修改数据后重新对游戏打包,一般都会改变数据的逻辑块排列和大小。这种情况下,访问将会失效。
这种情况,对破解者来说就像是开发者使用的一层保护措施。这也就是“LBA保护”一词的来源。
在下面的文章中,笔者也将继续使用LBA保护这个称呼,尽管并不贴切。

作为基础知识,自然也需要了解Sony为LBA提供的方法。
一般使用下列串进行访问:
"%s:/sce_lbn0%x_size0x%x"
换句话说也就是sprintf(pszLbaString,"%s:/sce_lbn0%x_size0x%x",pszDriverName,dwLBNumber,dwFileSize);
(注意,一般来说是这个格式,但也有其它的情况。但sce_lbn这个特征串是不会变的)
举例而言,如果一个文件的起始逻辑块为0x120,长度为0x4800,那么将disc0:/sce_lbn0120_size0x4800作为文件名即可。
IO句柄打开后,一切操作都和普通文件一样了。
例程:
int fd=sceIoOpen("disc0:/sce_lbn0120_size0x4800",PSP_O_RDONLY,0777); int dwSize=sceIoLseek32(fd,0,SEEK_END); sceIoClose(fd);
下面进入正题,也就是LBA保护的破解办法。举例的时候将以绝体绝命都市3(ULJS-00191)这个游戏为例。
将ISO Unpack再Repack以后无法运行——这是LBA保护的最明显特征。一般来说,有2种解决方法。笔者将分别进行讲解。

一:LBA表修复
出于编程简便和模块化的考量,大多数开发者在编写游戏时仍将使用文件名作为调用依据。
(极少部分游戏除外,例如空之轨迹系列的一部分文件名就是以LBA形式硬编码在BOOT里的,
这样的数据除了构建一个文件名的替换表以外没有特别合适的处理办法)
而这种情况下,一般会在ISO里放一个文件,用于记录每个文件的LBA值、大小和文件名的对应关系(部分游戏会把这个表和PackList合起来)。
在游戏运行时,首先加载这个表,之后其它的文件访问将通过查找这个表来进行。这个表称为LBA表。
通常LBA表都是单独加载的,因此它在BOOT内的文件名都是以普通方式记录,或至少是一个单独的LBA文件名。
只要生成一个新表,就可以让游戏正常运行。那么怎么找到这个文件呢?
对于采用了LBA表的游戏,BOOT内记录的普通文件名会很少,因此只要逐个筛查这些普通的文件名("disc0:/PSP_GAME/"开头的)即可,检查方法下述。
如果是有一些经验的话,也可以先去搜索特征串(sce_lbn),
基本上用LBA保护的游戏都一定要把这个串作为sprintf的格式串,而表的名称应该就在.rdata区内其所在位置的附近。
(因为同属类似的功能,代码里使用处应该也相近,而编译器在编译时会按照顺序来存储这些串)

在找到一个文件之后,检查其是否记录有大量文件名,并对一些LBA值和文件大小值进行搜索。这些值用UMDGEN先行导出。
如果存在,那么基本可以认定它就是LBA表。在本例中,LBA表是PSP_GAME/USRDIR/INSTALL/HEADER.BIN。
之后是分析这个表的格式。这一步属于破解范畴,不再赘述。注意“文件名-LBA-文件大小”的对应关系即可推出。
下面给出HEADER.BIN的格式:

typedef struct _LBA_TABLE_HEADER { int dwElementNum; //文件数 int dwOffsetStringTableStart; //文件名表位置 int dwReserved0; //-1 int dwReserved1; //-1 }Lba_Table_Header; typedef struct _LBA_ELEMENT { int dwNameOffsetInStringTable; //文件名在文件名表中的位置 int dwAccumulateLengthValue; //累计的一个长度和 int dwFileLength; //文件长度 int LbaStart; //起始逻辑块 int dwCRCValue; //数据校验和 }Lba_Element;

有了格式之后,编写程序,将新的数据对应的LBA表重新生成,并替换即可使游戏正常访问数据。
尽可能将所有数据的含义都解明,不明的数据可以进行动态调试。例如此例中,CRC校验和建议也要更新。
这种方法的好处是稳定易行,缺点则是每次更新数据都要重新构建一个LBA表,对于需要不断调试的游戏来说过于繁琐。

二:修改程序
对于一些游戏,其LBA表格式过于复杂,或需要不断调试数据,这种情况下构建LBA表是一项较为繁琐的工作。
这种情况下,便建议采用这里将要叙述的第二种方法,也就是修改程序。由于修改后的“一劳永逸”,在可行的情况下也是推荐的方法。
这种方法对破解者的反汇编能力有一点要求,不过不是很高。对于PSP程序的反汇编,Ps2Dev等处有一些不错的教程,略去不论。

在下面的叙述中笔者将使用PrxTool作为反汇编工具。
思路介绍如下:
1.首先查找对特征串的引用,一般来说集中在一处,而且一般是用于sprintf(sprintf的目标串此处称为Dst)。
2.在sprintf之前一般是根据普通文件名(Name)获得文件长度和起始逻辑块的操作,找到这个操作。
3.将函数修改为"strcpy(Dst,Name)"这样的操作
4.检查其它对数据的检查操作

基本上就是按照这个思路进行。对反汇编来说,没有什么通用的方法,更多依靠破解者自身的耐心和分析能力。

本例具体讲解如下:
特征串位置 : 0x08BE02E0。
=> 调用 : loc_0883D570处发现。        (第一步)

相关代码段:
loc_0883D50C:  ; Refs: 0x0883D4D4   
0x0883D50C: 0x52600012 '..`R' - beqzl      $s3, loc_0883D558
0x0883D510: 0x02A02021 '! ..' - move       $a0, $s5
0x0883D514: 0x8E62000C '..b.' - lw         $v0, 12($s3)
0x0883D518: 0x50400006 '..@P' - beqzl      $v0, loc_0883D534
0x0883D51C: 0x02A02021 '! ..' - move       $a0, $s5
0x0883D520: 0x8E620008 '..b.' - lw         $v0, 8($s3)
0x0883D524: 0xAEA20018 '....' - sw         $v0, 24($s5)
0x0883D528: 0x8E62000C '..b.' - lw         $v0, 12($s3)
0x0883D52C: 0x10000010 '....' - b          loc_0883D570
0x0883D530: 0xAEA2001C '....' - sw         $v0, 28($s5)

loc_0883D534:  ; Refs: 0x0883D518
0x0883D534: 0x0E20F5E1 '.. .' - jal        sub_0883D784
0x0883D538: 0x00000000 '....' - nop      
0x0883D53C: 0x00402021 '! @.' - move       $a0, $v0
0x0883D540: 0x0E20F202 '.. .' - jal        sub_0883C808
0x0883D544: 0x26A5001C '...&' - addiu      $a1, $s5, 28
0x0883D548: 0xAEA20018 '....' - sw         $v0, 24($s5)
0x0883D54C: 0x8EA2001C '....' - lw         $v0, 28($s5)
0x0883D550: 0x10000007 '....' - b          loc_0883D570
0x0883D554: 0xAE62000C '..b.' - sw         $v0, 12($s3)

loc_0883D558:  ; Refs: 0x0883D50C
0x0883D558: 0x0E20F5E1 '.. .' - jal        sub_0883D784
0x0883D55C: 0x00000000 '....' - nop      
0x0883D560: 0x00402021 '! @.' - move       $a0, $v0
0x0883D564: 0x0E20F202 '.. .' - jal        sub_0883C808
0x0883D568: 0x26A5001C '...&' - addiu      $a1, $s5, 28
0x0883D56C: 0xAEA20018 '....' - sw         $v0, 24($s5)

loc_0883D570:  ; Refs: 0x0883D52C 0x0883D550
0x0883D570: 0x8EA6001C '....' - lw         $a2, 28($s5)
0x0883D574: 0x3C0508BE '...<' - lui        $a1, 0x8BE
0x0883D578: 0x8EA70018 '....' - lw         $a3, 24($s5)
0x0883D57C: 0x26A4002C ',..&' - addiu      $a0, $s5, 44
0x0883D580: 0x0E20AF40 '@. .' - jal        sub_0882BD00
0x0883D584: 0x24A502E0 '...$' - addiu      $a1, $a1, 736
0x0883D588: 0x8FBF001C '....' - lw         $ra, 28($sp)

特征串被作为第二个参数($a1)传入,可以推知将要进入的函数sub_0882BD00是sprintf。
=> 还原为:sprintf(($s5+44),pszLbaFormat,($s5+28),($s5+24));
得知$s5+44为文件名存储位置,$s5+28为LBA值,$s5+24为文件长度。同时推知$s5是一个结构指针。
前溯,发现$s5+24和$s5+28有两种获得方式:
由$s3所指向的结构中读取(loc_0883D50C),
和由sub_0883C808的返回值和传入的$a1获得(loc_0883D534,loc_0883D558)。    (第二步)
由sub_0883C808入手,发现返回值为LBA值,传入的第2参数是长度的地址。
=> 其作用为获得LBA值和长度。
又其$a0为sub_0883D784($s5)返回值,查得为$s5+44。
=> $s5+44保存的是文件名。
=> 还原为dwSize=sub_0883C808(pszFileName,&dwLba);
=> $s5+44原来存储的是普通文件名,sprintf后为LBA文件名。因此直接去除sub_0882BD00的调用。  (第三步)
(若不同,则需将其改为一个strcpy操作,strcpy函数可在上下文中试着查找)

运行游戏后发现游戏反复读取数据,无法继续进行。疑为某些数据无法通过校验。
在0x883D57C下断,于此处强行修改$sp+24(长度)后即可通过,得知游戏要检验长度值。
进入sub_0883C808,检查后发现其内部操作是打开文件名所指的文件来获得长度,故而不存在问题。
返回考虑loc_0883D50C,此处检查$s3是否为空指针,如果不是则由$s3+8得到长度,$s3+12得到LBA。
=> 猜测此处为查表操作。(事实上$s3指向的正是前文的Lba_Element结构)
因此将查表操作统一替换即可:将0x883D50C的beqzl      $s3, loc_0883D558替换为b loc_0883D558。 (第四步)
运行游戏后一切正常。修改成功。

第二种办法的优点是一次修改即可生效,缺点为操作较第一种而言比较复杂,而且去除其它校验的过程也相对繁琐。
在过程中请多多利用动态调试。

通过这样的工作,我们已经成功的去除了游戏的LBA保护。此时再重新打包数据将不会有任何障碍。

Elysion
May.2009

=================================================

原文地址:http://blog.sina.com.cn/s/blog_43f940190100dsek.html

【转帖】PSP ISO文件LBA保护分析 by Elysion相关推荐

  1. PSP火影忍者之究极冲击 游戏ISO文件和完美通关存档

    PSP火影忍者之究极冲击 游戏ISO文件和完美通关存档 15550698221

  2. PSP愤怒的小鸟 游戏ISO文件和完美通关全三星存档和金手指

    PSP愤怒的小鸟 游戏ISO文件和完美通关全三星存档和金手指 15550698221

  3. PSP死神灵魂升温6 游戏ISO文件和完美通关存档和金手指

    PSP死神灵魂升温6 游戏ISO文件和完美通关存档和金手指 15550698221

  4. PSP 斯巴达勇士 游戏ISO文件和完美通关存档

    PSP 斯巴达勇士 游戏ISO文件和完美通关存档 15550698221

  5. 操作被占用的文件-unlocker机理分析(转)

    操作被占用的文件-unlocker机理分析 ==================================================================== 以下为转帖 操作被 ...

  6. Android中的ClassLoader与dex文件加密实现分析

    Android中的ClassLoader BaseDexClassLoader Dex类加载器的基类,包含Dex类加载器之间通用功能的实现. DexClassLoader A class loader ...

  7. 笔记本 win11 64位专业版iso文件v2021.07

    笔记本 win11 64位专业版iso文件v2021.07是微软最新推出的电脑操作系统,新版系统有着很多全新的功能.无论是注册表信息还是系统都进行了全面设置.同时应用商店也有了改进优化,保证用户们的使 ...

  8. 如何使用 GRUB 2 直接从硬盘运行 ISO 文件

    大多数 Linux 发行版都会提供一个可以从 USB 启动的 live 环境,以便用户无需安装即可测试系统.我们可以用它来评测这个发行版或仅仅是当成一个一次性系统,并且很容易将这些文件复制到一个 U ...

  9. 【C/C++基础进阶系列】实战记录 -- Dump 文件生成与分析

    [C/C++基础进阶系列]实战记录 -- Dump 文件生成与分析 [1]Windows 端 Dump 文件的捕获与分析 [1.1]添加 Windows 端 Dump 捕获的代码 代码下载,windo ...

  10. QQ 键盘加密保护分析

    QQ 键盘加密保护分析 让我们现在开始进入正题, QQ 键盘加密保护主要依赖的是 QQ 目录下的 3 个文件,分别是 npkcrypt.sys . npkcusb.sys 和 npkcrypt.vxd ...

最新文章

  1. OpenAI探索机器人模拟训练新方法:仿真与真实世界无缝衔接
  2. linux 输出重定向_linux学习笔记(实验楼) 实验12 数据流重定向
  3. 百度经验怎么赚钱之练就三星经验,轻松布局流量入口。
  4. 复合索引的列顺序判断
  5. 此域的推荐安全级别是“安全级-高”的解决办法
  6. AI人才缺口达百万:做了AI,就一定能拿到高薪offer吗?
  7. MySQL千万数据量深分页优化
  8. 数塔 简单的 动态规划
  9. SpringBoot→请求参数、返回参数、文件上传、拦截器、异常处理、定时任务、异步任务
  10. 锁屏界面提示某些设置已隐藏_OPPO手机忘记锁屏密码怎么办?教你一招轻松解开!...
  11. 光(复振幅)在自由空间中传播的matlab仿真——傅里叶光学方法
  12. oracle导入dmp文件出错,IMP导入时的错误以及解决办法
  13. usb声卡驱动_艾肯iCON ProDrive第三代USB声卡驱动全新发布!
  14. oracle瘦身,数据库瘦身
  15. 会议流程安排以及详细的资料。
  16. 视频倍速播放方法(有效!)
  17. 常见的弱口令爆破工具
  18. Eclipes更改主题及字体
  19. Chorme 浏览器查看请求头、响应头
  20. pandas中的dropna()方法解析

热门文章

  1. 计算机网络(第8版)期末复习
  2. mysql 储存特殊符号表情报错
  3. 计算机专业买啥样笔记本,高考结束,想学计算机专业,买台啥样的笔记本比较好,暑假自学c和cpp...
  4. Android 图片资源大瘦身
  5. 全球与中国自动识别系统单元市场深度研究分析报告
  6. 响应“交通强国”战略,百度地图重构行业生态价值
  7. 1.CPU体系架构-RISC指令集和CISC指令集
  8. jsp打印去掉页眉页脚
  9. cmd 如何打开资源管理器
  10. oracle自动化巡检报告