现在的位置: 首页 > 综合 > 正文

(PS)賭博黙示録カイジ汉化笔记(五)(完)

2013年10月10日 ⁄ 综合 ⁄ 共 5175字 ⁄ 字号 评论关闭

五.文本导出和导入B

 

程序员要有一种体谅翻译人员的心情,一个好的编辑器肯定是必要的。Agemo的主页上有一个AgemoEditor就是一个还不错的软件。当然我觉得还是差一点,比如没有专有名词统一的工具,没有版本控制,不支持小组合作。

 

蓝山魔导导出的文本,由于没有找到文本指针,文字零落,分段也不明确,而且只能用一般的文本编辑器进行编辑。感觉还是很差的。当然转成AgemoEditor专用格式的话,也不是很困难,可问题是文本指针的问题。Agemo在使用说明中说了一句话:

支持的文本格式2 - 地址,长度,文字


格式见右侧

本人不用这种格式的,如果你找到了指针表,
可以方便修改每一句的长度,建议导出我那种格式。

E9DA,30,底いため、通常攻擊には弱い。{结束符FFFF}
E57A,14,
スキル:なし{结束符FFFF}
F766,46,
この世に怨念を持ったまま死だ者の灵で、
F766,13,
生前の{结束符FFFF}

 

就是粗体的那句,是的,如果作为程序员无法找出指针,将一堆垃圾扔给翻译,这种事情我是做不出来的。最后还是只能进行更为复杂的分析。

 

至此,需要以下几个工具:

1)  Agemops_debugger,到Agemo的主页去下载。看名字就知道,用来调程序的。

2)  IDA,反汇编的工具,用来静态分析的。到看雪(pediy)去下载。

 

Ps_debugger,如何设置不再说明,可以参考附带说明文档。该程序不能直接加载镜像,所以要先用虚拟光驱加载,然后再“RUN CD”。游戏进入第一段文本画面后,点击“Pause CPU”按钮暂停游戏。点击“Dump”按钮将内存Dump下来,Dump下来的内容保存在dump目录下,其中vram.bin是显存,这个目录下还有另外一个软件vram.exe,就是Agemo主页上提到的ps显存查看器,这里没有使用说明,但是主页单独下载的压缩包里面有。

打开后就可以看到这个画面:

这个软件的作用我现在还不是很了解,所以不再多介绍。

 

ram.bin是内存,才是重要的部分,用winhex之类的软件打开,可以发现从00100000开始,其内容就是Course.dat004D4000开始的内容。显然,程序将此段内容从光盘读取到内存,然后读取内存,将文字显示出来。

 

接下来设置断点,选中Break下的MemRead,自动填充为80000000-80000000,前面为什么要带80请参考Agemo首页的PS资料。将这个始末地址修改成80100000-8010C000,但要注意修改后并不会立刻生效,要先取消MemRead,在选中MemRead,下方会提示“wait for pause on read  mem from 80100000 to 8010C000”,此时说明已经生效。

 

点击“Resume CPU”继续,程序提示“CPU Break, mem read at 00101676, 1 bytes

 

00101676Course.dat中就是004d5676,对应的是“雨粒”的“粒”,也就是将要显示的字。不去管它,继续点“Resume CPU

CPU Break, mem read at 00101677, 1 bytes

CPU Break, mem read at 00101678, 1 bytes

CPU Break, mem read at 00101679, 1 bytes

CPU Break, mem read at 0010167A, 1 bytes

CPU Break, mem read at 00100048, 2 bytes

CPU Break, mem read at 0010167B, 1 bytes

 

注意,顺序读取到167A后,也就是00,突然跳转到了0048,然后又跳转到了167B。这说明了几点:

1)  指针表中并没有指明文本的长度,文本还是靠00来表明句子结束的。

2)  48很可能就是指向167B指针。

 

 

 

48的数据是00 2B,注意程序读取了2 bytes。这一段数据部分的长度是164A,而164A + 6 + 2B = 167B,就是指向167B的指针。不停的“Resume”,可以看到:

 

CPU Break, mem read at 0010004A, 2 bytes (新的一句话)

CPU Break, mem read at 00101694, 1 bytes

CPU Break, mem read at 00101695, 1 bytes

CPU Break, mem read at 00101696, 1 bytes

CPU Break, mem read at 00101697, 1 bytes

CPU Break, mem read at 00101698, 1 bytes

CPU Break, mem read at 00101699, 1 bytes

CPU Break, mem read at 0010169A, 1 bytes

CPU Break, mem read at 0010169B, 1 bytes

CPU Break, mem read at 0010169C, 1 bytes

CPU Break, mem read at 0010169D, 1 bytes

CPU Break, mem read at 0010169E, 1 bytes

CPU Break, mem read at 0010169F, 1 bytes

CPU Break, mem read at 001016A0, 1 bytes

CPU Break, mem read at 001016A1, 1 bytes

CPU Break, mem read at 001016A2, 1 bytes

CPU Break, mem read at 001016A3, 1 bytes

CPU Break, mem read at 001016A4, 1 bytes

CPU Break, mem read at 001016A5, 1 bytes

CPU Break, mem read at 001016A6, 1 bytes

CPU Break, mem read at 001016A7, 1 bytes

CPU Break, mem read at 001016A8, 1 bytes

CPU Break, mem read at 001016A9, 1 bytes

CPU Break, mem read at 001016AA, 1 bytes

CPU Break, mem read at 0010004C, 2 bytes

CPU Break, mem read at 0010004C, 2 bytes

CPU Break, mem read at 0010004E, 2 bytes(到这里结束了)

 

出现了分页结束的符号,现在程序等待按键输入。按键后,又立刻断下,继续点“resume”:

CPU Break, mem read at 00100050, 2 bytes

CPU Break, mem read at 00100050, 2 bytes

CPU Break, mem read at 00100052, 2 bytes

CPU Break, mem read at 00100054, 2 bytes

CPU Break, mem read at 00100056, 2 bytes

CPU Break, mem read at 00100058, 2 bytes

CPU Break, mem read at 00100058, 2 bytes

CPU Break, mem read at 0010005A, 2 bytes

CPU Break, mem read at 0010005C, 2 bytes

CPU Break, mem read at 0010005E, 2 bytes

CPU Break, mem read at 001016AB, 1 bytes

CPU Break, mem read at 001016AC, 1 bytes

CPU Break, mem read at 001016AD, 1 bytes

 

 

一路从50读取到了5e,然后跳转到16AB,初步分析认为4F 20跳过12个字节,之后每2个字节就是一个指针,指向一句文本,一直到47 00 00 00为止,47 00 00 00是分页标记。

 

这些分析还是比较简单,只要有一些耐心,还能看出来32 30 00 00后面跟随的指针是指向“XXXXXX.MOV”之类的字符串的。但总的来说还是比较粗,下面考虑用IDA进行静态分析。

 

Ps_dugger虽然不像ollydbg或者SoftICE之类的软件那么功能众多,如何利用就要自己的想象力了。

 

Ps_debugger有一个asm log功能,这个功能有一个问题,就是不能进入死循环,否则记录下来的文件会大的惊人。一般来说超过1M,得到的记录文件基本就无用了。死循环一般来说到了等待输入的时候就会产生,如果显示文字的时候可以按键快进或者有时间控制,一般都会进入死循环。记录下来的文件会提示用到的寄存器的值,所以看起来还是挺方便的,对照asm logida,可以当做程序走了一遍。还有一个问题记录了所有的指令,包括一些小函数,每调用一次都会全部记录下来,不能像调试器那样步过。

 

我这次下的断点是这样的,重新启动游戏,对内存地址80100000-8010C000memread下断,第一次断在80100002,点击asm log,开始记录,不停地点resume,到读取到80100014停止。因为再点的话就开始播放视频进入死循环了。得到的记录在程序目录下的asm.log中,先复制一份备份,这个文件在程序重启时会清空的。

 

内容大致如下:

80116e18 : LHU     801eada5 (a1), 0002 (80100000 (v1)) [80100002]

80116e1c : LHU     80100000 (v1), 0004 (80100000 (v1)) [80100004]

80116e20 : ADDU    80100006 (v0), 80100006 (v0), 0000164a (a0),

80116e24 : LH      0000164a (a0), 0538 (801a6e2c (gp)) [801a7364]

80116e28 : SH      00000000 (r0), 003c (801a6e2c (gp)) [801a6e68]

80116e2c : SW      80101650 (v0), 0038 (801a6e2c (gp)) [801a6e64]

。。。。。。

8011687c : SLL     00002000 (v0), 00000003 (a1), 01 (1),

80116880 : ADDU    00000006 (v0), 00000006 (v0), 80100010 (v1),

80116884 : LHU     80100016 (v0), fffe (80100016 (v0)) [80100014]

 

打开ida,新建一个Consoles .psx Sony PlayStation Excutable项目,载入Slps_027.49,经过一段时间分析。按Ggo to),输入第一行指令的地址80116e18,可以看到如下代码:

 

(函数名和注释是我加的,加注释点;即可)

loc_80116E04:                   # CODE    XREF: ReadCourseHeader:loc_80116DE0j

       lw     $v1, 0x24($gp)    # 文本内存地址->v1

                                # 这里是80100000

       nop

       addiu  $v0, $v1, 6       # 数据开始部分->v0

       sw     $v0, 0x2C($gp)    # 保存到gp+2c

       lhu    $a0, 0($v1)       # 代码段长度->a0

       lhu    $a1, 2($v1)       # 文本段长度->a1

       lhu    $v1, 4($v1)       # 0x02->v1

       addu   $v0, $a0          # v0+a0->v0,文本部分指针

       lh     $a0, 0x538($gp)

       sh     $0, 0x3C($gp)

       sw     $v0, 0x38($gp)    # 保存到gp+38

       addu   $v0, $a1          # v0+a1->v0,文本结束指针

       sw     $v0, 0x40($gp)    # 保存到gp+40

       addu   $v0, $v1          # v0+2->v0,数据真正结束

       sw     $v0, 0x44($gp)    # 保存到gp+44

       bnez   $a0, loc_80116E4C

 

       lui    $v0, 0x801A   # 0x801a0000->v0

       sh     $0, 0x30($gp) # 0->gp+30

 

红色部分的指令就是80116e18的指令。

lhu $a1, 2($v1)   # 文本段长度->a1

80116e18 : LHU     801eada5 (a1), 0002 (80100000 (v1))

抱歉!评论已关闭.