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

《龙珠2DS》的字库破解过程

2014年02月13日 ⁄ 综合 ⁄ 共 4575字 ⁄ 字号 评论关闭

半年前写的文章了,原本是发表在兔友论坛上的,还是在自己的blog上也保留一份吧。

 

图片有些不能显示,点我去看原帖
(不需要注册)

---------------------------------------------------------------------------------------------------------------------------------------------------------


CT2打开
rom后很容易发现文本是标准
JIS编码,粗看了下文本在根目录下的
msg/jpn下。字库也很容易找到,在
/font/jpn下,但是用
CT2无法看到。这里需要
ASM 了。


1.jpg



在存档处可以看到这里的文本显示是以

OAM

的形式存在的,

OAM

可以理解是用

sprite

的方式,所以在第一个

OAM

那里

0x0660000

那里设断点:

[06600000.. 06600004]!

,关于如何在

No$gba

里设置断点,请看

No$gba help

文档里的

Debugging

部分。


这里停下来:


2.jpg


  可以看到最后停在
strr4,[r3,8h]。而
r3=0x040000D4。这里用到了
DMA4,关于
NDS
DMA请看
gbatek
http://nocash.emubase.de/gbatek.htm


0x040000D4,存的是源地址,是
0x2273440
0x040000D8,是目标地址,可以看到上图右下角这个值下就是我们刚才设置的地址。

0x040000DC,是复制的字节数

  可以去
0x2273440看到里面确实是可以直接显示(这里主要是为了区分前面无法直接显示)的字模了。这时候你可以
dump memory然后用
CT2看一下。这里说一下
No&gba里提供的
dump memory
Utility->Hexdump to File),但是这个
dump出的是
ASCII模式,所以需要自己写程序转换成二进制(这个很简单啦)。

TILE
4bpp,然后直接用
8*8显示如下


3.jpg


然后改成
32*16,并且用
ObjH-1234


4.jpg


好啦,我们继续。接下来就要考虑

0x2273440

开始的内容是从哪里来的了。下断

[2273440.. 2273444]!





5.jpg


可以看到最后在
strbr7,[r4,r0]停下了,对照刚才
dump下来的内存,看来到这里就已经开始解密字库了

继续

F7

的话可以看到一个循环

  1. 0208CBD8 E59D0018 ldr     r0,[r13,18h]                            ;2  48
  2. 0208CBDC E3580000 cmp     r8,0h                                   ;1  49
  3. 0208CBE0 E4D01001 ldrb    r1,[r0],1h – 读取rom中的数据               ;3  52
  4. 0208CBE4 E58D0018 str     r0,[r13,18h]                            ;1  53
  5. 0208CBE8 E59D3174 ldr     r3,[r13,174h]                           ;2  55
  6. 0208CBEC E2017033 and     r7,r1,33h                               ;1  56
  7. 0208CBF0 11A00107 movne   r0,r7,lsl 2h                            ;1  57
  8. 0208CBF4 E58D1014 str     r1,[r13,14h]                            ;1  58
  9. 0208CBF8 120070FF andne   r7,r0,0FFh                              ;1  59
  10. 0208CBFC E08A0006 add     r0,r10,r6                               ;1  60
  11. 0208CC00 E0891005 add     r1,r9,r5                                ;1  61
  12. 0208CC04 E1A0200B mov     r2,r11                                  ;1  62
  13. 0208CC08 EBFFF747 bl      208A92Ch                                ;3  65
  14. 0208CC0C E7C47000 strb    r7,[r4,r0]                              ;1  66
  15. 0208CC10 E59D0034 ldr     r0,[r13,34h]                            ;2  68
  16. 0208CC14 E5901014 ldr     r1,[r0,14h]                             ;3  71
  17. 0208CC18 E5900010 ldr     r0,[r0,10h]                             ;3  74
  18. 0208CC1C E0851001 add     r1,r5,r1                                ;1  75
  19. 0208CC20 E1510000 cmp     r1,r0                                   ;1  76
  20. 0208CC24 AA00000B bge     208CC58h                                ;3  79
  21. 0208CC28 E59D0014 ldr     r0,[r13,14h]                            ;2  81
  22. 0208CC2C E3580000 cmp     r8,0h                                   ;1  82
  23. 0208CC30 E20000CC and     r0,r0,0CCh                              ;1  83
  24. 0208CC34 E20070FF and     r7,r0,0FFh                              ;1  84
  25. 0208CC38 01A00147 moveq   r0,r7,asr 2h                            ;1  85
  26. 0208CC3C 020070FF andeq   r7,r0,0FFh                              ;1  86
  27. 0208CC40 E59D3174 ldr     r3,[r13,174h]                           ;2  88
  28. 0208CC44 E0891001 add     r1,r9,r1                                ;1  89
  29. 0208CC48 E08A0006 add     r0,r10,r6                               ;1  90
  30. 0208CC4C E1A0200B mov     r2,r11                                  ;1  91
  31. 0208CC50 EBFFF735 bl      208A92Ch                                ;3  94
  32. 0208CC54 E7C47000 strb    r7,[r4,r0]                              ;1  95
  33. 0208CC58 E59D0020 ldr     r0,[r13,20h]                            ;2  97
  34. 0208CC5C E2866002 add     r6,r6,2h                                ;1  98
  35. 0208CC60 E5D00002 ldrb    r0,[r0,2h]                              ;3  101
  36. 0208CC64 E1560000 cmp     r6,r0                                   ;1  102
  37. 0208CC68 BAFFFFDA blt     208CBD8h                                ;3  105

复制代码

我把重要的语句用红色标记了。

首先看

0208CBE0 E4D01001 ldrb r1,[r0],1h
;读取
rom中的数据

这一句就是从字库里去数据了,不信的话可以找到
r0所在的内存,去
rom里搜索,找到的就是
system16*16.fnt

然后再看这两句:

0208CC0C E7C47000strb r7,[r4,r0]
   ;1 66
0208CC54 E7C47000 strb r7,[r4,r0]
  ;1 95
r4就是刚才设置的断点的首地址,所以
r0就是偏移了,这两句的上面一句

0208CC50 EBFFF735 bl 208A92Ch ;3 94
很明显就是调用子函数计

r0,里面的内容大家有兴趣可以去看噢
J

好,接下来要讲的就是这段程序最重要的部分了(怎么才讲到最重要的地方
~):

0208CBEC E2017033 and r7,r1,33h
;1 56
0208CC30 E20000CC and r0,r0,0CCh
;1 83
0208CC34 E20070FF and r7,r0,0FFh
;1 84
0208CC38 01A00147 moveq r0,r7,asr 2h
;1 85
0208CC3C 020070FF andeq  r7,r0,0FFh
;1 86
其实从这两句已经能看到这个加密的主要部分,字库的上下部分重叠起来存了


上部用
r1&0x33
下部用
(r1&0xCC)>>2
这里似乎很难直接看出端倪(我很少用这种很书面的词语



),请看下面的图



6.jpg




CT2

进入

TILE

模式,可以看到字体大致是

12*14

。下面模拟解密的过程,还是用图(偶没美工天赋,大家将就着看吧)

7.jpg


  

这是原先的内存,每个
tile
32个字节,并且因为用了
4bpp
2个像素用一个字节存,所以这里宽只画了
4行。并且这里要注意,我们的例子中,只有
tile1
2
5
6有数据。

Process

读取第一个字节,解密成

t1



t2

,放入内存,

t1

为第

1

行的前两个像素,

t2

为第

8

行的前两个像素。

8.jpg





4

个字节都在第一个

TILE

里,但是到了第

5

个字节时,也就是(

1



5

)和(

8



5

)【这里理解为一个

12*14

字模的

1



5

列和

8



5

列】。解密成

b1



b2

,如下图

9.jpg



然后再是第

1

行和第

8

行解密完后,就是第

2

行和第

9

行了,假设第一个字节如下解密成

c1



c2

,如下:

10.jpg



好了,相信到这里大家都已经明白解密的过程了,解密时关键是要计算出这个字节对应的
t哪个
tile的哪个地方。下面就是大家写程序解密字库了,然后修改字库后再加密回来,一样的思路。

字库如下:

11.jpg



这个只是一部分。(里面的

字是我测试时用过的
~

字库的解密过程是写完了,但是这里还没提到字库文件的格式,这里我相信大家去分析一下的话都能分析出来,只是这里要提的一点是游戏里的

16*16

字库存放是变宽的,也就是英文,日文,中文汉字的宽度可能不一样。

抱歉!评论已关闭.